PluginProbe
Maps Widget for Google Maps / 4.25
Maps Widget for Google Maps v4.25
1.86 1.90 1.92 1.93 1.95 2.0 2.01 2.05 2.06 2.10 2.15 2.20 2.25 2.30 2.35 2.40 2.45 2.50 2.51 2.60 2.65 2.66 2.70 2.75 2.80 All 129 releases
google-maps-widget / google-maps-widget.php

google-maps-widget.php in Maps Widget for Google Maps 4.25, at google-maps-widget.php

1,608 lines 73.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Maps Widget for Google Maps
4 Plugin URI: https://www.gmapswidget.com/
5 Description: Display a single image super-fast loading Google Map in a widget. A larger, full featured map is available in a lightbox. Includes a user-friendly interface and numerous appearance options.
6 Author: WebFactory Ltd
7 Version: 4.25
8 Author URI: https://www.gmapswidget.com/
9 Text Domain: google-maps-widget
10 Domain Path: lang
11 Requires at least: 4.0
12 Requires PHP: 5.2
13 Tested up to: 6.5
14
15 Copyright 2012 - 2024 WebFactory Ltd (email : gmw@webfactoryltd.com)
16
17 This program is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License, version 2, as
19 published by the Free Software Foundation.
20
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31
32 // this is an include only WP file
33 if (!defined('ABSPATH')) {
34 wp_die('Do not load this file directly.');
35 }
36
37
38 if (!class_exists('GMW')) {
39
40 define('GMW_PLUGIN_DIR', plugin_dir_path(__FILE__));
41 define('GMW_PLUGIN_URL', plugin_dir_url(__FILE__));
42 define('GMW_BASE_FILE', basename(__FILE__));
43
44 require_once GMW_PLUGIN_DIR . 'gmw-widget.php';
45
46 class GMW {
47 static $version;
48 static $options = 'gmw_options';
49 static $licensing_servers = array('http://license.gmapswidget.com/', 'http://license2.gmapswidget.com/');
50
51
52 // get plugin version from header
53 static function get_plugin_version() {
54 $plugin_data = get_file_data(__FILE__, array('version' => 'Version'), 'plugin');
55 GMW::$version = $plugin_data['version'];
56
57 return $plugin_data['version'];
58 } // get_plugin_version
59
60
61 // hook everything up
62 static function init() {
63 if (is_admin()) {
64 // check if minimal required WP version is present
65 if (false === GMW::check_wp_version(4.0)) {
66 return false;
67 }
68
69 // check a few variables
70 GMW::maybe_upgrade();
71
72 // aditional links in plugin description
73 add_filter('plugin_action_links_' . basename(dirname(__FILE__)) . '/' . basename(__FILE__),
74 array('GMW', 'plugin_action_links'));
75 add_filter('plugin_row_meta', array('GMW', 'plugin_meta_links'), 10, 2);
76
77 // enqueue admin scripts
78 add_action('admin_enqueue_scripts', array('GMW', 'admin_enqueue_scripts'), 100);
79 add_action('customize_controls_enqueue_scripts', array('GMW', 'admin_enqueue_scripts'));
80
81 // JS dialog markup
82 add_action('admin_footer', array('GMW', 'admin_dialogs_markup'));
83
84 // register AJAX endpoints
85 add_action('wp_ajax_gmw_test_api_key', array('GMW', 'test_api_key_ajax'));
86 add_action('wp_ajax_gmw_activate', array('GMW', 'activate_license_key_ajax'));
87 add_action('wp_ajax_gmw_dismiss_pointer', array('GMW', 'dismiss_pointer_ajax'));
88
89 // custom admin actions
90 add_action('admin_action_gmw_dismiss_notice', array('GMW', 'dismiss_notice'));
91
92 // add options menu
93 add_action('admin_menu', array('GMW', 'add_menus'));
94
95 // settings registration
96 add_action('admin_init', array('GMW', 'register_settings'));
97
98 // display various notices
99 add_action('current_screen', array('GMW', 'add_notices'));
100 } else {
101 // enqueue frontend scripts
102 add_action('wp_enqueue_scripts', array('GMW', 'register_scripts'));
103 add_action('wp_footer', array('GMW', 'dialogs_markup'));
104 }
105 } // init
106
107
108 // some things have to be loaded earlier
109 static function plugins_loaded() {
110 GMW::get_plugin_version();
111
112 load_plugin_textdomain('google-maps-widget', false, basename(dirname(__FILE__)) . '/lang');
113 } // plugins_loaded
114
115
116 // initialize widgets
117 static function widgets_init() {
118 register_widget('GoogleMapsWidget');
119 } // widgets_init
120
121
122 // all settings are saved in one option
123 static function register_settings() {
124 register_setting(GMW::$options, GMW::$options, array('GMW', 'sanitize_settings'));
125 } // register_settings
126
127
128 // sanitize settings on save
129 static function sanitize_settings($values) {
130 $old_options = GMW::get_options();
131
132 foreach ($values as $key => $value) {
133 switch ($key) {
134 case 'api_key':
135 $values[$key] = str_replace(' ', '', $value);
136 break;
137 } // switch
138 } // foreach
139
140 if (strlen($values['api_key']) < 30) {
141 add_settings_error(GMW::$options, 'api_key', __('Google Maps API key is not valid. Access <a href="https://console.developers.google.com/project">Google Developers Console</a> to generate a key for free.', 'google-maps-widget'), 'error');
142 }
143
144 return array_merge($old_options, $values);
145 } // sanitize_settings
146
147
148 // return default options
149 static function default_options() {
150 $defaults = array('sc_map' => 'gmw',
151 'api_key' => '',
152 'track_ga' => '0',
153 'include_jquery' => '1',
154 'include_gmaps_api' => '1',
155 'include_lightbox_js' => '1',
156 'include_lightbox_css' => '1',
157 'disable_tooltips' => '0',
158 'disable_sidebar' => '0',
159 'activation_code' => '',
160 'license_active' => '',
161 'license_expires' => '',
162 'license_type' => ''
163 );
164
165 return $defaults;
166 } // default_settings
167
168
169 // get plugin's options
170 static function get_options() {
171 $options = get_option(GMW::$options, array());
172
173 if (!is_array($options)) {
174 $options = array();
175 }
176 $options = array_merge(GMW::default_options(), $options);
177
178 return $options;
179 } // get_options
180
181
182 // update and set one or more options
183 static function set_options($new_options) {
184 if (!is_array($new_options)) {
185 return false;
186 }
187
188 $options = GMW::get_options();
189 $options = array_merge($options, $new_options);
190
191 update_option(GMW::$options, $options);
192
193 return $options;
194 } // set_options
195
196
197 // add widgets link to plugins page
198 static function plugin_action_links($links) {
199 $settings_link = '<a href="' . admin_url('options-general.php?page=gmw_options') . '" title="' . __('Settings for Maps Widget for Google Maps', 'google-maps-widget') . '">' . __('Settings', 'google-maps-widget') . '</a>';
200 $widgets_link = '<a href="' . admin_url('widgets.php') . '" title="' . __('Configure Maps Widget for Google Maps for your theme', 'google-maps-widget') . '">' . __('Widgets', 'google-maps-widget') . '</a>';
201
202 array_unshift($links, $settings_link);
203 array_unshift($links, $widgets_link);
204
205 return $links;
206 } // plugin_action_links
207
208
209 // add links to plugin's description in plugins table
210 static function plugin_meta_links($links, $file) {
211 $documentation_link = '<a target="_blank" href="http://www.gmapswidget.com/documentation/" title="' . __('View Maps Widget for Google Maps documentation', 'google-maps-widget') . '">'. __('Documentation', 'google-maps-widget') . '</a>';
212 $support_link = '<a target="_blank" href="http://wordpress.org/support/plugin/google-maps-widget" title="' . __('Problems? We are here to help!', 'google-maps-widget') . '">' . __('Support', 'google-maps-widget') . '</a>';
213 $review_link = '<a target="_blank" href="https://wordpress.org/support/view/plugin-reviews/google-maps-widget?filter=5#pages" title="' . __('If you like it, please review the plugin', 'google-maps-widget') . '">' . __('Review the plugin', 'google-maps-widget') . '</a>';
214 $activate_link = '<a href="' . esc_url(admin_url('options-general.php?page=gmw_options&gmw_open_promo_dialog')) . '">' . __('Activate PRO features', 'google-maps-widget') . '</a>';
215
216 if ($file == plugin_basename(__FILE__)) {
217 $links[] = $documentation_link;
218 $links[] = $support_link;
219 $links[] = $review_link;
220 if (!GMW::is_activated()) {
221 $links[] = $activate_link;
222 }
223 }
224
225 return $links;
226 } // plugin_meta_links
227
228
229 // check if user has the minimal WP version required by GMW
230 static function check_wp_version($min_version) {
231 if (!version_compare(get_bloginfo('version'), $min_version, '>=')) {
232 add_action('admin_notices', array('GMW', 'notice_min_version_error'));
233 return false;
234 }
235
236 return true;
237 } // check_wp_version
238
239
240 // display error message if WP version is too low
241 static function notice_min_version_error() {
242 echo '<div class="error"><p>' . sprintf(__('Maps Widget for Google Maps <b>requires WordPress version 4.0</b> or higher to function properly. You are using WordPress version %s. Please <a href="%s">update it</a>.', 'google-maps-widget'), get_bloginfo('version'), admin_url('update-core.php')) . '</p></div>';
243 } // notice_min_version_error
244
245
246 // get users maps api key or one of temporary plugin ones
247 static function get_api_key($type = 'static') {
248 $options = GMW::get_options();
249 $default_api_keys = array('AIzaSyBvCK51-6tqdH0gu_lsUK8SxlGrvfUzIfo');
250
251 if ($type == 'test' && strlen($options['api_key']) < 30) {
252 return false;
253 }
254
255 if ($type == 'fallback' && empty($options['api_key'])) {
256 shuffle($default_api_keys);
257 return $default_api_keys[0];
258 }
259
260 if (!empty($options['api_key'])) {
261 return $options['api_key'];
262 } else {
263 return false;
264 }
265 } // get_api_key
266
267
268 // checkes if API key is active for all needed API services
269 static function test_api_key_ajax() {
270 check_ajax_referer('gmw_test_api_key');
271
272 $msg = '';
273 $error = false;
274 $api_key = substr(sanitize_key(@$_GET['api_key']), 0, 128);
275
276 $test = wp_remote_get(esc_url_raw('https://maps.googleapis.com/maps/api/staticmap?center=new+york+usa&size=100x100&key=' . $api_key));
277 if (wp_remote_retrieve_response_message($test) == 'OK') {
278 $msg .= 'Google Static Maps API test - OK' . "\n";
279 } else {
280 $msg .= 'Google Static Maps API test - FAILED' . "\n";
281 $error = true;
282 }
283
284 $test = wp_remote_get(esc_url_raw('https://www.google.com/maps/embed/v1/place?q=new+york+usa&key=' . $api_key));
285 if (wp_remote_retrieve_response_message($test) == 'OK') {
286 $msg .= 'Google Embed Maps API test - OK' . "\n\n";
287 } else {
288 $msg .= 'Google Embed Maps API test - FAILED' . "\n\n";
289 $error = true;
290 }
291
292 if ($error) {
293 $msg .= 'Something is not right. Please read the instruction below on how to generate the API key and double-check everything.';
294 } else {
295 $msg = 'The API key is OK! Don\'t forget to save it ;)';
296 }
297
298 wp_send_json_success($msg);
299 } // test_api_key
300
301
302 // build a complete URL for the iframe map
303 static function build_lightbox_url($widget) {
304 $map_params = array();
305
306 if ($widget['lightbox_mode'] == 'place') {
307 $map_params['q'] = $widget['address'];
308 $map_params['attribution_source'] = get_bloginfo('name')? get_bloginfo('name'): 'Maps Widget for Google Maps';
309 $map_params['attribution_web_url'] = get_home_url();
310 $map_params['attribution_ios_deep_link_id'] = 'comgooglemaps://?daddr=' . $widget['address'];
311 $map_params['maptype'] = $widget['lightbox_map_type'];
312 $map_params['zoom'] = $widget['lightbox_zoom'];
313 } elseif ($widget['lightbox_mode'] == 'directions') {
314 $map_params['origin'] = $widget['lightbox_origin'];
315 $map_params['destination'] = $widget['address'];
316 $map_params['maptype'] = $widget['lightbox_map_type'];
317 if (!empty($widget['lightbox_unit']) && $widget['lightbox_unit'] != 'auto') {
318 $map_params['units'] = $widget['lightbox_unit'];
319 }
320 if ($widget['lightbox_zoom'] != 'auto') {
321 $map_params['zoom'] = $widget['lightbox_zoom'];
322 }
323 } elseif ($widget['lightbox_mode'] == 'search') {
324 if (($coordinates = GMW::get_coordinates($widget['address'])) !== false) {
325 $map_params['center'] = $coordinates['lat'] . ',' . $coordinates['lng'];
326 }
327 $map_params['q'] = $widget['lightbox_search'];
328 $map_params['maptype'] = $widget['lightbox_map_type'];
329 if ($widget['lightbox_zoom'] != 'auto') {
330 $map_params['zoom'] = $widget['lightbox_zoom'];
331 }
332 } elseif ($widget['lightbox_mode'] == 'view') {
333 if (($coordinates = GMW::get_coordinates($widget['address'])) !== false) {
334 $map_params['center'] = $coordinates['lat'] . ',' . $coordinates['lng'];
335 }
336 $map_params['maptype'] = $widget['lightbox_map_type'];
337 if ($widget['lightbox_zoom'] != 'auto') {
338 $map_params['zoom'] = $widget['lightbox_zoom'];
339 }
340 } elseif ($widget['lightbox_mode'] == 'streetview') {
341 if (($coordinates = GMW::get_coordinates($widget['address'])) !== false) {
342 $map_params['location'] = $coordinates['lat'] . ',' . $coordinates['lng'];
343 }
344 $map_params['heading'] = $widget['lightbox_heading'];
345 $map_params['pitch'] = $widget['lightbox_pitch'];
346 }
347
348 if ($widget['lightbox_lang'] != 'auto') {
349 $map_params['language'] = $widget['lightbox_lang'];
350 }
351 $map_params['key'] = GMW::get_api_key('embed');
352
353 $map_url = 'https://www.google.com/maps/embed/v1/' . $widget['lightbox_mode'] . '?';
354 $map_url .= http_build_query($map_params, null, '&amp;');
355
356 return $map_url;
357 } // build_lightbox_url
358
359
360 // fetch coordinates based on the address
361 static function get_coordinates($address, $force_refresh = false) {
362 $address_hash = md5('gmw_' . $address);
363
364 if ($force_refresh || ($data = get_transient($address_hash)) === false) {
365 $url = 'https://maps.googleapis.com/maps/api/geocode/xml?address=' . urlencode($address) . '&key=' . GMW::get_api_key('fallback');
366 $result = wp_remote_get(esc_url_raw($url), array('sslverify' => false, 'timeout' => 10));
367
368 if (!is_wp_error($result) && $result['response']['code'] == 200) {
369 $data = new SimpleXMLElement($result['body']);
370
371 if ($data->status == 'OK') {
372 $cache_value['lat'] = (string) $data->result->geometry->location->lat;
373 $cache_value['lng'] = (string) $data->result->geometry->location->lng;
374 $cache_value['address'] = (string) $data->result->formatted_address;
375
376 // cache coordinates for 2 months
377 set_transient($address_hash, $cache_value, MONTH_IN_SECONDS * 2);
378 $data = $cache_value;
379 $data['cached'] = false;
380 } elseif (!$data->status) {
381 return false;
382 } else {
383 return false;
384 }
385 } else {
386 return false;
387 }
388 } else {
389 // data is cached
390 $data['cached'] = true;
391 }
392
393 return $data;
394 } // get_coordinates
395
396
397 // print dialogs markup in footer
398 static function dialogs_markup() {
399 $out = '';
400 $js_vars = array();
401 $measure_title = array('dark');
402
403 if (empty(GoogleMapsWidget::$widgets)) {
404 return;
405 }
406
407 // add CSS and JS in footer
408 $js_vars['colorbox_css'] = GMW_PLUGIN_URL . 'css/gmw.css' . '?ver=' . GMW::$version;
409 wp_enqueue_script('gmw-colorbox');
410 wp_enqueue_script('gmw');
411 wp_localize_script('gmw', 'gmw_data', $js_vars);
412
413 foreach (GoogleMapsWidget::$widgets as $widget) {
414 $map_url = GMW::build_lightbox_url($widget);
415
416 if ($widget['lightbox_fullscreen']) {
417 $widget['lightbox_width'] = '100%';
418 $widget['lightbox_height'] = '100%';
419 }
420
421 $out .= '<div class="gmw-dialog" style="display: none;" data-map-height="' . $widget['lightbox_height'] . '"
422 data-map-width="' . $widget['lightbox_width'] . '" data-thumb-height="' . $widget['thumb_height'] . '"
423 data-thumb-width="' . $widget['thumb_width'] . '" data-map-skin="' . $widget['lightbox_skin'] . '"
424 data-map-iframe-url="' . $map_url . '" id="gmw-dialog-' . $widget['id'] . '" title="' . esc_attr($widget['title']) . '"
425 data-close-button="' . (int) in_array('close_button', $widget['lightbox_feature']) . '"
426 data-show-title="' . (int) in_array('title', $widget['lightbox_feature']) . '"
427 data-measure-title="' . (int) in_array($widget['lightbox_skin'], $measure_title) . '"
428 data-close-overlay="' . (int) in_array('overlay_close', $widget['lightbox_feature']) . '"
429 data-close-esc="' . (int) in_array('esc_close', $widget['lightbox_feature']) . '">';
430 if ($widget['lightbox_header']) {
431 $tmp = str_ireplace(array('{address}'), array($widget['address']), $widget['lightbox_header']);
432 $out .= '<div class="gmw-header">' . wpautop(do_shortcode($tmp)) . '</div>';
433 }
434 $out .= '<div class="gmw-map"></div>';
435 if ($widget['lightbox_footer']) {
436 $tmp = str_ireplace(array('{address}'), array($widget['address']), $widget['lightbox_footer']);
437 $out .= '<div class="gmw-footer">' . wpautop(do_shortcode($tmp)) . '</div>';
438 }
439 $out .= "</div>\n";
440 } // foreach $widgets
441
442 self::wp_kses_wf($out);
443 } // dialogs_markup
444
445
446 // add plugin menus
447 static function add_menus() {
448 $title = __('Maps Widget for Google Maps', 'google-maps-widget');
449 add_options_page($title, $title, 'manage_options', GMW::$options, array('GMW', 'settings_screen'));
450 } // add_menus
451
452
453 // handle dismiss button for notices
454 static function dismiss_notice() {
455 check_ajax_referer('gmw_dismiss_notice');
456
457 if (empty($_GET['notice'])) {
458 wp_safe_redirect(admin_url());
459 exit;
460 }
461
462 $notice_name = substr(sanitize_key($_GET['notice']), 0, 32);
463
464 if ($notice_name == 'upgrade') {
465 GMW::set_options(array('dismiss_notice_upgrade2' => true));
466 } elseif ($notice_name == 'rate') {
467 GMW::set_options(array('dismiss_notice_rate' => true));
468 } elseif ($notice_name == 'api_key') {
469 GMW::set_options(array('dismiss_notice_api_key' => true));
470 } elseif ($notice_name == 'olduser') {
471 GMW::set_options(array('dismiss_notice_olduser' => true));
472 } else {
473 wp_safe_redirect(admin_url());
474 exit;
475 }
476
477 if (!empty($_GET['redirect'])) {
478 wp_safe_redirect(esc_url($_GET['redirect']));
479 } else {
480 wp_safe_redirect(admin_url());
481 }
482
483 exit;
484 } // dismiss_notice
485
486
487 // controls which notices are shown
488 static function add_notices() {
489 $options = GMW::get_options();
490 $notice = false;
491 global $wp_version;
492
493 if (false == is_plugin_active('classic-widgets/classic-widgets.php') && version_compare($wp_version, '5.8', '>=') == true) {
494 $notice = true;
495 add_action('admin_notices', array('GMW', 'notice_classic_widgets'));
496 }
497
498 // upgrade notice is shown after install
499 if (!$notice && empty($options['dismiss_notice_upgrade2']) &&
500 !GMW::is_activated() &&
501 (current_time('timestamp') - $options['first_install']) > 2) {
502 add_action('admin_notices', array('GMW', 'notice_upgrade'));
503 $notice = true;
504 } // show upgrade notice
505
506 // API key notification is shown only on GMW settings page
507 if (!GMW::get_api_key('test') && GMW::is_plugin_admin_page('settings')) {
508 add_action('admin_notices', array('GMW', 'notice_api_key'));
509 $notice = true;
510 } // show api key notice
511
512 // rating notification is shown after 7 days if you have active widgets
513 if (!$notice && empty($options['dismiss_notice_rate']) &&
514 self::count_active_widgets() > 0 &&
515 (current_time('timestamp') - $options['first_install']) > (DAY_IN_SECONDS * 3)) {
516 add_action('admin_notices', array('GMW', 'notice_rate_plugin'));
517 $notice = true;
518 } // show rate notice
519
520 // upsell to old users
521 if (!$notice && empty($options['dismiss_notice_olduser']) &&
522 ((current_time('timestamp') - $options['first_install']) > (DAY_IN_SECONDS * 60))) {
523 add_action('admin_notices', array('GMW', 'notice_olduser'));
524 $notice = true;
525 } // upsell to old users
526 } // add_notices
527
528
529 // display error notice if classic widgets are not available
530 static function notice_classic_widgets() {
531 echo '<div class="error notice" style="max-width: 700px;"><p><b>🔥 IMPORTANT 🔥</b><br><br>Google Maps Widget is NOT compatible with the new widgets edit screen (powered by Gutenberg).
532 <br>Install the official <a href="' . admin_url('plugin-install.php?s=classic%20widgets&tab=search&type=term') . '">Classic Widgets</a> plugin if you want to continue using Google Maps Widget.<br>
533 Or install the <a href="' . admin_url('plugin-install.php?s=map%20block&tab=search&type=tag') . '">free Map Block plugin</a> as the fastest way to add a great map to any post or sidebar.</p></div>';
534 } // notice_classic_widgets
535
536
537 // display message to get pro features for GMW
538 static function notice_upgrade() {
539 $promo_delta = HOUR_IN_SECONDS - 2;
540 $options = GMW::get_options();
541 $activate_url = admin_url('options-general.php?page=gmw_options&gmw_open_promo_dialog');
542 $dismiss_url = add_query_arg(array('action' => 'gmw_dismiss_notice', 'notice' => 'upgrade', 'redirect' => urlencode($_SERVER['REQUEST_URI'])), admin_url('admin.php'));
543 $dismiss_url = wp_nonce_url($dismiss_url, 'gmw_dismiss_notice');
544
545 echo '<div id="gmw_activate_notice" class="updated notice"><p>' . __('<b>Maps Widget for Google Maps <span style="color: #d54e21;">PRO</span></b> has more than 50 extra features &amp; options. Our support is super fast &amp; friendly and with the unlimited license you can install GMW on as many sites as you need.</p>', 'google-maps-widget');
546
547 if (current_time('timestamp') - $options['first_install'] < $promo_delta) {
548 $delta = $options['first_install_gmt'] + $promo_delta - time();
549 $h = $delta / 3600 % 24;
550 if ($h) {
551 $h .= 'h';
552 } else {
553 $h = '';
554 }
555 $min = $delta / 60 % 60;
556 echo '<p>We\'ve prepared a special <b>20% welcoming discount</b> available only for another <b class="gmw-countdown" data-endtime="' . esc_attr(($options['first_install_gmt'] + $promo_delta)) . '" style="font-weight: bold;">' . esc_attr($h) . ' ' . esc_attr($min) . 'min</b>.</p>';
557 echo '<p><a href="' . esc_url($activate_url) . '" style="vertical-align: baseline; margin-top: 15px;" class="button-primary"><b>Get a lifetime PRO license now for only $39 - LIMITED OFFER!</b></a>';
558 } else {
559 echo '<p><a href="' . esc_url($activate_url) . '" style="vertical-align: baseline; margin-top: 15px;" class="button-primary">' . __('See what PRO has to offer', 'google-maps-widget') . '</a>';
560 }
561
562 echo '&nbsp;&nbsp;<a href="' . esc_url($dismiss_url) . '" class="">' . __('I\'m not interested (remove notice)', 'google-maps-widget') . '</a>';
563 echo '</p></div>';
564 } // notice_activate_extra_features
565
566
567 // display message to get pro features for GMW
568 static function notice_olduser() {
569 $options = GMW::get_options();
570 $activate_url = admin_url('options-general.php?page=gmw_options&gmw_open_promo_dialog');
571 $dismiss_url = add_query_arg(array('action' => 'gmw_dismiss_notice', 'notice' => 'olduser', 'redirect' => urlencode($_SERVER['REQUEST_URI'])), admin_url('admin.php'));
572 $dismiss_url = wp_nonce_url($dismiss_url, 'gmw_dismiss_notice');
573
574 echo '<div class="updated notice">';
575 echo '<p style="font-size: 14px;">We have a <a class="open_promo_dialog" href="' . esc_url($activate_url) . '">special offer</a> only for users like <b>you</b> who\'ve been using Maps Widget for Google Maps for a while: a <b>one time payment</b>, lifetime license for <b>only $39</b>! No nonsense!<br><a class="open_promo_dialog" href="' . esc_url($activate_url) . '">Upgrade now</a> to <span class="gmw-pro-red">PRO</span> &amp; get more than 50 extra options &amp; features.</p><br>';
576
577 echo '<a class="open_promo_dialog button button-primary" href="' . esc_url($activate_url) . '"><b>Grab the limited offer!</b></a>&nbsp;&nbsp;<a href="' . esc_url($dismiss_url) . '" style="margin: 3px 0 0 5px; display: inline-block;">' . __('I\'m not interested (remove notice)', 'google-maps-widget') . '</a>';
578 echo '</p></div>';
579 } // notice_olduser
580
581
582 // display message to rate plugin
583 static function notice_rate_plugin() {
584 $rate_url = 'https://wordpress.org/support/view/plugin-reviews/google-maps-widget?rate=5#postform';
585 $dismiss_url = add_query_arg(array('action' => 'gmw_dismiss_notice', 'notice' => 'rate', 'redirect' => urlencode($_SERVER['REQUEST_URI'])), admin_url('admin.php'));
586 $dismiss_url = wp_nonce_url($dismiss_url, 'gmw_dismiss_notice');
587
588 echo '<div id="gmw_rate_notice" class="updated notice"><p>' . __('Hi! We saw you\'ve been using <b>Maps Widget for Google Maps</b> for a week and wanted to ask for your help to make the plugin better.<br>We just need a minute of your time to rate the plugin. Thank you!', 'google-maps-widget');
589
590 echo '<br><a target="_blank" href="' . esc_url($rate_url) . '" style="vertical-align: baseline; margin-top: 15px;" class="button-primary">' . __('Help make the plugin better by rating it', 'google-maps-widget') . '</a>';
591 echo '&nbsp;&nbsp;<a href="' . esc_url($dismiss_url) . '">' . __('I already rated the plugin', 'google-maps-widget') . '</a>';
592 echo '</p></div>';
593 } // notice_rate_plugin
594
595
596 // display message to enter API key
597 static function notice_api_key() {
598 echo '<div id="gmw_api_key_notice" class="error notice"><p>';
599 echo '<b>Important!</b> Google rules dictate that you have to register for a <b>free Google Maps API key</b>. ';
600 echo 'Please follow our <a href="http://www.gmapswidget.com/documentation/generate-google-maps-api-key/" target="_blank">short instructions</a> to get the key. If you don\'t configure the API key the maps will not work properly.';
601 echo '</p></div>';
602 } // notice_api_key
603
604
605 // register frontend scripts and styles
606 static function register_scripts() {
607 wp_register_style('gmw', GMW_PLUGIN_URL . 'css/gmw.css', array(), GMW::$version);
608
609 wp_register_script('gmw-colorbox', GMW_PLUGIN_URL . 'js/jquery.colorbox.min.js', array('jquery'), GMW::$version, true);
610 wp_register_script('gmw', GMW_PLUGIN_URL . 'js/gmw.js', array('jquery'), GMW::$version, true);
611 } // register_scripts
612
613
614 // enqueue CSS and JS scripts in admin
615 static function admin_enqueue_scripts() {
616 $js_localize = array('dialog_map_title' => __('Pick an address by drag &amp; dropping the pin', 'google-maps-widget'),
617 'undocumented_error' => __('An undocumented error has occured. Please refresh the page and try again.', 'google-maps-widget'),
618 'bad_api_key' => __('The API key format does not look right. Please double-check it.', 'google-maps-widget'),
619 'dialog_promo_title' => '<img alt="' . __('Maps Widget for Google Maps PRO', 'google-maps-widget') . '" title="' . __('Maps Widget for Google Maps PRO', 'google-maps-widget') . '" src="' . GMW_PLUGIN_URL . 'images/gmw-logo-pro-dialog.png' . '">',
620 'dialog_pins_title' => __('Pins Library', 'google-maps-widget'),
621 'plugin_name' => __('Maps Widget for Google Maps', 'google-maps-widget'),
622 'id_base' => 'googlemapswidget',
623 'map_picker_not_active' => __('Drag&drop address picking interface is a PRO feature. Interested in switching to PRO?', 'google-maps-widget'),
624 'customizer_address_picker' => __('At the moment, the address picker is not available in the theme customizer. Please use it in the admin widget GUI.', 'google-maps-widget'),
625 'customizer_pro_dialog' => __('To see what the PRO version offers please open GMW settings in the admin.', 'google-maps-widget'),
626 'map' => false,
627 'marker' => false,
628 'settings_url' => admin_url('options-general.php?page=gmw_options'),
629 'nonce_test_api_key' => wp_create_nonce('gmw_test_api_key'),
630 'nonce_activate_license_key' => wp_create_nonce('gmw_activate_license_key'),
631 'deactivate_confirmation' => __('Are you sure you want to deactivate Maps Widget for Google Maps?' . "\n" . 'All maps will be removed from the site. If you are removing it because of a problem please contact our support. They will be more than glad to help.', 'google-maps-widget'));
632
633 if (GMW::is_plugin_admin_page('widgets') || GMW::is_plugin_admin_page('settings') || is_customize_preview()) {
634 wp_enqueue_script('jquery-ui-tabs');
635 wp_enqueue_script('jquery-ui-dialog');
636 wp_enqueue_script('wp-pointer');
637 wp_enqueue_script('gmw-gmap', '//maps.google.com/maps/api/js?key=' . GMW::get_api_key('fallback'), array(), GMW::$version, true);
638 wp_enqueue_script('gmw-select2', GMW_PLUGIN_URL . 'js/select2.min.js', array('jquery'), GMW::$version, true);
639 wp_enqueue_script('gmw-admin', GMW_PLUGIN_URL . 'js/gmw-admin.js', array('jquery'), GMW::$version, true);
640
641 wp_enqueue_style('wp-jquery-ui-dialog');
642 wp_enqueue_style('wp-pointer');
643 wp_enqueue_style('gmw-select2', GMW_PLUGIN_URL . 'css/select2.min.css', array(), GMW::$version);
644 wp_enqueue_style('gmw-admin', GMW_PLUGIN_URL . 'css/gmw-admin.css', array(), GMW::$version);
645
646 wp_localize_script('gmw-admin', 'gmw', $js_localize);
647
648 // fix for agressive plugins
649 wp_dequeue_style('uiStyleSheet');
650 wp_dequeue_style('wpcufpnAdmin' );
651 wp_dequeue_style('unifStyleSheet' );
652 wp_dequeue_style('wpcufpn_codemirror');
653 wp_dequeue_style('wpcufpn_codemirrorTheme');
654 wp_dequeue_style('collapse-admin-css');
655 wp_dequeue_style('jquery-ui-css');
656 wp_dequeue_style('tribe-common-admin');
657 wp_dequeue_style('file-manager__jquery-ui-css');
658 wp_dequeue_style('file-manager__jquery-ui-css-theme');
659 wp_dequeue_style('wpmegmaps-jqueryui');
660 wp_dequeue_style('facebook-plugin-css');
661 wp_dequeue_style('facebook-tip-plugin-css');
662 wp_dequeue_style('facebook-member-plugin-css');
663 wp_dequeue_style('jquery-ui-tooltip-css');
664 wp_dequeue_style('social_warfare_admin');
665 } // if
666
667 if (GMW::is_plugin_admin_page('plugins')) {
668 wp_enqueue_script('gmw-admin-plugins', GMW_PLUGIN_URL . 'js/gmw-admin-plugins.js', array('jquery'), GMW::$version, true);
669 wp_localize_script('gmw-admin-plugins', 'gmw', $js_localize);
670 }
671
672
673 $pointers = get_transient('gmw_pointers');
674 if ($pointers && !GMW::is_plugin_admin_page('widgets') && !GMW::is_plugin_admin_page('settings')) {
675 $pointers['_nonce_dismiss_pointer'] = wp_create_nonce('gmw_dismiss_pointer');
676 wp_enqueue_script('wp-pointer');
677 wp_enqueue_script('gmw-pointers', plugins_url('js/gmw-admin-pointers.js', __FILE__), array('jquery'), self::$version, true);
678 wp_enqueue_style('wp-pointer');
679 wp_localize_script('wp-pointer', 'gmw_pointers', $pointers);
680 }
681 } // admin_enqueue_scripts
682
683
684 // reset all pointers to default state - visible
685 static function reset_pointers() {
686 $pointers = array();
687 $pointers['welcome'] = array('target' => '#menu-appearance', 'edge' => 'left', 'align' => 'right', 'content' => 'Thank you for installing <b>Maps Widget for Google Maps</b>! Please open <a href="' . admin_url('widgets.php'). '">Appearance - Widgets</a> to create your first map in seconds.');
688
689 set_transient('gmw_pointers', $pointers, 60 * DAY_IN_SECONDS);
690 } // reset_pointers
691
692
693 // permanently dismiss a pointer
694 static function dismiss_pointer_ajax() {
695 check_ajax_referer('gmw_dismiss_pointer');
696
697 $pointers = get_transient('gmw_pointers');
698
699 $pointer = substr(sanitize_key(@$_POST['pointer']), 0, 64);
700
701 if (empty($pointers) || empty($pointers[$pointer])) {
702 wp_send_json_error();
703 }
704
705 unset($pointers[$pointer]);
706 set_transient('gmw_pointers', $pointers);
707
708 wp_send_json_success();
709 } // dismiss_pointer_ajax
710
711
712 // check if plugin's admin page is shown
713 static function is_plugin_admin_page($page = 'widgets') {
714 $current_screen = get_current_screen();
715
716 if ($page == 'widgets' && $current_screen->id == 'widgets') {
717 return true;
718 }
719
720 if ($page == 'settings' && $current_screen->id == 'settings_page_gmw_options') {
721 return true;
722 }
723
724 if ($page == 'plugins' && $current_screen->id == 'plugins') {
725 return true;
726 }
727
728 return false;
729 } // is_plugin_admin_page
730
731
732 // check if license key is valid and not expired
733 static function is_activated() {
734 $options = GMW::get_options();
735
736 if (isset($options['license_active']) && $options['license_active'] === true &&
737 isset($options['license_expires']) && $options['license_expires'] >= date('Y-m-d')) {
738 return true;
739 } else {
740 return false;
741 }
742 } // is_activated
743
744
745 // check if activation code is valid
746 static function validate_activation_code($code) {
747 $request_params = array('sslverify' => false, 'timeout' => 15, 'redirection' => 2);
748 $request_args = array('action' => 'validate_license',
749 'code' => $code,
750 'codebase' => 'free',
751 'version' => GMW::$version,
752 'site' => get_home_url());
753
754 $out = array('success' => false, 'license_active' => false, 'activation_code' => $code, 'error' => '', 'license_type' => '', 'license_expires' => '1900-01-01');
755
756 $url = add_query_arg($request_args, GMW::$licensing_servers[0]);
757 $response = wp_remote_get(esc_url_raw($url), $request_params);
758
759 if (is_wp_error($response) || !wp_remote_retrieve_body($response)) {
760 $url = add_query_arg($request_args, GMW::$licensing_servers[1]);
761 $response = wp_remote_get(esc_url_raw($url), $request_params);
762 }
763
764 if (!is_wp_error($response) && wp_remote_retrieve_body($response)) {
765 $result = json_decode(wp_remote_retrieve_body($response), true);
766 if (is_array($result['data']) && sizeof($result['data']) == 4) {
767 $out['success'] = true;
768 $out = array_merge($out, $result['data']);
769 } else {
770 $out['error'] = 'Invalid response from licensing server. Please try again later.';
771 }
772 } else {
773 $out['error'] = 'Unable to contact licensing server. Please try again in a few moments.';
774 }
775
776 return $out;
777 } // validate_activation_code
778
779
780 // echo markup for promo dialog; only on widgets page
781 static function admin_dialogs_markup() {
782 $out = '';
783 $options = GMW::get_options();
784 $promo_delta = 1 * HOUR_IN_SECONDS - 5;
785 $promo_active = (bool) ((current_time('timestamp') - $options['first_install']) < $promo_delta);
786 $promo_active2 = (bool) ((current_time('timestamp') - $options['first_install']) > DAY_IN_SECONDS * 35);
787
788 if (GMW::is_plugin_admin_page('widgets') || GMW::is_plugin_admin_page('settings')) {
789 $current_user = wp_get_current_user();
790 if (empty($current_user->user_firstname)) {
791 $name = $current_user->display_name;
792 } else {
793 $name = $current_user->user_firstname;
794 }
795
796 $out .= '<div id="gmw_promo_dialog" style="display: none;">';
797
798 $out .= '<div id="gmw_dialog_intro" class="gmw_promo_dialog_screen">
799 <div class="content">
800 <div class="header"><p><a href="#" class="gmw_goto_pro">Learn more</a> about <span class="gmw-pro">PRO</span> features or <a href="#" class="gmw_goto_activation">enter your license key</a></p>';
801 if ($promo_active) {
802 $delta = $options['first_install_gmt'] + $promo_delta - time();
803 $h = $delta / 3600 % 24;
804 $min = $delta / 60 % 60;
805 $out .= '<div class="gmw-discount">We\'ve prepared a special <b>20% welcoming discount</b> available only for another <b class="gmw-countdown" data-endtime="' . ($options['first_install_gmt'] + $promo_delta) . '">' . $h . 'h ' . $min . 'min 0sec</b>. Discounts have been applied on the licenses below.</div>';
806 }
807 $out .= '</div>'; // header
808
809 $out .= '<table id="gmw-pricing-table">';
810 $out .= '<colgroup></colgroup><colgroup></colgroup><colgroup></colgroup>';
811 $out .= '<tr>';
812 $out .= '<td><div class="gmw-promo-icon"><img src="' . GMW_PLUGIN_URL . 'images/icon-agency.png" alt="Unlimited Agency Lifetime License" title="Unlimited Agency Lifetime License"></div><h3>Unlimited<br>Agency License</h3></td>';
813 $out .= '<td><div class="gmw-promo-icon"><img src="' . GMW_PLUGIN_URL . 'images/icon-unlimited.png" alt="Lifetime Personal License" title="Lifetime Personal License"></div><h3>Lifetime<br>Personal License</h3></td>';
814 $out .= '<td><div class="gmw-promo-icon"><img src="' . GMW_PLUGIN_URL . 'images/icon-yearly.png" alt="Yearly License" title="Yearly License"></div><h3>Single<br>Site License</h3></td>';
815 $out .= '</tr>';
816 $out .= '<tr>';
817 $out .= '<td>One Time Payment</td>';
818 $out .= '<td><span class="dashicons dashicons-yes"></span> One Time Payment</td>';
819 $out .= '<td>Yearly Payment</td>';
820 $out .= '</tr>';
821 $out .= '<tr>';
822 $out .= '<td>Unlimited Client &amp; Personal Sites</td>';
823 $out .= '<td><span class="dashicons dashicons-yes"></span> 1 Personal Site</td>';
824 $out .= '<td>1 Personal or Client Site</td>';
825 $out .= '</tr>';
826 $out .= '<tr>';
827 $out .= '<td>Lifetime Priority Support</td>';
828 $out .= '<td><span class="dashicons dashicons-yes"></span> Lifetime Priority Support</td>';
829 $out .= '<td>1 Year of Support</td>';
830 $out .= '</tr>';
831 $out .= '<tr>';
832 $out .= '<td>Lifetime Updates</td>';
833 $out .= '<td><span class="dashicons dashicons-yes"></span> Lifetime Updates</td>';
834 $out .= '<td>1 Year of Updates</td>';
835 $out .= '</tr>';
836 $out .= '<tr>';
837 $out .= '<td>';
838 if (1 || $promo_active) {
839 $out .= '<div class="gmw-promo-button gmw-promo-button-extra"><a href="https://gum.co/gmw-pro-agency/welcome?wanted=true&plugin_info=GMW+v' . GMW::$version . '" target="_blank" data-gumroad-single-product="true">only <strike>$79</strike> $54</a><span>discount: 32%</span></div>';
840 } else {
841 $out .= '<div class="gmw-promo-button"><a href="https://gum.co/gmw-pro-agency?wanted=true&plugin_info=GMW+v' . GMW::$version . '" data-noprevent="1" target="_blank" data-gumroad-single-product="true">BUY $79</a></div>';
842 }
843 $out .= '<span class="instant-download"><span class="dashicons dashicons-yes"></span> 100% No-Risk Money Back Guarantee<br><span class="dashicons dashicons-yes"></span> Secure payment<br><span class="dashicons dashicons-yes"></span> Instant activation</span>';
844 $out .= '</td>';
845 $out .= '<td>';
846 if (1 || $promo_active) {
847 $out .= '<div class="gmw-promo-button gmw-promo-button-extra"><a href="https://gum.co/gmw-pro/welcomegmw?wanted=true&plugin_info=GMW+v' . GMW::$version . '" target="_blank" data-gumroad-single-product="true">only <strike>$49</strike> $39</a><span>discount: 20%</span></div>';
848 } elseif ($promo_active2) {
849 $out .= '<div class="gmw-promo-button gmw-promo-button-extra"><a href="https://gum.co/gmw-pro/olduser4?wanted=true&plugin_info=GMW+v' . GMW::$version . '" target="_blank" data-gumroad-single-product="true">only <strike>$49</strike> $39</a><span>discount: 25%</span></div>';
850 } else {
851 $out .= '<div class="gmw-promo-button"><a href="https://gum.co/gmw-pro?wanted=true&plugin_info=GMW+v' . GMW::$version . '" data-noprevent="1" data-gumroad-single-product="true" target="_blank">BUY $49</a></div>';
852 }
853 $out .= '<span class="instant-download"><span class="dashicons dashicons-yes"></span> 100% No-Risk Money Back Guarantee<br><span class="dashicons dashicons-yes"></span> Secure payment<br><span class="dashicons dashicons-yes"></span> Instant activation</span>';
854 $out .= '</td>';
855 $out .= '<td><div class="gmw-promo-button"><a href="https://gum.co/gmw-yearly?wanted=false&yearly=true&plugin_info=GMW+v' . GMW::$version . '" data-noprevent="1" target="_blank" data-gumroad-single-product="true">$29 <small>/year</small></a></div>';
856 $out .= '<span class="instant-download"><span class="dashicons dashicons-yes"></span> 100% No-Risk Money Back Guarantee<br><span class="dashicons dashicons-yes"></span> Secure payment<br><span class="dashicons dashicons-yes"></span> Instant activation</span>';
857 $out .= '</td>';
858 $out .= '</tr>';
859 $out .= '</table>';
860
861 $out .= '</div></div>'; // dialog intro
862
863 $out .= '<div id="gmw_dialog_activate" style="display: none;" class="gmw_promo_dialog_screen">';
864 $out .= '<div class="content">';
865
866 if (GMW::is_activated()) {
867 $visible = ' style="display: none;"';
868 } else {
869 $visible = '';
870 }
871 $out .= '<div class="before_activate" ' . $visible . '><p class="input_row">
872 <input type="text" id="gmw_code" name="gmw_code" placeholder="Please enter the license key">
873 <span style="display: none;" class="error gmw_code">Unable to verify license key. Unknown error.</span></p>
874 <p class="center">
875 <a href="#" class="button button-primary" id="gmw_activate">Activate PRO features</a>
876 </p>
877 <p class="center">If you don\'t have a license key - <a href="#" class="gmw_goto_intro">Get it now</a></p>
878 </div>';
879
880
881 if (!GMW::is_activated()) {
882 $visible = ' style="display: none;"';
883 } else {
884 $visible = '';
885 }
886
887 $out .= '<div class="after_activate" ' . $visible . '>';
888 $out .= '<p class="center">Thank you for purchasing Maps Widget for Google Maps <b class="gmw-pro-red">PRO</b>! Your license has been verified.</p>';
889 $out .= '<ol class="gmw-faq-ul">
890 <li><a href="https://gmapswidget.com/pro-download/" target="_blank">Download</a> the PRO version ZIP file</li>
891 <li>Go to <a href="' . admin_url('plugin-install.php') . '">Plugins - Add New</a> and install the PRO version</li>
892 <li>When prompted, overwrite the free version with the PRO one</li>
893 <li>Create some maps ;)</li>
894 </ol>';
895 $out .= '</div>';
896
897 $out .= '</div>'; // content
898 $out .= '<div class="footer">
899 <ul class="gmw-faq-ul">
900 <li>Having problems paying or you misplaced your key? <a href="mailto:gmw@webfactoryltd.com?subject=Activation%20key%20problem">Email us</a></li>
901 <li>Key not working or can\'t upgrade? Our <a href="mailto:gmw@webfactoryltd.com?subject=Activation%20key%20problem">support</a> is here to help</li>
902 </ul>
903 </div>';
904 $out .= '</div>'; // activate screen
905
906 $out .= '<div id="gmw_dialog_pro_features" style="display: none;" class="gmw_promo_dialog_screen">
907 <div class="content">';
908 $out .= '<h4>See how <span class="gmw-pro-red">PRO</span> features can make your life easier!</h4>';
909 $out .= '<div class="features-left">';
910 $out .= '<b>Multiple pins support</b><br>';
911 $out .= '<ul class="features-list">';
912 $out .= '<li>Multiple pins support with per-pin options for appearance &amp; click behaviour</li>
913 <li>14 thumbnail &amp; lightbox map skins + create your own fully custom skin</li>
914 <li>1500+ map pins</li>
915 <li>4 extra map image formats for even faster loading</li>
916 <li>replace thumb with interactive map feature</li>
917 <li>extra hidden sidebar for easier shortcode handling</li>';
918 $out .= '</ul><br><br><b>Complete control over map design</b><br>';
919 $out .= '<ul class="features-list">';
920 $out .= '<li>19 map skins + build your own skin option</li>
921 <li>custom map language option</li>
922 <li>4 map modes; directions, view, street & streetview</li>
923 <li>fully customizable pin options for thumbnail map</li>
924 <li>Advanced cache &amp; fastest loading times</li>
925 <li>JS &amp; CSS optimization options</li>';
926 $out .= '</ul>';
927 $out .= '</div>';
928 $out .= '<div class="features-right">';
929 $out .= '<b>Advanced options</b><br>';
930 $out .= '<ul class="features-list">';
931 $out .= '<li>Full control over all pins</li>
932 <li>Complete shortcode support</li>
933 <li>Clustering support</li>
934 <li>Pins grouping &amp; filtering support</li>
935 <li>3 additional map link types</li>
936 <li>Fullscreen lightbox mode</li>
937 <li>Extra lightbox features</li>
938 <li>Disable thumbnail map - immediately load interactive map</li>';
939 $out .= '</ul><br><br><b>Unrivaled support</b><br>';
940 $out .= '<ul class="features-list">
941 <li>Clone widget feature</li>
942 <li>export & import tools</li>
943 <li>Google Analytics integration</li>
944 <li>Premium email support</li>
945 <li>Continuous updates &amp; new features</li>';
946 $out .= '</ul>';
947 $out .= '</div>';
948 $out .= ' </div>';
949 $out .= '<div class="footer">';
950 $out .= '<p class="center"><a href="#" class="button-secondary gmw_goto_intro">Go PRO now</a><br>
951 Or <a href="#" class="gmw_goto_activation">enter the license key</a> if you already have it.</p>';
952 $out .= '</div>';
953 $out .= '</div>'; // pro features screen
954
955 $out .= '</div>'; // dialog
956 } // promo dialog
957
958 // address picker and pins dialog
959 if (GMW::is_plugin_admin_page('widgets')) {
960 $out .= '<div id="gmw_map_dialog" style="display: none;">';
961 $out .= '<div id="gmw_map_canvas"></div><hr>';
962 $out .= '<div id="gmw_map_dialog_footer">';
963
964 $out .= '<p>Address picker is a <b class="gmw-pro-red">PRO</b> feature that gives you the option to easily drag &amp; drop the pin to any location you need and fine-tune its position. <a class="open_promo_dialog" href="#">Upgrade to PRO</a> to have full control over your pins.</p><input type="hidden" autofocus="autofocus" />';
965 $out .= '</div>'; // footer
966 $out .= '</div>'; // dialog
967 } // address picker and pins dialog if activated
968
969 self::wp_kses_wf($out);
970 } // admin_dialogs_markup
971
972
973 // complete options screen markup
974 static function settings_screen() {
975 if (!current_user_can('manage_options')) {
976 wp_die('Cheating? You don\'t have the right to access this page.', 'Maps Widget for Google Maps', array('back_link' => true));
977 }
978
979 $options = GMW::get_options();
980
981 echo '<div class="wrap gmw-options">';
982 echo '<h1><img alt="' . __('Maps Widget for Google Maps', 'google-maps-widget') . '" title="' . __('Maps Widget for Google Maps', 'google-maps-widget') . '" height="55" src="' . esc_url(GMW_PLUGIN_URL) . 'images/gmw-logo.png"> Maps Widget for Google Maps</h1>';
983
984 echo '<form method="post" action="options.php">';
985 settings_fields(GMW::$options);
986
987 echo '<div id="gmw-settings-tabs"><ul>';
988 echo '<li><a href="#gmw-settings">' . __('Settings', 'google-maps-widget') . '</a></li>';
989 echo '<li><a href="#gmw-import-pins">' . __('Import pins', 'google-maps-widget') . '</a></li>';
990 echo '<li><a href="#gmw-export">' . __('Export &amp; Import', 'google-maps-widget') . '</a></li>';
991 echo '<li><a href="#gmw-license">' . __('PRO License', 'google-maps-widget') . '</a></li>';
992 echo '</ul>';
993
994 echo '<div id="gmw-import-pins" style="display: none;">';
995 if (!GMW::is_activated()) {
996 echo '<p>Pins import is one of many <span class="gmw-pro-red">PRO</span> features. <a href="#" class="open_promo_dialog button button-primary">Upgrade now</a> to get access to more than 50 extra options &amp; features.</p>';
997 }
998
999 echo '<table class="form-table disabled">';
1000 echo '<tr>
1001 <th scope="row"><label for="widget_id">' . __('Maps Widget for Google Maps', 'google-maps-widget') . '</label></th>
1002 <td><select disabled="disabled" name="' . esc_attr(GMW::$options) . '[widget_id]" id="widget_id">';
1003 echo '<option value="">- select the widget to import pins to -</option>';
1004 echo '</select><br><span class="description">Choose a widget you want to import pins to. Any existing pins will be overwritten with the new pins. Other widget options will not be altered in any way.</span></td></tr>';
1005
1006 echo '<tr>
1007 <th scope="row"><label for="pins_txt">' . __('Pins, copy/paste', 'google-maps-widget') . '</label></th>';
1008 echo '<td><textarea disabled="disabled" style="width: 500px;" rows="3" name="' . esc_attr(GMW::$options) . '[pins_txt]" id="pins_txt">';
1009 echo '</textarea><br><span class="description">Data has to be formatted in a CSV fashion. One pin per line, individual fields double quoted and separated by a comma. All fields have to be included.<br>
1010 Please refer to the <a href="https://www.gmapswidget.com/documentation/importing-pins/" target="_blank">detailed documentation article</a> or grab the <a href="https://www.gmapswidget.com/wp-content/uploads/2018/02/sample-pins-import.csv" target="_blank">sample import file and modify it.</span></td></tr>';
1011
1012 echo '<tr>
1013 <th scope="row"><label for="pins_file">' . __('Pins, upload file', 'google-maps-widget') . '</label></th>';
1014 echo '<td><input type="file" disabled="disabled" name="pins_file" id="pins_file">';
1015 echo '<br><span class="description">See rules noted for the field above.</span></td></tr>';
1016
1017 echo '<tr>
1018 <th scope="row" colspan="2"><input disabled="disabled" type="submit" name="submit-import-pins" id="submit-import-pins" class="button button-primary button-large" value="Import pins"><br><i style="font-weight: normal;">No data will be written to the widget until you confirm it in step #2.</i></th>';
1019 echo '</tr>';
1020 echo '</table>';
1021
1022 echo '</div>'; // import pins
1023
1024 echo '<div id="gmw-settings" style="display: none;">';
1025 echo '<table class="form-table">';
1026 echo '<tr>
1027 <th scope="row"><label for="api_key">' . __('Google Maps API Key', 'google-maps-widget') . '</label></th>
1028 <td><input name="' . esc_attr(GMW::$options) . '[api_key]" type="text" id="api_key" value="' . esc_attr($options['api_key']) . '" class="regular-text" placeholder="Google Maps API key" oninput="setCustomValidity(\'\')" oninvalid="this.setCustomValidity(\'Please use Google Developers Console to generate an API key and enter it here. It is completely free.\')">
1029 <p class="description">New Google Maps usage policy dictates that everyone using the maps should register for a free API key.<br>
1030 Detailed instruction on how to generate a key in under a minute are available in the <a href="http://www.gmapswidget.com/documentation/generate-google-maps-api-key/" target="_blank">documentation</a>.<br>If you already have a key make sure the following APIs are enabled: Google Maps JavaScript API, Google Static Maps API, Google Maps Embed API &amp; Google Maps Geocoding API.</p></td>
1031
1032 </tr>';
1033 echo '</table>';
1034 self::wp_kses_wf(get_submit_button(__('Save Settings', 'google-maps-widget')));
1035
1036 if (!GMW::is_activated()) {
1037 echo '<p>Not sure if you should upgrade to <span class="gmw-pro-red">PRO</span>? It offers more than 50 extra features like shortcodes, Google Analytics tracking, multiple pins support &amp; much more; <a href="#" class="open_promo_dialog button" data-target-screen="gmw_dialog_pro_features">compare features now</a>.</p>';
1038 }
1039
1040 echo '<h3 class="title disabled"><br>Advanced Settings - available in the PRO version</h3>';
1041 echo '<table class="form-table disabled">';
1042 echo '<tr>
1043 <th scope="row"><label for="sc_map">' . __('Map Shortcode', 'google-maps-widget') . '</label></th>
1044 <td><input class="regular-text" name="' . esc_attr(GMW::$options) . '[sc_map]" type="text" id="sc_map" value="' . esc_attr($options['sc_map']) . '" disabled="disabled" placeholder="Map shortcode" required="required" oninvalid="this.setCustomValidity(\'Please enter the shortcode you want to use for Maps Widget for Google Maps maps.\')" oninput="setCustomValidity(\'\')">
1045 <p class="description">If the default shortcode "gmw" is taken by another plugin change it to something else, eg: "gmaps".</p></td>
1046 </tr>';
1047 echo '<tr>
1048 <th scope="row"><label for="track_ga">' . __('Track with Google Analytics', 'google-maps-widget') . '</label></th>
1049 <td><input name="' . esc_attr(GMW::$options) . '[track_ga]" disabled="disabled" type="checkbox" id="track_ga" value="1"' . checked('1', $options['track_ga'], false) . '>
1050 <span class="description">Each time the interactive map is opened either in lightbox or as a thumbnail replacement a Google Analytics Event will be tracked.<br>You need to have GA already configured on the site. It is fully compatible with all GA plugins and all GA tracking code versions. Default: unchecked.</span></td></tr>';
1051 echo '<tr>
1052 <th scope="row"><label for="include_jquery">' . __('Include jQuery', 'google-maps-widget') . '</label></th>
1053 <td><input name="' . esc_attr(GMW::$options) . '[include_jquery]" disabled="disabled" type="checkbox" id="include_jquery" value="1"' . checked('1', $options['include_jquery'], false) . '>
1054 <span class="description">If you\'re experiencing problems with double jQuery include disable this option. Default: checked.</span></td></tr>';
1055 echo '<tr>
1056 <th scope="row"><label for="include_gmaps_api">' . __('Include Google Maps API JS', 'google-maps-widget') . '</label></th>
1057 <td><input disabled="disabled" name="' . esc_attr(GMW::$options) . '[include_gmaps_api]" type="checkbox" id="include_gmaps_api" value="1"' . checked('1', $options['include_gmaps_api'], false) . '>
1058 <span class="description">If your theme or other plugins already include Google Maps API JS disable this option. Default: checked.</span></td></tr>';
1059 echo '<tr>
1060 <th scope="row"><label for="include_lightbox_css">' . __('Include Colorbox &amp; Thumbnail CSS', 'google-maps-widget') . '</label></th>
1061 <td><input name="' . esc_attr(GMW::$options) . '[include_lightbox_css]" disabled="disabled" type="checkbox" id="include_lightbox_css" value="1"' . checked('1', $options['include_lightbox_css'], false) . '>
1062 <span class="description">If your theme or other plugins already include Colorbox CSS disable this option.<br>Please note that widget (thumbnail map) related CSS will also be removed which will cause minor differences in the way it\'s displayed. Default: checked.</span></td></tr>';
1063 echo '<tr>
1064 <th scope="row"><label for="include_lightbox_js">' . __('Include Colorbox JS', 'google-maps-widget') . '</label></th>
1065 <td><input name="' . esc_attr(GMW::$options) . '[include_lightbox_js]" disabled="disabled" type="checkbox" id="include_lightbox_js" value="1"' . checked('1', $options['include_lightbox_js'], false) . '>
1066 <span class="description">If your theme or other plugins already include Colorbox JS file disable this option. Default: checked.</span></td></tr>';
1067 echo '<tr>
1068 <th scope="row"><label for="disable_tooltips">' . __('Disable Admin Tooltips', 'google-maps-widget') . '</label></th>
1069 <td><input name="' . esc_attr(GMW::$options) . '[disable_tooltips]" type="checkbox" disabled="disabled" id="disable_tooltips" value="1"' . checked('1', $options['disable_tooltips'], false) . '>
1070 <span class="description">All settings in widget edit GUI have tooltips. This setting completely disables them. Default: unchecked.</span></td></tr>';
1071 echo '<tr>
1072 <th scope="row"><label for="disable_sidebar">' . __('Disable Hidden Sidebar', 'google-maps-widget') . '</label></th>
1073 <td><input name="' . esc_attr(GMW::$options) . '[disable_sidebar]" disabled="disabled" type="checkbox" id="disable_sidebar" value="1"' . checked('1', $options['disable_sidebar'], false) . '>
1074 <span class="description">Hidden sidebar helps you to build maps that are displayed with shortcodes. If it bothers you in the admin, disable it. Default: unchecked.</span></td></tr>';
1075 echo '</table>';
1076
1077 echo '</div>'; // settings tab
1078
1079 echo '<div id="gmw-export" style="display: none;">';
1080 if (!GMW::is_activated()) {
1081 echo '<p>Export &amp; Import are one of many <span class="gmw-pro-red">PRO</span> features. <a href="#" class="open_promo_dialog button button-primary">Upgrade now</a> to get access to more than 50 extra options &amp; features.</p>';
1082 }
1083 echo '<table class="form-table disabled">';
1084 echo '<tr>
1085 <th scope="row"><span>' . __('Export widgets', 'google-maps-widget') . '</span></th>
1086 <td><a href="#" class="button button-secondary button-disabled">Download export file</a>
1087 <p class="description">The export file will only contain Maps Widget for Maps Widget for Google Maps. This includes active (in sidebars) widgets and inactive ones as well.</p></td>
1088 </tr>';
1089 echo '<tr>
1090 <th scope="row"><span>' . __('Import widgets', 'google-maps-widget') . '</span></th>
1091 <td><input type="file" disabled="disabled" name="gmw_widgets_import" id="gmw_widgets_import" accept=".txt">
1092 <input type="button" disabled="disabled" name="submit-import" id="submit-import" class="button button-secondary button-large" value="Import widgets">';
1093 echo '<p class="description">Only use TXT export files generated by Maps Widget for Google Maps.<br>
1094 Existing GMW widgets will not be overwritten nor any other widgets touched. If you renamed a sidebar or old one no longer exists widgets will be placed in the inactive widgets area.</p></td>
1095 </tr>';
1096 echo '</table>';
1097 echo '</div>'; // export/import tab
1098
1099 echo '<div id="gmw-license" style="display: none;">';
1100 if (GMW::is_activated()) {
1101 echo '<p>Your <b class="gmw-pro-red">PRO</b> license is validated.';
1102 echo '<ol class="normal">
1103 <li><a href="https://gmapswidget.com/pro-download/" target="_blank">Download</a> the PRO version ZIP file</li>
1104 <li>Go to <a href="' . admin_url('plugin-install.php') . '">Plugins - Add New</a> and install the PRO version</li>
1105 <li>When prompted, overwrite the free version with the PRO one</li>
1106 <li>Create some maps ;)</li>
1107 </ol>';
1108 } else {
1109 echo '<p>If you already bought the <b class="gmw-pro-red">PRO</b> license please <a href="#" data-target-screen="gmw_dialog_activate" class="open_promo_dialog">enter your license key</a> to activate it.</p>';
1110 echo '<p>Interested in a lifetime <b class="gmw-pro-red">PRO</b> license that offers more than 50 extra fetures?&nbsp;&nbsp; <a href="#" class="open_promo_dialog button button-primary">Upgrade now!</a></p>';
1111 }
1112
1113 echo '</div>'; // license tab
1114
1115 echo '</form>';
1116 echo '</div>'; // wrap
1117 } // settings_screen
1118
1119
1120 // check activation code and save if valid
1121 static function activate_license_key_ajax() {
1122 check_ajax_referer('gmw_activate_license_key');
1123
1124 $code = substr(sanitize_key(@$_POST['code']), 0, 64);
1125 $code = str_replace(' ', '', $code);
1126
1127 if (strlen($code) < 6 || strlen($code) > 50) {
1128 wp_send_json_error(__('Please double-check the license key. The format is not valid.', 'google-maps-widget'));
1129 }
1130
1131 $tmp = GMW::validate_activation_code($code);
1132 if ($tmp['success']) {
1133 GMW::set_options(array('activation_code' => $code, 'license_active' => $tmp['license_active'], 'license_type' => $tmp['license_type'], 'license_expires' => $tmp['license_expires']));
1134 }
1135 if ($tmp['license_active'] && $tmp['success']) {
1136 wp_send_json_success();
1137 } else {
1138 wp_send_json_error($tmp['error']);
1139 }
1140 } // activate_license_key_ajax
1141
1142
1143 // helper function for creating dropdowns
1144 static function create_select_options($options, $selected = null, $output = true) {
1145 $out = "\n";
1146
1147 if(!is_array($selected)) {
1148 $selected = array($selected);
1149 }
1150
1151 foreach ($options as $tmp) {
1152 $data = '';
1153 if (isset($tmp['disabled'])) {
1154 $data .= ' disabled="disabled" ';
1155 }
1156 if ($tmp['val'] == '-1') {
1157 $data .= ' class="gmw_promo" ';
1158 }
1159 if (in_array($tmp['val'], $selected)) {
1160 $out .= "<option selected=\"selected\" value=\"{$tmp['val']}\"{$data}>{$tmp['label']}&nbsp;</option>\n";
1161 } else {
1162 $out .= "<option value=\"{$tmp['val']}\"{$data}>{$tmp['label']}&nbsp;</option>\n";
1163 }
1164 } // foreach
1165
1166 if ($output) {
1167 self::wp_kses_wf($out);
1168 } else {
1169 return $out;
1170 }
1171 } // create_select_options
1172
1173 static function wp_kses_wf($html)
1174 {
1175 add_filter('safe_style_css', function ($styles) {
1176 $styles_wf = array(
1177 'text-align',
1178 'margin',
1179 'color',
1180 'float',
1181 'border',
1182 'background',
1183 'background-color',
1184 'border-bottom',
1185 'border-bottom-color',
1186 'border-bottom-style',
1187 'border-bottom-width',
1188 'border-collapse',
1189 'border-color',
1190 'border-left',
1191 'border-left-color',
1192 'border-left-style',
1193 'border-left-width',
1194 'border-right',
1195 'border-right-color',
1196 'border-right-style',
1197 'border-right-width',
1198 'border-spacing',
1199 'border-style',
1200 'border-top',
1201 'border-top-color',
1202 'border-top-style',
1203 'border-top-width',
1204 'border-width',
1205 'caption-side',
1206 'clear',
1207 'cursor',
1208 'direction',
1209 'font',
1210 'font-family',
1211 'font-size',
1212 'font-style',
1213 'font-variant',
1214 'font-weight',
1215 'height',
1216 'letter-spacing',
1217 'line-height',
1218 'margin-bottom',
1219 'margin-left',
1220 'margin-right',
1221 'margin-top',
1222 'overflow',
1223 'padding',
1224 'padding-bottom',
1225 'padding-left',
1226 'padding-right',
1227 'padding-top',
1228 'text-decoration',
1229 'text-indent',
1230 'vertical-align',
1231 'width',
1232 'display',
1233 );
1234
1235 foreach ($styles_wf as $style_wf) {
1236 $styles[] = $style_wf;
1237 }
1238 return $styles;
1239 });
1240
1241 $allowed_tags = wp_kses_allowed_html('post');
1242 $allowed_tags['input'] = array(
1243 'type' => true,
1244 'style' => true,
1245 'class' => true,
1246 'id' => true,
1247 'checked' => true,
1248 'disabled' => true,
1249 'name' => true,
1250 'size' => true,
1251 'placeholder' => true,
1252 'value' => true,
1253 'data-*' => true,
1254 'size' => true,
1255 'disabled' => true
1256 );
1257
1258 $allowed_tags['textarea'] = array(
1259 'type' => true,
1260 'style' => true,
1261 'class' => true,
1262 'id' => true,
1263 'checked' => true,
1264 'disabled' => true,
1265 'name' => true,
1266 'size' => true,
1267 'placeholder' => true,
1268 'value' => true,
1269 'data-*' => true,
1270 'cols' => true,
1271 'rows' => true,
1272 'disabled' => true,
1273 'autocomplete' => true
1274 );
1275
1276 $allowed_tags['select'] = array(
1277 'type' => true,
1278 'style' => true,
1279 'class' => true,
1280 'id' => true,
1281 'checked' => true,
1282 'disabled' => true,
1283 'name' => true,
1284 'size' => true,
1285 'placeholder' => true,
1286 'value' => true,
1287 'data-*' => true,
1288 'multiple' => true,
1289 'disabled' => true
1290 );
1291
1292 $allowed_tags['option'] = array(
1293 'type' => true,
1294 'style' => true,
1295 'class' => true,
1296 'id' => true,
1297 'checked' => true,
1298 'disabled' => true,
1299 'name' => true,
1300 'size' => true,
1301 'placeholder' => true,
1302 'value' => true,
1303 'selected' => true,
1304 'data-*' => true
1305 );
1306 $allowed_tags['optgroup'] = array(
1307 'type' => true,
1308 'style' => true,
1309 'class' => true,
1310 'id' => true,
1311 'checked' => true,
1312 'disabled' => true,
1313 'name' => true,
1314 'size' => true,
1315 'placeholder' => true,
1316 'value' => true,
1317 'selected' => true,
1318 'data-*' => true,
1319 'label' => true
1320 );
1321
1322 $allowed_tags['a'] = array(
1323 'href' => true,
1324 'data-*' => true,
1325 'class' => true,
1326 'style' => true,
1327 'id' => true,
1328 'target' => true,
1329 'data-*' => true,
1330 'role' => true,
1331 'aria-controls' => true,
1332 'aria-selected' => true,
1333 'disabled' => true
1334 );
1335
1336 $allowed_tags['div'] = array(
1337 'style' => true,
1338 'class' => true,
1339 'id' => true,
1340 'data-*' => true,
1341 'role' => true,
1342 'aria-labelledby' => true,
1343 'value' => true,
1344 'aria-modal' => true,
1345 'tabindex' => true
1346 );
1347
1348 $allowed_tags['li'] = array(
1349 'style' => true,
1350 'class' => true,
1351 'id' => true,
1352 'data-*' => true,
1353 'role' => true,
1354 'aria-labelledby' => true,
1355 'value' => true,
1356 'aria-modal' => true,
1357 'tabindex' => true
1358 );
1359
1360 $allowed_tags['span'] = array(
1361 'style' => true,
1362 'class' => true,
1363 'id' => true,
1364 'data-*' => true,
1365 'aria-hidden' => true
1366 );
1367
1368 $allowed_tags['style'] = array(
1369 'class' => true,
1370 'id' => true,
1371 'type' => true
1372 );
1373
1374 $allowed_tags['fieldset'] = array(
1375 'class' => true,
1376 'id' => true,
1377 'type' => true
1378 );
1379
1380 $allowed_tags['link'] = array(
1381 'class' => true,
1382 'id' => true,
1383 'type' => true,
1384 'rel' => true,
1385 'href' => true,
1386 'media' => true
1387 );
1388
1389 $allowed_tags['form'] = array(
1390 'style' => true,
1391 'class' => true,
1392 'id' => true,
1393 'method' => true,
1394 'action' => true,
1395 'data-*' => true
1396 );
1397
1398 $allowed_tags['script'] = array(
1399 'class' => true,
1400 'id' => true,
1401 'type' => true,
1402 'src' => true
1403 );
1404
1405 echo wp_kses($html, $allowed_tags);
1406
1407 add_filter('safe_style_css', function ($styles) {
1408 $styles_wf = array(
1409 'text-align',
1410 'margin',
1411 'color',
1412 'float',
1413 'border',
1414 'background',
1415 'background-color',
1416 'border-bottom',
1417 'border-bottom-color',
1418 'border-bottom-style',
1419 'border-bottom-width',
1420 'border-collapse',
1421 'border-color',
1422 'border-left',
1423 'border-left-color',
1424 'border-left-style',
1425 'border-left-width',
1426 'border-right',
1427 'border-right-color',
1428 'border-right-style',
1429 'border-right-width',
1430 'border-spacing',
1431 'border-style',
1432 'border-top',
1433 'border-top-color',
1434 'border-top-style',
1435 'border-top-width',
1436 'border-width',
1437 'caption-side',
1438 'clear',
1439 'cursor',
1440 'direction',
1441 'font',
1442 'font-family',
1443 'font-size',
1444 'font-style',
1445 'font-variant',
1446 'font-weight',
1447 'height',
1448 'letter-spacing',
1449 'line-height',
1450 'margin-bottom',
1451 'margin-left',
1452 'margin-right',
1453 'margin-top',
1454 'overflow',
1455 'padding',
1456 'padding-bottom',
1457 'padding-left',
1458 'padding-right',
1459 'padding-top',
1460 'text-decoration',
1461 'text-indent',
1462 'vertical-align',
1463 'width'
1464 );
1465
1466 foreach ($styles_wf as $style_wf) {
1467 if (($key = array_search($style_wf, $styles)) !== false) {
1468 unset($styles[$key]);
1469 }
1470 }
1471 return $styles;
1472 });
1473 }
1474
1475
1476 // sanitizes color code string, leaves # intact
1477 static function sanitize_hex_color( $color ) {
1478 if (empty($color)) {
1479 return '#ff0000';
1480 }
1481
1482 // 3 or 6 hex digits
1483 if (preg_match('|^#([A-Fa-f0-9]{3}){1,2}$|', $color)) {
1484 return $color;
1485 }
1486 } // sanitize_hex_color
1487
1488
1489 // converts color from human readable to hex
1490 static function convert_color($color) {
1491 $color_codes = array('black' => '#000000', 'white' => '#ffffff',
1492 'brown' => '#a52a2a', 'green' => '#00ff00',
1493 'purple' => '#800080', 'yellow' => '#ffff00',
1494 'blue' => '#0000ff', 'gray' => '#808080',
1495 'orange' => '#ffa500', 'red' => '#ff0000');
1496
1497 $color = strtolower(trim($color));
1498
1499 if (empty($color) || !isset($color_codes[$color])) {
1500 return '#ff0000';
1501 } else {
1502 return $color_codes[$color];
1503 }
1504 } // convert_color
1505
1506
1507 // helper function for checkbox handling
1508 static function check_var_isset($values, $variables) {
1509 foreach ($variables as $key => $value) {
1510 if (!isset($values[$key])) {
1511 $values[$key] = $value;
1512 }
1513 }
1514
1515 return $values;
1516 } // check_var_isset
1517
1518
1519 // activate doesn't get fired on upgrades so we have to compensate
1520 public static function maybe_upgrade() {
1521 $options = GMW::get_options();
1522
1523 if (!isset($options['first_version']) || !isset($options['first_install'])) {
1524 $options['first_version'] = GMW::$version;
1525 $options['first_install_gmt'] = time();
1526 $options['first_install'] = current_time('timestamp');
1527 GMW::set_options($options);
1528 }
1529 } // maybe_upgrade
1530
1531
1532 // write down a few things on plugin activation
1533 // NO DATA for tracking is sent anywhere unless user explicitly agrees to it!
1534 static function activate() {
1535 $options = GMW::get_options();
1536
1537 if (!isset($options['first_version']) || !isset($options['first_install'])) {
1538 $options['first_version'] = GMW::$version;
1539 $options['first_install'] = current_time('timestamp');
1540 GMW::set_options($options);
1541 }
1542
1543 if (isset($options['allow_tracking']) && $options['allow_tracking'] === true) {
1544 wp_clear_scheduled_hook('gmw_biweekly_cron');
1545 }
1546
1547 self::reset_pointers();
1548 } // activate
1549
1550
1551 // counts the number of active GMW widgets in all sidebars
1552 static function count_active_widgets() {
1553 $count = 0;
1554
1555 $sidebars = get_option('sidebars_widgets', array());
1556 foreach ($sidebars as $sidebar_name => $widgets) {
1557 if (strpos($sidebar_name, 'inactive') !== false || strpos($sidebar_name, 'orphaned') !== false) {
1558 continue;
1559 }
1560 if (is_array($widgets)) {
1561 foreach ($widgets as $widget_name) {
1562 if (strpos($widget_name, 'googlemapswidget') !== false) {
1563 $count++;
1564 }
1565 }
1566 }
1567 } // foreach sidebar
1568
1569 return $count;
1570 } // count_active_widgets
1571
1572
1573 // clean up on deactivation
1574 static function deactivate() {
1575 $options = GMW::get_options();
1576
1577 if (isset($options['allow_tracking']) && $options['allow_tracking'] === true) {
1578 wp_clear_scheduled_hook('gmw_biweekly_cron');
1579 }
1580
1581 delete_transient('gmw_pointers');
1582 } // deactivate
1583
1584
1585 // clean up on uninstall / delete
1586 static function uninstall() {
1587 // at the moment, due to lite/pro upgrade we never delete options
1588 $options = GMW::get_options();
1589
1590 if (isset($options['allow_tracking']) && $options['allow_tracking'] === true) {
1591 wp_clear_scheduled_hook('gmw_biweekly_cron');
1592 }
1593
1594 delete_transient('gmw_pointers');
1595 } // uninstall
1596 } // class GMW
1597
1598 } // if GMW class exists
1599
1600
1601 // hook everything up
1602 register_activation_hook(__FILE__, array('GMW', 'activate'));
1603 register_deactivation_hook(__FILE__, array('GMW', 'deactivate'));
1604 register_uninstall_hook(__FILE__, array('GMW', 'uninstall'));
1605 add_action('init', array('GMW', 'init'));
1606 add_action('plugins_loaded', array('GMW', 'plugins_loaded'));
1607 add_action('widgets_init', array('GMW', 'widgets_init'));
1608