PluginProbe
Maps Widget for Google Maps / 4.27
Maps Widget for Google Maps v4.27
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.27, at google-maps-widget.php

1,615 lines 74.1 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.27
8 Author URI: https://www.gmapswidget.com/
9 Text Domain: google-maps-widget
10 Requires at least: 4.0
11 Requires PHP: 7.2
12 Tested up to: 7.1
13 License: GPLv2 or later
14
15 Copyright 2012 - 2026 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 /* translators: %1$s WordPress version, %2$s is the Dashboard update URL */
243 self::wp_kses_wf('<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 %1$s. Please <a href="%2$s">update it</a>.', 'google-maps-widget'), get_bloginfo('version'), admin_url('update-core.php')) . '</p></div>');
244 } // notice_min_version_error
245
246
247 // get users maps api key or one of temporary plugin ones
248 static function get_api_key($type = 'static') {
249 $options = GMW::get_options();
250 $default_api_keys = array('AIzaSyBvCK51-6tqdH0gu_lsUK8SxlGrvfUzIfo');
251
252 if ($type == 'test' && strlen($options['api_key']) < 30) {
253 return false;
254 }
255
256 if ($type == 'fallback' && empty($options['api_key'])) {
257 shuffle($default_api_keys);
258 return $default_api_keys[0];
259 }
260
261 if (!empty($options['api_key'])) {
262 return $options['api_key'];
263 } else {
264 return false;
265 }
266 } // get_api_key
267
268
269 // checkes if API key is active for all needed API services
270 static function test_api_key_ajax() {
271 check_ajax_referer('gmw_test_api_key');
272
273 $msg = '';
274 $error = false;
275 $api_key = substr(sanitize_key($_GET['api_key'] ?? ''), 0, 128);
276
277 $test = wp_remote_get(esc_url_raw('https://maps.googleapis.com/maps/api/staticmap?center=new+york+usa&size=100x100&key=' . $api_key));
278 if (wp_remote_retrieve_response_message($test) == 'OK') {
279 $msg .= 'Google Static Maps API test - OK' . "\n";
280 } else {
281 $msg .= 'Google Static Maps API test - FAILED' . "\n";
282 $error = true;
283 }
284
285 $test = wp_remote_get(esc_url_raw('https://www.google.com/maps/embed/v1/place?q=new+york+usa&key=' . $api_key));
286 if (wp_remote_retrieve_response_message($test) == 'OK') {
287 $msg .= 'Google Embed Maps API test - OK' . "\n\n";
288 } else {
289 $msg .= 'Google Embed Maps API test - FAILED' . "\n\n";
290 $error = true;
291 }
292
293 if ($error) {
294 $msg .= 'Something is not right. Please read the instruction below on how to generate the API key and double-check everything.';
295 } else {
296 $msg = 'The API key is OK! Don\'t forget to save it ;)';
297 }
298
299 wp_send_json_success($msg);
300 } // test_api_key
301
302
303 // build a complete URL for the iframe map
304 static function build_lightbox_url($widget) {
305 $map_params = array();
306
307 if ($widget['lightbox_mode'] == 'place') {
308 $map_params['q'] = $widget['address'];
309 $map_params['attribution_source'] = get_bloginfo('name')? get_bloginfo('name'): 'Maps Widget for Google Maps';
310 $map_params['attribution_web_url'] = get_home_url();
311 $map_params['attribution_ios_deep_link_id'] = 'comgooglemaps://?daddr=' . $widget['address'];
312 $map_params['maptype'] = $widget['lightbox_map_type'];
313 $map_params['zoom'] = $widget['lightbox_zoom'];
314 } elseif ($widget['lightbox_mode'] == 'directions') {
315 $map_params['origin'] = $widget['lightbox_origin'];
316 $map_params['destination'] = $widget['address'];
317 $map_params['maptype'] = $widget['lightbox_map_type'];
318 if (!empty($widget['lightbox_unit']) && $widget['lightbox_unit'] != 'auto') {
319 $map_params['units'] = $widget['lightbox_unit'];
320 }
321 if ($widget['lightbox_zoom'] != 'auto') {
322 $map_params['zoom'] = $widget['lightbox_zoom'];
323 }
324 } elseif ($widget['lightbox_mode'] == 'search') {
325 if (($coordinates = GMW::get_coordinates($widget['address'])) !== false) {
326 $map_params['center'] = $coordinates['lat'] . ',' . $coordinates['lng'];
327 }
328 $map_params['q'] = $widget['lightbox_search'];
329 $map_params['maptype'] = $widget['lightbox_map_type'];
330 if ($widget['lightbox_zoom'] != 'auto') {
331 $map_params['zoom'] = $widget['lightbox_zoom'];
332 }
333 } elseif ($widget['lightbox_mode'] == 'view') {
334 if (($coordinates = GMW::get_coordinates($widget['address'])) !== false) {
335 $map_params['center'] = $coordinates['lat'] . ',' . $coordinates['lng'];
336 }
337 $map_params['maptype'] = $widget['lightbox_map_type'];
338 if ($widget['lightbox_zoom'] != 'auto') {
339 $map_params['zoom'] = $widget['lightbox_zoom'];
340 }
341 } elseif ($widget['lightbox_mode'] == 'streetview') {
342 if (($coordinates = GMW::get_coordinates($widget['address'])) !== false) {
343 $map_params['location'] = $coordinates['lat'] . ',' . $coordinates['lng'];
344 }
345 $map_params['heading'] = $widget['lightbox_heading'];
346 $map_params['pitch'] = $widget['lightbox_pitch'];
347 }
348
349 if ($widget['lightbox_lang'] != 'auto') {
350 $map_params['language'] = $widget['lightbox_lang'];
351 }
352 $map_params['key'] = GMW::get_api_key('embed');
353
354 $map_url = 'https://www.google.com/maps/embed/v1/' . $widget['lightbox_mode'] . '?';
355 $map_url .= http_build_query($map_params, "", '&amp;');
356
357 return $map_url;
358 } // build_lightbox_url
359
360
361 // fetch coordinates based on the address
362 static function get_coordinates($address, $force_refresh = false) {
363 $address_hash = md5('gmw_' . $address);
364
365 if ($force_refresh || ($data = get_transient($address_hash)) === false) {
366 $url = 'https://maps.googleapis.com/maps/api/geocode/xml?address=' . urlencode($address) . '&key=' . GMW::get_api_key('fallback');
367 $result = wp_remote_get(esc_url_raw($url), array('sslverify' => false, 'timeout' => 10));
368
369 if (!is_wp_error($result) && $result['response']['code'] == 200) {
370 $data = new SimpleXMLElement($result['body']);
371
372 if ($data->status == 'OK') {
373 $cache_value['lat'] = (string) $data->result->geometry->location->lat;
374 $cache_value['lng'] = (string) $data->result->geometry->location->lng;
375 $cache_value['address'] = (string) $data->result->formatted_address;
376
377 // cache coordinates for 2 months
378 set_transient($address_hash, $cache_value, MONTH_IN_SECONDS * 2);
379 $data = $cache_value;
380 $data['cached'] = false;
381 } elseif (!$data->status) {
382 return false;
383 } else {
384 return false;
385 }
386 } else {
387 return false;
388 }
389 } else {
390 // data is cached
391 $data['cached'] = true;
392 }
393
394 return $data;
395 } // get_coordinates
396
397
398 // print dialogs markup in footer
399 static function dialogs_markup() {
400 $out = '';
401 $js_vars = array();
402 $measure_title = array('dark');
403
404 if (empty(GoogleMapsWidget::$widgets)) {
405 return;
406 }
407
408 // add CSS and JS in footer
409 $js_vars['colorbox_css'] = GMW_PLUGIN_URL . 'css/gmw.css' . '?ver=' . GMW::$version;
410 wp_enqueue_script('gmw-colorbox');
411 wp_enqueue_script('gmw');
412 wp_localize_script('gmw', 'gmw_data', $js_vars);
413
414 foreach (GoogleMapsWidget::$widgets as $widget) {
415 $map_url = GMW::build_lightbox_url($widget);
416
417 if ($widget['lightbox_fullscreen']) {
418 $widget['lightbox_width'] = '100%';
419 $widget['lightbox_height'] = '100%';
420 }
421
422 $out .= '<div class="gmw-dialog" style="display: none;" data-map-height="' . $widget['lightbox_height'] . '"
423 data-map-width="' . $widget['lightbox_width'] . '" data-thumb-height="' . $widget['thumb_height'] . '"
424 data-thumb-width="' . $widget['thumb_width'] . '" data-map-skin="' . $widget['lightbox_skin'] . '"
425 data-map-iframe-url="' . $map_url . '" id="gmw-dialog-' . $widget['id'] . '" title="' . esc_attr($widget['title']) . '"
426 data-close-button="' . (int) in_array('close_button', $widget['lightbox_feature']) . '"
427 data-show-title="' . (int) in_array('title', $widget['lightbox_feature']) . '"
428 data-measure-title="' . (int) in_array($widget['lightbox_skin'], $measure_title) . '"
429 data-close-overlay="' . (int) in_array('overlay_close', $widget['lightbox_feature']) . '"
430 data-close-esc="' . (int) in_array('esc_close', $widget['lightbox_feature']) . '">';
431 if ($widget['lightbox_header']) {
432 $tmp = str_ireplace(array('{address}'), array($widget['address']), $widget['lightbox_header']);
433 $out .= '<div class="gmw-header">' . wpautop(do_shortcode($tmp)) . '</div>';
434 }
435 $out .= '<div class="gmw-map"></div>';
436 if ($widget['lightbox_footer']) {
437 $tmp = str_ireplace(array('{address}'), array($widget['address']), $widget['lightbox_footer']);
438 $out .= '<div class="gmw-footer">' . wpautop(do_shortcode($tmp)) . '</div>';
439 }
440 $out .= "</div>\n";
441 } // foreach $widgets
442
443 self::wp_kses_wf($out);
444 } // dialogs_markup
445
446
447 // add plugin menus
448 static function add_menus() {
449 $title = __('Maps Widget for Google Maps', 'google-maps-widget');
450 add_options_page($title, $title, 'manage_options', GMW::$options, array('GMW', 'settings_screen'));
451 } // add_menus
452
453
454 // handle dismiss button for notices
455 static function dismiss_notice() {
456 check_ajax_referer('gmw_dismiss_notice');
457
458 if (empty($_GET['notice'])) {
459 wp_safe_redirect(admin_url());
460 exit;
461 }
462
463 $notice_name = substr(sanitize_key($_GET['notice']), 0, 32);
464
465 if ($notice_name == 'upgrade') {
466 GMW::set_options(array('dismiss_notice_upgrade2' => true));
467 } elseif ($notice_name == 'rate') {
468 GMW::set_options(array('dismiss_notice_rate' => true));
469 } elseif ($notice_name == 'api_key') {
470 GMW::set_options(array('dismiss_notice_api_key' => true));
471 } elseif ($notice_name == 'olduser') {
472 GMW::set_options(array('dismiss_notice_olduser' => true));
473 } else {
474 wp_safe_redirect(admin_url());
475 exit;
476 }
477
478 $redirect = sanitize_text_field(wp_unslash($_GET['redirect'] ?? ''));
479 if (!empty($redirect)) {
480 wp_safe_redirect(esc_url($redirect));
481 } else {
482 wp_safe_redirect(admin_url());
483 }
484
485 exit;
486 } // dismiss_notice
487
488
489 // controls which notices are shown
490 static function add_notices() {
491 $options = GMW::get_options();
492 $notice = false;
493 global $wp_version;
494
495 if (false == is_plugin_active('classic-widgets/classic-widgets.php') && version_compare($wp_version, '5.8', '>=') == true) {
496 $notice = true;
497 add_action('admin_notices', array('GMW', 'notice_classic_widgets'));
498 }
499
500 // upgrade notice is shown after install
501 if (!$notice && empty($options['dismiss_notice_upgrade2']) &&
502 !GMW::is_activated() &&
503 (current_time('timestamp') - $options['first_install']) > 2) {
504 add_action('admin_notices', array('GMW', 'notice_upgrade'));
505 $notice = true;
506 } // show upgrade notice
507
508 // API key notification is shown only on GMW settings page
509 if (!GMW::get_api_key('test') && GMW::is_plugin_admin_page('settings')) {
510 add_action('admin_notices', array('GMW', 'notice_api_key'));
511 $notice = true;
512 } // show api key notice
513
514 // rating notification is shown after 7 days if you have active widgets
515 if (!$notice && empty($options['dismiss_notice_rate']) &&
516 self::count_active_widgets() > 0 &&
517 (current_time('timestamp') - $options['first_install']) > (DAY_IN_SECONDS * 3)) {
518 add_action('admin_notices', array('GMW', 'notice_rate_plugin'));
519 $notice = true;
520 } // show rate notice
521
522 // upsell to old users
523 if (!$notice && empty($options['dismiss_notice_olduser']) &&
524 ((current_time('timestamp') - $options['first_install']) > (DAY_IN_SECONDS * 60))) {
525 add_action('admin_notices', array('GMW', 'notice_olduser'));
526 $notice = true;
527 } // upsell to old users
528 } // add_notices
529
530
531 // display error notice if classic widgets are not available
532 static function notice_classic_widgets() {
533 if(false === get_option('gmw_disable_classic_widgets_alert')){
534 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).
535 <br>Install the official <a href="' . esc_url(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>
536 Or install the <a href="' . esc_url(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>';
537 }
538 } // notice_classic_widgets
539
540
541 // display message to get pro features for GMW
542 static function notice_upgrade() {
543 $promo_delta = HOUR_IN_SECONDS - 2;
544 $options = GMW::get_options();
545 $activate_url = admin_url('options-general.php?page=gmw_options&gmw_open_promo_dialog');
546 $request_url = sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'] ?? '' ));
547 $dismiss_url = add_query_arg(array('action' => 'gmw_dismiss_notice', 'notice' => 'upgrade', 'redirect' => urlencode($request_url)), admin_url('admin.php'));
548 $dismiss_url = wp_nonce_url($dismiss_url, 'gmw_dismiss_notice');
549
550 self::wp_kses_wf('<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'));
551
552 if (current_time('timestamp') - $options['first_install'] < $promo_delta) {
553 $delta = $options['first_install_gmt'] + $promo_delta - time();
554 $h = intval($delta / 3600) % 24;
555 if ($h) {
556 $h .= 'h';
557 } else {
558 $h = '';
559 }
560 $min = intval($delta / 60) % 60;
561 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>';
562 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>';
563 } else {
564 echo '<p><a href="' . esc_url($activate_url) . '" style="vertical-align: baseline; margin-top: 15px;" class="button-primary">' . esc_html__('See what PRO has to offer', 'google-maps-widget') . '</a>';
565 }
566
567 echo '&nbsp;&nbsp;<a href="' . esc_url($dismiss_url) . '" class="">' . esc_html__('I\'m not interested (remove notice)', 'google-maps-widget') . '</a>';
568 echo '</p></div>';
569 } // notice_activate_extra_features
570
571
572 // display message to get pro features for GMW
573 static function notice_olduser() {
574 $options = GMW::get_options();
575 $activate_url = admin_url('options-general.php?page=gmw_options&gmw_open_promo_dialog');
576 $request_url = sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'] ?? '' ));
577 $dismiss_url = add_query_arg(array('action' => 'gmw_dismiss_notice', 'notice' => 'olduser', 'redirect' => urlencode($request_url)), admin_url('admin.php'));
578 $dismiss_url = wp_nonce_url($dismiss_url, 'gmw_dismiss_notice');
579
580 echo '<div class="updated notice">';
581 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>';
582
583 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;">' . esc_html__('I\'m not interested (remove notice)', 'google-maps-widget') . '</a>';
584 echo '</p></div>';
585 } // notice_olduser
586
587
588 // display message to rate plugin
589 static function notice_rate_plugin() {
590 $rate_url = 'https://wordpress.org/support/view/plugin-reviews/google-maps-widget?rate=5#postform';
591 $request_url = sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'] ?? '' ));
592 $dismiss_url = add_query_arg(array('action' => 'gmw_dismiss_notice', 'notice' => 'rate', 'redirect' => urlencode($request_url)), admin_url('admin.php'));
593 $dismiss_url = wp_nonce_url($dismiss_url, 'gmw_dismiss_notice');
594
595 echo '<div id="gmw_rate_notice" class="updated notice"><p>' . esc_html__('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');
596
597 echo '<br><a target="_blank" href="' . esc_url($rate_url) . '" style="vertical-align: baseline; margin-top: 15px;" class="button-primary">' . esc_html__('Help make the plugin better by rating it', 'google-maps-widget') . '</a>';
598 echo '&nbsp;&nbsp;<a href="' . esc_url($dismiss_url) . '">' . esc_html__('I already rated the plugin', 'google-maps-widget') . '</a>';
599 echo '</p></div>';
600 } // notice_rate_plugin
601
602
603 // display message to enter API key
604 static function notice_api_key() {
605 echo '<div id="gmw_api_key_notice" class="error notice"><p>';
606 echo '<b>Important!</b> Google rules dictate that you have to register for a <b>free Google Maps API key</b>. ';
607 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.';
608 echo '</p></div>';
609 } // notice_api_key
610
611
612 // register frontend scripts and styles
613 static function register_scripts() {
614 wp_register_style('gmw', GMW_PLUGIN_URL . 'css/gmw.css', array(), GMW::$version);
615
616 wp_register_script('gmw-colorbox', GMW_PLUGIN_URL . 'js/jquery.colorbox.min.js', array('jquery'), GMW::$version, true);
617 wp_register_script('gmw', GMW_PLUGIN_URL . 'js/gmw.js', array('jquery'), GMW::$version, true);
618 } // register_scripts
619
620
621 // enqueue CSS and JS scripts in admin
622 static function admin_enqueue_scripts() {
623 $js_localize = array('dialog_map_title' => __('Pick an address by drag &amp; dropping the pin', 'google-maps-widget'),
624 'undocumented_error' => __('An undocumented error has occured. Please refresh the page and try again.', 'google-maps-widget'),
625 'bad_api_key' => __('The API key format does not look right. Please double-check it.', 'google-maps-widget'),
626 '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' . '">',
627 'dialog_pins_title' => __('Pins Library', 'google-maps-widget'),
628 'plugin_name' => __('Maps Widget for Google Maps', 'google-maps-widget'),
629 'id_base' => 'googlemapswidget',
630 'map_picker_not_active' => __('Drag&drop address picking interface is a PRO feature. Interested in switching to PRO?', 'google-maps-widget'),
631 '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'),
632 'customizer_pro_dialog' => __('To see what the PRO version offers please open GMW settings in the admin.', 'google-maps-widget'),
633 'map' => false,
634 'marker' => false,
635 'settings_url' => admin_url('options-general.php?page=gmw_options'),
636 'nonce_test_api_key' => wp_create_nonce('gmw_test_api_key'),
637 'nonce_activate_license_key' => wp_create_nonce('gmw_activate_license_key'),
638 'deactivate_confirmation' => __('Are you sure you want to deactivate Maps Widget for Google Maps? 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'));
639
640 if (GMW::is_plugin_admin_page('widgets') || GMW::is_plugin_admin_page('settings') || is_customize_preview()) {
641 wp_enqueue_script('jquery-ui-tabs');
642 wp_enqueue_script('jquery-ui-dialog');
643 wp_enqueue_script('wp-pointer');
644 wp_enqueue_script('gmw-gmap', '//maps.google.com/maps/api/js?key=' . GMW::get_api_key('fallback'), array(), GMW::$version, true);
645 wp_enqueue_script('gmw-select2', GMW_PLUGIN_URL . 'js/select2.min.js', array('jquery'), GMW::$version, true);
646 wp_enqueue_script('gmw-admin', GMW_PLUGIN_URL . 'js/gmw-admin.js', array('jquery'), GMW::$version, true);
647
648 wp_enqueue_style('wp-jquery-ui-dialog');
649 wp_enqueue_style('wp-pointer');
650 wp_enqueue_style('gmw-select2', GMW_PLUGIN_URL . 'css/select2.min.css', array(), GMW::$version);
651 wp_enqueue_style('gmw-admin', GMW_PLUGIN_URL . 'css/gmw-admin.css', array(), GMW::$version);
652
653 wp_localize_script('gmw-admin', 'gmw', $js_localize);
654
655 // fix for agressive plugins
656 wp_dequeue_style('uiStyleSheet');
657 wp_dequeue_style('wpcufpnAdmin' );
658 wp_dequeue_style('unifStyleSheet' );
659 wp_dequeue_style('wpcufpn_codemirror');
660 wp_dequeue_style('wpcufpn_codemirrorTheme');
661 wp_dequeue_style('collapse-admin-css');
662 wp_dequeue_style('jquery-ui-css');
663 wp_dequeue_style('tribe-common-admin');
664 wp_dequeue_style('file-manager__jquery-ui-css');
665 wp_dequeue_style('file-manager__jquery-ui-css-theme');
666 wp_dequeue_style('wpmegmaps-jqueryui');
667 wp_dequeue_style('facebook-plugin-css');
668 wp_dequeue_style('facebook-tip-plugin-css');
669 wp_dequeue_style('facebook-member-plugin-css');
670 wp_dequeue_style('jquery-ui-tooltip-css');
671 wp_dequeue_style('social_warfare_admin');
672 } // if
673
674 if (GMW::is_plugin_admin_page('plugins')) {
675 wp_enqueue_script('gmw-admin-plugins', GMW_PLUGIN_URL . 'js/gmw-admin-plugins.js', array('jquery'), GMW::$version, true);
676 wp_localize_script('gmw-admin-plugins', 'gmw', $js_localize);
677 }
678
679
680 $pointers = get_transient('gmw_pointers');
681 if ($pointers && !GMW::is_plugin_admin_page('widgets') && !GMW::is_plugin_admin_page('settings')) {
682 $pointers['_nonce_dismiss_pointer'] = wp_create_nonce('gmw_dismiss_pointer');
683 wp_enqueue_script('wp-pointer');
684 wp_enqueue_script('gmw-pointers', plugins_url('js/gmw-admin-pointers.js', __FILE__), array('jquery'), self::$version, true);
685 wp_enqueue_style('wp-pointer');
686 wp_localize_script('wp-pointer', 'gmw_pointers', $pointers);
687 }
688 } // admin_enqueue_scripts
689
690
691 // reset all pointers to default state - visible
692 static function reset_pointers() {
693 $pointers = array();
694 $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.');
695
696 set_transient('gmw_pointers', $pointers, 60 * DAY_IN_SECONDS);
697 } // reset_pointers
698
699
700 // permanently dismiss a pointer
701 static function dismiss_pointer_ajax() {
702 check_ajax_referer('gmw_dismiss_pointer');
703
704 $pointers = get_transient('gmw_pointers');
705
706 $pointer = substr(sanitize_key($_POST['pointer'] ?? ''), 0, 64);
707
708 if (empty($pointers) || empty($pointers[$pointer])) {
709 wp_send_json_error();
710 }
711
712 unset($pointers[$pointer]);
713 set_transient('gmw_pointers', $pointers);
714
715 wp_send_json_success();
716 } // dismiss_pointer_ajax
717
718
719 // check if plugin's admin page is shown
720 static function is_plugin_admin_page($page = 'widgets') {
721 $current_screen = get_current_screen();
722
723 if ($page == 'widgets' && $current_screen->id == 'widgets') {
724 return true;
725 }
726
727 if ($page == 'settings' && $current_screen->id == 'settings_page_gmw_options') {
728 return true;
729 }
730
731 if ($page == 'plugins' && $current_screen->id == 'plugins') {
732 return true;
733 }
734
735 return false;
736 } // is_plugin_admin_page
737
738
739 // check if license key is valid and not expired
740 static function is_activated() {
741 $options = GMW::get_options();
742
743 if (isset($options['license_active']) && $options['license_active'] === true &&
744 isset($options['license_expires']) && $options['license_expires'] >= wp_date('Y-m-d')) {
745 return true;
746 } else {
747 return false;
748 }
749 } // is_activated
750
751
752 // check if activation code is valid
753 static function validate_activation_code($code) {
754 $request_params = array('sslverify' => false, 'timeout' => 15, 'redirection' => 2);
755 $request_args = array('action' => 'validate_license',
756 'code' => $code,
757 'codebase' => 'free',
758 'version' => GMW::$version,
759 'site' => get_home_url());
760
761 $out = array('success' => false, 'license_active' => false, 'activation_code' => $code, 'error' => '', 'license_type' => '', 'license_expires' => '1900-01-01');
762
763 $url = add_query_arg($request_args, GMW::$licensing_servers[0]);
764 $response = wp_remote_get(esc_url_raw($url), $request_params);
765
766 if (is_wp_error($response) || !wp_remote_retrieve_body($response)) {
767 $url = add_query_arg($request_args, GMW::$licensing_servers[1]);
768 $response = wp_remote_get(esc_url_raw($url), $request_params);
769 }
770
771 if (!is_wp_error($response) && wp_remote_retrieve_body($response)) {
772 $result = json_decode(wp_remote_retrieve_body($response), true);
773 if (is_array($result['data']) && sizeof($result['data']) == 4) {
774 $out['success'] = true;
775 $out = array_merge($out, $result['data']);
776 } else {
777 $out['error'] = 'Invalid response from licensing server. Please try again later.';
778 }
779 } else {
780 $out['error'] = 'Unable to contact licensing server. Please try again in a few moments.';
781 }
782
783 return $out;
784 } // validate_activation_code
785
786
787 // echo markup for promo dialog; only on widgets page
788 static function admin_dialogs_markup() {
789 $out = '';
790 $options = GMW::get_options();
791 $promo_delta = 1 * HOUR_IN_SECONDS - 5;
792 $promo_active = (bool) ((current_time('timestamp') - $options['first_install']) < $promo_delta);
793 $promo_active2 = (bool) ((current_time('timestamp') - $options['first_install']) > DAY_IN_SECONDS * 35);
794
795 if (GMW::is_plugin_admin_page('widgets') || GMW::is_plugin_admin_page('settings')) {
796 $current_user = wp_get_current_user();
797 if (empty($current_user->user_firstname)) {
798 $name = $current_user->display_name;
799 } else {
800 $name = $current_user->user_firstname;
801 }
802
803 $out .= '<div id="gmw_promo_dialog" style="display: none;">';
804
805 $out .= '<div id="gmw_dialog_intro" class="gmw_promo_dialog_screen">
806 <div class="content">
807 <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>';
808 if ($promo_active) {
809 $delta = $options['first_install_gmt'] + $promo_delta - time();
810 $h = fmod($delta / 3600, 24);
811 $min = fmod($delta / 60, 60);
812 $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>';
813 }
814 $out .= '</div>'; // header
815
816 $out .= '<table id="gmw-pricing-table">';
817 $out .= '<colgroup></colgroup><colgroup></colgroup><colgroup></colgroup>';
818 $out .= '<tr>';
819 $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>';
820 $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>';
821 $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>';
822 $out .= '</tr>';
823 $out .= '<tr>';
824 $out .= '<td>One Time Payment</td>';
825 $out .= '<td><span class="dashicons dashicons-yes"></span> One Time Payment</td>';
826 $out .= '<td>Yearly Payment</td>';
827 $out .= '</tr>';
828 $out .= '<tr>';
829 $out .= '<td>Unlimited Client &amp; Personal Sites</td>';
830 $out .= '<td><span class="dashicons dashicons-yes"></span> 1 Personal Site</td>';
831 $out .= '<td>1 Personal or Client Site</td>';
832 $out .= '</tr>';
833 $out .= '<tr>';
834 $out .= '<td>Lifetime Priority Support</td>';
835 $out .= '<td><span class="dashicons dashicons-yes"></span> Lifetime Priority Support</td>';
836 $out .= '<td>1 Year of Support</td>';
837 $out .= '</tr>';
838 $out .= '<tr>';
839 $out .= '<td>Lifetime Updates</td>';
840 $out .= '<td><span class="dashicons dashicons-yes"></span> Lifetime Updates</td>';
841 $out .= '<td>1 Year of Updates</td>';
842 $out .= '</tr>';
843 $out .= '<tr>';
844 $out .= '<td>';
845 if (1 || $promo_active) {
846 $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>';
847 } else {
848 $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>';
849 }
850 $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>';
851 $out .= '</td>';
852 $out .= '<td>';
853 if (1 || $promo_active) {
854 $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>';
855 } elseif ($promo_active2) {
856 $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>';
857 } else {
858 $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>';
859 }
860 $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>';
861 $out .= '</td>';
862 $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>';
863 $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>';
864 $out .= '</td>';
865 $out .= '</tr>';
866 $out .= '</table>';
867
868 $out .= '</div></div>'; // dialog intro
869
870 $out .= '<div id="gmw_dialog_activate" style="display: none;" class="gmw_promo_dialog_screen">';
871 $out .= '<div class="content">';
872
873 if (GMW::is_activated()) {
874 $visible = ' style="display: none;"';
875 } else {
876 $visible = '';
877 }
878 $out .= '<div class="before_activate" ' . $visible . '><p class="input_row">
879 <input type="text" id="gmw_code" name="gmw_code" placeholder="Please enter the license key">
880 <span style="display: none;" class="error gmw_code">Unable to verify license key. Unknown error.</span></p>
881 <p class="center">
882 <a href="#" class="button button-primary" id="gmw_activate">Activate PRO features</a>
883 </p>
884 <p class="center">If you don\'t have a license key - <a href="#" class="gmw_goto_intro">Get it now</a></p>
885 </div>';
886
887
888 if (!GMW::is_activated()) {
889 $visible = ' style="display: none;"';
890 } else {
891 $visible = '';
892 }
893
894 $out .= '<div class="after_activate" ' . $visible . '>';
895 $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>';
896 $out .= '<ol class="gmw-faq-ul">
897 <li><a href="https://gmapswidget.com/pro-download/" target="_blank">Download</a> the PRO version ZIP file</li>
898 <li>Go to <a href="' . admin_url('plugin-install.php') . '">Plugins - Add New</a> and install the PRO version</li>
899 <li>When prompted, overwrite the free version with the PRO one</li>
900 <li>Create some maps ;)</li>
901 </ol>';
902 $out .= '</div>';
903
904 $out .= '</div>'; // content
905 $out .= '<div class="footer">
906 <ul class="gmw-faq-ul">
907 <li>Having problems paying or you misplaced your key? <a href="mailto:gmw@webfactoryltd.com?subject=Activation%20key%20problem">Email us</a></li>
908 <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>
909 </ul>
910 </div>';
911 $out .= '</div>'; // activate screen
912
913 $out .= '<div id="gmw_dialog_pro_features" style="display: none;" class="gmw_promo_dialog_screen">
914 <div class="content">';
915 $out .= '<h4>See how <span class="gmw-pro-red">PRO</span> features can make your life easier!</h4>';
916 $out .= '<div class="features-left">';
917 $out .= '<b>Multiple pins support</b><br>';
918 $out .= '<ul class="features-list">';
919 $out .= '<li>Multiple pins support with per-pin options for appearance &amp; click behaviour</li>
920 <li>14 thumbnail &amp; lightbox map skins + create your own fully custom skin</li>
921 <li>1500+ map pins</li>
922 <li>4 extra map image formats for even faster loading</li>
923 <li>replace thumb with interactive map feature</li>
924 <li>extra hidden sidebar for easier shortcode handling</li>';
925 $out .= '</ul><br><br><b>Complete control over map design</b><br>';
926 $out .= '<ul class="features-list">';
927 $out .= '<li>19 map skins + build your own skin option</li>
928 <li>custom map language option</li>
929 <li>4 map modes; directions, view, street & streetview</li>
930 <li>fully customizable pin options for thumbnail map</li>
931 <li>Advanced cache &amp; fastest loading times</li>
932 <li>JS &amp; CSS optimization options</li>';
933 $out .= '</ul>';
934 $out .= '</div>';
935 $out .= '<div class="features-right">';
936 $out .= '<b>Advanced options</b><br>';
937 $out .= '<ul class="features-list">';
938 $out .= '<li>Full control over all pins</li>
939 <li>Complete shortcode support</li>
940 <li>Clustering support</li>
941 <li>Pins grouping &amp; filtering support</li>
942 <li>3 additional map link types</li>
943 <li>Fullscreen lightbox mode</li>
944 <li>Extra lightbox features</li>
945 <li>Disable thumbnail map - immediately load interactive map</li>';
946 $out .= '</ul><br><br><b>Unrivaled support</b><br>';
947 $out .= '<ul class="features-list">
948 <li>Clone widget feature</li>
949 <li>export & import tools</li>
950 <li>Google Analytics integration</li>
951 <li>Premium email support</li>
952 <li>Continuous updates &amp; new features</li>';
953 $out .= '</ul>';
954 $out .= '</div>';
955 $out .= ' </div>';
956 $out .= '<div class="footer">';
957 $out .= '<p class="center"><a href="#" class="button-secondary gmw_goto_intro">Go PRO now</a><br>
958 Or <a href="#" class="gmw_goto_activation">enter the license key</a> if you already have it.</p>';
959 $out .= '</div>';
960 $out .= '</div>'; // pro features screen
961
962 $out .= '</div>'; // dialog
963 } // promo dialog
964
965 // address picker and pins dialog
966 if (GMW::is_plugin_admin_page('widgets')) {
967 $out .= '<div id="gmw_map_dialog" style="display: none;">';
968 $out .= '<div id="gmw_map_canvas"></div><hr>';
969 $out .= '<div id="gmw_map_dialog_footer">';
970
971 $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" />';
972 $out .= '</div>'; // footer
973 $out .= '</div>'; // dialog
974 } // address picker and pins dialog if activated
975
976 self::wp_kses_wf($out);
977 } // admin_dialogs_markup
978
979
980 // complete options screen markup
981 static function settings_screen() {
982 if (!current_user_can('manage_options')) {
983 wp_die('Cheating? You don\'t have the right to access this page.', 'Maps Widget for Google Maps', array('back_link' => true));
984 }
985
986 $options = GMW::get_options();
987
988 echo '<div class="wrap gmw-options">';
989 echo '<h1><img alt="' . esc_html__('Maps Widget for Google Maps', 'google-maps-widget') . '" title="' . esc_html__('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>';
990
991 echo '<form method="post" action="options.php">';
992 settings_fields(GMW::$options);
993
994 echo '<div id="gmw-settings-tabs"><ul>';
995 echo '<li><a href="#gmw-settings">' . esc_html__('Settings', 'google-maps-widget') . '</a></li>';
996 echo '<li><a href="#gmw-import-pins">' . esc_html__('Import pins', 'google-maps-widget') . '</a></li>';
997 echo '<li><a href="#gmw-export">' . esc_html__('Export &amp; Import', 'google-maps-widget') . '</a></li>';
998 echo '<li><a href="#gmw-license">' . esc_html__('PRO License', 'google-maps-widget') . '</a></li>';
999 echo '</ul>';
1000
1001 echo '<div id="gmw-import-pins" style="display: none;">';
1002 if (!GMW::is_activated()) {
1003 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>';
1004 }
1005
1006 echo '<table class="form-table disabled">';
1007 echo '<tr>
1008 <th scope="row"><label for="widget_id">' . esc_html__('Maps Widget for Google Maps', 'google-maps-widget') . '</label></th>
1009 <td><select disabled="disabled" name="' . esc_attr(GMW::$options) . '[widget_id]" id="widget_id">';
1010 echo '<option value="">- select the widget to import pins to -</option>';
1011 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>';
1012
1013 echo '<tr>
1014 <th scope="row"><label for="pins_txt">' . esc_html__('Pins, copy/paste', 'google-maps-widget') . '</label></th>';
1015 echo '<td><textarea disabled="disabled" style="width: 500px;" rows="3" name="' . esc_attr(GMW::$options) . '[pins_txt]" id="pins_txt">';
1016 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>
1017 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>';
1018
1019 echo '<tr>
1020 <th scope="row"><label for="pins_file">' . esc_html__('Pins, upload file', 'google-maps-widget') . '</label></th>';
1021 echo '<td><input type="file" disabled="disabled" name="pins_file" id="pins_file">';
1022 echo '<br><span class="description">See rules noted for the field above.</span></td></tr>';
1023
1024 echo '<tr>
1025 <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>';
1026 echo '</tr>';
1027 echo '</table>';
1028
1029 echo '</div>'; // import pins
1030
1031 echo '<div id="gmw-settings" style="display: none;">';
1032 echo '<table class="form-table">';
1033 echo '<tr>
1034 <th scope="row"><label for="api_key">' . esc_html__('Google Maps API Key', 'google-maps-widget') . '</label></th>
1035 <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.\')">
1036 <p class="description">New Google Maps usage policy dictates that everyone using the maps should register for a free API key.<br>
1037 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>
1038
1039 </tr>';
1040 echo '</table>';
1041 self::wp_kses_wf(get_submit_button(__('Save Settings', 'google-maps-widget')));
1042
1043 if (!GMW::is_activated()) {
1044 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>';
1045 }
1046
1047 echo '<h3 class="title disabled"><br>Advanced Settings - available in the PRO version</h3>';
1048 echo '<table class="form-table disabled">';
1049 echo '<tr>
1050 <th scope="row"><label for="sc_map">' . esc_html__('Map Shortcode', 'google-maps-widget') . '</label></th>
1051 <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(\'\')">
1052 <p class="description">If the default shortcode "gmw" is taken by another plugin change it to something else, eg: "gmaps".</p></td>
1053 </tr>';
1054 echo '<tr>
1055 <th scope="row"><label for="track_ga">' . esc_html__('Track with Google Analytics', 'google-maps-widget') . '</label></th>
1056 <td><input name="' . esc_attr(GMW::$options) . '[track_ga]" disabled="disabled" type="checkbox" id="track_ga" value="1"' . checked('1', $options['track_ga'], false) . '>
1057 <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>';
1058 echo '<tr>
1059 <th scope="row"><label for="include_jquery">' . esc_html__('Include jQuery', 'google-maps-widget') . '</label></th>
1060 <td><input name="' . esc_attr(GMW::$options) . '[include_jquery]" disabled="disabled" type="checkbox" id="include_jquery" value="1"' . checked('1', $options['include_jquery'], false) . '>
1061 <span class="description">If you\'re experiencing problems with double jQuery include disable this option. Default: checked.</span></td></tr>';
1062 echo '<tr>
1063 <th scope="row"><label for="include_gmaps_api">' . esc_html__('Include Google Maps API JS', 'google-maps-widget') . '</label></th>
1064 <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) . '>
1065 <span class="description">If your theme or other plugins already include Google Maps API JS disable this option. Default: checked.</span></td></tr>';
1066 echo '<tr>
1067 <th scope="row"><label for="include_lightbox_css">' . esc_html__('Include Colorbox &amp; Thumbnail CSS', 'google-maps-widget') . '</label></th>
1068 <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) . '>
1069 <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>';
1070 echo '<tr>
1071 <th scope="row"><label for="include_lightbox_js">' . esc_html__('Include Colorbox JS', 'google-maps-widget') . '</label></th>
1072 <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) . '>
1073 <span class="description">If your theme or other plugins already include Colorbox JS file disable this option. Default: checked.</span></td></tr>';
1074 echo '<tr>
1075 <th scope="row"><label for="disable_tooltips">' . esc_html__('Disable Admin Tooltips', 'google-maps-widget') . '</label></th>
1076 <td><input name="' . esc_attr(GMW::$options) . '[disable_tooltips]" type="checkbox" disabled="disabled" id="disable_tooltips" value="1"' . checked('1', $options['disable_tooltips'], false) . '>
1077 <span class="description">All settings in widget edit GUI have tooltips. This setting completely disables them. Default: unchecked.</span></td></tr>';
1078 echo '<tr>
1079 <th scope="row"><label for="disable_sidebar">' . esc_html__('Disable Hidden Sidebar', 'google-maps-widget') . '</label></th>
1080 <td><input name="' . esc_attr(GMW::$options) . '[disable_sidebar]" disabled="disabled" type="checkbox" id="disable_sidebar" value="1"' . checked('1', $options['disable_sidebar'], false) . '>
1081 <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>';
1082 echo '</table>';
1083
1084 echo '</div>'; // settings tab
1085
1086 echo '<div id="gmw-export" style="display: none;">';
1087 if (!GMW::is_activated()) {
1088 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>';
1089 }
1090 echo '<table class="form-table disabled">';
1091 echo '<tr>
1092 <th scope="row"><span>' . esc_html__('Export widgets', 'google-maps-widget') . '</span></th>
1093 <td><a href="#" class="button button-secondary button-disabled">Download export file</a>
1094 <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>
1095 </tr>';
1096 echo '<tr>
1097 <th scope="row"><span>' . esc_html__('Import widgets', 'google-maps-widget') . '</span></th>
1098 <td><input type="file" disabled="disabled" name="gmw_widgets_import" id="gmw_widgets_import" accept=".txt">
1099 <input type="button" disabled="disabled" name="submit-import" id="submit-import" class="button button-secondary button-large" value="Import widgets">';
1100 echo '<p class="description">Only use TXT export files generated by Maps Widget for Google Maps.<br>
1101 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>
1102 </tr>';
1103 echo '</table>';
1104 echo '</div>'; // export/import tab
1105
1106 echo '<div id="gmw-license" style="display: none;">';
1107 if (GMW::is_activated()) {
1108 echo '<p>Your <b class="gmw-pro-red">PRO</b> license is validated.';
1109 echo '<ol class="normal">
1110 <li><a href="https://gmapswidget.com/pro-download/" target="_blank">Download</a> the PRO version ZIP file</li>
1111 <li>Go to <a href="' . esc_html(admin_url('plugin-install.php')) . '">Plugins - Add New</a> and install the PRO version</li>
1112 <li>When prompted, overwrite the free version with the PRO one</li>
1113 <li>Create some maps ;)</li>
1114 </ol>';
1115 } else {
1116 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>';
1117 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>';
1118 }
1119
1120 echo '</div>'; // license tab
1121
1122 echo '</form>';
1123 echo '</div>'; // wrap
1124 } // settings_screen
1125
1126
1127 // check activation code and save if valid
1128 static function activate_license_key_ajax() {
1129 check_ajax_referer('gmw_activate_license_key');
1130
1131 $code = substr(sanitize_key($_POST['code'] ?? ''), 0, 64);
1132 $code = str_replace(' ', '', $code);
1133
1134 if (strlen($code) < 6 || strlen($code) > 50) {
1135 wp_send_json_error(__('Please double-check the license key. The format is not valid.', 'google-maps-widget'));
1136 }
1137
1138 $tmp = GMW::validate_activation_code($code);
1139 if ($tmp['success']) {
1140 GMW::set_options(array('activation_code' => $code, 'license_active' => $tmp['license_active'], 'license_type' => $tmp['license_type'], 'license_expires' => $tmp['license_expires']));
1141 }
1142 if ($tmp['license_active'] && $tmp['success']) {
1143 wp_send_json_success();
1144 } else {
1145 wp_send_json_error($tmp['error']);
1146 }
1147 } // activate_license_key_ajax
1148
1149
1150 // helper function for creating dropdowns
1151 static function create_select_options($options, $selected = null, $output = true) {
1152 $out = "\n";
1153
1154 if(!is_array($selected)) {
1155 $selected = array($selected);
1156 }
1157
1158 foreach ($options as $tmp) {
1159 $data = '';
1160 if (isset($tmp['disabled'])) {
1161 $data .= ' disabled="disabled" ';
1162 }
1163 if ($tmp['val'] == '-1') {
1164 $data .= ' class="gmw_promo" ';
1165 }
1166 if (in_array($tmp['val'], $selected)) {
1167 $out .= "<option selected=\"selected\" value=\"{$tmp['val']}\"{$data}>{$tmp['label']}&nbsp;</option>\n";
1168 } else {
1169 $out .= "<option value=\"{$tmp['val']}\"{$data}>{$tmp['label']}&nbsp;</option>\n";
1170 }
1171 } // foreach
1172
1173 if ($output) {
1174 self::wp_kses_wf($out);
1175 } else {
1176 return $out;
1177 }
1178 } // create_select_options
1179
1180 static function wp_kses_wf($html)
1181 {
1182 add_filter('safe_style_css', function ($styles) {
1183 $styles_wf = array(
1184 'text-align',
1185 'margin',
1186 'color',
1187 'float',
1188 'border',
1189 'background',
1190 'background-color',
1191 'border-bottom',
1192 'border-bottom-color',
1193 'border-bottom-style',
1194 'border-bottom-width',
1195 'border-collapse',
1196 'border-color',
1197 'border-left',
1198 'border-left-color',
1199 'border-left-style',
1200 'border-left-width',
1201 'border-right',
1202 'border-right-color',
1203 'border-right-style',
1204 'border-right-width',
1205 'border-spacing',
1206 'border-style',
1207 'border-top',
1208 'border-top-color',
1209 'border-top-style',
1210 'border-top-width',
1211 'border-width',
1212 'caption-side',
1213 'clear',
1214 'cursor',
1215 'direction',
1216 'font',
1217 'font-family',
1218 'font-size',
1219 'font-style',
1220 'font-variant',
1221 'font-weight',
1222 'height',
1223 'letter-spacing',
1224 'line-height',
1225 'margin-bottom',
1226 'margin-left',
1227 'margin-right',
1228 'margin-top',
1229 'overflow',
1230 'padding',
1231 'padding-bottom',
1232 'padding-left',
1233 'padding-right',
1234 'padding-top',
1235 'text-decoration',
1236 'text-indent',
1237 'vertical-align',
1238 'width',
1239 'display',
1240 );
1241
1242 foreach ($styles_wf as $style_wf) {
1243 $styles[] = $style_wf;
1244 }
1245 return $styles;
1246 });
1247
1248 $allowed_tags = wp_kses_allowed_html('post');
1249 $allowed_tags['input'] = array(
1250 'type' => true,
1251 'style' => true,
1252 'class' => true,
1253 'id' => true,
1254 'checked' => true,
1255 'disabled' => true,
1256 'name' => true,
1257 'size' => true,
1258 'placeholder' => true,
1259 'value' => true,
1260 'data-*' => true,
1261 'size' => true,
1262 'disabled' => true
1263 );
1264
1265 $allowed_tags['textarea'] = array(
1266 'type' => true,
1267 'style' => true,
1268 'class' => true,
1269 'id' => true,
1270 'checked' => true,
1271 'disabled' => true,
1272 'name' => true,
1273 'size' => true,
1274 'placeholder' => true,
1275 'value' => true,
1276 'data-*' => true,
1277 'cols' => true,
1278 'rows' => true,
1279 'disabled' => true,
1280 'autocomplete' => true
1281 );
1282
1283 $allowed_tags['select'] = array(
1284 'type' => true,
1285 'style' => true,
1286 'class' => true,
1287 'id' => true,
1288 'checked' => true,
1289 'disabled' => true,
1290 'name' => true,
1291 'size' => true,
1292 'placeholder' => true,
1293 'value' => true,
1294 'data-*' => true,
1295 'multiple' => true,
1296 'disabled' => true
1297 );
1298
1299 $allowed_tags['option'] = array(
1300 'type' => true,
1301 'style' => true,
1302 'class' => true,
1303 'id' => true,
1304 'checked' => true,
1305 'disabled' => true,
1306 'name' => true,
1307 'size' => true,
1308 'placeholder' => true,
1309 'value' => true,
1310 'selected' => true,
1311 'data-*' => true
1312 );
1313 $allowed_tags['optgroup'] = array(
1314 'type' => true,
1315 'style' => true,
1316 'class' => true,
1317 'id' => true,
1318 'checked' => true,
1319 'disabled' => true,
1320 'name' => true,
1321 'size' => true,
1322 'placeholder' => true,
1323 'value' => true,
1324 'selected' => true,
1325 'data-*' => true,
1326 'label' => true
1327 );
1328
1329 $allowed_tags['a'] = array(
1330 'href' => true,
1331 'data-*' => true,
1332 'class' => true,
1333 'style' => true,
1334 'id' => true,
1335 'target' => true,
1336 'data-*' => true,
1337 'role' => true,
1338 'aria-controls' => true,
1339 'aria-selected' => true,
1340 'disabled' => true
1341 );
1342
1343 $allowed_tags['div'] = array(
1344 'style' => true,
1345 'class' => true,
1346 'id' => true,
1347 'data-*' => true,
1348 'role' => true,
1349 'aria-labelledby' => true,
1350 'value' => true,
1351 'aria-modal' => true,
1352 'tabindex' => true
1353 );
1354
1355 $allowed_tags['li'] = array(
1356 'style' => true,
1357 'class' => true,
1358 'id' => true,
1359 'data-*' => true,
1360 'role' => true,
1361 'aria-labelledby' => true,
1362 'value' => true,
1363 'aria-modal' => true,
1364 'tabindex' => true
1365 );
1366
1367 $allowed_tags['span'] = array(
1368 'style' => true,
1369 'class' => true,
1370 'id' => true,
1371 'data-*' => true,
1372 'aria-hidden' => true
1373 );
1374
1375 $allowed_tags['style'] = array(
1376 'class' => true,
1377 'id' => true,
1378 'type' => true
1379 );
1380
1381 $allowed_tags['fieldset'] = array(
1382 'class' => true,
1383 'id' => true,
1384 'type' => true
1385 );
1386
1387 $allowed_tags['link'] = array(
1388 'class' => true,
1389 'id' => true,
1390 'type' => true,
1391 'rel' => true,
1392 'href' => true,
1393 'media' => true
1394 );
1395
1396 $allowed_tags['form'] = array(
1397 'style' => true,
1398 'class' => true,
1399 'id' => true,
1400 'method' => true,
1401 'action' => true,
1402 'data-*' => true
1403 );
1404
1405 $allowed_tags['script'] = array(
1406 'class' => true,
1407 'id' => true,
1408 'type' => true,
1409 'src' => true
1410 );
1411
1412 echo wp_kses($html, $allowed_tags);
1413
1414 add_filter('safe_style_css', function ($styles) {
1415 $styles_wf = array(
1416 'text-align',
1417 'margin',
1418 'color',
1419 'float',
1420 'border',
1421 'background',
1422 'background-color',
1423 'border-bottom',
1424 'border-bottom-color',
1425 'border-bottom-style',
1426 'border-bottom-width',
1427 'border-collapse',
1428 'border-color',
1429 'border-left',
1430 'border-left-color',
1431 'border-left-style',
1432 'border-left-width',
1433 'border-right',
1434 'border-right-color',
1435 'border-right-style',
1436 'border-right-width',
1437 'border-spacing',
1438 'border-style',
1439 'border-top',
1440 'border-top-color',
1441 'border-top-style',
1442 'border-top-width',
1443 'border-width',
1444 'caption-side',
1445 'clear',
1446 'cursor',
1447 'direction',
1448 'font',
1449 'font-family',
1450 'font-size',
1451 'font-style',
1452 'font-variant',
1453 'font-weight',
1454 'height',
1455 'letter-spacing',
1456 'line-height',
1457 'margin-bottom',
1458 'margin-left',
1459 'margin-right',
1460 'margin-top',
1461 'overflow',
1462 'padding',
1463 'padding-bottom',
1464 'padding-left',
1465 'padding-right',
1466 'padding-top',
1467 'text-decoration',
1468 'text-indent',
1469 'vertical-align',
1470 'width'
1471 );
1472
1473 foreach ($styles_wf as $style_wf) {
1474 if (($key = array_search($style_wf, $styles)) !== false) {
1475 unset($styles[$key]);
1476 }
1477 }
1478 return $styles;
1479 });
1480 }
1481
1482
1483 // sanitizes color code string, leaves # intact
1484 static function sanitize_hex_color( $color ) {
1485 if (empty($color)) {
1486 return '#ff0000';
1487 }
1488
1489 // 3 or 6 hex digits
1490 if (preg_match('|^#([A-Fa-f0-9]{3}){1,2}$|', $color)) {
1491 return $color;
1492 }
1493 } // sanitize_hex_color
1494
1495
1496 // converts color from human readable to hex
1497 static function convert_color($color) {
1498 $color_codes = array('black' => '#000000', 'white' => '#ffffff',
1499 'brown' => '#a52a2a', 'green' => '#00ff00',
1500 'purple' => '#800080', 'yellow' => '#ffff00',
1501 'blue' => '#0000ff', 'gray' => '#808080',
1502 'orange' => '#ffa500', 'red' => '#ff0000');
1503
1504 $color = strtolower(trim($color));
1505
1506 if (empty($color) || !isset($color_codes[$color])) {
1507 return '#ff0000';
1508 } else {
1509 return $color_codes[$color];
1510 }
1511 } // convert_color
1512
1513
1514 // helper function for checkbox handling
1515 static function check_var_isset($values, $variables) {
1516 foreach ($variables as $key => $value) {
1517 if (!isset($values[$key])) {
1518 $values[$key] = $value;
1519 }
1520 }
1521
1522 return $values;
1523 } // check_var_isset
1524
1525
1526 // activate doesn't get fired on upgrades so we have to compensate
1527 public static function maybe_upgrade() {
1528 $options = GMW::get_options();
1529
1530 if (!isset($options['first_version']) || !isset($options['first_install'])) {
1531 $options['first_version'] = GMW::$version;
1532 $options['first_install_gmt'] = time();
1533 $options['first_install'] = current_time('timestamp');
1534 GMW::set_options($options);
1535 }
1536 } // maybe_upgrade
1537
1538
1539 // write down a few things on plugin activation
1540 // NO DATA for tracking is sent anywhere unless user explicitly agrees to it!
1541 static function activate() {
1542 $options = GMW::get_options();
1543
1544 if (!isset($options['first_version']) || !isset($options['first_install'])) {
1545 $options['first_version'] = GMW::$version;
1546 $options['first_install'] = current_time('timestamp');
1547 GMW::set_options($options);
1548 }
1549
1550 if (isset($options['allow_tracking']) && $options['allow_tracking'] === true) {
1551 wp_clear_scheduled_hook('gmw_biweekly_cron');
1552 }
1553
1554 self::reset_pointers();
1555 } // activate
1556
1557
1558 // counts the number of active GMW widgets in all sidebars
1559 static function count_active_widgets() {
1560 $count = 0;
1561
1562 $sidebars = get_option('sidebars_widgets', array());
1563 foreach ($sidebars as $sidebar_name => $widgets) {
1564 if (strpos($sidebar_name, 'inactive') !== false || strpos($sidebar_name, 'orphaned') !== false) {
1565 continue;
1566 }
1567 if (is_array($widgets)) {
1568 foreach ($widgets as $widget_name) {
1569 if (strpos($widget_name, 'googlemapswidget') !== false) {
1570 $count++;
1571 }
1572 }
1573 }
1574 } // foreach sidebar
1575
1576 return $count;
1577 } // count_active_widgets
1578
1579
1580 // clean up on deactivation
1581 static function deactivate() {
1582 $options = GMW::get_options();
1583
1584 if (isset($options['allow_tracking']) && $options['allow_tracking'] === true) {
1585 wp_clear_scheduled_hook('gmw_biweekly_cron');
1586 }
1587
1588 delete_transient('gmw_pointers');
1589 } // deactivate
1590
1591
1592 // clean up on uninstall / delete
1593 static function uninstall() {
1594 // at the moment, due to lite/pro upgrade we never delete options
1595 $options = GMW::get_options();
1596
1597 if (isset($options['allow_tracking']) && $options['allow_tracking'] === true) {
1598 wp_clear_scheduled_hook('gmw_biweekly_cron');
1599 }
1600
1601 delete_transient('gmw_pointers');
1602 } // uninstall
1603 } // class GMW
1604
1605 } // if GMW class exists
1606
1607
1608 // hook everything up
1609 register_activation_hook(__FILE__, array('GMW', 'activate'));
1610 register_deactivation_hook(__FILE__, array('GMW', 'deactivate'));
1611 register_uninstall_hook(__FILE__, array('GMW', 'uninstall'));
1612 add_action('init', array('GMW', 'init'));
1613 add_action('plugins_loaded', array('GMW', 'plugins_loaded'));
1614 add_action('widgets_init', array('GMW', 'widgets_init'));
1615