Geolocation API and display the location using Google Maps. It also supports the geo-location-javascript library and the MaxMind GeoIP Javascript Service for backwards compatibility. * Plugin Name: Author geoLocation * Plugin URI: http://xenthrax.com/wordpress/author-geolocation/ * Version: 1.1a3 * * Donate: http://xenthrax.com/donate/ * * Plugin Shortlink: http://xenthrax.com/author-geolocation/ * Other Plugins: http://xenthrax.com/wordpress/ * * WordPress Plugin: https://wordpress.org/extend/plugins/author-geolocation/ */ /** * If you notice any issues or bugs in the plugin please contact me [@link http://xenthrax.com/about/] * If you make any revisions to and/or re-release this plugin please contact me [@link http://xenthrax.com/about/] */ /** * Copyright (c) 2010-2013 Tom Thorogood * * This file is part of "Author geoLocation" Wordpress Plugin. * * "Author geoLocation" is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 3. * * You may NOT assume that you can use any other version of the GPL. * * "Author geoLocation" 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 "Author geoLocation". If not, see . */ /** * @package Author geoLocation * @since 1.0 */ class Author_geoLocation { /** * @access private * @since 1.0 * @var array */ private $notices = array(); /** * @access private * @since 1.1 * @param string $key * @param bool $esc Optional. * @param bool $echo Optional. * @return string Data */ function _plugin_data($key, $esc = false, $echo = false) { static $plugin_data; $key = strtolower($key); if (is_null($plugin_data)) { $plugin_data = get_file_data(__FILE__, array( 'author' => 'Author', 'authoruri' => 'Author URI', 'donate' => 'Donate', 'name' => 'Plugin Name', 'uri' => 'Plugin URI', 'version' => 'Version', 'shortlink' => 'Plugin Shortlink', 'otherplugins' => 'Other Plugins' )); } if (!array_key_exists($key, $plugin_data) || empty($plugin_data[$key])) return false; $data = $plugin_data[$key]; if ($esc) { switch ($key) { case 'author': case 'name': case 'version': $data = esc_html($data); break; case 'authoruri': case 'donate': case 'uri': case 'shortlink': case 'otherplugins': $data = esc_url($data); break; /*default: return false;*/ } } $data = apply_filters("{$this->slug('hook')}-plugin-data", $data, $key, $esc, $echo, $plugin_data); if ($data === NULL) return false; if (!$echo) return $data; echo $data; return true; } /** * @access private * @since 1.0 * @param string $context Optional. * @param bool $esc Optional. * @param bool $echo Optional. * @return string */ private function slug($context = 'name', $esc = false, $echo = false) { if (!is_string($context)) { $echo = $esc; $esc = $context; $context = 'name'; } switch ($context) { case 'plugin': $slug = plugin_basename(__FILE__); break; case 'settings': $slug = 'settings_page_' . basename(dirname(__FILE__)) . '/' . basename(__FILE__, '.php'); break; case 'name': case 'slug': $slug = preg_replace('/[^a-z0-9_\-]/i', '-', $this->_plugin_data('name')); break; case 'js': $slug = preg_replace('/[^a-z0-9_]/i', '_', $this->_plugin_data('name')); break; case 'hook': $slug = 'author-geolocation'; break; default: $slug = false; break; } if ($context !== 'hook') $slug = apply_filters("{$this->slug('hook')}-slug", $slug, $context, $esc, $echo); if ($slug === false) return false; if ($esc) $slug = esc_html($slug); if (!$echo) return $slug; echo $slug; return true; } /** * @access private * @since 1.1 * @param bool $opening * @param bool $echo Optional. * @return string Comment tag */ function _comment_tag($opening, $echo = true) { if ($opening) $tag = "\n"; else $tag = "\n"; $tag = apply_filters("{$this->slug('hook')}-comment-tag", $tag, $opening, $echo); if ($tag === false) return false; if (!$echo) return $tag; echo $tag; return true; } /** * @access public * @since 1.0 * @param bool $esc * @param bool $echo * @return string Plugin version */ function version($esc = false, $echo = false) { return $this->_plugin_data('version', $esc, $echo); } /** * @since 1.0 */ function Author_geoLocation() { $args = func_get_args(); call_user_func_array(array(&$this, '__construct'), $args); } /** * @since 1.0 */ function __construct() { load_plugin_textdomain($this->slug(), false, basename(dirname(__FILE__)) . '/lang'); $this->add_option('version', $this->version()); foreach ($this->default_options() as $name => $value) $this->add_option($name, $value); foreach (array('admin_head-post-new.php', 'admin_head-post.php') as $filter) add_action($filter, array(&$this, '_admin_head_post')); foreach (array('load-post-new.php', 'load-post.php') as $filter) add_action($filter, array(&$this, '_admin_post_init')); add_filter('plugin_row_meta', array(&$this, '_plugin_row_meta'), 10, 2); add_action("admin_head-{$this->slug('settings')}", array(&$this, '_admin_head_options')); add_action("load-{$this->slug('settings')}", array(&$this, '_options_init')); add_action('admin_notices', array(&$this, '_admin_notices')); add_action('the_content', array(&$this, '_the_content')); add_action('admin_menu', array(&$this, '_admin_menu')); add_action('save_post', array(&$this, '_save_post')); add_action('wp_head', array(&$this, '_head')); add_action('init', array(&$this, '_init')); add_shortcode('address', array(&$this, '_address_shortcode')); add_shortcode('map', array(&$this, '_map_shortcode')); } /** * @access private * @since 1.0 * @return void */ function _init() { wp_enqueue_script('google-maps', '//maps.google.com/maps/api/js?sensor=false', array(), 3); } /** * @access private * @since 1.0 * @return void */ function _admin_post_init() { wp_enqueue_script('jquery'); wp_enqueue_script('google-maps', '//maps.google.com/maps/api/js?sensor=false', array(), 3); if ($this->get_option('legacy')) { wp_enqueue_script('google-gears', $this->_plugin_url('/js/gears.init.js'), array(), null); wp_enqueue_script('geo-location', $this->_plugin_url('/js/geo.js'), array(), '0.4.7'); } } /** * @access private * @since 1.0 * @return void */ function _head() { $this->_comment_tag(true); ?> _comment_tag(false); } /** * @access private * @since 1.0 * @param string $name * @param string $value Optional. * @return void */ private function add_option($name, $value = '') { $value = apply_filters("{$this->slug('hook')}-add-option", $value, $name); if ($value === NULL) return; add_option("{$this->slug()}-{$name}", $value); } /** * @access private * @since 1.0 * @param string $name * @return string Option value */ private function get_option($name) { $value = get_option("{$this->slug()}-{$name}"); return apply_filters("{$this->slug('hook')}-get-option", $value, $name); } /** * @access private * @since 1.0 * @param string $name * @param string $value Optional. * @return void */ private function set_option($name, $value = '') { $value = apply_filters("{$this->slug('hook')}-set-option", $value, $name); if ($value === NULL) return; update_option("{$this->slug()}-{$name}", $value); } /** * @access private * @since 1.0 * @return array Author geoLocation default options */ private function default_options() { $options = array( 'fallback-width' => 640, 'fallback-height' => 250, 'legacy' => true, 'position' => 'after', 'type' => 'ROADMAP', 'zoom' => 15 ); return apply_filters("{$this->slug('hook')}-default-options", $options); } /** * @note WordPress < 2.9.0 will always return true * @access public * @since 1.0 * @return bool Is latest version of Author geoLocation */ function latest_version() { $latest = true; if (function_exists('get_site_transient')) { $plugins = get_site_transient('update_plugins'); $latest = (!isset($plugins->response) || !is_array($plugins->response) || !isset($plugins->response[$this->slug('plugin')])); } return apply_filters("{$this->slug('hook')}-latest-version", $latest); } /** * @access private * @since 1.0 * @deprected 1.1 * @deprected Use $Author_geoLocation->_plugin_url() * * @return Current Working URL */ private function cwu() { _deprecated_function(__CLASS__ . '::' . __FUNCTION__, '1.1', '$Author_geoLocation->_plugin_url()'); return $this->_plugin_url(); } /** * @access private * @since 1.1 * @return string URL */ private function _plugin_url($path) { return apply_filters("{$this->slug('hook')}-plugin-url", plugins_url($path, __FILE__), $path); } /** * @access private * @since 2.0 * @return array Links to display */ function _plugin_row_meta($links, $file) { if ($file == $this->slug('plugin')) { $links[] = '' . __('Settings', $this->slug()) . ''; $links[] = "_plugin_data('donate')}\">" . __('Donate', $this->slug()) . ''; } return $links; } /** * @access private * @since 1.0 * @return void */ function _options_init() { if (isset($_POST["{$this->slug()}-submit"])) { if (check_admin_referer(__FILE__ . "_{$this->slug()}_{$this->version()}")) { $this->set_option('legacy', isset($_POST["{$this->slug()}-legacy"])); if (isset($_POST["{$this->slug()}-position"])) { $position = stripslashes(strtolower(trim($_POST["{$this->slug()}-position"]))); if (in_array($position, array('manual', 'before', 'after'))) $this->set_option('position', $position); } if (isset($_POST["{$this->slug()}-type"])) { $type = stripslashes(strtoupper(trim($_POST["{$this->slug()}-type"]))); if (in_array($type, array('ROADMAP', 'SATELLITE', 'HYBRID', 'TERRAIN'))) $this->set_option('type', $type); } if (isset($_POST["{$this->slug()}-zoom"])) { $zoom = stripslashes(trim($_POST["{$this->slug()}-zoom"])); if (is_numeric($zoom) && intval($zoom) >= 0) $this->set_option('zoom', intval($zoom)); } if (isset($_POST["{$this->slug()}-fallback-width"]) && isset($_POST["{$this->slug()}-fallback-height"])) { $width = stripslashes(trim($_POST["{$this->slug()}-fallback-width"])); $height = stripslashes(trim($_POST["{$this->slug()}-fallback-height"])); if (is_numeric($width) && intval($width) >= 0 && is_numeric($height) && intval($height) >= 0) { $this->set_option('fallback-width', intval($width)); $this->set_option('fallback-height', intval($height)); } } do_action("{$this->slug('hook')}-set-options"); $this->add_notice('Options saved successfully.'); } } else if (isset($_POST["{$this->slug()}-reset"])) { if (check_admin_referer(__FILE__ . "_{$this->slug()}_{$this->version()}")) { foreach ($this->default_options() as $name => $value) $this->set_option($name, $value); do_action("{$this->slug('hook')}-reset-options"); $this->add_notice('Options reset.'); } } } /** * @access public * @since 1.0 * @param int $id * @return object|null Location */ function location($id = 0) { if (empty($id)) $id = get_the_ID(); $locationmeta = $location = get_post_meta($id, "_{$this->slug()}-location", true); if (empty($location)) return null; if (is_object($location)) $location = get_object_vars($location); else if (is_string($location)) $location = @unserialize($location); if (empty($location)) return null; $location = (array)$location; if (isset($location['error']) && $location['error']) return false; if (!isset($location['latitude'], $location['longitude'], $location['latlng']) || empty($location['latitude']) || empty($location['longitude']) || empty($location['latlng'])) return null; unset($location['error'], $location['post_id']); $location = (object)array_merge(array( 'address' => '', 'latlng' => '0,0', 'latitude' => '0', 'longitude' => '0', 'position' => $this->get_option('position'), 'post_id' => $id, 'type' => $this->get_option('type'), 'zoom' => $this->get_option('zoom') ), $location); return apply_filters("{$this->slug('hook')}-location", $location, $id, $locationmeta); } /** * @access public * @since 1.0 * @param int $id * @return object|null Last known location */ function lastLocation($id = 0) { global $wpdb; if (empty($id)) $id = get_current_user_id(); $last = $wpdb->get_var($wpdb->prepare("SELECT post.ID FROM {$wpdb->postmeta} meta, {$wpdb->posts} post WHERE post.post_author = '%d' AND meta.post_ID = post.ID AND meta.meta_key = '_{$this->slug()}-location' ORDER BY post.post_date_gmt DESC LIMIT 0,1", $id)); $location = !empty($last) ? $this->location($last) : null; return apply_filters("{$this->slug('hook')}-last-location", $location, $id, $last); } /** * @access private * @since 1.0 * @param string $msg * @param string $type Optional. * @param int $priority Optional. * @return void */ private function add_notice($msg, $type = 'updated', $priority = false) { $type = strtolower($type); $priority = ($priority === false) ? (($type === 'error') ? 5 : 10) : (int)$priority; $msg = apply_filters("{$this->slug('hook')}-add-notice", $msg, $type, $priority); if (empty($msg)) return false; $this->notices[$priority][] = (object)array( 'msg' => (string)$msg, 'type' => (string)$type ); return true; } /** * @access private * @since 1.0 * @return void */ function _admin_notices() { $this->notices = apply_filters("{$this->slug('hook')}-print-notices", $this->notices); ksort($this->notices); if (!empty($this->notices)) { $this->_comment_tag(true); foreach ($this->notices as $priority => $notices) foreach ($notices as $notice) echo "
type}\">

