php
/*
Plugin Name: MapPress Easy Google Maps
Plugin URI: http://www.wphostreviews.com/mappress
Author URI: http://www.wphostreviews.com/mappress
Description: MapPress makes it easy to insert Google Maps in WordPress posts and pages.
Version: 1.5.8.8
Author: Chris Richardson
*/
/*
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.
*/
// ----------------------------------------------------------------------------------
// Class mappress - plugin class
// ----------------------------------------------------------------------------------
class mappress {
var $plugin_name = "MapPress"; // plugin display name
var $wordpress_tag = 'mappress-google-maps-for-wordpress'; // tag assigned by wordpress.org
var $prefix = 'mappress'; // plugin filenames
var $version = '1.5.8.8';
var $development = false; // JS versions
var $doc_link = 'http://wphostreviews.com/mappress/mappress-documentation-144';
var $bug_link = 'http://wphostreviews.com/mappress/chris-contact';
var $widget_defaults = array ('title' => 'MapPress Map', 'map_single' => 0, 'map_multi' => 1, 'width' => 200, 'height' => 200, 'googlebar' => 0);
var $map_defaults = array ('icons_url' => '', 'api_key' => '', 'country' => '', 'size' => 'MEDIUM', 'width' => 0, 'height' => 0, 'zoom' => 0, 'center_lat' => 0, 'center_lng' => 0,
'address_format' => 'CORRECTED', 'bigzoom' => 1, 'googlebar' => 1, 'auto_center' => 1, 'scrollwheel_zoom' => 0, 'language' => '',
'maptypes' => 0, 'directions' => 1, 'maptype' => 'normal', 'streetview' => 1, 'traffic' => 1, 'open_info' => 0, 'default_icon' => '', 'poweredby' => 1);
var $map_sizes = array ('SMALL' => array('width' => 300, 'height' => 225),
'MEDIUM' => array('width' => 400, 'height' => 300),
'LARGE' => array('width' => 640, 'height' => 480) );
var $div_num = 0; // Current map
var $plugin_page = '';
function mappress() {
global $wpdb, $wp_version;
// Initialize options & help
$this->helper = new helpx(array($this, 'get_debug'));
// help_debug=errors -> PHP errors, help_debug=info -> phpinfo + args, help_debug=maps -> maps, help_debug=script -> script
if (isset($_GET['help_debug'])) {
$this->helper->get_info($_GET['help_debug']);
$this->debug = $_GET['help_debug'];
}
// This plugin doesn't work for feeds!
if (is_feed())
return;
// Define constants for pre-2.6 compatibility
if ( ! defined( 'WP_CONTENT_URL' ) )
define( 'WP_CONTENT_URL', get_option( 'siteurl' ) . '/wp-content' );
if ( ! defined( 'WP_CONTENT_DIR' ) )
define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' );
if ( ! defined( 'WP_PLUGIN_URL' ) )
define( 'WP_PLUGIN_URL', WP_CONTENT_URL. '/plugins/' );
if ( ! defined( 'WP_PLUGIN_DIR' ) )
define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' );
// Localization
if( version_compare( $wp_version, '2.7', '>=') )
load_plugin_textdomain($this->prefix, false, $this->wordpress_tag . '/languages');
else
load_plugin_textdomain($this->prefix, "wp-content/plugins/$this->wordpress_tag/languages");
// Notices
add_action('admin_notices', array(&$this, 'hook_admin_notices'));
// Install and activate
register_activation_hook(__FILE__, array(&$this, 'hook_activation'));
add_action('admin_menu', array(&$this, 'hook_admin_menu'));
// Shortcode processing
add_shortcode($this->prefix, array(&$this, 'map_shortcodes'));
// Post save hook for saving maps
add_action('save_post', array(&$this, 'hook_save_post'));
// Non-admin scripts & stylesheets
add_action("wp_print_scripts", array(&$this, 'hook_print_scripts'));
add_action("wp_print_styles", array(&$this, 'hook_print_styles'));
add_action('wp_head', array(&$this, 'hook_head'));
// Uninstall
if ( function_exists('register_uninstall_hook') )
register_uninstall_hook(__FILE__, array(&$this, 'hook_uninstall'));
}
/**
* Add admin menu and admin scripts/stylesheets
* Admin script - post edit and options page
* Content script - content (and also post-edit map)
* CSS - content, plugins, post-edit
*
*/
function hook_admin_menu() {
// Add menu
$mypage = add_options_page($this->plugin_name, $this->plugin_name, 8, __FILE__, array(&$this, 'admin_menu'));
$this->plugin_page = $mypage;
// Post edit shortcode boxes - note that this MUST be admin_menu call
add_meta_box($this->prefix, $this->plugin_name, array(&$this, 'meta_box'), 'post', 'normal', 'high');
add_meta_box($this->prefix, $this->plugin_name, array($this, 'meta_box'), 'page', 'normal', 'high');
// Add scripts & styles for admin pages
add_action("admin_print_scripts-$mypage", array(&$this, 'hook_admin_print_scripts'));
add_action("admin_print_scripts-post.php", array(&$this, 'hook_admin_print_scripts'));
add_action("admin_print_scripts-post-new.php", array(&$this, 'hook_admin_print_scripts'));
add_action("admin_print_scripts-page.php", array(&$this, 'hook_admin_print_scripts'));
add_action("admin_print_scripts-page-new.php", array(&$this, 'hook_admin_print_scripts'));
add_action("admin_print_styles-$mypage", array(&$this, 'hook_admin_print_styles'));
add_action("admin_print_styles-post.php", array(&$this, 'hook_admin_print_styles'));
add_action("admin_print_styles-post-new.php", array(&$this, 'hook_admin_print_styles'));
add_action("admin_print_styles-page.php", array(&$this, 'hook_admin_print_styles'));
add_action("admin_print_styles-page-new.php", array(&$this, 'hook_admin_print_styles'));
}
/**
* Scripts for non-admin screens
*
*/
function hook_print_scripts() {
$key = $this->get_array_option('api_key', 'map_options');
$lang = $this->get_array_option('language', 'map_options');
// Only load for non-admin, non-feed
if (is_admin() || is_feed())
return;
if ($this->debug == 'maps') {
echo "\r\n\r\n";
$result = $this->all_maps();
echo "\r\n ";
}
// Only load if API key isn't empty'
if (empty($key))
return;
// Only load scripts if at least one post has map coordinates (we don't check if map shortcode is present, though)
if (!$this->has_maps())
return;
wp_enqueue_script('googlemaps', "http://maps.google.com/maps?file=api&v=2&key=$key&hl=$lang");
if (substr($this->debug, 0, 4) == 'http')
$script = $this->debug;
elseif ($this->development)
$script = $this->plugin_url('mappress.js');
else
$script = $this->plugin_url('mappress-min.js');
wp_enqueue_script('mappress', $script, FALSE, $this->version);
wp_enqueue_script('mapcontrol', $this->plugin_url('mapcontrol.js'), FALSE, $this->version);
// Stylesheet
if(function_exists('wp_enqueue_style'))
wp_enqueue_style('mappress', $this->plugin_url("mappress.css"), FALSE, $this->version);
// Localize script texts
wp_localize_script($this->prefix, $this->prefix . 'l10n', array(
'dir_400' => __('Google error: BAD REQUEST', $this->prefix),
'dir_500' => __('Google internal error. Try again later.', $this->prefix),
'dir_601' => __('The starting or ending address was missing.', $this->prefix),
'dir_602' => __('The starting or ending address could not be found.', $this->prefix),
'dir_603' => __('Google cannot return those directions for legal or contractual reasons', $this->prefix),
'dir_604' => __('Google cannot return directions between those addresses. There is no route between them or the routing information is not available.', $this->prefix),
'dir_610' => __('Invalid map API key', $this->prefix),
'dir_620' => __('Your key has issued too many queries in one day.', $this->prefix),
'dir_default' => __('Unknown error, unable to return directions. Status code = ', $this->prefix),
'enter_address' => __('Enter address'),
'no_address' => __('No matching address', $this->prefix),
'did_you_mean' => __('Did you mean: ', $this->prefix),
'street_603' => __('Error: your browser does not seem to support the street view Flash player', $this->prefix),
'street_600' => __('Sorry, no street view data is available for this location', $this->prefix),
'street_default' => __('Sorry, Google was unable to display the street view in your browser', $this->prefix),
'street_view' => __('Street view', $this->prefix),
'directions' => __('Get directions', $this->prefix),
'address' => __('Address', $this->prefix),
'to_here' => __('to here', $this->prefix),
'from_here' => __('from here', $this->prefix),
'go' => __('Go', $this->prefix)
));
}
/**
* Stylesheets for non-admin pages
*
*/
function hook_print_styles() {
// Only load for non-admin, non-feed
if (is_admin() || is_feed())
return;
// Only load stylesheets if at least one post has map coordinates (we don't check if map shortcode is present, though)
if (!$this->has_maps())
return;
if(function_exists('wp_enqueue_style'))
wp_enqueue_style($this->prefix, $this->plugin_url("$this->prefix.css"), FALSE, $this->version);
}
/**
* Scripts only for our specific admin pages
*
*/
function hook_admin_print_scripts() {
if ($this->debug == 'maps')
echo "\r\n\r\n";
// We need maps API to validate the key on options page; key may be being updated in $_POST when we hit this event
if (isset($_POST['api_key']))
$key = $_POST['api_key'];
else
$key = $this->get_array_option('api_key', 'map_options');
$lang = $this->get_array_option('language', 'map_options');
if (!empty($key))
wp_enqueue_script('googlemaps', "http://maps.google.com/maps?file=api&v=2&key=$key&hl=$lang");
if ($this->development) {
wp_enqueue_script('mappress_admin', $this->plugin_url('mappress_admin.js'), array('jquery-ui-core', 'jquery-ui-dialog'), $this->version);
wp_enqueue_script('mappress', $this->plugin_url('mappress.js'), array('jquery-ui-core', 'jquery-ui-dialog'), $this->version);
} else {
wp_enqueue_script('mappress_admin', $this->plugin_url('mappress_admin-min.js'), array('jquery-ui-core', 'jquery-ui-dialog'), $this->version);
wp_enqueue_script('mappress', $this->plugin_url('mappress-min.js'), array('jquery-ui-core', 'jquery-ui-dialog'), $this->version);
}
$script = $this->plugin_url('mappress.js');
wp_localize_script($this->prefix, $this->prefix . 'l10n', array(
'api_missing' => __('Please enter your API key. Need an API key? Get one ', $this->prefix),
'api_incompatible' => __('MapPress could not load google maps. Either your browser is incompatible or your API key is invalid. Need an API key? Get one ', $this->prefix),
'here' => __('here', $this->prefix),
'no_address' => __('No matching address', $this->prefix),
'address_exists' => __('That address is already on the map : ', $this->prefix),
'edit' => __('Edit', $this->prefix),
'save' => __('Save', $this->prefix),
'cancel' => __('Cancel', $this->prefix),
'del' => __('Delete', $this->prefix),
'enter_location' => __('Please enter a location to map', $this->prefix),
'title' => __('Title', $this->prefix),
'delete_this_marker' => __('Delete this map marker?', $this->prefix),
'select_icon' => __('Press escape or click here to cancel: ', $this->prefix),
'currently_mapped' => __('Currently mapped', $this->prefix)
));
// Add action to load our geocoder and icons declarations that can't be enqueued
add_action('admin_head', array(&$this, 'hook_head'));
if ($this->debug == 'maps')
echo "\r\n\r\n";
}
function hook_admin_print_styles() {
if(function_exists('wp_enqueue_style'))
wp_enqueue_style($this->prefix, $this->plugin_url("$this->prefix.css"), FALSE, $this->version);
}
/**
* Add js declarations since they can't be 'enqueued', needed by both admin and regular pages
*
*/
function hook_head() {
$key = $this->get_array_option('api_key', 'map_options');
if ($this->debug == 'maps')
echo "\r\n\r\n";
// For non-admin pages ONLY: load scripts only if at least one post has map coordinates (we don't check if map shortcode is present, though)
if (!is_admin() && !$this->has_maps())
return;
// Do nothing if no API key available
if (empty($key))
return;
// Load geocoder
echo "\r\n";
// Load needed icons
$this->icons = $this->get_array_option('icons');
if (empty($this->icons)) {
$this->icons = mpicon::read($url, 'icons.txt');
$this->update_array_option('icons', $this->icons);
}
// Only declare the icons needed to render current page
// TODO : extend this code for marker icons - or better yet replace with AJAX call to fetch only what we need for each map
$default_icon = $this->get_array_option('default_icon', 'map_options');
if ($this->debug == 'maps') {
echo "\r\n\r\n";
}
$default_icon = $this->get_array_option('default_icon', 'map_options');
$needed_icons = array($this->icons[$default_icon]);
mpicon::draw($needed_icons);
// Load map sizes
echo "\r\n";
if ($this->debug == 'maps')
echo "\r\n\r\n";
}
function hook_activation() {
// upgrade
$current_version = $this->get_array_option('version');
// Re-read the icon list (format may change)
$this->icons = mpicon::read($url, 'icons.txt');
$this->update_array_option('icons', $this->icons);
// If version number was not set or is prior to 1.3, upgrade option values
if ($current_version == false || $current_version < '1.3') {
foreach($this->map_defaults as $key=>$value) {
$current_value = $this->get_array_option($key);
if (isset($current_value) && $current_value !== false) {
$map_options[$key] = $current_value;
}
}
// Delete the old option format
delete_option('mappress');
// Add the new options format
$map_options['googlebar'] = 1;
$this->update_array_option('map_options', $map_options);
// We'll assume another version was installed if API_KEY isn't empty
// In that case, warn the user to upgrade his maps
$key = $this->get_array_option('api_key', 'map_options');
}
// Save current version #
$this->update_array_option('version', $this->version);
}
/**
* Delete all option on uninstall
*
*/
function hook_uninstall() {
update_options($this->prefix, '');
}
function hook_save_post($post_id) {
// This hook gets triggered on autosaves, but WP doesn't populate all of the _POST variables (sigh)
// So ignore it unless at least one of our fields is set.
if (!isset($_POST['mapp_zoom']))
return;
delete_post_meta($post_id, '_mapp_map');
delete_post_meta($post_id, '_mapp_pois');
// Process map header fields. Filter out empty strings so as not to affect shortcode_atts() calls later
if (!empty($_POST['mapp_size']))
$map['size'] = $_POST['mapp_size'];
if (!empty($_POST['mapp_maptype']))
$map['maptype'] = $_POST['mapp_maptype'];
if (!empty($_POST['mapp_width']))
$map['width'] = $_POST['mapp_width'];
if (!empty($_POST['mapp_height']))
$map['height'] = $_POST['mapp_height'];
if (!empty($_POST['mapp_zoom']))
$map['zoom'] = $_POST['mapp_zoom'];
if (!empty($_POST['mapp_center_lat']))
$map['center_lat'] = $_POST['mapp_center_lat'];
if (!empty($_POST['mapp_center_lng']))
$map['center_lng'] = $_POST['mapp_center_lng'];
$map['auto_center'] = $_POST['mapp_auto_center'];
update_post_meta($post_id, '_mapp_map', $map);
// Process POIs
$addresses = (array) $_POST['mapp_poi_address'];
foreach($addresses as $key=>$address) {
// Get the data for the POI.
$caption = $_POST['mapp_poi_caption'][$key];
$body = $_POST['mapp_poi_body'][$key];
$corrected_address = $_POST['mapp_poi_corrected_address'][$key];
$lat = $_POST['mapp_poi_lat'][$key];
$lng = $_POST['mapp_poi_lng'][$key];
$boundsbox_north = $_POST['mapp_poi_boundsbox_north'][$key];
$boundsbox_south = $_POST['mapp_poi_boundsbox_south'][$key];
$boundsbox_west = $_POST['mapp_poi_boundsbox_west'][$key];
$boundsbox_east = $_POST['mapp_poi_boundsbox_east'][$key];
// If somehow we didn't get lat/lng then skip this POI
if (empty($lat) || empty($lng))
continue;
// Add the POI to our array for the metadata
$pois[] = array('address' => $address, 'caption' => $caption, 'body' => $body,
'corrected_address' => $corrected_address, 'lat' => $lat, 'lng' => $lng,
'boundsbox' => array('north' => $boundsbox_north, 'south' => $boundsbox_south, 'east' => $boundsbox_east,
'west' => $boundsbox_west));
}
if (!empty($pois))
update_post_meta($post_id, '_mapp_pois', $pois);
}
/**
* Hook: admin notices
* Used for upgrade notification
*/
function hook_admin_notices() {
global $pagenow;
// Check if API key entered; it may be in process of being updated
if (isset($_POST['api_key']))
$key = $_POST['api_key'];
else
$key = $this->get_array_option('api_key', 'map_options');
if (empty($key)) {
echo "
";
return;
}
}
function has_maps() {
global $posts;
if ($this->debug == 'maps')
echo "\r\n\r\n";
$found = false;
if (empty($posts))
return false;
foreach($posts as $key=>$post)
if (get_post_meta($post->ID, '_mapp_pois', true))
$found = true;
if ($this->debug == 'maps')
echo "\r\n\r\n";
return $found;
}
function all_maps() {
global $wpdb;
$sql = "SELECT m.post_id, p.post_title FROM $wpdb->postmeta m, $wpdb->posts p "
. " WHERE m.meta_key = '_mapp_pois' AND m.post_id = p.id AND m.meta_value != '' AND p.post_content like '%[mappress]%' AND p.post_status = 'publish'";
$results = $wpdb->get_results($sql);
foreach ((array)$results as $result)
$all_maps[] = get_permalink($result->post_id);
return $all_maps;
}
function get_debug() {
$result = $this->all_maps();
return array($result, count($result));
}
/**
* Shortcode form for post edit screen
*
*/
function meta_box($post) {
$map = get_post_meta($post->ID, '_mapp_map', true);
$pois = get_post_meta($post->ID, '_mapp_pois', true);
// Load the edit map
// Note that mapTypes is hardcoded = TRUE (so user can change type, even if not displayed in blog)
$map['maptypes'] = 1;
$this->map($map, $pois, true);
// The
will be filled in with the list of POIs
echo "";
}
function output_map_sizes($selected = "", $width = 0, $height = 0) {
// Output small/med/large
foreach ($this->map_sizes as $key => $ms) {
$checked = ($selected == $key) ? "checked = 'checked'" : $checked = "";
if ($key == 'SMALL')
$label = __('Small', $this->prefix);
if ($key == 'MEDIUM')
$label = __('Medium', $this->prefix);
if ($key == 'LARGE')
$label = __('Large', $this->prefix);
echo "$label ({$ms['width']}x{$ms['height']}) ";
}
// Output 'custom' option
$checked = ($selected == 'CUSTOM') ? "checked = 'checked'" : $checked = "";
echo "" . __('Custom', $this->prefix);
// If size isn't 'CUSTOM' then disable the custom width/height input fields
if ($selected != 'CUSTOM')
$disabled = "readonly = 'readonly'";
else
$disabled = "";
// Output custom width and height
echo "";
echo " x ";
}
/**
* Map a shortcode in a post. Called by WordPress shortcode processor.
*
* @param mixed $atts - shortcode attributes
*/
function map_shortcodes($atts='') {
global $id;
if ($this->debug == 'maps')
echo "\r\n\r\n";
if (is_feed())
return;
$map = get_post_meta($id, '_mapp_map', true);
$pois = get_post_meta($id, '_mapp_pois', true);
$result = $this->map($map, $pois, false);
if ($this->debug == 'maps') {
echo "\r\n\r\n";
}
return $result;
}
function map($map, $pois, $editable = false) {
if ($this->debug == 'maps') {
echo "\r\n\r\n";
}
$map_args = $this->map_defaults;
$map_args = shortcode_atts($map_args, $this->get_array_option('map_options'));
$map_args = shortcode_atts($map_args, $map);
if ($editable) {
$map_name = 'editMap';
$map_args['editable'] = 1;
} else {
$map_name = $this->prefix . $this->div_num;
$this->div_num++;
$map_args['editable'] = 0;
}
$args = array("mapname" => $map_name, "editable" => $map_args['editable'], "size" => $map_args['size'], "width" => $map_args['width'], "height" => $map_args['height'],
"zoom" => $map_args['zoom'], "autoCenter" => $map_args['auto_center'], "centerLat" => $map_args['center_lat'], "centerLng" => $map_args['center_lng'],
"addressFormat" => $map_args['address_format'], "bigZoom" => $map_args['bigzoom'], "googlebar" => $map_args['googlebar'], 'scrollWheelZoom' => $map_args['scrollwheel_zoom'],
"language" => $map_args['language'], "mapTypes" => $map_args['maptypes'], "directions" => $map_args['directions'], "mapType" => $map_args['maptype'],
"streetView" => $map_args['streetview'], "traffic" => $map_args['traffic'], "initialOpenInfo" => $map_args['open_info'],
"defaultIcon" => $map_args['default_icon'], "pois" => $pois);
$args = json_encode($args);
if ($this->debug == 'maps')
echo "\r\n\r\n";
// If we couldn't encode just give up
if (empty($args))
return;
if ($this->debug == 'maps')
echo "\r\n\r\n";
if ($editable) {
// For backwards compatibility: try to figure out the map size if none was specified
if (empty($map_args['size'])) {
// Try to match to each standard size
foreach($this->map_sizes as $key => $ms) {
if ($ms['width'] == $map_args['width'] && $ms['height'] == $map_args['height']) {
$map_args['size'] = $key;
$map['size'] = $key;
}
}
// If still no match, use 'custom'
if (empty($map_args['size'])) {
$map_args['size'] = 'CUSTOM';
$map['size'] = 'CUSTOM';
}
}
?>
php _e('Street Address, city, state, country, or place', $this->prefix) ?>
php _e('Latitude/Longitude ', $this->prefix) ?>
php _e('Preview', $this->prefix) ?>
php $checked = ($map_args['auto_center']) ? "checked='checked'" : ''; ?>
/>
php _e('Automatically center/zoom map when saved (uncheck to display map exactly as shown below)', $this->prefix) ?>
php _e('Currently mapped', $this->prefix) ?>
php _e('Click on a marker or use the links below to edit or delete markers.', $this->prefix) ?>
php
echo "";
// Display maps
} else {
if ($this->debug == 'maps')
echo "\r\n\r\n";
// If there are no POIs then don't try to draw the map at all
if (empty($pois))
return;
if ($this->debug == 'maps')
echo "\r\n\r\n";
$map = "";
$map .= "";
if ($this->debug == 'maps')
echo "\r\n\r\n";
if ($map_args['poweredby'])
$map .= "
";
}
if ($this->debug == 'maps')
echo "\r\n\r\n";
return $map;
}
}
/**
* Get plugin url
*/
function plugin_url ($path) {
if (function_exists('plugins_url'))
return plugins_url("$this->wordpress_tag/$path");
else
return WP_PLUGIN_URL . "$this->wordpress_tag/$path";
}
/**
* Get option value. Options are stored under a single key
*/
function get_array_option($option, $subarray='') {
$options = get_option($this->prefix);
if (empty($options))
return false;
if ($subarray) {
if (isset($options[$subarray][$option]))
return $options[$subarray][$option];
else
return false;
}
// No subarray
if (isset($options[$option]))
return $options[$option];
else
return false;
// If we get here it's an error
return false;
}
/**
* Set option value. Options are stored as an array under a single key
*/
function update_array_option($option, $value) {
$options = get_option($this->prefix);
$options[$option] = $value;
update_option($this->prefix, $options);
}
/**
* Delete option value from option array.
*
*/
function delete_array_option($option) {
$options = get_option($this->prefix);
if (isset($options[$option])) {
unset ($options[$option]);
update_option($this->prefix, $options);
return true;
}
return false;
}
/**
* Options page
*
*/
function admin_menu() {
if ( !current_user_can('manage_options') )
die ( __( "ACCESS DENIED: You don't have permission to do this.", $this->plugin_name) );
// If user hasn't specificed a URL for the icons, use plugin directory
$url = $this->get_array_option('icons_url');
if (empty($url) || $url == false)
$url = plugins_url($this->wordpress_tag . '/icons');
// Read icons
$this->icons = mpicon::read($url, 'icons.txt');
if ($this->icons === false)
$error = "Unable to read icons. Check that the icons.txt file exists and does not have any errors.";
// Save options
if (isset($_POST['save'])) {
check_admin_referer($this->prefix);
foreach($_POST as $key=>$value)
if (!empty($_POST[$key]) || $_POST[$key] === '0')
$new_options[$key] = strip_tags(mysql_real_escape_string ($_POST[$key]));
// $map_options = shortcode_atts($this->map_defaults, $new_values);
$this->update_array_option('map_options', $new_options);
// Save the icons that we loaded
$this->update_array_option('icons', $this->icons);
$message = __('Settings saved', $this->prefix);
}
$map_options = shortcode_atts($this->map_defaults, $this->get_array_option('map_options'));
$icons = $this->get_array_option('icons');
$cctld_link = '(' . __("what's my country code?", $this->prefix) . ')';
$lang_link = '(' . __("supported languages", $this->prefix) . ')';
$help_msg = $this->get_array_option('help_msg');
?>