false );
$http_response = wp_remote_get( $url, $args );
if ( is_wp_error( $http_response ) ) {
$error_msg = sprintf(
'Unable to retrieve URL %s, error: %s',
$url, $http_response->get_error_message()
);
error_log( $error_msg, 4 );
return $http_response;
} else {
$json = wp_remote_retrieve_body( $http_response );
$data = json_decode( $json, $assoc = true );
set_transient( $cachekey, $data, $cachetime );
}
}
return $data;
}
}
/**
* holds the community directory
*/
class FF_Directory
{
private $directory;
private $ed;
function __construct( $ext_data_service = null ) {
if ( is_null( $ext_data_service ) ) {
$this->ed = new FF_Meta_Externaldata();
} else {
$this->ed = $ext_data_service;
}
$data = $this->ed->get( FF_META_DEFAULT_DIR );
if ( is_wp_error( $data ) ) {
$this->directory = array();
} else {
$this->directory = $data;
}
}
function get_url_by_city( $city ) {
if ( array_key_exists( $city, $this->directory ) ) {
return $this->directory[$city];
} else {
return false;
}
}
// get one big array of all known community data
function get_all_data() {
$all_locs = array();
foreach ( $this->directory as $tmp_city => $url ) {
$tmp_meta = $this->ed->get( $url );
if ( ! is_wp_error( $tmp_meta ) ) {
$all_locs[$tmp_city] = $tmp_meta;
}
}
return $all_locs;
}
}
/**
* OO interface to handle a single community/city
*/
class FF_Community
{
public $name;
public $street;
public $zip;
public $city;
public $lon;
public $lat;
/**
* Default constructor from metadata
*/
function __construct( $metadata ) {
$loc = $metadata['location'];
$this->name = ( isset( $loc['address'] ) && isset( $loc['address']['Name'] ) )
? $loc['address']['Name'] : '';
$this->street = ( isset( $loc['address'] ) && isset( $loc['address']['Street'] ) )
? $loc['address']['Street'] : '';
$this->zip = ( isset( $loc['address'] ) && isset( $loc['address']['Zipcode'] ) )
? $loc['address']['Zipcode'] : '';
$this->city = isset( $loc['city'] ) ? $loc['city'] : '';
$this->lon = isset( $loc['lon'] ) ? $loc['lon'] : '';
$this->lat = isset( $loc['lat'] ) ? $loc['lat'] : '';
}
/**
* Alternative constructor from city name
*/
static function make_from_city( $city, $ext_data_service = null ) {
if ( is_null( $ext_data_service ) ) {
$ed = new FF_Meta_Externaldata();
} else {
$ed = $ext_data_service;
}
$directory = new FF_Directory( $ed );
if ( false === ( $url = $directory->get_url_by_city( $city ) ) ) {
return '\n";
}
if ( false === ( $metadata = $ed->get( $url ) ) ) {
return "\n";
}
return new FF_Community( $metadata );
}
function format_address() {
if ( empty( $this->name ) || empty( $this->street ) || empty( $this->zip ) ) {
return '';
}
// TODO: style address + map as single box
// TODO: once it is "ready" package openlayers.js into the plugin
// ( cf. http://docs.openlayers.org/library/deploying.html )
// TODO: handle missing values ( i.e. only name & city )
return sprintf(
'
%s %s %s %s
',
$this->name, $this->street, $this->zip, $this->city
);
}
}
/**
* main class for whole plugin
*/
class FF_Meta
{
private $dir;
private $ed;
function reinit_external_data_service( $ext_data_service = null ) {
if ( is_null( $ext_data_service ) ) {
$this->ed = new FF_Meta_Externaldata();
} else {
$this->ed = $ext_data_service;
}
$this->dir = new FF_Directory( $this->ed );
}
function __construct( $ext_data_service = null ) {
if ( is_null( $ext_data_service ) ) {
$this->ed = new FF_Meta_Externaldata();
} else {
$this->ed = $ext_data_service;
}
$this->dir = new FF_Directory( $this->ed );
}
function register_stuff() {
if ( ! shortcode_exists( 'ff_state' ) ) {
add_shortcode( 'ff_state', array( $this, 'shortcode_handler' ) );
}
if ( ! shortcode_exists( 'ff_services' ) ) {
add_shortcode( 'ff_services', array( $this, 'shortcode_handler' ) );
}
if ( ! shortcode_exists( 'ff_contact' ) ) {
add_shortcode( 'ff_contact', array( $this, 'shortcode_handler' ) );
}
if ( ! shortcode_exists( 'ff_location' ) ) {
add_shortcode( 'ff_location', array( $this, 'shortcode_handler' ) );
}
if ( ! shortcode_exists( 'ff_list' ) ) {
add_shortcode( 'ff_list', array( $this, 'shortcode_handler' ) );
}
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
add_action( 'admin_init', array( $this, 'admin_init' ) );
register_uninstall_hook( __FILE__, array( 'ff_meta', 'uninstall_hook' ) );
}
private function aux_get_all_locations_json() {
if ( WP_DEBUG || ( false === ( $json_locs = get_transient( 'FF_metadata_json_locs' ) ) ) ) {
$all_locs = array();
$comm_list = $this->dir->get_all_data();
foreach ( $comm_list as $entry ) {
if ( isset( $entry['location'] )
&& isset( $entry['location']['lat'] )
&& isset( $entry['location']['lon'] )
) {
$all_locs[$entry['location']['city']] = array(
'lat' => $entry['location']['lat'],
'lon' => $entry['location']['lon'],
);
}
}
$json_locs = json_encode( $all_locs );
$cachetime = get_option( 'FF_meta_cachetime', FF_META_DEFAULT_CACHETIME ) * MINUTE_IN_SECONDS;
set_transient( 'FF_metadata_json_locs', $json_locs, $cachetime );
}
return $json_locs;
}
function output_ff_state( $citydata ) {
if ( isset( $citydata['state'] ) && isset( $citydata['state']['nodes'] ) ) {
return sprintf( '%s', $citydata['state']['nodes'] );
} else {
return '';
}
}
function output_ff_location( $citydata ) {
// normal per-city code
$loc = new FF_Community( $citydata );
$outstr = $loc->format_address();
$json_locs = $this->aux_get_all_locations_json();
if ( ! empty( $loc->name ) && ! empty( $loc->name ) ) {
$icon_url = plugin_dir_url( __FILE__ ) . 'freifunk_marker.png';
$loccity = $loc->city;
$outstr .= <<
EOT;
}
return $outstr;
}
function output_ff_services( $citydata ) {
if ( ! isset( $citydata['services'] ) ) {
return '';
}
$services = $citydata['services'];
$outstr = 'Dienst Beschreibung Freifunk URI Internet URI ';
foreach ( $services as $service ) {
$internalUri = isset($service['internalUri']) ? $service['internalUri'] : '';
$externalUri = isset($service['externalUri']) ? $service['externalUri'] : '';
$outstr .= sprintf(
'%s %s %s %s ',
$service['serviceName'], $service['serviceDescription'],
$internalUri, $internalUri,
$externalUri, $externalUri
);
}
$outstr .= '
';
return $outstr;
}
function output_ff_contact( $citydata ) {
if ( ! isset( $citydata['contact'] ) ) {
return '';
}
$contact = $citydata['contact'];
$outstr = '';
// Output -- rather ugly but the data is not uniform,
// some fields are URIs, some are usernames, ...
if ( ! empty( $contact['email'] ) ) {
$outstr .= sprintf(
'E-Mail: %s ',
$contact['email'], $contact['email']
);
}
if ( ! empty( $contact['ml'] ) ) {
$outstr .= sprintf(
'Mailingliste: %s ',
$contact['ml'], $contact['ml']
);
}
if ( ! empty( $contact['irc'] ) ) {
$outstr .= sprintf(
'IRC: %s ',
$contact['irc'], $contact['irc']
);
}
if ( ! empty( $contact['twitter'] ) ) {
// catch username instead of URI
if ( $contact['twitter'][0] === '@' ) {
$twitter_url = 'http://twitter.com/' . ltrim( $contact['twitter'], '@' );
$twitter_handle = $contact['twitter'];
} else {
$twitter_url = $contact['twitter'];
$twitter_handle = '@' . substr(
$contact['twitter'], strrpos( $contact['twitter'], '/' ) + 1
);
}
$outstr .= sprintf(
'Twitter: %s ',
$twitter_url, $twitter_handle
);
}
if ( ! empty( $contact['facebook'] ) ) {
$outstr .= sprintf(
'Facebook: %s ',
$contact['facebook'], $contact['facebook']
);
}
if ( ! empty( $contact['googleplus'] ) ) {
$outstr .= sprintf(
'G+: %s ',
$contact['googleplus'], $contact['googleplus']
);
}
if ( ! empty( $contact['jabber'] ) ) {
$outstr .= sprintf(
'XMPP: %s ',
$contact['jabber'], $contact['jabber']
);
}
$outstr .= '
';
return $outstr;
}
function output_ff_list() {
$comm_list = $this->dir->get_all_data();
$outstr = '';
$outstr .= 'Name Stadt Knoten ';
foreach ( $comm_list as $handle => $entry ) {
$outstr .= sprintf(
'%s %s %s ',
esc_url( $entry['url'] ),
isset( $entry['name'] ) ? esc_html( $entry['name'] ) : esc_html($handle),
isset( $entry['location']['city'] ) ? esc_html( $entry['location']['city'] ) : 'n/a',
isset( $entry['state']['nodes'] ) ? esc_html( $entry['state']['nodes'] ) : 'n/a'
);
}
$outstr .= '
';
return $outstr;
}
function shortcode_handler( $atts, $content, $shortcode ) {
// $atts[0] holds the city name, if given
if ( empty( $atts[0] ) ) {
$city = get_option( 'FF_meta_city', FF_META_DEFAULT_CITY );
} else {
$city = $atts[0];
}
if ( false === ( $cityurl = $this->dir->get_url_by_city( $city ) ) ) {
return "\n";
}
$ed = new FF_Meta_Externaldata();
if ( false === ( $metadata = $this->ed->get( $cityurl ) ) ) {
return "\n";
}
$outstr = "";
switch ( $shortcode ) {
case 'ff_state':
$outstr .= $this->output_ff_state( $metadata );
break;
case 'ff_location':
$outstr .= $this->output_ff_location( $metadata );
break;
case 'ff_services':
$outstr .= $this->output_ff_services( $metadata );
break;
case 'ff_contact':
$outstr .= $this->output_ff_contact( $metadata );
break;
case 'ff_list':
$outstr .= $this->output_ff_list();
break;
default:
$outstr .= '';
break;
}
$outstr .= '
';
return $outstr;
}
function admin_menu() {
// Options Page:
add_options_page(
'FF Meta Plugin', // page title
'FF Meta', // menu title
'manage_options', // req'd capability
'ff_meta_plugin', // menu slug
array( 'FF_meta', 'options_page' ) // callback function
);
}
function admin_init() {
register_setting(
'ff_meta_settings-group', // group name
'ff_meta_cachetime' // option name
);
register_setting(
'ff_meta_settings-group', // group name
'ff_meta_city' // option name
);
add_settings_section(
'ff_meta_section-one', // ID
'Section One', // Title
array( 'FF_Meta', 'section_one_callback' ), // callback to fill
'ff_meta_plugin' // page to display on
);
add_settings_field(
'ff_meta_city', // ID
'Default community', // Title
array( 'FF_Meta', 'city_callback' ), // callback to fill field
'ff_meta_plugin', // menu page=slug to display field on
'ff_meta_section-one', // section to display the field in
array( 'label_for' => 'ff_meta_city_id' ) // ID of input element
);
add_settings_field(
'ff_meta_cachetime', // ID
'Cache time', // Title
array( 'FF_Meta', 'cachetime_callback' ), // callback to fill field
'ff_meta_plugin', // menu page=slug to display field on
'ff_meta_section-one', // section to display the field in
array( 'label_for' => 'ff_meta_cachetime_id' ) // ID of input element
);
}
function section_one_callback() {
echo 'This Plugin provides shortcodes to display information'
.' from the Freifunk meta.json.';
}
function cachetime_callback() {
$time = get_option( 'ff_meta_cachetime', FF_META_DEFAULT_CACHETIME );
echo ' Data from external URLs is cached'
.' for this number of minutes.';
}
function city_callback() {
$ed = new FF_Meta_Externaldata();
if ( false === ( $directory = $this->ed->get( FF_META_DEFAULT_DIR ) ) ) {
// TODO: error handling
return;
}
$default_city = get_option( 'ff_meta_city', FF_META_DEFAULT_CITY );
echo "";
foreach ( array_keys( $directory ) as $city ) {
$prettycity = ucwords( str_replace( array( '_', '-' ), ' ', $city ) );
$selected = selected( $default_city, $city );
printf(
'%s ',
esc_attr( $city ), $selected, esc_str( $prettycity )
);
}
echo ' ';
echo 'This is the default city parameter.
';
}
function options_page() {
?>
Freifunk Meta Plugin Options
register_stuff();
$GLOBALS['wp-plugin-ffmeta'] = $ffmeta;