{$notice->msg}

\n"; $this->_comment_tag(false); } } /** * @access private * @since 1.0 * @param object $location * @return string Adress link HTML */ function _address_html($location) { switch ($location->type) { case 'HYBRID': $map_t = 'h'; break; case 'SATELLITE': $map_t = 'k'; break; case 'TERRAIN': $map_t = 'p'; break; case 'ROADMAP': default: $map_t = 'm'; break; } $address = esc_html($location->address); $address = <<{$address} EOD; return apply_filters("{$this->slug('hook')}-address-html", $address, $location); } /** * @access private * @since 1.0 * @param object $location * @param bool $show_address Optional. * @return string Map HTML */ private function map_html($location, $show_address = true) { static $mapcount = 0; $mapcount++; $address = sprintf(__('Posted from %1$s', 'author-geolocation'), $this->_address_html($location)); $address_style = $show_address ? '' : ' style="display:none;"'; $type = strtolower($location->type); $size = "{$this->get_option('fallback-width')}x{$this->get_option('fallback-height')}"; if (has_filter('Author_geoLocation_fallback_image_size')) { _deprecated_function('Author_geoLocation_fallback_image_size', '1.1', "Fallback size in plugin options."); $size = apply_filters('Author_geoLocation_fallback_image_size', $size, $location); } $map = <<_comment_tag(true)}
{$address}.
{$this->_comment_tag(false)} EOD; return apply_filters("{$this->slug('hook')}-map-html", $map, $location, $show_address, $size, $mapcount); } /** * @access private * @since 1.0 * @param array $atts * @return string Map HTML */ function _map_shortcode($atts) { $atts = shortcode_atts(array('dont_hide' => false, 'post_id' => 0, 'show_address' => false), $atts); $location = $this->location($atts['post_id']); $show = $atts['dont_hide'] || is_singular(); $map = ($show && $location) ? $this->map_html($location, $atts['show_address']) : ''; return apply_filters("{$this->slug('hook')}-map-shortcode", $map, $atts, $location, $show); } /** * @access private * @since 1.0 * @param array $atts * @return string Address */ function _address_shortcode($atts) { $atts = shortcode_atts(array('before' => __('Posted from ', 'author-geolocation'), 'after' => '.', 'linkify' => true, 'post_id' => 0), $atts); $location = $this->location($atts['post_id']); $address = $location ? $atts['before'] . ($atts['linkify'] ? $this->_address_html($location) : htmlentities($location->address)) . $atts['after'] : ''; return apply_filters("{$this->slug('hook')}-address-shortcode", $address, $atts, $location); } /** * @access private * @since 1.0 * @param string $content * @return Post content */ function _the_content($content) { if (is_singular()) { $location = $this->location(); if ($location && apply_filters("{$this->slug('hook')}-add-to-content", true, $location, $content)) { switch ($location->position) { case 'before': $content = $this->map_html($location) . $content; break; case 'after': $content .= $this->map_html($location); break; } } } return $content; } /** * @access private * @since 1.0 * @param int $id * @return int Post id */ function _save_post($id) { if (isset($_POST["{$this->slug()}-nonce"]) && wp_verify_nonce($_POST["{$this->slug()}-nonce"], __FILE__ . "_{$this->slug()}_{$this->version()}") && (!defined('DOING_AUTOSAVE') || !DOING_AUTOSAVE) && current_user_can(sprintf('edit_%s', $_POST['post_type']), $id)) { $address = stripslashes(trim($_POST["{$this->slug()}-address"])); $location = (object)array('error' => true); if (!empty($address)) { $latlng = stripslashes(trim($_POST["{$this->slug()}-latlng"])); if (empty($latlng) || !$_POST["{$this->slug()}-js"]) { $result = wp_remote_get('http://maps.google.com/maps/api/geocode/json?address=' . urlencode($address) . '&sensor=false'); $json = json_decode($result['body']); if (!is_a($json, 'WP_Error') && $json->status == 'OK' && count($json->results) > 0) { $latlng = "{$json->results[0]->geometry->location->lat},{$json->results[0]->geometry->location->lng}"; $latlng_ = array( $json->results[0]->geometry->location->lat, $json->results[0]->geometry->location->lng ); } else { $this->add_notice(sprintf(__('Author geoLocation encountered an error while trying to convert %1$s to latlng coordanates.', $this->slug()), htmlentities($address))); return $id; } } else $latlng_ = explode(',', $latlng); if (!empty($latlng) && count($latlng_) == 2 && !empty($latlng_[0]) && !empty($latlng_[1])) { $suffix = $_POST["{$this->slug()}-js"] ? '' : '-no-js'; $position = stripslashes(strtolower(trim($_POST["{$this->slug()}-position"]))); $type = stripslashes(strtoupper(trim($_POST["{$this->slug()}-type{$suffix}"]))); $zoom = stripslashes(trim($_POST["{$this->slug()}-zoom{$suffix}"])); $location = (object)array( 'address' => $address, 'latlng' => $latlng, 'latitude' => $latlng_[0], 'longitude' => $latlng_[1], 'position' => in_array($position, array('manual', 'before', 'after')) ? $position : $this->get_option('position'), 'type' => in_array($type, array('ROADMAP', 'SATELLITE', 'HYBRID', 'TERRAIN')) ? $type : $this->get_option('type'), 'zoom' => (is_numeric($zoom) && intval($zoom) >= 0) ? intval($zoom) : $this->get_option('zoom') ); } } $location = apply_filters("{$this->slug('hook')}-save-post", $location, $id); if (!empty($location)) update_post_meta($id, "_{$this->slug()}-location", /*serialize(*/$location/*)*/); } return $id; } /** * @access private * @since 1.0 * @return void */ function _admin_meta_box() { $id = (isset($_GET['post']) && !empty($_GET['post'])) ? intval(stripslashes($_GET['post'])) : 0; $location = !empty($id) ? $this->location($id) : null; if (is_null($location)) $location = $this->lastLocation(); $pos = $location ? $location->position : $this->get_option('position'); $type = $location ? $location->type : $this->get_option('type'); $zoom = $location ? $location->zoom : $this->get_option('zoom'); if (!apply_filters("{$this->slug('hook')}-do-meta-box", true, $id, $location, $pos, $type, $zoom)) return; $this->_comment_tag(true); ?>
slug()}_{$this->version()}", "{$this->slug()}-nonce"); ?>
_comment_tag(false); } /** * @access private * @since 1.0 * @return void */ function _admin_menu() { add_options_page($this->_plugin_data('name'), $this->_plugin_data('name'), 'manage_options', __FILE__, array(&$this, '_options_page')); foreach (array('page', 'post', 'custom_post_type') as $type) //verify this works for custom post types! add_meta_box('location', 'Location', array(&$this, '_admin_meta_box'), $type, 'normal', 'high'); } /** * @access private * @since 1.0 * @return void */ function _admin_head_options() { $this->_comment_tag(true); ?> _comment_tag(false); } /** * @access private * @since 1.0 * @return void */ function _admin_head_post() { $id = (isset($_GET['post']) && !empty($_GET['post'])) ? intval(stripslashes($_GET['post'])) : 0; $location = !empty($id) ? $this->location($id) : null; if (is_null($location)) $location = $this->lastLocation(); if (!apply_filters("{$this->slug('hook')}-do-post-head", true, $id, $location)) return; $this->_comment_tag(true); ?> _comment_tag(false); } /** * @access private * @since 1.0 * @return void */ function _options_page() { global $wp_version; $pos = $this->get_option('position'); $type = $this->get_option('type'); $this->_comment_tag(true); ?>

_plugin_data('Name', true, true); ?>

=')) { ?> slug('hook')}-options-page"); ?>
slug()); ?> _plugin_data('author', true, true); ?> | slug()), $this->_plugin_data('author', true)); ?> | slug()); ?> | slug()); ?>
slug()); ?> version(true, true); ?> version(true, true); ?>
 
