From 8f89abc9ed6bf4bcf65c0d9c996f69188a75ced2 Mon Sep 17 00:00:00 2001 From: Martin Schuette Date: Fri, 4 Apr 2014 22:53:21 +0000 Subject: [PATCH 01/37] add uninstall_hook --- freifunkmeta.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/freifunkmeta.php b/freifunkmeta.php index fe65de6..228e9f4 100644 --- a/freifunkmeta.php +++ b/freifunkmeta.php @@ -209,3 +209,8 @@ function ff_meta_options_page() { Date: Sun, 6 Apr 2014 15:06:40 +0000 Subject: [PATCH 02/37] start writing ff_location --- freifunk_marker.png | Bin 0 -> 522 bytes freifunkmeta.php | 91 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 freifunk_marker.png diff --git a/freifunk_marker.png b/freifunk_marker.png new file mode 100644 index 0000000000000000000000000000000000000000..279c9620b4a6aa36fc3f0cc6a8f3a1402c9b9dfd GIT binary patch literal 522 zcmeAS@N?(olHy`uVBq!ia0y~yU=U$oU=ZM7V_;wqlZcmQU|?WN@^*J&_z!{$_AZ~y zz`(#+;1OBOz`!jG!i)^F=14FwFs|}+aSX9I-FxM{cSxYbv5)6>8ZY)sXyb8pbh@ae z#g(1>G|G!J>dW#i8Nz?rbAPGda#2y-dMQd|3Ttxr68QyzDoHn-X3w<#zNJ9tSoQ3e zt>5#`RquaZIj{H~FPE0vox_ETjf68w`8_s>rR}-*JI|7Rw?D^`U7Pshyyi?OIrt;> z@`lN-Nlpt7vA2B)yg6}QXUCQD(B+4we646N*ggM{yW7^ifw!2OudH$uPCQjLN7?7; zQ5Avt)x9puDar&T?on(<>%*WOwiIyJ|3VJQ__w#z6>U)-;yRvKcBHx*l>aPbi zSY*3g-qh86bYy7t8&Sxs$8(UmMOm zwIu0$pH{ukvC2-~{Hb%^?K)w-VH@Limu%PYwZfhk0{(N)alLA1ud5+>zE)OOn=O_r zeC@Ywdv+f**_I=1wsP&gRQrSjGnO5-crI}yy|zIh&1HUW=dq>Jif2x{niJW>o%OKj zc&NUDgksF~q7#xc%eP&8Q6fB(d0$lL=5uW?Z4ATrq|y^t%s
%s %s', + $loc_name, $loc_street, $loc_zip, $loc_city); + $outstr .= '

'; + + // gather all location data + if ( false === ( $json_locs = get_transient( "ff_metadata_json_locs" ) ) ) { + $all_locs = array(); + $arr_select = array('lat' => 1, 'lon' => 1); + foreach ($directory as $tmp_city => $url) { + try { + $tmp_meta = ff_meta_getmetadata($url); + if (!empty($tmp_meta['location'])) { + $tmp_loc = array_intersect_key($tmp_meta['location'], $arr_select); + $all_locs[$tmp_city] = $tmp_loc; + } + } catch (Exception $e) { + // pass + } + } + $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 ); + } + + if ( !empty($loc_name) && !empty($loc_name) ) { + $icon_url = plugin_dir_url(__FILE__) . "freifunk_marker.png"; + $outstr .= << + + + + + +EOT; + } + break; + case 'ff_services': $outstr .= '
    '; if (isset($metadata['services'])) { From dcda5cb9dafaf9f39719b1a43a4f2f768da97b11 Mon Sep 17 00:00:00 2001 From: Martin Schuette Date: Sun, 6 Apr 2014 15:09:20 +0000 Subject: [PATCH 03/37] update --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d7a6d5b..f063f7f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,9 @@ A small Wordpress plugin to render Freifunk metadata according to the [api.freif It reads (and caches) JSON input from a configured URL and provides shortcodes to output the data. -Currently implemented are `[ff_services]` and `[ff_contact]`. +Currently implemented are `[ff_services]`, `[ff_contact]`, and `[ff_state]`. + +An `[ff_location]` is also usable, but needs more work. ## Example From 14d592f2ec8574c458833cb1f2bbcec05046df02 Mon Sep 17 00:00:00 2001 From: "info@mschuette.name" Date: Tue, 8 Apr 2014 13:08:03 +0000 Subject: [PATCH 04/37] link ff_location screenshot --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index f063f7f..951b4ea 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ An `[ff_location]` is also usable, but needs more work. Text: + Location: + + [ff_location] + Services: [ff_services] @@ -26,4 +30,7 @@ Text: Output: +![ff_location output example])(http://mschuette.name/wp/wp-upload/freifunk_meta_location_sample.png) + ![shortcode output example](http://mschuette.name/wp/wp-upload/freifunk_meta_example.png) + From 94c6027fa326ee059be66faf8f8faebe98a81115 Mon Sep 17 00:00:00 2001 From: "info@mschuette.name" Date: Tue, 8 Apr 2014 13:08:48 +0000 Subject: [PATCH 05/37] fix typo, ff_location screenshot --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 951b4ea..de2ee9b 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Text: Output: -![ff_location output example])(http://mschuette.name/wp/wp-upload/freifunk_meta_location_sample.png) +![_location output example](http://mschuette.name/wp/wp-upload/freifunk_meta_location_sample.png) ![shortcode output example](http://mschuette.name/wp/wp-upload/freifunk_meta_example.png) From 5d5f3d07eb0b40af78ed3a9da2b3b3bf51246a24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sch=C3=BCtte?= Date: Mon, 19 May 2014 19:16:38 +0200 Subject: [PATCH 06/37] refactor all functions into classes + methods --- freifunkmeta.php | 548 +++++++++++++++++++++++++++-------------------- 1 file changed, 320 insertions(+), 228 deletions(-) diff --git a/freifunkmeta.php b/freifunkmeta.php index ece7799..76a8bc2 100644 --- a/freifunkmeta.php +++ b/freifunkmeta.php @@ -1,9 +1,9 @@ directory = FF_Meta_Externaldata::get(FF_META_DEFAULT_DIR); } - if (false === ($directory = ff_meta_getmetadata ( FF_META_DEFAULT_DIR )) - || empty($directory[$city])) { - return "\n"; - } - $url = $directory[$city]; + function get_url_by_city($city) { + $val = $this->directory[$city]; - if (false === ($metadata = ff_meta_getmetadata ($url))) { - return "\n"; + if (empty($val)) { + return false; + } else { + return $val; + } + } +} + +/** + * 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'] : ''; } - $outstr = "
    "; - switch ($name) { - case 'ff_state': - $state = $metadata['state']; - $outstr .= sprintf('%s', $state['nodes']); - break; + /** + * Alternative constructor from city name + */ + static function make_from_city($city) { + // TODO: test + if (false === ($url = $this->dir->get_url_by_city($city))) { + return "\n"; + } + if (false === ($metadata = FF_Meta_Externaldata::get($url))) { + return "\n"; + } + return new FF_Community($metadata); + } - case 'ff_location': - // normal per-city code - $loc = $metadata['location']; - $loc_name = (isset($loc['address']) && isset($loc['address']['Name'])) ? $loc['address']['Name'] : ''; - $loc_street = (isset($loc['address']) && isset($loc['address']['Street'])) ? $loc['address']['Street'] : ''; - $loc_zip = (isset($loc['address']) && isset($loc['address']['Zipcode'])) ? $loc['address']['Zipcode'] : ''; - $loc_city = isset($loc['city']) ? $loc['city'] : ''; - $loc_lon = isset($loc['lon']) ? $loc['lon'] : ''; - $loc_lat = isset($loc['lat']) ? $loc['lat'] : ''; - if (empty($loc_name) || empty($loc_street) || empty($loc_zip)) { - return ''; - } + 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) . '

    '; + } +} - // 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) - $outstr .= '

    '; - $outstr .= sprintf('%s
    %s
    %s %s', - $loc_name, $loc_street, $loc_zip, $loc_city); - $outstr .= '

    '; +/** + * main class for whole plugin + */ +class FF_Meta +{ + private $dir; - // gather all location data - if ( false === ( $json_locs = get_transient( "ff_metadata_json_locs" ) ) ) { - $all_locs = array(); - $arr_select = array('lat' => 1, 'lon' => 1); - foreach ($directory as $tmp_city => $url) { - try { - $tmp_meta = ff_meta_getmetadata($url); - if (!empty($tmp_meta['location'])) { - $tmp_loc = array_intersect_key($tmp_meta['location'], $arr_select); - $all_locs[$tmp_city] = $tmp_loc; - } - } catch (Exception $e) { - // pass + function __construct() { + $this->dir = new FF_Directory(); + } + + 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')); + } + + 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')); + } + + function output_ff_state($citydata) { + $state = $citydata['state']; + return sprintf('%s', $state['nodes']); + } + + function aux_get_all_locations() { + // gather all location data + if (false === ( $json_locs = get_transient("FF_metadata_json_locs") )) { + $all_locs = array(); + $arr_select = array('lat' => 1, 'lon' => 1); + foreach ($this->dir as $tmp_city => $url) { + try { + $tmp_meta = FF_Meta_Externaldata::get($url); + if (!empty($tmp_meta['location'])) { + $tmp_loc = array_intersect_key($tmp_meta['location'], $arr_select); + $all_locs[$tmp_city] = $tmp_loc; } + } catch (Exception $e) { + // pass } - $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 ); } + $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; + } - if ( !empty($loc_name) && !empty($loc_name) ) { - $icon_url = plugin_dir_url(__FILE__) . "freifunk_marker.png"; - $outstr .= <<format_address(); + $json_locs = $this->aux_get_all_locations(); + + if (!empty($loc_name) && !empty($loc_name)) { + $icon_url = plugin_dir_url(__FILE__) . "freifunk_marker.png"; + $outstr .= <<
    - + EOT; - } - return $outstr; - } + } + return $outstr; + } - function output_ff_services($citydata) { - $outstr = '
      '; - if (isset($citydata['services'])) { - $services = $citydata['services']; - foreach ($services as $service) { - $outstr .= sprintf('
    • %s (%s): %s
    • ', $service['serviceName'], $service['serviceDescription'], $service['internalUri'], $service['internalUri']); - } - } - $outstr .= '
    '; - return $outstr; - } + function output_ff_services( $citydata ) { + $outstr = '
      '; + if ( isset( $citydata['services'] ) ) { + $services = $citydata['services']; + foreach ( $services as $service ) { + $outstr .= sprintf( '
    • %s (%s ): %s
    • ', $service['serviceName'], $service['serviceDescription'], $service['internalUri'], $service['internalUri'] ); + } + } + $outstr .= '
    '; + return $outstr; + } - function output_ff_contact($citydata) { - $outstr = '

    '; - $contact = $citydata['contact']; - // 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
    \n", $contact['email'], $contact['email']); - } - if (!empty($contact['ml'])) { - $outstr .= sprintf("Mailingliste: %s
    \n", $contact['ml'], $contact['ml']); - } - if (!empty($contact['irc'])) { - $outstr .= sprintf("IRC: %s
    \n", $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
    \n", $twitter_url, $twitter_handle); - } - if (!empty($contact['facebook'])) { - $outstr .= sprintf("Facebook: %s
    \n", $contact['facebook'], $contact['facebook']); - } - if (!empty($contact['googleplus'])) { - $outstr .= sprintf("G+: %s
    \n", $contact['googleplus'], $contact['googleplus']); - } - if (!empty($contact['jabber'])) { - $outstr .= sprintf("XMPP: %s
    \n", $contact['jabber'], $contact['jabber']); - } - $outstr .= '

    '; - return $outstr; - } + function output_ff_contact( $citydata ) { + $outstr = '

    '; + $contact = $citydata['contact']; + // 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
    \n", $contact['email'], $contact['email'] ); + } + if ( ! empty( $contact['ml'] ) ) { + $outstr .= sprintf( "Mailingliste: %s
    \n", $contact['ml'], $contact['ml'] ); + } + if ( ! empty( $contact['irc'] ) ) { + $outstr .= sprintf( "IRC: %s
    \n", $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
    \n", $twitter_url, $twitter_handle ); + } + if ( ! empty( $contact['facebook'] ) ) { + $outstr .= sprintf( "Facebook: %s
    \n", $contact['facebook'], $contact['facebook'] ); + } + if ( ! empty( $contact['googleplus'] ) ) { + $outstr .= sprintf( "G+: %s
    \n", $contact['googleplus'], $contact['googleplus'] ); + } + if ( ! empty( $contact['jabber'] ) ) { + $outstr .= sprintf( "XMPP: %s
    \n", $contact['jabber'], $contact['jabber'] ); + } + $outstr .= '

    '; + return $outstr; + } - function output_ff_list() { - return 'here be some ff_list'; - } - - 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]; - } + function output_ff_list() { + return 'here be some ff_list'; + } + + 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"; - } + if ( false === ( $cityurl = $this->dir->get_url_by_city( $city ) ) ) { + return "\n"; + } - if (false === ($metadata = FF_Meta_Externaldata::get($cityurl))) { - return "\n"; - } + if ( false === ( $metadata = FF_Meta_Externaldata::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; - } + $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_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 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 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 " minutes" - ."

    Data from external URLs is cached for this number of minutes.

    "; - } + function cachetime_callback() { + $time = get_option( 'ff_meta_cachetime', FF_META_DEFAULT_CACHETIME ); + echo " minutes'. + "

    Data from external URLs is cached for this number of minutes.

    "; + } - function city_callback() { - if (false === ($directory = FF_Meta_Externaldata::get ( FF_META_DEFAULT_DIR ))) { - // TODO: error handling - return; - } - $default_city = get_option( 'ff_meta_city', FF_META_DEFAULT_CITY ); + function city_callback() { + if ( false === ( $directory = FF_Meta_Externaldata::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.

    "; - } + echo "'; + echo "

    This is the default city parameter.

    "; + } - function options_page() { - ?> -
    -

    Freifunk Meta Plugin Options

    -
    - - - -
    -
    - +
    +

    Freifunk Meta Plugin Options

    +
    + + + +
    +
    + Date: Mon, 16 Jun 2014 14:13:12 +0000 Subject: [PATCH 22/37] some more code formatting, also add FF_Meta_Externaldata as service to FF_Dir and FF_Meta --- freifunkmeta.php | 270 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 183 insertions(+), 87 deletions(-) diff --git a/freifunkmeta.php b/freifunkmeta.php index d064b74..b7995bc 100644 --- a/freifunkmeta.php +++ b/freifunkmeta.php @@ -14,20 +14,34 @@ define( 'FF_META_DEFAULT_CITY', 'hamburg' ); /** * class to fetch and cache data from external URLs + * returns either an array from decoded JSON data, or WP_Error */ class FF_Meta_Externaldata { public function get( $url ) { - /* gets metadata from URL, handles caching */ + //error_log( "FF_Meta_Externaldata::get( $url )" ); + /* gets metadata from URL, handles caching, + * hashed because cache keys should be <= 40 chars */ $cachekey = 'ff_metadata_'.hash( 'crc32', $url ); - $cachetime = get_option( 'ff_meta_cachetime', FF_META_DEFAULT_CACHETIME ) * MINUTE_IN_SECONDS; + $cachetime = get_option( + 'ff_meta_cachetime', FF_META_DEFAULT_CACHETIME + ) * MINUTE_IN_SECONDS; // Caching - if ( false === ( $data = get_transient( $cachekey ) ) ) { + if ( WP_DEBUG || ( false === ( $data = get_transient( $cachekey ) ) ) ) { $http_response = wp_remote_get( $url ); - $json = wp_remote_retrieve_body( $http_response ); - $data = json_decode( $json, $assoc = true ); - set_transient( $cachekey, $data, $cachetime ); + 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; } @@ -40,18 +54,25 @@ class FF_Directory { private $directory; - function __construct() { - $ed = new FF_Meta_Externaldata(); - $this->directory = $ed->get( FF_META_DEFAULT_DIR ); + function __construct( $ext_data_service = null ) { + if ( is_null( $ext_data_service ) ) { + $ed = new FF_Meta_Externaldata(); + } else { + $ed = $ext_data_service; + } + $data = $ed->get( FF_META_DEFAULT_DIR ); + if ( is_wp_error( $data ) ) { + $this->directory = array(); + } else { + $this->directory = $data; + } } function get_url_by_city( $city ) { - $val = $this->directory[$city]; - - if ( empty( $val ) ) { - return false; + if ( array_key_exists( $city, $this->directory ) ) { + return $this->directory[$city]; } else { - return $val; + return false; } } } @@ -73,9 +94,12 @@ class FF_Community */ 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->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'] : ''; @@ -84,12 +108,19 @@ class FF_Community /** * Alternative constructor from city name */ - static function make_from_city( $city ) { - // TODO: test - if ( false === ( $url = $this->dir->get_url_by_city( $city ) ) ) { - return "\n"; + 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; } - if ( false === ( $metadata = FF_Meta_Externaldata::get( $url ) ) ) { + $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 ); @@ -100,9 +131,13 @@ class FF_Community 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: 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 ) . '

    '; + return sprintf( + '

    %s
    %s
    %s %s

    ', + $this->name, $this->street, $this->zip, $this->city + ); } } @@ -112,9 +147,24 @@ class FF_Community class FF_Meta { private $dir; + private $ed; - function __construct() { - $this->dir = new FF_Directory(); + 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() { @@ -137,18 +187,21 @@ class FF_Meta } function output_ff_state( $citydata ) { - $state = $citydata['state']; - return sprintf( '%s', $state['nodes'] ); + if ( isset( $citydata['state'] ) && isset( $citydata['state']['nodes'] ) ) { + return sprintf( '%s', $citydata['state']['nodes'] ); + } else { + return ''; + } } function aux_get_all_locations() { // gather all location data - if ( false === ( $json_locs = get_transient( 'FF_metadata_json_locs' ) ) ) { + if ( WP_DEBUG || ( false === ( $json_locs = get_transient( 'FF_metadata_json_locs' ) ) ) ) { $all_locs = array(); $arr_select = array( 'lat' => 1, 'lon' => 1 ); foreach ( $this->dir as $tmp_city => $url ) { try { - $tmp_meta = FF_Meta_Externaldata::get( $url ); + $tmp_meta = $this->ed->get( $url ); if ( ! empty( $tmp_meta['location'] ) ) { $tmp_loc = array_intersect_key( $tmp_meta['location'], $arr_select ); $all_locs[$tmp_city] = $tmp_loc; @@ -170,42 +223,44 @@ class FF_Meta $outstr = $loc->format_address(); $json_locs = $this->aux_get_all_locations(); - if ( ! empty( $loc_name ) && ! empty( $loc_name ) ) { + if ( ! empty( $loc->name ) && ! empty( $loc->name ) ) { $icon_url = plugin_dir_url( __FILE__ ) . 'freifunk_marker.png'; + $loccity = $loc->city; $outstr .= << +