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 = ''; foreach ( $services as $service ) { $outstr .= sprintf( '', $service['serviceName'], $service['serviceDescription'], $service['internalUri'], $service['internalUri'], $service['externalUri']?:'#', $service['externalUri']?:'' ); } $outstr .= '
DienstBeschreibungFreifunk URIInternet URI
%s%s%s%s
'; 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 .= ''; foreach ( $comm_list as $handle => $entry ) { $outstr .= sprintf( '', 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 .= '
NameStadtKnoten
%s%s%s
'; 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 "'; echo '

This is the default city parameter.

'; } function options_page() { ?>

Freifunk Meta Plugin Options

register_stuff(); $GLOBALS['wp-plugin-ffmeta'] = $ffmeta;