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

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