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

1,288 lines 63.2 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.20
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: 5.6
14
15 Copyright 2012 - 2021 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('AIzaSyDlGWq9fCAJopqM0FakFvUWH0J52-tr3UM',
250 'AIzaSyCyD5k7KE2BqpCVoy4dPACJdjvRr2n5ofE');
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, null, '&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 echo $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 if (empty($_GET['notice'])) {
457 wp_safe_redirect(admin_url());
458 exit;
459 }
460
461 $notice_name = substr(sanitize_key($_GET['notice']), 0, 32);
462
463 if ($notice_name == 'upgrade') {
464 GMW::set_options(array('dismiss_notice_upgrade2' => true));
465 } elseif ($notice_name == 'rate') {
466 GMW::set_options(array('dismiss_notice_rate' => true));
467 } elseif ($notice_name == 'api_key') {
468 GMW::set_options(array('dismiss_notice_api_key' => true));
469 } elseif ($notice_name == 'olduser') {
470 GMW::set_options(array('dismiss_notice_olduser' => true));
471 } else {
472 wp_safe_redirect(admin_url());
473 exit;
474 }
475
476 if (!empty($_GET['redirect'])) {
477 wp_safe_redirect(esc_url($_GET['redirect']));
478 } else {
479 wp_safe_redirect(admin_url());
480 }
481
482 exit;
483 } // dismiss_notice
484
485
486 // controls which notices are shown
487 static function add_notices() {
488 $options = GMW::get_options();
489 $notice = false;
490
491 // upgrade notice is shown after install
492 if (!$notice && empty($options['dismiss_notice_upgrade2']) &&
493 !GMW::is_activated() &&
494 (current_time('timestamp') - $options['first_install']) > 2) {
495 add_action('admin_notices', array('GMW', 'notice_upgrade'));
496 $notice = true;
497 } // show upgrade notice
498
499 // API key notification is shown only on GMW settings page
500 if (!GMW::get_api_key('test') && GMW::is_plugin_admin_page('settings')) {
501 add_action('admin_notices', array('GMW', 'notice_api_key'));
502 $notice = true;
503 } // show api key notice
504
505 // rating notification is shown after 7 days if you have active widgets
506 if (!$notice && empty($options['dismiss_notice_rate']) &&
507 self::count_active_widgets() > 0 &&
508 (current_time('timestamp') - $options['first_install']) > (DAY_IN_SECONDS * 3)) {
509 add_action('admin_notices', array('GMW', 'notice_rate_plugin'));
510 $notice = true;
511 } // show rate notice
512
513 // upsell to old users
514 if (!$notice && empty($options['dismiss_notice_olduser']) &&
515 ((current_time('timestamp') - $options['first_install']) > (DAY_IN_SECONDS * 60))) {
516 add_action('admin_notices', array('GMW', 'notice_olduser'));
517 $notice = true;
518 } // upsell to old users
519 } // add_notices
520
521
522 // display message to get pro features for GMW
523 static function notice_upgrade() {
524 $promo_delta = HOUR_IN_SECONDS - 2;
525 $options = GMW::get_options();
526 $activate_url = admin_url('options-general.php?page=gmw_options&gmw_open_promo_dialog');
527 $dismiss_url = add_query_arg(array('action' => 'gmw_dismiss_notice', 'notice' => 'upgrade', 'redirect' => urlencode($_SERVER['REQUEST_URI'])), admin_url('admin.php'));
528
529 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');
530
531 if (current_time('timestamp') - $options['first_install'] < $promo_delta) {
532 $delta = $options['first_install_gmt'] + $promo_delta - time();
533 $h = $delta / 3600 % 24;
534 if ($h) {
535 $h .= 'h';
536 } else {
537 $h = '';
538 }
539 $min = $delta / 60 % 60;
540 echo '<p>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) . '" style="font-weight: bold;">' . $h . ' ' . $min . 'min</b>.</p>';
541 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>';
542 } else {
543 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>';
544 }
545
546 echo '&nbsp;&nbsp;<a href="' . esc_url($dismiss_url) . '" class="">' . __('I\'m not interested (remove notice)', 'google-maps-widget') . '</a>';
547 echo '</p></div>';
548 } // notice_activate_extra_features
549
550
551 // display message to get pro features for GMW
552 static function notice_olduser() {
553 $options = GMW::get_options();
554 $activate_url = admin_url('options-general.php?page=gmw_options&gmw_open_promo_dialog');
555 $dismiss_url = add_query_arg(array('action' => 'gmw_dismiss_notice', 'notice' => 'olduser', 'redirect' => urlencode($_SERVER['REQUEST_URI'])), admin_url('admin.php'));
556
557 echo '<div class="updated notice">';
558 echo '<p style="font-size: 14px;">We have a <a class="open_promo_dialog" href="' . $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="' . $activate_url . '">Upgrade now</a> to <span class="gmw-pro-red">PRO</span> &amp; get more than 50 extra options &amp; features.</p><br>';
559
560 echo '<a class="open_promo_dialog button button-primary" href="' . $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>';
561 echo '</p></div>';
562 } // notice_olduser
563
564
565 // display message to rate plugin
566 static function notice_rate_plugin() {
567 $rate_url = 'https://wordpress.org/support/view/plugin-reviews/google-maps-widget?rate=5#postform';
568 $dismiss_url = add_query_arg(array('action' => 'gmw_dismiss_notice', 'notice' => 'rate', 'redirect' => urlencode($_SERVER['REQUEST_URI'])), admin_url('admin.php'));
569
570 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');
571
572 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>';
573 echo '&nbsp;&nbsp;<a href="' . esc_url($dismiss_url) . '">' . __('I already rated the plugin', 'google-maps-widget') . '</a>';
574 echo '</p></div>';
575 } // notice_rate_plugin
576
577
578 // display message to enter API key
579 static function notice_api_key() {
580 echo '<div id="gmw_api_key_notice" class="error notice"><p>';
581 echo '<b>Important!</b> Google rules dictate that you have to register for a <b>free Google Maps API key</b>. ';
582 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.';
583 echo '</p></div>';
584 } // notice_api_key
585
586
587 // register frontend scripts and styles
588 static function register_scripts() {
589 wp_register_style('gmw', GMW_PLUGIN_URL . 'css/gmw.css', array(), GMW::$version);
590
591 wp_register_script('gmw-colorbox', GMW_PLUGIN_URL . 'js/jquery.colorbox.min.js', array('jquery'), GMW::$version, true);
592 wp_register_script('gmw', GMW_PLUGIN_URL . 'js/gmw.js', array('jquery'), GMW::$version, true);
593 } // register_scripts
594
595
596 // enqueue CSS and JS scripts in admin
597 static function admin_enqueue_scripts() {
598 $js_localize = array('dialog_map_title' => __('Pick an address by drag &amp; dropping the pin', 'google-maps-widget'),
599 'undocumented_error' => __('An undocumented error has occured. Please refresh the page and try again.', 'google-maps-widget'),
600 'bad_api_key' => __('The API key format does not look right. Please double-check it.', 'google-maps-widget'),
601 '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' . '">',
602 'dialog_pins_title' => __('Pins Library', 'google-maps-widget'),
603 'plugin_name' => __('Maps Widget for Google Maps', 'google-maps-widget'),
604 'id_base' => 'googlemapswidget',
605 'map_picker_not_active' => __('Drag&drop address picking interface is a PRO feature. Interested in switching to PRO?', 'google-maps-widget'),
606 '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'),
607 'customizer_pro_dialog' => __('To see what the PRO version offers please open GMW settings in the admin.', 'google-maps-widget'),
608 'map' => false,
609 'marker' => false,
610 'settings_url' => admin_url('options-general.php?page=gmw_options'),
611 'nonce_test_api_key' => wp_create_nonce('gmw_test_api_key'),
612 'nonce_activate_license_key' => wp_create_nonce('gmw_activate_license_key'),
613 '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'));
614
615 if (GMW::is_plugin_admin_page('widgets') || GMW::is_plugin_admin_page('settings') || is_customize_preview()) {
616 wp_enqueue_script('jquery-ui-tabs');
617 wp_enqueue_script('jquery-ui-dialog');
618 wp_enqueue_script('wp-pointer');
619 wp_enqueue_script('gmw-gmap', '//maps.google.com/maps/api/js?key=' . GMW::get_api_key('fallback'), array(), GMW::$version, true);
620 wp_enqueue_script('gmw-select2', GMW_PLUGIN_URL . 'js/select2.min.js', array('jquery'), GMW::$version, true);
621 wp_enqueue_script('gmw-admin', GMW_PLUGIN_URL . 'js/gmw-admin.js', array('jquery'), GMW::$version, true);
622
623 wp_enqueue_style('wp-jquery-ui-dialog');
624 wp_enqueue_style('wp-pointer');
625 wp_enqueue_style('gmw-select2', GMW_PLUGIN_URL . 'css/select2.min.css', array(), GMW::$version);
626 wp_enqueue_style('gmw-admin', GMW_PLUGIN_URL . 'css/gmw-admin.css', array(), GMW::$version);
627
628 wp_localize_script('gmw-admin', 'gmw', $js_localize);
629
630 // fix for agressive plugins
631 wp_dequeue_style('uiStyleSheet');
632 wp_dequeue_style('wpcufpnAdmin' );
633 wp_dequeue_style('unifStyleSheet' );
634 wp_dequeue_style('wpcufpn_codemirror');
635 wp_dequeue_style('wpcufpn_codemirrorTheme');
636 wp_dequeue_style('collapse-admin-css');
637 wp_dequeue_style('jquery-ui-css');
638 wp_dequeue_style('tribe-common-admin');
639 wp_dequeue_style('file-manager__jquery-ui-css');
640 wp_dequeue_style('file-manager__jquery-ui-css-theme');
641 wp_dequeue_style('wpmegmaps-jqueryui');
642 wp_dequeue_style('facebook-plugin-css');
643 wp_dequeue_style('facebook-tip-plugin-css');
644 wp_dequeue_style('facebook-member-plugin-css');
645 wp_dequeue_style('jquery-ui-tooltip-css');
646 wp_dequeue_style('social_warfare_admin');
647 } // if
648
649 if (GMW::is_plugin_admin_page('plugins')) {
650 wp_enqueue_script('gmw-admin-plugins', GMW_PLUGIN_URL . 'js/gmw-admin-plugins.js', array('jquery'), GMW::$version, true);
651 wp_localize_script('gmw-admin-plugins', 'gmw', $js_localize);
652 }
653
654
655 $pointers = get_transient('gmw_pointers');
656 if ($pointers && !GMW::is_plugin_admin_page('widgets') && !GMW::is_plugin_admin_page('settings')) {
657 $pointers['_nonce_dismiss_pointer'] = wp_create_nonce('gmw_dismiss_pointer');
658 wp_enqueue_script('wp-pointer');
659 wp_enqueue_script('gmw-pointers', plugins_url('js/gmw-admin-pointers.js', __FILE__), array('jquery'), self::$version, true);
660 wp_enqueue_style('wp-pointer');
661 wp_localize_script('wp-pointer', 'gmw_pointers', $pointers);
662 }
663 } // admin_enqueue_scripts
664
665
666 // reset all pointers to default state - visible
667 static function reset_pointers() {
668 $pointers = array();
669 $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.');
670
671 set_transient('gmw_pointers', $pointers, 60 * DAY_IN_SECONDS);
672 } // reset_pointers
673
674
675 // permanently dismiss a pointer
676 static function dismiss_pointer_ajax() {
677 check_ajax_referer('gmw_dismiss_pointer');
678
679 $pointers = get_transient('gmw_pointers');
680
681 $pointer = substr(sanitize_key(@$_POST['pointer']), 0, 64);
682
683 if (empty($pointers) || empty($pointers[$pointer])) {
684 wp_send_json_error();
685 }
686
687 unset($pointers[$pointer]);
688 set_transient('gmw_pointers', $pointers);
689
690 wp_send_json_success();
691 } // dismiss_pointer_ajax
692
693
694 // check if plugin's admin page is shown
695 static function is_plugin_admin_page($page = 'widgets') {
696 $current_screen = get_current_screen();
697
698 if ($page == 'widgets' && $current_screen->id == 'widgets') {
699 return true;
700 }
701
702 if ($page == 'settings' && $current_screen->id == 'settings_page_gmw_options') {
703 return true;
704 }
705
706 if ($page == 'plugins' && $current_screen->id == 'plugins') {
707 return true;
708 }
709
710 return false;
711 } // is_plugin_admin_page
712
713
714 // check if license key is valid and not expired
715 static function is_activated() {
716 $options = GMW::get_options();
717
718 if (isset($options['license_active']) && $options['license_active'] === true &&
719 isset($options['license_expires']) && $options['license_expires'] >= date('Y-m-d')) {
720 return true;
721 } else {
722 return false;
723 }
724 } // is_activated
725
726
727 // check if activation code is valid
728 static function validate_activation_code($code) {
729 $request_params = array('sslverify' => false, 'timeout' => 15, 'redirection' => 2);
730 $request_args = array('action' => 'validate_license',
731 'code' => $code,
732 'codebase' => 'free',
733 'version' => GMW::$version,
734 'site' => get_home_url());
735
736 $out = array('success' => false, 'license_active' => false, 'activation_code' => $code, 'error' => '', 'license_type' => '', 'license_expires' => '1900-01-01');
737
738 $url = add_query_arg($request_args, GMW::$licensing_servers[0]);
739 $response = wp_remote_get(esc_url_raw($url), $request_params);
740
741 if (is_wp_error($response) || !wp_remote_retrieve_body($response)) {
742 $url = add_query_arg($request_args, GMW::$licensing_servers[1]);
743 $response = wp_remote_get(esc_url_raw($url), $request_params);
744 }
745
746 if (!is_wp_error($response) && wp_remote_retrieve_body($response)) {
747 $result = json_decode(wp_remote_retrieve_body($response), true);
748 if (is_array($result['data']) && sizeof($result['data']) == 4) {
749 $out['success'] = true;
750 $out = array_merge($out, $result['data']);
751 } else {
752 $out['error'] = 'Invalid response from licensing server. Please try again later.';
753 }
754 } else {
755 $out['error'] = 'Unable to contact licensing server. Please try again in a few moments.';
756 }
757
758 return $out;
759 } // validate_activation_code
760
761
762 // echo markup for promo dialog; only on widgets page
763 static function admin_dialogs_markup() {
764 $out = '';
765 $options = GMW::get_options();
766 $promo_delta = 1 * HOUR_IN_SECONDS - 5;
767 $promo_active = (bool) ((current_time('timestamp') - $options['first_install']) < $promo_delta);
768 $promo_active2 = (bool) ((current_time('timestamp') - $options['first_install']) > DAY_IN_SECONDS * 35);
769
770 if (GMW::is_plugin_admin_page('widgets') || GMW::is_plugin_admin_page('settings')) {
771 $current_user = wp_get_current_user();
772 if (empty($current_user->user_firstname)) {
773 $name = $current_user->display_name;
774 } else {
775 $name = $current_user->user_firstname;
776 }
777
778 $out .= '<div id="gmw_promo_dialog" style="display: none;">';
779
780 $out .= '<div id="gmw_dialog_intro" class="gmw_promo_dialog_screen">
781 <div class="content">
782 <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>';
783 if ($promo_active) {
784 $delta = $options['first_install_gmt'] + $promo_delta - time();
785 $h = $delta / 3600 % 24;
786 $min = $delta / 60 % 60;
787 $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>';
788 }
789 $out .= '</div>'; // header
790
791 $out .= '<table id="gmw-pricing-table">';
792 $out .= '<colgroup></colgroup><colgroup></colgroup><colgroup></colgroup>';
793 $out .= '<tr>';
794 $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>';
795 $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>';
796 $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>';
797 $out .= '</tr>';
798 $out .= '<tr>';
799 $out .= '<td>One Time Payment</td>';
800 $out .= '<td><span class="dashicons dashicons-yes"></span> One Time Payment</td>';
801 $out .= '<td>Yearly Payment</td>';
802 $out .= '</tr>';
803 $out .= '<tr>';
804 $out .= '<td>Unlimited Client &amp; Personal Sites</td>';
805 $out .= '<td><span class="dashicons dashicons-yes"></span> 1 Personal Site</td>';
806 $out .= '<td>1 Personal or Client Site</td>';
807 $out .= '</tr>';
808 $out .= '<tr>';
809 $out .= '<td>Lifetime Priority Support</td>';
810 $out .= '<td><span class="dashicons dashicons-yes"></span> Lifetime Priority Support</td>';
811 $out .= '<td>1 Year of Support</td>';
812 $out .= '</tr>';
813 $out .= '<tr>';
814 $out .= '<td>Lifetime Updates</td>';
815 $out .= '<td><span class="dashicons dashicons-yes"></span> Lifetime Updates</td>';
816 $out .= '<td>1 Year of Updates</td>';
817 $out .= '</tr>';
818 $out .= '<tr>';
819 $out .= '<td>';
820 if (1 || $promo_active) {
821 $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>';
822 } else {
823 $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>';
824 }
825 $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>';
826 $out .= '</td>';
827 $out .= '<td>';
828 if (1 || $promo_active) {
829 $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>';
830 } elseif ($promo_active2) {
831 $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>';
832 } else {
833 $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>';
834 }
835 $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>';
836 $out .= '</td>';
837 $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>';
838 $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>';
839 $out .= '</td>';
840 $out .= '</tr>';
841 $out .= '</table>';
842
843 $out .= '</div></div>'; // dialog intro
844
845 $out .= '<div id="gmw_dialog_activate" style="display: none;" class="gmw_promo_dialog_screen">';
846 $out .= '<div class="content">';
847
848 if (GMW::is_activated()) {
849 $visible = ' style="display: none;"';
850 } else {
851 $visible = '';
852 }
853 $out .= '<div class="before_activate" ' . $visible . '><p class="input_row">
854 <input type="text" id="gmw_code" name="gmw_code" placeholder="Please enter the license key">
855 <span style="display: none;" class="error gmw_code">Unable to verify license key. Unknown error.</span></p>
856 <p class="center">
857 <a href="#" class="button button-primary" id="gmw_activate">Activate PRO features</a>
858 </p>
859 <p class="center">If you don\'t have a license key - <a href="#" class="gmw_goto_intro">Get it now</a></p>
860 </div>';
861
862
863 if (!GMW::is_activated()) {
864 $visible = ' style="display: none;"';
865 } else {
866 $visible = '';
867 }
868
869 $out .= '<div class="after_activate" ' . $visible . '>';
870 $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>';
871 $out .= '<ol class="gmw-faq-ul">
872 <li><a href="https://gmapswidget.com/pro-download/" target="_blank">Download</a> the PRO version ZIP file</li>
873 <li>Go to <a href="' . admin_url('plugin-install.php') . '">Plugins - Add New</a> and install the PRO version</li>
874 <li>When prompted, overwrite the free version with the PRO one</li>
875 <li>Create some maps ;)</li>
876 </ol>';
877 $out .= '</div>';
878
879 $out .= '</div>'; // content
880 $out .= '<div class="footer">
881 <ul class="gmw-faq-ul">
882 <li>Having problems paying or you misplaced your key? <a href="mailto:gmw@webfactoryltd.com?subject=Activation%20key%20problem">Email us</a></li>
883 <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>
884 </ul>
885 </div>';
886 $out .= '</div>'; // activate screen
887
888 $out .= '<div id="gmw_dialog_pro_features" style="display: none;" class="gmw_promo_dialog_screen">
889 <div class="content">';
890 $out .= '<h4>See how <span class="gmw-pro-red">PRO</span> features can make your life easier!</h4>';
891 $out .= '<div class="features-left">';
892 $out .= '<b>Multiple pins support</b><br>';
893 $out .= '<ul class="features-list">';
894 $out .= '<li>Multiple pins support with per-pin options for appearance &amp; click behaviour</li>
895 <li>14 thumbnail &amp; lightbox map skins + create your own fully custom skin</li>
896 <li>1500+ map pins</li>
897 <li>4 extra map image formats for even faster loading</li>
898 <li>replace thumb with interactive map feature</li>
899 <li>extra hidden sidebar for easier shortcode handling</li>';
900 $out .= '</ul><br><br><b>Complete control over map design</b><br>';
901 $out .= '<ul class="features-list">';
902 $out .= '<li>19 map skins + build your own skin option</li>
903 <li>custom map language option</li>
904 <li>4 map modes; directions, view, street & streetview</li>
905 <li>fully customizable pin options for thumbnail map</li>
906 <li>Advanced cache &amp; fastest loading times</li>
907 <li>JS &amp; CSS optimization options</li>';
908 $out .= '</ul>';
909 $out .= '</div>';
910 $out .= '<div class="features-right">';
911 $out .= '<b>Advanced options</b><br>';
912 $out .= '<ul class="features-list">';
913 $out .= '<li>Full control over all pins</li>
914 <li>Complete shortcode support</li>
915 <li>Clustering support</li>
916 <li>Pins grouping &amp; filtering support</li>
917 <li>3 additional map link types</li>
918 <li>Fullscreen lightbox mode</li>
919 <li>Extra lightbox features</li>
920 <li>Disable thumbnail map - immediately load interactive map</li>';
921 $out .= '</ul><br><br><b>Unrivaled support</b><br>';
922 $out .= '<ul class="features-list">
923 <li>Clone widget feature</li>
924 <li>export & import tools</li>
925 <li>Google Analytics integration</li>
926 <li>Premium email support</li>
927 <li>Continuous updates &amp; new features</li>';
928 $out .= '</ul>';
929 $out .= '</div>';
930 $out .= ' </div>';
931 $out .= '<div class="footer">';
932 $out .= '<p class="center"><a href="#" class="button-secondary gmw_goto_intro">Go PRO now</a><br>
933 Or <a href="#" class="gmw_goto_activation">enter the license key</a> if you already have it.</p>';
934 $out .= '</div>';
935 $out .= '</div>'; // pro features screen
936
937 $out .= '</div>'; // dialog
938 } // promo dialog
939
940 // address picker and pins dialog
941 if (GMW::is_plugin_admin_page('widgets')) {
942 $out .= '<div id="gmw_map_dialog" style="display: none;">';
943 $out .= '<div id="gmw_map_canvas"></div><hr>';
944 $out .= '<div id="gmw_map_dialog_footer">';
945
946 $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" />';
947 $out .= '</div>'; // footer
948 $out .= '</div>'; // dialog
949 } // address picker and pins dialog if activated
950
951 echo $out;
952 } // admin_dialogs_markup
953
954
955 // complete options screen markup
956 static function settings_screen() {
957 if (!current_user_can('manage_options')) {
958 wp_die('Cheating? You don\'t have the right to access this page.', 'Maps Widget for Google Maps', array('back_link' => true));
959 }
960
961 $options = GMW::get_options();
962
963 echo '<div class="wrap gmw-options">';
964 echo '<h1><img alt="' . __('Maps Widget for Google Maps', 'google-maps-widget') . '" title="' . __('Maps Widget for Google Maps', 'google-maps-widget') . '" height="55" src="' . GMW_PLUGIN_URL . 'images/gmw-logo.png"> Maps Widget for Google Maps</h1>';
965
966 echo '<form method="post" action="options.php">';
967 settings_fields(GMW::$options);
968
969 echo '<div id="gmw-settings-tabs"><ul>';
970 echo '<li><a href="#gmw-settings">' . __('Settings', 'google-maps-widget') . '</a></li>';
971 echo '<li><a href="#gmw-import-pins">' . __('Import pins', 'google-maps-widget') . '</a></li>';
972 echo '<li><a href="#gmw-export">' . __('Export &amp; Import', 'google-maps-widget') . '</a></li>';
973 echo '<li><a href="#gmw-license">' . __('PRO License', 'google-maps-widget') . '</a></li>';
974 echo '</ul>';
975
976 echo '<div id="gmw-import-pins" style="display: none;">';
977 if (!GMW::is_activated()) {
978 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>';
979 }
980
981 echo '<table class="form-table disabled">';
982 echo '<tr>
983 <th scope="row"><label for="widget_id">' . __('Maps Widget for Google Maps', 'google-maps-widget') . '</label></th>
984 <td><select disabled="disabled" name="' . GMW::$options . '[widget_id]" id="widget_id">';
985 echo '<option value="">- select the widget to import pins to -</option>';
986 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>';
987
988 echo '<tr>
989 <th scope="row"><label for="pins_txt">' . __('Pins, copy/paste', 'google-maps-widget') . '</label></th>';
990 echo '<td><textarea disabled="disabled" style="width: 500px;" rows="3" name="' . GMW::$options . '[pins_txt]" id="pins_txt">';
991 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>
992 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>';
993
994 echo '<tr>
995 <th scope="row"><label for="pins_file">' . __('Pins, upload file', 'google-maps-widget') . '</label></th>';
996 echo '<td><input type="file" disabled="disabled" name="pins_file" id="pins_file">';
997 echo '<br><span class="description">See rules noted for the field above.</span></td></tr>';
998
999 echo '<tr>
1000 <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>';
1001 echo '</tr>';
1002 echo '</table>';
1003
1004 echo '</div>'; // import pins
1005
1006 echo '<div id="gmw-settings" style="display: none;">';
1007 echo '<table class="form-table">';
1008 echo '<tr>
1009 <th scope="row"><label for="api_key">' . __('Google Maps API Key', 'google-maps-widget') . '</label></th>
1010 <td><input name="' . 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.\')">
1011 <p class="description">New Google Maps usage policy dictates that everyone using the maps should register for a free API key.<br>
1012 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>
1013
1014 </tr>';
1015 echo '</table>';
1016 echo get_submit_button(__('Save Settings', 'google-maps-widget'));
1017
1018 if (!GMW::is_activated()) {
1019 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>';
1020 }
1021
1022 echo '<h3 class="title disabled"><br>Advanced Settings - available in the PRO version</h3>';
1023 echo '<table class="form-table disabled">';
1024 echo '<tr>
1025 <th scope="row"><label for="sc_map">' . __('Map Shortcode', 'google-maps-widget') . '</label></th>
1026 <td><input class="regular-text" name="' . 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(\'\')">
1027 <p class="description">If the default shortcode "gmw" is taken by another plugin change it to something else, eg: "gmaps".</p></td>
1028 </tr>';
1029 echo '<tr>
1030 <th scope="row"><label for="track_ga">' . __('Track with Google Analytics', 'google-maps-widget') . '</label></th>
1031 <td><input name="' . GMW::$options . '[track_ga]" disabled="disabled" type="checkbox" id="track_ga" value="1"' . checked('1', $options['track_ga'], false) . '>
1032 <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>';
1033 echo '<tr>
1034 <th scope="row"><label for="include_jquery">' . __('Include jQuery', 'google-maps-widget') . '</label></th>
1035 <td><input name="' . GMW::$options . '[include_jquery]" disabled="disabled" type="checkbox" id="include_jquery" value="1"' . checked('1', $options['include_jquery'], false) . '>
1036 <span class="description">If you\'re experiencing problems with double jQuery include disable this option. Default: checked.</span></td></tr>';
1037 echo '<tr>
1038 <th scope="row"><label for="include_gmaps_api">' . __('Include Google Maps API JS', 'google-maps-widget') . '</label></th>
1039 <td><input disabled="disabled" name="' . GMW::$options . '[include_gmaps_api]" type="checkbox" id="include_gmaps_api" value="1"' . checked('1', $options['include_gmaps_api'], false) . '>
1040 <span class="description">If your theme or other plugins already include Google Maps API JS disable this option. Default: checked.</span></td></tr>';
1041 echo '<tr>
1042 <th scope="row"><label for="include_lightbox_css">' . __('Include Colorbox &amp; Thumbnail CSS', 'google-maps-widget') . '</label></th>
1043 <td><input name="' . GMW::$options . '[include_lightbox_css]" disabled="disabled" type="checkbox" id="include_lightbox_css" value="1"' . checked('1', $options['include_lightbox_css'], false) . '>
1044 <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>';
1045 echo '<tr>
1046 <th scope="row"><label for="include_lightbox_js">' . __('Include Colorbox JS', 'google-maps-widget') . '</label></th>
1047 <td><input name="' . GMW::$options . '[include_lightbox_js]" disabled="disabled" type="checkbox" id="include_lightbox_js" value="1"' . checked('1', $options['include_lightbox_js'], false) . '>
1048 <span class="description">If your theme or other plugins already include Colorbox JS file disable this option. Default: checked.</span></td></tr>';
1049 echo '<tr>
1050 <th scope="row"><label for="disable_tooltips">' . __('Disable Admin Tooltips', 'google-maps-widget') . '</label></th>
1051 <td><input name="' . GMW::$options . '[disable_tooltips]" type="checkbox" disabled="disabled" id="disable_tooltips" value="1"' . checked('1', $options['disable_tooltips'], false) . '>
1052 <span class="description">All settings in widget edit GUI have tooltips. This setting completely disables them. Default: unchecked.</span></td></tr>';
1053 echo '<tr>
1054 <th scope="row"><label for="disable_sidebar">' . __('Disable Hidden Sidebar', 'google-maps-widget') . '</label></th>
1055 <td><input name="' . GMW::$options . '[disable_sidebar]" disabled="disabled" type="checkbox" id="disable_sidebar" value="1"' . checked('1', $options['disable_sidebar'], false) . '>
1056 <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>';
1057 echo '</table>';
1058
1059 echo '</div>'; // settings tab
1060
1061 echo '<div id="gmw-export" style="display: none;">';
1062 if (!GMW::is_activated()) {
1063 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>';
1064 }
1065 echo '<table class="form-table disabled">';
1066 echo '<tr>
1067 <th scope="row"><span>' . __('Export widgets', 'google-maps-widget') . '</span></th>
1068 <td><a href="#" class="button button-secondary button-disabled">Download export file</a>
1069 <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>
1070 </tr>';
1071 echo '<tr>
1072 <th scope="row"><span>' . __('Import widgets', 'google-maps-widget') . '</span></th>
1073 <td><input type="file" disabled="disabled" name="gmw_widgets_import" id="gmw_widgets_import" accept=".txt">
1074 <input type="button" disabled="disabled" name="submit-import" id="submit-import" class="button button-secondary button-large" value="Import widgets">';
1075 echo '<p class="description">Only use TXT export files generated by Maps Widget for Google Maps.<br>
1076 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>
1077 </tr>';
1078 echo '</table>';
1079 echo '</div>'; // export/import tab
1080
1081 echo '<div id="gmw-license" style="display: none;">';
1082 if (GMW::is_activated()) {
1083 echo '<p>Your <b class="gmw-pro-red">PRO</b> license is validated.';
1084 echo '<ol class="normal">
1085 <li><a href="https://gmapswidget.com/pro-download/" target="_blank">Download</a> the PRO version ZIP file</li>
1086 <li>Go to <a href="' . admin_url('plugin-install.php') . '">Plugins - Add New</a> and install the PRO version</li>
1087 <li>When prompted, overwrite the free version with the PRO one</li>
1088 <li>Create some maps ;)</li>
1089 </ol>';
1090 } else {
1091 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>';
1092 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>';
1093 }
1094
1095 echo '</div>'; // license tab
1096
1097 echo '</form>';
1098 echo '</div>'; // wrap
1099 } // settings_screen
1100
1101
1102 // check activation code and save if valid
1103 static function activate_license_key_ajax() {
1104 check_ajax_referer('gmw_activate_license_key');
1105
1106 $code = substr(sanitize_key(@$_POST['code']), 0, 64);
1107 $code = str_replace(' ', '', $code);
1108
1109 if (strlen($code) < 6 || strlen($code) > 50) {
1110 wp_send_json_error(__('Please double-check the license key. The format is not valid.', 'google-maps-widget'));
1111 }
1112
1113 $tmp = GMW::validate_activation_code($code);
1114 if ($tmp['success']) {
1115 GMW::set_options(array('activation_code' => $code, 'license_active' => $tmp['license_active'], 'license_type' => $tmp['license_type'], 'license_expires' => $tmp['license_expires']));
1116 }
1117 if ($tmp['license_active'] && $tmp['success']) {
1118 wp_send_json_success();
1119 } else {
1120 wp_send_json_error($tmp['error']);
1121 }
1122 } // activate_license_key_ajax
1123
1124
1125 // helper function for creating dropdowns
1126 static function create_select_options($options, $selected = null, $output = true) {
1127 $out = "\n";
1128
1129 if(!is_array($selected)) {
1130 $selected = array($selected);
1131 }
1132
1133 foreach ($options as $tmp) {
1134 $data = '';
1135 if (isset($tmp['disabled'])) {
1136 $data .= ' disabled="disabled" ';
1137 }
1138 if ($tmp['val'] == '-1') {
1139 $data .= ' class="gmw_promo" ';
1140 }
1141 if (in_array($tmp['val'], $selected)) {
1142 $out .= "<option selected=\"selected\" value=\"{$tmp['val']}\"{$data}>{$tmp['label']}&nbsp;</option>\n";
1143 } else {
1144 $out .= "<option value=\"{$tmp['val']}\"{$data}>{$tmp['label']}&nbsp;</option>\n";
1145 }
1146 } // foreach
1147
1148 if ($output) {
1149 echo $out;
1150 } else {
1151 return $out;
1152 }
1153 } // create_select_options
1154
1155
1156 // sanitizes color code string, leaves # intact
1157 static function sanitize_hex_color( $color ) {
1158 if (empty($color)) {
1159 return '#ff0000';
1160 }
1161
1162 // 3 or 6 hex digits
1163 if (preg_match('|^#([A-Fa-f0-9]{3}){1,2}$|', $color)) {
1164 return $color;
1165 }
1166 } // sanitize_hex_color
1167
1168
1169 // converts color from human readable to hex
1170 static function convert_color($color) {
1171 $color_codes = array('black' => '#000000', 'white' => '#ffffff',
1172 'brown' => '#a52a2a', 'green' => '#00ff00',
1173 'purple' => '#800080', 'yellow' => '#ffff00',
1174 'blue' => '#0000ff', 'gray' => '#808080',
1175 'orange' => '#ffa500', 'red' => '#ff0000');
1176
1177 $color = strtolower(trim($color));
1178
1179 if (empty($color) || !isset($color_codes[$color])) {
1180 return '#ff0000';
1181 } else {
1182 return $color_codes[$color];
1183 }
1184 } // convert_color
1185
1186
1187 // helper function for checkbox handling
1188 static function check_var_isset($values, $variables) {
1189 foreach ($variables as $key => $value) {
1190 if (!isset($values[$key])) {
1191 $values[$key] = $value;
1192 }
1193 }
1194
1195 return $values;
1196 } // check_var_isset
1197
1198
1199 // activate doesn't get fired on upgrades so we have to compensate
1200 public static function maybe_upgrade() {
1201 $options = GMW::get_options();
1202
1203 if (!isset($options['first_version']) || !isset($options['first_install'])) {
1204 $options['first_version'] = GMW::$version;
1205 $options['first_install_gmt'] = time();
1206 $options['first_install'] = current_time('timestamp');
1207 GMW::set_options($options);
1208 }
1209 } // maybe_upgrade
1210
1211
1212 // write down a few things on plugin activation
1213 // NO DATA for tracking is sent anywhere unless user explicitly agrees to it!
1214 static function activate() {
1215 $options = GMW::get_options();
1216
1217 if (!isset($options['first_version']) || !isset($options['first_install'])) {
1218 $options['first_version'] = GMW::$version;
1219 $options['first_install'] = current_time('timestamp');
1220 GMW::set_options($options);
1221 }
1222
1223 if (isset($options['allow_tracking']) && $options['allow_tracking'] === true) {
1224 wp_clear_scheduled_hook('gmw_biweekly_cron');
1225 }
1226
1227 self::reset_pointers();
1228 } // activate
1229
1230
1231 // counts the number of active GMW widgets in all sidebars
1232 static function count_active_widgets() {
1233 $count = 0;
1234
1235 $sidebars = get_option('sidebars_widgets', array());
1236 foreach ($sidebars as $sidebar_name => $widgets) {
1237 if (strpos($sidebar_name, 'inactive') !== false || strpos($sidebar_name, 'orphaned') !== false) {
1238 continue;
1239 }
1240 if (is_array($widgets)) {
1241 foreach ($widgets as $widget_name) {
1242 if (strpos($widget_name, 'googlemapswidget') !== false) {
1243 $count++;
1244 }
1245 }
1246 }
1247 } // foreach sidebar
1248
1249 return $count;
1250 } // count_active_widgets
1251
1252
1253 // clean up on deactivation
1254 static function deactivate() {
1255 $options = GMW::get_options();
1256
1257 if (isset($options['allow_tracking']) && $options['allow_tracking'] === true) {
1258 wp_clear_scheduled_hook('gmw_biweekly_cron');
1259 }
1260
1261 delete_transient('gmw_pointers');
1262 } // deactivate
1263
1264
1265 // clean up on uninstall / delete
1266 static function uninstall() {
1267 // at the moment, due to lite/pro upgrade we never delete options
1268 $options = GMW::get_options();
1269
1270 if (isset($options['allow_tracking']) && $options['allow_tracking'] === true) {
1271 wp_clear_scheduled_hook('gmw_biweekly_cron');
1272 }
1273
1274 delete_transient('gmw_pointers');
1275 } // uninstall
1276 } // class GMW
1277
1278 } // if GMW class exists
1279
1280
1281 // hook everything up
1282 register_activation_hook(__FILE__, array('GMW', 'activate'));
1283 register_deactivation_hook(__FILE__, array('GMW', 'deactivate'));
1284 register_uninstall_hook(__FILE__, array('GMW', 'uninstall'));
1285 add_action('init', array('GMW', 'init'));
1286 add_action('plugins_loaded', array('GMW', 'plugins_loaded'));
1287 add_action('widgets_init', array('GMW', 'widgets_init'));
1288