slug()); ?> get_option('legacy')); ?> /> Geolocation API with the geo-location-javascript library and Google Gears.', $this->slug()); ?>
slug()); ?> slug()); ?>
slug()); ?> slug()); ?>
slug()); ?> slug()); ?>
slug()); ?> slug()); ?> slug()); ?>
 
 
tweeting about this plugin, writing a post about this plugin or donating.', $this->slug()), admin_url('post-new.php'), urlencode($this->_plugin_data('name')), urlencode($this->_plugin_data('shortlink')), $this->_plugin_data('donate', true)); ?>
GeoIP JavaScript Service by MaxMind.', $this->slug()); ?>
slug()}_{$this->version()}"); ?>
_comment_tag(false); } } /** * @access public * @since 1.0 */ $Author_geoLocation = new Author_geoLocation(); /** * @access public * @since 1.0 * @param int $id Optional. * @return object Location */ if (!function_exists('get_the_location')) { function get_the_location($id = 0) { global $Author_geoLocation; $location = $Author_geoLocation->location($id); return apply_filters('get_the_location', $location, $id); } } /** * @access public * @since 1.0 * @param int $id Optional. * @param string $before Optional. * @param string $after Optional. * @param bool $linkify Optional. * @return void */ if (!function_exists('the_location')) { function the_location($id = 0, $before = 'Posted from ', $after = '.', $linkify = true) { global $Author_geoLocation; $address = $Author_geoLocation->_address_shortcode(array('before' => $before, 'after' => $after, 'linkify' => $linkify, 'post_id' => $id)); echo apply_filters('the_location', $address, $id, $before, $after, $linkify); } } ?>