Created
January 8, 2011 01:11
-
-
Save mfields/770404 to your computer and use it in GitHub Desktop.
WordPress Taxonomy Map Plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Plugin Name: Taxonomy Map | |
Plugin URI: http://wordpress.mfields.org/plugins/taxonomy-images/ | |
Description: Use a hierarchical taxonomy system to display Goole map. | |
Version: 0.1 | |
Author: Michael Fields | |
Author URI: http://wordpress.mfields.org/ | |
License: GPLv2 | |
Copyright 2010 Michael Fields michael@mfields.org | |
This program is free software; you can redistribute it and/or modify | |
it under the terms of the GNU General Public License version 2 as published by | |
the Free Software Foundation. | |
This program is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
You should have received a copy of the GNU General Public License | |
along with this program; if not, write to the Free Software | |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
*/ | |
define( 'TAXONOMY_MAP_URI', plugin_dir_url( __FILE__ ) ); | |
define( 'TAXONOMY_MAP_VERSION', '0.1' ); | |
define( 'TAXONOMY_MAP_TAXONOMY', 'location' ); | |
$taxonomy_map = array(); | |
/** | |
* Default settings. | |
* @global array $taxonomy_map_settings_default | |
* @see http://code.google.com/apis/maps/documentation/javascript/reference.html#MapOptions | |
* @since 2010-09-10 | |
*/ | |
$taxonomy_map_settings_default = array( | |
'zoom' => 17, /* int */ | |
'scrollwheel' => false, /* bool */ | |
); | |
function taxonomy_map_get( $key ) { | |
global $taxonomy_map; | |
if( isset( $taxonomy_map[$key] ) ) { | |
return $taxonomy_map[$key]; | |
} | |
return null; | |
} | |
function taxonomy_map_set( $key, $value ) { | |
global $taxonomy_map; | |
$taxonomy_map[$key] = $value; | |
} | |
function taxonomy_map_get_setting( $key ) { | |
global $taxonomy_map_settings_default; | |
if( isset( $taxonomy_map_settings_default[$key] ) ) { | |
return $taxonomy_map_settings_default[$key]; | |
} | |
return null; | |
} | |
$taxonomy_map_metabox = new Taxonomy_Checklist( TAXONOMY_MAP_TAXONOMY ); | |
add_action( 'init', 'taxonomy_map_register_taxonomy' ); | |
add_action( 'wp_head', 'taxonomy_map_print_meta_tags' ); | |
add_filter( 'script_loader_src', 'taxonomy_map_filter_google_map_api_uri' ); | |
add_action( 'wp_print_scripts', 'taxonomy_map_js' ); | |
add_action( 'get_header', 'taxonomy_map_set_location' ); | |
add_filter( 'the_content', 'taxonomy_map_append_map_to_content' ); | |
if( !function_exists( 'pr' ) ) { | |
function pr( $var ) { | |
print '<pre>' . print_r( $var, true ) . '</pre>'; | |
} | |
} | |
if( !function_exists( 'taxonomy_map_has_location' ) ) { | |
/** | |
* Should a map be generated for the current view? | |
* @uses $taxonomy_map | |
* @since 2010-07-02 | |
* @return bool true if view is a single resource that has a latitude and longitude; false if not. | |
*/ | |
function taxonomy_map_has_location() { | |
if( is_single() && null !== taxonomy_map_get( 'lat' ) && null !== taxonomy_map_get( 'lng' ) ) { | |
return true; | |
} | |
return false; | |
} | |
} | |
if( !function_exists( 'taxonomy_map_register_taxonomy' ) ) { | |
function taxonomy_map_register_taxonomy() { | |
/** | |
* Registers "Locations" taxonomy | |
* @since 2010-07-02 | |
* @alter 2010-09-10 | |
* @todo Check to see if taxonomy already exists before registering. | |
* @todo Provide a way for users to change the name + labels. | |
*/ | |
register_taxonomy( TAXONOMY_MAP_TAXONOMY, 'post', array( | |
'hierarchical' => true, | |
'label' => 'Locations', | |
'singular' => 'Location', | |
# 'update_count_callback' => $tax['update_count_callback'], | |
) ); | |
} | |
} | |
if( !function_exists( 'taxonomy_map_js' ) ) { | |
/** | |
* Required scripts. | |
* @uses $taxonomy_map | |
* @uses TAXONOMY_MAP_URI | |
* @uses TAXONOMY_MAP_VERSION | |
* @return void | |
* @since 2010-09-09 | |
* @alter 2010-09-09 | |
*/ | |
function taxonomy_map_js() { | |
if( taxonomy_map_has_location() ) { | |
wp_enqueue_script( 'taxonomy-map-api', 'http://maps.google.com/maps/api/js', array(), TAXONOMY_MAP_VERSION ); | |
wp_enqueue_script( 'taxonomy-map', TAXONOMY_MAP_URI . '/taxonomy-map.js', array( 'taxonomy-map-api' ), TAXONOMY_MAP_VERSION ); | |
global $taxonomy_map; | |
wp_localize_script( 'taxonomy-map', 'taxonomyMapPlugin', array ( | |
'location' => taxonomy_map_get( 'location' ), | |
'lat' => taxonomy_map_get( 'lat' ), | |
'lng' => taxonomy_map_get( 'lng' ), | |
'zoom' => taxonomy_map_get_setting( 'zoom' ), | |
'scrollwheel' => taxonomy_map_get_setting( 'scrollwheel' ), | |
) ); | |
} | |
} | |
} | |
if( !function_exists( 'taxonomy_map_filter_google_map_api_uri' ) ) { | |
/** | |
* Add sensor parameter to the url string for Google Maps URI. | |
* @param string | |
* @return string | |
* @since 2010-09-09 | |
* @alter 2010-09-09 | |
*/ | |
function taxonomy_map_filter_google_map_api_uri( $url ) { | |
if ( false === strpos( $url, 'http://maps.google.com/maps/api/js' ) ) { | |
return $url; | |
} | |
list( $url ) = explode( '?', $url ); | |
return $url . '?sensor=false'; | |
} | |
} | |
if( !function_exists( 'taxonomy_map_print_meta_tags' ) ) { | |
/** | |
* Add sensor parameter to the url string for Google Maps URI. | |
* @uses taxonomy_map_has_location() | |
* @return void | |
* @since 2010-09-09 | |
* @alter 2010-09-09 | |
* @todo Remove CSS. | |
*/ | |
function taxonomy_map_print_meta_tags() { | |
if( taxonomy_map_has_location() ) { | |
print '<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />'; | |
print '<style type="text/css">#map_canvas { width:660px; height:450px; }</style>'; | |
} | |
} | |
} | |
if( !function_exists( 'taxonomy_map_find_country' ) ) { | |
function taxonomy_map_find_country( $locations ) { | |
$o = array(); | |
foreach( $locations as $location => $values ) { | |
$values = get_object_vars( $values ); | |
if( $values['parent'] == '0' ) { | |
$o = array( | |
'id' => $values['term_id'], | |
'name' => $values['name'] | |
); | |
} | |
} | |
return $o; | |
} | |
} | |
if( !function_exists( 'taxonomy_map_find_child' ) ) { | |
function taxonomy_map_find_child( $locations, $parent ) { | |
$o = array(); | |
foreach( $locations as $location => $values ) { | |
$values = get_object_vars( $values ); | |
if( $values['parent'] == $parent['id'] ) { | |
$o = array( | |
'id' => $values['term_id'], | |
'name' => $values['name'] | |
); | |
} | |
} | |
return $o; | |
} | |
} | |
if( !function_exists( 'taxonomy_map_append_map_to_content' ) ) { | |
/** | |
* Appends a map to the_content on single templates | |
* where the queried object is associated with a 'location'. | |
* @uses taxonomy_map_has_location() | |
* @return string | |
* @since 2010-07-02 | |
* @alter 2010-09-09 | |
*/ | |
function taxonomy_map_append_map_to_content( $content ) { | |
if( taxonomy_map_has_location() ) { | |
global $post; | |
$terms = wp_get_object_terms( (int) $post->ID, TAXONOMY_MAP_TAXONOMY ); | |
# pr( $terms ); | |
# $uri = get_term_link( , TAXONOMY_MAP_TAXONOMY ); | |
return $content . "\n" . '<div id="map_canvas"></div>'; | |
} | |
return $content; | |
} | |
} | |
// FIX THIS STUFF BELOW!!!! | |
if( !function_exists( 'taxonomy_map_google_map_geocoding_request_url' ) ) { | |
/** | |
* Generate a url to a Google's geocoding service. | |
* @param array | |
* @return string | |
* @since 2010-07-02 | |
* @alter 2010-09-09 | |
*/ | |
function taxonomy_map_google_map_geocoding_request_url( $args ) { | |
$url = 'http://maps.google.com/maps/api/geocode/json'; | |
$defaults = array( 'sensor' => 'false', 'filter' => 'display' ); | |
$query = ''; | |
$count = 1; | |
$args = array_merge( $defaults, $args ); | |
$amp = ( $args['filter'] === 'display' ) ? '&' : '&'; | |
foreach( $args as $key => $value ) { | |
$key = urlencode( $key ); | |
$value = urlencode( $value ); | |
$query.= ( $count === 1 ) ? '?' : $amp; | |
$query.= $key . '=' . $value; | |
$count++; | |
} | |
if( !empty( $query ) ) { | |
return $url . $query; | |
} | |
return ''; | |
} | |
} | |
if( !function_exists( 'taxonomy_map_get_location_coords' ) ) { | |
function taxonomy_map_get_location_coords( $location_name ) { | |
global $taxonomy_map; | |
$options = get_option( 'taxonomy_map_coords' ); | |
if( !empty( $location_name ) ) { | |
$taxonomy_map['location']['name'] = $location_name; | |
/* Look in setttings. */ | |
if( is_array( $options ) ) { | |
$key = sanitize_title_with_dashes( $location_name ); | |
if( array_key_exists( $key, $options ) ) { | |
return $options[$key]; | |
} | |
} | |
/* Get coords from Google */ | |
$url = taxonomy_map_google_map_geocoding_request_url( array( | |
'address' => $taxonomy_map['location']['name'], | |
'filter' => 'entity' | |
) ); | |
$file = file_get_contents( $url ); | |
if( $file !== false ) | |
$json = taxonomy_map_google_map_geocoding_parse_json( $file ); | |
if( is_array( $json ) ) { | |
$key = sanitize_title_with_dashes( $location_name ); | |
$options[$key] = $json; | |
update_option( 'taxonomy_map_coords', $options ); | |
return $json; | |
} | |
} | |
return array(); | |
} | |
} | |
if( !function_exists( 'taxonomy_map_set_location' ) ) { | |
function taxonomy_map_set_location() { | |
global $post; | |
$location_name = taxonomy_map_get_location_name( $post ); | |
if( !empty( $location_name ) ) { | |
taxonomy_map_set( 'location', $location_name ); | |
$options = get_option( 'taxonomy_map_coords' ); | |
/* Look in setttings. */ | |
if( is_array( $options ) ) { | |
$key = sanitize_title_with_dashes( $location_name ); | |
if( array_key_exists( $key, $options ) ) { | |
taxonomy_map_set( 'lat', $options[$key][0] ); | |
taxonomy_map_set( 'lng', $options[$key][1] ); | |
return; | |
} | |
} | |
$url = taxonomy_map_google_map_geocoding_request_url( array( | |
'address' => taxonomy_map_get( 'location' ), | |
'filter' => 'entity' | |
) ); | |
$file = file_get_contents( $url ); | |
if( $file !== false ) { | |
$json = taxonomy_map_google_map_geocoding_parse_json( $file ); | |
} | |
if( is_array( $json ) ) { | |
$key = sanitize_title_with_dashes( $location_name ); | |
$options[$key] = $json; | |
update_option( 'taxonomy_map_coords', $options ); | |
taxonomy_map_set( 'lat', $json[0]); | |
taxonomy_map_set( 'lng', $json[1] ); | |
} | |
} | |
} | |
} | |
if( !function_exists( 'taxonomy_map_google_map_geocoding_parse_json' ) ) { | |
function taxonomy_map_google_map_geocoding_parse_json( $file ) { | |
$responses = array( | |
'OK', /* At least one geocode was returned. */ | |
'ZERO_RESULTS', /* Geocode was successful but returned no results. */ | |
'OVER_QUERY_LIMIT', /* Over quota. */ | |
'REQUEST_DENIED', /* Request was denied, generally because of lack of a sensor parameter. */ | |
'INVALID_REQUEST' /* Generally indicates that the query (address or latlng) is missing. */ | |
); | |
$defaults = array( 'status' => null, 'results' => array() ); | |
$json = json_decode( $file, true ); | |
if( !is_array( $json ) ) { | |
return false; | |
} | |
$json = array_merge( $defaults, $json ); | |
if( $json['status'] !== $responses[0] ) { | |
return false; | |
} | |
if( empty( $json['results'] ) ) { | |
return false; | |
} | |
return array( | |
$json['results'][0]['geometry']['location']['lat'], | |
$json['results'][0]['geometry']['location']['lng'] | |
); | |
} | |
} | |
/** | |
* Force a taxonomy meta box to retain term hierarchy. | |
* Derived from: http://scribu.net/wordpress/category-checklist-tree | |
* @author Michael Fields http://wordpress.mfields.org/ | |
* @author Scribu http://scribu.net | |
* | |
* @since 2009-11-01 | |
* @alter 2010-09-10 | |
* | |
* 2010-09-09 | |
* - Changed name of class. | |
* - Added $taxonomy_slug property. | |
* - Obsesive compulsive syntax modifications. | |
* - Allowed class to be used for any registered taxonomy. | |
* - Replaced meta_box() with code post_categories_meta_box() from WordPress v3.0.1. | |
*/ | |
class Taxonomy_Checklist { | |
public $taxonomy_slug = null; | |
public function __construct( $taxonomy_slug = 'category' ) { | |
$this->taxonomy_slug = $taxonomy_slug; | |
add_action( '_admin_menu', array( $this, 'get_taxonomy' ), 100 ); | |
} | |
public function get_taxonomy() { | |
$taxonomy = get_taxonomy( $this->taxonomy_slug ); | |
if( $taxonomy ) { | |
$this->taxonomy = $taxonomy; | |
add_action( 'admin_menu', array( $this, 'replace_box' ), 100 ); | |
} | |
} | |
public function replace_box() { | |
$div = $this->taxonomy->name . 'div'; | |
remove_meta_box( $div, 'post', 'normal' ); | |
add_meta_box( $div, __( 'Location' ), array( $this, 'meta_box' ), 'post', 'side', 'high' ); | |
} | |
public function meta_box( $post ) { | |
$tax = $this->taxonomy; | |
$taxonomy = $this->taxonomy_slug; | |
?> | |
<div id="taxonomy-<?php echo $taxonomy; ?>" class="categorydiv"> | |
<ul id="<?php echo $taxonomy; ?>-tabs" class="category-tabs"> | |
<li class="tabs"><a href="#<?php echo $taxonomy; ?>-all" tabindex="3"><?php echo $tax->labels->all_items; ?></a></li> | |
<li class="hide-if-no-js"><a href="#<?php echo $taxonomy; ?>-pop" tabindex="3"><?php _e( 'Most Used' ); ?></a></li> | |
</ul> | |
<div id="<?php echo $taxonomy; ?>-pop" class="tabs-panel" style="display: none;"> | |
<ul id="<?php echo $taxonomy; ?>checklist-pop" class="categorychecklist form-no-clear" > | |
<?php $popular_ids = wp_popular_terms_checklist($taxonomy); ?> | |
</ul> | |
</div> | |
<div id="<?php echo $taxonomy; ?>-all" class="tabs-panel"> | |
<?php | |
$name = ( $taxonomy == 'category' ) ? 'post_category' : 'tax_input[' . $taxonomy . ']'; | |
echo "<input type='hidden' name='{$name}[]' value='0' />"; // Allows for an empty term set to be sent. 0 is an invalid Term ID and will be ignored by empty() checks. | |
?> | |
<ul id="<?php echo $taxonomy; ?>checklist" class="list:<?php echo $taxonomy?> categorychecklist form-no-clear"> | |
<?php | |
wp_terms_checklist($post->ID, array( | |
'taxonomy' => $taxonomy, | |
'popular_cats' => $popular_ids, | |
'checked_ontop' => false, | |
) | |
); ?> | |
</ul> | |
</div> | |
<?php if ( !current_user_can($tax->cap->assign_terms) ) : ?> | |
<p><em><?php _e('You cannot modify this taxonomy.'); ?></em></p> | |
<?php endif; ?> | |
<?php if ( current_user_can($tax->cap->edit_terms) ) : ?> | |
<div id="<?php echo $taxonomy; ?>-adder" class="wp-hidden-children"> | |
<h4> | |
<a id="<?php echo $taxonomy; ?>-add-toggle" href="#<?php echo $taxonomy; ?>-add" class="hide-if-no-js" tabindex="3"> | |
<?php | |
/* translators: %s: add new taxonomy label */ | |
printf( __( '+ %s' ), $tax->labels->add_new_item ); | |
?> | |
</a> | |
</h4> | |
<p id="<?php echo $taxonomy; ?>-add" class="category-add wp-hidden-child"> | |
<label class="screen-reader-text" for="new<?php echo $taxonomy; ?>"><?php echo $tax->labels->add_new_item; ?></label> | |
<input type="text" name="new<?php echo $taxonomy; ?>" id="new<?php echo $taxonomy; ?>" class="form-required form-input-tip" value="<?php echo esc_attr( $tax->labels->new_item_name ); ?>" tabindex="3" aria-required="true"/> | |
<label class="screen-reader-text" for="new<?php echo $taxonomy; ?>_parent"> | |
<?php echo $tax->labels->parent_item_colon; ?> | |
</label> | |
<?php wp_dropdown_categories( array( 'taxonomy' => $taxonomy, 'hide_empty' => 0, 'name' => 'new'.$taxonomy.'_parent', 'orderby' => 'name', 'hierarchical' => 1, 'show_option_none' => '— ' . $tax->labels->parent_item . ' —', 'tab_index' => 3 ) ); ?> | |
<input type="button" id="<?php echo $taxonomy; ?>-add-submit" class="add:<?php echo $taxonomy ?>checklist:<?php echo $taxonomy ?>-add button category-add-sumbit" value="<?php echo esc_attr( $tax->labels->add_new_item ); ?>" tabindex="3" /> | |
<?php wp_nonce_field( 'add-'.$taxonomy, '_ajax_nonce-add-'.$taxonomy, false ); ?> | |
<span id="<?php echo $taxonomy; ?>-ajax-response"></span> | |
</p> | |
</div> | |
<?php endif; ?> | |
</div> | |
<?php | |
} | |
} | |
if( !function_exists( 'taxonomy_map_get_location_name' ) ) { | |
/** | |
* | |
* @uses TAXONOMY_MAP_TAXONOMY | |
* @uses taxonomy_map_get_term_parents() | |
* return mixed string location on siccess false on failure. | |
* @since 2010-07-02 | |
* @since 2010-09-10 | |
* @todo add_support for multiple locations. | |
*/ | |
function taxonomy_map_get_location_name( $post ) { | |
$locations = get_the_terms( $post->ID, TAXONOMY_MAP_TAXONOMY ); | |
$locations = array_values( (array) $locations ); /* Rey key the array */ | |
if( isset( $locations[0]->term_id ) ) { | |
return taxonomy_map_get_term_parents( (int) $locations[0]->term_id ); | |
} | |
return false; | |
} | |
} | |
if( !function_exists( 'taxonomy_map_get_term_parents' ) ) { | |
/** | |
* Reverse the output of _taxonomy_map_get_term_parents(). | |
* @uses _taxonomy_map_get_term_parents() | |
* @since 2010-09-10 | |
* @since 2010-09-10 | |
*/ | |
function taxonomy_map_get_term_parents( $id, $sep = ', ' ) { | |
$parents = _taxonomy_map_get_term_parents( $id, $sep ); | |
$parents = explode( $sep, trim( $parents, $sep ) ); | |
$parents = array_reverse( $parents ); | |
return implode( $sep, $parents ); | |
} | |
} | |
if( !function_exists( '_taxonomy_map_get_term_parents' ) ) { | |
/** | |
* @since 2010-09-10 | |
* @since 2010-09-10 | |
*/ | |
function _taxonomy_map_get_term_parents( $id, $sep = ', ', $visited = array() ) { | |
$chain = ''; | |
$parent = get_term( $id, TAXONOMY_MAP_TAXONOMY ); | |
if ( is_wp_error( $parent ) ) { | |
return $parent; | |
} | |
if ( $parent->parent && ( $parent->parent != $parent->term_id ) && !in_array( $parent->parent, $visited ) ) { | |
$visited[] = $parent->parent; | |
$chain .= _taxonomy_map_get_term_parents( $parent->parent, $sep, $visited ) . $sep; | |
} | |
$chain .= $parent->name; | |
return $chain; | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment