WP Google Maps - Version 8.1.22

Version Description

  • 2022-03-29 =
  • Recompiled some internal files as they were out-dated for some new installations
Download this release

Release Info

Developer DylanAuty
Plugin Icon 128x128 WP Google Maps
Version 8.1.22
Comparing to
See all releases

Code changes from version 8.1.21 to 8.1.22

base/classes/widget_module.class.php CHANGED
@@ -1,129 +1,129 @@
1
- <?php
2
-
3
- if(!defined('ABSPATH'))
4
- exit;
5
-
6
- class wpgmza_widget extends WP_Widget {
7
-
8
- /**
9
- * Widget Constructor
10
- */
11
- function __construct() {
12
- parent::__construct(
13
- 'wpgmza_map_widget',
14
- __('WP Google Maps', 'wp-google-maps'),
15
- array(
16
- 'description' => __( 'Add your map as a widget', 'wp-google-maps' ),
17
- 'classname' => 'wpgmza_widget'
18
- )
19
- );
20
- }
21
-
22
- /**
23
- * Outputs Widget Content
24
- *
25
- * @param array $args Display arguments including 'before_title', 'after_title', 'before_widget', and 'after_widget'.
26
- * @param array $instance The settings for the instance of a widget
27
- *
28
- * @return void
29
- */
30
- public function widget( $args, $instance ) {
31
-
32
- if(!isset($instance['title']))
33
- $instance['title'] = '';
34
-
35
- $title = apply_filters( 'widget_title', $instance['title'] );
36
-
37
- echo $args['before_widget'];
38
- if (!empty($title)){
39
- echo $args['before_title'] . esc_html($title) . $args['after_title'];
40
- }
41
-
42
- if(!isset($instance['selection'])){
43
- global $wpdb;
44
- $instance['selection'] = $wpdb->get_var("SELECT id FROM {$wpdb->prefix}wpgmza_maps ORDER BY id DESC LIMIT 1");
45
- }
46
-
47
- echo do_shortcode("[wpgmza id='".intval($instance['selection'])."']");
48
-
49
- echo $args['after_widget'];
50
- }
51
-
52
- /**
53
- * Outputs the settings update form.
54
- *
55
- * @param array $instance Display arguments including 'before_title', 'after_title', 'before_widget', and 'after_widget'.
56
- *
57
- * @return void/string 'noform' (Default - Inherited)
58
- */
59
- public function form($instance) {
60
- if( $instance) {
61
- if (isset($instance['title'])) { $title = esc_attr($instance['title']); } else { $title = ""; }
62
- if (isset($instance['selection'])) { $selection = esc_attr($instance['selection']); } else { $selection = false; }
63
- } else {
64
- $title = '';
65
- $selection = false;
66
- }
67
-
68
- echo "<p>";
69
- echo "<label for=\"".$this->get_field_id('title')."\">".__('Title', 'wp-google-maps')."</label>";
70
- echo "<input class=\"widefat\" id=\"".$this->get_field_id('title')."\" name=\"".$this->get_field_name('title')."\" type=\"text\" value=\"".$title."\" />";
71
- echo "</p>";
72
-
73
-
74
- echo "<p><label for=\"".$this->get_field_id('selection')."\">".__('Select your map:', 'wp-google-maps')."</label>";
75
- echo "<select class='widefat' name='".$this->get_field_name('selection')."'>";
76
- wpgmza_get_widget_select_field($selection);
77
- echo "</select></p>";
78
-
79
- }
80
-
81
- /**
82
- * Updates a particular instance of a widget.
83
- *
84
- * @param array $new_instance New settings for this instance as input
85
- * @param array $old_instance Old settings for this instance
86
- *
87
- * @return array $instance
88
- */
89
- public function update( $new_instance, $old_instance ) {
90
- $instance = array();
91
- $instance['selection'] = ( ! empty( $new_instance['selection'] ) ) ? strip_tags( $new_instance['selection'] ) : '';
92
- $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
93
-
94
- return $instance;
95
- }
96
- }
97
-
98
- /**
99
- * Registers the 'wpgmza' widget
100
- *
101
- * @return void
102
- */
103
- function wpgmza_load_widget() {
104
- register_widget( 'wpgmza_widget' );
105
- }
106
-
107
- /**
108
- * Outputs the 'options' for the map select field
109
- *
110
- * @return void
111
- */
112
- function wpgmza_get_widget_select_field($selection) {
113
- global $wpdb;
114
- global $wpgmza_tblname_maps;
115
-
116
- if (function_exists('wpgmza_get_widget_select_field_pro')) { wpgmza_get_widget_select_field_pro(); return; }
117
-
118
- $results = $wpdb->get_results("SELECT * FROM $wpgmza_tblname_maps WHERE `active` = 0 ORDER BY `id` DESC ");
119
-
120
- foreach ( $results as $result ) {
121
- $sel = ( intval($selection) == $result->id ) ? "selected" : '';
122
-
123
- echo "<option ".$sel." value=\"".$result->id."\">[ID: ".$result->id."] ".stripslashes($result->map_title)."</option>";
124
- }
125
-
126
-
127
-
128
- }
129
- add_action( 'widgets_init', 'wpgmza_load_widget' );
1
+ <?php
2
+
3
+ if(!defined('ABSPATH'))
4
+ exit;
5
+
6
+ class wpgmza_widget extends WP_Widget {
7
+
8
+ /**
9
+ * Widget Constructor
10
+ */
11
+ function __construct() {
12
+ parent::__construct(
13
+ 'wpgmza_map_widget',
14
+ __('WP Google Maps', 'wp-google-maps'),
15
+ array(
16
+ 'description' => __( 'Add your map as a widget', 'wp-google-maps' ),
17
+ 'classname' => 'wpgmza_widget'
18
+ )
19
+ );
20
+ }
21
+
22
+ /**
23
+ * Outputs Widget Content
24
+ *
25
+ * @param array $args Display arguments including 'before_title', 'after_title', 'before_widget', and 'after_widget'.
26
+ * @param array $instance The settings for the instance of a widget
27
+ *
28
+ * @return void
29
+ */
30
+ public function widget( $args, $instance ) {
31
+
32
+ if(!isset($instance['title']))
33
+ $instance['title'] = '';
34
+
35
+ $title = apply_filters( 'widget_title', $instance['title'] );
36
+
37
+ echo $args['before_widget'];
38
+ if (!empty($title)){
39
+ echo $args['before_title'] . esc_html($title) . $args['after_title'];
40
+ }
41
+
42
+ if(!isset($instance['selection'])){
43
+ global $wpdb;
44
+ $instance['selection'] = $wpdb->get_var("SELECT id FROM {$wpdb->prefix}wpgmza_maps ORDER BY id DESC LIMIT 1");
45
+ }
46
+
47
+ echo do_shortcode("[wpgmza id='".intval($instance['selection'])."']");
48
+
49
+ echo $args['after_widget'];
50
+ }
51
+
52
+ /**
53
+ * Outputs the settings update form.
54
+ *
55
+ * @param array $instance Display arguments including 'before_title', 'after_title', 'before_widget', and 'after_widget'.
56
+ *
57
+ * @return void/string 'noform' (Default - Inherited)
58
+ */
59
+ public function form($instance) {
60
+ if( $instance) {
61
+ if (isset($instance['title'])) { $title = esc_attr($instance['title']); } else { $title = ""; }
62
+ if (isset($instance['selection'])) { $selection = esc_attr($instance['selection']); } else { $selection = false; }
63
+ } else {
64
+ $title = '';
65
+ $selection = false;
66
+ }
67
+
68
+ echo "<p>";
69
+ echo "<label for=\"".$this->get_field_id('title')."\">".__('Title', 'wp-google-maps')."</label>";
70
+ echo "<input class=\"widefat\" id=\"".$this->get_field_id('title')."\" name=\"".$this->get_field_name('title')."\" type=\"text\" value=\"".$title."\" />";
71
+ echo "</p>";
72
+
73
+
74
+ echo "<p><label for=\"".$this->get_field_id('selection')."\">".__('Select your map:', 'wp-google-maps')."</label>";
75
+ echo "<select class='widefat' name='".$this->get_field_name('selection')."'>";
76
+ wpgmza_get_widget_select_field($selection);
77
+ echo "</select></p>";
78
+
79
+ }
80
+
81
+ /**
82
+ * Updates a particular instance of a widget.
83
+ *
84
+ * @param array $new_instance New settings for this instance as input
85
+ * @param array $old_instance Old settings for this instance
86
+ *
87
+ * @return array $instance
88
+ */
89
+ public function update( $new_instance, $old_instance ) {
90
+ $instance = array();
91
+ $instance['selection'] = ( ! empty( $new_instance['selection'] ) ) ? strip_tags( $new_instance['selection'] ) : '';
92
+ $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
93
+
94
+ return $instance;
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Registers the 'wpgmza' widget
100
+ *
101
+ * @return void
102
+ */
103
+ function wpgmza_load_widget() {
104
+ register_widget( 'wpgmza_widget' );
105
+ }
106
+
107
+ /**
108
+ * Outputs the 'options' for the map select field
109
+ *
110
+ * @return void
111
+ */
112
+ function wpgmza_get_widget_select_field($selection) {
113
+ global $wpdb;
114
+ global $wpgmza_tblname_maps;
115
+
116
+ if (function_exists('wpgmza_get_widget_select_field_pro')) { wpgmza_get_widget_select_field_pro(); return; }
117
+
118
+ $results = $wpdb->get_results("SELECT * FROM $wpgmza_tblname_maps WHERE `active` = 0 ORDER BY `id` DESC ");
119
+
120
+ foreach ( $results as $result ) {
121
+ $sel = ( intval($selection) == $result->id ) ? "selected" : '';
122
+
123
+ echo "<option ".$sel." value=\"".$result->id."\">[ID: ".$result->id."] ".stripslashes($result->map_title)."</option>";
124
+ }
125
+
126
+
127
+
128
+ }
129
+ add_action( 'widgets_init', 'wpgmza_load_widget' );
css/common.css CHANGED
@@ -1,801 +1,801 @@
1
- /** Override the auto complete styles */
2
- .pac-container {
3
- border-radius: 2px;
4
- border-top: none;
5
- font-family: Roboto, sans-serif;
6
-
7
- box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
8
- -webkit-box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
9
- -moz-box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
10
- -o-box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
11
- }
12
-
13
- .pac-container .pac-item{
14
- border-top: none;
15
- }
16
-
17
- .pac-container .pac-item .pac-item-query{
18
- color: #333;
19
-
20
- }
21
-
22
- .wpgmza-google-maps-api-error-overlay,
23
- .wpgmza-google-maps-api-error-overlay *
24
- {
25
- text-align: left;
26
- }
27
-
28
- .wpgmza-google-api-error-list
29
- {
30
- list-style: none;
31
- }
32
-
33
- .wpgmza-google-api-error-list li
34
- {
35
- background: ghostwhite;
36
- padding: 0.5em;
37
- margin: 0.5em;
38
- border-color:1px solid #ccc;
39
- }
40
-
41
- .wpgmza-google-api-error-list li:before
42
- {
43
- content: "\26D4";
44
- color: red;
45
- }
46
-
47
- .wpgmza-google-maps-api-error-overlay a
48
- {
49
- color: blue;
50
- }
51
-
52
- .wpgmza-google-maps-api-error-overlay .wpgmza-documentation-buttons
53
- {
54
- float: right;
55
- }
56
-
57
- .wpgmza-google-maps-api-error-overlay .wpgmza-documentation-buttons a
58
- {
59
- color: #444444;
60
- background: #F3F3F3;
61
- border: 1px #DADADA solid;
62
- padding: 5px 10px;
63
- border-radius: 2px;
64
- cursor: pointer;
65
- font-size: 9pt;
66
- outline: none;
67
- }
68
-
69
- .wpgmza-google-maps-api-error-overlay .wpgmza-documentation-buttons a:hover {
70
- border: 1px #C6C6C6 solid;
71
- box-shadow: 1px 1px 1px #EAEAEA;
72
- color: #333333;
73
- background: #F7F7F7;
74
- }
75
-
76
- .wpgmza-google-maps-api-error-overlay .wpgmza-documentation-buttons a:active {
77
- box-shadow: inset 1px 1px 1px #DFDFDF;
78
- }
79
-
80
- .wpgmza-google-maps-api-error-overlay .wpgmza-documentation-buttons a i
81
- {
82
- font-weight: bold;
83
- padding-right: 0.3em;
84
- }
85
-
86
- .wpgmza-google-maps-api-error-overlay .wpgmza-front-end-only
87
- {
88
- color: red;
89
- font-size: 0.8em;
90
- }
91
-
92
- .wpgmza-google-html-overlay
93
- {
94
- position: absolute;
95
- }
96
-
97
- .wpgmza-google-maps-api-error-overlay
98
- {
99
- position: absolute;
100
-
101
- top: 0px;
102
- left: 0px;
103
-
104
- width: 100%;
105
- height: 100%;
106
-
107
- background: rgba(255,255,255,0.95);
108
- padding: 1em;
109
-
110
- text-align: center;
111
- z-index: 2;
112
-
113
- overflow-y: scroll;
114
- }
115
-
116
- [data-wpgmza-table]
117
- {
118
- overflow: visible;
119
- }
120
-
121
- .wpgmza-modern-store-locator .wpgmza_cat_checkbox_holder
122
- {
123
- margin: 0 auto;
124
- pointer-events: all;
125
- }
126
-
127
- .wpgmza-modern-store-locator .wpgmza-inner { flex-wrap: wrap; }
128
-
129
- .ol-info-window-plain
130
- {
131
- min-width: 240px;
132
- }
133
-
134
- .wpgmza-marker-gallery
135
- {
136
- cursor: pointer;
137
- }
138
-
139
- .wpgmza-gallery-input li
140
- {
141
- position: relative;
142
-
143
- width: 120px;
144
- height: 120px;
145
- margin: 0.25em;
146
-
147
- display: inline-block;
148
- vertical-align: top;
149
-
150
- background-size: cover;
151
- box-sizing: border-box;
152
- }
153
-
154
- .wpgmza-gallery-input li.wpgmza-add-new-picture
155
- {
156
- cursor: pointer;
157
- border: #E8E8E8 dashed 6px;
158
- color: #E8E8E8;
159
- }
160
-
161
- .wpgmza-gallery-input li.wpgmza-add-new-picture:hover
162
- {
163
- border-color: lightgray;
164
- color: lightgray;
165
- }
166
-
167
- .wpgmza-gallery-input li.wpgmza-add-new-picture>i
168
- {
169
- position: absolute;
170
-
171
- left: 50%;
172
- top: 50%;
173
-
174
- transform: translate(-50%, -50%);
175
-
176
- font-size: 32px;
177
- }
178
-
179
- #wpgmaps_options fieldset
180
- {
181
- margin-bottom: 1em;
182
- }
183
-
184
- /*(#wpgmaps_options fieldset>*,
185
- .wpgmza-marker-panel fieldset>*
186
- {
187
- display: inline-block;
188
- vertical-align: top;
189
- }*/
190
-
191
- #wpgmaps_options input:disabled + label,
192
- .wpgmza-feature-panel input:disabled + label,
193
- .wpgmza-pro-feature
194
- {
195
- opacity: 0.6;
196
- }
197
-
198
- .wpgmza-feature-panel .wpgmza-save-feature-container button
199
- {
200
- width: 100%;
201
- }
202
-
203
- #wpgmaps_options legend,
204
- .wpgmza-feature-panel legend,
205
- #wpgmza-theme-panel label,
206
- #advanced-markers legend {
207
- width: 20%;
208
- max-width:180px;
209
- }
210
-
211
- #wpgmaps_options [type="number"],
212
- .wpgmza-marker-panel [type="number"]
213
- {
214
- width: 64px;
215
- }
216
-
217
- #wpgmaps_options fieldset>label,
218
- .wpgmza-marker-panel fieldset>label
219
- {
220
- width: 200px;
221
- }
222
-
223
- #wpgmaps_options fieldset>label+div,
224
- .wpgmza-marker-panel fieldset>label+div
225
- {
226
- width: calc(100% - 200px);
227
- }
228
-
229
- .wpgmza-marker-icon-preview
230
- {
231
- width: 32px;
232
- height: 32px;
233
- background-repeat: no-repeat;
234
- background-position: center;
235
- background-size: contain;
236
- border: #E8E8E8 dashed 6px;
237
- }
238
-
239
- .wpgmza-marker-icon-picker>*
240
- {
241
- display: inline-block;
242
- vertical-align: middle;
243
- }
244
-
245
- .wpgmza-rating-gradient-container
246
- {
247
- display: inline-block;
248
- vertical-align: middle;
249
-
250
- border: 1px solid lightgray;
251
- width: 128px;
252
- height: 1em;
253
- }
254
-
255
- .wpgmza-rating-gradient-container>.wpgmza-rating-gradient
256
- {
257
- height: 100%;
258
-
259
- /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ff0000+0,00ff00+100 */
260
- background: #ff0000; /* Old browsers */
261
- background: -moz-linear-gradient(left, #ff0000 0%, #00ff00 128px); /* FF3.6-15 */
262
- background: -webkit-linear-gradient(left, #ff0000 0%,#00ff00 128px); /* Chrome10-25,Safari5.1-6 */
263
- background: linear-gradient(to right, #ff0000 0%,#00ff00 128px); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
264
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff0000', endColorstr='#00ff00',GradientType=1 ); /* IE6-9 */
265
-
266
- pointer-events: none;
267
-
268
- transition: width 0.5s;
269
- }
270
-
271
- .wpgmza-rating-stars-container
272
- {
273
- position: relative;
274
- font-size: 1.5em;
275
- cursor: pointer;
276
- }
277
-
278
- .wpgmza-rating-stars-container + .wpgmza-num-ratings
279
- {
280
- position: relative;
281
- }
282
-
283
- .wpgmza-rating-stars-container>span
284
- {
285
- position: absolute;
286
- top: 0px;
287
- left: 0px;
288
- padding-top: 0.3em;
289
- }
290
-
291
- .wpgmza-rating-stars-container>span.wpgmza-background
292
- {
293
- text-shadow: 0px 0px 2px black;
294
- }
295
-
296
- .wpgmza-rating-stars-container>span.wpgmza-foreground
297
- {
298
- overflow: hidden;
299
- color: yellow;
300
- text-shadow: 0px -1px 3px orange inner;
301
- }
302
-
303
- .wpgmza-rating-thumbs-container i
304
- {
305
- /* display: none; */
306
- }
307
-
308
- .wpgmza-rating-thumbs-container, .wpgmza-rating-thumbs-container *
309
- {
310
- display: inline-block;
311
- vertical-align: middle;
312
- }
313
-
314
- .wpgmza-rating-thumbs-container
315
- {
316
- background: ghostwhite;
317
- /* background: linear-gradient(to right, #88AFD0 0%, #88AFD0 75%, transparent 75%, transparent 100%); */
318
-
319
- border: 1px solid lightgrey;
320
- border-radius: 6px;
321
- }
322
-
323
- .wpgmza-rating-thumbs-container>span.wpgmza-downvote,
324
- .wpgmza-rating-thumbs-container>span.wpgmza-upvote
325
- {
326
- padding: 0.5em 1em;
327
- }
328
-
329
- .wpgmza-rating-thumbs-container i
330
- {
331
- position: relative;
332
- font-size: 1.5em;
333
-
334
- top: 0.0em;
335
- transition: top 0.6s;
336
- }
337
-
338
- .wpgmza-rating-thumbs-container .wpgmza-upvote>i
339
- {
340
- top: -0.05em;
341
- }
342
-
343
- .wpgmza-rating-thumbs-container .wpgmza-down>i
344
- {
345
- top: 0.05em;
346
- }
347
-
348
- .wpgmza-rating-thumbs-container .wpgmza-upvote:hover>i
349
- {
350
- top: -0.25em;
351
- }
352
-
353
- .wpgmza-rating-thumbs-container .wpgmza-downvote:hover>i
354
- {
355
- top: 0.25em;
356
- }
357
-
358
- .wpgmza-rating-thumbs-container>span.wpgmza-upvote
359
- {
360
- border-left: 1px solid lightgrey;
361
- }
362
-
363
- .wpgmza-rating-thumbs-container>span:hover,
364
- .wpgmza-rating-thumbs-container>span.wpgmza-remembered-rating
365
- {
366
- /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,c9c9c9+100&0.5+0,0.2+100 */
367
- background: -moz-linear-gradient(top, rgba(255,255,255,0.5) 0%, rgba(201,201,201,0.2) 100%); /* FF3.6-15 */
368
- background: -webkit-linear-gradient(top, rgba(255,255,255,0.5) 0%,rgba(201,201,201,0.2) 100%); /* Chrome10-25,Safari5.1-6 */
369
- background: linear-gradient(to bottom, rgba(255,255,255,0.5) 0%,rgba(201,201,201,0.2) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
370
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#80ffffff', endColorstr='#33c9c9c9',GradientType=0 ); /* IE6-9 */
371
- }
372
-
373
- .wpgmza-rating-thumbs-container>span:active
374
- {
375
- /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,c9c9c9+100&0.5+0,0.2+100 */
376
- background: -moz-linear-gradient(bottom, rgba(255,255,255,0.5) 0%, rgba(201,201,201,0.2) 100%); /* FF3.6-15 */
377
- background: -webkit-linear-gradient(bottom, rgba(255,255,255,0.5) 0%,rgba(201,201,201,0.2) 100%); /* Chrome10-25,Safari5.1-6 */
378
- background: linear-gradient(to top, rgba(255,255,255,0.5) 0%,rgba(201,201,201,0.2) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
379
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#33c9c9c9', endColorstr='#80ffffff',GradientType=0 ); /* IE6-9 */
380
- }
381
-
382
- .wpgmza-rating.wpgmza-loading
383
- {
384
- filter: grayscale(100%);
385
- }
386
-
387
- .wpgmza-google-text-overlay > .wpgmza-inner
388
- {
389
- position: absolute;
390
- transform: translate(-50%, -50%);
391
-
392
- text-align: center;
393
- font-weight: bold;
394
-
395
- text-shadow: 0px 0px 2px white;
396
- text-shadow: 0px 0px 2px white,
397
- 0px 0px 2px white,
398
- 0px 0px 2px white,
399
- 0px 0px 2px white;
400
- }
401
-
402
- .wpgmza-modern-store-locator {
403
- text-align: center;
404
- padding-top: 10px;
405
- }
406
-
407
- .wpgmza-modern-store-locator > .wpgmza-inner {
408
- display: inline-block;
409
- background: white;
410
- padding: 0.5em !important;
411
-
412
- border-radius: 2px;
413
- font-family: Roboto, sans-serif;
414
-
415
- box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
416
- -webkit-box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
417
- -moz-box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
418
- -o-box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
419
-
420
- }
421
-
422
- .wpgmza-modern-store-locator input,
423
- .wpgmza-modern-store-locator select {
424
- height: 28px !important;
425
- vertical-align: top;
426
- padding: 0 6px !important;
427
- margin: 0 2px;
428
- color: #777;
429
- }
430
-
431
- .wpgmza-select-theme-preset
432
- {
433
- position: absolute;
434
- right: 0.5em;
435
- bottom: 0.5em;
436
- }
437
-
438
- #wpgmza-theme-editor
439
- {
440
-
441
- background: #fff;
442
- z-index: 999;
443
- box-sizing: border-box;
444
- overflow-y: auto;
445
- }
446
-
447
- #wpgmza-theme-editor>*
448
- {
449
- }
450
-
451
- #wpgmza-theme-editor fieldset>label
452
- {
453
- width: 100px;
454
- }
455
-
456
- #wpgmza-theme-editor fieldset>label + div
457
- {
458
- display: inline-block;
459
- vertical-align: middle;
460
- }
461
-
462
- #wpgmza-theme-editor fieldset>label + div > input[type="checkbox"]:not(:checked) + input
463
- {
464
- display: none;
465
- }
466
-
467
- .wpgmza-import-log
468
- {
469
- display: none;
470
- position: relative;
471
- }
472
-
473
- .wpgmza-import-log > .wpgmza-log-contents
474
- {
475
- white-space: pre-wrap;
476
- display: block;
477
- word-wrap: break-word;
478
- border: 1px dotted grey;
479
- padding: 1em;
480
- font-family: monospace;
481
- font-size: 11px;
482
- }
483
-
484
- .wpgmza-import-log-buttons
485
- {
486
- position: absolute;
487
- right: 0;
488
- bottom: 100%;
489
- }
490
-
491
- /* Global settings page */
492
-
493
- #wpgmza-global-settings>ul>li
494
- {
495
- display: inline-block;
496
- }
497
-
498
- form.wpgmza-form *
499
- {
500
- box-sizing: border-box;
501
- }
502
-
503
- .wpgmza-form legend
504
- {
505
- margin-right: 30px;
506
- margin-bottom: 6px;
507
- margin-top: 6px;
508
- /* padding: 1em; */
509
- }
510
-
511
-
512
- /*form.wpgmza-form label
513
- {
514
- display: block;
515
- }*/
516
-
517
- .wpgmza-form input[type="color"]
518
- {
519
- height: 2em;
520
- }
521
-
522
- form.wpgmza-form .wpgmza-fancy-toggle-button,
523
- form.wpgmza-form .wpgmza-fancy-toggle-button + label
524
- {
525
- display: inline-block;
526
- vertical-align: baseline;
527
- }
528
-
529
- form.wpgmza-form .wpgmza-fancy-toggle-button + label
530
- {
531
- padding: 1em 1em;
532
- }
533
-
534
- .wpgmza-upgrade-tab, .wpgmza-upgrade-tab a,
535
- .update-att,
536
- .update-att a
537
- {
538
- color: #2B323C !important;
539
- }
540
-
541
- .wpgmza-action-buttons>*
542
- {
543
- text-align: center;
544
- }
545
-
546
- .wpgmza-preloader
547
- {
548
- pointer-events: none; /* Prevent mouse wheel scrolling on preloader */
549
- z-index: 10000000000;
550
-
551
- display: inline-block;
552
- position: relative;
553
- width: 64px;
554
- height: 64px;
555
-
556
- position: absolute;
557
- top: 50%;
558
- left: 50%;
559
- transform: translate(-50%, -50%);
560
- }
561
-
562
- .wpgmza-preloader div {
563
- position: absolute;
564
- top: 27px;
565
- width: 11px;
566
- height: 11px;
567
- border-radius: 50%;
568
-
569
- background: #fff;
570
- box-shadow: 0px 0px 2px black;
571
-
572
- animation-timing-function: cubic-bezier(0, 1, 1, 0);
573
- }
574
- .wpgmza-preloader div:nth-child(1) {
575
- left: 6px;
576
- animation: wpgmza-preloader1 0.6s infinite;
577
- }
578
- .wpgmza-preloader div:nth-child(2) {
579
- left: 6px;
580
- animation: wpgmza-preloader2 0.6s infinite;
581
- }
582
- .wpgmza-preloader div:nth-child(3) {
583
- left: 26px;
584
- animation: wpgmza-preloader2 0.6s infinite;
585
- }
586
- .wpgmza-preloader div:nth-child(4) {
587
- left: 45px;
588
- animation: wpgmza-preloader3 0.6s infinite;
589
- }
590
- @keyframes wpgmza-preloader1 {
591
- 0% {
592
- transform: scale(0);
593
- }
594
- 100% {
595
- transform: scale(1);
596
- }
597
- }
598
- @keyframes wpgmza-preloader3 {
599
- 0% {
600
- transform: scale(1);
601
- }
602
- 100% {
603
- transform: scale(0);
604
- }
605
- }
606
- @keyframes wpgmza-preloader2 {
607
- 0% {
608
- transform: translate(0, 0);
609
- }
610
- 100% {
611
- transform: translate(19px, 0);
612
- }
613
- }
614
-
615
- #wpgmza-credits-page .wpgmza-developer-avatar
616
- {
617
- width: 60px;
618
- }
619
-
620
- .wpgmza-feature-panel .wpgmza-preloader div
621
- {
622
- background: #000;
623
- box-shadow: 0px 0px 2px white;
624
-
625
- transition: opacity 0.6s;
626
- }
627
-
628
- .wpgmza-feature-panel.wpgmza-loading > * :not(.wpgmza-preloader)
629
- {
630
- opacity: 0.5;
631
- }
632
-
633
- .wpgmza-form .ui-tabs-nav>li
634
- {
635
- cursor: pointer;
636
- }
637
-
638
- #wpgmaps_tabs_markers.wpgmza-form ul.wpgmza-tab-wrap img
639
- {
640
- height: 1.3em;
641
- width: auto;
642
- display: inline-block;
643
- vertical-align: middle;
644
- margin-right: 0.3em;
645
- }
646
-
647
- #wpgmaps_tabs_markers.wpgmza-form ul.wpgmza-tab-wrap .ui-tabs-active img
648
- {
649
- /*filter: invert(100%);*/
650
- }
651
-
652
- input[name='wpgmza_developer_mode'] + .notice-warning
653
- {
654
- display: none;
655
- }
656
-
657
- input[name='wpgmza_developer_mode']:checked + .notice-warning
658
- {
659
- display: block;
660
- }
661
-
662
- .wpgmza-gesture-overlay
663
- {
664
- color: white;
665
- background: rgba(0,0,0,0.5);
666
- position: absolute;
667
- top: 0px;
668
- left: 0px;
669
- width: 100%;
670
- height: 100%;
671
- z-index: 999;
672
- text-align: center;
673
- line-height: 400px;
674
- pointer-events: none;
675
- }
676
-
677
- #wpgmza-admin-map-table-container td
678
- {
679
- white-space: nowrap;
680
- }
681
-
682
- .wpgmza-review-nag
683
- {
684
- padding: 10px;
685
- border: 2px solid #46b450;
686
- border-radius: 3px;
687
- }
688
-
689
- #wpgmza-theme-presets input[type="radio"]
690
- {
691
- display: none;
692
- }
693
-
694
- #wpgmza-global-settings #xml-cache-settings
695
- {
696
- display: none;
697
- }
698
-
699
- #wpgmza-map-edit-page input[name='wpgmza_iw_type']
700
- {
701
- display: none;
702
- }
703
-
704
- .wpgmza-marker-listing-style-menu img
705
- {
706
- width: 90px;
707
- height: auto;
708
- }
709
-
710
- /*.wpgmza-marker-listing-style-menu input[type='radio']
711
- {
712
- display: none;
713
- }*/
714
-
715
- #wpgmza-marker-listing-preview
716
- {
717
- float: right;
718
- }
719
-
720
- .wpgmza-marker-listing-style-menu input[type='radio']:checked + img
721
- {
722
- /*border-left: #0073AA 3px solid;*/
723
- border-top-left-radius: 3px;
724
- border-bottom-left-radius: 3px;
725
- position: relative;
726
- /*left: -3px;*/
727
- /*margin-right: -3px;*/
728
- }
729
-
730
- .wpgmza-marker-listing-style-menu input[type='radio']:checked + img + span,
731
- input[type='radio']:checked + .wpgmza-infowindow-picker__item span{
732
- font-weight: 800;
733
- }
734
-
735
- .wpgmza-marker-listing-style-menu
736
- {
737
- display: flex;
738
- flex-wrap: wrap;
739
- }
740
-
741
- .wpgmza-marker-listing-style-menu input[type='radio']
742
- {
743
- display: none;
744
- }
745
-
746
- #wpgmza-pro-features.wpgmza-upsell
747
- {
748
- background: transparent;
749
- border: none;
750
- }
751
-
752
- #wpgmza-pro-features.wpgmza-upsell a
753
- {
754
- color: #2f76e1;
755
- font-weight: normal;
756
- }
757
-
758
- #open-route-service-key-notice .wpgmza-flex,
759
- #wpgmza-map-edit-page #marker-filtering .wpgmza-flex
760
- {
761
- display: block;
762
- }
763
-
764
- #wpgmza-map-edit-page .wpgmza_map
765
- {
766
- z-index: 2;
767
- width: 100% !important;
768
- float: right !important;
769
- margin-left: 15px;
770
- }
771
-
772
- .map-container-wrap {
773
- float:left;
774
- width:50%;
775
- }
776
-
777
-
778
- #wpgmza-global-settings input[name='wpgmza_iw_type'] {
779
- display: none;
780
- }
781
-
782
- .wpgmza-feature-accordion .dataTable,
783
- .wpgmza-table-container .dataTable{
784
- width: 100% !important;
785
- }
786
- .wgmza-map-editor-holder {
787
- display: block;
788
- overflow: auto;
789
- clear: both;
790
- }
791
-
792
- #wpgmaps_save_reminder {
793
- padding-top: 14px;
794
- clear: both;
795
- display: block;
796
- overflow: auto;
797
- }
798
-
799
- .wpgmza_map .gm-svpc img {
800
- max-width: initial;
801
  }
1
+ /** Override the auto complete styles */
2
+ .pac-container {
3
+ border-radius: 2px;
4
+ border-top: none;
5
+ font-family: Roboto, sans-serif;
6
+
7
+ box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
8
+ -webkit-box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
9
+ -moz-box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
10
+ -o-box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
11
+ }
12
+
13
+ .pac-container .pac-item{
14
+ border-top: none;
15
+ }
16
+
17
+ .pac-container .pac-item .pac-item-query{
18
+ color: #333;
19
+
20
+ }
21
+
22
+ .wpgmza-google-maps-api-error-overlay,
23
+ .wpgmza-google-maps-api-error-overlay *
24
+ {
25
+ text-align: left;
26
+ }
27
+
28
+ .wpgmza-google-api-error-list
29
+ {
30
+ list-style: none;
31
+ }
32
+
33
+ .wpgmza-google-api-error-list li
34
+ {
35
+ background: ghostwhite;
36
+ padding: 0.5em;
37
+ margin: 0.5em;
38
+ border-color:1px solid #ccc;
39
+ }
40
+
41
+ .wpgmza-google-api-error-list li:before
42
+ {
43
+ content: "\26D4";
44
+ color: red;
45
+ }
46
+
47
+ .wpgmza-google-maps-api-error-overlay a
48
+ {
49
+ color: blue;
50
+ }
51
+
52
+ .wpgmza-google-maps-api-error-overlay .wpgmza-documentation-buttons
53
+ {
54
+ float: right;
55
+ }
56
+
57
+ .wpgmza-google-maps-api-error-overlay .wpgmza-documentation-buttons a
58
+ {
59
+ color: #444444;
60
+ background: #F3F3F3;
61
+ border: 1px #DADADA solid;
62
+ padding: 5px 10px;
63
+ border-radius: 2px;
64
+ cursor: pointer;
65
+ font-size: 9pt;
66
+ outline: none;
67
+ }
68
+
69
+ .wpgmza-google-maps-api-error-overlay .wpgmza-documentation-buttons a:hover {
70
+ border: 1px #C6C6C6 solid;
71
+ box-shadow: 1px 1px 1px #EAEAEA;
72
+ color: #333333;
73
+ background: #F7F7F7;
74
+ }
75
+
76
+ .wpgmza-google-maps-api-error-overlay .wpgmza-documentation-buttons a:active {
77
+ box-shadow: inset 1px 1px 1px #DFDFDF;
78
+ }
79
+
80
+ .wpgmza-google-maps-api-error-overlay .wpgmza-documentation-buttons a i
81
+ {
82
+ font-weight: bold;
83
+ padding-right: 0.3em;
84
+ }
85
+
86
+ .wpgmza-google-maps-api-error-overlay .wpgmza-front-end-only
87
+ {
88
+ color: red;
89
+ font-size: 0.8em;
90
+ }
91
+
92
+ .wpgmza-google-html-overlay
93
+ {
94
+ position: absolute;
95
+ }
96
+
97
+ .wpgmza-google-maps-api-error-overlay
98
+ {
99
+ position: absolute;
100
+
101
+ top: 0px;
102
+ left: 0px;
103
+
104
+ width: 100%;
105
+ height: 100%;
106
+
107
+ background: rgba(255,255,255,0.95);
108
+ padding: 1em;
109
+
110
+ text-align: center;
111
+ z-index: 2;
112
+
113
+ overflow-y: scroll;
114
+ }
115
+
116
+ [data-wpgmza-table]
117
+ {
118
+ overflow: visible;
119
+ }
120
+
121
+ .wpgmza-modern-store-locator .wpgmza_cat_checkbox_holder
122
+ {
123
+ margin: 0 auto;
124
+ pointer-events: all;
125
+ }
126
+
127
+ .wpgmza-modern-store-locator .wpgmza-inner { flex-wrap: wrap; }
128
+
129
+ .ol-info-window-plain
130
+ {
131
+ min-width: 240px;
132
+ }
133
+
134
+ .wpgmza-marker-gallery
135
+ {
136
+ cursor: pointer;
137
+ }
138
+
139
+ .wpgmza-gallery-input li
140
+ {
141
+ position: relative;
142
+
143
+ width: 120px;
144
+ height: 120px;
145
+ margin: 0.25em;
146
+
147
+ display: inline-block;
148
+ vertical-align: top;
149
+
150
+ background-size: cover;
151
+ box-sizing: border-box;
152
+ }
153
+
154
+ .wpgmza-gallery-input li.wpgmza-add-new-picture
155
+ {
156
+ cursor: pointer;
157
+ border: #E8E8E8 dashed 6px;
158
+ color: #E8E8E8;
159
+ }
160
+
161
+ .wpgmza-gallery-input li.wpgmza-add-new-picture:hover
162
+ {
163
+ border-color: lightgray;
164
+ color: lightgray;
165
+ }
166
+
167
+ .wpgmza-gallery-input li.wpgmza-add-new-picture>i
168
+ {
169
+ position: absolute;
170
+
171
+ left: 50%;
172
+ top: 50%;
173
+
174
+ transform: translate(-50%, -50%);
175
+
176
+ font-size: 32px;
177
+ }
178
+
179
+ #wpgmaps_options fieldset
180
+ {
181
+ margin-bottom: 1em;
182
+ }
183
+
184
+ /*(#wpgmaps_options fieldset>*,
185
+ .wpgmza-marker-panel fieldset>*
186
+ {
187
+ display: inline-block;
188
+ vertical-align: top;
189
+ }*/
190
+
191
+ #wpgmaps_options input:disabled + label,
192
+ .wpgmza-feature-panel input:disabled + label,
193
+ .wpgmza-pro-feature
194
+ {
195
+ opacity: 0.6;
196
+ }
197
+
198
+ .wpgmza-feature-panel .wpgmza-save-feature-container button
199
+ {
200
+ width: 100%;
201
+ }
202
+
203
+ #wpgmaps_options legend,
204
+ .wpgmza-feature-panel legend,
205
+ #wpgmza-theme-panel label,
206
+ #advanced-markers legend {
207
+ width: 20%;
208
+ max-width:180px;
209
+ }
210
+
211
+ #wpgmaps_options [type="number"],
212
+ .wpgmza-marker-panel [type="number"]
213
+ {
214
+ width: 64px;
215
+ }
216
+
217
+ #wpgmaps_options fieldset>label,
218
+ .wpgmza-marker-panel fieldset>label
219
+ {
220
+ width: 200px;
221
+ }
222
+
223
+ #wpgmaps_options fieldset>label+div,
224
+ .wpgmza-marker-panel fieldset>label+div
225
+ {
226
+ width: calc(100% - 200px);
227
+ }
228
+
229
+ .wpgmza-marker-icon-preview
230
+ {
231
+ width: 32px;
232
+ height: 32px;
233
+ background-repeat: no-repeat;
234
+ background-position: center;
235
+ background-size: contain;
236
+ border: #E8E8E8 dashed 6px;
237
+ }
238
+
239
+ .wpgmza-marker-icon-picker>*
240
+ {
241
+ display: inline-block;
242
+ vertical-align: middle;
243
+ }
244
+
245
+ .wpgmza-rating-gradient-container
246
+ {
247
+ display: inline-block;
248
+ vertical-align: middle;
249
+
250
+ border: 1px solid lightgray;
251
+ width: 128px;
252
+ height: 1em;
253
+ }
254
+
255
+ .wpgmza-rating-gradient-container>.wpgmza-rating-gradient
256
+ {
257
+ height: 100%;
258
+
259
+ /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ff0000+0,00ff00+100 */
260
+ background: #ff0000; /* Old browsers */
261
+ background: -moz-linear-gradient(left, #ff0000 0%, #00ff00 128px); /* FF3.6-15 */
262
+ background: -webkit-linear-gradient(left, #ff0000 0%,#00ff00 128px); /* Chrome10-25,Safari5.1-6 */
263
+ background: linear-gradient(to right, #ff0000 0%,#00ff00 128px); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
264
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff0000', endColorstr='#00ff00',GradientType=1 ); /* IE6-9 */
265
+
266
+ pointer-events: none;
267
+
268
+ transition: width 0.5s;
269
+ }
270
+
271
+ .wpgmza-rating-stars-container
272
+ {
273
+ position: relative;
274
+ font-size: 1.5em;
275
+ cursor: pointer;
276
+ }
277
+
278
+ .wpgmza-rating-stars-container + .wpgmza-num-ratings
279
+ {
280
+ position: relative;
281
+ }
282
+
283
+ .wpgmza-rating-stars-container>span
284
+ {
285
+ position: absolute;
286
+ top: 0px;
287
+ left: 0px;
288
+ padding-top: 0.3em;
289
+ }
290
+
291
+ .wpgmza-rating-stars-container>span.wpgmza-background
292
+ {
293
+ text-shadow: 0px 0px 2px black;
294
+ }
295
+
296
+ .wpgmza-rating-stars-container>span.wpgmza-foreground
297
+ {
298
+ overflow: hidden;
299
+ color: yellow;
300
+ text-shadow: 0px -1px 3px orange inner;
301
+ }
302
+
303
+ .wpgmza-rating-thumbs-container i
304
+ {
305
+ /* display: none; */
306
+ }
307
+
308
+ .wpgmza-rating-thumbs-container, .wpgmza-rating-thumbs-container *
309
+ {
310
+ display: inline-block;
311
+ vertical-align: middle;
312
+ }
313
+
314
+ .wpgmza-rating-thumbs-container
315
+ {
316
+ background: ghostwhite;
317
+ /* background: linear-gradient(to right, #88AFD0 0%, #88AFD0 75%, transparent 75%, transparent 100%); */
318
+
319
+ border: 1px solid lightgrey;
320
+ border-radius: 6px;
321
+ }
322
+
323
+ .wpgmza-rating-thumbs-container>span.wpgmza-downvote,
324
+ .wpgmza-rating-thumbs-container>span.wpgmza-upvote
325
+ {
326
+ padding: 0.5em 1em;
327
+ }
328
+
329
+ .wpgmza-rating-thumbs-container i
330
+ {
331
+ position: relative;
332
+ font-size: 1.5em;
333
+
334
+ top: 0.0em;
335
+ transition: top 0.6s;
336
+ }
337
+
338
+ .wpgmza-rating-thumbs-container .wpgmza-upvote>i
339
+ {
340
+ top: -0.05em;
341
+ }
342
+
343
+ .wpgmza-rating-thumbs-container .wpgmza-down>i
344
+ {
345
+ top: 0.05em;
346
+ }
347
+
348
+ .wpgmza-rating-thumbs-container .wpgmza-upvote:hover>i
349
+ {
350
+ top: -0.25em;
351
+ }
352
+
353
+ .wpgmza-rating-thumbs-container .wpgmza-downvote:hover>i
354
+ {
355
+ top: 0.25em;
356
+ }
357
+
358
+ .wpgmza-rating-thumbs-container>span.wpgmza-upvote
359
+ {
360
+ border-left: 1px solid lightgrey;
361
+ }
362
+
363
+ .wpgmza-rating-thumbs-container>span:hover,
364
+ .wpgmza-rating-thumbs-container>span.wpgmza-remembered-rating
365
+ {
366
+ /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,c9c9c9+100&0.5+0,0.2+100 */
367
+ background: -moz-linear-gradient(top, rgba(255,255,255,0.5) 0%, rgba(201,201,201,0.2) 100%); /* FF3.6-15 */
368
+ background: -webkit-linear-gradient(top, rgba(255,255,255,0.5) 0%,rgba(201,201,201,0.2) 100%); /* Chrome10-25,Safari5.1-6 */
369
+ background: linear-gradient(to bottom, rgba(255,255,255,0.5) 0%,rgba(201,201,201,0.2) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
370
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#80ffffff', endColorstr='#33c9c9c9',GradientType=0 ); /* IE6-9 */
371
+ }
372
+
373
+ .wpgmza-rating-thumbs-container>span:active
374
+ {
375
+ /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,c9c9c9+100&0.5+0,0.2+100 */
376
+ background: -moz-linear-gradient(bottom, rgba(255,255,255,0.5) 0%, rgba(201,201,201,0.2) 100%); /* FF3.6-15 */
377
+ background: -webkit-linear-gradient(bottom, rgba(255,255,255,0.5) 0%,rgba(201,201,201,0.2) 100%); /* Chrome10-25,Safari5.1-6 */
378
+ background: linear-gradient(to top, rgba(255,255,255,0.5) 0%,rgba(201,201,201,0.2) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
379
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#33c9c9c9', endColorstr='#80ffffff',GradientType=0 ); /* IE6-9 */
380
+ }
381
+
382
+ .wpgmza-rating.wpgmza-loading
383
+ {
384
+ filter: grayscale(100%);
385
+ }
386
+
387
+ .wpgmza-google-text-overlay > .wpgmza-inner
388
+ {
389
+ position: absolute;
390
+ transform: translate(-50%, -50%);
391
+
392
+ text-align: center;
393
+ font-weight: bold;
394
+
395
+ text-shadow: 0px 0px 2px white;
396
+ text-shadow: 0px 0px 2px white,
397
+ 0px 0px 2px white,
398
+ 0px 0px 2px white,
399
+ 0px 0px 2px white;
400
+ }
401
+
402
+ .wpgmza-modern-store-locator {
403
+ text-align: center;
404
+ padding-top: 10px;
405
+ }
406
+
407
+ .wpgmza-modern-store-locator > .wpgmza-inner {
408
+ display: inline-block;
409
+ background: white;
410
+ padding: 0.5em !important;
411
+
412
+ border-radius: 2px;
413
+ font-family: Roboto, sans-serif;
414
+
415
+ box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
416
+ -webkit-box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
417
+ -moz-box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
418
+ -o-box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
419
+
420
+ }
421
+
422
+ .wpgmza-modern-store-locator input,
423
+ .wpgmza-modern-store-locator select {
424
+ height: 28px !important;
425
+ vertical-align: top;
426
+ padding: 0 6px !important;
427
+ margin: 0 2px;
428
+ color: #777;
429
+ }
430
+
431
+ .wpgmza-select-theme-preset
432
+ {
433
+ position: absolute;
434
+ right: 0.5em;
435
+ bottom: 0.5em;
436
+ }
437
+
438
+ #wpgmza-theme-editor
439
+ {
440
+
441
+ background: #fff;
442
+ z-index: 999;
443
+ box-sizing: border-box;
444
+ overflow-y: auto;
445
+ }
446
+
447
+ #wpgmza-theme-editor>*
448
+ {
449
+ }
450
+
451
+ #wpgmza-theme-editor fieldset>label
452
+ {
453
+ width: 100px;
454
+ }
455
+
456
+ #wpgmza-theme-editor fieldset>label + div
457
+ {
458
+ display: inline-block;
459
+ vertical-align: middle;
460
+ }
461
+
462
+ #wpgmza-theme-editor fieldset>label + div > input[type="checkbox"]:not(:checked) + input
463
+ {
464
+ display: none;
465
+ }
466
+
467
+ .wpgmza-import-log
468
+ {
469
+ display: none;
470
+ position: relative;
471
+ }
472
+
473
+ .wpgmza-import-log > .wpgmza-log-contents
474
+ {
475
+ white-space: pre-wrap;
476
+ display: block;
477
+ word-wrap: break-word;
478
+ border: 1px dotted grey;
479
+ padding: 1em;
480
+ font-family: monospace;
481
+ font-size: 11px;
482
+ }
483
+
484
+ .wpgmza-import-log-buttons
485
+ {
486
+ position: absolute;
487
+ right: 0;
488
+ bottom: 100%;
489
+ }
490
+
491
+ /* Global settings page */
492
+
493
+ #wpgmza-global-settings>ul>li
494
+ {
495
+ display: inline-block;
496
+ }
497
+
498
+ form.wpgmza-form *
499
+ {
500
+ box-sizing: border-box;
501
+ }
502
+
503
+ .wpgmza-form legend
504
+ {
505
+ margin-right: 30px;
506
+ margin-bottom: 6px;
507
+ margin-top: 6px;
508
+ /* padding: 1em; */
509
+ }
510
+
511
+
512
+ /*form.wpgmza-form label
513
+ {
514
+ display: block;
515
+ }*/
516
+
517
+ .wpgmza-form input[type="color"]
518
+ {
519
+ height: 2em;
520
+ }
521
+
522
+ form.wpgmza-form .wpgmza-fancy-toggle-button,
523
+ form.wpgmza-form .wpgmza-fancy-toggle-button + label
524
+ {
525
+ display: inline-block;
526
+ vertical-align: baseline;
527
+ }
528
+
529
+ form.wpgmza-form .wpgmza-fancy-toggle-button + label
530
+ {
531
+ padding: 1em 1em;
532
+ }
533
+
534
+ .wpgmza-upgrade-tab, .wpgmza-upgrade-tab a,
535
+ .update-att,
536
+ .update-att a
537
+ {
538
+ color: #2B323C !important;
539
+ }
540
+
541
+ .wpgmza-action-buttons>*
542
+ {
543
+ text-align: center;
544
+ }
545
+
546
+ .wpgmza-preloader
547
+ {
548
+ pointer-events: none; /* Prevent mouse wheel scrolling on preloader */
549
+ z-index: 10000000000;
550
+
551
+ display: inline-block;
552
+ position: relative;
553
+ width: 64px;
554
+ height: 64px;
555
+
556
+ position: absolute;
557
+ top: 50%;
558
+ left: 50%;
559
+ transform: translate(-50%, -50%);
560
+ }
561
+
562
+ .wpgmza-preloader div {
563
+ position: absolute;
564
+ top: 27px;
565
+ width: 11px;
566
+ height: 11px;
567
+ border-radius: 50%;
568
+
569
+ background: #fff;
570
+ box-shadow: 0px 0px 2px black;
571
+
572
+ animation-timing-function: cubic-bezier(0, 1, 1, 0);
573
+ }
574
+ .wpgmza-preloader div:nth-child(1) {
575
+ left: 6px;
576
+ animation: wpgmza-preloader1 0.6s infinite;
577
+ }
578
+ .wpgmza-preloader div:nth-child(2) {
579
+ left: 6px;
580
+ animation: wpgmza-preloader2 0.6s infinite;
581
+ }
582
+ .wpgmza-preloader div:nth-child(3) {
583
+ left: 26px;
584
+ animation: wpgmza-preloader2 0.6s infinite;
585
+ }
586
+ .wpgmza-preloader div:nth-child(4) {
587
+ left: 45px;
588
+ animation: wpgmza-preloader3 0.6s infinite;
589
+ }
590
+ @keyframes wpgmza-preloader1 {
591
+ 0% {
592
+ transform: scale(0);
593
+ }
594
+ 100% {
595
+ transform: scale(1);
596
+ }
597
+ }
598
+ @keyframes wpgmza-preloader3 {
599
+ 0% {
600
+ transform: scale(1);
601
+ }
602
+ 100% {
603
+ transform: scale(0);
604
+ }
605
+ }
606
+ @keyframes wpgmza-preloader2 {
607
+ 0% {
608
+ transform: translate(0, 0);
609
+ }
610
+ 100% {
611
+ transform: translate(19px, 0);
612
+ }
613
+ }
614
+
615
+ #wpgmza-credits-page .wpgmza-developer-avatar
616
+ {
617
+ width: 60px;
618
+ }
619
+
620
+ .wpgmza-feature-panel .wpgmza-preloader div
621
+ {
622
+ background: #000;
623
+ box-shadow: 0px 0px 2px white;
624
+
625
+ transition: opacity 0.6s;
626
+ }
627
+
628
+ .wpgmza-feature-panel.wpgmza-loading > * :not(.wpgmza-preloader)
629
+ {
630
+ opacity: 0.5;
631
+ }
632
+
633
+ .wpgmza-form .ui-tabs-nav>li
634
+ {
635
+ cursor: pointer;
636
+ }
637
+
638
+ #wpgmaps_tabs_markers.wpgmza-form ul.wpgmza-tab-wrap img
639
+ {
640
+ height: 1.3em;
641
+ width: auto;
642
+ display: inline-block;
643
+ vertical-align: middle;
644
+ margin-right: 0.3em;
645
+ }
646
+
647
+ #wpgmaps_tabs_markers.wpgmza-form ul.wpgmza-tab-wrap .ui-tabs-active img
648
+ {
649
+ /*filter: invert(100%);*/
650
+ }
651
+
652
+ input[name='wpgmza_developer_mode'] + .notice-warning
653
+ {
654
+ display: none;
655
+ }
656
+
657
+ input[name='wpgmza_developer_mode']:checked + .notice-warning
658
+ {
659
+ display: block;
660
+ }
661
+
662
+ .wpgmza-gesture-overlay
663
+ {
664
+ color: white;
665
+ background: rgba(0,0,0,0.5);
666
+ position: absolute;
667
+ top: 0px;
668
+ left: 0px;
669
+ width: 100%;
670
+ height: 100%;
671
+ z-index: 999;
672
+ text-align: center;
673
+ line-height: 400px;
674
+ pointer-events: none;
675
+ }
676
+
677
+ #wpgmza-admin-map-table-container td
678
+ {
679
+ white-space: nowrap;
680
+ }
681
+
682
+ .wpgmza-review-nag
683
+ {
684
+ padding: 10px;
685
+ border: 2px solid #46b450;
686
+ border-radius: 3px;
687
+ }
688
+
689
+ #wpgmza-theme-presets input[type="radio"]
690
+ {
691
+ display: none;
692
+ }
693
+
694
+ #wpgmza-global-settings #xml-cache-settings
695
+ {
696
+ display: none;
697
+ }
698
+
699
+ #wpgmza-map-edit-page input[name='wpgmza_iw_type']
700
+ {
701
+ display: none;
702
+ }
703
+
704
+ .wpgmza-marker-listing-style-menu img
705
+ {
706
+ width: 90px;
707
+ height: auto;
708
+ }
709
+
710
+ /*.wpgmza-marker-listing-style-menu input[type='radio']
711
+ {
712
+ display: none;
713
+ }*/
714
+
715
+ #wpgmza-marker-listing-preview
716
+ {
717
+ float: right;
718
+ }
719
+
720
+ .wpgmza-marker-listing-style-menu input[type='radio']:checked + img
721
+ {
722
+ /*border-left: #0073AA 3px solid;*/
723
+ border-top-left-radius: 3px;
724
+ border-bottom-left-radius: 3px;
725
+ position: relative;
726
+ /*left: -3px;*/
727
+ /*margin-right: -3px;*/
728
+ }
729
+
730
+ .wpgmza-marker-listing-style-menu input[type='radio']:checked + img + span,
731
+ input[type='radio']:checked + .wpgmza-infowindow-picker__item span{
732
+ font-weight: 800;
733
+ }
734
+
735
+ .wpgmza-marker-listing-style-menu
736
+ {
737
+ display: flex;
738
+ flex-wrap: wrap;
739
+ }
740
+
741
+ .wpgmza-marker-listing-style-menu input[type='radio']
742
+ {
743
+ display: none;
744
+ }
745
+
746
+ #wpgmza-pro-features.wpgmza-upsell
747
+ {
748
+ background: transparent;
749
+ border: none;
750
+ }
751
+
752
+ #wpgmza-pro-features.wpgmza-upsell a
753
+ {
754
+ color: #2f76e1;
755
+ font-weight: normal;
756
+ }
757
+
758
+ #open-route-service-key-notice .wpgmza-flex,
759
+ #wpgmza-map-edit-page #marker-filtering .wpgmza-flex
760
+ {
761
+ display: block;
762
+ }
763
+
764
+ #wpgmza-map-edit-page .wpgmza_map
765
+ {
766
+ z-index: 2;
767
+ width: 100% !important;
768
+ float: right !important;
769
+ margin-left: 15px;
770
+ }
771
+
772
+ .map-container-wrap {
773
+ float:left;
774
+ width:50%;
775
+ }
776
+
777
+
778
+ #wpgmza-global-settings input[name='wpgmza_iw_type'] {
779
+ display: none;
780
+ }
781
+
782
+ .wpgmza-feature-accordion .dataTable,
783
+ .wpgmza-table-container .dataTable{
784
+ width: 100% !important;
785
+ }
786
+ .wgmza-map-editor-holder {
787
+ display: block;
788
+ overflow: auto;
789
+ clear: both;
790
+ }
791
+
792
+ #wpgmaps_save_reminder {
793
+ padding-top: 14px;
794
+ clear: both;
795
+ display: block;
796
+ overflow: auto;
797
+ }
798
+
799
+ .wpgmza_map .gm-svpc img {
800
+ max-width: initial;
801
  }
css/open-layers.css CHANGED
@@ -1,193 +1,193 @@
1
- .wpgmza-ol-modern-infowindow-container
2
- {
3
- position: absolute;
4
- top: 0px;
5
- right: 0px;
6
-
7
- }
8
-
9
- .wpgmza_map
10
- {
11
- position: relative;
12
- }
13
-
14
- /*
15
- .wpgmza-ol-modern-infowindow-container .wpgmza_modern_infowindow
16
- {
17
- min-width: 160px;
18
- }
19
- */
20
-
21
- @keyframes wpgmza-bounce {
22
- from {
23
- bottom: 0px;
24
- }
25
- to {
26
- bottom: 15px;
27
- }
28
- }
29
- @-webkit-keyframes wpgmza-bounce {
30
- from {
31
- bottom: 0px;
32
- }
33
- to {
34
- bottom: 15px;
35
- }
36
- }
37
-
38
- @keyframes wpgmza-drop {
39
- from {
40
- bottom: 100vh;
41
- }
42
- to {
43
- bottom: 0vh;
44
- }
45
- }
46
-
47
- @-webkit-keyframes wpgmza-drop {
48
- from {
49
- bottom: 100vh;
50
- }
51
- to {
52
- bottom: 0vh;
53
- }
54
- }
55
-
56
- .ol-marker
57
- {
58
- position: relative;
59
- }
60
-
61
- .ol-marker>img
62
- {
63
- /* NB: Re-added, removing this breaks marker animations */
64
- position: absolute;
65
- bottom: 0px;
66
- transform: translateX(-50%);
67
- max-width: none;
68
- z-index: 2;
69
- }
70
-
71
- .ol-marker[data-anim='bounce']>img
72
- {
73
- animation: wpgmza-bounce 0.3s infinite alternate;
74
- -webkit-animation: wpgmza-bounce 0.3s infinite alternate;
75
- }
76
-
77
- .ol-marker[data-anim='drop']>img
78
- {
79
- animation: wpgmza-drop 0.3s;
80
- -webkit-animation: wpgmza-drop 0.3s;
81
- }
82
-
83
- .ol-marker-label
84
- {
85
- top: 1.5em;
86
- position: relative;
87
- transform: translateX(-50%);
88
- text-shadow:
89
- 0px 0px 1px white,
90
- 0px 0px 1px white,
91
- 0px 0px 1px white,
92
- 0px 0px 2px white,
93
- 0px 0px 2px white,
94
- 0px 0px 2px white,
95
- 0px 0px 3px white,
96
- 0px 0px 3px white;
97
- }
98
-
99
- .ol-info-window-plain {
100
- position: absolute;
101
- bottom: 56px;
102
- left: 0px;
103
- transform: translateX(-50%);
104
- background: white;
105
- /* box-shadow: 2px 2px 5px rgba(0,0,0,0.5); */
106
- /* border: 1px solid lightgray; */
107
- padding: 10px;
108
- font-size: 14px;
109
- }
110
-
111
- .ol-info-window-plain:after
112
- {
113
- content: '';
114
- position: absolute;
115
- bottom: 0;
116
- left: 50%;
117
- width: 0;
118
- height: 0;
119
- border: 8px solid transparent;
120
- border-top-color: white;
121
- border-bottom: 0;
122
- margin-left: -8px;
123
- margin-bottom: -8px;
124
- }
125
-
126
- .ol-info-window-close
127
- {
128
- float: right;
129
- margin: 0 0 3px 3px;
130
- cursor: pointer;
131
- }
132
-
133
- .ol-info-window-container,
134
- .wpgmza-pro-info-window-container
135
- {
136
- z-index: 999999;
137
- }
138
-
139
- .wpgmza_map, #wpgmza_map
140
- {
141
- position: relative;
142
- }
143
-
144
- .wpgmza-ol-canvas-overlay
145
- {
146
- position: absolute;
147
- left: 0px;
148
- top: 0px;
149
- pointer-events: none;
150
- z-index: 1;
151
- }
152
-
153
- .wpgmza_map[data-maps-engine="open-layers"] .wpgmza-modern-store-locator,
154
- #wpgmza_map[data-maps-engine="open-layers"] .wpgmza-modern-store-locator
155
- {
156
- position: absolute;
157
- top: 0px;
158
- left: 50%;
159
- /*width: 100%;*/
160
- max-width: 100% !important;
161
- z-index: 99;
162
- }
163
-
164
- .wpgmza-modern-store-locator {
165
- pointer-events: none;
166
- z-index: 0;
167
- position: absolute;
168
- top: 0px;
169
- max-width: 100% !important;
170
- left: 50%;
171
- }
172
- .wpgmza-modern-store-locator .wpgmza-inner {
173
- position:relative;
174
- left:-50%;
175
- }
176
-
177
- .wpgmza-modern-store-locator>.wpgmza-inner
178
- {
179
- pointer-events: all;
180
- }
181
-
182
- .ol-info-window-polygon {
183
- bottom: 0 !important;
184
- }
185
-
186
- .rtl .wpgmza_map * {
187
- direction: ltr;
188
- }
189
-
190
- .rtl .wpgmza_map .wpgmza-infowindow,
191
- .rtl .wpgmza_map .wpgmza-infowindow *{
192
- direction: rtl;
193
  }
1
+ .wpgmza-ol-modern-infowindow-container
2
+ {
3
+ position: absolute;
4
+ top: 0px;
5
+ right: 0px;
6
+
7
+ }
8
+
9
+ .wpgmza_map
10
+ {
11
+ position: relative;
12
+ }
13
+
14
+ /*
15
+ .wpgmza-ol-modern-infowindow-container .wpgmza_modern_infowindow
16
+ {
17
+ min-width: 160px;
18
+ }
19
+ */
20
+
21
+ @keyframes wpgmza-bounce {
22
+ from {
23
+ bottom: 0px;
24
+ }
25
+ to {
26
+ bottom: 15px;
27
+ }
28
+ }
29
+ @-webkit-keyframes wpgmza-bounce {
30
+ from {
31
+ bottom: 0px;
32
+ }
33
+ to {
34
+ bottom: 15px;
35
+ }
36
+ }
37
+
38
+ @keyframes wpgmza-drop {
39
+ from {
40
+ bottom: 100vh;
41
+ }
42
+ to {
43
+ bottom: 0vh;
44
+ }
45
+ }
46
+
47
+ @-webkit-keyframes wpgmza-drop {
48
+ from {
49
+ bottom: 100vh;
50
+ }
51
+ to {
52
+ bottom: 0vh;
53
+ }
54
+ }
55
+
56
+ .ol-marker
57
+ {
58
+ position: relative;
59
+ }
60
+
61
+ .ol-marker>img
62
+ {
63
+ /* NB: Re-added, removing this breaks marker animations */
64
+ position: absolute;
65
+ bottom: 0px;
66
+ transform: translateX(-50%);
67
+ max-width: none;
68
+ z-index: 2;
69
+ }
70
+
71
+ .ol-marker[data-anim='bounce']>img
72
+ {
73
+ animation: wpgmza-bounce 0.3s infinite alternate;
74
+ -webkit-animation: wpgmza-bounce 0.3s infinite alternate;
75
+ }
76
+
77
+ .ol-marker[data-anim='drop']>img
78
+ {
79
+ animation: wpgmza-drop 0.3s;
80
+ -webkit-animation: wpgmza-drop 0.3s;
81
+ }
82
+
83
+ .ol-marker-label
84
+ {
85
+ top: 1.5em;
86
+ position: relative;
87
+ transform: translateX(-50%);
88
+ text-shadow:
89
+ 0px 0px 1px white,
90
+ 0px 0px 1px white,
91
+ 0px 0px 1px white,
92
+ 0px 0px 2px white,
93
+ 0px 0px 2px white,
94
+ 0px 0px 2px white,
95
+ 0px 0px 3px white,
96
+ 0px 0px 3px white;
97
+ }
98
+
99
+ .ol-info-window-plain {
100
+ position: absolute;
101
+ bottom: 56px;
102
+ left: 0px;
103
+ transform: translateX(-50%);
104
+ background: white;
105
+ /* box-shadow: 2px 2px 5px rgba(0,0,0,0.5); */
106
+ /* border: 1px solid lightgray; */
107
+ padding: 10px;
108
+ font-size: 14px;
109
+ }
110
+
111
+ .ol-info-window-plain:after
112
+ {
113
+ content: '';
114
+ position: absolute;
115
+ bottom: 0;
116
+ left: 50%;
117
+ width: 0;
118
+ height: 0;
119
+ border: 8px solid transparent;
120
+ border-top-color: white;
121
+ border-bottom: 0;
122
+ margin-left: -8px;
123
+ margin-bottom: -8px;
124
+ }
125
+
126
+ .ol-info-window-close
127
+ {
128
+ float: right;
129
+ margin: 0 0 3px 3px;
130
+ cursor: pointer;
131
+ }
132
+
133
+ .ol-info-window-container,
134
+ .wpgmza-pro-info-window-container
135
+ {
136
+ z-index: 999999;
137
+ }
138
+
139
+ .wpgmza_map, #wpgmza_map
140
+ {
141
+ position: relative;
142
+ }
143
+
144
+ .wpgmza-ol-canvas-overlay
145
+ {
146
+ position: absolute;
147
+ left: 0px;
148
+ top: 0px;
149
+ pointer-events: none;
150
+ z-index: 1;
151
+ }
152
+
153
+ .wpgmza_map[data-maps-engine="open-layers"] .wpgmza-modern-store-locator,
154
+ #wpgmza_map[data-maps-engine="open-layers"] .wpgmza-modern-store-locator
155
+ {
156
+ position: absolute;
157
+ top: 0px;
158
+ left: 50%;
159
+ /*width: 100%;*/
160
+ max-width: 100% !important;
161
+ z-index: 99;
162
+ }
163
+
164
+ .wpgmza-modern-store-locator {
165
+ pointer-events: none;
166
+ z-index: 0;
167
+ position: absolute;
168
+ top: 0px;
169
+ max-width: 100% !important;
170
+ left: 50%;
171
+ }
172
+ .wpgmza-modern-store-locator .wpgmza-inner {
173
+ position:relative;
174
+ left:-50%;
175
+ }
176
+
177
+ .wpgmza-modern-store-locator>.wpgmza-inner
178
+ {
179
+ pointer-events: all;
180
+ }
181
+
182
+ .ol-info-window-polygon {
183
+ bottom: 0 !important;
184
+ }
185
+
186
+ .rtl .wpgmza_map * {
187
+ direction: ltr;
188
+ }
189
+
190
+ .rtl .wpgmza_map .wpgmza-infowindow,
191
+ .rtl .wpgmza_map .wpgmza-infowindow *{
192
+ direction: rtl;
193
  }
html/map-edit-page/map-edit-page.html.php CHANGED
@@ -1,2654 +1,2654 @@
1
- <div id="wpgmza-map-edit-page" class='wrap'>
2
- <h1 id="wpgmza-main-heading">
3
- <?php
4
- _e('WP Google Maps', 'wp-google-maps');
5
- ?>
6
- <span id="wpgmza-title-label" class="wpgmza-label-amber"><small></small></span>
7
- </h1>
8
-
9
- <div class="wide">
10
- <h2>
11
- <?php
12
- _e('Create your Map', 'wp-google-maps');
13
- ?>
14
-
15
- <a href="admin.php?page=wp-google-maps-menu&amp;action=new"
16
- class="add-new-h2 add-new-editor">
17
- <?php
18
- _e("New","wp-google-maps");
19
- ?>
20
- </a>
21
-
22
- <div class='update-nag update-blue update-slim' id='wpmgza_unsave_notice' style='display:none;'>
23
- <?php
24
- _e('Unsaved data will be lost', 'wp-google-maps');
25
- ?>
26
- </div>
27
- </h2>
28
-
29
- <div id="wpgmza-gdpr-privacy-policy-notice"></div>
30
-
31
- <form action="" method="POST" id="wpgmaps_options" name="wpgmza_map_form">
32
-
33
- <input name="action" type="hidden" value="wpgmza_save_map"/>
34
- <input name="redirect_to" type="hidden"/>
35
- <input name="map_id" type="hidden"/>
36
- <input name="real_post_nonce" type="hidden"/>
37
-
38
- <!-- NB: Is name attribute valid on a form? Check spec please -->
39
-
40
- <div id="wpgmaps_tabs">
41
- <ul>
42
- <li>
43
- <a href="#general-settings">
44
- <?php
45
- _e('General Settings', 'wp-google-maps');
46
- ?>
47
- </a>
48
- </li>
49
- <li>
50
- <a href="#themes">
51
- <?php
52
- _e('Themes', 'wp-google-maps');
53
- ?>
54
- </a>
55
- </li>
56
- <li>
57
- <a href="#directions">
58
- <?php
59
- _e('Directions', 'wp-google-maps');
60
- ?>
61
- </a>
62
- </li>
63
- <li>
64
- <a href="#store-locator">
65
- <?php
66
- _e('Store Locator', 'wp-google-maps');
67
- ?>
68
- </a>
69
- </li>
70
- <li>
71
- <a href="#advanced-settings">
72
- <?php
73
- _e('Advanced Settings', 'wp-google-maps');
74
- ?>
75
- </a>
76
- </li>
77
- <li>
78
- <a href="#marker-listing">
79
- <?php
80
- _e('Marker Listing', 'wp-google-maps');
81
- ?>
82
- </a>
83
- </li>
84
- <li>
85
- <a href="#marker-filtering">
86
- <?php
87
- _e('Marker Filtering', 'wp-google-maps');
88
- ?>
89
- </a>
90
- </li>
91
- <li class="wpgmza-upgrade-tab wpgmza-upsell">
92
- <a href="#pro-upgrade">
93
- <?php
94
- _e('Pro Upgrade', 'wp-google-maps');
95
- ?>
96
- </a>
97
- </li>
98
- </ul>
99
-
100
- <div id="general-settings">
101
- <h3>
102
- <?php
103
- _e('Map Settings', 'wp-google-maps');
104
- ?>
105
- </h3>
106
-
107
- <input type='hidden' name='http_referer'/>
108
- <input type='hidden' name='wpgmza_id' id='wpgmza_id'/>
109
-
110
- <!-- NB: Populate dynamically -->
111
- <input type='hidden' name='map_start_lat'/>
112
- <input type='hidden' name='map_start_lng'/>
113
- <input type='hidden' name='wpgmza_start_location' id='wpgmza_start_location'/>
114
-
115
- <select id='wpgmza_start_zoom' name='wpgmza_start_zoom' style='display: none;'>
116
- <option value="1">1</option>
117
- <option value="2">2</option>
118
- <option value="3">3</option>
119
- <option value="4" selected>4</option>
120
- <option value="5">5</option>
121
- <option value="6">6</option>
122
- <option value="7">7</option>
123
- <option value="8">8</option>
124
- <option value="9">9</option>
125
- <option value="10">10</option>
126
- <option value="11">11</option>
127
- <option value="12">12</option>
128
- <option value="13">13</option>
129
- <option value="14">14</option>
130
- <option value="15">15</option>
131
- <option value="16">16</option>
132
- <option value="17">17</option>
133
- <option value="18">18</option>
134
- <option value="19">19</option>
135
- <option value="20">20</option>
136
- <option value="21">21</option>
137
- </select>
138
-
139
- <!-- NB: Adapted from old table based layout -->
140
- <fieldset>
141
- <legend>
142
- <?php
143
- _e("Short code","wp-google-maps");
144
- ?>
145
- </legend>
146
-
147
- <input type="text" readonly name="shortcode" class="wpgmza_copy_shortcode"/>
148
-
149
- <small class='wpgmza-info__small'>
150
- <i>
151
-
152
- <?php
153
- _e("copy this into your post or page to display the map", "wp-google-maps");
154
-
155
- // NB: I recommend adding a unique ID or class to this link and using the DOM to set the href rather than mixing content with logic here. - Perry
156
- echo ". ".__(sprintf("Or <a href='%s' target='BLANK'>click here to automatically create a Map Page now</a>.","admin.php?page=wp-google-maps-menu&amp;action=create-map-page&amp;map_id=".intval($_REQUEST['map_id'])),"wp-google-maps");
157
-
158
- ?>
159
- </i>
160
- </small>
161
- </fieldset>
162
-
163
- <fieldset>
164
- <legend>
165
- <?php
166
- _e("Map Name", "wp-google-maps");
167
- ?>
168
- </legend>
169
-
170
- <input id='wpgmza_title' name='map_title' class='regular-text' type='text'/>
171
- </fieldset>
172
-
173
- <fieldset>
174
- <legend>
175
- <?php
176
- _e("Zoom Level", "wp-google-maps");
177
- ?>
178
- </legend>
179
-
180
- <input type="text" id="amount" class='map_start_zoom' style="display: none;" name="map_start_zoom"/>
181
-
182
- <div id="slider-range-max"></div>
183
- </fieldset>
184
-
185
- <fieldset>
186
- <legend>
187
- <?php
188
- _e("Width", "wp-google-maps");
189
- ?>
190
- </legend>
191
-
192
- <input id="wpgmza_width" name="map_width" type="number" value="100"/>
193
-
194
- <select id='wpgmza_map_width_type' name='map_width_type'>
195
- <option value="px">px</option>
196
- <option value="%" selected="selected">%</option>
197
- </select>
198
-
199
- <small>
200
- <em>
201
- <?php
202
- _e("Set to 100% for a responsive map", "wp-google-maps");
203
- ?>
204
- </em>
205
- </small>
206
- </fieldset>
207
-
208
- <fieldset>
209
- <legend>
210
- <?php
211
- _e("Height", "wp-google-maps");
212
- ?>
213
- </legend>
214
-
215
- <input id='wpgmza_height' name='map_height' type='number'/>
216
-
217
- <select id='wpgmza_map_height_type' name='map_height_type'>
218
- <option value="px">px</option>
219
- <option value="%">%</option>
220
- </select>
221
-
222
- <span style='display:none;' id='wpgmza_height_warning'>
223
- <small>
224
- <?php
225
- _e("We recommend that you leave your height in PX. Depending on your theme, using % for the height may break your map.", "wp-google-maps");
226
- ?>
227
- </small>
228
- </span>
229
- </fieldset>
230
- </div>
231
-
232
- <div id="themes" class="wpgmza-open-layers-feature-unavailable wpgmza-theme-panel">
233
-
234
- <span class='notice notice-warning' data-wpgmza-require-engine="open-layers">
235
- <?php
236
- _e("Not available while using the OpenLayers engine.", "wp-google-maps");
237
- ?>
238
- </span>
239
-
240
- </div>
241
-
242
- <div id="directions" class="wpgmza-directions-box-settings-panel">
243
-
244
- <div class="update-nag update-att wpgmza-upsell">
245
-
246
- <i class="fa fa-arrow-circle-right"></i>
247
-
248
- <?php
249
- _e('<a target="_BLANK" href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=directions">
250
- Enable directions</a> with the Pro version for only $39.99 once off. Support and updates included forever', 'wp-google-maps');
251
- ?>
252
-
253
- </div>
254
-
255
- <table class='form-table wpgmza-pro-feature' id='wpgmaps_directions_options'>
256
- <tr>
257
- <td width='200px'><?php _e("Enable Directions?","wp-google-maps"); ?>:</td>
258
- <td>
259
- <div class='switch'>
260
- <input type='checkbox' class='cmn-toggle cmn-toggle-yes-no wpgmza-pro-feature'> <label class='cmn-override-big' data-on='<?php _e("No","wp-google-maps"); ?>' data-off='<?php _e("No","wp-google-maps"); ?>'></label>
261
- </div>
262
- </td>
263
- </tr>
264
- <tr>
265
- <td>
266
- <?php _e("Directions Box Open by Default?","wp-google-maps"); ?>:
267
- </td>
268
- <td>
269
- <select class='postform wpgmza-pro-feature'>
270
- <option><?php _e("No","wp-google-maps"); ?></option>
271
- <option><?php _e("Yes, on the left","wp-google-maps"); ?></option>
272
- <option><?php _e("Yes, on the right","wp-google-maps"); ?></option>
273
- <option><?php _e("Yes, above","wp-google-maps"); ?></option>
274
- <option><?php _e("Yes, below","wp-google-maps"); ?></option>
275
- </select>
276
- </td>
277
- </tr>
278
- <tr>
279
- <td>
280
- <?php _e("Directions Box Width","wp-google-maps"); ?>:
281
- </td>
282
- <td>
283
- <input type='text' size='4' maxlength='4' class='small-text wpgmza-pro-feature' /> px
284
- </td>
285
- </tr>
286
-
287
- </table>
288
-
289
- </div>
290
-
291
- <div id="store-locator">
292
-
293
- <!-- TODO: Use progressive enhancement here -->
294
-
295
- <fieldset>
296
- <legend>
297
- <?php
298
- _e("Enable Store Locator", "wp-google-maps");
299
- ?>
300
- </legend>
301
-
302
- <input type='checkbox'
303
- id='store_locator_enabled'
304
- name='store_locator_enabled'
305
- class='postform cmn-toggle cmn-toggle-yes-no'/>
306
- <label class='cmn-override-big-wide'
307
- for='store_locator_enabled'
308
- data-on='<?php esc_attr_e("Yes", "wp-google-maps"); ?>'
309
- data-off='<?php esc_attr_e("No", "wp-google-maps"); ?>'>
310
- </label>
311
-
312
- </fieldset>
313
-
314
- <fieldset data-require-legacy-user-interface-style="true">
315
- <legend>
316
- <?php
317
- _e("Store Locator Style", "wp-google-maps");
318
- ?>
319
- </legend>
320
-
321
- <ul>
322
- <li>
323
- <label>
324
- <input type='radio'
325
- name='store_locator_style'
326
- value='legacy'
327
- />
328
-
329
- <?php
330
- _e("Legacy", "wp-google-maps");
331
- ?>
332
- </label>
333
- </li>
334
- <li>
335
- <label>
336
- <input type='radio'
337
- name='store_locator_style'
338
- value='modern'
339
- />
340
-
341
- <?php
342
- _e("Modern", "wp-google-maps");
343
- ?>
344
- </label>
345
- </li>
346
- </ul>
347
- </fieldset>
348
-
349
- <fieldset data-require-legacy-user-interface-style="false">
350
- <legend>
351
- <?php
352
- _e("Store Locator Style", "wp-google-maps");
353
- ?>
354
- </legend>
355
-
356
- <label class="notice notice-info">
357
- <?php
358
- echo sprintf(
359
- __("Looking for styling settings? Try our new <a href='%s' target='_blank'>User Interface Style</a> setting.", "wp-google-maps"),
360
- admin_url('admin.php?page=wp-google-maps-menu-settings')
361
- );
362
- ?>
363
- </label>
364
-
365
- </fieldset>
366
-
367
- <fieldset class="wpgmza-pro-feature">
368
- <legend>
369
- <?php
370
- _e("Search Area", "wp-google-maps");
371
- ?>
372
- </legend>
373
-
374
- <ul>
375
- <li>
376
- <label>
377
- <input type='radio'
378
- name='store_locator_search_area'
379
- value='radial'
380
- checked='checked'
381
- class="wpgmza-pro-feature"
382
- />
383
-
384
- <?php
385
- _e("Radial", "wp-google-maps");
386
- ?>
387
- </label>
388
-
389
- <p>
390
- <small>
391
- <?php
392
- _e("Allows the user to select a radius from a predefined list", "wp-google-maps");
393
- ?>
394
- </small>
395
- </p>
396
- </li>
397
- <li>
398
- <label>
399
- <input type='radio'
400
- name='store_locator_search_area'
401
- value='auto'
402
- class="wpgmza-pro-feature"
403
- />
404
-
405
- <?php
406
- _e("Auto", "wp-google-maps");
407
- ?>
408
- </label>
409
-
410
- <p>
411
- <small>
412
- <?php
413
- _e("Intelligently detects the zoom level based on the location entered", "wp-google-maps");
414
- ?>
415
- </small>
416
- </p>
417
-
418
- <p class="wpgmza-pro-feature-hide" data-search-area="auto">
419
- <small>
420
- <?php
421
- _e("Marker listings will not be filtered based on visible markers. Enable the 'Only load markers within viewport (beta)' option for beta filtering support", "wp-google-maps");
422
- ?>
423
- </small>
424
- </p>
425
- </li>
426
- <ul>
427
- </fieldset>
428
-
429
- <div class="wpgmza-upsell">
430
- <i class="fa fa-arrow-circle-right"></i>
431
- <?php
432
- _e('Enable intelligent, automatic search area with our <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=store-locator">Pro add-on</a>', 'wp-google-maps');
433
- ?>
434
- </div>
435
-
436
- <fieldset data-search-area="radial">
437
- <legend>
438
- <?php
439
- _e("Radius Style", "wp-google-maps");
440
- ?>
441
- </legend>
442
- <ul>
443
- <li>
444
- <label>
445
- <input type='radio'
446
- name='wpgmza_store_locator_radius_style'
447
- value='legacy'
448
- checked='checked'
449
- />
450
-
451
- <?php
452
- _e("Legacy", "wp-google-maps");
453
- ?>
454
- </label>
455
- </li>
456
- <li>
457
- <label>
458
- <input type='radio'
459
- name='wpgmza_store_locator_radius_style'
460
- value='modern'/>
461
-
462
- <?php
463
- _e("Modern", "wp-google-maps");
464
- ?>
465
- </label>
466
- </li>
467
- </ul>
468
- </fieldset>
469
-
470
- <fieldset data-search-area="radial">
471
- <legend>
472
- <?php
473
- _e("Default radius", "wp-google-maps");
474
- ?>
475
- </legend>
476
-
477
- <select name='wpgmza_store_locator_default_radius' class='wpgmza-store-locator-default-radius'></select>
478
- </fieldset>
479
-
480
- <fieldset data-search-area="auto">
481
- <legend>
482
- <?php
483
- _e("Maximum zoom", "wp-google-maps");
484
- ?>
485
- </legend>
486
-
487
- <input name='store_locator_auto_area_max_zoom'
488
- type='number'
489
- min='1'
490
- max='21'/>
491
- </fieldset>
492
-
493
- <fieldset id="wpgmza-store-locator-country-restriction-container" class="wpgmza-pro-feature">
494
- <legend>
495
- <?php
496
- _e("Restrict to country", "wp-google-maps");
497
- ?>
498
- </legend>
499
- </fieldset>
500
-
501
- <fieldset>
502
- <legend>
503
- <?php
504
- _e("Show distance in", "wp-google-maps");
505
- ?>
506
- </legend>
507
-
508
- <input type='checkbox'
509
- id='store_locator_distance'
510
- name='store_locator_distance'
511
- class='postform cmn-toggle cmn-toggle-yes-no'/>
512
- <label class='cmn-override-big-wide'
513
- for='store_locator_distance'
514
- data-on='<?php esc_attr_e("Miles", "wp-google-maps"); ?>'
515
- data-off='<?php esc_attr_e("Kilometers", "wp-google-maps"); ?>'>
516
- </label>
517
- </fieldset>
518
-
519
- <fieldset>
520
- <legend>
521
- <?php
522
- _e("Store Locator Placement", "wp-google-maps");
523
- ?>
524
- </legend>
525
-
526
- <div class='switch'>
527
- <input type='checkbox'
528
- id='wpgmza_store_locator_position'
529
- name='wpgmza_store_locator_position'
530
- class='postform cmn-toggle cmn-toggle-yes-no'/>
531
- <label class='cmn-override-big-wide'
532
- for='wpgmza_store_locator_position'
533
- data-on='<?php esc_attr_e("Below Map", "wp-google-maps"); ?>'
534
- data-off='<?php esc_attr_e("Above Map","wp-google-maps"); ?>'>
535
- </label>
536
- </div>
537
- </fieldset>
538
-
539
- <fieldset>
540
- <legend>
541
- <?php
542
- _e("Show distance from search", "wp-google-maps");
543
- ?>
544
- </legend>
545
- <div class='switch'>
546
- <input type='checkbox'
547
- id='store_locator_show_distance'
548
- name='store_locator_show_distance'
549
- class='postform cmn-toggle cmn-toggle-round-flat'
550
- />
551
- <label for='store_locator_show_distance'></label>
552
- </div>
553
- </fieldset>
554
-
555
- <fieldset class="wpgmza-pro-feature">
556
- <legend>
557
- <?php
558
- _e("Allow category selection", "wp-google-maps");
559
- ?>
560
- </legend>
561
- <div class='switch'>
562
- <input type='checkbox'
563
- id='wpgmza_store_locator_category_enabled'
564
- name='store_locator_category'
565
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'
566
- />
567
- <label for='wpgmza_store_locator_category_enabled'></label>
568
- </div>
569
- </fieldset>
570
-
571
- <div class="wpgmza-upsell">
572
- <i class="fa fa-arrow-circle-right"></i>
573
- <?php
574
- _e('Enable search by category with our <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=store-locator">Pro add-on</a>', 'wp-google-maps');
575
- ?>
576
- </div>
577
-
578
- <fieldset class="wpgmza-pro-feature">
579
- <legend>
580
- <?php
581
- _e("Allow users to use their location as the starting point", "wp-google-maps");
582
- ?>
583
- </legend>
584
-
585
- <div class='switch'>
586
- <input type='checkbox'
587
- id='wpgmza_store_locator_use_their_location'
588
- name='wpgmza_store_locator_use_their_location'
589
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'>
590
- <label for='wpgmza_store_locator_use_their_location'></label>
591
- </div>
592
- </fieldset>
593
-
594
- <div class="wpgmza-upsell">
595
- <i class="fa fa-arrow-circle-right"></i>
596
- <?php
597
- _e('Enable user geolocation features with our <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=store-locator">Pro add-on</a>', 'wp-google-maps');
598
- ?>
599
- </div>
600
-
601
- <fieldset class="wpgmza-pro-feature">
602
- <legend>
603
- <?php
604
- _e("Show center point as an icon", "wp-google-maps");
605
- ?>
606
- </legend>
607
-
608
- <div class='switch'>
609
- <input type='checkbox'
610
- id='wpgmza_store_locator_bounce'
611
- name='wpgmza_store_locator_bounce'
612
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'>
613
- <label for='wpgmza_store_locator_bounce'></label>
614
- </div>
615
- </fieldset>
616
-
617
- <fieldset id="wpgmza_store_locator_bounce_conditional"
618
- style="display: none;"
619
- class="wpgmza-store-locator-marker-icon-picker-container wpgmza-pro-feature">
620
- <legend>
621
- <?php
622
- _e("Default Icon", "wp-google-maps");
623
- ?>
624
- </legend>
625
- </fieldset>
626
-
627
- <fieldset class="wpgmza-pro-feature">
628
- <legend>
629
- <?php
630
- _e("Marker animation", "wp-google-maps");
631
- ?>
632
- </legend>
633
-
634
- <select name="wpgmza_sl_animation" id="wpgmza_sl_animation" class="wpgmza-pro-feature">
635
- <option value="0">
636
- <?php
637
- _e("None", "wp-google-maps");
638
- ?>
639
- </option>
640
- <option value="1">
641
- <?php
642
- _e("Bounce", "wp-google-maps");
643
- ?>
644
- </option>
645
- <option value="2">
646
- <?php
647
- _e("Drop", "wp-google-maps");
648
- ?>
649
- </option>
650
- </select>
651
- </fieldset>
652
-
653
- <fieldset class="wpgmza-pro-feature">
654
- <legend>
655
- <?php
656
- _e("Hide all markers until a search is done", "wp-google-maps");
657
- ?>
658
- </legend>
659
-
660
- <div class='switch'>
661
- <input type='checkbox'
662
- id='wpgmza_store_locator_hide_before_search'
663
- name='wpgmza_store_locator_hide_before_search'
664
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'>
665
- <label for='wpgmza_store_locator_hide_before_search'></label>
666
- </div>
667
- </fieldset>
668
-
669
- <fieldset class="wpgmza-pro-feature">
670
- <legend>
671
- <?php
672
- _e("Query String", "wp-google-maps");
673
- ?>
674
- </legend>
675
-
676
- <input type="text" name="store_locator_query_string" id="wpgmza_store_locator_query_string" class="wpgmza-pro-feature"/>
677
- </fieldset>
678
-
679
- <fieldset class="wpgmza-pro-feature">
680
- <legend>
681
- <?php
682
- _e("Default address", "wp-google-maps");
683
- ?>
684
- </legend>
685
-
686
- <input type="text"
687
- name="store_locator_default_address"
688
- id="wpgmza_store_locator_default_address"
689
- class="wpgmza-address wpgmza-pro-feature"
690
- />
691
- </fieldset>
692
-
693
- <fieldset class="wpgmza-pro-feature">
694
- <legend>
695
- <?php
696
- _e("Enable title search", "wp-google-maps");
697
- ?>
698
- </legend>
699
-
700
- <div class='switch'>
701
- <input type='checkbox'
702
- id='wpgmza_store_locator_name_search'
703
- name='store_locator_name_search'
704
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'>
705
- <label for='wpgmza_store_locator_name_search'></label>
706
- </div>
707
- </fieldset>
708
-
709
- <fieldset class="wpgmza-pro-feature">
710
- <legend>
711
- <?php
712
- _e("Title search String", "wp-google-maps");
713
- ?>
714
- </legend>
715
-
716
- <input type="text"
717
- name="store_locator_name_string"
718
- id="wpgmza_store_locator_name_string"
719
- class="wpgmza-pro-feature"/>
720
- </fieldset>
721
-
722
- <fieldset class="wpgmza-pro-feature">
723
- <legend>
724
- <?php
725
- _e( "Not found message", "wp-google-maps");
726
- ?>
727
- </legend>
728
-
729
- <input type="text"
730
- name="store_locator_not_found_message"
731
- id="wpgmza_store_locator_not_found_message"
732
- class="wpgmza-pro-feature"/>
733
- </fieldset>
734
-
735
- <h3>
736
- <?php
737
- _e("Style options", "wp-google-maps");
738
- ?>
739
- </h3>
740
-
741
- <fieldset class="wpgmza-pro-feature">
742
- <legend>
743
- <?php
744
- _e("Line color", "wp-google-maps");
745
- ?>
746
- </legend>
747
- <input id="sl_stroke_color"
748
- name="sl_stroke_color"
749
- type="color"
750
- class="color wpgmza-pro-feature"/>
751
- </fieldset>
752
-
753
- <fieldset class="wpgmza_legacy_sl_style_option_area wpgmza-pro-feature">
754
- <legend>
755
- <?php
756
- _e("Line opacity", "wp-google-maps");
757
- ?>
758
- </legend>
759
-
760
- <input id="sl_stroke_opacity"
761
- name="sl_stroke_opacity"
762
- type="number"
763
- min="0"
764
- max="1"
765
- step="0.01"
766
- class="wpgmza-pro-feature"/>
767
-
768
- <small>
769
- <?php
770
- _e("(0 - 1.0) example: 0.5 for 50%", "wp-google-maps");
771
- ?>
772
- </small>
773
- </fieldset>
774
-
775
- <fieldset class="wpgmza_legacy_sl_style_option_area wpgmza-pro-feature">
776
- <legend>
777
- <?php
778
- _e("Fill color", "wp-google-maps");
779
- ?>
780
- </legend>
781
-
782
- <input id="sl_fill_color"
783
- name="sl_fill_color"
784
- type="color"
785
- class="color wpgmza-pro-feature"/>
786
- </fieldset>
787
-
788
- <fieldset class="wpgmza_legacy_sl_style_option_area wpgmza-pro-feature">
789
- <legend>
790
- <?php
791
- _e("Fill opacity", "wp-google-maps");
792
- ?>
793
- </legend>
794
-
795
- <input id="sl_fill_opacity"
796
- name="sl_fill_opacity"
797
- type="number"
798
- min="0"
799
- max="1"
800
- step="0.01"
801
- class="wpgmza-pro-feature"/>
802
- </fieldset>
803
-
804
- <div class="wpgmza-upsell">
805
- <i class="fa fa-arrow-circle-right"></i>
806
- <?php
807
- _e('Enable custom styling options with our <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=store-locator">Pro add-on</a>', 'wp-google-maps');
808
- ?>
809
- </div>
810
-
811
- <p>
812
- <em>
813
- <?php
814
- _e('View', 'wp-google-maps');
815
- ?>
816
- <a href='http://wpgmaps.com/documentation/store-locator' target='_BLANK'>
817
- <?php
818
- _e('Store Locator Documentation', 'wp-google-maps');
819
- ?>
820
- </a>
821
- </em>
822
- </p>
823
- </div>
824
-
825
- <div id="advanced-settings">
826
- <h3>
827
- <?php
828
- _e("Advanced Settings:", "wp-google-maps")
829
- ?>
830
- </h3>
831
-
832
- <fieldset id="advanced-settings-marker-icon-picker-container">
833
- <legend>
834
- <?php
835
- _e("Default Marker Image", "wp-google-maps");
836
- ?>
837
- </legend>
838
-
839
- <div class="wpgmza-upsell">
840
- <i class="fa fa-arrow-circle-right"></i>
841
- <?php
842
- _e('Enable custom marker icons with our <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=advanced">Pro add-on</a>', 'wp-google-maps');
843
- ?>
844
- </div>
845
- </fieldset>
846
-
847
- <fieldset data-wpgmza-require-engine="google-maps">
848
- <legend>
849
- <?php
850
- _e("Map type", "wp-google-maps");
851
- ?>
852
- </legend>
853
-
854
- <select id="wpgmza_map_type" name="type">
855
- <option value="1">
856
- <?php
857
- _e("Roadmap", "wp-google-maps");
858
- ?>
859
- </option>
860
- <option value="2">
861
- <?php
862
- _e("Satellite", "wp-google-maps");
863
- ?>
864
- </option>
865
- <option value="3">
866
- <?php
867
- _e("Hybrid", "wp-google-maps");
868
- ?>
869
- </option>
870
- <option value="4">
871
- <?php
872
- _e("Terrain", "wp-google-maps");
873
- ?>
874
- </option>
875
- </select>
876
-
877
- <div class='wpgmza-open-layers-feature-unavailable'></div>
878
- </fieldset>
879
-
880
- <fieldset>
881
- <legend>
882
- <?php
883
- _e("Map Alignment", "wp-google-maps");
884
- ?>
885
- </legend>
886
-
887
- <select id="wpgmza_map_align"
888
- name="wpgmza_map_align"
889
- class="postform">
890
- <option value="1">
891
- <?php
892
- _e('Left', 'wp-google-maps');
893
- ?>
894
- </option>
895
- <option value="2">
896
- <?php
897
- _e('Center', 'wp-google-maps');
898
- ?>
899
- </option>
900
- <option value="3">
901
- <?php
902
- _e('Right', 'wp-google-maps');
903
- ?>
904
- </option>
905
- <option value="4">
906
- <?php
907
- _e('None', 'wp-google-maps');
908
- ?>
909
- </option>
910
- </select>
911
- </fieldset>
912
-
913
- <fieldset class="wpgmza-pro-feature">
914
- <legend>
915
- <?php
916
- _e("Show User's Location?", "wp-google-maps");
917
- ?>
918
- </legend>
919
-
920
- <div class='switch wpgmza-geolocation-setting'>
921
- <input
922
- type='checkbox'
923
- id='wpgmza_show_user_location'
924
- name='show_user_location'
925
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
926
- <label for='wpgmza_show_user_location'></label>
927
- </div>
928
- </fieldset>
929
-
930
- <div class="wpgmza-upsell">
931
- <i class="fa fa-arrow-circle-right"></i>
932
- <?php
933
- _e('Enable user geolocation features with our <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=advanced">Pro add-on</a>', 'wp-google-maps');
934
- ?>
935
- </div>
936
-
937
- <fieldset class="wpgmza-user-location-marker-icon-picker-container wpgmza-pro-feature" id="wpgmza_show_user_location_conditional" style="display: none;">
938
- <legend>
939
- <?php
940
- _e("Default User Location Icon", "wp-google-maps");
941
- ?>
942
- </legend>
943
- </fieldset>
944
-
945
- <fieldset class="wpgmza-pro-feature">
946
- <legend>
947
- <?php
948
- _e("Jump to nearest marker on initialization?", "wp-google-maps");
949
- ?>
950
- </legend>
951
-
952
- <div class='switch wpgmza-geolocation-setting'>
953
- <input
954
- type='checkbox'
955
- id='wpgmza_jump_to_nearest_marker_on_initialization'
956
- name='jump_to_nearest_marker_on_initialization'
957
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
958
- <label for='wpgmza_jump_to_nearest_marker_on_initialization'></label>
959
- </div>
960
- </fieldset>
961
-
962
- <fieldset class="wpgmza-pro-feature">
963
- <legend>
964
- <?php
965
- _e("Automatically pan to users location?", "wp-google-maps");
966
- ?>
967
- </legend>
968
-
969
- <div class='switch wpgmza-geolocation-setting'>
970
- <input type='checkbox'
971
- id='wpgmza_automatically_pan_to_users_location'
972
- name='automatically_pan_to_users_location'
973
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
974
- <label for="wpgmza_automatically_pan_to_users_location"></label>
975
- </div>
976
- </fieldset>
977
-
978
- <fieldset class="wpgmza-pro-feature">
979
- <legend>
980
- <?php
981
- _e("Override User Location Zoom Level", "wp-google-maps");
982
- ?>
983
- </legend>
984
-
985
- <div class='switch wpgmza-geolocation-setting'>
986
- <input type='checkbox'
987
- id='wpgmza_override_users_location_zoom_level'
988
- name='override_users_location_zoom_level'
989
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
990
- <label for="wpgmza_override_users_location_zoom_level"></label>
991
- </div>
992
- </fieldset>
993
-
994
- <fieldset
995
- class="wpgmza-override-users-location-zoom-levels wpgmza-no-flex"
996
- id="wpgmza_override_users_location_zoom_levels_slider"
997
- style="display: none;">
998
- <legend>
999
- <?php
1000
- _e("Zoom Level", "wp-google-maps");
1001
- ?>
1002
- </legend>
1003
-
1004
- <input name="override_users_location_zoom_levels" style="display: none;" type="text" id="override_users_location_zoom_levels_slider">
1005
-
1006
- <div id="override-users-location-zoom-levels-slider"></div>
1007
- </fieldset>
1008
-
1009
- <fieldset class="wpgmza-pro-feature">
1010
- <legend>
1011
- <?php
1012
- _e("Show distance from location?", "wp-google-maps");
1013
- ?>
1014
- </legend>
1015
-
1016
- <div class='switch wpgmza-geolocation-setting'>
1017
- <input type='checkbox'
1018
- id='wpgmza_show_distance_from_location'
1019
- name='show_distance_from_location'
1020
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'
1021
- value='1'/>
1022
-
1023
- <label
1024
- for='wpgmza_show_distance_from_location'
1025
- data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1026
- data-off='<?php _e("No", "wp-google-maps"); ?>'>
1027
- </label>
1028
- </div>
1029
- <!--<small>
1030
- <em>
1031
- <?php
1032
- _e("This feature will use the users location (where available) or the searched address when a store locator search is performed.","wp-google-maps");
1033
- ?>
1034
- </em>
1035
- </small>-->
1036
- </fieldset>
1037
-
1038
-
1039
- <fieldset>
1040
- <legend>
1041
- <?php
1042
- _e("Maximum Zoom Out Level", "wp-google-maps");
1043
- ?>
1044
- </legend>
1045
-
1046
- <input id='wpgmza_max_zoom'
1047
- name='map_max_zoom'
1048
- min="0"
1049
- max="21"
1050
- step="1"
1051
- value="21"
1052
- type="number"/>
1053
- </fieldset>
1054
-
1055
- <fieldset>
1056
- <legend>
1057
- <?php
1058
- _e("Maximum Zoom In Level", "wp-google-maps");
1059
- ?>
1060
- </legend>
1061
-
1062
- <input id='wpgmza_min_zoom'
1063
- name='map_min_zoom'
1064
- min="0"
1065
- max="21"
1066
- step="1"
1067
- value="0"
1068
- type="number"/>
1069
- </fieldset>
1070
-
1071
- <div class="wpgmza-upsell">
1072
-
1073
- <i class="fa fa-arrow-circle-right"> </i>
1074
- <?php
1075
- echo sprintf(
1076
- __(
1077
- 'Get the rest of these advanced features with the Pro version for only <a href="%s" target="_BLANK">$39.99 once off</a>. Support and updates included forever.',
1078
- "wp-google-maps"
1079
- ),
1080
- "https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=advanced"
1081
- );
1082
- ?>
1083
-
1084
- </div>
1085
-
1086
- <fieldset class="wpgmza-pro-feature">
1087
- <legend>
1088
- <?php
1089
- _e("Click marker opens link", "wp-google-maps");
1090
- ?>
1091
- </legend>
1092
-
1093
- <div class='switch'>
1094
- <input type='checkbox'
1095
- id='wpgmza_click_open_link'
1096
- name='click_open_link'
1097
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
1098
- <label for='wpgmza_click_open_link'
1099
- data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1100
- data-off='<?php _e("No", "wp-google-maps"); ?>'>
1101
- </label>
1102
- </div>
1103
- </fieldset>
1104
-
1105
- <fieldset class="wpgmza-pro-feature">
1106
- <legend>
1107
- <?php
1108
- _e("Fit map bounds to markers?", "wp-google-maps");
1109
- ?>
1110
- </legend>
1111
-
1112
- <div class='switch'>
1113
- <input type='checkbox'
1114
- id='wpgmza_fit_maps_bounds_to_markers'
1115
- name='fit_maps_bounds_to_markers'
1116
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
1117
- <label for='wpgmza_fit_maps_bounds_to_markers'
1118
- data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1119
- data-off='<?php _e("No", "wp-google-maps"); ?>'>
1120
- </label>
1121
- </div>
1122
- </fieldset>
1123
-
1124
- <fieldset class="wpgmza-pro-feature">
1125
- <legend>
1126
- <?php
1127
- _e("Fit map bounds to markers after filtering?", "wp-google-maps");
1128
- ?>
1129
- </legend>
1130
-
1131
- <div class='switch'>
1132
- <input type='checkbox'
1133
- id='wpgmza_fit_maps_bounds_to_markers_after_filtering'
1134
- name='fit_maps_bounds_to_markers_after_filtering'
1135
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
1136
- <label for='wpgmza_fit_maps_bounds_to_markers_after_filtering'
1137
- data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1138
- data-off='<?php _e("No", "wp-google-maps"); ?>'>
1139
- </label>
1140
- </div>
1141
- </fieldset>
1142
-
1143
- <fieldset>
1144
- <legend>
1145
- <?php
1146
- _e("Hide point of interest", "wp-google-maps");
1147
- ?>
1148
- </legend>
1149
-
1150
- <div class='switch'>
1151
- <input type='checkbox'
1152
- id='wpgmza_hide_point_of_interest'
1153
- name='hide_point_of_interest'
1154
- class='postform cmn-toggle cmn-toggle-round-flat'/>
1155
- <label for='wpgmza_hide_point_of_interest'
1156
- data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1157
- data-off='<?php _e("No", "wp-google-maps"); ?>'>
1158
- </label>
1159
- </div>
1160
- </fieldset>
1161
-
1162
-
1163
- <fieldset class="wpgmza-pro-feature">
1164
- <legend>
1165
- <?php
1166
- _e("Zoom on marker click", "wp-google-maps");
1167
- ?>
1168
- </legend>
1169
-
1170
- <div>
1171
- <div class='switch'>
1172
- <input type='checkbox'
1173
- id='wpgmza_zoom_on_marker_click'
1174
- name='wpgmza_zoom_on_marker_click'
1175
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'>
1176
- <label for='wpgmza_zoom_on_marker_click'
1177
- data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1178
- data-off='<?php _e("No", "wp-google-maps"); ?>'>
1179
- </label>
1180
- </div>
1181
- </div>
1182
- </fieldset>
1183
-
1184
- <fieldset
1185
- class="wpgmza-zoom-on-marker-click-zoom-level wpgmza-no-flex"
1186
- id="wpgmza_zoom_on_marker_click_zoom_level"
1187
- style="display: none;">
1188
- <legend>
1189
- <?php
1190
- _e("Zoom Level", "wp-google-maps");
1191
- ?>
1192
- </legend>
1193
-
1194
- <input name="wpgmza_zoom_on_marker_click_slider" style="display: none;" type="text" id="wpgmza_zoom_on_marker_click_slider">
1195
-
1196
- <div id="zoom-on-marker-click-slider"></div>
1197
- </fieldset>
1198
-
1199
-
1200
- <fieldset>
1201
- <legend>
1202
- <?php
1203
- _e('Enable Layers', 'wp-google-maps');
1204
- ?>
1205
- </legend>
1206
-
1207
- <div>
1208
- <div class='switch switch-inline'>
1209
- <input type='checkbox'
1210
- id='wpgmza_bicycle'
1211
- name='bicycle'
1212
- class='postform cmn-toggle cmn-toggle-round-flat'>
1213
- <label for='wpgmza_bicycle'></label>
1214
- <label for='wpgmza_bicycle'>
1215
- <?php
1216
- _e("Bicycle Layer","wp-google-maps");
1217
- ?>
1218
- </label>
1219
- </div>
1220
-
1221
- <br>
1222
-
1223
- <div class='switch switch-inline'>
1224
- <input type='checkbox'
1225
- id='wpgmza_traffic'
1226
- name='traffic'
1227
- class='postform cmn-toggle cmn-toggle-round-flat'>
1228
- <label for='wpgmza_traffic'></label>
1229
- <label for='wpgmza_traffic'>
1230
- <?php
1231
- _e("Traffic Layer","wp-google-maps");
1232
- ?>
1233
- </label>
1234
- </div>
1235
-
1236
- <br>
1237
-
1238
- <div class='switch switch-inline'>
1239
- <input type='checkbox'
1240
- id='wpgmza_transport'
1241
- name='transport_layer'
1242
- class='postform cmn-toggle cmn-toggle-round-flat'>
1243
- <label for='wpgmza_transport'></label>
1244
- <label for='wpgmza_transport'>
1245
- <?php
1246
- _e("Transit Layer","wp-google-maps");
1247
- ?>
1248
- </label>
1249
- </div>
1250
-
1251
- <div class='wpgmza-open-layers-feature-unavailable'></div>
1252
- </div>
1253
- </fieldset>
1254
-
1255
- <fieldset class="wpgmza-pro-feature">
1256
- <legend>
1257
- <?php
1258
- _e("Close InfoWindow on Map Click", "wp-google-maps");
1259
- ?>
1260
- </legend>
1261
- <div class='switch'>
1262
- <input type="checkbox"
1263
- id="close_infowindow_on_map_click"
1264
- name="close_infowindow_on_map_click"
1265
- class="postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature"/>
1266
- <label for="close_infowindow_on_map_click"></label>
1267
- </div>
1268
- </fieldset>
1269
-
1270
- <fieldset class="wpgmza-pro-feature">
1271
- <legend>
1272
- <?php
1273
- _e("Disable lightbox for marker images", "wp-google-maps");
1274
- ?>
1275
- </legend>
1276
- <div class='switch'>
1277
- <input type="checkbox"
1278
- id="disable_lightbox_images"
1279
- name="disable_lightbox_images"
1280
- class="postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature"/>
1281
- <label for="disable_lightbox_images"></label>
1282
- </div>
1283
- </fieldset>
1284
-
1285
- <fieldset class="wpgmza-pro-feature">
1286
- <legend>
1287
- <?php
1288
- _e("Use Raw JPEG coordinates?", "wp-google-maps");
1289
- ?>
1290
- </legend>
1291
- <div class='switch'>
1292
- <input type="checkbox"
1293
- id="use_Raw_Jpeg_Coordinates"
1294
- name="use_Raw_Jpeg_Coordinates"
1295
- class="postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature"/>
1296
- <label for="use_Raw_Jpeg_Coordinates"></label>
1297
- </div>
1298
- </fieldset>
1299
-
1300
- <fieldset class="wpgmza-pro-feature" data-wpgmza-require-engine="google-maps">
1301
- <legend>
1302
- <?php
1303
- _e("Enable Polygon Labels", "wp-google-maps");
1304
- ?>
1305
- </legend>
1306
- <div class='switch'>
1307
- <input type="checkbox"
1308
- id="polygon_labels"
1309
- name="polygon_labels"
1310
- class="postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature"/>
1311
- <label for="polygon_labels"></label>
1312
- </div>
1313
- </fieldset>
1314
-
1315
- <fieldset class="wpgmza-pro-feature">
1316
- <legend>
1317
- <?php
1318
- _e("Disable Polygon InfoWindows", "wp-google-maps");
1319
- ?>
1320
- </legend>
1321
- <div class='switch'>
1322
- <input type="checkbox"
1323
- id="disable_polygon_info_windows"
1324
- name="disable_polygon_info_windows"
1325
- class="postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature"/>
1326
- <label for="disable_polygon_info_windows"></label>
1327
- </div>
1328
- </fieldset>
1329
-
1330
- <fieldset class="wpgmza-pro-feature">
1331
- <legend>
1332
- <?php
1333
- _e("KML/GeoRSS URL", "wp-google-maps");
1334
- ?>
1335
- </legend>
1336
-
1337
- <input id='wpgmza_kml'
1338
- name='kml'
1339
- type='text'
1340
- class='regular-text wpgmza-pro-feature'/>
1341
- <em>
1342
- <small class='wpgmza-text-field__description'>
1343
- <?php
1344
- _e("The KML/GeoRSS layer will over-ride most of your map settings","wp-google-maps");
1345
-
1346
- _e("For multiple sources, separate each one by a comma.","wp-google-maps");
1347
- ?>
1348
- </small>
1349
- </em>
1350
- </fieldset>
1351
-
1352
- <fieldset id="wpgmza-integration-panel-container" class="wpgmza-pro-feature wpgmza-pro-feature-hide">
1353
- <legend>
1354
- <?php
1355
- _e("Integration", "wp-google-maps");
1356
- ?>
1357
- </legend>
1358
- </fieldset>
1359
-
1360
- <fieldset id="wpgmza-marker-ratings" class="wpgmza-pro-feature">
1361
- <legend>
1362
- <?php
1363
- _e('Enable Marker Ratings', 'wp-google-maps');
1364
- ?>
1365
- </legend>
1366
- <div class='switch'>
1367
- <input type='checkbox'
1368
- id='enable_marker_ratings'
1369
- name='enable_marker_ratings'
1370
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
1371
- <label for='enable_marker_ratings'></label>
1372
- </div>
1373
- </fieldset>
1374
-
1375
- <fieldset class="wpgmza-pro-feature">
1376
- <legend>
1377
- <?php
1378
- _e("Only load markers within viewport (beta)", "wp-google-maps");
1379
- ?>
1380
- </legend>
1381
- <div class='switch switch-inline'>
1382
- <input type="checkbox"
1383
- id="only_load_markers_within_viewport"
1384
- name="only_load_markers_within_viewport"
1385
- class="postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature"/>
1386
- <label for="only_load_markers_within_viewport"></label>
1387
- <small><?php _e("This feature may not work as expected with bounds specific settings", "wp-google-maps"); ?></small>
1388
- </div>
1389
- </fieldset>
1390
-
1391
- <fieldset class="wpgmza-pro-feature">
1392
- <legend>
1393
- <?php
1394
- _e("Infowindow Style", "wp-google-maps");
1395
- ?>
1396
- </legend>
1397
- <div class='wpgmza-infowindow-style-picker wpgmza-flex'>
1398
-
1399
- <label>
1400
- <input type="radio" name="wpgmza_iw_type" value="0" class="wpgmza-pro-feature"/>
1401
- <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_hide'>
1402
- <div class="wpgmza-card wpgmza-card-border__hover">
1403
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_1.png'; ?>"
1404
- title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
1405
- class="wpgmza_mlist_selection"
1406
- />
1407
- <span class='wpgmza-infowindow-style__name'>
1408
- <?php
1409
- _e('Default Infowindow', 'wp-google-maps');
1410
- ?>
1411
- </span>
1412
- </div>
1413
- </div>
1414
- </label>
1415
-
1416
- <label>
1417
- <input type="radio" name="wpgmza_iw_type" value="1" class="wpgmza-pro-feature"/>
1418
- <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_show'>
1419
- <div class="wpgmza-card wpgmza-card-border__hover">
1420
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_2.png'; ?>"
1421
- title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
1422
- class="wpgmza_mlist_selection"
1423
- />
1424
- <span class='wpgmza-infowindow-style__name'>
1425
- <?php
1426
- _e('Modern Infowindow', 'wp-google-maps');
1427
- ?>
1428
- </span>
1429
- </div>
1430
- </div>
1431
- </label>
1432
-
1433
- <label>
1434
- <input type="radio" name="wpgmza_iw_type" value="2" class="wpgmza-pro-feature"/>
1435
- <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_show'>
1436
- <div class="wpgmza-card wpgmza-card-border__hover">
1437
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_3.png'; ?>"
1438
- title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
1439
- class="wpgmza_mlist_selection"
1440
- />
1441
- <span class='wpgmza-infowindow-style__name'>
1442
- <?php
1443
- _e('Modern Plus Infowindow', 'wp-google-maps');
1444
- ?>
1445
- </span>
1446
- </div>
1447
- </div>
1448
- </label>
1449
-
1450
- <label>
1451
- <input type="radio" name="wpgmza_iw_type" value="3" class="wpgmza-pro-feature"/>
1452
- <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_show'>
1453
- <div class="wpgmza-card wpgmza-card-border__hover">
1454
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_4.png'; ?>"
1455
- title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
1456
- class="wpgmza_mlist_selection"
1457
- />
1458
- <span class='wpgmza-infowindow-style__name'>
1459
- <?php
1460
- _e('Circular Infowindow', 'wp-google-maps');
1461
- ?>
1462
- </span>
1463
- </div>
1464
- </div>
1465
- </label>
1466
-
1467
-
1468
-
1469
- <label>
1470
- <input type="radio" name="wpgmza_iw_type" value="-1" class="wpgmza-pro-feature"/>
1471
- <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_hide'>
1472
- <div class="wpgmza-card wpgmza-card-border__hover">
1473
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_inherit.png'; ?>"
1474
- title="<?php esc_attr_e('Inherit Global Setting', 'wp-google-maps'); ?>"
1475
- class="wpgmza_mlist_selection"
1476
- />
1477
- <span class='wpgmza-infowindow-style__name'>
1478
- <?php
1479
- _e('Inherit Global Setting', 'wp-google-maps');
1480
- ?>
1481
- </span>
1482
- </div>
1483
- </div>
1484
- </label>
1485
- </div>
1486
- </fieldset>
1487
-
1488
- <fieldset id="iw_custom_colors_row" style="display: none;">
1489
- <legend>
1490
- <?php
1491
- _e("Infowindow Colors", "wp-google-maps");
1492
- ?>
1493
- </legend>
1494
-
1495
- <ul>
1496
- <li>
1497
- <input id="iw_primary_color" name="iw_primary_color" type="color" class="color"/>
1498
- <label for="iw_primary_color">
1499
- <?php
1500
- _e('Primary Color', 'wp-google-maps');
1501
- ?>
1502
- </label>
1503
- </li>
1504
- <li>
1505
- <input id="iw_accent_color" name="iw_accent_color" type="color" class="color"/>
1506
- <label for="iw_accent_color">
1507
- <?php
1508
- _e('Accent Color', 'wp-google-maps');
1509
- ?>
1510
- </label>
1511
- </li>
1512
- <li>
1513
- <input id="iw_text_color" name="iw_text_color" type="color" class="color"/>
1514
- <label for="iw_text_color">
1515
- <?php
1516
- _e('Text Color', 'wp-google-maps');
1517
- ?>
1518
- </label>
1519
- </li>
1520
- </ul>
1521
- </fieldset>
1522
- </div>
1523
-
1524
- <div id="marker-listing">
1525
-
1526
- <div class="wpgmza-upsell">
1527
- <i class="fa fa-arrow-circle-right"></i>
1528
- <?php
1529
- _e('Enable Marker Listing with the <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=marker_listing"target="_BLANK">Pro version for only $39.99 once off</a>. Support and updates included forever.', "wp-google-maps");
1530
- ?>
1531
- </div>
1532
-
1533
- <fieldset class="wpgmza-pro-feature">
1534
- <legend>
1535
- <?php
1536
- _e('Marker Listing Style', 'wp-google-maps');
1537
- ?>
1538
- </legend>
1539
-
1540
- <div class="wpgmza-marker-listing-style-menu">
1541
-
1542
- <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1543
- <div class='wpgmza-marker-listing-picker__item'>
1544
- <label class="wpgmza-card wpgmza-card-border__hover">
1545
- <input type="radio" name="wpgmza_listmarkers_by" value="0" checked="checked"/>
1546
- <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_0.png'/>
1547
- <span class='wpgmza-listing-item__title'>
1548
- <?php
1549
- _e('No marker listing', 'wp-google-maps');
1550
- ?>
1551
- </span>
1552
- </label>
1553
- </div>
1554
- </div>
1555
-
1556
- <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1557
- <div class='wpgmza-marker-listing-picker__item'>
1558
- <label class="wpgmza-card wpgmza-card-border__hover">
1559
- <input type="radio" name="wpgmza_listmarkers_by" value="1"/>
1560
- <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_1.png'/>
1561
- <span class='wpgmza-listing-item__title'>
1562
- <?php
1563
- _e('Basic table', 'wp-google-maps');
1564
- ?>
1565
- </span>
1566
- </label>
1567
- </div>
1568
- </div>
1569
-
1570
- <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1571
- <div class='wpgmza-marker-listing-picker__item'>
1572
- <label class="wpgmza-card wpgmza-card-border__hover">
1573
- <input type="radio" name="wpgmza_listmarkers_by" value="4"/>
1574
- <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_2.png'/>
1575
-
1576
- <span class='wpgmza-listing-item__title'>
1577
- <?php
1578
- _e('Basic list', 'wp-google-maps');
1579
- ?>
1580
- </span>
1581
- </label>
1582
- </div>
1583
- </div>
1584
-
1585
- <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1586
- <div class='wpgmza-marker-listing-picker__item'>
1587
- <label class="wpgmza-card wpgmza-card-border__hover">
1588
- <input type="radio" name="wpgmza_listmarkers_by" value="2"/>
1589
- <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_3.png'/>
1590
- <span class='wpgmza-listing-item__title'>
1591
- <?php
1592
- _e('Advanced table', 'wp-google-maps');
1593
- ?>
1594
- </span>
1595
- </label>
1596
- </div>
1597
- </div>
1598
-
1599
- <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1600
- <div class='wpgmza-marker-listing-picker__item'>
1601
- <label class="wpgmza-card wpgmza-card-border__hover">
1602
- <input type="radio" name="wpgmza_listmarkers_by" value="3"/>
1603
- <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_4.png'/>
1604
- <span class='wpgmza-listing-item__title'>
1605
- <?php
1606
- _e('Carousel', 'wp-google-maps');
1607
- ?>
1608
- </span>
1609
- </label>
1610
- </div>
1611
- </div>
1612
-
1613
- <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1614
- <div class='wpgmza-marker-listing-picker__item'>
1615
- <label class="wpgmza-card wpgmza-card-border__hover">
1616
- <input type="radio" name="wpgmza_listmarkers_by" value="6"/>
1617
- <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_modern.png'/>
1618
- <span class='wpgmza-listing-item__title'>
1619
- <?php
1620
- _e('Modern', 'wp-google-maps');
1621
- ?>
1622
- </span>
1623
- </label>
1624
- </div>
1625
- </div>
1626
-
1627
- <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1628
- <div class='wpgmza-marker-listing-picker__item'>
1629
- <label class="wpgmza-card wpgmza-card-border__hover">
1630
- <input type="radio" name="wpgmza_listmarkers_by" value="7"/>
1631
- <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_grid.png'/>
1632
- <span class='wpgmza-listing-item__title'>
1633
- <?php
1634
- _e('Grid', 'wp-google-maps');
1635
- ?>
1636
- </span>
1637
- </label>
1638
- </div>
1639
- </div>
1640
-
1641
- </div>
1642
- </fieldset>
1643
-
1644
- <fieldset class="wpgmza-pro-feature">
1645
- <legend>
1646
- <?php
1647
- _e("Marker Listing Placement", "wp-google-maps");
1648
- ?>
1649
- </legend>
1650
-
1651
- <div class='switch'>
1652
- <input type='checkbox'
1653
- id='wpgmza_marker_listing_position'
1654
- name='wpgmza_marker_listing_position'
1655
- class='postform cmn-toggle cmn-toggle-yes-no'>
1656
- <label class='cmn-override-big-wide'
1657
- for='wpgmza_marker_listing_position'
1658
- data-on='<?php esc_attr_e("Above Map", "wp-google-maps"); ?>'
1659
- data-off='<?php esc_attr_e("Below Map", "wp-google-maps"); ?>'>
1660
- </label>
1661
- </div>
1662
- </fieldset>
1663
-
1664
- <fieldset class="wpgmza-pro-feature">
1665
- <legend>
1666
- <?php
1667
- _e("Order markers by", "wp-google-maps");
1668
- ?>
1669
- </legend>
1670
-
1671
- <select id="order_markers_by" name="order_markers_by" class="postform">
1672
- <option value="1">
1673
- <?php
1674
- _e('ID', 'wp-google-maps');
1675
- ?>
1676
- </option>
1677
- <option value="2">
1678
- <?php
1679
- _e('Title', 'wp-google-maps');
1680
- ?>
1681
- </option>
1682
- <option value="3">
1683
- <?php
1684
- _e('Address', 'wp-google-maps');
1685
- ?>
1686
- </option>
1687
- <option value="4">
1688
- <?php
1689
- _e('Description', 'wp-google-maps');
1690
- ?>
1691
- </option>
1692
- <option value="5">
1693
- <?php
1694
- _e('Category', 'wp-google-maps');
1695
- ?>
1696
- </option>
1697
- <option value="6">
1698
- <?php
1699
- _e('Category Priority', 'wp-google-maps');
1700
- ?>
1701
- </option>
1702
- <option value="7">
1703
- <?php
1704
- _e('Distance', 'wp-google-maps');
1705
- ?>
1706
- </option>
1707
- <option value="8">
1708
- <?php
1709
- _e('Rating', 'wp-google-maps');
1710
- ?>
1711
- </option>
1712
- </select>
1713
-
1714
- <select id="order_markers_choice" name="order_markers_choice">
1715
- <option value="1">
1716
- <?php
1717
- _e("Ascending", "wp-google-maps");
1718
- ?>
1719
- </option>
1720
- <option value="2">
1721
- <?php
1722
- _e("Descending", "wp-google-maps");
1723
- ?>
1724
- </option>
1725
- </select>
1726
- </fieldset>
1727
-
1728
- <fieldset class="wpgmza-pro-feature" data-wpgmza-require-engine="google-maps">
1729
- <legend>
1730
- <?php
1731
- _e("Move list inside map", "wp-google-maps");
1732
- ?>
1733
- </legend>
1734
-
1735
- <div class='switch'>
1736
- <input id='wpgmza_push_in_map'
1737
- name='wpgmza_push_in_map'
1738
- class='cmn-toggle cmn-toggle-round-flat'
1739
- type='checkbox'
1740
- value='1'/>
1741
- <label for='wpgmza_push_in_map'></label>
1742
- </div>
1743
- </fieldset>
1744
-
1745
- <fieldset id="wpgmza_marker_list_conditional" class="wpgmza-pro-feature" data-wpgmza-require-engine="google-maps">
1746
- <legend>
1747
- <?php
1748
- _e("Placement: ","wp-google-maps");
1749
- ?>
1750
- </legend>
1751
- <select id="wpgmza_push_in_map_placement" name="wpgmza_push_in_map_placement" class="postform">
1752
- <option value="1">
1753
- <?php
1754
- _e("Top Left", "wp-google-maps");
1755
- ?>
1756
- </option>
1757
- <option value="2">
1758
- <?php
1759
- _e("Top Center", "wp-google-maps");
1760
- ?>
1761
- </option>
1762
- <option value="3">
1763
- <?php
1764
- _e("Top Right", "wp-google-maps");
1765
- ?>
1766
- </option>
1767
- <option value="5">
1768
- <?php
1769
- _e("Left Top", "wp-google-maps");
1770
- ?>
1771
- </option>
1772
- <option value="4">
1773
- <?php
1774
- _e("Left Center", "wp-google-maps");
1775
- ?>
1776
- </option>
1777
- <option value="7">
1778
- <?php
1779
- _e("Right Top", "wp-google-maps");
1780
- ?>
1781
- </option>
1782
- <option value="8">
1783
- <?php
1784
- _e("Right Center", "wp-google-maps");
1785
- ?>
1786
- </option>
1787
- <option value="6">
1788
- <?php
1789
- _e("Left Bottom", "wp-google-maps");
1790
- ?>
1791
- </option>
1792
- <option value="99">
1793
- <?php
1794
- _e("Right Bottom", "wp-google-maps");
1795
- ?>
1796
- </option>
1797
- <option value="11">
1798
- <?php
1799
- _e("Bottom Center", "wp-google-maps");
1800
- ?>
1801
- </option>
1802
- <option value="10">
1803
- <?php
1804
- _e("Bottom Left", "wp-google-maps");
1805
- ?>
1806
- </option>
1807
- <option value="12">
1808
- <?php
1809
- _e("Bottom Right", "wp-google-maps");
1810
- ?>
1811
- </option>
1812
- </select>
1813
- </fieldset>
1814
-
1815
- <fieldset class="wpgmza-pro-feature" data-wpgmza-require-engine="google-maps">
1816
-
1817
- <legend>
1818
- <?php
1819
- _e("Container Width: ", "wp-google-maps");
1820
- ?>
1821
- </legend>
1822
-
1823
-
1824
- <input type="text"
1825
- name="wpgmza_push_in_map_width"
1826
- id="wpgmza_push_in_map_width"
1827
- placeholder='<?php esc_attr_e('% or px', 'wp-google-maps'); ?>'/>
1828
-
1829
- <em>
1830
- <?php
1831
- _e('Set as % or px, eg. 30% or 400px', 'wp-google-maps');
1832
- ?>
1833
- </em>
1834
- </fieldset>
1835
- <fieldset class="wpgmza-pro-feature" data-wpgmza-require-engine="google-maps">
1836
-
1837
- <legend>
1838
- <?php
1839
- _e("Container Height: ", "wp-google-maps");
1840
- ?>
1841
- </legend>
1842
-
1843
- <input type="text"
1844
- name="wpgmza_push_in_map_height"
1845
- id="wpgmza_push_in_map_height"
1846
- placeholder='<?php esc_attr_e('% or px', 'wp-google-maps'); ?>'/>
1847
- </fieldset>
1848
-
1849
- <fieldset class="wpgmza-pro-feature">
1850
- <legend>
1851
- <?php
1852
- _e("Filter by Category", "wp-google-maps");
1853
- ?>
1854
- </legend>
1855
- <div class='switch'>
1856
- <input id='filterbycat'
1857
- name='filterbycat'
1858
- class='cmn-toggle cmn-toggle-round-flat'
1859
- type='checkbox' value='1'/>
1860
- <label for='filterbycat'></label>
1861
- </div>
1862
- <label for='filterbycat' class='wpgmza-info__small'>
1863
- <?php
1864
- _e("Allow users to filter by category?", "wp-google-maps");
1865
- ?>
1866
- </label>
1867
- </fieldset>
1868
-
1869
- <fieldset class="wpgmza-pro-feature">
1870
- <legend>
1871
- <?php
1872
- _e("Override zoom level on listing click", "wp-google-maps");
1873
- ?>
1874
- </legend>
1875
-
1876
- <div>
1877
- <div class='switch'>
1878
- <input type='checkbox'
1879
- id='zoom_level_on_marker_listing_override'
1880
- name='zoom_level_on_marker_listing_override'
1881
- class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'>
1882
- <label for='zoom_level_on_marker_listing_override'
1883
- data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1884
- data-off='<?php _e("No", "wp-google-maps"); ?>'>
1885
- </label>
1886
- </div>
1887
- </div>
1888
- </fieldset>
1889
-
1890
- <fieldset
1891
- class="wpgmza-zoom-on-marker-listing-click-zoom-level wpgmza-no-flex"
1892
- id="zoom_level_on_marker_listing_click_level"
1893
- style="display: none;">
1894
- <legend>
1895
- <?php
1896
- _e("Zoom Level", "wp-google-maps");
1897
- ?>
1898
- </legend>
1899
-
1900
- <input name="zoom_level_on_marker_listing_click" style="display: none;" type="text" id="zoom_level_on_marker_listing_click">
1901
-
1902
- <div id="zoom-on-marker-listing-click-slider"></div>
1903
- </fieldset>
1904
-
1905
-
1906
-
1907
- <h3>
1908
- <?php
1909
- _e('DataTable Options', 'wp-google-maps');
1910
- ?>
1911
- </h3>
1912
-
1913
- <fieldset class="wpgmza-pro-feature">
1914
- <legend>
1915
- <?php
1916
- _e("No results message", "wp-google-maps");
1917
- ?>
1918
- </legend>
1919
-
1920
- <div>
1921
- <input type="text"
1922
- name="datatable_no_result_message"
1923
- id="datatable_no_result_message"
1924
- placeholder='<?php esc_attr_e('No matching records found', 'wp-google-maps'); ?>'
1925
- />
1926
- </div>
1927
- </fieldset>
1928
-
1929
- <fieldset class="wpgmza-pro-feature">
1930
- <legend>
1931
- <?php
1932
- _e("Remove search box", "wp-google-maps");
1933
- ?>
1934
- </legend>
1935
- <div class='switch'>
1936
- <input id='remove_search_box_datables'
1937
- name='remove_search_box_datables'
1938
- class='cmn-toggle cmn-toggle-round-flat'
1939
- type='checkbox' value='1'/>
1940
- <label for='remove_search_box_datables'></label>
1941
- </div>
1942
- <label for='remove_search_box_datables' class='wpgmza-info__small'>
1943
- <?php
1944
- _e("Remove search box from Marker Listing Table?", "wp-google-maps");
1945
- ?>
1946
- </label>
1947
- </fieldset>
1948
-
1949
- <fieldset class="wpgmza-pro-feature">
1950
- <legend>
1951
- <?php
1952
- _e("Select different pagination style", "wp-google-maps");
1953
- ?>
1954
- </legend>
1955
-
1956
- <select id="dataTable_pagination_style" name="dataTable_pagination_style" class="postform">
1957
- <option value="default">
1958
- <?php
1959
- _e("Default", "wp-google-maps");
1960
- ?>
1961
- </option>
1962
- <option value="page-number-buttons-only">
1963
- <?php
1964
- _e('Page number buttons only', 'wp-google-maps');
1965
- ?>
1966
- </option>
1967
- <option value="prev-and-next-buttons-only">
1968
- <?php
1969
- _e('Previous and Next buttons only', 'wp-google-maps');
1970
- ?>
1971
- </option>
1972
- <option value="prev-and-next-buttons-plus-page-numbers">
1973
- <?php
1974
- _e('Previous and Next buttons, plus page numbers', 'wp-google-maps');
1975
- ?>
1976
- </option>
1977
- <option value="first-prev-next-and-last-buttons">
1978
- <?php
1979
- _e('First, Previous, Next and Last buttons', 'wp-google-maps');
1980
- ?>
1981
- </option>
1982
- <option value="first-prev-next-and-last-buttons-plus-page-numbers">
1983
- <?php
1984
- _e('First, Previous, Next and Last buttons, plus page numbers', 'wp-google-maps');
1985
- ?>
1986
- </option>
1987
- <option value="first-and-last-buttons-plus-page-numbers">
1988
- <?php
1989
- _e('First and Last buttons, plus page numbers', 'wp-google-maps');
1990
- ?>
1991
- </option>
1992
- </select>
1993
- </fieldset>
1994
-
1995
- <fieldset class="wpgmza-pro-feature">
1996
- <legend>
1997
- <?php
1998
- _e("Change listing table search string", "wp-google-maps");
1999
- ?>
2000
- </legend>
2001
-
2002
- <div>
2003
- <input type="text"
2004
- name="datatable_search_string"
2005
- id="datatable_search_string"
2006
- placeholder='<?php esc_attr_e('Search:', 'wp-google-maps'); ?>'
2007
- />
2008
- </div>
2009
- </fieldset>
2010
-
2011
- <!--<fieldset class="wpgmza-pro-feature">
2012
- <div class='switch'>
2013
- <input id='datatable_result'
2014
- name='datatable_result'
2015
- class='cmn-toggle cmn-toggle-round-flat'
2016
- type='checkbox' value='1'/>
2017
- <label for='datatable_result'></label>
2018
- </div>
2019
- <label for='datatable_result' class='wpgmza-info__small'>
2020
- <?php
2021
- _e("Example: Showing 1 of 6 to 6 entries", "wp-google-maps");
2022
- ?>
2023
- </label>
2024
- </fieldset>-->
2025
-
2026
- <fieldset id="datable_strings" class="wpgmza-pro-feature">
2027
- <legend>
2028
- <?php
2029
- _e("Change results string", "wp-google-maps");
2030
- ?>
2031
- </legend>
2032
- <div>
2033
- <span>
2034
- <p><?php esc_attr_e('Showing:', 'wp-google-maps'); ?></p>
2035
- <input type="text"
2036
- name="datatable_result_start"
2037
- id="datatable_result_start"
2038
- placeholder='<?php esc_attr_e('Showing:', 'wp-google-maps'); ?>'
2039
- /></span>
2040
- </div>
2041
- <div>
2042
- <span>
2043
- <p><?php esc_attr_e('of', 'wp-google-maps'); ?></p>
2044
- <input type="text"
2045
- name="datatable_result_of"
2046
- id="datatable_result_of"
2047
- placeholder='<?php esc_attr_e('of', 'wp-google-maps'); ?>'
2048
- /></span>
2049
- </div>
2050
- <div>
2051
- <span>
2052
- <p><?php esc_attr_e('to', 'wp-google-maps'); ?></p>
2053
- <input type="text"
2054
- name="datatable_result_to"
2055
- id="datatable_result_to"
2056
- placeholder='<?php esc_attr_e('to', 'wp-google-maps'); ?>'
2057
- /></span>
2058
- </div>
2059
-
2060
- <div>
2061
- <span>
2062
- <p><?php esc_attr_e('entries', 'wp-google-maps'); ?></p>
2063
- <input type="text"
2064
- name="datatable_result_total"
2065
- id="datatable_result_total"
2066
- placeholder='<?php esc_attr_e('entries', 'wp-google-maps'); ?>'
2067
- /></span>
2068
- </div>
2069
- </fieldset>
2070
-
2071
- <!--
2072
- <fieldset class="wpgmza-pro-feature">
2073
- <legend>
2074
- <?php
2075
- _e("Change entries string", "wp-google-maps");
2076
- ?>
2077
- </legend>
2078
- <div class='switch'>
2079
- <input id='datatable_result_page'
2080
- name='datatable_result_page'
2081
- class='cmn-toggle cmn-toggle-round-flat'
2082
- type='checkbox' value='1'/>
2083
- <label for='datatable_result_page'></label>
2084
- </div>
2085
- <label for='datatable_result_page' class='wpgmza-info__small'>
2086
- <?php
2087
- _e("Example: Showing entries", "wp-google-maps");
2088
- ?>
2089
- </label>
2090
- </fieldset>
2091
- -->
2092
-
2093
- <fieldset id="datable_strings_entries" class="wpgmza-pro-feature">
2094
- <legend>
2095
-
2096
- </legend>
2097
- <div>
2098
- <span>
2099
- <p><?php esc_attr_e('Show:', 'wp-google-maps'); ?></p>
2100
- <input type="text"
2101
- name="datatable_result_show"
2102
- id="datatable_result_show"
2103
- placeholder='<?php esc_attr_e('Show:', 'wp-google-maps'); ?>'
2104
- /></span>
2105
- </div>
2106
-
2107
- <div>
2108
- <span>
2109
- <p><?php esc_attr_e('Entries', 'wp-google-maps'); ?></p>
2110
- <input type="text"
2111
- name="datatable_result_entries"
2112
- id="datatable_result_entries"
2113
- placeholder='<?php esc_attr_e('Entries', 'wp-google-maps'); ?>'
2114
- /></span>
2115
- </div>
2116
- </fieldset>
2117
-
2118
- </div>
2119
-
2120
- <div id="pro-upgrade" class="wpgmza-pro-feature-upsell">
2121
- <div id="wpgm_premium">
2122
- <div class='wpgmza-flex'>
2123
- <div class="wpgm_premium_row">
2124
- <div class='wpgmza-card'>
2125
- <div class="wpgm_icon"></div>
2126
- <div class="wpgm_details">
2127
- <h2>
2128
- <?php _e("Create custom markers with detailed info windows", "wp-google-maps") ?></h2>
2129
- <p><?php _e("Add titles, descriptions, HTML, images, animations and custom icons to your markers.", "wp-google-maps") ?></p>
2130
- </div>
2131
- </div>
2132
- </div>
2133
- <div class="wpgm_premium_row">
2134
- <div class='wpgmza-card'>
2135
- <div class="wpgm_icon"></div>
2136
- <div class="wpgm_details">
2137
- <h2>Enable directions</h2>
2138
- <p><?php _e("Allow your visitors to get directions to your markers. Either use their location as the starting point or allow them to type in an address.", "wp-google-maps") ?></p>
2139
- </div>
2140
- </div>
2141
- </div>
2142
- <div class="wpgm_premium_row">
2143
- <div class='wpgmza-card'>
2144
- <div class="wpgm_icon"></div>
2145
- <div class="wpgm_details">
2146
- <h2>Unlimited maps</h2>
2147
- <p><?php _e('Create as many maps as you like.', "wp-google-maps") ?></p>
2148
- </div>
2149
- </div>
2150
- </div>
2151
- <div class="wpgm_premium_row">
2152
- <div class='wpgmza-card'>
2153
- <div class="wpgm_icon"></div>
2154
- <div class="wpgm_details">
2155
- <h2>List your markers</h2>
2156
- <p><?php _e('Choose between three methods of listing your markers.', "wp-google-maps") ?></p>
2157
- </div>
2158
- </div>
2159
- </div>
2160
- <div class="wpgm_premium_row">
2161
- <div class='wpgmza-card'>
2162
- <div class="wpgm_icon"></div>
2163
- <div class="wpgm_details">
2164
- <h2><?php _e('Add categories to your markers', "wp-google-maps") ?></h2>
2165
- <p><?php _e('Create and assign categories to your markers which can then be filtered on your map.', "wp-google-maps") ?></p>
2166
- </div>
2167
- </div>
2168
- </div>
2169
- <div class="wpgm_premium_row">
2170
- <div class='wpgmza-card'>
2171
- <div class="wpgm_icon"></div>
2172
- <div class="wpgm_details">
2173
- <h2><?php _e('Advanced options', "wp-google-maps") ?></h2>
2174
- <p><?php _e("Enable advanced options such as showing your visitor's location, marker sorting, bicycle layers, traffic layers and more!", "wp-google-maps") ?></p>
2175
- </div>
2176
- </div>
2177
- </div>
2178
- <div class="wpgm_premium_row">
2179
- <div class='wpgmza-card'>
2180
- <div class="wpgm_icon"></div>
2181
- <div class="wpgm_details">
2182
- <h2><?php _e('Import / Export', "wp-google-maps") ?></h2>
2183
- <p><?php _e('Export your markers to a CSV file for quick and easy editing. Import large quantities of markers at once.', "wp-google-maps") ?></p>
2184
- </div>
2185
- </div>
2186
- </div>
2187
- <div class="wpgm_premium_row">
2188
- <div class='wpgmza-card'>
2189
- <div class="wpgm_icon"></div>
2190
- <div class="wpgm_details">
2191
- <h2><?php _e('Add KML &amp; Fusion Tables', "wp-google-maps") ?></h2>
2192
- <p><?php _e('Add your own KML layers or Fusion Table data to your map', "wp-google-maps") ?></p>
2193
- </div>
2194
- </div>
2195
- </div>
2196
- <div class="wpgm_premium_row">
2197
- <div class='wpgmza-card'>
2198
- <div class="wpgm_icon"></div>
2199
- <div class="wpgm_details">
2200
- <h2><?php _e('Polygons and Polylines', "wp-google-maps") ?></h2>
2201
- <p><?php _e('Add custom polygons and polylines to your map by simply clicking on the map. Perfect for displaying routes and serviced areas.', "wp-google-maps") ?></p>
2202
- </div>
2203
- </div>
2204
- </div>
2205
- <div class="wpgm_premium_row">
2206
- <div class='wpgmza-card'>
2207
- <div class="wpgm_icon"></div>
2208
- <div class="wpgm_details">
2209
- <h2><?php _e('Amazing Support', "wp-google-maps") ?></h2>
2210
- <p><?php _e('We pride ourselves on providing quick and amazing support. <a target="_BLANK" href="http://wordpress.org/support/view/plugin-reviews/wp-google-maps?filter=5">Read what some of our users think of our support</a>.', "wp-google-maps") ?></p>
2211
- </div>
2212
- </div>
2213
- </div>
2214
- <div class="wpgm_premium_row">
2215
- <div class="wpgmza-card">
2216
- <div class="wpgm_icon"></div>
2217
- <div class="wpgm_details">
2218
- <h2><?php _e('Easy Upgrade', "wp-google-maps") ?></h2>
2219
- <p><?php _e("You'll receive a download link immediately. Simply upload and activate the Pro plugin to your WordPress admin area and you're done!", "wp-google-maps") ?></p>
2220
- </div>
2221
- </div>
2222
- </div>
2223
- <div class="wpgm_premium_row">
2224
- <div class='wpgmza-card'>
2225
- <div class="wpgm_icon"></div>
2226
- <div class="wpgm_details">
2227
- <h2><?php _e('Free updates and support forever', "wp-google-maps") ?></h2>
2228
- <p><?php _e("Once you're a pro user, you'll receive free updates and support forever! You'll also receive amazing specials on any future plugins we release.", "wp-google-maps") ?></p>
2229
- </div>
2230
- </div>
2231
- </div>
2232
- </div>
2233
-
2234
- <p>
2235
- <?php
2236
- _e('Get all of this and more for only $39.99 once off', 'wp-google-maps');
2237
- ?>
2238
- </p>
2239
- <p>
2240
- <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=upgradenow" target="_BLANK" title="Upgrade now for only $39.99 once off" class="button-primary" style="font-size:20px; display:block; width:220px; text-align:center; height:42px; line-height:41px;" id="wpgmza-upgrade-now__btn">
2241
- <?php esc_html_e('Upgrade Now', "wp-google-maps") ?>
2242
- </a>
2243
- </p>
2244
-
2245
- <p>
2246
- <a href="https://www.wpgmaps.com/demo/" target="_BLANK">
2247
- <?php esc_html_e('View the demos', 'wp-google-maps'); ?></a>
2248
- </p>
2249
-
2250
- <p>
2251
- <?php
2252
- _e("Have a sales question? Contact Nick on <a href=\"mailto:nick@wpgmaps.com\">nick@wpgmaps.com</a> or use our <a href=\"https://www.wpgmaps.com/contact-us/\" target=\"_BLANK\">contact form</a>.", "wp-google-maps")
2253
- ?>
2254
- </p>
2255
- <p>
2256
- <?php
2257
- _e("Need help? <a href=\"https://www.wpgmaps.com/forums/\" target=\"_BLANK\">Ask a question on our support forum</a>.", "wp-google-maps")
2258
- ?>
2259
- </p>
2260
- </div>
2261
- </div>
2262
-
2263
- </div> <!-- End of tabs -->
2264
-
2265
- <!-- NB: <p> has a semantic meaning. Recommend using div instead with a class for padding / margin -->
2266
- <p>
2267
- <input type='submit' name='wpgmza_savemap' class='button-primary' value='<?php _e("Save Map", "wp-google-maps"); ?> &raquo;'/>
2268
- </p>
2269
-
2270
- <p class='wpgmza-map-edit__mouse-tip'>
2271
- <?php
2272
- _e("Tip: Use your mouse to change the layout of your map. When you have positioned the map to your desired location, press \"Save Map\" to keep your settings.", "wp-google-maps");
2273
- ?>
2274
- </p>
2275
- </form>
2276
-
2277
- <div class='wgmza-map-editor-holder'>
2278
- <div style="display:block; overflow-y:auto; overflow-x:hidden; width:49%; margin-right:1%; float:left;">
2279
- <div id="wpgmaps_tabs_markers" class="wpgmza-form">
2280
-
2281
- <div class="wpgmza-editor-row">
2282
- <div class="wpgmza-editor-col">
2283
- <ul class='wpgmza-tab-wrap'>
2284
- <li>
2285
- <a href="#markers">
2286
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/marker-tab-icon.png"; ?>" alt=""/>
2287
- <?php _e("Markers","wp-google-maps"); ?>
2288
- </a>
2289
- </li>
2290
-
2291
- <li class="wpgmza-basic-only wpgmza-upgrade-tab">
2292
- <a href="#advanced-markers">
2293
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/marker-tab-icon.png"; ?>" alt=""/>
2294
- <?php _e("Advanced Markers","wp-google-maps"); ?>
2295
- </a>
2296
- </li>
2297
-
2298
- <li>
2299
- <a href="#polygons">
2300
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/polygon.png"; ?>" alt=""/>
2301
- <?php _e("Polygons","wp-google-maps"); ?>
2302
- </a>
2303
- </li>
2304
- <li>
2305
- <a href="#polylines">
2306
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/polyline.png"; ?>" alt=""/>
2307
- <?php _e("Polylines","wp-google-maps"); ?>
2308
- </a>
2309
- </li>
2310
- <li>
2311
- <a href="#heatmaps">
2312
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/heatmap.png"; ?>" alt=""/>
2313
- <?php _e("Heatmaps","wp-google-maps"); ?>
2314
- </a>
2315
- </li>
2316
- <li>
2317
- <a href="#circles">
2318
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/circle.png"; ?>" alt=""/>
2319
- <?php _e("Circles","wp-google-maps"); ?>
2320
- </a>
2321
- </li>
2322
- <li>
2323
- <a href="#rectangles">
2324
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/rectangle.png"; ?>" alt=""/>
2325
- <?php _e("Rectangles","wp-google-maps"); ?>
2326
- </a>
2327
- </li>
2328
- </ul>
2329
- </div>
2330
- </div>
2331
-
2332
- <div class="wpgmza-editor-row">
2333
-
2334
- <?php /* map used to be here */ ?>
2335
-
2336
- </div>
2337
-
2338
-
2339
-
2340
-
2341
- <div class="wpgmza-feature-accordion" id="markers" data-wpgmza-feature-type="marker">
2342
-
2343
- <div class="wpgmza-accordion">
2344
- <h3
2345
- data-add-caption="<?php esc_attr_e('Add a new Marker', 'wp-google-maps'); ?>"
2346
- data-edit-caption="<?php esc_attr_e('Edit Marker', 'wp-google-maps'); ?>">
2347
-
2348
- <!-- <i class="fa fa-plus-circle" aria-hidden="true"></i> -->
2349
- <?php _e('Add a new Marker', 'wp-google-maps'); ?>
2350
-
2351
- </h3>
2352
-
2353
- <div class="wpgmza-feature-panel-container"></div>
2354
-
2355
-
2356
-
2357
-
2358
-
2359
-
2360
- </div>
2361
-
2362
- </div>
2363
-
2364
- <div class="wpgmza-feature-accordion" id="polygons" data-wpgmza-feature-type="polygon">
2365
-
2366
- <div class="wpgmza-accordion">
2367
- <h3
2368
- data-add-caption="<?php esc_attr_e('Add a new Polygon', 'wp-google-maps'); ?>"
2369
- data-edit-caption="<?php esc_attr_e('Edit Polygon', 'wp-google-maps'); ?>">
2370
-
2371
- <!-- <i class="fa fa-plus-circle" aria-hidden="true"></i> -->
2372
- <?php _e('Add a new Polygon', 'wp-google-maps'); ?>
2373
-
2374
- </h3>
2375
-
2376
- <div class="wpgmza-feature-panel-container"></div>
2377
-
2378
-
2379
-
2380
-
2381
- </div>
2382
-
2383
- </div>
2384
-
2385
- <div class="wpgmza-feature-accordion" id="polylines" data-wpgmza-feature-type="polyline">
2386
-
2387
- <div class="wpgmza-accordion">
2388
- <h3
2389
- data-add-caption="<?php esc_attr_e('Add a new Polyline', 'wp-google-maps'); ?>"
2390
- data-edit-caption="<?php esc_attr_e('Edit Polyline', 'wp-google-maps'); ?>">
2391
-
2392
- <!-- <i class="fa fa-plus-circle" aria-hidden="true"></i> -->
2393
- <?php _e('Add a new Polyline', 'wp-google-maps'); ?>
2394
-
2395
- </h3>
2396
-
2397
- <div class="wpgmza-feature-panel-container"></div>
2398
-
2399
-
2400
- </div>
2401
-
2402
- </div>
2403
-
2404
- <div class="wpgmza-feature-accordion" id="heatmaps" data-wpgmza-feature-type="heatmap">
2405
-
2406
- <div class="wpgmza-accordion">
2407
- <h3
2408
- data-add-caption="<?php esc_attr_e('Add a new Heatmap', 'wp-google-maps'); ?>"
2409
- data-edit-caption="<?php esc_attr_e('Edit Heatmaps', 'wp-google-maps'); ?>">
2410
-
2411
- <?php _e('Add a new Heatmap', 'wp-google-maps'); ?>
2412
-
2413
- </h3>
2414
-
2415
- <div class="wpgmza-feature-panel-container"></div>
2416
-
2417
-
2418
-
2419
- </div>
2420
-
2421
- </div>
2422
-
2423
- <div class="wpgmza-feature-accordion" id="circles" data-wpgmza-feature-type="circle">
2424
-
2425
- <div class="wpgmza-accordion">
2426
- <h3
2427
- data-add-caption="<?php esc_attr_e('Add a new Circle', 'wp-google-maps'); ?>"
2428
- data-edit-caption="<?php esc_attr_e('Edit Circle', 'wp-google-maps'); ?>">
2429
-
2430
- <!-- <i class="fa fa-plus-circle" aria-hidden="true"></i> -->
2431
- <?php _e('Add a new Circle', 'wp-google-maps'); ?>
2432
-
2433
- </h3>
2434
-
2435
- <div class="wpgmza-feature-panel-container"></div>
2436
-
2437
-
2438
-
2439
-
2440
- </div>
2441
-
2442
- </div>
2443
-
2444
- <div class="wpgmza-feature-accordion" id="rectangles" data-wpgmza-feature-type="rectangle">
2445
-
2446
- <div class="wpgmza-accordion">
2447
- <h3
2448
- data-add-caption="<?php esc_attr_e('Add a new Rectangle', 'wp-google-maps'); ?>"
2449
- data-edit-caption="<?php esc_attr_e('Edit Rectangle', 'wp-google-maps'); ?>">
2450
- <!-- <i class="fa fa-plus-circle" aria-hidden="true"></i> -->
2451
- <?php _e('Add a new Rectangle', 'wp-google-maps'); ?>
2452
- </h3>
2453
-
2454
- <div class="wpgmza-feature-panel-container"></div>
2455
-
2456
-
2457
-
2458
-
2459
- </div>
2460
-
2461
- </div>
2462
-
2463
- <div id="advanced-markers">
2464
-
2465
- <div class="wpgmza-upsell">
2466
- <i class="fa fa-arrow-circle-right"></i>
2467
- <a target="_BLANK" href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=advanced_markers"><?php esc_html_e("Add advanced markers", "wp-google-maps"); ?></a>
2468
- <?php
2469
- esc_html_e("with the Pro version","wp-google-maps");
2470
- ?>
2471
- </div>
2472
-
2473
- <!-- The content will be imported by MapEditPage -->
2474
-
2475
- </div>
2476
-
2477
- </div>
2478
-
2479
-
2480
-
2481
-
2482
- </div>
2483
-
2484
- <div class="wpgmza-editor-col map-container-wrap">
2485
- <?php echo wpgmaps_check_if_no_api_key(); ?>
2486
- <p class='notice notice-error wpgmza-missing-key-notice wpgmza-hidden'>
2487
- <?php
2488
- echo sprintf(
2489
- __('Please ensure you <a href="%s">enter a Google Maps API key</a> to continue using Google Maps. Alternatively, swap over to Open Layers by clicking <a id="wpgm-swap-to-open-layers" href="%s">here</a>.', 'wp-google-maps'),
2490
- "admin.php?page=wp-google-maps-menu-settings",
2491
- "javascript:void(0);"
2492
- );
2493
- ?>
2494
- </p>
2495
- <div class='map_wrapper'>
2496
- <div id="wpgmza-map-container"></div>
2497
- </div>
2498
-
2499
- <div id="wpgmaps_save_reminder" style="display:none;">
2500
- <div class="wpgmza-nag wpgmza-update-nag" style='text-align:center;'>
2501
- <h4><?php _e("Remember to save your map!","wp-google-maps"); ?></h4>
2502
- </div>
2503
- </div>
2504
-
2505
- </div>
2506
- </div>
2507
-
2508
- <h3 class="separate wpgmza-table-container-title" id="wpgmza-table-container-title-Rectangle"><?php _e('Edit existing Rectangles', 'wp-google-maps'); ?></h3>
2509
- <h3 class="separate wpgmza-table-container-title" id="wpgmza-table-container-title-Circle"><?php _e('Edit existing Circles', 'wp-google-maps'); ?></h3>
2510
- <h3 class="separate wpgmza-table-container-title" id="wpgmza-table-container-title-Heatmap"><?php _e('Edit existing Heatmaps', 'wp-google-maps'); ?></h3>
2511
- <h3 class="separate wpgmza-table-container-title" id="wpgmza-table-container-title-Polyline"><?php _e('Edit existing Polylines', 'wp-google-maps'); ?></h3>
2512
- <h3 class="separate wpgmza-table-container-title" id="wpgmza-table-container-title-Polygon"><?php _e('Edit existing Polygons', 'wp-google-maps'); ?></h3>
2513
- <h3 class="separate wpgmza-table-container-title" id="wpgmza-table-container-title-Marker"><?php _e('Edit existing Markers', 'wp-google-maps'); ?></h3>
2514
-
2515
-
2516
- <div class="wpgmza-table-container" id="wpgmza-table-container-Marker"></div>
2517
- <div class="wpgmza-table-container" id="wpgmza-table-container-Polygon"></div>
2518
- <div class="wpgmza-table-container" id="wpgmza-table-container-Polyline"></div>
2519
- <div class="wpgmza-table-container wpgmza-pro-feature-hide" id="wpgmza-table-container-Heatmap"></div>
2520
- <div class="wpgmza-table-container" id="wpgmza-table-container-Rectangle"></div>
2521
- <div class="wpgmza-table-container" id="wpgmza-table-container-Circle"></div>
2522
-
2523
-
2524
-
2525
- <div style='clear:both;' id='wpgmza-pro-features' class="wpgmza-upsell wpgmza-flex wpgmza_no_shadow">
2526
- <div class='wpgmza-pro-features__item'>
2527
- <div class='wpgmza-card'>
2528
- <div>
2529
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL; ?>images/custom_markers.jpg"
2530
- width="260"
2531
- class='wpgmza-promo'
2532
- title="<?php _e("Add detailed information to your markers!", "wp-google-maps"); ?>"
2533
- alt="<?php _e("Add custom markers to your map!", "wp-google-maps"); ?>"
2534
- />
2535
- <br/>
2536
- <br/>
2537
- </div>
2538
- <div valign="middle">
2539
- <span style="font-size:18px; color:#666;"
2540
- class='wpgmza-feature-item__desc'>
2541
- <?php
2542
- _e("Add detailed information to your markers for only", "wp-google-maps");
2543
- ?>
2544
- <strong>$39.99</strong>
2545
- <?php
2546
- _e("Click", "wp-google-maps");
2547
- ?>
2548
-
2549
- <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=image1"
2550
- title="Pro Edition"
2551
- target="_BLANK">
2552
- <?php
2553
- _e("here","wp-google-maps");
2554
- ?>
2555
- </a>
2556
- </span>
2557
- </div>
2558
- </div>
2559
- </div>
2560
- <div class='wpgmza-pro-features__item'>
2561
- <div class='wpgmza-card'>
2562
- <div>
2563
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL; ?>images/custom_marker_icons.jpg"
2564
- width="260"
2565
- class='wpgmza-promo'
2566
- title="<?php _e("Add custom markers to your map!", "wp-google-maps"); ?>"
2567
- alt="<?php _e("Add custom markers to your map!", "wp-google-maps"); ?>"/>
2568
-
2569
- <br />
2570
- <br />
2571
- </div>
2572
- <div valign="middle">
2573
- <span style="font-size:18px; color:#666;" class='wpgmza-feature-item__desc'>
2574
- <?php
2575
- _e("Add different marker icons, or your own icons to make your map really stand out!", "wp-google-maps");
2576
- ?>
2577
-
2578
- <?php
2579
- _e("Click","wp-google-maps");
2580
- ?>
2581
- <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=image3"
2582
- title="<?php _e("Pro Edition", "wp-google-maps"); ?>"
2583
- target="_BLANK">
2584
- <?php
2585
- _e("here", "wp-google-maps");
2586
- ?>
2587
- </a>
2588
- </span>
2589
- </div>
2590
- </div>
2591
- </div>
2592
- <div class='wpgmza-pro-features__item'>
2593
- <div class='wpgmza-card'>
2594
- <div>
2595
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL; ?>images/get_directions.jpg"
2596
- width="260"
2597
- class='wpgmza-promo'
2598
- title="<?php _e("Add custom markers to your map!", "wp-google-maps"); ?>"
2599
- alt="<?php _e("Add custom markers to your map!", "wp-google-maps"); ?>"/>
2600
- <br />
2601
- <br />
2602
- </div>
2603
- <div valign="middle">
2604
- <span style="font-size:18px; color:#666;" class='wpgmza-feature-item__desc'>
2605
- <?php
2606
- _e("Allow your visitors to get directions to your markers!", "wp-google-maps");
2607
- ?>
2608
-
2609
- <?php
2610
- _e("Click", "wp-google-maps");
2611
- ?>
2612
- <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=image2"
2613
- title="<?php _e("Pro Edition", "wp-google-maps"); ?>"
2614
- target="_BLANK">
2615
- <?php
2616
- _e("here", "wp-google-maps");
2617
- ?>
2618
- </a>
2619
- </span>
2620
- </div>
2621
- </div>
2622
- </div>
2623
- </div>
2624
-
2625
- <p id='wpgmza-basic-footer-text'>
2626
- <small>
2627
- <?php
2628
- _e("Thank you for using <a href='https://www.wpgmaps.com'>WP Google Maps</a>! Please <a href='https://wordpress.org/support/plugin/wp-google-maps/reviews/'>rate us on WordPress.org</a>", 'wp-google-maps');
2629
- ?>
2630
- |
2631
- <?php
2632
- echo sprintf(
2633
- __("WP Google Maps is a product of <img src='%s' alt='CODECABIN_' style='height: 1em;' class='wpgmze_cc_footer_image'/>", 'wp-google-maps'),
2634
- WPGMZA_PLUGIN_DIR_URL . 'images/codecabin.png'
2635
- );
2636
- ?>
2637
- |
2638
- <?php
2639
- _e("Please refer to our <a href='https://www.wpgmaps.com/privacy-policy' target='_blank'>Privacy Policy</a> for information on Data Processing", 'wp-google-maps')
2640
- ?>
2641
- |
2642
- <?php
2643
- _e("WP Google Maps encourages you to make use of the amazing icons at ", "wp-google-maps");
2644
- ?>
2645
- <a href='https://mappity.org'>https://mappity.org</a>
2646
- |
2647
- <?php
2648
- _e('Translating the plugin with', 'wp-google-maps'); ?>
2649
- <a href='https://www.wpgmaps.com/documentation/translating-the-plugin-with-wpml/' target='_BLANK'><?php esc_html_e('WPML', 'wp-google-maps'); ?></a>
2650
- </small>
2651
- </p>
2652
-
2653
-
2654
  </div>
1
+ <div id="wpgmza-map-edit-page" class='wrap'>
2
+ <h1 id="wpgmza-main-heading">
3
+ <?php
4
+ _e('WP Google Maps', 'wp-google-maps');
5
+ ?>
6
+ <span id="wpgmza-title-label" class="wpgmza-label-amber"><small></small></span>
7
+ </h1>
8
+
9
+ <div class="wide">
10
+ <h2>
11
+ <?php
12
+ _e('Create your Map', 'wp-google-maps');
13
+ ?>
14
+
15
+ <a href="admin.php?page=wp-google-maps-menu&amp;action=new"
16
+ class="add-new-h2 add-new-editor">
17
+ <?php
18
+ _e("New","wp-google-maps");
19
+ ?>
20
+ </a>
21
+
22
+ <div class='update-nag update-blue update-slim' id='wpmgza_unsave_notice' style='display:none;'>
23
+ <?php
24
+ _e('Unsaved data will be lost', 'wp-google-maps');
25
+ ?>
26
+ </div>
27
+ </h2>
28
+
29
+ <div id="wpgmza-gdpr-privacy-policy-notice"></div>
30
+
31
+ <form action="" method="POST" id="wpgmaps_options" name="wpgmza_map_form">
32
+
33
+ <input name="action" type="hidden" value="wpgmza_save_map"/>
34
+ <input name="redirect_to" type="hidden"/>
35
+ <input name="map_id" type="hidden"/>
36
+ <input name="real_post_nonce" type="hidden"/>
37
+
38
+ <!-- NB: Is name attribute valid on a form? Check spec please -->
39
+
40
+ <div id="wpgmaps_tabs">
41
+ <ul>
42
+ <li>
43
+ <a href="#general-settings">
44
+ <?php
45
+ _e('General Settings', 'wp-google-maps');
46
+ ?>
47
+ </a>
48
+ </li>
49
+ <li>
50
+ <a href="#themes">
51
+ <?php
52
+ _e('Themes', 'wp-google-maps');
53
+ ?>
54
+ </a>
55
+ </li>
56
+ <li>
57
+ <a href="#directions">
58
+ <?php
59
+ _e('Directions', 'wp-google-maps');
60
+ ?>
61
+ </a>
62
+ </li>
63
+ <li>
64
+ <a href="#store-locator">
65
+ <?php
66
+ _e('Store Locator', 'wp-google-maps');
67
+ ?>
68
+ </a>
69
+ </li>
70
+ <li>
71
+ <a href="#advanced-settings">
72
+ <?php
73
+ _e('Advanced Settings', 'wp-google-maps');
74
+ ?>
75
+ </a>
76
+ </li>
77
+ <li>
78
+ <a href="#marker-listing">
79
+ <?php
80
+ _e('Marker Listing', 'wp-google-maps');
81
+ ?>
82
+ </a>
83
+ </li>
84
+ <li>
85
+ <a href="#marker-filtering">
86
+ <?php
87
+ _e('Marker Filtering', 'wp-google-maps');
88
+ ?>
89
+ </a>
90
+ </li>
91
+ <li class="wpgmza-upgrade-tab wpgmza-upsell">
92
+ <a href="#pro-upgrade">
93
+ <?php
94
+ _e('Pro Upgrade', 'wp-google-maps');
95
+ ?>
96
+ </a>
97
+ </li>
98
+ </ul>
99
+
100
+ <div id="general-settings">
101
+ <h3>
102
+ <?php
103
+ _e('Map Settings', 'wp-google-maps');
104
+ ?>
105
+ </h3>
106
+
107
+ <input type='hidden' name='http_referer'/>
108
+ <input type='hidden' name='wpgmza_id' id='wpgmza_id'/>
109
+
110
+ <!-- NB: Populate dynamically -->
111
+ <input type='hidden' name='map_start_lat'/>
112
+ <input type='hidden' name='map_start_lng'/>
113
+ <input type='hidden' name='wpgmza_start_location' id='wpgmza_start_location'/>
114
+
115
+ <select id='wpgmza_start_zoom' name='wpgmza_start_zoom' style='display: none;'>
116
+ <option value="1">1</option>
117
+ <option value="2">2</option>
118
+ <option value="3">3</option>
119
+ <option value="4" selected>4</option>
120
+ <option value="5">5</option>
121
+ <option value="6">6</option>
122
+ <option value="7">7</option>
123
+ <option value="8">8</option>
124
+ <option value="9">9</option>
125
+ <option value="10">10</option>
126
+ <option value="11">11</option>
127
+ <option value="12">12</option>
128
+ <option value="13">13</option>
129
+ <option value="14">14</option>
130
+ <option value="15">15</option>
131
+ <option value="16">16</option>
132
+ <option value="17">17</option>
133
+ <option value="18">18</option>
134
+ <option value="19">19</option>
135
+ <option value="20">20</option>
136
+ <option value="21">21</option>
137
+ </select>
138
+
139
+ <!-- NB: Adapted from old table based layout -->
140
+ <fieldset>
141
+ <legend>
142
+ <?php
143
+ _e("Short code","wp-google-maps");
144
+ ?>
145
+ </legend>
146
+
147
+ <input type="text" readonly name="shortcode" class="wpgmza_copy_shortcode"/>
148
+
149
+ <small class='wpgmza-info__small'>
150
+ <i>
151
+
152
+ <?php
153
+ _e("copy this into your post or page to display the map", "wp-google-maps");
154
+
155
+ // NB: I recommend adding a unique ID or class to this link and using the DOM to set the href rather than mixing content with logic here. - Perry
156
+ echo ". ".__(sprintf("Or <a href='%s' target='BLANK'>click here to automatically create a Map Page now</a>.","admin.php?page=wp-google-maps-menu&amp;action=create-map-page&amp;map_id=".intval($_REQUEST['map_id'])),"wp-google-maps");
157
+
158
+ ?>
159
+ </i>
160
+ </small>
161
+ </fieldset>
162
+
163
+ <fieldset>
164
+ <legend>
165
+ <?php
166
+ _e("Map Name", "wp-google-maps");
167
+ ?>
168
+ </legend>
169
+
170
+ <input id='wpgmza_title' name='map_title' class='regular-text' type='text'/>
171
+ </fieldset>
172
+
173
+ <fieldset>
174
+ <legend>
175
+ <?php
176
+ _e("Zoom Level", "wp-google-maps");
177
+ ?>
178
+ </legend>
179
+
180
+ <input type="text" id="amount" class='map_start_zoom' style="display: none;" name="map_start_zoom"/>
181
+
182
+ <div id="slider-range-max"></div>
183
+ </fieldset>
184
+
185
+ <fieldset>
186
+ <legend>
187
+ <?php
188
+ _e("Width", "wp-google-maps");
189
+ ?>
190
+ </legend>
191
+
192
+ <input id="wpgmza_width" name="map_width" type="number" value="100"/>
193
+
194
+ <select id='wpgmza_map_width_type' name='map_width_type'>
195
+ <option value="px">px</option>
196
+ <option value="%" selected="selected">%</option>
197
+ </select>
198
+
199
+ <small>
200
+ <em>
201
+ <?php
202
+ _e("Set to 100% for a responsive map", "wp-google-maps");
203
+ ?>
204
+ </em>
205
+ </small>
206
+ </fieldset>
207
+
208
+ <fieldset>
209
+ <legend>
210
+ <?php
211
+ _e("Height", "wp-google-maps");
212
+ ?>
213
+ </legend>
214
+
215
+ <input id='wpgmza_height' name='map_height' type='number'/>
216
+
217
+ <select id='wpgmza_map_height_type' name='map_height_type'>
218
+ <option value="px">px</option>
219
+ <option value="%">%</option>
220
+ </select>
221
+
222
+ <span style='display:none;' id='wpgmza_height_warning'>
223
+ <small>
224
+ <?php
225
+ _e("We recommend that you leave your height in PX. Depending on your theme, using % for the height may break your map.", "wp-google-maps");
226
+ ?>
227
+ </small>
228
+ </span>
229
+ </fieldset>
230
+ </div>
231
+
232
+ <div id="themes" class="wpgmza-open-layers-feature-unavailable wpgmza-theme-panel">
233
+
234
+ <span class='notice notice-warning' data-wpgmza-require-engine="open-layers">
235
+ <?php
236
+ _e("Not available while using the OpenLayers engine.", "wp-google-maps");
237
+ ?>
238
+ </span>
239
+
240
+ </div>
241
+
242
+ <div id="directions" class="wpgmza-directions-box-settings-panel">
243
+
244
+ <div class="update-nag update-att wpgmza-upsell">
245
+
246
+ <i class="fa fa-arrow-circle-right"></i>
247
+
248
+ <?php
249
+ _e('<a target="_BLANK" href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=directions">
250
+ Enable directions</a> with the Pro version for only $39.99 once off. Support and updates included forever', 'wp-google-maps');
251
+ ?>
252
+
253
+ </div>
254
+
255
+ <table class='form-table wpgmza-pro-feature' id='wpgmaps_directions_options'>
256
+ <tr>
257
+ <td width='200px'><?php _e("Enable Directions?","wp-google-maps"); ?>:</td>
258
+ <td>
259
+ <div class='switch'>
260
+ <input type='checkbox' class='cmn-toggle cmn-toggle-yes-no wpgmza-pro-feature'> <label class='cmn-override-big' data-on='<?php _e("No","wp-google-maps"); ?>' data-off='<?php _e("No","wp-google-maps"); ?>'></label>
261
+ </div>
262
+ </td>
263
+ </tr>
264
+ <tr>
265
+ <td>
266
+ <?php _e("Directions Box Open by Default?","wp-google-maps"); ?>:
267
+ </td>
268
+ <td>
269
+ <select class='postform wpgmza-pro-feature'>
270
+ <option><?php _e("No","wp-google-maps"); ?></option>
271
+ <option><?php _e("Yes, on the left","wp-google-maps"); ?></option>
272
+ <option><?php _e("Yes, on the right","wp-google-maps"); ?></option>
273
+ <option><?php _e("Yes, above","wp-google-maps"); ?></option>
274
+ <option><?php _e("Yes, below","wp-google-maps"); ?></option>
275
+ </select>
276
+ </td>
277
+ </tr>
278
+ <tr>
279
+ <td>
280
+ <?php _e("Directions Box Width","wp-google-maps"); ?>:
281
+ </td>
282
+ <td>
283
+ <input type='text' size='4' maxlength='4' class='small-text wpgmza-pro-feature' /> px
284
+ </td>
285
+ </tr>
286
+
287
+ </table>
288
+
289
+ </div>
290
+
291
+ <div id="store-locator">
292
+
293
+ <!-- TODO: Use progressive enhancement here -->
294
+
295
+ <fieldset>
296
+ <legend>
297
+ <?php
298
+ _e("Enable Store Locator", "wp-google-maps");
299
+ ?>
300
+ </legend>
301
+
302
+ <input type='checkbox'
303
+ id='store_locator_enabled'
304
+ name='store_locator_enabled'
305
+ class='postform cmn-toggle cmn-toggle-yes-no'/>
306
+ <label class='cmn-override-big-wide'
307
+ for='store_locator_enabled'
308
+ data-on='<?php esc_attr_e("Yes", "wp-google-maps"); ?>'
309
+ data-off='<?php esc_attr_e("No", "wp-google-maps"); ?>'>
310
+ </label>
311
+
312
+ </fieldset>
313
+
314
+ <fieldset data-require-legacy-user-interface-style="true">
315
+ <legend>
316
+ <?php
317
+ _e("Store Locator Style", "wp-google-maps");
318
+ ?>
319
+ </legend>
320
+
321
+ <ul>
322
+ <li>
323
+ <label>
324
+ <input type='radio'
325
+ name='store_locator_style'
326
+ value='legacy'
327
+ />
328
+
329
+ <?php
330
+ _e("Legacy", "wp-google-maps");
331
+ ?>
332
+ </label>
333
+ </li>
334
+ <li>
335
+ <label>
336
+ <input type='radio'
337
+ name='store_locator_style'
338
+ value='modern'
339
+ />
340
+
341
+ <?php
342
+ _e("Modern", "wp-google-maps");
343
+ ?>
344
+ </label>
345
+ </li>
346
+ </ul>
347
+ </fieldset>
348
+
349
+ <fieldset data-require-legacy-user-interface-style="false">
350
+ <legend>
351
+ <?php
352
+ _e("Store Locator Style", "wp-google-maps");
353
+ ?>
354
+ </legend>
355
+
356
+ <label class="notice notice-info">
357
+ <?php
358
+ echo sprintf(
359
+ __("Looking for styling settings? Try our new <a href='%s' target='_blank'>User Interface Style</a> setting.", "wp-google-maps"),
360
+ admin_url('admin.php?page=wp-google-maps-menu-settings')
361
+ );
362
+ ?>
363
+ </label>
364
+
365
+ </fieldset>
366
+
367
+ <fieldset class="wpgmza-pro-feature">
368
+ <legend>
369
+ <?php
370
+ _e("Search Area", "wp-google-maps");
371
+ ?>
372
+ </legend>
373
+
374
+ <ul>
375
+ <li>
376
+ <label>
377
+ <input type='radio'
378
+ name='store_locator_search_area'
379
+ value='radial'
380
+ checked='checked'
381
+ class="wpgmza-pro-feature"
382
+ />
383
+
384
+ <?php
385
+ _e("Radial", "wp-google-maps");
386
+ ?>
387
+ </label>
388
+
389
+ <p>
390
+ <small>
391
+ <?php
392
+ _e("Allows the user to select a radius from a predefined list", "wp-google-maps");
393
+ ?>
394
+ </small>
395
+ </p>
396
+ </li>
397
+ <li>
398
+ <label>
399
+ <input type='radio'
400
+ name='store_locator_search_area'
401
+ value='auto'
402
+ class="wpgmza-pro-feature"
403
+ />
404
+
405
+ <?php
406
+ _e("Auto", "wp-google-maps");
407
+ ?>
408
+ </label>
409
+
410
+ <p>
411
+ <small>
412
+ <?php
413
+ _e("Intelligently detects the zoom level based on the location entered", "wp-google-maps");
414
+ ?>
415
+ </small>
416
+ </p>
417
+
418
+ <p class="wpgmza-pro-feature-hide" data-search-area="auto">
419
+ <small>
420
+ <?php
421
+ _e("Marker listings will not be filtered based on visible markers. Enable the 'Only load markers within viewport (beta)' option for beta filtering support", "wp-google-maps");
422
+ ?>
423
+ </small>
424
+ </p>
425
+ </li>
426
+ <ul>
427
+ </fieldset>
428
+
429
+ <div class="wpgmza-upsell">
430
+ <i class="fa fa-arrow-circle-right"></i>
431
+ <?php
432
+ _e('Enable intelligent, automatic search area with our <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=store-locator">Pro add-on</a>', 'wp-google-maps');
433
+ ?>
434
+ </div>
435
+
436
+ <fieldset data-search-area="radial">
437
+ <legend>
438
+ <?php
439
+ _e("Radius Style", "wp-google-maps");
440
+ ?>
441
+ </legend>
442
+ <ul>
443
+ <li>
444
+ <label>
445
+ <input type='radio'
446
+ name='wpgmza_store_locator_radius_style'
447
+ value='legacy'
448
+ checked='checked'
449
+ />
450
+
451
+ <?php
452
+ _e("Legacy", "wp-google-maps");
453
+ ?>
454
+ </label>
455
+ </li>
456
+ <li>
457
+ <label>
458
+ <input type='radio'
459
+ name='wpgmza_store_locator_radius_style'
460
+ value='modern'/>
461
+
462
+ <?php
463
+ _e("Modern", "wp-google-maps");
464
+ ?>
465
+ </label>
466
+ </li>
467
+ </ul>
468
+ </fieldset>
469
+
470
+ <fieldset data-search-area="radial">
471
+ <legend>
472
+ <?php
473
+ _e("Default radius", "wp-google-maps");
474
+ ?>
475
+ </legend>
476
+
477
+ <select name='wpgmza_store_locator_default_radius' class='wpgmza-store-locator-default-radius'></select>
478
+ </fieldset>
479
+
480
+ <fieldset data-search-area="auto">
481
+ <legend>
482
+ <?php
483
+ _e("Maximum zoom", "wp-google-maps");
484
+ ?>
485
+ </legend>
486
+
487
+ <input name='store_locator_auto_area_max_zoom'
488
+ type='number'
489
+ min='1'
490
+ max='21'/>
491
+ </fieldset>
492
+
493
+ <fieldset id="wpgmza-store-locator-country-restriction-container" class="wpgmza-pro-feature">
494
+ <legend>
495
+ <?php
496
+ _e("Restrict to country", "wp-google-maps");
497
+ ?>
498
+ </legend>
499
+ </fieldset>
500
+
501
+ <fieldset>
502
+ <legend>
503
+ <?php
504
+ _e("Show distance in", "wp-google-maps");
505
+ ?>
506
+ </legend>
507
+
508
+ <input type='checkbox'
509
+ id='store_locator_distance'
510
+ name='store_locator_distance'
511
+ class='postform cmn-toggle cmn-toggle-yes-no'/>
512
+ <label class='cmn-override-big-wide'
513
+ for='store_locator_distance'
514
+ data-on='<?php esc_attr_e("Miles", "wp-google-maps"); ?>'
515
+ data-off='<?php esc_attr_e("Kilometers", "wp-google-maps"); ?>'>
516
+ </label>
517
+ </fieldset>
518
+
519
+ <fieldset>
520
+ <legend>
521
+ <?php
522
+ _e("Store Locator Placement", "wp-google-maps");
523
+ ?>
524
+ </legend>
525
+
526
+ <div class='switch'>
527
+ <input type='checkbox'
528
+ id='wpgmza_store_locator_position'
529
+ name='wpgmza_store_locator_position'
530
+ class='postform cmn-toggle cmn-toggle-yes-no'/>
531
+ <label class='cmn-override-big-wide'
532
+ for='wpgmza_store_locator_position'
533
+ data-on='<?php esc_attr_e("Below Map", "wp-google-maps"); ?>'
534
+ data-off='<?php esc_attr_e("Above Map","wp-google-maps"); ?>'>
535
+ </label>
536
+ </div>
537
+ </fieldset>
538
+
539
+ <fieldset>
540
+ <legend>
541
+ <?php
542
+ _e("Show distance from search", "wp-google-maps");
543
+ ?>
544
+ </legend>
545
+ <div class='switch'>
546
+ <input type='checkbox'
547
+ id='store_locator_show_distance'
548
+ name='store_locator_show_distance'
549
+ class='postform cmn-toggle cmn-toggle-round-flat'
550
+ />
551
+ <label for='store_locator_show_distance'></label>
552
+ </div>
553
+ </fieldset>
554
+
555
+ <fieldset class="wpgmza-pro-feature">
556
+ <legend>
557
+ <?php
558
+ _e("Allow category selection", "wp-google-maps");
559
+ ?>
560
+ </legend>
561
+ <div class='switch'>
562
+ <input type='checkbox'
563
+ id='wpgmza_store_locator_category_enabled'
564
+ name='store_locator_category'
565
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'
566
+ />
567
+ <label for='wpgmza_store_locator_category_enabled'></label>
568
+ </div>
569
+ </fieldset>
570
+
571
+ <div class="wpgmza-upsell">
572
+ <i class="fa fa-arrow-circle-right"></i>
573
+ <?php
574
+ _e('Enable search by category with our <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=store-locator">Pro add-on</a>', 'wp-google-maps');
575
+ ?>
576
+ </div>
577
+
578
+ <fieldset class="wpgmza-pro-feature">
579
+ <legend>
580
+ <?php
581
+ _e("Allow users to use their location as the starting point", "wp-google-maps");
582
+ ?>
583
+ </legend>
584
+
585
+ <div class='switch'>
586
+ <input type='checkbox'
587
+ id='wpgmza_store_locator_use_their_location'
588
+ name='wpgmza_store_locator_use_their_location'
589
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'>
590
+ <label for='wpgmza_store_locator_use_their_location'></label>
591
+ </div>
592
+ </fieldset>
593
+
594
+ <div class="wpgmza-upsell">
595
+ <i class="fa fa-arrow-circle-right"></i>
596
+ <?php
597
+ _e('Enable user geolocation features with our <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=store-locator">Pro add-on</a>', 'wp-google-maps');
598
+ ?>
599
+ </div>
600
+
601
+ <fieldset class="wpgmza-pro-feature">
602
+ <legend>
603
+ <?php
604
+ _e("Show center point as an icon", "wp-google-maps");
605
+ ?>
606
+ </legend>
607
+
608
+ <div class='switch'>
609
+ <input type='checkbox'
610
+ id='wpgmza_store_locator_bounce'
611
+ name='wpgmza_store_locator_bounce'
612
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'>
613
+ <label for='wpgmza_store_locator_bounce'></label>
614
+ </div>
615
+ </fieldset>
616
+
617
+ <fieldset id="wpgmza_store_locator_bounce_conditional"
618
+ style="display: none;"
619
+ class="wpgmza-store-locator-marker-icon-picker-container wpgmza-pro-feature">
620
+ <legend>
621
+ <?php
622
+ _e("Default Icon", "wp-google-maps");
623
+ ?>
624
+ </legend>
625
+ </fieldset>
626
+
627
+ <fieldset class="wpgmza-pro-feature">
628
+ <legend>
629
+ <?php
630
+ _e("Marker animation", "wp-google-maps");
631
+ ?>
632
+ </legend>
633
+
634
+ <select name="wpgmza_sl_animation" id="wpgmza_sl_animation" class="wpgmza-pro-feature">
635
+ <option value="0">
636
+ <?php
637
+ _e("None", "wp-google-maps");
638
+ ?>
639
+ </option>
640
+ <option value="1">
641
+ <?php
642
+ _e("Bounce", "wp-google-maps");
643
+ ?>
644
+ </option>
645
+ <option value="2">
646
+ <?php
647
+ _e("Drop", "wp-google-maps");
648
+ ?>
649
+ </option>
650
+ </select>
651
+ </fieldset>
652
+
653
+ <fieldset class="wpgmza-pro-feature">
654
+ <legend>
655
+ <?php
656
+ _e("Hide all markers until a search is done", "wp-google-maps");
657
+ ?>
658
+ </legend>
659
+
660
+ <div class='switch'>
661
+ <input type='checkbox'
662
+ id='wpgmza_store_locator_hide_before_search'
663
+ name='wpgmza_store_locator_hide_before_search'
664
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'>
665
+ <label for='wpgmza_store_locator_hide_before_search'></label>
666
+ </div>
667
+ </fieldset>
668
+
669
+ <fieldset class="wpgmza-pro-feature">
670
+ <legend>
671
+ <?php
672
+ _e("Query String", "wp-google-maps");
673
+ ?>
674
+ </legend>
675
+
676
+ <input type="text" name="store_locator_query_string" id="wpgmza_store_locator_query_string" class="wpgmza-pro-feature"/>
677
+ </fieldset>
678
+
679
+ <fieldset class="wpgmza-pro-feature">
680
+ <legend>
681
+ <?php
682
+ _e("Default address", "wp-google-maps");
683
+ ?>
684
+ </legend>
685
+
686
+ <input type="text"
687
+ name="store_locator_default_address"
688
+ id="wpgmza_store_locator_default_address"
689
+ class="wpgmza-address wpgmza-pro-feature"
690
+ />
691
+ </fieldset>
692
+
693
+ <fieldset class="wpgmza-pro-feature">
694
+ <legend>
695
+ <?php
696
+ _e("Enable title search", "wp-google-maps");
697
+ ?>
698
+ </legend>
699
+
700
+ <div class='switch'>
701
+ <input type='checkbox'
702
+ id='wpgmza_store_locator_name_search'
703
+ name='store_locator_name_search'
704
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'>
705
+ <label for='wpgmza_store_locator_name_search'></label>
706
+ </div>
707
+ </fieldset>
708
+
709
+ <fieldset class="wpgmza-pro-feature">
710
+ <legend>
711
+ <?php
712
+ _e("Title search String", "wp-google-maps");
713
+ ?>
714
+ </legend>
715
+
716
+ <input type="text"
717
+ name="store_locator_name_string"
718
+ id="wpgmza_store_locator_name_string"
719
+ class="wpgmza-pro-feature"/>
720
+ </fieldset>
721
+
722
+ <fieldset class="wpgmza-pro-feature">
723
+ <legend>
724
+ <?php
725
+ _e( "Not found message", "wp-google-maps");
726
+ ?>
727
+ </legend>
728
+
729
+ <input type="text"
730
+ name="store_locator_not_found_message"
731
+ id="wpgmza_store_locator_not_found_message"
732
+ class="wpgmza-pro-feature"/>
733
+ </fieldset>
734
+
735
+ <h3>
736
+ <?php
737
+ _e("Style options", "wp-google-maps");
738
+ ?>
739
+ </h3>
740
+
741
+ <fieldset class="wpgmza-pro-feature">
742
+ <legend>
743
+ <?php
744
+ _e("Line color", "wp-google-maps");
745
+ ?>
746
+ </legend>
747
+ <input id="sl_stroke_color"
748
+ name="sl_stroke_color"
749
+ type="color"
750
+ class="color wpgmza-pro-feature"/>
751
+ </fieldset>
752
+
753
+ <fieldset class="wpgmza_legacy_sl_style_option_area wpgmza-pro-feature">
754
+ <legend>
755
+ <?php
756
+ _e("Line opacity", "wp-google-maps");
757
+ ?>
758
+ </legend>
759
+
760
+ <input id="sl_stroke_opacity"
761
+ name="sl_stroke_opacity"
762
+ type="number"
763
+ min="0"
764
+ max="1"
765
+ step="0.01"
766
+ class="wpgmza-pro-feature"/>
767
+
768
+ <small>
769
+ <?php
770
+ _e("(0 - 1.0) example: 0.5 for 50%", "wp-google-maps");
771
+ ?>
772
+ </small>
773
+ </fieldset>
774
+
775
+ <fieldset class="wpgmza_legacy_sl_style_option_area wpgmza-pro-feature">
776
+ <legend>
777
+ <?php
778
+ _e("Fill color", "wp-google-maps");
779
+ ?>
780
+ </legend>
781
+
782
+ <input id="sl_fill_color"
783
+ name="sl_fill_color"
784
+ type="color"
785
+ class="color wpgmza-pro-feature"/>
786
+ </fieldset>
787
+
788
+ <fieldset class="wpgmza_legacy_sl_style_option_area wpgmza-pro-feature">
789
+ <legend>
790
+ <?php
791
+ _e("Fill opacity", "wp-google-maps");
792
+ ?>
793
+ </legend>
794
+
795
+ <input id="sl_fill_opacity"
796
+ name="sl_fill_opacity"
797
+ type="number"
798
+ min="0"
799
+ max="1"
800
+ step="0.01"
801
+ class="wpgmza-pro-feature"/>
802
+ </fieldset>
803
+
804
+ <div class="wpgmza-upsell">
805
+ <i class="fa fa-arrow-circle-right"></i>
806
+ <?php
807
+ _e('Enable custom styling options with our <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=store-locator">Pro add-on</a>', 'wp-google-maps');
808
+ ?>
809
+ </div>
810
+
811
+ <p>
812
+ <em>
813
+ <?php
814
+ _e('View', 'wp-google-maps');
815
+ ?>
816
+ <a href='http://wpgmaps.com/documentation/store-locator' target='_BLANK'>
817
+ <?php
818
+ _e('Store Locator Documentation', 'wp-google-maps');
819
+ ?>
820
+ </a>
821
+ </em>
822
+ </p>
823
+ </div>
824
+
825
+ <div id="advanced-settings">
826
+ <h3>
827
+ <?php
828
+ _e("Advanced Settings:", "wp-google-maps")
829
+ ?>
830
+ </h3>
831
+
832
+ <fieldset id="advanced-settings-marker-icon-picker-container">
833
+ <legend>
834
+ <?php
835
+ _e("Default Marker Image", "wp-google-maps");
836
+ ?>
837
+ </legend>
838
+
839
+ <div class="wpgmza-upsell">
840
+ <i class="fa fa-arrow-circle-right"></i>
841
+ <?php
842
+ _e('Enable custom marker icons with our <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=advanced">Pro add-on</a>', 'wp-google-maps');
843
+ ?>
844
+ </div>
845
+ </fieldset>
846
+
847
+ <fieldset data-wpgmza-require-engine="google-maps">
848
+ <legend>
849
+ <?php
850
+ _e("Map type", "wp-google-maps");
851
+ ?>
852
+ </legend>
853
+
854
+ <select id="wpgmza_map_type" name="type">
855
+ <option value="1">
856
+ <?php
857
+ _e("Roadmap", "wp-google-maps");
858
+ ?>
859
+ </option>
860
+ <option value="2">
861
+ <?php
862
+ _e("Satellite", "wp-google-maps");
863
+ ?>
864
+ </option>
865
+ <option value="3">
866
+ <?php
867
+ _e("Hybrid", "wp-google-maps");
868
+ ?>
869
+ </option>
870
+ <option value="4">
871
+ <?php
872
+ _e("Terrain", "wp-google-maps");
873
+ ?>
874
+ </option>
875
+ </select>
876
+
877
+ <div class='wpgmza-open-layers-feature-unavailable'></div>
878
+ </fieldset>
879
+
880
+ <fieldset>
881
+ <legend>
882
+ <?php
883
+ _e("Map Alignment", "wp-google-maps");
884
+ ?>
885
+ </legend>
886
+
887
+ <select id="wpgmza_map_align"
888
+ name="wpgmza_map_align"
889
+ class="postform">
890
+ <option value="1">
891
+ <?php
892
+ _e('Left', 'wp-google-maps');
893
+ ?>
894
+ </option>
895
+ <option value="2">
896
+ <?php
897
+ _e('Center', 'wp-google-maps');
898
+ ?>
899
+ </option>
900
+ <option value="3">
901
+ <?php
902
+ _e('Right', 'wp-google-maps');
903
+ ?>
904
+ </option>
905
+ <option value="4">
906
+ <?php
907
+ _e('None', 'wp-google-maps');
908
+ ?>
909
+ </option>
910
+ </select>
911
+ </fieldset>
912
+
913
+ <fieldset class="wpgmza-pro-feature">
914
+ <legend>
915
+ <?php
916
+ _e("Show User's Location?", "wp-google-maps");
917
+ ?>
918
+ </legend>
919
+
920
+ <div class='switch wpgmza-geolocation-setting'>
921
+ <input
922
+ type='checkbox'
923
+ id='wpgmza_show_user_location'
924
+ name='show_user_location'
925
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
926
+ <label for='wpgmza_show_user_location'></label>
927
+ </div>
928
+ </fieldset>
929
+
930
+ <div class="wpgmza-upsell">
931
+ <i class="fa fa-arrow-circle-right"></i>
932
+ <?php
933
+ _e('Enable user geolocation features with our <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=advanced">Pro add-on</a>', 'wp-google-maps');
934
+ ?>
935
+ </div>
936
+
937
+ <fieldset class="wpgmza-user-location-marker-icon-picker-container wpgmza-pro-feature" id="wpgmza_show_user_location_conditional" style="display: none;">
938
+ <legend>
939
+ <?php
940
+ _e("Default User Location Icon", "wp-google-maps");
941
+ ?>
942
+ </legend>
943
+ </fieldset>
944
+
945
+ <fieldset class="wpgmza-pro-feature">
946
+ <legend>
947
+ <?php
948
+ _e("Jump to nearest marker on initialization?", "wp-google-maps");
949
+ ?>
950
+ </legend>
951
+
952
+ <div class='switch wpgmza-geolocation-setting'>
953
+ <input
954
+ type='checkbox'
955
+ id='wpgmza_jump_to_nearest_marker_on_initialization'
956
+ name='jump_to_nearest_marker_on_initialization'
957
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
958
+ <label for='wpgmza_jump_to_nearest_marker_on_initialization'></label>
959
+ </div>
960
+ </fieldset>
961
+
962
+ <fieldset class="wpgmza-pro-feature">
963
+ <legend>
964
+ <?php
965
+ _e("Automatically pan to users location?", "wp-google-maps");
966
+ ?>
967
+ </legend>
968
+
969
+ <div class='switch wpgmza-geolocation-setting'>
970
+ <input type='checkbox'
971
+ id='wpgmza_automatically_pan_to_users_location'
972
+ name='automatically_pan_to_users_location'
973
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
974
+ <label for="wpgmza_automatically_pan_to_users_location"></label>
975
+ </div>
976
+ </fieldset>
977
+
978
+ <fieldset class="wpgmza-pro-feature">
979
+ <legend>
980
+ <?php
981
+ _e("Override User Location Zoom Level", "wp-google-maps");
982
+ ?>
983
+ </legend>
984
+
985
+ <div class='switch wpgmza-geolocation-setting'>
986
+ <input type='checkbox'
987
+ id='wpgmza_override_users_location_zoom_level'
988
+ name='override_users_location_zoom_level'
989
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
990
+ <label for="wpgmza_override_users_location_zoom_level"></label>
991
+ </div>
992
+ </fieldset>
993
+
994
+ <fieldset
995
+ class="wpgmza-override-users-location-zoom-levels wpgmza-no-flex"
996
+ id="wpgmza_override_users_location_zoom_levels_slider"
997
+ style="display: none;">
998
+ <legend>
999
+ <?php
1000
+ _e("Zoom Level", "wp-google-maps");
1001
+ ?>
1002
+ </legend>
1003
+
1004
+ <input name="override_users_location_zoom_levels" style="display: none;" type="text" id="override_users_location_zoom_levels_slider">
1005
+
1006
+ <div id="override-users-location-zoom-levels-slider"></div>
1007
+ </fieldset>
1008
+
1009
+ <fieldset class="wpgmza-pro-feature">
1010
+ <legend>
1011
+ <?php
1012
+ _e("Show distance from location?", "wp-google-maps");
1013
+ ?>
1014
+ </legend>
1015
+
1016
+ <div class='switch wpgmza-geolocation-setting'>
1017
+ <input type='checkbox'
1018
+ id='wpgmza_show_distance_from_location'
1019
+ name='show_distance_from_location'
1020
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'
1021
+ value='1'/>
1022
+
1023
+ <label
1024
+ for='wpgmza_show_distance_from_location'
1025
+ data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1026
+ data-off='<?php _e("No", "wp-google-maps"); ?>'>
1027
+ </label>
1028
+ </div>
1029
+ <!--<small>
1030
+ <em>
1031
+ <?php
1032
+ _e("This feature will use the users location (where available) or the searched address when a store locator search is performed.","wp-google-maps");
1033
+ ?>
1034
+ </em>
1035
+ </small>-->
1036
+ </fieldset>
1037
+
1038
+
1039
+ <fieldset>
1040
+ <legend>
1041
+ <?php
1042
+ _e("Maximum Zoom Out Level", "wp-google-maps");
1043
+ ?>
1044
+ </legend>
1045
+
1046
+ <input id='wpgmza_max_zoom'
1047
+ name='map_max_zoom'
1048
+ min="0"
1049
+ max="21"
1050
+ step="1"
1051
+ value="21"
1052
+ type="number"/>
1053
+ </fieldset>
1054
+
1055
+ <fieldset>
1056
+ <legend>
1057
+ <?php
1058
+ _e("Maximum Zoom In Level", "wp-google-maps");
1059
+ ?>
1060
+ </legend>
1061
+
1062
+ <input id='wpgmza_min_zoom'
1063
+ name='map_min_zoom'
1064
+ min="0"
1065
+ max="21"
1066
+ step="1"
1067
+ value="0"
1068
+ type="number"/>
1069
+ </fieldset>
1070
+
1071
+ <div class="wpgmza-upsell">
1072
+
1073
+ <i class="fa fa-arrow-circle-right"> </i>
1074
+ <?php
1075
+ echo sprintf(
1076
+ __(
1077
+ 'Get the rest of these advanced features with the Pro version for only <a href="%s" target="_BLANK">$39.99 once off</a>. Support and updates included forever.',
1078
+ "wp-google-maps"
1079
+ ),
1080
+ "https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=advanced"
1081
+ );
1082
+ ?>
1083
+
1084
+ </div>
1085
+
1086
+ <fieldset class="wpgmza-pro-feature">
1087
+ <legend>
1088
+ <?php
1089
+ _e("Click marker opens link", "wp-google-maps");
1090
+ ?>
1091
+ </legend>
1092
+
1093
+ <div class='switch'>
1094
+ <input type='checkbox'
1095
+ id='wpgmza_click_open_link'
1096
+ name='click_open_link'
1097
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
1098
+ <label for='wpgmza_click_open_link'
1099
+ data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1100
+ data-off='<?php _e("No", "wp-google-maps"); ?>'>
1101
+ </label>
1102
+ </div>
1103
+ </fieldset>
1104
+
1105
+ <fieldset class="wpgmza-pro-feature">
1106
+ <legend>
1107
+ <?php
1108
+ _e("Fit map bounds to markers?", "wp-google-maps");
1109
+ ?>
1110
+ </legend>
1111
+
1112
+ <div class='switch'>
1113
+ <input type='checkbox'
1114
+ id='wpgmza_fit_maps_bounds_to_markers'
1115
+ name='fit_maps_bounds_to_markers'
1116
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
1117
+ <label for='wpgmza_fit_maps_bounds_to_markers'
1118
+ data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1119
+ data-off='<?php _e("No", "wp-google-maps"); ?>'>
1120
+ </label>
1121
+ </div>
1122
+ </fieldset>
1123
+
1124
+ <fieldset class="wpgmza-pro-feature">
1125
+ <legend>
1126
+ <?php
1127
+ _e("Fit map bounds to markers after filtering?", "wp-google-maps");
1128
+ ?>
1129
+ </legend>
1130
+
1131
+ <div class='switch'>
1132
+ <input type='checkbox'
1133
+ id='wpgmza_fit_maps_bounds_to_markers_after_filtering'
1134
+ name='fit_maps_bounds_to_markers_after_filtering'
1135
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
1136
+ <label for='wpgmza_fit_maps_bounds_to_markers_after_filtering'
1137
+ data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1138
+ data-off='<?php _e("No", "wp-google-maps"); ?>'>
1139
+ </label>
1140
+ </div>
1141
+ </fieldset>
1142
+
1143
+ <fieldset>
1144
+ <legend>
1145
+ <?php
1146
+ _e("Hide point of interest", "wp-google-maps");
1147
+ ?>
1148
+ </legend>
1149
+
1150
+ <div class='switch'>
1151
+ <input type='checkbox'
1152
+ id='wpgmza_hide_point_of_interest'
1153
+ name='hide_point_of_interest'
1154
+ class='postform cmn-toggle cmn-toggle-round-flat'/>
1155
+ <label for='wpgmza_hide_point_of_interest'
1156
+ data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1157
+ data-off='<?php _e("No", "wp-google-maps"); ?>'>
1158
+ </label>
1159
+ </div>
1160
+ </fieldset>
1161
+
1162
+
1163
+ <fieldset class="wpgmza-pro-feature">
1164
+ <legend>
1165
+ <?php
1166
+ _e("Zoom on marker click", "wp-google-maps");
1167
+ ?>
1168
+ </legend>
1169
+
1170
+ <div>
1171
+ <div class='switch'>
1172
+ <input type='checkbox'
1173
+ id='wpgmza_zoom_on_marker_click'
1174
+ name='wpgmza_zoom_on_marker_click'
1175
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'>
1176
+ <label for='wpgmza_zoom_on_marker_click'
1177
+ data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1178
+ data-off='<?php _e("No", "wp-google-maps"); ?>'>
1179
+ </label>
1180
+ </div>
1181
+ </div>
1182
+ </fieldset>
1183
+
1184
+ <fieldset
1185
+ class="wpgmza-zoom-on-marker-click-zoom-level wpgmza-no-flex"
1186
+ id="wpgmza_zoom_on_marker_click_zoom_level"
1187
+ style="display: none;">
1188
+ <legend>
1189
+ <?php
1190
+ _e("Zoom Level", "wp-google-maps");
1191
+ ?>
1192
+ </legend>
1193
+
1194
+ <input name="wpgmza_zoom_on_marker_click_slider" style="display: none;" type="text" id="wpgmza_zoom_on_marker_click_slider">
1195
+
1196
+ <div id="zoom-on-marker-click-slider"></div>
1197
+ </fieldset>
1198
+
1199
+
1200
+ <fieldset>
1201
+ <legend>
1202
+ <?php
1203
+ _e('Enable Layers', 'wp-google-maps');
1204
+ ?>
1205
+ </legend>
1206
+
1207
+ <div>
1208
+ <div class='switch switch-inline'>
1209
+ <input type='checkbox'
1210
+ id='wpgmza_bicycle'
1211
+ name='bicycle'
1212
+ class='postform cmn-toggle cmn-toggle-round-flat'>
1213
+ <label for='wpgmza_bicycle'></label>
1214
+ <label for='wpgmza_bicycle'>
1215
+ <?php
1216
+ _e("Bicycle Layer","wp-google-maps");
1217
+ ?>
1218
+ </label>
1219
+ </div>
1220
+
1221
+ <br>
1222
+
1223
+ <div class='switch switch-inline'>
1224
+ <input type='checkbox'
1225
+ id='wpgmza_traffic'
1226
+ name='traffic'
1227
+ class='postform cmn-toggle cmn-toggle-round-flat'>
1228
+ <label for='wpgmza_traffic'></label>
1229
+ <label for='wpgmza_traffic'>
1230
+ <?php
1231
+ _e("Traffic Layer","wp-google-maps");
1232
+ ?>
1233
+ </label>
1234
+ </div>
1235
+
1236
+ <br>
1237
+
1238
+ <div class='switch switch-inline'>
1239
+ <input type='checkbox'
1240
+ id='wpgmza_transport'
1241
+ name='transport_layer'
1242
+ class='postform cmn-toggle cmn-toggle-round-flat'>
1243
+ <label for='wpgmza_transport'></label>
1244
+ <label for='wpgmza_transport'>
1245
+ <?php
1246
+ _e("Transit Layer","wp-google-maps");
1247
+ ?>
1248
+ </label>
1249
+ </div>
1250
+
1251
+ <div class='wpgmza-open-layers-feature-unavailable'></div>
1252
+ </div>
1253
+ </fieldset>
1254
+
1255
+ <fieldset class="wpgmza-pro-feature">
1256
+ <legend>
1257
+ <?php
1258
+ _e("Close InfoWindow on Map Click", "wp-google-maps");
1259
+ ?>
1260
+ </legend>
1261
+ <div class='switch'>
1262
+ <input type="checkbox"
1263
+ id="close_infowindow_on_map_click"
1264
+ name="close_infowindow_on_map_click"
1265
+ class="postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature"/>
1266
+ <label for="close_infowindow_on_map_click"></label>
1267
+ </div>
1268
+ </fieldset>
1269
+
1270
+ <fieldset class="wpgmza-pro-feature">
1271
+ <legend>
1272
+ <?php
1273
+ _e("Disable lightbox for marker images", "wp-google-maps");
1274
+ ?>
1275
+ </legend>
1276
+ <div class='switch'>
1277
+ <input type="checkbox"
1278
+ id="disable_lightbox_images"
1279
+ name="disable_lightbox_images"
1280
+ class="postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature"/>
1281
+ <label for="disable_lightbox_images"></label>
1282
+ </div>
1283
+ </fieldset>
1284
+
1285
+ <fieldset class="wpgmza-pro-feature">
1286
+ <legend>
1287
+ <?php
1288
+ _e("Use Raw JPEG coordinates?", "wp-google-maps");
1289
+ ?>
1290
+ </legend>
1291
+ <div class='switch'>
1292
+ <input type="checkbox"
1293
+ id="use_Raw_Jpeg_Coordinates"
1294
+ name="use_Raw_Jpeg_Coordinates"
1295
+ class="postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature"/>
1296
+ <label for="use_Raw_Jpeg_Coordinates"></label>
1297
+ </div>
1298
+ </fieldset>
1299
+
1300
+ <fieldset class="wpgmza-pro-feature" data-wpgmza-require-engine="google-maps">
1301
+ <legend>
1302
+ <?php
1303
+ _e("Enable Polygon Labels", "wp-google-maps");
1304
+ ?>
1305
+ </legend>
1306
+ <div class='switch'>
1307
+ <input type="checkbox"
1308
+ id="polygon_labels"
1309
+ name="polygon_labels"
1310
+ class="postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature"/>
1311
+ <label for="polygon_labels"></label>
1312
+ </div>
1313
+ </fieldset>
1314
+
1315
+ <fieldset class="wpgmza-pro-feature">
1316
+ <legend>
1317
+ <?php
1318
+ _e("Disable Polygon InfoWindows", "wp-google-maps");
1319
+ ?>
1320
+ </legend>
1321
+ <div class='switch'>
1322
+ <input type="checkbox"
1323
+ id="disable_polygon_info_windows"
1324
+ name="disable_polygon_info_windows"
1325
+ class="postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature"/>
1326
+ <label for="disable_polygon_info_windows"></label>
1327
+ </div>
1328
+ </fieldset>
1329
+
1330
+ <fieldset class="wpgmza-pro-feature">
1331
+ <legend>
1332
+ <?php
1333
+ _e("KML/GeoRSS URL", "wp-google-maps");
1334
+ ?>
1335
+ </legend>
1336
+
1337
+ <input id='wpgmza_kml'
1338
+ name='kml'
1339
+ type='text'
1340
+ class='regular-text wpgmza-pro-feature'/>
1341
+ <em>
1342
+ <small class='wpgmza-text-field__description'>
1343
+ <?php
1344
+ _e("The KML/GeoRSS layer will over-ride most of your map settings","wp-google-maps");
1345
+
1346
+ _e("For multiple sources, separate each one by a comma.","wp-google-maps");
1347
+ ?>
1348
+ </small>
1349
+ </em>
1350
+ </fieldset>
1351
+
1352
+ <fieldset id="wpgmza-integration-panel-container" class="wpgmza-pro-feature wpgmza-pro-feature-hide">
1353
+ <legend>
1354
+ <?php
1355
+ _e("Integration", "wp-google-maps");
1356
+ ?>
1357
+ </legend>
1358
+ </fieldset>
1359
+
1360
+ <fieldset id="wpgmza-marker-ratings" class="wpgmza-pro-feature">
1361
+ <legend>
1362
+ <?php
1363
+ _e('Enable Marker Ratings', 'wp-google-maps');
1364
+ ?>
1365
+ </legend>
1366
+ <div class='switch'>
1367
+ <input type='checkbox'
1368
+ id='enable_marker_ratings'
1369
+ name='enable_marker_ratings'
1370
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'/>
1371
+ <label for='enable_marker_ratings'></label>
1372
+ </div>
1373
+ </fieldset>
1374
+
1375
+ <fieldset class="wpgmza-pro-feature">
1376
+ <legend>
1377
+ <?php
1378
+ _e("Only load markers within viewport (beta)", "wp-google-maps");
1379
+ ?>
1380
+ </legend>
1381
+ <div class='switch switch-inline'>
1382
+ <input type="checkbox"
1383
+ id="only_load_markers_within_viewport"
1384
+ name="only_load_markers_within_viewport"
1385
+ class="postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature"/>
1386
+ <label for="only_load_markers_within_viewport"></label>
1387
+ <small><?php _e("This feature may not work as expected with bounds specific settings", "wp-google-maps"); ?></small>
1388
+ </div>
1389
+ </fieldset>
1390
+
1391
+ <fieldset class="wpgmza-pro-feature">
1392
+ <legend>
1393
+ <?php
1394
+ _e("Infowindow Style", "wp-google-maps");
1395
+ ?>
1396
+ </legend>
1397
+ <div class='wpgmza-infowindow-style-picker wpgmza-flex'>
1398
+
1399
+ <label>
1400
+ <input type="radio" name="wpgmza_iw_type" value="0" class="wpgmza-pro-feature"/>
1401
+ <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_hide'>
1402
+ <div class="wpgmza-card wpgmza-card-border__hover">
1403
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_1.png'; ?>"
1404
+ title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
1405
+ class="wpgmza_mlist_selection"
1406
+ />
1407
+ <span class='wpgmza-infowindow-style__name'>
1408
+ <?php
1409
+ _e('Default Infowindow', 'wp-google-maps');
1410
+ ?>
1411
+ </span>
1412
+ </div>
1413
+ </div>
1414
+ </label>
1415
+
1416
+ <label>
1417
+ <input type="radio" name="wpgmza_iw_type" value="1" class="wpgmza-pro-feature"/>
1418
+ <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_show'>
1419
+ <div class="wpgmza-card wpgmza-card-border__hover">
1420
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_2.png'; ?>"
1421
+ title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
1422
+ class="wpgmza_mlist_selection"
1423
+ />
1424
+ <span class='wpgmza-infowindow-style__name'>
1425
+ <?php
1426
+ _e('Modern Infowindow', 'wp-google-maps');
1427
+ ?>
1428
+ </span>
1429
+ </div>
1430
+ </div>
1431
+ </label>
1432
+
1433
+ <label>
1434
+ <input type="radio" name="wpgmza_iw_type" value="2" class="wpgmza-pro-feature"/>
1435
+ <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_show'>
1436
+ <div class="wpgmza-card wpgmza-card-border__hover">
1437
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_3.png'; ?>"
1438
+ title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
1439
+ class="wpgmza_mlist_selection"
1440
+ />
1441
+ <span class='wpgmza-infowindow-style__name'>
1442
+ <?php
1443
+ _e('Modern Plus Infowindow', 'wp-google-maps');
1444
+ ?>
1445
+ </span>
1446
+ </div>
1447
+ </div>
1448
+ </label>
1449
+
1450
+ <label>
1451
+ <input type="radio" name="wpgmza_iw_type" value="3" class="wpgmza-pro-feature"/>
1452
+ <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_show'>
1453
+ <div class="wpgmza-card wpgmza-card-border__hover">
1454
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_4.png'; ?>"
1455
+ title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
1456
+ class="wpgmza_mlist_selection"
1457
+ />
1458
+ <span class='wpgmza-infowindow-style__name'>
1459
+ <?php
1460
+ _e('Circular Infowindow', 'wp-google-maps');
1461
+ ?>
1462
+ </span>
1463
+ </div>
1464
+ </div>
1465
+ </label>
1466
+
1467
+
1468
+
1469
+ <label>
1470
+ <input type="radio" name="wpgmza_iw_type" value="-1" class="wpgmza-pro-feature"/>
1471
+ <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_hide'>
1472
+ <div class="wpgmza-card wpgmza-card-border__hover">
1473
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_inherit.png'; ?>"
1474
+ title="<?php esc_attr_e('Inherit Global Setting', 'wp-google-maps'); ?>"
1475
+ class="wpgmza_mlist_selection"
1476
+ />
1477
+ <span class='wpgmza-infowindow-style__name'>
1478
+ <?php
1479
+ _e('Inherit Global Setting', 'wp-google-maps');
1480
+ ?>
1481
+ </span>
1482
+ </div>
1483
+ </div>
1484
+ </label>
1485
+ </div>
1486
+ </fieldset>
1487
+
1488
+ <fieldset id="iw_custom_colors_row" style="display: none;">
1489
+ <legend>
1490
+ <?php
1491
+ _e("Infowindow Colors", "wp-google-maps");
1492
+ ?>
1493
+ </legend>
1494
+
1495
+ <ul>
1496
+ <li>
1497
+ <input id="iw_primary_color" name="iw_primary_color" type="color" class="color"/>
1498
+ <label for="iw_primary_color">
1499
+ <?php
1500
+ _e('Primary Color', 'wp-google-maps');
1501
+ ?>
1502
+ </label>
1503
+ </li>
1504
+ <li>
1505
+ <input id="iw_accent_color" name="iw_accent_color" type="color" class="color"/>
1506
+ <label for="iw_accent_color">
1507
+ <?php
1508
+ _e('Accent Color', 'wp-google-maps');
1509
+ ?>
1510
+ </label>
1511
+ </li>
1512
+ <li>
1513
+ <input id="iw_text_color" name="iw_text_color" type="color" class="color"/>
1514
+ <label for="iw_text_color">
1515
+ <?php
1516
+ _e('Text Color', 'wp-google-maps');
1517
+ ?>
1518
+ </label>
1519
+ </li>
1520
+ </ul>
1521
+ </fieldset>
1522
+ </div>
1523
+
1524
+ <div id="marker-listing">
1525
+
1526
+ <div class="wpgmza-upsell">
1527
+ <i class="fa fa-arrow-circle-right"></i>
1528
+ <?php
1529
+ _e('Enable Marker Listing with the <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=marker_listing"target="_BLANK">Pro version for only $39.99 once off</a>. Support and updates included forever.', "wp-google-maps");
1530
+ ?>
1531
+ </div>
1532
+
1533
+ <fieldset class="wpgmza-pro-feature">
1534
+ <legend>
1535
+ <?php
1536
+ _e('Marker Listing Style', 'wp-google-maps');
1537
+ ?>
1538
+ </legend>
1539
+
1540
+ <div class="wpgmza-marker-listing-style-menu">
1541
+
1542
+ <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1543
+ <div class='wpgmza-marker-listing-picker__item'>
1544
+ <label class="wpgmza-card wpgmza-card-border__hover">
1545
+ <input type="radio" name="wpgmza_listmarkers_by" value="0" checked="checked"/>
1546
+ <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_0.png'/>
1547
+ <span class='wpgmza-listing-item__title'>
1548
+ <?php
1549
+ _e('No marker listing', 'wp-google-maps');
1550
+ ?>
1551
+ </span>
1552
+ </label>
1553
+ </div>
1554
+ </div>
1555
+
1556
+ <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1557
+ <div class='wpgmza-marker-listing-picker__item'>
1558
+ <label class="wpgmza-card wpgmza-card-border__hover">
1559
+ <input type="radio" name="wpgmza_listmarkers_by" value="1"/>
1560
+ <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_1.png'/>
1561
+ <span class='wpgmza-listing-item__title'>
1562
+ <?php
1563
+ _e('Basic table', 'wp-google-maps');
1564
+ ?>
1565
+ </span>
1566
+ </label>
1567
+ </div>
1568
+ </div>
1569
+
1570
+ <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1571
+ <div class='wpgmza-marker-listing-picker__item'>
1572
+ <label class="wpgmza-card wpgmza-card-border__hover">
1573
+ <input type="radio" name="wpgmza_listmarkers_by" value="4"/>
1574
+ <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_2.png'/>
1575
+
1576
+ <span class='wpgmza-listing-item__title'>
1577
+ <?php
1578
+ _e('Basic list', 'wp-google-maps');
1579
+ ?>
1580
+ </span>
1581
+ </label>
1582
+ </div>
1583
+ </div>
1584
+
1585
+ <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1586
+ <div class='wpgmza-marker-listing-picker__item'>
1587
+ <label class="wpgmza-card wpgmza-card-border__hover">
1588
+ <input type="radio" name="wpgmza_listmarkers_by" value="2"/>
1589
+ <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_3.png'/>
1590
+ <span class='wpgmza-listing-item__title'>
1591
+ <?php
1592
+ _e('Advanced table', 'wp-google-maps');
1593
+ ?>
1594
+ </span>
1595
+ </label>
1596
+ </div>
1597
+ </div>
1598
+
1599
+ <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1600
+ <div class='wpgmza-marker-listing-picker__item'>
1601
+ <label class="wpgmza-card wpgmza-card-border__hover">
1602
+ <input type="radio" name="wpgmza_listmarkers_by" value="3"/>
1603
+ <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_4.png'/>
1604
+ <span class='wpgmza-listing-item__title'>
1605
+ <?php
1606
+ _e('Carousel', 'wp-google-maps');
1607
+ ?>
1608
+ </span>
1609
+ </label>
1610
+ </div>
1611
+ </div>
1612
+
1613
+ <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1614
+ <div class='wpgmza-marker-listing-picker__item'>
1615
+ <label class="wpgmza-card wpgmza-card-border__hover">
1616
+ <input type="radio" name="wpgmza_listmarkers_by" value="6"/>
1617
+ <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_modern.png'/>
1618
+ <span class='wpgmza-listing-item__title'>
1619
+ <?php
1620
+ _e('Modern', 'wp-google-maps');
1621
+ ?>
1622
+ </span>
1623
+ </label>
1624
+ </div>
1625
+ </div>
1626
+
1627
+ <div class='wpgmza-marker-listing-picker wpgmza-flex'>
1628
+ <div class='wpgmza-marker-listing-picker__item'>
1629
+ <label class="wpgmza-card wpgmza-card-border__hover">
1630
+ <input type="radio" name="wpgmza_listmarkers_by" value="7"/>
1631
+ <img class='wpgmza-listing-item__img' src='<?php echo WPGMZA_PLUGIN_DIR_URL; ?>/images/marker_list_grid.png'/>
1632
+ <span class='wpgmza-listing-item__title'>
1633
+ <?php
1634
+ _e('Grid', 'wp-google-maps');
1635
+ ?>
1636
+ </span>
1637
+ </label>
1638
+ </div>
1639
+ </div>
1640
+
1641
+ </div>
1642
+ </fieldset>
1643
+
1644
+ <fieldset class="wpgmza-pro-feature">
1645
+ <legend>
1646
+ <?php
1647
+ _e("Marker Listing Placement", "wp-google-maps");
1648
+ ?>
1649
+ </legend>
1650
+
1651
+ <div class='switch'>
1652
+ <input type='checkbox'
1653
+ id='wpgmza_marker_listing_position'
1654
+ name='wpgmza_marker_listing_position'
1655
+ class='postform cmn-toggle cmn-toggle-yes-no'>
1656
+ <label class='cmn-override-big-wide'
1657
+ for='wpgmza_marker_listing_position'
1658
+ data-on='<?php esc_attr_e("Above Map", "wp-google-maps"); ?>'
1659
+ data-off='<?php esc_attr_e("Below Map", "wp-google-maps"); ?>'>
1660
+ </label>
1661
+ </div>
1662
+ </fieldset>
1663
+
1664
+ <fieldset class="wpgmza-pro-feature">
1665
+ <legend>
1666
+ <?php
1667
+ _e("Order markers by", "wp-google-maps");
1668
+ ?>
1669
+ </legend>
1670
+
1671
+ <select id="order_markers_by" name="order_markers_by" class="postform">
1672
+ <option value="1">
1673
+ <?php
1674
+ _e('ID', 'wp-google-maps');
1675
+ ?>
1676
+ </option>
1677
+ <option value="2">
1678
+ <?php
1679
+ _e('Title', 'wp-google-maps');
1680
+ ?>
1681
+ </option>
1682
+ <option value="3">
1683
+ <?php
1684
+ _e('Address', 'wp-google-maps');
1685
+ ?>
1686
+ </option>
1687
+ <option value="4">
1688
+ <?php
1689
+ _e('Description', 'wp-google-maps');
1690
+ ?>
1691
+ </option>
1692
+ <option value="5">
1693
+ <?php
1694
+ _e('Category', 'wp-google-maps');
1695
+ ?>
1696
+ </option>
1697
+ <option value="6">
1698
+ <?php
1699
+ _e('Category Priority', 'wp-google-maps');
1700
+ ?>
1701
+ </option>
1702
+ <option value="7">
1703
+ <?php
1704
+ _e('Distance', 'wp-google-maps');
1705
+ ?>
1706
+ </option>
1707
+ <option value="8">
1708
+ <?php
1709
+ _e('Rating', 'wp-google-maps');
1710
+ ?>
1711
+ </option>
1712
+ </select>
1713
+
1714
+ <select id="order_markers_choice" name="order_markers_choice">
1715
+ <option value="1">
1716
+ <?php
1717
+ _e("Ascending", "wp-google-maps");
1718
+ ?>
1719
+ </option>
1720
+ <option value="2">
1721
+ <?php
1722
+ _e("Descending", "wp-google-maps");
1723
+ ?>
1724
+ </option>
1725
+ </select>
1726
+ </fieldset>
1727
+
1728
+ <fieldset class="wpgmza-pro-feature" data-wpgmza-require-engine="google-maps">
1729
+ <legend>
1730
+ <?php
1731
+ _e("Move list inside map", "wp-google-maps");
1732
+ ?>
1733
+ </legend>
1734
+
1735
+ <div class='switch'>
1736
+ <input id='wpgmza_push_in_map'
1737
+ name='wpgmza_push_in_map'
1738
+ class='cmn-toggle cmn-toggle-round-flat'
1739
+ type='checkbox'
1740
+ value='1'/>
1741
+ <label for='wpgmza_push_in_map'></label>
1742
+ </div>
1743
+ </fieldset>
1744
+
1745
+ <fieldset id="wpgmza_marker_list_conditional" class="wpgmza-pro-feature" data-wpgmza-require-engine="google-maps">
1746
+ <legend>
1747
+ <?php
1748
+ _e("Placement: ","wp-google-maps");
1749
+ ?>
1750
+ </legend>
1751
+ <select id="wpgmza_push_in_map_placement" name="wpgmza_push_in_map_placement" class="postform">
1752
+ <option value="1">
1753
+ <?php
1754
+ _e("Top Left", "wp-google-maps");
1755
+ ?>
1756
+ </option>
1757
+ <option value="2">
1758
+ <?php
1759
+ _e("Top Center", "wp-google-maps");
1760
+ ?>
1761
+ </option>
1762
+ <option value="3">
1763
+ <?php
1764
+ _e("Top Right", "wp-google-maps");
1765
+ ?>
1766
+ </option>
1767
+ <option value="5">
1768
+ <?php
1769
+ _e("Left Top", "wp-google-maps");
1770
+ ?>
1771
+ </option>
1772
+ <option value="4">
1773
+ <?php
1774
+ _e("Left Center", "wp-google-maps");
1775
+ ?>
1776
+ </option>
1777
+ <option value="7">
1778
+ <?php
1779
+ _e("Right Top", "wp-google-maps");
1780
+ ?>
1781
+ </option>
1782
+ <option value="8">
1783
+ <?php
1784
+ _e("Right Center", "wp-google-maps");
1785
+ ?>
1786
+ </option>
1787
+ <option value="6">
1788
+ <?php
1789
+ _e("Left Bottom", "wp-google-maps");
1790
+ ?>
1791
+ </option>
1792
+ <option value="99">
1793
+ <?php
1794
+ _e("Right Bottom", "wp-google-maps");
1795
+ ?>
1796
+ </option>
1797
+ <option value="11">
1798
+ <?php
1799
+ _e("Bottom Center", "wp-google-maps");
1800
+ ?>
1801
+ </option>
1802
+ <option value="10">
1803
+ <?php
1804
+ _e("Bottom Left", "wp-google-maps");
1805
+ ?>
1806
+ </option>
1807
+ <option value="12">
1808
+ <?php
1809
+ _e("Bottom Right", "wp-google-maps");
1810
+ ?>
1811
+ </option>
1812
+ </select>
1813
+ </fieldset>
1814
+
1815
+ <fieldset class="wpgmza-pro-feature" data-wpgmza-require-engine="google-maps">
1816
+
1817
+ <legend>
1818
+ <?php
1819
+ _e("Container Width: ", "wp-google-maps");
1820
+ ?>
1821
+ </legend>
1822
+
1823
+
1824
+ <input type="text"
1825
+ name="wpgmza_push_in_map_width"
1826
+ id="wpgmza_push_in_map_width"
1827
+ placeholder='<?php esc_attr_e('% or px', 'wp-google-maps'); ?>'/>
1828
+
1829
+ <em>
1830
+ <?php
1831
+ _e('Set as % or px, eg. 30% or 400px', 'wp-google-maps');
1832
+ ?>
1833
+ </em>
1834
+ </fieldset>
1835
+ <fieldset class="wpgmza-pro-feature" data-wpgmza-require-engine="google-maps">
1836
+
1837
+ <legend>
1838
+ <?php
1839
+ _e("Container Height: ", "wp-google-maps");
1840
+ ?>
1841
+ </legend>
1842
+
1843
+ <input type="text"
1844
+ name="wpgmza_push_in_map_height"
1845
+ id="wpgmza_push_in_map_height"
1846
+ placeholder='<?php esc_attr_e('% or px', 'wp-google-maps'); ?>'/>
1847
+ </fieldset>
1848
+
1849
+ <fieldset class="wpgmza-pro-feature">
1850
+ <legend>
1851
+ <?php
1852
+ _e("Filter by Category", "wp-google-maps");
1853
+ ?>
1854
+ </legend>
1855
+ <div class='switch'>
1856
+ <input id='filterbycat'
1857
+ name='filterbycat'
1858
+ class='cmn-toggle cmn-toggle-round-flat'
1859
+ type='checkbox' value='1'/>
1860
+ <label for='filterbycat'></label>
1861
+ </div>
1862
+ <label for='filterbycat' class='wpgmza-info__small'>
1863
+ <?php
1864
+ _e("Allow users to filter by category?", "wp-google-maps");
1865
+ ?>
1866
+ </label>
1867
+ </fieldset>
1868
+
1869
+ <fieldset class="wpgmza-pro-feature">
1870
+ <legend>
1871
+ <?php
1872
+ _e("Override zoom level on listing click", "wp-google-maps");
1873
+ ?>
1874
+ </legend>
1875
+
1876
+ <div>
1877
+ <div class='switch'>
1878
+ <input type='checkbox'
1879
+ id='zoom_level_on_marker_listing_override'
1880
+ name='zoom_level_on_marker_listing_override'
1881
+ class='postform cmn-toggle cmn-toggle-round-flat wpgmza-pro-feature'>
1882
+ <label for='zoom_level_on_marker_listing_override'
1883
+ data-on='<?php _e("Yes", "wp-google-maps"); ?>'
1884
+ data-off='<?php _e("No", "wp-google-maps"); ?>'>
1885
+ </label>
1886
+ </div>
1887
+ </div>
1888
+ </fieldset>
1889
+
1890
+ <fieldset
1891
+ class="wpgmza-zoom-on-marker-listing-click-zoom-level wpgmza-no-flex"
1892
+ id="zoom_level_on_marker_listing_click_level"
1893
+ style="display: none;">
1894
+ <legend>
1895
+ <?php
1896
+ _e("Zoom Level", "wp-google-maps");
1897
+ ?>
1898
+ </legend>
1899
+
1900
+ <input name="zoom_level_on_marker_listing_click" style="display: none;" type="text" id="zoom_level_on_marker_listing_click">
1901
+
1902
+ <div id="zoom-on-marker-listing-click-slider"></div>
1903
+ </fieldset>
1904
+
1905
+
1906
+
1907
+ <h3>
1908
+ <?php
1909
+ _e('DataTable Options', 'wp-google-maps');
1910
+ ?>
1911
+ </h3>
1912
+
1913
+ <fieldset class="wpgmza-pro-feature">
1914
+ <legend>
1915
+ <?php
1916
+ _e("No results message", "wp-google-maps");
1917
+ ?>
1918
+ </legend>
1919
+
1920
+ <div>
1921
+ <input type="text"
1922
+ name="datatable_no_result_message"
1923
+ id="datatable_no_result_message"
1924
+ placeholder='<?php esc_attr_e('No matching records found', 'wp-google-maps'); ?>'
1925
+ />
1926
+ </div>
1927
+ </fieldset>
1928
+
1929
+ <fieldset class="wpgmza-pro-feature">
1930
+ <legend>
1931
+ <?php
1932
+ _e("Remove search box", "wp-google-maps");
1933
+ ?>
1934
+ </legend>
1935
+ <div class='switch'>
1936
+ <input id='remove_search_box_datables'
1937
+ name='remove_search_box_datables'
1938
+ class='cmn-toggle cmn-toggle-round-flat'
1939
+ type='checkbox' value='1'/>
1940
+ <label for='remove_search_box_datables'></label>
1941
+ </div>
1942
+ <label for='remove_search_box_datables' class='wpgmza-info__small'>
1943
+ <?php
1944
+ _e("Remove search box from Marker Listing Table?", "wp-google-maps");
1945
+ ?>
1946
+ </label>
1947
+ </fieldset>
1948
+
1949
+ <fieldset class="wpgmza-pro-feature">
1950
+ <legend>
1951
+ <?php
1952
+ _e("Select different pagination style", "wp-google-maps");
1953
+ ?>
1954
+ </legend>
1955
+
1956
+ <select id="dataTable_pagination_style" name="dataTable_pagination_style" class="postform">
1957
+ <option value="default">
1958
+ <?php
1959
+ _e("Default", "wp-google-maps");
1960
+ ?>
1961
+ </option>
1962
+ <option value="page-number-buttons-only">
1963
+ <?php
1964
+ _e('Page number buttons only', 'wp-google-maps');
1965
+ ?>
1966
+ </option>
1967
+ <option value="prev-and-next-buttons-only">
1968
+ <?php
1969
+ _e('Previous and Next buttons only', 'wp-google-maps');
1970
+ ?>
1971
+ </option>
1972
+ <option value="prev-and-next-buttons-plus-page-numbers">
1973
+ <?php
1974
+ _e('Previous and Next buttons, plus page numbers', 'wp-google-maps');
1975
+ ?>
1976
+ </option>
1977
+ <option value="first-prev-next-and-last-buttons">
1978
+ <?php
1979
+ _e('First, Previous, Next and Last buttons', 'wp-google-maps');
1980
+ ?>
1981
+ </option>
1982
+ <option value="first-prev-next-and-last-buttons-plus-page-numbers">
1983
+ <?php
1984
+ _e('First, Previous, Next and Last buttons, plus page numbers', 'wp-google-maps');
1985
+ ?>
1986
+ </option>
1987
+ <option value="first-and-last-buttons-plus-page-numbers">
1988
+ <?php
1989
+ _e('First and Last buttons, plus page numbers', 'wp-google-maps');
1990
+ ?>
1991
+ </option>
1992
+ </select>
1993
+ </fieldset>
1994
+
1995
+ <fieldset class="wpgmza-pro-feature">
1996
+ <legend>
1997
+ <?php
1998
+ _e("Change listing table search string", "wp-google-maps");
1999
+ ?>
2000
+ </legend>
2001
+
2002
+ <div>
2003
+ <input type="text"
2004
+ name="datatable_search_string"
2005
+ id="datatable_search_string"
2006
+ placeholder='<?php esc_attr_e('Search:', 'wp-google-maps'); ?>'
2007
+ />
2008
+ </div>
2009
+ </fieldset>
2010
+
2011
+ <!--<fieldset class="wpgmza-pro-feature">
2012
+ <div class='switch'>
2013
+ <input id='datatable_result'
2014
+ name='datatable_result'
2015
+ class='cmn-toggle cmn-toggle-round-flat'
2016
+ type='checkbox' value='1'/>
2017
+ <label for='datatable_result'></label>
2018
+ </div>
2019
+ <label for='datatable_result' class='wpgmza-info__small'>
2020
+ <?php
2021
+ _e("Example: Showing 1 of 6 to 6 entries", "wp-google-maps");
2022
+ ?>
2023
+ </label>
2024
+ </fieldset>-->
2025
+
2026
+ <fieldset id="datable_strings" class="wpgmza-pro-feature">
2027
+ <legend>
2028
+ <?php
2029
+ _e("Change results string", "wp-google-maps");
2030
+ ?>
2031
+ </legend>
2032
+ <div>
2033
+ <span>
2034
+ <p><?php esc_attr_e('Showing:', 'wp-google-maps'); ?></p>
2035
+ <input type="text"
2036
+ name="datatable_result_start"
2037
+ id="datatable_result_start"
2038
+ placeholder='<?php esc_attr_e('Showing:', 'wp-google-maps'); ?>'
2039
+ /></span>
2040
+ </div>
2041
+ <div>
2042
+ <span>
2043
+ <p><?php esc_attr_e('of', 'wp-google-maps'); ?></p>
2044
+ <input type="text"
2045
+ name="datatable_result_of"
2046
+ id="datatable_result_of"
2047
+ placeholder='<?php esc_attr_e('of', 'wp-google-maps'); ?>'
2048
+ /></span>
2049
+ </div>
2050
+ <div>
2051
+ <span>
2052
+ <p><?php esc_attr_e('to', 'wp-google-maps'); ?></p>
2053
+ <input type="text"
2054
+ name="datatable_result_to"
2055
+ id="datatable_result_to"
2056
+ placeholder='<?php esc_attr_e('to', 'wp-google-maps'); ?>'
2057
+ /></span>
2058
+ </div>
2059
+
2060
+ <div>
2061
+ <span>
2062
+ <p><?php esc_attr_e('entries', 'wp-google-maps'); ?></p>
2063
+ <input type="text"
2064
+ name="datatable_result_total"
2065
+ id="datatable_result_total"
2066
+ placeholder='<?php esc_attr_e('entries', 'wp-google-maps'); ?>'
2067
+ /></span>
2068
+ </div>
2069
+ </fieldset>
2070
+
2071
+ <!--
2072
+ <fieldset class="wpgmza-pro-feature">
2073
+ <legend>
2074
+ <?php
2075
+ _e("Change entries string", "wp-google-maps");
2076
+ ?>
2077
+ </legend>
2078
+ <div class='switch'>
2079
+ <input id='datatable_result_page'
2080
+ name='datatable_result_page'
2081
+ class='cmn-toggle cmn-toggle-round-flat'
2082
+ type='checkbox' value='1'/>
2083
+ <label for='datatable_result_page'></label>
2084
+ </div>
2085
+ <label for='datatable_result_page' class='wpgmza-info__small'>
2086
+ <?php
2087
+ _e("Example: Showing entries", "wp-google-maps");
2088
+ ?>
2089
+ </label>
2090
+ </fieldset>
2091
+ -->
2092
+
2093
+ <fieldset id="datable_strings_entries" class="wpgmza-pro-feature">
2094
+ <legend>
2095
+
2096
+ </legend>
2097
+ <div>
2098
+ <span>
2099
+ <p><?php esc_attr_e('Show:', 'wp-google-maps'); ?></p>
2100
+ <input type="text"
2101
+ name="datatable_result_show"
2102
+ id="datatable_result_show"
2103
+ placeholder='<?php esc_attr_e('Show:', 'wp-google-maps'); ?>'
2104
+ /></span>
2105
+ </div>
2106
+
2107
+ <div>
2108
+ <span>
2109
+ <p><?php esc_attr_e('Entries', 'wp-google-maps'); ?></p>
2110
+ <input type="text"
2111
+ name="datatable_result_entries"
2112
+ id="datatable_result_entries"
2113
+ placeholder='<?php esc_attr_e('Entries', 'wp-google-maps'); ?>'
2114
+ /></span>
2115
+ </div>
2116
+ </fieldset>
2117
+
2118
+ </div>
2119
+
2120
+ <div id="pro-upgrade" class="wpgmza-pro-feature-upsell">
2121
+ <div id="wpgm_premium">
2122
+ <div class='wpgmza-flex'>
2123
+ <div class="wpgm_premium_row">
2124
+ <div class='wpgmza-card'>
2125
+ <div class="wpgm_icon"></div>
2126
+ <div class="wpgm_details">
2127
+ <h2>
2128
+ <?php _e("Create custom markers with detailed info windows", "wp-google-maps") ?></h2>
2129
+ <p><?php _e("Add titles, descriptions, HTML, images, animations and custom icons to your markers.", "wp-google-maps") ?></p>
2130
+ </div>
2131
+ </div>
2132
+ </div>
2133
+ <div class="wpgm_premium_row">
2134
+ <div class='wpgmza-card'>
2135
+ <div class="wpgm_icon"></div>
2136
+ <div class="wpgm_details">
2137
+ <h2>Enable directions</h2>
2138
+ <p><?php _e("Allow your visitors to get directions to your markers. Either use their location as the starting point or allow them to type in an address.", "wp-google-maps") ?></p>
2139
+ </div>
2140
+ </div>
2141
+ </div>
2142
+ <div class="wpgm_premium_row">
2143
+ <div class='wpgmza-card'>
2144
+ <div class="wpgm_icon"></div>
2145
+ <div class="wpgm_details">
2146
+ <h2>Unlimited maps</h2>
2147
+ <p><?php _e('Create as many maps as you like.', "wp-google-maps") ?></p>
2148
+ </div>
2149
+ </div>
2150
+ </div>
2151
+ <div class="wpgm_premium_row">
2152
+ <div class='wpgmza-card'>
2153
+ <div class="wpgm_icon"></div>
2154
+ <div class="wpgm_details">
2155
+ <h2>List your markers</h2>
2156
+ <p><?php _e('Choose between three methods of listing your markers.', "wp-google-maps") ?></p>
2157
+ </div>
2158
+ </div>
2159
+ </div>
2160
+ <div class="wpgm_premium_row">
2161
+ <div class='wpgmza-card'>
2162
+ <div class="wpgm_icon"></div>
2163
+ <div class="wpgm_details">
2164
+ <h2><?php _e('Add categories to your markers', "wp-google-maps") ?></h2>
2165
+ <p><?php _e('Create and assign categories to your markers which can then be filtered on your map.', "wp-google-maps") ?></p>
2166
+ </div>
2167
+ </div>
2168
+ </div>
2169
+ <div class="wpgm_premium_row">
2170
+ <div class='wpgmza-card'>
2171
+ <div class="wpgm_icon"></div>
2172
+ <div class="wpgm_details">
2173
+ <h2><?php _e('Advanced options', "wp-google-maps") ?></h2>
2174
+ <p><?php _e("Enable advanced options such as showing your visitor's location, marker sorting, bicycle layers, traffic layers and more!", "wp-google-maps") ?></p>
2175
+ </div>
2176
+ </div>
2177
+ </div>
2178
+ <div class="wpgm_premium_row">
2179
+ <div class='wpgmza-card'>
2180
+ <div class="wpgm_icon"></div>
2181
+ <div class="wpgm_details">
2182
+ <h2><?php _e('Import / Export', "wp-google-maps") ?></h2>
2183
+ <p><?php _e('Export your markers to a CSV file for quick and easy editing. Import large quantities of markers at once.', "wp-google-maps") ?></p>
2184
+ </div>
2185
+ </div>
2186
+ </div>
2187
+ <div class="wpgm_premium_row">
2188
+ <div class='wpgmza-card'>
2189
+ <div class="wpgm_icon"></div>
2190
+ <div class="wpgm_details">
2191
+ <h2><?php _e('Add KML &amp; Fusion Tables', "wp-google-maps") ?></h2>
2192
+ <p><?php _e('Add your own KML layers or Fusion Table data to your map', "wp-google-maps") ?></p>
2193
+ </div>
2194
+ </div>
2195
+ </div>
2196
+ <div class="wpgm_premium_row">
2197
+ <div class='wpgmza-card'>
2198
+ <div class="wpgm_icon"></div>
2199
+ <div class="wpgm_details">
2200
+ <h2><?php _e('Polygons and Polylines', "wp-google-maps") ?></h2>
2201
+ <p><?php _e('Add custom polygons and polylines to your map by simply clicking on the map. Perfect for displaying routes and serviced areas.', "wp-google-maps") ?></p>
2202
+ </div>
2203
+ </div>
2204
+ </div>
2205
+ <div class="wpgm_premium_row">
2206
+ <div class='wpgmza-card'>
2207
+ <div class="wpgm_icon"></div>
2208
+ <div class="wpgm_details">
2209
+ <h2><?php _e('Amazing Support', "wp-google-maps") ?></h2>
2210
+ <p><?php _e('We pride ourselves on providing quick and amazing support. <a target="_BLANK" href="http://wordpress.org/support/view/plugin-reviews/wp-google-maps?filter=5">Read what some of our users think of our support</a>.', "wp-google-maps") ?></p>
2211
+ </div>
2212
+ </div>
2213
+ </div>
2214
+ <div class="wpgm_premium_row">
2215
+ <div class="wpgmza-card">
2216
+ <div class="wpgm_icon"></div>
2217
+ <div class="wpgm_details">
2218
+ <h2><?php _e('Easy Upgrade', "wp-google-maps") ?></h2>
2219
+ <p><?php _e("You'll receive a download link immediately. Simply upload and activate the Pro plugin to your WordPress admin area and you're done!", "wp-google-maps") ?></p>
2220
+ </div>
2221
+ </div>
2222
+ </div>
2223
+ <div class="wpgm_premium_row">
2224
+ <div class='wpgmza-card'>
2225
+ <div class="wpgm_icon"></div>
2226
+ <div class="wpgm_details">
2227
+ <h2><?php _e('Free updates and support forever', "wp-google-maps") ?></h2>
2228
+ <p><?php _e("Once you're a pro user, you'll receive free updates and support forever! You'll also receive amazing specials on any future plugins we release.", "wp-google-maps") ?></p>
2229
+ </div>
2230
+ </div>
2231
+ </div>
2232
+ </div>
2233
+
2234
+ <p>
2235
+ <?php
2236
+ _e('Get all of this and more for only $39.99 once off', 'wp-google-maps');
2237
+ ?>
2238
+ </p>
2239
+ <p>
2240
+ <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=upgradenow" target="_BLANK" title="Upgrade now for only $39.99 once off" class="button-primary" style="font-size:20px; display:block; width:220px; text-align:center; height:42px; line-height:41px;" id="wpgmza-upgrade-now__btn">
2241
+ <?php esc_html_e('Upgrade Now', "wp-google-maps") ?>
2242
+ </a>
2243
+ </p>
2244
+
2245
+ <p>
2246
+ <a href="https://www.wpgmaps.com/demo/" target="_BLANK">
2247
+ <?php esc_html_e('View the demos', 'wp-google-maps'); ?></a>
2248
+ </p>
2249
+
2250
+ <p>
2251
+ <?php
2252
+ _e("Have a sales question? Contact Nick on <a href=\"mailto:nick@wpgmaps.com\">nick@wpgmaps.com</a> or use our <a href=\"https://www.wpgmaps.com/contact-us/\" target=\"_BLANK\">contact form</a>.", "wp-google-maps")
2253
+ ?>
2254
+ </p>
2255
+ <p>
2256
+ <?php
2257
+ _e("Need help? <a href=\"https://www.wpgmaps.com/forums/\" target=\"_BLANK\">Ask a question on our support forum</a>.", "wp-google-maps")
2258
+ ?>
2259
+ </p>
2260
+ </div>
2261
+ </div>
2262
+
2263
+ </div> <!-- End of tabs -->
2264
+
2265
+ <!-- NB: <p> has a semantic meaning. Recommend using div instead with a class for padding / margin -->
2266
+ <p>
2267
+ <input type='submit' name='wpgmza_savemap' class='button-primary' value='<?php _e("Save Map", "wp-google-maps"); ?> &raquo;'/>
2268
+ </p>
2269
+
2270
+ <p class='wpgmza-map-edit__mouse-tip'>
2271
+ <?php
2272
+ _e("Tip: Use your mouse to change the layout of your map. When you have positioned the map to your desired location, press \"Save Map\" to keep your settings.", "wp-google-maps");
2273
+ ?>
2274
+ </p>
2275
+ </form>
2276
+
2277
+ <div class='wgmza-map-editor-holder'>
2278
+ <div style="display:block; overflow-y:auto; overflow-x:hidden; width:49%; margin-right:1%; float:left;">
2279
+ <div id="wpgmaps_tabs_markers" class="wpgmza-form">
2280
+
2281
+ <div class="wpgmza-editor-row">
2282
+ <div class="wpgmza-editor-col">
2283
+ <ul class='wpgmza-tab-wrap'>
2284
+ <li>
2285
+ <a href="#markers">
2286
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/marker-tab-icon.png"; ?>" alt=""/>
2287
+ <?php _e("Markers","wp-google-maps"); ?>
2288
+ </a>
2289
+ </li>
2290
+
2291
+ <li class="wpgmza-basic-only wpgmza-upgrade-tab">
2292
+ <a href="#advanced-markers">
2293
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/marker-tab-icon.png"; ?>" alt=""/>
2294
+ <?php _e("Advanced Markers","wp-google-maps"); ?>
2295
+ </a>
2296
+ </li>
2297
+
2298
+ <li>
2299
+ <a href="#polygons">
2300
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/polygon.png"; ?>" alt=""/>
2301
+ <?php _e("Polygons","wp-google-maps"); ?>
2302
+ </a>
2303
+ </li>
2304
+ <li>
2305
+ <a href="#polylines">
2306
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/polyline.png"; ?>" alt=""/>
2307
+ <?php _e("Polylines","wp-google-maps"); ?>
2308
+ </a>
2309
+ </li>
2310
+ <li>
2311
+ <a href="#heatmaps">
2312
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/heatmap.png"; ?>" alt=""/>
2313
+ <?php _e("Heatmaps","wp-google-maps"); ?>
2314
+ </a>
2315
+ </li>
2316
+ <li>
2317
+ <a href="#circles">
2318
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/circle.png"; ?>" alt=""/>
2319
+ <?php _e("Circles","wp-google-maps"); ?>
2320
+ </a>
2321
+ </li>
2322
+ <li>
2323
+ <a href="#rectangles">
2324
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . "images/rectangle.png"; ?>" alt=""/>
2325
+ <?php _e("Rectangles","wp-google-maps"); ?>
2326
+ </a>
2327
+ </li>
2328
+ </ul>
2329
+ </div>
2330
+ </div>
2331
+
2332
+ <div class="wpgmza-editor-row">
2333
+
2334
+ <?php /* map used to be here */ ?>
2335
+
2336
+ </div>
2337
+
2338
+
2339
+
2340
+
2341
+ <div class="wpgmza-feature-accordion" id="markers" data-wpgmza-feature-type="marker">
2342
+
2343
+ <div class="wpgmza-accordion">
2344
+ <h3
2345
+ data-add-caption="<?php esc_attr_e('Add a new Marker', 'wp-google-maps'); ?>"
2346
+ data-edit-caption="<?php esc_attr_e('Edit Marker', 'wp-google-maps'); ?>">
2347
+
2348
+ <!-- <i class="fa fa-plus-circle" aria-hidden="true"></i> -->
2349
+ <?php _e('Add a new Marker', 'wp-google-maps'); ?>
2350
+
2351
+ </h3>
2352
+
2353
+ <div class="wpgmza-feature-panel-container"></div>
2354
+
2355
+
2356
+
2357
+
2358
+
2359
+
2360
+ </div>
2361
+
2362
+ </div>
2363
+
2364
+ <div class="wpgmza-feature-accordion" id="polygons" data-wpgmza-feature-type="polygon">
2365
+
2366
+ <div class="wpgmza-accordion">
2367
+ <h3
2368
+ data-add-caption="<?php esc_attr_e('Add a new Polygon', 'wp-google-maps'); ?>"
2369
+ data-edit-caption="<?php esc_attr_e('Edit Polygon', 'wp-google-maps'); ?>">
2370
+
2371
+ <!-- <i class="fa fa-plus-circle" aria-hidden="true"></i> -->
2372
+ <?php _e('Add a new Polygon', 'wp-google-maps'); ?>
2373
+
2374
+ </h3>
2375
+
2376
+ <div class="wpgmza-feature-panel-container"></div>
2377
+
2378
+
2379
+
2380
+
2381
+ </div>
2382
+
2383
+ </div>
2384
+
2385
+ <div class="wpgmza-feature-accordion" id="polylines" data-wpgmza-feature-type="polyline">
2386
+
2387
+ <div class="wpgmza-accordion">
2388
+ <h3
2389
+ data-add-caption="<?php esc_attr_e('Add a new Polyline', 'wp-google-maps'); ?>"
2390
+ data-edit-caption="<?php esc_attr_e('Edit Polyline', 'wp-google-maps'); ?>">
2391
+
2392
+ <!-- <i class="fa fa-plus-circle" aria-hidden="true"></i> -->
2393
+ <?php _e('Add a new Polyline', 'wp-google-maps'); ?>
2394
+
2395
+ </h3>
2396
+
2397
+ <div class="wpgmza-feature-panel-container"></div>
2398
+
2399
+
2400
+ </div>
2401
+
2402
+ </div>
2403
+
2404
+ <div class="wpgmza-feature-accordion" id="heatmaps" data-wpgmza-feature-type="heatmap">
2405
+
2406
+ <div class="wpgmza-accordion">
2407
+ <h3
2408
+ data-add-caption="<?php esc_attr_e('Add a new Heatmap', 'wp-google-maps'); ?>"
2409
+ data-edit-caption="<?php esc_attr_e('Edit Heatmaps', 'wp-google-maps'); ?>">
2410
+
2411
+ <?php _e('Add a new Heatmap', 'wp-google-maps'); ?>
2412
+
2413
+ </h3>
2414
+
2415
+ <div class="wpgmza-feature-panel-container"></div>
2416
+
2417
+
2418
+
2419
+ </div>
2420
+
2421
+ </div>
2422
+
2423
+ <div class="wpgmza-feature-accordion" id="circles" data-wpgmza-feature-type="circle">
2424
+
2425
+ <div class="wpgmza-accordion">
2426
+ <h3
2427
+ data-add-caption="<?php esc_attr_e('Add a new Circle', 'wp-google-maps'); ?>"
2428
+ data-edit-caption="<?php esc_attr_e('Edit Circle', 'wp-google-maps'); ?>">
2429
+
2430
+ <!-- <i class="fa fa-plus-circle" aria-hidden="true"></i> -->
2431
+ <?php _e('Add a new Circle', 'wp-google-maps'); ?>
2432
+
2433
+ </h3>
2434
+
2435
+ <div class="wpgmza-feature-panel-container"></div>
2436
+
2437
+
2438
+
2439
+
2440
+ </div>
2441
+
2442
+ </div>
2443
+
2444
+ <div class="wpgmza-feature-accordion" id="rectangles" data-wpgmza-feature-type="rectangle">
2445
+
2446
+ <div class="wpgmza-accordion">
2447
+ <h3
2448
+ data-add-caption="<?php esc_attr_e('Add a new Rectangle', 'wp-google-maps'); ?>"
2449
+ data-edit-caption="<?php esc_attr_e('Edit Rectangle', 'wp-google-maps'); ?>">
2450
+ <!-- <i class="fa fa-plus-circle" aria-hidden="true"></i> -->
2451
+ <?php _e('Add a new Rectangle', 'wp-google-maps'); ?>
2452
+ </h3>
2453
+
2454
+ <div class="wpgmza-feature-panel-container"></div>
2455
+
2456
+
2457
+
2458
+
2459
+ </div>
2460
+
2461
+ </div>
2462
+
2463
+ <div id="advanced-markers">
2464
+
2465
+ <div class="wpgmza-upsell">
2466
+ <i class="fa fa-arrow-circle-right"></i>
2467
+ <a target="_BLANK" href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=advanced_markers"><?php esc_html_e("Add advanced markers", "wp-google-maps"); ?></a>
2468
+ <?php
2469
+ esc_html_e("with the Pro version","wp-google-maps");
2470
+ ?>
2471
+ </div>
2472
+
2473
+ <!-- The content will be imported by MapEditPage -->
2474
+
2475
+ </div>
2476
+
2477
+ </div>
2478
+
2479
+
2480
+
2481
+
2482
+ </div>
2483
+
2484
+ <div class="wpgmza-editor-col map-container-wrap">
2485
+ <?php echo wpgmaps_check_if_no_api_key(); ?>
2486
+ <p class='notice notice-error wpgmza-missing-key-notice wpgmza-hidden'>
2487
+ <?php
2488
+ echo sprintf(
2489
+ __('Please ensure you <a href="%s">enter a Google Maps API key</a> to continue using Google Maps. Alternatively, swap over to Open Layers by clicking <a id="wpgm-swap-to-open-layers" href="%s">here</a>.', 'wp-google-maps'),
2490
+ "admin.php?page=wp-google-maps-menu-settings",
2491
+ "javascript:void(0);"
2492
+ );
2493
+ ?>
2494
+ </p>
2495
+ <div class='map_wrapper'>
2496
+ <div id="wpgmza-map-container"></div>
2497
+ </div>
2498
+
2499
+ <div id="wpgmaps_save_reminder" style="display:none;">
2500
+ <div class="wpgmza-nag wpgmza-update-nag" style='text-align:center;'>
2501
+ <h4><?php _e("Remember to save your map!","wp-google-maps"); ?></h4>
2502
+ </div>
2503
+ </div>
2504
+
2505
+ </div>
2506
+ </div>
2507
+
2508
+ <h3 class="separate wpgmza-table-container-title" id="wpgmza-table-container-title-Rectangle"><?php _e('Edit existing Rectangles', 'wp-google-maps'); ?></h3>
2509
+ <h3 class="separate wpgmza-table-container-title" id="wpgmza-table-container-title-Circle"><?php _e('Edit existing Circles', 'wp-google-maps'); ?></h3>
2510
+ <h3 class="separate wpgmza-table-container-title" id="wpgmza-table-container-title-Heatmap"><?php _e('Edit existing Heatmaps', 'wp-google-maps'); ?></h3>
2511
+ <h3 class="separate wpgmza-table-container-title" id="wpgmza-table-container-title-Polyline"><?php _e('Edit existing Polylines', 'wp-google-maps'); ?></h3>
2512
+ <h3 class="separate wpgmza-table-container-title" id="wpgmza-table-container-title-Polygon"><?php _e('Edit existing Polygons', 'wp-google-maps'); ?></h3>
2513
+ <h3 class="separate wpgmza-table-container-title" id="wpgmza-table-container-title-Marker"><?php _e('Edit existing Markers', 'wp-google-maps'); ?></h3>
2514
+
2515
+
2516
+ <div class="wpgmza-table-container" id="wpgmza-table-container-Marker"></div>
2517
+ <div class="wpgmza-table-container" id="wpgmza-table-container-Polygon"></div>
2518
+ <div class="wpgmza-table-container" id="wpgmza-table-container-Polyline"></div>
2519
+ <div class="wpgmza-table-container wpgmza-pro-feature-hide" id="wpgmza-table-container-Heatmap"></div>
2520
+ <div class="wpgmza-table-container" id="wpgmza-table-container-Rectangle"></div>
2521
+ <div class="wpgmza-table-container" id="wpgmza-table-container-Circle"></div>
2522
+
2523
+
2524
+
2525
+ <div style='clear:both;' id='wpgmza-pro-features' class="wpgmza-upsell wpgmza-flex wpgmza_no_shadow">
2526
+ <div class='wpgmza-pro-features__item'>
2527
+ <div class='wpgmza-card'>
2528
+ <div>
2529
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL; ?>images/custom_markers.jpg"
2530
+ width="260"
2531
+ class='wpgmza-promo'
2532
+ title="<?php _e("Add detailed information to your markers!", "wp-google-maps"); ?>"
2533
+ alt="<?php _e("Add custom markers to your map!", "wp-google-maps"); ?>"
2534
+ />
2535
+ <br/>
2536
+ <br/>
2537
+ </div>
2538
+ <div valign="middle">
2539
+ <span style="font-size:18px; color:#666;"
2540
+ class='wpgmza-feature-item__desc'>
2541
+ <?php
2542
+ _e("Add detailed information to your markers for only", "wp-google-maps");
2543
+ ?>
2544
+ <strong>$39.99</strong>
2545
+ <?php
2546
+ _e("Click", "wp-google-maps");
2547
+ ?>
2548
+
2549
+ <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=image1"
2550
+ title="Pro Edition"
2551
+ target="_BLANK">
2552
+ <?php
2553
+ _e("here","wp-google-maps");
2554
+ ?>
2555
+ </a>
2556
+ </span>
2557
+ </div>
2558
+ </div>
2559
+ </div>
2560
+ <div class='wpgmza-pro-features__item'>
2561
+ <div class='wpgmza-card'>
2562
+ <div>
2563
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL; ?>images/custom_marker_icons.jpg"
2564
+ width="260"
2565
+ class='wpgmza-promo'
2566
+ title="<?php _e("Add custom markers to your map!", "wp-google-maps"); ?>"
2567
+ alt="<?php _e("Add custom markers to your map!", "wp-google-maps"); ?>"/>
2568
+
2569
+ <br />
2570
+ <br />
2571
+ </div>
2572
+ <div valign="middle">
2573
+ <span style="font-size:18px; color:#666;" class='wpgmza-feature-item__desc'>
2574
+ <?php
2575
+ _e("Add different marker icons, or your own icons to make your map really stand out!", "wp-google-maps");
2576
+ ?>
2577
+
2578
+ <?php
2579
+ _e("Click","wp-google-maps");
2580
+ ?>
2581
+ <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=image3"
2582
+ title="<?php _e("Pro Edition", "wp-google-maps"); ?>"
2583
+ target="_BLANK">
2584
+ <?php
2585
+ _e("here", "wp-google-maps");
2586
+ ?>
2587
+ </a>
2588
+ </span>
2589
+ </div>
2590
+ </div>
2591
+ </div>
2592
+ <div class='wpgmza-pro-features__item'>
2593
+ <div class='wpgmza-card'>
2594
+ <div>
2595
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL; ?>images/get_directions.jpg"
2596
+ width="260"
2597
+ class='wpgmza-promo'
2598
+ title="<?php _e("Add custom markers to your map!", "wp-google-maps"); ?>"
2599
+ alt="<?php _e("Add custom markers to your map!", "wp-google-maps"); ?>"/>
2600
+ <br />
2601
+ <br />
2602
+ </div>
2603
+ <div valign="middle">
2604
+ <span style="font-size:18px; color:#666;" class='wpgmza-feature-item__desc'>
2605
+ <?php
2606
+ _e("Allow your visitors to get directions to your markers!", "wp-google-maps");
2607
+ ?>
2608
+
2609
+ <?php
2610
+ _e("Click", "wp-google-maps");
2611
+ ?>
2612
+ <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=image2"
2613
+ title="<?php _e("Pro Edition", "wp-google-maps"); ?>"
2614
+ target="_BLANK">
2615
+ <?php
2616
+ _e("here", "wp-google-maps");
2617
+ ?>
2618
+ </a>
2619
+ </span>
2620
+ </div>
2621
+ </div>
2622
+ </div>
2623
+ </div>
2624
+
2625
+ <p id='wpgmza-basic-footer-text'>
2626
+ <small>
2627
+ <?php
2628
+ _e("Thank you for using <a href='https://www.wpgmaps.com'>WP Google Maps</a>! Please <a href='https://wordpress.org/support/plugin/wp-google-maps/reviews/'>rate us on WordPress.org</a>", 'wp-google-maps');
2629
+ ?>
2630
+ |
2631
+ <?php
2632
+ echo sprintf(
2633
+ __("WP Google Maps is a product of <img src='%s' alt='CODECABIN_' style='height: 1em;' class='wpgmze_cc_footer_image'/>", 'wp-google-maps'),
2634
+ WPGMZA_PLUGIN_DIR_URL . 'images/codecabin.png'
2635
+ );
2636
+ ?>
2637
+ |
2638
+ <?php
2639
+ _e("Please refer to our <a href='https://www.wpgmaps.com/privacy-policy' target='_blank'>Privacy Policy</a> for information on Data Processing", 'wp-google-maps')
2640
+ ?>
2641
+ |
2642
+ <?php
2643
+ _e("WP Google Maps encourages you to make use of the amazing icons at ", "wp-google-maps");
2644
+ ?>
2645
+ <a href='https://mappity.org'>https://mappity.org</a>
2646
+ |
2647
+ <?php
2648
+ _e('Translating the plugin with', 'wp-google-maps'); ?>
2649
+ <a href='https://www.wpgmaps.com/documentation/translating-the-plugin-with-wpml/' target='_BLANK'><?php esc_html_e('WPML', 'wp-google-maps'); ?></a>
2650
+ </small>
2651
+ </p>
2652
+
2653
+
2654
  </div>
html/map-list-page.html.php CHANGED
@@ -1,125 +1,125 @@
1
- <div id='WPGMMapList'>
2
- <div style='padding:10px; display:block; overflow:auto'>
3
-
4
- <div style="float: right;">
5
-
6
- <button type="button"
7
- class="button button-primary wpgmza-pro-new wpgmza-pro-feature wpgmza-pro-feature-hide"
8
- data-action="new-map">
9
- <?php
10
- _e("Add New", "wp-google-maps");
11
- ?>
12
- </button>
13
-
14
- <button type="button"
15
- class="button button-primary wpgmza-pro-wizard wpgmza-pro-feature wpgmza-pro-feature-hide"
16
- data-action="wizard">
17
- <?php
18
- _e("Wizard", "wp-google-maps");
19
- ?>
20
- </button>
21
-
22
- </div>
23
-
24
- <h1>
25
- <?php
26
- esc_html_e("My Maps", "wp-google-maps");
27
- ?>
28
- </h1>
29
-
30
- <div class='wpgmza-review-nag'>
31
- <?php
32
- echo sprintf( __( '<h3>We need your love!</h3><p>If you are enjoying our plugin, please consider <a href="%1$s" target="_blank" class="button-border button-border__green">reviewing WP Google Maps</a>. It would mean the world to us! If you are experiencing issues with the plugin, please <a href="%2$s" target="_blank" class="button-border button-border__green">contact us</a> and we will help you as soon as humanly possible!</p>', 'wp-google-maps' ),
33
- esc_url('https://wordpress.org/support/view/plugin-reviews/wp-google-maps?filter=5'),
34
- esc_url('http://www.wpgmaps.com/contact-us/')
35
- );
36
- ?>
37
-
38
- <p>
39
- <a href='admin.php?page=wp-google-maps-menu&amp;wpgmza-close-review-nag' class='wpgmza_close_review_nag button-border button-border__green' title="<?php esc_html_e("We will not nag you again, promise!","wp-google-maps"); ?>">
40
- <?php
41
- esc_html_e("Close","wp-google-maps");
42
- ?>
43
- </a>
44
- </p>
45
- </div>
46
-
47
- <p class='wpgmza_upgrade_nag'>
48
- <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=mappage_1"
49
- target="_BLANK"
50
- title="<?php esc_html_e("Pro Version", "wp-google-maps"); ?>">
51
- <?php
52
- esc_html_e("Create unlimited maps", "wp-google-maps");
53
- ?></a>
54
-
55
- <?php
56
- esc_html_e("with the", "wp-google-maps");
57
- ?>
58
-
59
- <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=mappage_2"
60
- title="Pro Version"
61
- target="_BLANK">
62
- <?php
63
- esc_html_e("Pro Version", "wp-google-maps");
64
- ?></a>
65
-
66
- <?php
67
- esc_html_e("of WP Google Maps for only", "wp-google-maps");
68
- ?>
69
-
70
- <strong>$39.99 <?php esc_html_e("once off!","wp-google-maps"); ?></strong>
71
- </p>
72
-
73
- <div id="wpgmza-admin-map-table-container"></div>
74
- </div>
75
- </div>
76
-
77
- <?php /*
78
-
79
- Will seek approval from WP.org first before implementing this.
80
-
81
- <div id='WPGMFeeds'>
82
- <div id='WPGMLatestNews'>
83
- <div id='WPGMLatestNewsInner'>
84
-
85
- <div style='background-color:#fff; padding:10px;'>
86
- <h4><?php _e("Latest News", "wp-google-maps"); ?></h4>
87
- <?php
88
- WPGMZA\Plugin::output_rss_feed(array('http://wpgmaps.com/public-feeds/latest-news'), 5, true, true, 100);
89
- ?>
90
- </div>
91
-
92
-
93
- </div>
94
-
95
- </div>
96
- <div id='WPGMFeatureRequests'>
97
- <div id='WPGMFeatureRequestsInner'>
98
-
99
- <div style='background-color:#fff; padding:10px;'>
100
- <h4><?php _e("Latest Feature Requests", "wp-google-maps"); ?></h4>
101
- <?php
102
- WPGMZA\Plugin::output_rss_feed(array('http://wpgmaps.com/public-feeds/latest-feature-requests'), 5, true, true, 100);
103
- ?>
104
- <p><a href='https://www.wpgmaps.com/forums/forum/suggestions/' class='button button-primary' target='_BLANK'>Submit a request</a></p>
105
- </div>
106
-
107
-
108
- </div>
109
-
110
- </div>
111
- <div id='WPGMLatestTopics'>
112
- <div id='WPGMLatestTopicsInner'>
113
-
114
- <div style='background-color:#fff; padding:10px;'>
115
- <h4><?php _e("Latest Forum Topics", "wp-google-maps"); ?></h4>
116
- <?php
117
- WPGMZA\Plugin::output_rss_feed(array('http://wpgmaps.com/public-feeds/latest-forum-topics'), 5, true, true, 100);
118
- ?>
119
- <p><a href='https://www.wpgmaps.com/forums/' class='button button-primary' target='_BLANK'>Create a ticket</a></p>
120
- </div>
121
-
122
- </div>
123
-
124
- </div>
125
  </div> */
1
+ <div id='WPGMMapList'>
2
+ <div style='padding:10px; display:block; overflow:auto'>
3
+
4
+ <div style="float: right;">
5
+
6
+ <button type="button"
7
+ class="button button-primary wpgmza-pro-new wpgmza-pro-feature wpgmza-pro-feature-hide"
8
+ data-action="new-map">
9
+ <?php
10
+ _e("Add New", "wp-google-maps");
11
+ ?>
12
+ </button>
13
+
14
+ <button type="button"
15
+ class="button button-primary wpgmza-pro-wizard wpgmza-pro-feature wpgmza-pro-feature-hide"
16
+ data-action="wizard">
17
+ <?php
18
+ _e("Wizard", "wp-google-maps");
19
+ ?>
20
+ </button>
21
+
22
+ </div>
23
+
24
+ <h1>
25
+ <?php
26
+ esc_html_e("My Maps", "wp-google-maps");
27
+ ?>
28
+ </h1>
29
+
30
+ <div class='wpgmza-review-nag'>
31
+ <?php
32
+ echo sprintf( __( '<h3>We need your love!</h3><p>If you are enjoying our plugin, please consider <a href="%1$s" target="_blank" class="button-border button-border__green">reviewing WP Google Maps</a>. It would mean the world to us! If you are experiencing issues with the plugin, please <a href="%2$s" target="_blank" class="button-border button-border__green">contact us</a> and we will help you as soon as humanly possible!</p>', 'wp-google-maps' ),
33
+ esc_url('https://wordpress.org/support/view/plugin-reviews/wp-google-maps?filter=5'),
34
+ esc_url('http://www.wpgmaps.com/contact-us/')
35
+ );
36
+ ?>
37
+
38
+ <p>
39
+ <a href='admin.php?page=wp-google-maps-menu&amp;wpgmza-close-review-nag' class='wpgmza_close_review_nag button-border button-border__green' title="<?php esc_html_e("We will not nag you again, promise!","wp-google-maps"); ?>">
40
+ <?php
41
+ esc_html_e("Close","wp-google-maps");
42
+ ?>
43
+ </a>
44
+ </p>
45
+ </div>
46
+
47
+ <p class='wpgmza_upgrade_nag'>
48
+ <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=mappage_1"
49
+ target="_BLANK"
50
+ title="<?php esc_html_e("Pro Version", "wp-google-maps"); ?>">
51
+ <?php
52
+ esc_html_e("Create unlimited maps", "wp-google-maps");
53
+ ?></a>
54
+
55
+ <?php
56
+ esc_html_e("with the", "wp-google-maps");
57
+ ?>
58
+
59
+ <a href="https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=mappage_2"
60
+ title="Pro Version"
61
+ target="_BLANK">
62
+ <?php
63
+ esc_html_e("Pro Version", "wp-google-maps");
64
+ ?></a>
65
+
66
+ <?php
67
+ esc_html_e("of WP Google Maps for only", "wp-google-maps");
68
+ ?>
69
+
70
+ <strong>$39.99 <?php esc_html_e("once off!","wp-google-maps"); ?></strong>
71
+ </p>
72
+
73
+ <div id="wpgmza-admin-map-table-container"></div>
74
+ </div>
75
+ </div>
76
+
77
+ <?php /*
78
+
79
+ Will seek approval from WP.org first before implementing this.
80
+
81
+ <div id='WPGMFeeds'>
82
+ <div id='WPGMLatestNews'>
83
+ <div id='WPGMLatestNewsInner'>
84
+
85
+ <div style='background-color:#fff; padding:10px;'>
86
+ <h4><?php _e("Latest News", "wp-google-maps"); ?></h4>
87
+ <?php
88
+ WPGMZA\Plugin::output_rss_feed(array('http://wpgmaps.com/public-feeds/latest-news'), 5, true, true, 100);
89
+ ?>
90
+ </div>
91
+
92
+
93
+ </div>
94
+
95
+ </div>
96
+ <div id='WPGMFeatureRequests'>
97
+ <div id='WPGMFeatureRequestsInner'>
98
+
99
+ <div style='background-color:#fff; padding:10px;'>
100
+ <h4><?php _e("Latest Feature Requests", "wp-google-maps"); ?></h4>
101
+ <?php
102
+ WPGMZA\Plugin::output_rss_feed(array('http://wpgmaps.com/public-feeds/latest-feature-requests'), 5, true, true, 100);
103
+ ?>
104
+ <p><a href='https://www.wpgmaps.com/forums/forum/suggestions/' class='button button-primary' target='_BLANK'>Submit a request</a></p>
105
+ </div>
106
+
107
+
108
+ </div>
109
+
110
+ </div>
111
+ <div id='WPGMLatestTopics'>
112
+ <div id='WPGMLatestTopicsInner'>
113
+
114
+ <div style='background-color:#fff; padding:10px;'>
115
+ <h4><?php _e("Latest Forum Topics", "wp-google-maps"); ?></h4>
116
+ <?php
117
+ WPGMZA\Plugin::output_rss_feed(array('http://wpgmaps.com/public-feeds/latest-forum-topics'), 5, true, true, 100);
118
+ ?>
119
+ <p><a href='https://www.wpgmaps.com/forums/' class='button button-primary' target='_BLANK'>Create a ticket</a></p>
120
+ </div>
121
+
122
+ </div>
123
+
124
+ </div>
125
  </div> */
html/newsletter-opt-in.html.php CHANGED
@@ -1,31 +1,31 @@
1
- <?php
2
-
3
- if(!defined('ABSPATH'))
4
- exit;
5
-
6
- ?>
7
-
8
- <div id="wpgmza-welcome-page" class="wrap about-wrap">
9
- <p>&nbsp;</p>
10
-
11
- <img style="width: 512px;" src="<?php echo WPGMZA_PLUGIN_DIR_URL . 'images/new-banner.png'; ?>" alt="WP Google Maps"/>
12
-
13
- <div class="about-text"><?php _e("Thank you for joining our newsletter!","wp-google-maps"); ?></div>
14
-
15
- <p><?php printf(__("Your email address (%s) has been sent to our server and automatically added to our mailing list","wp-google-maps"), get_option('admin_email')); ?></p>
16
-
17
- <a class="button-primary" href="javascript:window.close();">Close Window</a>
18
-
19
- <p>&nbsp;</p>
20
- </div>
21
-
22
- <script type="text/javascript">
23
- !function(){if(!window.EncTracking||!window.EncTracking.started){window.EncTracking=Object.assign({}, window.EncTracking, {queue:window.EncTracking&&window.EncTracking.queue?window.EncTracking.queue:[],track:function(t){this.queue.push({type:"track",props:t})},identify:function(t){this.queue.push({type:"identify",props:t})},started:!0});var t=window.EncTracking;t.writeKey="fC5wJAMVagrn9oy7erfLfb1Kx",t.hasOptedIn=true,t.shouldGetConsent=true,t.hasOptedIn&&(t.shouldGetConsent=!1),t.optIn=function(){t.hasOptedIn=!0,t&&t.init()},t.optOut=function(){t.hasOptedIn=!1,t&&t.setOptOut&&t.setOptOut(!0)};var n=function(t){var n=document.createElement("script");n.type="text/javascript",n.async=void 0===t||t,n.src="https://resources-app.encharge.io/encharge-tracking.min.js";var e=document.getElementsByTagName("script")[0];e.parentNode.insertBefore(n,e)};"complete"===document.readyState?n():window.attachEvent?window.attachEvent("onload",n):window.addEventListener("load",n,!1)}}();
24
- </script>
25
-
26
- <script>
27
- EncTracking.identify({
28
- email: "<?php echo get_option('admin_email'); ?>",
29
- tags: "Free"
30
- });
31
  </script>
1
+ <?php
2
+
3
+ if(!defined('ABSPATH'))
4
+ exit;
5
+
6
+ ?>
7
+
8
+ <div id="wpgmza-welcome-page" class="wrap about-wrap">
9
+ <p>&nbsp;</p>
10
+
11
+ <img style="width: 512px;" src="<?php echo WPGMZA_PLUGIN_DIR_URL . 'images/new-banner.png'; ?>" alt="WP Google Maps"/>
12
+
13
+ <div class="about-text"><?php _e("Thank you for joining our newsletter!","wp-google-maps"); ?></div>
14
+
15
+ <p><?php printf(__("Your email address (%s) has been sent to our server and automatically added to our mailing list","wp-google-maps"), get_option('admin_email')); ?></p>
16
+
17
+ <a class="button-primary" href="javascript:window.close();">Close Window</a>
18
+
19
+ <p>&nbsp;</p>
20
+ </div>
21
+
22
+ <script type="text/javascript">
23
+ !function(){if(!window.EncTracking||!window.EncTracking.started){window.EncTracking=Object.assign({}, window.EncTracking, {queue:window.EncTracking&&window.EncTracking.queue?window.EncTracking.queue:[],track:function(t){this.queue.push({type:"track",props:t})},identify:function(t){this.queue.push({type:"identify",props:t})},started:!0});var t=window.EncTracking;t.writeKey="fC5wJAMVagrn9oy7erfLfb1Kx",t.hasOptedIn=true,t.shouldGetConsent=true,t.hasOptedIn&&(t.shouldGetConsent=!1),t.optIn=function(){t.hasOptedIn=!0,t&&t.init()},t.optOut=function(){t.hasOptedIn=!1,t&&t.setOptOut&&t.setOptOut(!0)};var n=function(t){var n=document.createElement("script");n.type="text/javascript",n.async=void 0===t||t,n.src="https://resources-app.encharge.io/encharge-tracking.min.js";var e=document.getElementsByTagName("script")[0];e.parentNode.insertBefore(n,e)};"complete"===document.readyState?n():window.attachEvent?window.attachEvent("onload",n):window.addEventListener("load",n,!1)}}();
24
+ </script>
25
+
26
+ <script>
27
+ EncTracking.identify({
28
+ email: "<?php echo get_option('admin_email'); ?>",
29
+ tags: "Free"
30
+ });
31
  </script>
html/settings-page.html.php CHANGED
@@ -1,1611 +1,1611 @@
1
- <form
2
- method="POST"
3
- id="wpgmza-global-settings"
4
- class="wpgmza-form"
5
- action="<?php
6
- echo admin_url('admin-post.php');
7
- ?>"
8
- >
9
-
10
- <input
11
- type="hidden"
12
- name="action"
13
- value="wpgmza_save_settings"
14
- />
15
-
16
- <ul class='settings-tabs-nav'>
17
- <li>
18
- <a href="#general-settings">
19
- <?php esc_html_e('General Settings', 'wp-google-maps'); ?>
20
- </a>
21
- </li>
22
- <li>
23
- <a href="#info-windows">
24
- <?php esc_html_e('InfoWindows', 'wp-google-maps'); ?>
25
- </a>
26
- </li>
27
- <li>
28
- <a href="#marker-listing">
29
- <?php esc_html_e('Marker Listing', 'wp-google-maps'); ?>
30
- </a>
31
- </li>
32
- <li>
33
- <a href="#store-locator">
34
- <?php esc_html_e('Store Locator', 'wp-google-maps'); ?>
35
- </a>
36
- </li>
37
- <li>
38
- <a href="#advanced-settings">
39
- <?php esc_html_e('Advanced Settings', 'wp-google-maps'); ?>
40
- </a>
41
- </li>
42
- <li>
43
- <a href="#gdpr-compliance">
44
- <?php esc_html_e('GDPR Compliance', 'wp-google-maps'); ?>
45
- </a>
46
- </li>
47
- </ul>
48
-
49
- <div id="general-settings">
50
-
51
- <fieldset>
52
- <legend>
53
- <?php esc_html_e('Maps Engine', 'wp-google-maps'); ?>
54
- </legend>
55
- <select name="wpgmza_maps_engine" id="wpgmza_maps_engine">
56
- <option value="google-maps"><?php esc_html_e('Google Maps', 'wp-google-maps'); ?></option>
57
- <option value="open-layers"><?php esc_html_e('OpenLayers', 'wp-google-maps'); ?></option>
58
- </select>
59
- </fieldset>
60
-
61
- <fieldset>
62
- <legend>
63
- <?php esc_html_e('General Map Settings', 'wp-google-maps'); ?>
64
- </legend>
65
-
66
- <div role="group">
67
- <label>
68
- <div>
69
- <input name="wpgmza_settings_map_full_screen_control" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
70
- <?php esc_html_e('Disable Full Screen Control', 'wp-google-maps'); ?>
71
- </div>
72
- </label>
73
-
74
- <label data-required-maps-engine="google-maps">
75
- <div>
76
- <input name="wpgmza_settings_map_streetview" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
77
- <?php esc_html_e('Disable StreetView', 'wp-google-maps'); ?>
78
- </div>
79
- </label>
80
-
81
- <label>
82
- <div>
83
- <input name="wpgmza_settings_map_zoom" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
84
- <?php esc_html_e('Disable Zoom Controls', 'wp-google-maps'); ?>
85
- </div>
86
- </label>
87
-
88
- <label data-required-maps-engine="google-maps">
89
- <div>
90
- <input name="wpgmza_settings_map_pan" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
91
- <?php esc_html_e('Disable Pan Controls', 'wp-google-maps'); ?>
92
- </div>
93
- </label>
94
-
95
- <label data-required-maps-engine="google-maps">
96
- <div>
97
- <input name="wpgmza_settings_map_type" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
98
- <?php esc_html_e('Disable Map Type Controls', 'wp-google-maps'); ?>
99
- </div>
100
- </label>
101
-
102
- <label data-required-maps-engine="google-maps">
103
- <div>
104
- <input name="wpgmza_settings_map_tilt_controls" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
105
- <?php esc_html_e('Disable Tilt Controls', 'wp-google-maps'); ?>
106
- </div>
107
- </label>
108
-
109
- <label>
110
- <div>
111
- <input name="wpgmza_settings_map_scroll" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
112
- <?php esc_html_e('Disable Mouse Wheel Zoom', 'wp-google-maps'); ?>
113
- </div>
114
- </label>
115
-
116
- <label>
117
- <div>
118
- <input name="wpgmza_settings_map_draggable" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
119
- <?php esc_html_e('Disable Mouse Dragging', 'wp-google-maps'); ?>
120
- </div>
121
- </label>
122
-
123
- <label>
124
- <div>
125
- <input name="wpgmza_settings_map_clickzoom" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
126
- <?php esc_html_e('Disable Mouse Double Click Zooming', 'wp-google-maps'); ?>
127
- </div>
128
- </label>
129
-
130
- </div>
131
- </fieldset>
132
-
133
- <fieldset>
134
- <legend>
135
- <?php esc_html_e('User Interface Style', 'wp-google-maps'); ?>
136
- (<em><a href='https://www.wpgmaps.com/documentation/user-interface-style-options/' target='_BLANK'><?php esc_html_e('examples', 'wp-google-maps'); ?></a></em>)
137
- </legend>
138
-
139
- <ul>
140
- <li>
141
- <label>
142
- <input type='radio'
143
- name='user_interface_style'
144
- value='default'
145
- checked="checked"/>
146
- <?php
147
- _e("<strong>Default</strong> - The default front end.", "wp-google-maps")
148
- ?>
149
- </label>
150
- </li>
151
- <li>
152
- <label>
153
- <input type='radio'
154
- name='user_interface_style'
155
- value='modern'/>
156
- <?php
157
- _e("<strong>Modern</strong> - Puts components inside the map, with pull-out panels.", "wp-google-maps")
158
- ?>
159
- </label>
160
- </li>
161
- <li>
162
- <label>
163
- <input type='radio'
164
- name='user_interface_style'
165
- value='legacy'/>
166
- <?php
167
- _e("<strong>Legacy</strong> - This setting is the same as Default, but provides options to change individual components to the modern style.", "wp-google-maps")
168
- ?>
169
- </label>
170
- </li>
171
- <li>
172
- <label>
173
- <input type='radio'
174
- name='user_interface_style'
175
- value='compact'/>
176
- <?php
177
- _e("<strong>Compact</strong> - Puts all components and their labels inline.", "wp-google-maps")
178
- ?>
179
- </label>
180
- </li>
181
- <li>
182
- <label>
183
- <input type='radio'
184
- name='user_interface_style'
185
- value='minimal'/>
186
- <?php
187
- _e("<strong>Minimal</strong> - The same as Compact, but with icons instead of text labels.", "wp-google-maps");
188
- ?>
189
- </label>
190
- </li>
191
- <li>
192
- <label>
193
- <input type='radio'
194
- name='user_interface_style'
195
- value='bare-bones'/>
196
- <?php
197
- _e("<strong>Bare Bones</strong> - Applies no styling to the components at all. This is recommended for designers and developers who want to style the components from scratch.", "wp-google-maps")
198
- ?>
199
- </label>
200
- </li>
201
- </ul>
202
-
203
- </fieldset>
204
-
205
- <fieldset>
206
- <legend>
207
- <?php esc_html_e('Category Selection Logic', 'wp-google-maps'); ?>
208
- </legend>
209
- <ul>
210
- <li>
211
- <label>
212
- <input name='wpgmza_settings_cat_logic' type='radio' id='wpgmza_settings_cat_logic_or' value='0' checked="checked" />
213
- <?php echo __("OR"," wp-google-maps") . " &nbsp; (<span class='description'>" . __("Example: Show the marker if it belongs to Cat A _OR_ Cat B.", "wp-google-maps") . "</span>)"; ?>
214
- </label>
215
- </li>
216
-
217
- <li>
218
- <label>
219
- <input name='wpgmza_settings_cat_logic' type='radio' id='wpgmza_settings_cat_logic_and' value='1'/>
220
- <?php echo __("AND"," wp-google-maps") . " &nbsp; (<span class='description'>" . __("Example: Only show the marker if it belongs to Cat A _AND_ Cat B.", "wp-google-maps") . "</span>)"; ?>
221
- </label>
222
- </li>
223
- </ul>
224
- </fieldset>
225
-
226
- <fieldset>
227
- <legend>
228
- <?php esc_html_e('Filter by category displayed as', 'wp-google-maps'); ?>
229
- </legend>
230
- <ul>
231
- <li>
232
- <label>
233
- <input name='wpgmza_settings_filterbycat_type' type='radio' id='wpgmza_settings_filterbycat_type_dropdown' value='1' checked="checked" />
234
- <?php _e("Dropdown","wp-google-maps"); ?>
235
- </label>
236
- </li>
237
- <li>
238
- <label>
239
- <input name='wpgmza_settings_filterbycat_type' type='radio' id='wpgmza_settings_filterbycat_type_checkboxes' value='2' />
240
- <?php _e("Checkboxes","wp-google-maps"); ?>
241
- </label>
242
- </li>
243
- </ul>
244
- </fieldset>
245
-
246
-
247
- <!--<fieldset>
248
- <legend>
249
- <?php esc_html_e('Troubleshooting Options', 'wp-google-maps'); ?>
250
- </legend>
251
-
252
- <label>
253
- <input name="wpgmza_settings_force_jquery" class="wpgmza-fancy-toggle-button" type="checkbox"/>
254
- <?php
255
- esc_html_e("Over-ride current jQuery with version 1.11.3 (Tick this box if you are receiving jQuery related errors after updating to WordPress 4.5)", 'wp-google-maps');
256
- ?>
257
- </label>
258
-
259
- <label data-required-maps-engine="google-maps">
260
- <input name="wpgmza_settings_remove_api" class="wpgmza-fancy-toggle-button" type="checkbox"/>
261
- <?php
262
- esc_html_e("Do not load the Google Maps API (Only check this if your theme loads the Google Maps API by default)", 'wp-google-maps');
263
- ?>
264
- </label>
265
- </fieldset>-->
266
-
267
- <fieldset>
268
- <legend>
269
- <?php esc_html_e('Use FontAwesome', 'wp-google-maps'); ?>
270
- </legend>
271
- <select name='use_fontawesome'>
272
- <option value='4.*'>4.*</option>
273
- <option value='5.*'>5.*</option>
274
- <option value='none'><?php esc_html_e("None", "wp-google-maps"); ?></option>
275
- </select>
276
- </fieldset>
277
-
278
-
279
-
280
- <fieldset data-required-maps-engine="open-layers">
281
- <legend>
282
- <?php esc_html_e('Tile Server URL', 'wp-google-maps'); ?>
283
- </legend>
284
- <select name="tile_server_url">
285
-
286
- <option
287
- value="https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png"
288
- data-usage-policy="https://wiki.openstreetmap.org/wiki/Tile_usage_policy">
289
- <?php
290
- _e('OpenStreetMap', 'wp-google-maps');
291
- ?>
292
- </option>
293
-
294
- <option
295
- value="https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png"
296
- data-usage-policy="https://foundation.wikimedia.org/wiki/Maps_Terms_of_Use"
297
- data-preview-image="https://wiki.openstreetmap.org/w/images/0/02/Wikimedia-tile.png">
298
- <?php
299
- _e('Wikimedia Maps', 'wp-google-maps');
300
- ?>
301
- </option>
302
-
303
- <option value="https://tile.thunderforest.com/cycle/{z}/{x}/{y}.png"
304
- data-preview-image="https://b.tile.opencyclemap.org/cycle/16/33199/22539.png">
305
- <?php
306
- _e('OpenCycleMap *', 'wp-google-maps');
307
- ?>
308
- </option>
309
-
310
- <option value="https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png"
311
- data-preview-image="https://wiki.openstreetmap.org/w/images/6/63/Humanitarian_style.png">
312
- <?php
313
- _e('Humanitarian', 'wp-google-maps');
314
- ?>
315
- </option>
316
-
317
- <option value="https://{a-c}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png"
318
- data-preview-image="https://a.www.toolserver.org/tiles/bw-mapnik/9/264/179.png">
319
- <?php
320
- _e('Mapnik OSM B&amp;W', 'wp-google-maps');
321
- ?>
322
- </option>
323
-
324
- <option value="https://tiles.wmflabs.org/osm-no-labels/{z}/{x}/{y}.png"
325
- data-preview-image="https://c.tiles.wmflabs.org/osm-no-labels/14/7452/6839.png">
326
- <?php
327
- _e('Mapnik OSM No Labels', 'wp-google-maps');
328
- ?>
329
- </option>
330
-
331
- <option value="https://a.tile.stamen.com/toner/{z}/{x}/{y}.png"
332
- data-preview-image="https://a.tile.stamen.com/toner/10/529/366.png">
333
- <?php
334
- _e('Stamen Toner', 'wp-google-maps');
335
- ?>
336
- </option>
337
-
338
- <option value="http://c.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg"
339
- data-preview-image="http://wiki.openstreetmap.org/w/images/d/d2/Tile_watercolor_stamen.jpg">
340
- <?php
341
- _e('Stamen Watercolor', 'wp-google-maps');
342
- ?> (No SSL)
343
- </option>
344
-
345
- <option value="https://tile.thunderforest.com/transport/{z}/{x}/{y}.png"
346
- data-preview-image="https://a.tile2.opencyclemap.org/transport/13/4150/2819.png">
347
- <?php
348
- _e('Transport Map *', 'wp-google-maps');
349
- ?>
350
- </option>
351
-
352
- <option value="https://tile.thunderforest.com/landscape/{z}/{x}/{y}.png"
353
- data-preview-image="https://a.tile.thunderforest.com/landscape/14/4773/6144.png">
354
- <?php
355
- _e('Thunderforest Landscape *', 'wp-google-maps');
356
- ?>
357
- </option>
358
-
359
- <option value="https://tile.thunderforest.com/outdoors/{z}/{x}/{y}.png"
360
- data-preview-image="https://a.tile.thunderforest.com/outdoors/14/4772/6144.png">
361
- <?php
362
- _e('Thunderforest Outdoors *', 'wp-google-maps');
363
- ?>
364
- </option>
365
-
366
- <option value="https://tile.memomaps.de/tilegen/{z}/{x}/{y}.png"
367
- data-preview-image="https://tile.memomaps.de/tilegen/12/2200/1343.png">
368
- <?php
369
- _e('Öpnvkarte', 'wp-google-maps');
370
- ?>
371
- </option>
372
-
373
- <option value="http://www.openptmap.org/tiles/{z}/{x}/{y}.png"
374
- data-preview-image="http://www.openptmap.org/tiles//10/529/366.png">
375
- <?php
376
- _e('OpenPtMap', 'wp-google-maps');
377
- ?> (No SSL)
378
- </option>
379
-
380
- <option value="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png">
381
- <?php
382
- _e('Carto Light (Positron) *', 'wp-google-maps');
383
- ?>
384
- </option>
385
-
386
- <option value="https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png"
387
- data-preview-image="https://wiki.openstreetmap.org/w/images/b/ba/Cartodb_dark_tile.png">
388
- <?php
389
- _e('Carto Dark (Dark Matter) *', 'wp-google-maps');
390
- ?>
391
- </option>
392
-
393
- <option value="https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png">
394
- <?php
395
- _e('MapTiler Streets *', 'wp-google-maps');
396
- ?>
397
- </option>
398
-
399
- <option value="https://api.maptiler.com/maps/outdoor/{z}/{x}/{y}.png">
400
- <?php
401
- _e('MapTiler Outdoor *', 'wp-google-maps');
402
- ?>
403
- </option>
404
-
405
- <option value="https://api.maptiler.com/maps/pastel/{z}/{x}/{y}.png">
406
- <?php
407
- _e('MapTiler Pastel *', 'wp-google-maps');
408
- ?>
409
- </option>
410
-
411
- <option value="https://api.maptiler.com/maps/basic/{z}/{x}/{y}.png">
412
- <?php
413
- _e('MapTiler Basic *', 'wp-google-maps');
414
- ?>
415
- </option>
416
-
417
- <option value="https://caltopo.com/tile/mb_topo/{z}/{x}/{y}.png">
418
- <?php
419
- _e('Caltopo *', 'wp-google-maps');
420
- ?>
421
- </option>
422
-
423
- <option value="custom_override">
424
- <?php
425
- _e('Other (Enter URL)', 'wp-google-maps');
426
- ?>
427
- </option>
428
-
429
- </select>
430
- <small>&nbsp; * <?php _e("You can add an API key under the Advanced Settings tab if required by your TileServer provider", "wp-google-maps"); ?></small>
431
- </fieldset>
432
-
433
- <fieldset data-required-maps-engine="open-layers">
434
- <legend class='wpgmza_tile_server_override_component wpgmza-hidden'><?php _e('Custom Tile Server URL', 'wp-google-maps'); ?></legend>
435
- <input class='wpgmza_tile_server_override_component wpgmza-hidden' name="tile_server_url_override" placeholder="https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
436
- </fieldset>
437
-
438
- <fieldset data-required-maps-engine="google-maps">
439
- <legend>
440
- <?php _e('Load Maps Engine API', 'wp-google-maps'); ?>
441
- </legend>
442
- <select name="wpgmza_load_engine_api_condition">
443
- <option value="where-required">
444
- <?php
445
- _e('Where required', 'wp-google-maps');
446
- ?>
447
- </option>
448
- <option value="always">
449
- <?php
450
- _e('Always', 'wp-google-maps');
451
- ?>
452
- </option>
453
- <option value="only-front-end">
454
- <?php
455
- _e('Only Front End', 'wp-google-maps');
456
- ?>
457
- </option>
458
- <option value="only-back-end">
459
- <?php
460
- _e('Only Back End', 'wp-google-maps');
461
- ?>
462
- </option>
463
- <option value="never">
464
- <?php
465
- _e('Never', 'wp-google-maps');
466
- ?>
467
- </option>
468
- </select>
469
- </fieldset>
470
-
471
- <fieldset>
472
- <legend><?php _e('Always include engine API on pages', 'wp-google-maps'); ?></legend>
473
- <input name="wpgmza_always_include_engine_api_on_pages" placeholder="<?php _e('Page IDs'); ?>"/>
474
- </fieldset>
475
-
476
- <fieldset>
477
- <legend><?php _e('Always exclude engine API on pages', 'wp-google-maps'); ?></legend>
478
- <input name="wpgmza_always_exclude_engine_api_on_pages" placeholder="<?php _e('Page IDs'); ?>"/>
479
- </fieldset>
480
-
481
- <fieldset>
482
- <legend><?php _e('Prevent other plugins and theme loading API', 'wp-google-maps'); ?></legend>
483
- <input name="wpgmza_prevent_other_plugins_and_theme_loading_api" type="checkbox"/>
484
- <small>
485
- <?php
486
- _e("Use this setting if you are experiencing Google Maps API issues, such as invalid key warnings, or Multiple API warnings", "wp-google-maps");
487
- ?>
488
- </small>
489
- </fieldset>
490
-
491
- <fieldset>
492
- <legend><?php _e("Lowest level of access to the map editor","wp-google-maps"); ?></legend>
493
- <select name="wpgmza_settings_access_level">
494
- <option value="manage_options"><?php _e('Admin', 'wp-google-maps'); ?></option>
495
- <option value="edit_pages"><?php _e('Editor', 'wp-google-maps'); ?></option>
496
- <option value="edit_published_posts"><?php _e('Author', 'wp-google-maps'); ?></option>
497
- <option value="edit_posts"><?php _e('Contributor', 'wp-google-maps'); ?></option>
498
- <option value="read"><?php _e('Subscriber', 'wp-google-maps'); ?></option>
499
- </select>
500
- </fieldset>
501
-
502
- <fieldset>
503
- <legend><?php _e("Retina Icon Width","wp-google-maps"); ?></legend>
504
- <span class="settings-group">
505
- <input name='wpgmza_settings_retina_width' type='text' size='4' maxlength='4' id='wpgmza_settings_retina_width'/> px
506
- </span>
507
- </fieldset>
508
- <fieldset>
509
- <legend><?php _e("Retina Icon Height","wp-google-maps"); ?></legend>
510
- <span class="settings-group">
511
- <input name='wpgmza_settings_retina_height' type='text' size='4' maxlength='4' id='wpgmza_settings_retina_height'/> px
512
- </span>
513
- </fieldset>
514
-
515
-
516
- <!-- NB: Usage tracking dropped as of 2018 GDPR changes -->
517
-
518
- <fieldset>
519
- <legend><?php _e("Greedy Gesture Handling","wp-google-maps"); ?></legend>
520
- <input name="wpgmza_force_greedy_gestures" type="checkbox"/>
521
- <small>
522
- <?php
523
- _e("Check this setting to disable two finger pan on mobiles, and Ctrl + Zoom on desktops. Enabling this setting will allow one finger panning on mobiles, and will enable zoom without Ctrl on desktops.", "wp-google-maps");
524
- ?>
525
- </small>
526
- </fieldset>
527
-
528
- <fieldset class="wpgmza-pro-feature wpgmza-pro-feature-hide">
529
- <legend>
530
- <?php
531
- _e("Disable Lightbox", "wp-google-maps");
532
- ?>
533
- </legend>
534
- <input name="disable_lightbox_images" type="checkbox"/>
535
- <small>
536
- <?php
537
- _e("Prevents the larger image lightbox from opening up when pictures in the infowindow or marker listing are clicked", "wp-google-maps");
538
- ?>
539
- </small>
540
- </fieldset>
541
- </div>
542
-
543
- <div id="info-windows">
544
-
545
- <fieldset class="wpgmza-pro-feature-hide">
546
- <legend>
547
- <?php
548
- _e("Infowindow Style", "wp-google-maps");
549
- ?>
550
- </legend>
551
-
552
-
553
- <div class='wpgmza-infowindow-style-picker wpgmza-flex'>
554
-
555
- <label>
556
- <input type="radio" name="wpgmza_iw_type" value="0" class="wpgmza-pro-feature"/>
557
- <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_hide'>
558
- <div class="wpgmza-card wpgmza-card-border__hover">
559
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_1.png'; ?>"
560
- title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
561
- class="wpgmza_mlist_selection"
562
- />
563
- <span class='wpgmza-infowindow-style__name'>
564
- <?php
565
- _e('Default Infowindow', 'wp-google-maps');
566
- ?>
567
- </span>
568
- </div>
569
- </div>
570
- </label>
571
-
572
- <label>
573
- <input type="radio" name="wpgmza_iw_type" value="1" class="wpgmza-pro-feature"/>
574
- <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_show'>
575
- <div class="wpgmza-card wpgmza-card-border__hover">
576
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_2.png'; ?>"
577
- title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
578
- class="wpgmza_mlist_selection"
579
- />
580
- <span class='wpgmza-infowindow-style__name'>
581
- <?php
582
- _e('Modern Infowindow', 'wp-google-maps');
583
- ?>
584
- </span>
585
- </div>
586
- </div>
587
- </label>
588
-
589
- <label>
590
- <input type="radio" name="wpgmza_iw_type" value="2" class="wpgmza-pro-feature"/>
591
- <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_show'>
592
- <div class="wpgmza-card wpgmza-card-border__hover">
593
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_3.png'; ?>"
594
- title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
595
- class="wpgmza_mlist_selection"
596
- />
597
- <span class='wpgmza-infowindow-style__name'>
598
- <?php
599
- _e('Modern Plus Infowindow', 'wp-google-maps');
600
- ?>
601
- </span>
602
- </div>
603
- </div>
604
- </label>
605
-
606
- <label>
607
- <input type="radio" name="wpgmza_iw_type" value="3" class="wpgmza-pro-feature"/>
608
- <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_show'>
609
- <div class="wpgmza-card wpgmza-card-border__hover">
610
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_4.png'; ?>"
611
- title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
612
- class="wpgmza_mlist_selection"
613
- />
614
- <span class='wpgmza-infowindow-style__name'>
615
- <?php
616
- _e('Circular Infowindow', 'wp-google-maps');
617
- ?>
618
- </span>
619
- </div>
620
- </div>
621
- </label>
622
-
623
-
624
- <label>
625
- <input type="radio" name="wpgmza_iw_type" value="-1" class="wpgmza-pro-feature"/>
626
- <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_hide'>
627
- <div class="wpgmza-card wpgmza-card-border__hover">
628
- <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_inherit.png'; ?>"
629
- title="<?php esc_attr_e('No Global Setting', 'wp-google-maps'); ?>"
630
- class="wpgmza_mlist_selection"
631
- />
632
-
633
- <span class='wpgmza-infowindow-style__name'>
634
- <?php
635
- _e('No Global Setting', 'wp-google-maps');
636
- ?>
637
- </span>
638
- </div>
639
- </div>
640
- </label>
641
- </div>
642
- </fieldset>
643
-
644
- <fieldset class="wpgmza-pro-feature-hide">
645
- <legend><?php _e("Resize Images", "wp-google-maps"); ?></legend>
646
-
647
- <div class='switch'>
648
- <input name='wpgmza_settings_image_resizing'
649
- class='cmn-toggle cmn-toggle-round-flat'
650
- type='checkbox'
651
- id='wpgmza_settings_image_resizing' value='yes'/>
652
- <label for='wpgmza_settings_image_resizing'>
653
- </label>
654
- </div>
655
- <?php
656
- esc_html_e("Resize all images to the below sizes","wp-google-maps");
657
- ?>
658
-
659
- </fieldset>
660
-
661
- <fieldset class="wpgmza-pro-feature-hide">
662
- <legend><?php _e("Default Image Width", "wp-google-maps"); ?></legend>
663
-
664
- <input name='wpgmza_settings_image_width' type='text' size='4' maxlength='4' id='wpgmza_settings_image_width'/>
665
- <em><?php esc_html_e("(can be left blank - max width will be limited to max infowindow width)","wp-google-maps"); ?></em>
666
- </fieldset>
667
-
668
- <fieldset class="wpgmza-pro-feature-hide">
669
- <legend><?php _e("Default Image Height", "wp-google-maps"); ?></legend>
670
-
671
- <input name='wpgmza_settings_image_height' type='text' size='4' maxlength='4' id='wpgmza_settings_image_height'/>
672
- <em><?php esc_html_e("(can be left blank - leaving both the width and height blank will revert to full size images being used)","wp-google-maps"); ?></em>
673
- </fieldset>
674
-
675
- <fieldset class="wpgmza-pro-feature-hide">
676
- <legend><?php _e("Max InfoWindow Width", "wp-google-maps"); ?></legend>
677
-
678
- <input name='wpgmza_settings_infowindow_width' type='text' size='4' maxlength='4' id='wpgmza_settings_infowindow_width'/>
679
- <em><?php esc_html_e("(can be left blank - leaving both the width and height blank will revert to full size images being used)","wp-google-maps"); ?></em>
680
- </fieldset>
681
-
682
- <fieldset class="wpgmza-pro-feature-hide">
683
- <legend><?php _e("Other settings", "wp-google-maps"); ?></legend>
684
-
685
- <ul>
686
- <li>
687
- <div class='switch'>
688
- <input name='wpgmza_settings_infowindow_links'
689
- class='cmn-toggle cmn-toggle-round-flat'
690
- type='checkbox'
691
- id='wpgmza_settings_infowindow_links'
692
- value='yes'/>
693
- <label for='wpgmza_settings_infowindow_links'></label>
694
- </div>
695
- <?php
696
- esc_html_e("Open links in a new window ","wp-google-maps");
697
- ?><em><?php esc_html_e("(Tick this if you want to open your links in a new window)","wp-google-maps"); ?></em>
698
- </li>
699
- <li>
700
- <div class='switch'>
701
- <input name='wpgmza_settings_infowindow_address'
702
- class='cmn-toggle cmn-toggle-round-flat'
703
- type='checkbox'
704
- id='wpgmza_settings_infowindow_address'
705
- value='yes'/>
706
- <label for='wpgmza_settings_infowindow_address'></label>
707
- </div>
708
- <?php
709
- esc_html_e("Hide the address field","wp-google-maps");
710
- ?>
711
- </li>
712
- </ul>
713
- </fieldset>
714
-
715
- <fieldset class="wpgmza-pro-feature-hide">
716
- <legend><?php _e("Link text", "wp-google-maps"); ?></legend>
717
-
718
- <input name='wpgmza_settings_infowindow_link_text' type='text' id='wpgmza_settings_infowindow_link_text'/>
719
- </fieldset>
720
-
721
- <fieldset>
722
- <legend><?php _e("Open Marker InfoWindows by", "wp-google-maps"); ?></legend>
723
-
724
- <ul>
725
- <li>
726
- <label>
727
- <input name="wpgmza_settings_map_open_marker_by" value="1" type="radio" checked="checked"/>
728
- <?php _e('Click', 'wp-google-maps'); ?>
729
- </label>
730
- </li>
731
- <li>
732
- <label>
733
- <input name="wpgmza_settings_map_open_marker_by" value="2" type="radio"/>
734
- <?php _e('Hover', 'wp-google-maps'); ?>
735
- </label>
736
- </li>
737
- </ul>
738
- </fieldset>
739
-
740
- <fieldset>
741
- <legend><?php _e('Disable InfoWindows', 'wp-google-maps'); ?></legend>
742
- <input name="wpgmza_settings_disable_infowindows" type="checkbox"/>
743
- <small>
744
- <?php
745
- _e("Enabling this setting will prevent any infowindows from opening for all your maps", "wp-google-maps");
746
- ?>
747
- </small>
748
- </fieldset>
749
- </div>
750
-
751
- <!-- class="wpgmza-pro-feature" -->
752
- <div id="marker-listing">
753
-
754
- <h3>
755
- <?php
756
- esc_html_e("Marker Listing Settings","wp-google-maps");
757
- ?>
758
- </h3>
759
-
760
- <p>
761
- <?php
762
- esc_html_e("Changing these settings will alter the way the marker list appears on your website.","wp-google-maps");
763
- ?>
764
- </p>
765
-
766
- <div class="update-nag update-att wpgmza-upsell">
767
- <i class="fa fa-arrow-circle-right"></i>
768
- <a target="_blank"
769
- href="<?php
770
-
771
- echo esc_attr(\WPGMZA\Plugin::getProLink("https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=mlisting_settings"));
772
-
773
- ?>">
774
-
775
- <?php _e('Add Beautiful Marker Listings
776
- </a>
777
- to your maps with the Pro version for only $39.99 once off. Support and updates included forever.', 'wp-google-maps');
778
- ?>
779
-
780
- </div>
781
-
782
- <h4>
783
- <?php
784
- esc_html_e("Advanced Marker Listing","wp-google-maps");
785
- ?>
786
- &amp;
787
- <?php
788
- esc_html_e("Basic Marker Listings","wp-google-maps");
789
- ?>
790
- </h4>
791
-
792
- <fieldset class="wpgmza-pro-feature">
793
-
794
- <legend>
795
- <?php
796
- _e("Column Visibility", "wp-google-maps");
797
- ?>
798
- </legend>
799
-
800
- <ul>
801
- <li>
802
- <div class='switch'>
803
- <input name='wpgmza_settings_markerlist_icon'
804
- class='cmn-toggle cmn-toggle-round-flat'
805
- type='checkbox'
806
- id='wpgmza_settings_markerlist_icon' value='yes'/>
807
-
808
- <label for='wpgmza_settings_markerlist_icon'></label>
809
- </div>
810
- <?php
811
- esc_html_e("Hide the Icon column","wp-google-maps");
812
- ?>
813
- </li>
814
-
815
- <li>
816
- <div class='switch'>
817
- <input name='wpgmza_settings_markerlist_link'
818
- class='cmn-toggle cmn-toggle-round-flat'
819
- type='checkbox'
820
- id='wpgmza_settings_markerlist_link'
821
- value='yes'/>
822
- <label for='wpgmza_settings_markerlist_link'></label>
823
- </div>
824
- <?php
825
- esc_html_e("Hide the Link column","wp-google-maps");
826
- ?>
827
- </li>
828
-
829
- <li>
830
- <div class='switch'>
831
- <input name='wpgmza_settings_markerlist_title'
832
- class='cmn-toggle cmn-toggle-round-flat'
833
- type='checkbox'
834
- id='wpgmza_settings_markerlist_title' value='yes'/>
835
- <label for='wpgmza_settings_markerlist_title'></label>
836
- </div>
837
- <?php
838
- esc_html_e("Hide the Title column","wp-google-maps");
839
- ?>
840
- </li>
841
-
842
- <li>
843
- <div class='switch'>
844
- <input name='wpgmza_settings_markerlist_address'
845
- class='cmn-toggle cmn-toggle-round-flat'
846
- type='checkbox'
847
- id='wpgmza_settings_markerlist_address'
848
- value='yes'/>
849
- <label for='wpgmza_settings_markerlist_address'></label>
850
- </div>
851
- <?php
852
- esc_html_e("Hide the Address column","wp-google-maps");
853
- ?>
854
- </li>
855
-
856
- <li>
857
- <div class='switch'>
858
- <input name='wpgmza_settings_markerlist_category'
859
- class='cmn-toggle cmn-toggle-round-flat'
860
- type='checkbox'
861
- id='wpgmza_settings_markerlist_category'
862
- value='yes'/>
863
- <label for='wpgmza_settings_markerlist_category'></label>
864
- </div>
865
- <?php
866
- esc_html_e("Hide the Category column","wp-google-maps");
867
- ?>
868
- </li>
869
-
870
- <li>
871
- <div class='switch'>
872
- <input name='wpgmza_settings_markerlist_description'
873
- class='cmn-toggle cmn-toggle-round-flat'
874
- type='checkbox'
875
- id='wpgmza_settings_markerlist_description'
876
- value='yes'/>
877
- <label for='wpgmza_settings_markerlist_description'></label>
878
- </div>
879
- <?php
880
- esc_html_e("Hide the Description column","wp-google-maps");
881
- ?>
882
- </li>
883
-
884
-
885
-
886
- </ul>
887
-
888
- </fieldset>
889
-
890
- <fieldset class="wpgmza-pro-feature">
891
-
892
- <legend>
893
- <?php
894
- _e("Dependencies", "wp-google-maps");
895
- ?>
896
- </legend>
897
-
898
- <ul>
899
- <li>
900
- <div class='switch'>
901
- <input name='wpgmza_do_not_enqueue_datatables'
902
- class='cmn-toggle cmn-toggle-round-flat'
903
- type='checkbox'
904
- id='wpgmza_do_not_enqueue_datatables'
905
- value='yes'/>
906
- <label for='wpgmza_do_not_enqueue_datatables'></label>
907
- </div>
908
- <?php
909
- esc_html_e("Do not Enqueue Datatables","wp-google-maps");
910
- ?>
911
- </li>
912
- </ul>
913
- </fieldset>
914
-
915
- <fieldset class="wpgmza-pro-feature">
916
- <legend>
917
- <?php
918
- esc_html_e("Show X items by default","wp-google-maps");
919
- ?>
920
- </legend>
921
-
922
- <select id='wpgmza_default_items' name='wpgmza_default_items'>
923
- <option value="5">5</option>
924
- <option value="10">10</option>
925
- <option value="25">25</option>
926
- <option value="50">50</option>
927
- <option value="100">100</option>
928
- <option value="-1">ALL</option>
929
- </select>
930
- </fieldset>
931
-
932
- <h4>
933
- <?php
934
- esc_html_e("Carousel Marker Listing","wp-google-maps");
935
- ?>
936
- </h4>
937
-
938
- <fieldset class="wpgmza-pro-feature">
939
- <legend>
940
- <?php
941
- esc_html_e("Theme selection","wp-google-maps");
942
- ?>
943
- </legend>
944
-
945
- <select id='wpgmza_settings_carousel_markerlist_theme'
946
- name='wpgmza_settings_carousel_markerlist_theme'>
947
- <option value="sky">
948
- <?php
949
- esc_html_e("Sky","wp-google-maps");
950
- ?>
951
- </option>
952
- <option value="sun">
953
- <?php
954
- esc_html_e("Sun","wp-google-maps");
955
- ?>
956
- </option>
957
- <option value="earth">
958
- <?php
959
- esc_html_e("Earth","wp-google-maps");
960
- ?>
961
- </option>
962
- <option value="monotone">
963
- <?php
964
- esc_html_e("Monotone","wp-google-maps");
965
- ?>
966
- </option>
967
- <option value="pinkpurple">
968
- <?php
969
- esc_html_e("PinkPurple","wp-google-maps"); ?>
970
- </option>
971
- <option value="white">
972
- <?php
973
- esc_html_e("White","wp-google-maps");
974
- ?>
975
- </option>
976
- <option value="black">
977
- <?php
978
- esc_html_e("Black","wp-google-maps");
979
- ?>
980
- </option>
981
- </select>
982
- </fieldset>
983
-
984
- <fieldset class="wpgmza-pro-feature">
985
- <legend>
986
- <?php
987
- _e("Field Visibility", "wp-google-maps");
988
- ?>
989
- </legend>
990
-
991
- <ul>
992
- <li>
993
- <div class='switch'><input name='wpgmza_settings_carousel_markerlist_image' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_image' value='yes'/><label for='wpgmza_settings_carousel_markerlist_image'></label></div>
994
- <?php esc_html_e("Hide the Image","wp-google-maps"); ?><br />
995
- </li>
996
-
997
- <li>
998
- <div class='switch'><input name='wpgmza_settings_carousel_markerlist_title' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_title' value='yes'/><label for='wpgmza_settings_carousel_markerlist_title'></label></div> <?php esc_html_e("Hide the Title","wp-google-maps"); ?>
999
- </li>
1000
-
1001
- <li>
1002
- <div class='switch'><input name='wpgmza_settings_carousel_markerlist_icon' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_icon' value='yes'/><label for='wpgmza_settings_carousel_markerlist_icon'></label></div> <?php esc_html_e("Hide the Marker Icon","wp-google-maps"); ?>
1003
- </li>
1004
-
1005
- <li>
1006
- <div class='switch'><input name='wpgmza_settings_carousel_markerlist_address' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_address' value='yes'/><label for='wpgmza_settings_carousel_markerlist_address'></label></div> <?php esc_html_e("Hide the Address","wp-google-maps"); ?>
1007
- </li>
1008
-
1009
- <li>
1010
- <div class='switch'><input name='wpgmza_settings_carousel_markerlist_description' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_description' value='yes'/><label for='wpgmza_settings_carousel_markerlist_description'></label></div> <?php esc_html_e("Hide the Description","wp-google-maps"); ?>
1011
- </li>
1012
-
1013
- <li>
1014
- <div class='switch'><input name='wpgmza_settings_carousel_markerlist_marker_link' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_marker_link' value='yes'/><label for='wpgmza_settings_carousel_markerlist_marker_link'></label></div> <?php esc_html_e("Hide the Marker Link","wp-google-maps"); ?>
1015
- </li>
1016
-
1017
- <li>
1018
- <div class='switch'><input name='wpgmza_settings_carousel_markerlist_directions' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_directions' value='yes'/><label for='wpgmza_settings_carousel_markerlist_directions'></label></div> <?php esc_html_e("Hide the Directions Link","wp-google-maps"); ?>
1019
- </li>
1020
- </ul>
1021
- </fieldset>
1022
-
1023
- <fieldset class="wpgmza-pro-feature">
1024
-
1025
- <legend>
1026
- <?php
1027
- esc_html_e("Image and Carousel options", "wp-google-maps");
1028
- ?>
1029
- </legend>
1030
-
1031
- <ul>
1032
- <li>
1033
- <div class='switch'><input name='wpgmza_settings_carousel_markerlist_resize_image' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_resize_image' value='yes'/><label for='wpgmza_settings_carousel_markerlist_resize_image'></label></div> <?php esc_html_e("Resize Images with Timthumb","wp-google-maps"); ?>
1034
- </li>
1035
-
1036
- <li>
1037
- <div class='switch'><input name='carousel_lazyload' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='carousel_lazyload' value='yes'/><label for='carousel_lazyload'></label></div> <?php esc_html_e("Enable lazyload of images","wp-google-maps"); ?>
1038
- </li>
1039
-
1040
- <li>
1041
- <div class='switch'><input name='carousel_autoheight' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='carousel_autoheight' value='yes'/><label for='carousel_autoheight'></label></div> <?php esc_html_e("Enable autoheight","wp-google-maps"); ?>
1042
- </li>
1043
-
1044
- <li>
1045
- <div class='switch'><input name='carousel_pagination' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='carousel_pagination' value='yes'/> <label for='carousel_pagination'></label></div><?php esc_html_e("Enable pagination","wp-google-maps"); ?>
1046
- </li>
1047
-
1048
- <li>
1049
- <div class='switch'><input name='carousel_navigation' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='carousel_navigation' value='yes'/><label for='carousel_navigation'></label></div> <?php esc_html_e("Enable navigation","wp-google-maps"); ?>
1050
- </li>
1051
-
1052
-
1053
- </ul>
1054
-
1055
- </fieldset>
1056
-
1057
- <fieldset class="wpgmza-pro-feature">
1058
-
1059
- <legend>
1060
- <?php
1061
- _e("Dependencies", "wp-google-maps");
1062
- ?>
1063
- </legend>
1064
-
1065
- <ul>
1066
- <li>
1067
- <div class='switch'>
1068
- <input name='wpgmza_do_not_enqueue_owl_carousel'
1069
- class='cmn-toggle cmn-toggle-round-flat'
1070
- type='checkbox'
1071
- id='wpgmza_do_not_enqueue_owl_carousel'
1072
- value='yes'/>
1073
- <label for='wpgmza_do_not_enqueue_owl_carousel'></label>
1074
- </div>
1075
- <?php
1076
- esc_html_e("Do not Enqueue Owl Carousel","wp-google-maps");
1077
- ?>
1078
- </li>
1079
-
1080
- <li>
1081
- <div class='switch'>
1082
- <input name='wpgmza_do_not_enqueue_owl_carousel_themes'
1083
- class='cmn-toggle cmn-toggle-round-flat'
1084
- type='checkbox'
1085
- id='wpgmza_do_not_enqueue_owl_carousel_themes'
1086
- value='yes'/>
1087
- <label for='wpgmza_do_not_enqueue_owl_carousel_themes'></label>
1088
- </div>
1089
- <?php
1090
- esc_html_e("Do not Enqueue Owl Theme","wp-google-maps");
1091
- ?>
1092
- </li>
1093
- </ul>
1094
- </fieldset>
1095
-
1096
- <fieldset class="wpgmza-pro-feature">
1097
- <legend>
1098
- <?php
1099
- esc_html_e("Responsivity Settings", "wp-google-maps")
1100
- ?>
1101
- </legend>
1102
-
1103
- <ul>
1104
- <li>
1105
- <input name='carousel_items' type='text' id='carousel_items' value="5"/>
1106
- <?php esc_html_e("Items","wp-google-maps"); ?>
1107
- </li>
1108
-
1109
- <li>
1110
- <input name='carousel_items_tablet' type='text' id='carousel_items_tablet' value="3"/>
1111
- <?php esc_html_e("Items (Tablet)","wp-google-maps"); ?>
1112
- </li>
1113
-
1114
- <li>
1115
- <input name='carousel_items_mobile' type='text' id='carousel_items_mobile' value="1"/>
1116
- <?php esc_html_e("Items (Mobile)","wp-google-maps"); ?>
1117
- </li>
1118
-
1119
- <li>
1120
- <input name='carousel_autoplay' type='text' id='carousel_autoplay' value="5000"/>
1121
- <?php esc_html_e("Autoplay after x milliseconds (1000 = 1 second)","wp-google-maps"); ?>
1122
- </li>
1123
- </ul>
1124
- </fieldset>
1125
-
1126
- </div>
1127
-
1128
- <div id="store-locator">
1129
- <fieldset>
1130
- <legend><?php _e('Store Locator Radii', 'wp-google-maps'); ?></legend>
1131
- <label>
1132
- <input name="wpgmza_store_locator_radii" pattern="^\d+(,\s*\d+)*$"/>
1133
- <p>
1134
- <small>
1135
- <?php _e('Use a comma to separate values, eg: 1, 5, 10, 50, 100', 'wp-google-maps'); ?>
1136
- </small>
1137
- </p>
1138
- </label>
1139
- </fieldset>
1140
- </div>
1141
-
1142
- <div id="advanced-settings">
1143
- <h3><?php _e('API Keys', 'wp-google-maps'); ?></h3>
1144
-
1145
- <fieldset data-required-maps-engine="google-maps">
1146
- <legend><?php _e('Google Maps API Key (required)', 'wp-google-maps'); ?></legend>
1147
- <label>
1148
- <input name="wpgmza_google_maps_api_key" id='wpgmza_google_maps_api_key' style='width: 400px;'/>
1149
- <p>
1150
- <small>
1151
- <?php
1152
- _e("This API key can be obtained from
1153
- the <a href='https://wpgmaps.com/google-maps-developer-console/' target='_BLANK'>Google Developers Console</a>. Our <a href='http://www.wpgmaps.com/documentation/creating-a-google-maps-api-key/' target='_BLANK'>documentation</a> provides a full guide on how to obtain this.", "wp-google-maps");
1154
- ?>
1155
- </small>
1156
- </p>
1157
- </label>
1158
- </fieldset>
1159
-
1160
- <fieldset data-required-maps-engine="google-maps" class="wpgmza-pro-feature">
1161
- <legend class="wpgmza-pro-feature-hide">
1162
- <?php
1163
- _e("Alternative Import API Key", "wp-google-maps");
1164
- ?>
1165
- </legend>
1166
- <label class="wpgmza-pro-feature-hide">
1167
- <input name="importer_google_maps_api_key"/>
1168
- <p>
1169
- <small>
1170
- <?php
1171
- _e("Generate an IP restricted key to paste into this field if you are experiencing 'Request Denied' when running imports", "wp-google-maps");
1172
- ?>
1173
- </small>
1174
- </p>
1175
- </label>
1176
- </fieldset>
1177
-
1178
- <fieldset data-required-maps-engine="open-layers">
1179
- <legend>
1180
- <?php echo __('OpenLayers Tileserver Key', 'wp-google-maps'); ?>
1181
- </legend>
1182
- <label>
1183
- <input name='open_layers_api_key'/>
1184
- <p>
1185
- <small>
1186
- <?php _e("This is an optional API key provided by your preferred OpenLayers tile service, and should only be added if required by the TileServer provider", "wp-google-maps"); ?>
1187
- </small>
1188
- </p>
1189
-
1190
- </label>
1191
-
1192
- </fieldset>
1193
-
1194
- <fieldset data-required-maps-engine="open-layers" class="wpgmza-pro-feature">
1195
- <legend class="wpgmza-pro-feature-hide">
1196
- <?php echo __('OpenRouteService Key', 'wp-google-maps'); ?>
1197
- </legend>
1198
- <label class="wpgmza-pro-feature-hide">
1199
- <input name='open_route_service_key'/>
1200
- <p>
1201
- <small>
1202
- <?php _e("This API key can be obtained from the <a href='https://openrouteservice.org/dev/#/login' target='_BLANK'>OpenRouteService Developers Console</a>.", "wp-google-maps"); ?>
1203
- </small>
1204
- </p>
1205
-
1206
- </label>
1207
-
1208
-
1209
- </fieldset>
1210
-
1211
-
1212
-
1213
- <h3>
1214
- <?php
1215
- esc_html_e("Marker Data Location", "wp-google-maps");
1216
- ?>
1217
- </h3>
1218
-
1219
- <p>
1220
- <?php
1221
- esc_html_e("We suggest that you change the two fields below ONLY if you are experiencing issues when trying to save the marker XML files.", "wp-google-maps");
1222
- ?>
1223
- </p>
1224
-
1225
- <fieldset>
1226
- <legend><?php esc_html_e("Pull marker data from", "wp-google-maps"); ?></legend>
1227
-
1228
- <ul>
1229
- <li>
1230
- <label>
1231
- <input name="wpgmza_settings_marker_pull" value="0" type="radio" checked="checked"/>
1232
- <?php
1233
- esc_html_e("Database", "wp-google-maps");
1234
- ?>
1235
- </label>
1236
- </li>
1237
- <li>
1238
- <label>
1239
- <input name="wpgmza_settings_marker_pull" value="1" type="radio"/>
1240
- <?php
1241
- esc_html_e("XML File", "wp-google-maps");
1242
- ?>
1243
- </label>
1244
- </li>
1245
- </ul>
1246
- </fieldset>
1247
-
1248
- <fieldset id="xml-cache-settings">
1249
-
1250
- <fieldset>
1251
- <legend><?php esc_html_e("Marker data XML directory", "wp-google-maps"); ?></legend>
1252
- <input name="wpgmza_marker_xml_location" class="regular-text code"/>
1253
- <p>
1254
- <small>
1255
- <?php esc_html_e("You can use the following", "wp-google-maps"); ?>
1256
- : {wp_content_dir},{plugins_dir},{uploads_dir}
1257
- </small>
1258
- </p>
1259
- <p>
1260
- <small>
1261
- <?php esc_html_e("Currently using", "wp-google-maps"); ?>
1262
- <strong>
1263
- NB: Add $marker_location here
1264
- </strong>
1265
- </small>
1266
- </p>
1267
- <!-- NB: See wpgmza_file_perms_check in legacy-core.php -->
1268
- </fieldset>
1269
-
1270
- <fieldset>
1271
- <legend><?php esc_html_e("Marker data XML URL", "wp-google-maps"); ?></legend>
1272
- <input name="wpgmza_marker_xml_url" class="regular-text code"/>
1273
- <p>
1274
- <small>
1275
- <?php esc_html_e("You can use the following", "wp-google-maps"); ?>
1276
- : {wp_content_dir},{plugins_dir},{uploads_dir}
1277
- </small>
1278
- </p>
1279
- <p>
1280
- <small>
1281
- <?php esc_html_e("Currently using", "wp-google-maps"); ?>
1282
- <strong>
1283
- NB: Add $marker_url here
1284
- </strong>
1285
- </small>
1286
- </p>
1287
- <!-- NB: See wpgmza_file_perms_check in legacy-core.php -->
1288
- </fieldset>
1289
-
1290
- </fieldset>
1291
-
1292
- <!--<fieldset id="library-script-panel-container"></fieldset>-->
1293
-
1294
- <h3><?php esc_html_e('Custom Scripts', 'wp-google-maps'); ?></h3>
1295
-
1296
- <fieldset>
1297
- <legend>
1298
- <?php esc_html_e('Custom CSS', 'wp-google-maps'); ?>
1299
- </legend>
1300
- <textarea name="wpgmza_custom_css"></textarea>
1301
- </fieldset>
1302
-
1303
- <fieldset>
1304
- <legend>
1305
- <?php esc_html_e('Custom JS', 'wp-google-maps'); ?>
1306
- </legend>
1307
- <textarea name="wpgmza_custom_js"></textarea>
1308
- </fieldset>
1309
-
1310
- <h3 data-required-maps-engine="open-layers"><?php esc_html_e('Other Caching', 'wp-google-maps'); ?></h3>
1311
-
1312
- <fieldset data-required-maps-engine="open-layers">
1313
- <legend>
1314
- <?php _e("Flush Geocode Cache", "wp-google-maps"); ?>
1315
- </legend>
1316
- <button id="wpgmza_flush_cache_btn" class="button-primary">
1317
- <?php _e('Flush', 'wp-google-maps'); ?>
1318
- </button>
1319
- </fieldset>
1320
-
1321
- <h3><?php esc_html_e('Danger Zone', 'wp-google-maps'); ?></h3>
1322
- <?php echo wpgmaps_danger_zone_nonce(); ?>
1323
- <fieldset id="wpgmza-destroy-data" class='wpgmza-danger-zone'>
1324
- <legend><?php esc_html_e("Data Management", "wp-google-maps"); ?></legend>
1325
-
1326
- <p>
1327
- <label>
1328
- <button danger="wpgmza_destroy_all_data" name="wpgmza_destroy_data" class="wpgmza_destroy_data wpgmza_general_btn button button-secondary">Complete Reset</button>
1329
-
1330
- <small class="wpgmza-button-hint-small">
1331
- <?php
1332
- esc_html_e('This will delete all settings, maps, markers, shapes, categories, and custom fields and reset the plugin back to the first time you used it.', 'wp-google-maps');
1333
- ?>
1334
- </small>
1335
-
1336
- </label>
1337
- </p>
1338
- <p>&nbsp;</p>
1339
- <p>
1340
- <label>
1341
- <button danger="wpgmza_reset_all_settings" name="wpgmza_destroy_data" class="wpgmza_destroy_data wpgmza_general_btn button button-secondary">Reset all settings</button>
1342
-
1343
- <small class="wpgmza-button-hint-small">
1344
- <?php
1345
- esc_html_e('This will reset all settings back to their default.', 'wp-google-maps');
1346
- ?>
1347
- </small>
1348
-
1349
- </label>
1350
- </p>
1351
- <p>&nbsp;</p>
1352
- <p class="wpgmza-pro-feature-hide">
1353
- <label>
1354
- <button danger="wpgmza_destroy_maps" name="wpgmza_destroy_data" class="wpgmza_destroy_data wpgmza_general_btn button button-secondary">Delete all maps</button>
1355
-
1356
- <small class="wpgmza-button-hint-small">
1357
- <?php
1358
- esc_html_e('This will delete all maps, markers, shapes, categories, and custom fields.', 'wp-google-maps');
1359
- ?>
1360
- </small>
1361
-
1362
- </label>
1363
- </p>
1364
- <p>
1365
- <label>
1366
- <button danger="wpgmza_destroy_markers" name="wpgmza_destroy_data" class="wpgmza_destroy_data wpgmza_general_btn button button-secondary">Delete all markers</button>
1367
-
1368
- <small class="wpgmza-button-hint-small">
1369
- <?php
1370
- esc_html_e('This will delete all markers.', 'wp-google-maps');
1371
- ?>
1372
- </small>
1373
-
1374
- </label>
1375
- </p>
1376
- <p>
1377
- <label>
1378
- <button danger="wpgmza_destroy_shapes" name="wpgmza_destroy_data" class="wpgmza_destroy_data wpgmza_general_btn button button-secondary">Delete all shapes</button>
1379
-
1380
- <small class="wpgmza-button-hint-small">
1381
- <?php
1382
- esc_html_e('This will delete all shapes.', 'wp-google-maps');
1383
- ?>
1384
- </small>
1385
-
1386
- </label>
1387
- </p>
1388
-
1389
- </fieldset>
1390
-
1391
-
1392
- <h3><?php esc_html_e('Miscellaneous Settings', 'wp-google-maps'); ?></h3>
1393
-
1394
- <fieldset>
1395
- <legend><?php esc_html_e('Disable Compressed Path Variables', 'wp-google-maps'); ?></legend>
1396
- <label>
1397
- <input name="disable_compressed_path_variables" type="checkbox"/>
1398
-
1399
- <small>
1400
- <?php
1401
- esc_html_e('We recommend using this setting if you frequently experience HTTP 414 - Request URI too long. We do not recommend using this setting if your site uses REST caching or a CDN.', 'wp-google-maps');
1402
- ?>
1403
- </small>
1404
-
1405
- </label>
1406
- </fieldset>
1407
-
1408
- <fieldset>
1409
- <legend><?php esc_html_e("Disable Autoptimize Compatibility Fix", "wp-google-maps"); ?></legend>
1410
- <label>
1411
- <input name="disable_autoptimize_compatibility_fix" type="checkbox"/>
1412
-
1413
- <small>
1414
- <?php
1415
- esc_html_e("Use this setting if you are experiencing issues with Autoptimize's CSS aggregation. This may cause issues on setups with a large amount of marker data.", "wp-google-maps");
1416
- ?>
1417
- </small>
1418
-
1419
- </label>
1420
- </fieldset>
1421
-
1422
- <fieldset id="wpgmza-disable-automatic-backups" class="wpgmza-pro-feature">
1423
- <legend><?php esc_html_e("Disable Automatic Backups (beta)", "wp-google-maps"); ?></legend>
1424
- <label>
1425
- <input name="disable_automatic_backups" type="checkbox"/>
1426
-
1427
- <small>
1428
- <?php
1429
- esc_html_e('We recommend leaving automatic backups enabled. We will automatically backup your data before an import or update to our plugin.', 'wp-google-maps');
1430
- ?>
1431
- </small>
1432
-
1433
- </label>
1434
- </fieldset>
1435
-
1436
- <fieldset id="wpgmza-developer-mode">
1437
- <legend><?php esc_html_e("Developer Mode", "wp-google-maps"); ?></legend>
1438
- <label>
1439
- <input name="wpgmza_developer_mode" type="checkbox"/>
1440
-
1441
- <small>
1442
- <?php
1443
- esc_html_e('Always rebuilds combined script files and script cache, does not load combined and minified scripts. Includes database query SQL with REST API responses.', 'wp-google-maps');
1444
- ?>
1445
- </small>
1446
-
1447
- </label>
1448
- </fieldset>
1449
-
1450
-
1451
-
1452
- </div>
1453
-
1454
- <div id="gdpr-compliance">
1455
- <div id="wpgmza-gdpr-compliance">
1456
-
1457
- <div>
1458
- <h3><?php _e( 'GDPR Compliance', 'wp-google-maps' ); ?></h3>
1459
- <p>
1460
- <?php
1461
- _e('Our GDPR notice will be displayed whenever the agreement cookie is not set. Agreeing to the notice will set this cookie.', 'wp-google-maps');
1462
- ?>
1463
- </p>
1464
- <p>
1465
- <?php
1466
- _e('Some caching and optimization plugins will continue to serve your map page with the GDPR agreement, disregarding this cookie. In this instance, clicking "I Agree" will reload the page and appear to have no effect. To solve this issue, we recommend you exclude your map page from caching and optimization.', 'wp-google-maps');
1467
- ?>
1468
- </p>
1469
- </div>
1470
-
1471
-
1472
- <div id="wpgmza-gpdr-general-compliance">
1473
-
1474
- <h2>
1475
- <?php _e('General Complicance', 'wp-google-maps'); ?>
1476
- </h2>
1477
-
1478
-
1479
- <fieldset>
1480
-
1481
- <label for="wpgmza_gdpr_require_consent_before_load">
1482
- <?php
1483
- _e('Require consent before loading Maps API', 'wp-google-maps');
1484
- ?>
1485
- <i class="fa fa-question-circle"
1486
- title="<?php _e('The GDPR views IP Addresses as Personal Data, which requires consent before being processed. Loading the Google Maps API stores some user information, such as IP Addresses. WP Google Maps endeavours to uphold the spirit of data protection as per the GDPR. Enable this to option to prevent the Maps API from loading, until a user has consented to it.', 'wp-google-maps'); ?>"/>
1487
- </label>
1488
- <input name="wpgmza_gdpr_require_consent_before_load" type="checkbox"/>
1489
- </fieldset>
1490
-
1491
- <span class="notice notice-error wpgmza-complianz-notice wpgmza-hidden" style="margin-left: 0; display: block;">
1492
- <strong><?php _e("Important Note", "wp-google-maps"); ?>:</strong>
1493
- <?php
1494
- _e('GDPR consent automatically enabled and configured by Complianz', 'wp-google-maps');
1495
- ?>
1496
- <br><br>
1497
- <?php
1498
- _e('WP Google Maps GDPR options have been disabled as they are fully controlled by Complianz', 'wp-google-maps');
1499
- ?>
1500
- </span>
1501
- </div>
1502
-
1503
-
1504
- <div id="wpgmza-gdpr-compliance-notice" style="display: none;">
1505
-
1506
- <h2>
1507
- <?php _e('GDPR Consent Notice', 'wp-google-maps'); ?>
1508
- </h2>
1509
-
1510
- <fieldset>
1511
- <legend>
1512
- <label for="wpgmza_gdpr_default_notice">
1513
- <?php
1514
- _e('GDPR Notice', 'wp-google-maps');
1515
- ?>
1516
- <i class="fa fa-question-circle"
1517
- title="<?php _e('Users will be asked to accept the notice shown here, in the form of a check box.', 'wp-google-maps'); ?>"></i>
1518
- </label>
1519
- </legend>
1520
- <div name="wpgmza_gdpr_default_notice"></div>
1521
- </fieldset>
1522
-
1523
- <fieldset>
1524
- <legend>
1525
- <label for="wpgmza_gdpr_company_name">
1526
- <?php
1527
- _e('Company Name', 'wp-google-maps');
1528
- ?>
1529
- </label>
1530
- </legend>
1531
- <span class="settings-group">
1532
- <input name="wpgmza_gdpr_company_name"/>
1533
- </span>
1534
- </fieldset>
1535
-
1536
-
1537
- <fieldset>
1538
- <legend>
1539
- <label for="wpgmza_gdpr_retention_purpose">
1540
- <?php
1541
- _e('Retention Purpose(s)', 'wp-google-maps');
1542
- ?>
1543
- </label>
1544
- </legend>
1545
- <span class="settings-group">
1546
- <div>
1547
- <input name="wpgmza_gdpr_retention_purpose"/>
1548
- <br/>
1549
- <small>
1550
- <?php
1551
- _e('The GDPR regulates that you need to state why you are processing data.', 'wp-google-maps');
1552
- ?>
1553
- </small>
1554
- </div>
1555
- </span>
1556
- </fieldset>
1557
-
1558
- <fieldset>
1559
- <legend>
1560
- <label for="wpgmza_gdpr_override_notice">
1561
- <?php
1562
- _e('Override GDPR Notice', 'wp-google-maps');
1563
- ?>
1564
- <input name="wpgmza_gdpr_override_notice" type="checkbox" id="wpgmza_gdpr_override_notice"/>
1565
- </label>
1566
- </legend>
1567
- </fieldset>
1568
-
1569
- <span class="notice notice-error" style="padding: 0.5em; display: block;">
1570
- <?php
1571
- _e('By checking this box, you agree to take sole responsibility for GDPR Compliance with regards to this plugin.', 'wp-google-maps');
1572
- ?>
1573
- </span>
1574
-
1575
- <fieldset id="wpgmza_gdpr_override_notice_text">
1576
- <legend>
1577
- <label for="wpgmza_gdpr_override_notice_text">
1578
- <?php
1579
- _e('Override Text', 'wp-google-maps');
1580
- ?>
1581
- </label>
1582
- </legend>
1583
- <span class="settings-group">
1584
- <textarea name="wpgmza_gdpr_notice_override_text"></textarea>
1585
- </span>
1586
- </fieldset>
1587
-
1588
-
1589
- </div>
1590
-
1591
- <p>
1592
- <?php
1593
- _e('For more information about WPGM and GDPR compliance, please refer to our <a href="https://www.wpgmaps.com/gdpr/">GDPR information page</a> and our <a href="https://www.wpgmaps.com/privacy-policy/">Privacy Policy</a>', 'wp-google-maps');
1594
- ?>
1595
- </p>
1596
- </div>
1597
- </div>
1598
-
1599
- <div class="addition-tabs">
1600
-
1601
- </div>
1602
-
1603
- <p style="text-align: right;">
1604
- <button type="submit" class="button button-primary">
1605
- <?php
1606
- esc_html_e("Save Settings", "wp-google-maps");
1607
- ?>
1608
- </button>
1609
- </p>
1610
-
1611
  </form>
1
+ <form
2
+ method="POST"
3
+ id="wpgmza-global-settings"
4
+ class="wpgmza-form"
5
+ action="<?php
6
+ echo admin_url('admin-post.php');
7
+ ?>"
8
+ >
9
+
10
+ <input
11
+ type="hidden"
12
+ name="action"
13
+ value="wpgmza_save_settings"
14
+ />
15
+
16
+ <ul class='settings-tabs-nav'>
17
+ <li>
18
+ <a href="#general-settings">
19
+ <?php esc_html_e('General Settings', 'wp-google-maps'); ?>
20
+ </a>
21
+ </li>
22
+ <li>
23
+ <a href="#info-windows">
24
+ <?php esc_html_e('InfoWindows', 'wp-google-maps'); ?>
25
+ </a>
26
+ </li>
27
+ <li>
28
+ <a href="#marker-listing">
29
+ <?php esc_html_e('Marker Listing', 'wp-google-maps'); ?>
30
+ </a>
31
+ </li>
32
+ <li>
33
+ <a href="#store-locator">
34
+ <?php esc_html_e('Store Locator', 'wp-google-maps'); ?>
35
+ </a>
36
+ </li>
37
+ <li>
38
+ <a href="#advanced-settings">
39
+ <?php esc_html_e('Advanced Settings', 'wp-google-maps'); ?>
40
+ </a>
41
+ </li>
42
+ <li>
43
+ <a href="#gdpr-compliance">
44
+ <?php esc_html_e('GDPR Compliance', 'wp-google-maps'); ?>
45
+ </a>
46
+ </li>
47
+ </ul>
48
+
49
+ <div id="general-settings">
50
+
51
+ <fieldset>
52
+ <legend>
53
+ <?php esc_html_e('Maps Engine', 'wp-google-maps'); ?>
54
+ </legend>
55
+ <select name="wpgmza_maps_engine" id="wpgmza_maps_engine">
56
+ <option value="google-maps"><?php esc_html_e('Google Maps', 'wp-google-maps'); ?></option>
57
+ <option value="open-layers"><?php esc_html_e('OpenLayers', 'wp-google-maps'); ?></option>
58
+ </select>
59
+ </fieldset>
60
+
61
+ <fieldset>
62
+ <legend>
63
+ <?php esc_html_e('General Map Settings', 'wp-google-maps'); ?>
64
+ </legend>
65
+
66
+ <div role="group">
67
+ <label>
68
+ <div>
69
+ <input name="wpgmza_settings_map_full_screen_control" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
70
+ <?php esc_html_e('Disable Full Screen Control', 'wp-google-maps'); ?>
71
+ </div>
72
+ </label>
73
+
74
+ <label data-required-maps-engine="google-maps">
75
+ <div>
76
+ <input name="wpgmza_settings_map_streetview" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
77
+ <?php esc_html_e('Disable StreetView', 'wp-google-maps'); ?>
78
+ </div>
79
+ </label>
80
+
81
+ <label>
82
+ <div>
83
+ <input name="wpgmza_settings_map_zoom" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
84
+ <?php esc_html_e('Disable Zoom Controls', 'wp-google-maps'); ?>
85
+ </div>
86
+ </label>
87
+
88
+ <label data-required-maps-engine="google-maps">
89
+ <div>
90
+ <input name="wpgmza_settings_map_pan" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
91
+ <?php esc_html_e('Disable Pan Controls', 'wp-google-maps'); ?>
92
+ </div>
93
+ </label>
94
+
95
+ <label data-required-maps-engine="google-maps">
96
+ <div>
97
+ <input name="wpgmza_settings_map_type" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
98
+ <?php esc_html_e('Disable Map Type Controls', 'wp-google-maps'); ?>
99
+ </div>
100
+ </label>
101
+
102
+ <label data-required-maps-engine="google-maps">
103
+ <div>
104
+ <input name="wpgmza_settings_map_tilt_controls" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
105
+ <?php esc_html_e('Disable Tilt Controls', 'wp-google-maps'); ?>
106
+ </div>
107
+ </label>
108
+
109
+ <label>
110
+ <div>
111
+ <input name="wpgmza_settings_map_scroll" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
112
+ <?php esc_html_e('Disable Mouse Wheel Zoom', 'wp-google-maps'); ?>
113
+ </div>
114
+ </label>
115
+
116
+ <label>
117
+ <div>
118
+ <input name="wpgmza_settings_map_draggable" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
119
+ <?php esc_html_e('Disable Mouse Dragging', 'wp-google-maps'); ?>
120
+ </div>
121
+ </label>
122
+
123
+ <label>
124
+ <div>
125
+ <input name="wpgmza_settings_map_clickzoom" class="wpgmza-fancy-toggle-switch" type="checkbox"/>
126
+ <?php esc_html_e('Disable Mouse Double Click Zooming', 'wp-google-maps'); ?>
127
+ </div>
128
+ </label>
129
+
130
+ </div>
131
+ </fieldset>
132
+
133
+ <fieldset>
134
+ <legend>
135
+ <?php esc_html_e('User Interface Style', 'wp-google-maps'); ?>
136
+ (<em><a href='https://www.wpgmaps.com/documentation/user-interface-style-options/' target='_BLANK'><?php esc_html_e('examples', 'wp-google-maps'); ?></a></em>)
137
+ </legend>
138
+
139
+ <ul>
140
+ <li>
141
+ <label>
142
+ <input type='radio'
143
+ name='user_interface_style'
144
+ value='default'
145
+ checked="checked"/>
146
+ <?php
147
+ _e("<strong>Default</strong> - The default front end.", "wp-google-maps")
148
+ ?>
149
+ </label>
150
+ </li>
151
+ <li>
152
+ <label>
153
+ <input type='radio'
154
+ name='user_interface_style'
155
+ value='modern'/>
156
+ <?php
157
+ _e("<strong>Modern</strong> - Puts components inside the map, with pull-out panels.", "wp-google-maps")
158
+ ?>
159
+ </label>
160
+ </li>
161
+ <li>
162
+ <label>
163
+ <input type='radio'
164
+ name='user_interface_style'
165
+ value='legacy'/>
166
+ <?php
167
+ _e("<strong>Legacy</strong> - This setting is the same as Default, but provides options to change individual components to the modern style.", "wp-google-maps")
168
+ ?>
169
+ </label>
170
+ </li>
171
+ <li>
172
+ <label>
173
+ <input type='radio'
174
+ name='user_interface_style'
175
+ value='compact'/>
176
+ <?php
177
+ _e("<strong>Compact</strong> - Puts all components and their labels inline.", "wp-google-maps")
178
+ ?>
179
+ </label>
180
+ </li>
181
+ <li>
182
+ <label>
183
+ <input type='radio'
184
+ name='user_interface_style'
185
+ value='minimal'/>
186
+ <?php
187
+ _e("<strong>Minimal</strong> - The same as Compact, but with icons instead of text labels.", "wp-google-maps");
188
+ ?>
189
+ </label>
190
+ </li>
191
+ <li>
192
+ <label>
193
+ <input type='radio'
194
+ name='user_interface_style'
195
+ value='bare-bones'/>
196
+ <?php
197
+ _e("<strong>Bare Bones</strong> - Applies no styling to the components at all. This is recommended for designers and developers who want to style the components from scratch.", "wp-google-maps")
198
+ ?>
199
+ </label>
200
+ </li>
201
+ </ul>
202
+
203
+ </fieldset>
204
+
205
+ <fieldset>
206
+ <legend>
207
+ <?php esc_html_e('Category Selection Logic', 'wp-google-maps'); ?>
208
+ </legend>
209
+ <ul>
210
+ <li>
211
+ <label>
212
+ <input name='wpgmza_settings_cat_logic' type='radio' id='wpgmza_settings_cat_logic_or' value='0' checked="checked" />
213
+ <?php echo __("OR"," wp-google-maps") . " &nbsp; (<span class='description'>" . __("Example: Show the marker if it belongs to Cat A _OR_ Cat B.", "wp-google-maps") . "</span>)"; ?>
214
+ </label>
215
+ </li>
216
+
217
+ <li>
218
+ <label>
219
+ <input name='wpgmza_settings_cat_logic' type='radio' id='wpgmza_settings_cat_logic_and' value='1'/>
220
+ <?php echo __("AND"," wp-google-maps") . " &nbsp; (<span class='description'>" . __("Example: Only show the marker if it belongs to Cat A _AND_ Cat B.", "wp-google-maps") . "</span>)"; ?>
221
+ </label>
222
+ </li>
223
+ </ul>
224
+ </fieldset>
225
+
226
+ <fieldset>
227
+ <legend>
228
+ <?php esc_html_e('Filter by category displayed as', 'wp-google-maps'); ?>
229
+ </legend>
230
+ <ul>
231
+ <li>
232
+ <label>
233
+ <input name='wpgmza_settings_filterbycat_type' type='radio' id='wpgmza_settings_filterbycat_type_dropdown' value='1' checked="checked" />
234
+ <?php _e("Dropdown","wp-google-maps"); ?>
235
+ </label>
236
+ </li>
237
+ <li>
238
+ <label>
239
+ <input name='wpgmza_settings_filterbycat_type' type='radio' id='wpgmza_settings_filterbycat_type_checkboxes' value='2' />
240
+ <?php _e("Checkboxes","wp-google-maps"); ?>
241
+ </label>
242
+ </li>
243
+ </ul>
244
+ </fieldset>
245
+
246
+
247
+ <!--<fieldset>
248
+ <legend>
249
+ <?php esc_html_e('Troubleshooting Options', 'wp-google-maps'); ?>
250
+ </legend>
251
+
252
+ <label>
253
+ <input name="wpgmza_settings_force_jquery" class="wpgmza-fancy-toggle-button" type="checkbox"/>
254
+ <?php
255
+ esc_html_e("Over-ride current jQuery with version 1.11.3 (Tick this box if you are receiving jQuery related errors after updating to WordPress 4.5)", 'wp-google-maps');
256
+ ?>
257
+ </label>
258
+
259
+ <label data-required-maps-engine="google-maps">
260
+ <input name="wpgmza_settings_remove_api" class="wpgmza-fancy-toggle-button" type="checkbox"/>
261
+ <?php
262
+ esc_html_e("Do not load the Google Maps API (Only check this if your theme loads the Google Maps API by default)", 'wp-google-maps');
263
+ ?>
264
+ </label>
265
+ </fieldset>-->
266
+
267
+ <fieldset>
268
+ <legend>
269
+ <?php esc_html_e('Use FontAwesome', 'wp-google-maps'); ?>
270
+ </legend>
271
+ <select name='use_fontawesome'>
272
+ <option value='4.*'>4.*</option>
273
+ <option value='5.*'>5.*</option>
274
+ <option value='none'><?php esc_html_e("None", "wp-google-maps"); ?></option>
275
+ </select>
276
+ </fieldset>
277
+
278
+
279
+
280
+ <fieldset data-required-maps-engine="open-layers">
281
+ <legend>
282
+ <?php esc_html_e('Tile Server URL', 'wp-google-maps'); ?>
283
+ </legend>
284
+ <select name="tile_server_url">
285
+
286
+ <option
287
+ value="https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png"
288
+ data-usage-policy="https://wiki.openstreetmap.org/wiki/Tile_usage_policy">
289
+ <?php
290
+ _e('OpenStreetMap', 'wp-google-maps');
291
+ ?>
292
+ </option>
293
+
294
+ <option
295
+ value="https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png"
296
+ data-usage-policy="https://foundation.wikimedia.org/wiki/Maps_Terms_of_Use"
297
+ data-preview-image="https://wiki.openstreetmap.org/w/images/0/02/Wikimedia-tile.png">
298
+ <?php
299
+ _e('Wikimedia Maps', 'wp-google-maps');
300
+ ?>
301
+ </option>
302
+
303
+ <option value="https://tile.thunderforest.com/cycle/{z}/{x}/{y}.png"
304
+ data-preview-image="https://b.tile.opencyclemap.org/cycle/16/33199/22539.png">
305
+ <?php
306
+ _e('OpenCycleMap *', 'wp-google-maps');
307
+ ?>
308
+ </option>
309
+
310
+ <option value="https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png"
311
+ data-preview-image="https://wiki.openstreetmap.org/w/images/6/63/Humanitarian_style.png">
312
+ <?php
313
+ _e('Humanitarian', 'wp-google-maps');
314
+ ?>
315
+ </option>
316
+
317
+ <option value="https://{a-c}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png"
318
+ data-preview-image="https://a.www.toolserver.org/tiles/bw-mapnik/9/264/179.png">
319
+ <?php
320
+ _e('Mapnik OSM B&amp;W', 'wp-google-maps');
321
+ ?>
322
+ </option>
323
+
324
+ <option value="https://tiles.wmflabs.org/osm-no-labels/{z}/{x}/{y}.png"
325
+ data-preview-image="https://c.tiles.wmflabs.org/osm-no-labels/14/7452/6839.png">
326
+ <?php
327
+ _e('Mapnik OSM No Labels', 'wp-google-maps');
328
+ ?>
329
+ </option>
330
+
331
+ <option value="https://a.tile.stamen.com/toner/{z}/{x}/{y}.png"
332
+ data-preview-image="https://a.tile.stamen.com/toner/10/529/366.png">
333
+ <?php
334
+ _e('Stamen Toner', 'wp-google-maps');
335
+ ?>
336
+ </option>
337
+
338
+ <option value="http://c.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg"
339
+ data-preview-image="http://wiki.openstreetmap.org/w/images/d/d2/Tile_watercolor_stamen.jpg">
340
+ <?php
341
+ _e('Stamen Watercolor', 'wp-google-maps');
342
+ ?> (No SSL)
343
+ </option>
344
+
345
+ <option value="https://tile.thunderforest.com/transport/{z}/{x}/{y}.png"
346
+ data-preview-image="https://a.tile2.opencyclemap.org/transport/13/4150/2819.png">
347
+ <?php
348
+ _e('Transport Map *', 'wp-google-maps');
349
+ ?>
350
+ </option>
351
+
352
+ <option value="https://tile.thunderforest.com/landscape/{z}/{x}/{y}.png"
353
+ data-preview-image="https://a.tile.thunderforest.com/landscape/14/4773/6144.png">
354
+ <?php
355
+ _e('Thunderforest Landscape *', 'wp-google-maps');
356
+ ?>
357
+ </option>
358
+
359
+ <option value="https://tile.thunderforest.com/outdoors/{z}/{x}/{y}.png"
360
+ data-preview-image="https://a.tile.thunderforest.com/outdoors/14/4772/6144.png">
361
+ <?php
362
+ _e('Thunderforest Outdoors *', 'wp-google-maps');
363
+ ?>
364
+ </option>
365
+
366
+ <option value="https://tile.memomaps.de/tilegen/{z}/{x}/{y}.png"
367
+ data-preview-image="https://tile.memomaps.de/tilegen/12/2200/1343.png">
368
+ <?php
369
+ _e('Öpnvkarte', 'wp-google-maps');
370
+ ?>
371
+ </option>
372
+
373
+ <option value="http://www.openptmap.org/tiles/{z}/{x}/{y}.png"
374
+ data-preview-image="http://www.openptmap.org/tiles//10/529/366.png">
375
+ <?php
376
+ _e('OpenPtMap', 'wp-google-maps');
377
+ ?> (No SSL)
378
+ </option>
379
+
380
+ <option value="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png">
381
+ <?php
382
+ _e('Carto Light (Positron) *', 'wp-google-maps');
383
+ ?>
384
+ </option>
385
+
386
+ <option value="https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png"
387
+ data-preview-image="https://wiki.openstreetmap.org/w/images/b/ba/Cartodb_dark_tile.png">
388
+ <?php
389
+ _e('Carto Dark (Dark Matter) *', 'wp-google-maps');
390
+ ?>
391
+ </option>
392
+
393
+ <option value="https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png">
394
+ <?php
395
+ _e('MapTiler Streets *', 'wp-google-maps');
396
+ ?>
397
+ </option>
398
+
399
+ <option value="https://api.maptiler.com/maps/outdoor/{z}/{x}/{y}.png">
400
+ <?php
401
+ _e('MapTiler Outdoor *', 'wp-google-maps');
402
+ ?>
403
+ </option>
404
+
405
+ <option value="https://api.maptiler.com/maps/pastel/{z}/{x}/{y}.png">
406
+ <?php
407
+ _e('MapTiler Pastel *', 'wp-google-maps');
408
+ ?>
409
+ </option>
410
+
411
+ <option value="https://api.maptiler.com/maps/basic/{z}/{x}/{y}.png">
412
+ <?php
413
+ _e('MapTiler Basic *', 'wp-google-maps');
414
+ ?>
415
+ </option>
416
+
417
+ <option value="https://caltopo.com/tile/mb_topo/{z}/{x}/{y}.png">
418
+ <?php
419
+ _e('Caltopo *', 'wp-google-maps');
420
+ ?>
421
+ </option>
422
+
423
+ <option value="custom_override">
424
+ <?php
425
+ _e('Other (Enter URL)', 'wp-google-maps');
426
+ ?>
427
+ </option>
428
+
429
+ </select>
430
+ <small>&nbsp; * <?php _e("You can add an API key under the Advanced Settings tab if required by your TileServer provider", "wp-google-maps"); ?></small>
431
+ </fieldset>
432
+
433
+ <fieldset data-required-maps-engine="open-layers">
434
+ <legend class='wpgmza_tile_server_override_component wpgmza-hidden'><?php _e('Custom Tile Server URL', 'wp-google-maps'); ?></legend>
435
+ <input class='wpgmza_tile_server_override_component wpgmza-hidden' name="tile_server_url_override" placeholder="https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
436
+ </fieldset>
437
+
438
+ <fieldset data-required-maps-engine="google-maps">
439
+ <legend>
440
+ <?php _e('Load Maps Engine API', 'wp-google-maps'); ?>
441
+ </legend>
442
+ <select name="wpgmza_load_engine_api_condition">
443
+ <option value="where-required">
444
+ <?php
445
+ _e('Where required', 'wp-google-maps');
446
+ ?>
447
+ </option>
448
+ <option value="always">
449
+ <?php
450
+ _e('Always', 'wp-google-maps');
451
+ ?>
452
+ </option>
453
+ <option value="only-front-end">
454
+ <?php
455
+ _e('Only Front End', 'wp-google-maps');
456
+ ?>
457
+ </option>
458
+ <option value="only-back-end">
459
+ <?php
460
+ _e('Only Back End', 'wp-google-maps');
461
+ ?>
462
+ </option>
463
+ <option value="never">
464
+ <?php
465
+ _e('Never', 'wp-google-maps');
466
+ ?>
467
+ </option>
468
+ </select>
469
+ </fieldset>
470
+
471
+ <fieldset>
472
+ <legend><?php _e('Always include engine API on pages', 'wp-google-maps'); ?></legend>
473
+ <input name="wpgmza_always_include_engine_api_on_pages" placeholder="<?php _e('Page IDs'); ?>"/>
474
+ </fieldset>
475
+
476
+ <fieldset>
477
+ <legend><?php _e('Always exclude engine API on pages', 'wp-google-maps'); ?></legend>
478
+ <input name="wpgmza_always_exclude_engine_api_on_pages" placeholder="<?php _e('Page IDs'); ?>"/>
479
+ </fieldset>
480
+
481
+ <fieldset>
482
+ <legend><?php _e('Prevent other plugins and theme loading API', 'wp-google-maps'); ?></legend>
483
+ <input name="wpgmza_prevent_other_plugins_and_theme_loading_api" type="checkbox"/>
484
+ <small>
485
+ <?php
486
+ _e("Use this setting if you are experiencing Google Maps API issues, such as invalid key warnings, or Multiple API warnings", "wp-google-maps");
487
+ ?>
488
+ </small>
489
+ </fieldset>
490
+
491
+ <fieldset>
492
+ <legend><?php _e("Lowest level of access to the map editor","wp-google-maps"); ?></legend>
493
+ <select name="wpgmza_settings_access_level">
494
+ <option value="manage_options"><?php _e('Admin', 'wp-google-maps'); ?></option>
495
+ <option value="edit_pages"><?php _e('Editor', 'wp-google-maps'); ?></option>
496
+ <option value="edit_published_posts"><?php _e('Author', 'wp-google-maps'); ?></option>
497
+ <option value="edit_posts"><?php _e('Contributor', 'wp-google-maps'); ?></option>
498
+ <option value="read"><?php _e('Subscriber', 'wp-google-maps'); ?></option>
499
+ </select>
500
+ </fieldset>
501
+
502
+ <fieldset>
503
+ <legend><?php _e("Retina Icon Width","wp-google-maps"); ?></legend>
504
+ <span class="settings-group">
505
+ <input name='wpgmza_settings_retina_width' type='text' size='4' maxlength='4' id='wpgmza_settings_retina_width'/> px
506
+ </span>
507
+ </fieldset>
508
+ <fieldset>
509
+ <legend><?php _e("Retina Icon Height","wp-google-maps"); ?></legend>
510
+ <span class="settings-group">
511
+ <input name='wpgmza_settings_retina_height' type='text' size='4' maxlength='4' id='wpgmza_settings_retina_height'/> px
512
+ </span>
513
+ </fieldset>
514
+
515
+
516
+ <!-- NB: Usage tracking dropped as of 2018 GDPR changes -->
517
+
518
+ <fieldset>
519
+ <legend><?php _e("Greedy Gesture Handling","wp-google-maps"); ?></legend>
520
+ <input name="wpgmza_force_greedy_gestures" type="checkbox"/>
521
+ <small>
522
+ <?php
523
+ _e("Check this setting to disable two finger pan on mobiles, and Ctrl + Zoom on desktops. Enabling this setting will allow one finger panning on mobiles, and will enable zoom without Ctrl on desktops.", "wp-google-maps");
524
+ ?>
525
+ </small>
526
+ </fieldset>
527
+
528
+ <fieldset class="wpgmza-pro-feature wpgmza-pro-feature-hide">
529
+ <legend>
530
+ <?php
531
+ _e("Disable Lightbox", "wp-google-maps");
532
+ ?>
533
+ </legend>
534
+ <input name="disable_lightbox_images" type="checkbox"/>
535
+ <small>
536
+ <?php
537
+ _e("Prevents the larger image lightbox from opening up when pictures in the infowindow or marker listing are clicked", "wp-google-maps");
538
+ ?>
539
+ </small>
540
+ </fieldset>
541
+ </div>
542
+
543
+ <div id="info-windows">
544
+
545
+ <fieldset class="wpgmza-pro-feature-hide">
546
+ <legend>
547
+ <?php
548
+ _e("Infowindow Style", "wp-google-maps");
549
+ ?>
550
+ </legend>
551
+
552
+
553
+ <div class='wpgmza-infowindow-style-picker wpgmza-flex'>
554
+
555
+ <label>
556
+ <input type="radio" name="wpgmza_iw_type" value="0" class="wpgmza-pro-feature"/>
557
+ <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_hide'>
558
+ <div class="wpgmza-card wpgmza-card-border__hover">
559
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_1.png'; ?>"
560
+ title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
561
+ class="wpgmza_mlist_selection"
562
+ />
563
+ <span class='wpgmza-infowindow-style__name'>
564
+ <?php
565
+ _e('Default Infowindow', 'wp-google-maps');
566
+ ?>
567
+ </span>
568
+ </div>
569
+ </div>
570
+ </label>
571
+
572
+ <label>
573
+ <input type="radio" name="wpgmza_iw_type" value="1" class="wpgmza-pro-feature"/>
574
+ <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_show'>
575
+ <div class="wpgmza-card wpgmza-card-border__hover">
576
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_2.png'; ?>"
577
+ title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
578
+ class="wpgmza_mlist_selection"
579
+ />
580
+ <span class='wpgmza-infowindow-style__name'>
581
+ <?php
582
+ _e('Modern Infowindow', 'wp-google-maps');
583
+ ?>
584
+ </span>
585
+ </div>
586
+ </div>
587
+ </label>
588
+
589
+ <label>
590
+ <input type="radio" name="wpgmza_iw_type" value="2" class="wpgmza-pro-feature"/>
591
+ <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_show'>
592
+ <div class="wpgmza-card wpgmza-card-border__hover">
593
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_3.png'; ?>"
594
+ title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
595
+ class="wpgmza_mlist_selection"
596
+ />
597
+ <span class='wpgmza-infowindow-style__name'>
598
+ <?php
599
+ _e('Modern Plus Infowindow', 'wp-google-maps');
600
+ ?>
601
+ </span>
602
+ </div>
603
+ </div>
604
+ </label>
605
+
606
+ <label>
607
+ <input type="radio" name="wpgmza_iw_type" value="3" class="wpgmza-pro-feature"/>
608
+ <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_show'>
609
+ <div class="wpgmza-card wpgmza-card-border__hover">
610
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_4.png'; ?>"
611
+ title="<?php esc_attr_e('Default', 'wp-google-maps'); ?>"
612
+ class="wpgmza_mlist_selection"
613
+ />
614
+ <span class='wpgmza-infowindow-style__name'>
615
+ <?php
616
+ _e('Circular Infowindow', 'wp-google-maps');
617
+ ?>
618
+ </span>
619
+ </div>
620
+ </div>
621
+ </label>
622
+
623
+
624
+ <label>
625
+ <input type="radio" name="wpgmza_iw_type" value="-1" class="wpgmza-pro-feature"/>
626
+ <div class='wpgmza-flex-item wpgmza-infowindow-picker__item iw_custom_click_hide'>
627
+ <div class="wpgmza-card wpgmza-card-border__hover">
628
+ <img src="<?php echo WPGMZA_PLUGIN_DIR_URL . '/images/marker_iw_type_inherit.png'; ?>"
629
+ title="<?php esc_attr_e('No Global Setting', 'wp-google-maps'); ?>"
630
+ class="wpgmza_mlist_selection"
631
+ />
632
+
633
+ <span class='wpgmza-infowindow-style__name'>
634
+ <?php
635
+ _e('No Global Setting', 'wp-google-maps');
636
+ ?>
637
+ </span>
638
+ </div>
639
+ </div>
640
+ </label>
641
+ </div>
642
+ </fieldset>
643
+
644
+ <fieldset class="wpgmza-pro-feature-hide">
645
+ <legend><?php _e("Resize Images", "wp-google-maps"); ?></legend>
646
+
647
+ <div class='switch'>
648
+ <input name='wpgmza_settings_image_resizing'
649
+ class='cmn-toggle cmn-toggle-round-flat'
650
+ type='checkbox'
651
+ id='wpgmza_settings_image_resizing' value='yes'/>
652
+ <label for='wpgmza_settings_image_resizing'>
653
+ </label>
654
+ </div>
655
+ <?php
656
+ esc_html_e("Resize all images to the below sizes","wp-google-maps");
657
+ ?>
658
+
659
+ </fieldset>
660
+
661
+ <fieldset class="wpgmza-pro-feature-hide">
662
+ <legend><?php _e("Default Image Width", "wp-google-maps"); ?></legend>
663
+
664
+ <input name='wpgmza_settings_image_width' type='text' size='4' maxlength='4' id='wpgmza_settings_image_width'/>
665
+ <em><?php esc_html_e("(can be left blank - max width will be limited to max infowindow width)","wp-google-maps"); ?></em>
666
+ </fieldset>
667
+
668
+ <fieldset class="wpgmza-pro-feature-hide">
669
+ <legend><?php _e("Default Image Height", "wp-google-maps"); ?></legend>
670
+
671
+ <input name='wpgmza_settings_image_height' type='text' size='4' maxlength='4' id='wpgmza_settings_image_height'/>
672
+ <em><?php esc_html_e("(can be left blank - leaving both the width and height blank will revert to full size images being used)","wp-google-maps"); ?></em>
673
+ </fieldset>
674
+
675
+ <fieldset class="wpgmza-pro-feature-hide">
676
+ <legend><?php _e("Max InfoWindow Width", "wp-google-maps"); ?></legend>
677
+
678
+ <input name='wpgmza_settings_infowindow_width' type='text' size='4' maxlength='4' id='wpgmza_settings_infowindow_width'/>
679
+ <em><?php esc_html_e("(can be left blank - leaving both the width and height blank will revert to full size images being used)","wp-google-maps"); ?></em>
680
+ </fieldset>
681
+
682
+ <fieldset class="wpgmza-pro-feature-hide">
683
+ <legend><?php _e("Other settings", "wp-google-maps"); ?></legend>
684
+
685
+ <ul>
686
+ <li>
687
+ <div class='switch'>
688
+ <input name='wpgmza_settings_infowindow_links'
689
+ class='cmn-toggle cmn-toggle-round-flat'
690
+ type='checkbox'
691
+ id='wpgmza_settings_infowindow_links'
692
+ value='yes'/>
693
+ <label for='wpgmza_settings_infowindow_links'></label>
694
+ </div>
695
+ <?php
696
+ esc_html_e("Open links in a new window ","wp-google-maps");
697
+ ?><em><?php esc_html_e("(Tick this if you want to open your links in a new window)","wp-google-maps"); ?></em>
698
+ </li>
699
+ <li>
700
+ <div class='switch'>
701
+ <input name='wpgmza_settings_infowindow_address'
702
+ class='cmn-toggle cmn-toggle-round-flat'
703
+ type='checkbox'
704
+ id='wpgmza_settings_infowindow_address'
705
+ value='yes'/>
706
+ <label for='wpgmza_settings_infowindow_address'></label>
707
+ </div>
708
+ <?php
709
+ esc_html_e("Hide the address field","wp-google-maps");
710
+ ?>
711
+ </li>
712
+ </ul>
713
+ </fieldset>
714
+
715
+ <fieldset class="wpgmza-pro-feature-hide">
716
+ <legend><?php _e("Link text", "wp-google-maps"); ?></legend>
717
+
718
+ <input name='wpgmza_settings_infowindow_link_text' type='text' id='wpgmza_settings_infowindow_link_text'/>
719
+ </fieldset>
720
+
721
+ <fieldset>
722
+ <legend><?php _e("Open Marker InfoWindows by", "wp-google-maps"); ?></legend>
723
+
724
+ <ul>
725
+ <li>
726
+ <label>
727
+ <input name="wpgmza_settings_map_open_marker_by" value="1" type="radio" checked="checked"/>
728
+ <?php _e('Click', 'wp-google-maps'); ?>
729
+ </label>
730
+ </li>
731
+ <li>
732
+ <label>
733
+ <input name="wpgmza_settings_map_open_marker_by" value="2" type="radio"/>
734
+ <?php _e('Hover', 'wp-google-maps'); ?>
735
+ </label>
736
+ </li>
737
+ </ul>
738
+ </fieldset>
739
+
740
+ <fieldset>
741
+ <legend><?php _e('Disable InfoWindows', 'wp-google-maps'); ?></legend>
742
+ <input name="wpgmza_settings_disable_infowindows" type="checkbox"/>
743
+ <small>
744
+ <?php
745
+ _e("Enabling this setting will prevent any infowindows from opening for all your maps", "wp-google-maps");
746
+ ?>
747
+ </small>
748
+ </fieldset>
749
+ </div>
750
+
751
+ <!-- class="wpgmza-pro-feature" -->
752
+ <div id="marker-listing">
753
+
754
+ <h3>
755
+ <?php
756
+ esc_html_e("Marker Listing Settings","wp-google-maps");
757
+ ?>
758
+ </h3>
759
+
760
+ <p>
761
+ <?php
762
+ esc_html_e("Changing these settings will alter the way the marker list appears on your website.","wp-google-maps");
763
+ ?>
764
+ </p>
765
+
766
+ <div class="update-nag update-att wpgmza-upsell">
767
+ <i class="fa fa-arrow-circle-right"></i>
768
+ <a target="_blank"
769
+ href="<?php
770
+
771
+ echo esc_attr(\WPGMZA\Plugin::getProLink("https://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&amp;utm_medium=link&amp;utm_campaign=mlisting_settings"));
772
+
773
+ ?>">
774
+
775
+ <?php _e('Add Beautiful Marker Listings
776
+ </a>
777
+ to your maps with the Pro version for only $39.99 once off. Support and updates included forever.', 'wp-google-maps');
778
+ ?>
779
+
780
+ </div>
781
+
782
+ <h4>
783
+ <?php
784
+ esc_html_e("Advanced Marker Listing","wp-google-maps");
785
+ ?>
786
+ &amp;
787
+ <?php
788
+ esc_html_e("Basic Marker Listings","wp-google-maps");
789
+ ?>
790
+ </h4>
791
+
792
+ <fieldset class="wpgmza-pro-feature">
793
+
794
+ <legend>
795
+ <?php
796
+ _e("Column Visibility", "wp-google-maps");
797
+ ?>
798
+ </legend>
799
+
800
+ <ul>
801
+ <li>
802
+ <div class='switch'>
803
+ <input name='wpgmza_settings_markerlist_icon'
804
+ class='cmn-toggle cmn-toggle-round-flat'
805
+ type='checkbox'
806
+ id='wpgmza_settings_markerlist_icon' value='yes'/>
807
+
808
+ <label for='wpgmza_settings_markerlist_icon'></label>
809
+ </div>
810
+ <?php
811
+ esc_html_e("Hide the Icon column","wp-google-maps");
812
+ ?>
813
+ </li>
814
+
815
+ <li>
816
+ <div class='switch'>
817
+ <input name='wpgmza_settings_markerlist_link'
818
+ class='cmn-toggle cmn-toggle-round-flat'
819
+ type='checkbox'
820
+ id='wpgmza_settings_markerlist_link'
821
+ value='yes'/>
822
+ <label for='wpgmza_settings_markerlist_link'></label>
823
+ </div>
824
+ <?php
825
+ esc_html_e("Hide the Link column","wp-google-maps");
826
+ ?>
827
+ </li>
828
+
829
+ <li>
830
+ <div class='switch'>
831
+ <input name='wpgmza_settings_markerlist_title'
832
+ class='cmn-toggle cmn-toggle-round-flat'
833
+ type='checkbox'
834
+ id='wpgmza_settings_markerlist_title' value='yes'/>
835
+ <label for='wpgmza_settings_markerlist_title'></label>
836
+ </div>
837
+ <?php
838
+ esc_html_e("Hide the Title column","wp-google-maps");
839
+ ?>
840
+ </li>
841
+
842
+ <li>
843
+ <div class='switch'>
844
+ <input name='wpgmza_settings_markerlist_address'
845
+ class='cmn-toggle cmn-toggle-round-flat'
846
+ type='checkbox'
847
+ id='wpgmza_settings_markerlist_address'
848
+ value='yes'/>
849
+ <label for='wpgmza_settings_markerlist_address'></label>
850
+ </div>
851
+ <?php
852
+ esc_html_e("Hide the Address column","wp-google-maps");
853
+ ?>
854
+ </li>
855
+
856
+ <li>
857
+ <div class='switch'>
858
+ <input name='wpgmza_settings_markerlist_category'
859
+ class='cmn-toggle cmn-toggle-round-flat'
860
+ type='checkbox'
861
+ id='wpgmza_settings_markerlist_category'
862
+ value='yes'/>
863
+ <label for='wpgmza_settings_markerlist_category'></label>
864
+ </div>
865
+ <?php
866
+ esc_html_e("Hide the Category column","wp-google-maps");
867
+ ?>
868
+ </li>
869
+
870
+ <li>
871
+ <div class='switch'>
872
+ <input name='wpgmza_settings_markerlist_description'
873
+ class='cmn-toggle cmn-toggle-round-flat'
874
+ type='checkbox'
875
+ id='wpgmza_settings_markerlist_description'
876
+ value='yes'/>
877
+ <label for='wpgmza_settings_markerlist_description'></label>
878
+ </div>
879
+ <?php
880
+ esc_html_e("Hide the Description column","wp-google-maps");
881
+ ?>
882
+ </li>
883
+
884
+
885
+
886
+ </ul>
887
+
888
+ </fieldset>
889
+
890
+ <fieldset class="wpgmza-pro-feature">
891
+
892
+ <legend>
893
+ <?php
894
+ _e("Dependencies", "wp-google-maps");
895
+ ?>
896
+ </legend>
897
+
898
+ <ul>
899
+ <li>
900
+ <div class='switch'>
901
+ <input name='wpgmza_do_not_enqueue_datatables'
902
+ class='cmn-toggle cmn-toggle-round-flat'
903
+ type='checkbox'
904
+ id='wpgmza_do_not_enqueue_datatables'
905
+ value='yes'/>
906
+ <label for='wpgmza_do_not_enqueue_datatables'></label>
907
+ </div>
908
+ <?php
909
+ esc_html_e("Do not Enqueue Datatables","wp-google-maps");
910
+ ?>
911
+ </li>
912
+ </ul>
913
+ </fieldset>
914
+
915
+ <fieldset class="wpgmza-pro-feature">
916
+ <legend>
917
+ <?php
918
+ esc_html_e("Show X items by default","wp-google-maps");
919
+ ?>
920
+ </legend>
921
+
922
+ <select id='wpgmza_default_items' name='wpgmza_default_items'>
923
+ <option value="5">5</option>
924
+ <option value="10">10</option>
925
+ <option value="25">25</option>
926
+ <option value="50">50</option>
927
+ <option value="100">100</option>
928
+ <option value="-1">ALL</option>
929
+ </select>
930
+ </fieldset>
931
+
932
+ <h4>
933
+ <?php
934
+ esc_html_e("Carousel Marker Listing","wp-google-maps");
935
+ ?>
936
+ </h4>
937
+
938
+ <fieldset class="wpgmza-pro-feature">
939
+ <legend>
940
+ <?php
941
+ esc_html_e("Theme selection","wp-google-maps");
942
+ ?>
943
+ </legend>
944
+
945
+ <select id='wpgmza_settings_carousel_markerlist_theme'
946
+ name='wpgmza_settings_carousel_markerlist_theme'>
947
+ <option value="sky">
948
+ <?php
949
+ esc_html_e("Sky","wp-google-maps");
950
+ ?>
951
+ </option>
952
+ <option value="sun">
953
+ <?php
954
+ esc_html_e("Sun","wp-google-maps");
955
+ ?>
956
+ </option>
957
+ <option value="earth">
958
+ <?php
959
+ esc_html_e("Earth","wp-google-maps");
960
+ ?>
961
+ </option>
962
+ <option value="monotone">
963
+ <?php
964
+ esc_html_e("Monotone","wp-google-maps");
965
+ ?>
966
+ </option>
967
+ <option value="pinkpurple">
968
+ <?php
969
+ esc_html_e("PinkPurple","wp-google-maps"); ?>
970
+ </option>
971
+ <option value="white">
972
+ <?php
973
+ esc_html_e("White","wp-google-maps");
974
+ ?>
975
+ </option>
976
+ <option value="black">
977
+ <?php
978
+ esc_html_e("Black","wp-google-maps");
979
+ ?>
980
+ </option>
981
+ </select>
982
+ </fieldset>
983
+
984
+ <fieldset class="wpgmza-pro-feature">
985
+ <legend>
986
+ <?php
987
+ _e("Field Visibility", "wp-google-maps");
988
+ ?>
989
+ </legend>
990
+
991
+ <ul>
992
+ <li>
993
+ <div class='switch'><input name='wpgmza_settings_carousel_markerlist_image' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_image' value='yes'/><label for='wpgmza_settings_carousel_markerlist_image'></label></div>
994
+ <?php esc_html_e("Hide the Image","wp-google-maps"); ?><br />
995
+ </li>
996
+
997
+ <li>
998
+ <div class='switch'><input name='wpgmza_settings_carousel_markerlist_title' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_title' value='yes'/><label for='wpgmza_settings_carousel_markerlist_title'></label></div> <?php esc_html_e("Hide the Title","wp-google-maps"); ?>
999
+ </li>
1000
+
1001
+ <li>
1002
+ <div class='switch'><input name='wpgmza_settings_carousel_markerlist_icon' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_icon' value='yes'/><label for='wpgmza_settings_carousel_markerlist_icon'></label></div> <?php esc_html_e("Hide the Marker Icon","wp-google-maps"); ?>
1003
+ </li>
1004
+
1005
+ <li>
1006
+ <div class='switch'><input name='wpgmza_settings_carousel_markerlist_address' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_address' value='yes'/><label for='wpgmza_settings_carousel_markerlist_address'></label></div> <?php esc_html_e("Hide the Address","wp-google-maps"); ?>
1007
+ </li>
1008
+
1009
+ <li>
1010
+ <div class='switch'><input name='wpgmza_settings_carousel_markerlist_description' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_description' value='yes'/><label for='wpgmza_settings_carousel_markerlist_description'></label></div> <?php esc_html_e("Hide the Description","wp-google-maps"); ?>
1011
+ </li>
1012
+
1013
+ <li>
1014
+ <div class='switch'><input name='wpgmza_settings_carousel_markerlist_marker_link' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_marker_link' value='yes'/><label for='wpgmza_settings_carousel_markerlist_marker_link'></label></div> <?php esc_html_e("Hide the Marker Link","wp-google-maps"); ?>
1015
+ </li>
1016
+
1017
+ <li>
1018
+ <div class='switch'><input name='wpgmza_settings_carousel_markerlist_directions' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_directions' value='yes'/><label for='wpgmza_settings_carousel_markerlist_directions'></label></div> <?php esc_html_e("Hide the Directions Link","wp-google-maps"); ?>
1019
+ </li>
1020
+ </ul>
1021
+ </fieldset>
1022
+
1023
+ <fieldset class="wpgmza-pro-feature">
1024
+
1025
+ <legend>
1026
+ <?php
1027
+ esc_html_e("Image and Carousel options", "wp-google-maps");
1028
+ ?>
1029
+ </legend>
1030
+
1031
+ <ul>
1032
+ <li>
1033
+ <div class='switch'><input name='wpgmza_settings_carousel_markerlist_resize_image' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='wpgmza_settings_carousel_markerlist_resize_image' value='yes'/><label for='wpgmza_settings_carousel_markerlist_resize_image'></label></div> <?php esc_html_e("Resize Images with Timthumb","wp-google-maps"); ?>
1034
+ </li>
1035
+
1036
+ <li>
1037
+ <div class='switch'><input name='carousel_lazyload' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='carousel_lazyload' value='yes'/><label for='carousel_lazyload'></label></div> <?php esc_html_e("Enable lazyload of images","wp-google-maps"); ?>
1038
+ </li>
1039
+
1040
+ <li>
1041
+ <div class='switch'><input name='carousel_autoheight' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='carousel_autoheight' value='yes'/><label for='carousel_autoheight'></label></div> <?php esc_html_e("Enable autoheight","wp-google-maps"); ?>
1042
+ </li>
1043
+
1044
+ <li>
1045
+ <div class='switch'><input name='carousel_pagination' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='carousel_pagination' value='yes'/> <label for='carousel_pagination'></label></div><?php esc_html_e("Enable pagination","wp-google-maps"); ?>
1046
+ </li>
1047
+
1048
+ <li>
1049
+ <div class='switch'><input name='carousel_navigation' class='cmn-toggle cmn-toggle-round-flat' type='checkbox' id='carousel_navigation' value='yes'/><label for='carousel_navigation'></label></div> <?php esc_html_e("Enable navigation","wp-google-maps"); ?>
1050
+ </li>
1051
+
1052
+
1053
+ </ul>
1054
+
1055
+ </fieldset>
1056
+
1057
+ <fieldset class="wpgmza-pro-feature">
1058
+
1059
+ <legend>
1060
+ <?php
1061
+ _e("Dependencies", "wp-google-maps");
1062
+ ?>
1063
+ </legend>
1064
+
1065
+ <ul>
1066
+ <li>
1067
+ <div class='switch'>
1068
+ <input name='wpgmza_do_not_enqueue_owl_carousel'
1069
+ class='cmn-toggle cmn-toggle-round-flat'
1070
+ type='checkbox'
1071
+ id='wpgmza_do_not_enqueue_owl_carousel'
1072
+ value='yes'/>
1073
+ <label for='wpgmza_do_not_enqueue_owl_carousel'></label>
1074
+ </div>
1075
+ <?php
1076
+ esc_html_e("Do not Enqueue Owl Carousel","wp-google-maps");
1077
+ ?>
1078
+ </li>
1079
+
1080
+ <li>
1081
+ <div class='switch'>
1082
+ <input name='wpgmza_do_not_enqueue_owl_carousel_themes'
1083
+ class='cmn-toggle cmn-toggle-round-flat'
1084
+ type='checkbox'
1085
+ id='wpgmza_do_not_enqueue_owl_carousel_themes'
1086
+ value='yes'/>
1087
+ <label for='wpgmza_do_not_enqueue_owl_carousel_themes'></label>
1088
+ </div>
1089
+ <?php
1090
+ esc_html_e("Do not Enqueue Owl Theme","wp-google-maps");
1091
+ ?>
1092
+ </li>
1093
+ </ul>
1094
+ </fieldset>
1095
+
1096
+ <fieldset class="wpgmza-pro-feature">
1097
+ <legend>
1098
+ <?php
1099
+ esc_html_e("Responsivity Settings", "wp-google-maps")
1100
+ ?>
1101
+ </legend>
1102
+
1103
+ <ul>
1104
+ <li>
1105
+ <input name='carousel_items' type='text' id='carousel_items' value="5"/>
1106
+ <?php esc_html_e("Items","wp-google-maps"); ?>
1107
+ </li>
1108
+
1109
+ <li>
1110
+ <input name='carousel_items_tablet' type='text' id='carousel_items_tablet' value="3"/>
1111
+ <?php esc_html_e("Items (Tablet)","wp-google-maps"); ?>
1112
+ </li>
1113
+
1114
+ <li>
1115
+ <input name='carousel_items_mobile' type='text' id='carousel_items_mobile' value="1"/>
1116
+ <?php esc_html_e("Items (Mobile)","wp-google-maps"); ?>
1117
+ </li>
1118
+
1119
+ <li>
1120
+ <input name='carousel_autoplay' type='text' id='carousel_autoplay' value="5000"/>
1121
+ <?php esc_html_e("Autoplay after x milliseconds (1000 = 1 second)","wp-google-maps"); ?>
1122
+ </li>
1123
+ </ul>
1124
+ </fieldset>
1125
+
1126
+ </div>
1127
+
1128
+ <div id="store-locator">
1129
+ <fieldset>
1130
+ <legend><?php _e('Store Locator Radii', 'wp-google-maps'); ?></legend>
1131
+ <label>
1132
+ <input name="wpgmza_store_locator_radii" pattern="^\d+(,\s*\d+)*$"/>
1133
+ <p>
1134
+ <small>
1135
+ <?php _e('Use a comma to separate values, eg: 1, 5, 10, 50, 100', 'wp-google-maps'); ?>
1136
+ </small>
1137
+ </p>
1138
+ </label>
1139
+ </fieldset>
1140
+ </div>
1141
+
1142
+ <div id="advanced-settings">
1143
+ <h3><?php _e('API Keys', 'wp-google-maps'); ?></h3>
1144
+
1145
+ <fieldset data-required-maps-engine="google-maps">
1146
+ <legend><?php _e('Google Maps API Key (required)', 'wp-google-maps'); ?></legend>
1147
+ <label>
1148
+ <input name="wpgmza_google_maps_api_key" id='wpgmza_google_maps_api_key' style='width: 400px;'/>
1149
+ <p>
1150
+ <small>
1151
+ <?php
1152
+ _e("This API key can be obtained from
1153
+ the <a href='https://wpgmaps.com/google-maps-developer-console/' target='_BLANK'>Google Developers Console</a>. Our <a href='http://www.wpgmaps.com/documentation/creating-a-google-maps-api-key/' target='_BLANK'>documentation</a> provides a full guide on how to obtain this.", "wp-google-maps");
1154
+ ?>
1155
+ </small>
1156
+ </p>
1157
+ </label>
1158
+ </fieldset>
1159
+
1160
+ <fieldset data-required-maps-engine="google-maps" class="wpgmza-pro-feature">
1161
+ <legend class="wpgmza-pro-feature-hide">
1162
+ <?php
1163
+ _e("Alternative Import API Key", "wp-google-maps");
1164
+ ?>
1165
+ </legend>
1166
+ <label class="wpgmza-pro-feature-hide">
1167
+ <input name="importer_google_maps_api_key"/>
1168
+ <p>
1169
+ <small>
1170
+ <?php
1171
+ _e("Generate an IP restricted key to paste into this field if you are experiencing 'Request Denied' when running imports", "wp-google-maps");
1172
+ ?>
1173
+ </small>
1174
+ </p>
1175
+ </label>
1176
+ </fieldset>
1177
+
1178
+ <fieldset data-required-maps-engine="open-layers">
1179
+ <legend>
1180
+ <?php echo __('OpenLayers Tileserver Key', 'wp-google-maps'); ?>
1181
+ </legend>
1182
+ <label>
1183
+ <input name='open_layers_api_key'/>
1184
+ <p>
1185
+ <small>
1186
+ <?php _e("This is an optional API key provided by your preferred OpenLayers tile service, and should only be added if required by the TileServer provider", "wp-google-maps"); ?>
1187
+ </small>
1188
+ </p>
1189
+
1190
+ </label>
1191
+
1192
+ </fieldset>
1193
+
1194
+ <fieldset data-required-maps-engine="open-layers" class="wpgmza-pro-feature">
1195
+ <legend class="wpgmza-pro-feature-hide">
1196
+ <?php echo __('OpenRouteService Key', 'wp-google-maps'); ?>
1197
+ </legend>
1198
+ <label class="wpgmza-pro-feature-hide">
1199
+ <input name='open_route_service_key'/>
1200
+ <p>
1201
+ <small>
1202
+ <?php _e("This API key can be obtained from the <a href='https://openrouteservice.org/dev/#/login' target='_BLANK'>OpenRouteService Developers Console</a>.", "wp-google-maps"); ?>
1203
+ </small>
1204
+ </p>
1205
+
1206
+ </label>
1207
+
1208
+
1209
+ </fieldset>
1210
+
1211
+
1212
+
1213
+ <h3>
1214
+ <?php
1215
+ esc_html_e("Marker Data Location", "wp-google-maps");
1216
+ ?>
1217
+ </h3>
1218
+
1219
+ <p>
1220
+ <?php
1221
+ esc_html_e("We suggest that you change the two fields below ONLY if you are experiencing issues when trying to save the marker XML files.", "wp-google-maps");
1222
+ ?>
1223
+ </p>
1224
+
1225
+ <fieldset>
1226
+ <legend><?php esc_html_e("Pull marker data from", "wp-google-maps"); ?></legend>
1227
+
1228
+ <ul>
1229
+ <li>
1230
+ <label>
1231
+ <input name="wpgmza_settings_marker_pull" value="0" type="radio" checked="checked"/>
1232
+ <?php
1233
+ esc_html_e("Database", "wp-google-maps");
1234
+ ?>
1235
+ </label>
1236
+ </li>
1237
+ <li>
1238
+ <label>
1239
+ <input name="wpgmza_settings_marker_pull" value="1" type="radio"/>
1240
+ <?php
1241
+ esc_html_e("XML File", "wp-google-maps");
1242
+ ?>
1243
+ </label>
1244
+ </li>
1245
+ </ul>
1246
+ </fieldset>
1247
+
1248
+ <fieldset id="xml-cache-settings">
1249
+
1250
+ <fieldset>
1251
+ <legend><?php esc_html_e("Marker data XML directory", "wp-google-maps"); ?></legend>
1252
+ <input name="wpgmza_marker_xml_location" class="regular-text code"/>
1253
+ <p>
1254
+ <small>
1255
+ <?php esc_html_e("You can use the following", "wp-google-maps"); ?>
1256
+ : {wp_content_dir},{plugins_dir},{uploads_dir}
1257
+ </small>
1258
+ </p>
1259
+ <p>
1260
+ <small>
1261
+ <?php esc_html_e("Currently using", "wp-google-maps"); ?>
1262
+ <strong>
1263
+ NB: Add $marker_location here
1264
+ </strong>
1265
+ </small>
1266
+ </p>
1267
+ <!-- NB: See wpgmza_file_perms_check in legacy-core.php -->
1268
+ </fieldset>
1269
+
1270
+ <fieldset>
1271
+ <legend><?php esc_html_e("Marker data XML URL", "wp-google-maps"); ?></legend>
1272
+ <input name="wpgmza_marker_xml_url" class="regular-text code"/>
1273
+ <p>
1274
+ <small>
1275
+ <?php esc_html_e("You can use the following", "wp-google-maps"); ?>
1276
+ : {wp_content_dir},{plugins_dir},{uploads_dir}
1277
+ </small>
1278
+ </p>
1279
+ <p>
1280
+ <small>
1281
+ <?php esc_html_e("Currently using", "wp-google-maps"); ?>
1282
+ <strong>
1283
+ NB: Add $marker_url here
1284
+ </strong>
1285
+ </small>
1286
+ </p>
1287
+ <!-- NB: See wpgmza_file_perms_check in legacy-core.php -->
1288
+ </fieldset>
1289
+
1290
+ </fieldset>
1291
+
1292
+ <!--<fieldset id="library-script-panel-container"></fieldset>-->
1293
+
1294
+ <h3><?php esc_html_e('Custom Scripts', 'wp-google-maps'); ?></h3>
1295
+
1296
+ <fieldset>
1297
+ <legend>
1298
+ <?php esc_html_e('Custom CSS', 'wp-google-maps'); ?>
1299
+ </legend>
1300
+ <textarea name="wpgmza_custom_css"></textarea>
1301
+ </fieldset>
1302
+
1303
+ <fieldset>
1304
+ <legend>
1305
+ <?php esc_html_e('Custom JS', 'wp-google-maps'); ?>
1306
+ </legend>
1307
+ <textarea name="wpgmza_custom_js"></textarea>
1308
+ </fieldset>
1309
+
1310
+ <h3 data-required-maps-engine="open-layers"><?php esc_html_e('Other Caching', 'wp-google-maps'); ?></h3>
1311
+
1312
+ <fieldset data-required-maps-engine="open-layers">
1313
+ <legend>
1314
+ <?php _e("Flush Geocode Cache", "wp-google-maps"); ?>
1315
+ </legend>
1316
+ <button id="wpgmza_flush_cache_btn" class="button-primary">
1317
+ <?php _e('Flush', 'wp-google-maps'); ?>
1318
+ </button>
1319
+ </fieldset>
1320
+
1321
+ <h3><?php esc_html_e('Danger Zone', 'wp-google-maps'); ?></h3>
1322
+ <?php echo wpgmaps_danger_zone_nonce(); ?>
1323
+ <fieldset id="wpgmza-destroy-data" class='wpgmza-danger-zone'>
1324
+ <legend><?php esc_html_e("Data Management", "wp-google-maps"); ?></legend>
1325
+
1326
+ <p>
1327
+ <label>
1328
+ <button danger="wpgmza_destroy_all_data" name="wpgmza_destroy_data" class="wpgmza_destroy_data wpgmza_general_btn button button-secondary">Complete Reset</button>
1329
+
1330
+ <small class="wpgmza-button-hint-small">
1331
+ <?php
1332
+ esc_html_e('This will delete all settings, maps, markers, shapes, categories, and custom fields and reset the plugin back to the first time you used it.', 'wp-google-maps');
1333
+ ?>
1334
+ </small>
1335
+
1336
+ </label>
1337
+ </p>
1338
+ <p>&nbsp;</p>
1339
+ <p>
1340
+ <label>
1341
+ <button danger="wpgmza_reset_all_settings" name="wpgmza_destroy_data" class="wpgmza_destroy_data wpgmza_general_btn button button-secondary">Reset all settings</button>
1342
+
1343
+ <small class="wpgmza-button-hint-small">
1344
+ <?php
1345
+ esc_html_e('This will reset all settings back to their default.', 'wp-google-maps');
1346
+ ?>
1347
+ </small>
1348
+
1349
+ </label>
1350
+ </p>
1351
+ <p>&nbsp;</p>
1352
+ <p class="wpgmza-pro-feature-hide">
1353
+ <label>
1354
+ <button danger="wpgmza_destroy_maps" name="wpgmza_destroy_data" class="wpgmza_destroy_data wpgmza_general_btn button button-secondary">Delete all maps</button>
1355
+
1356
+ <small class="wpgmza-button-hint-small">
1357
+ <?php
1358
+ esc_html_e('This will delete all maps, markers, shapes, categories, and custom fields.', 'wp-google-maps');
1359
+ ?>
1360
+ </small>
1361
+
1362
+ </label>
1363
+ </p>
1364
+ <p>
1365
+ <label>
1366
+ <button danger="wpgmza_destroy_markers" name="wpgmza_destroy_data" class="wpgmza_destroy_data wpgmza_general_btn button button-secondary">Delete all markers</button>
1367
+
1368
+ <small class="wpgmza-button-hint-small">
1369
+ <?php
1370
+ esc_html_e('This will delete all markers.', 'wp-google-maps');
1371
+ ?>
1372
+ </small>
1373
+
1374
+ </label>
1375
+ </p>
1376
+ <p>
1377
+ <label>
1378
+ <button danger="wpgmza_destroy_shapes" name="wpgmza_destroy_data" class="wpgmza_destroy_data wpgmza_general_btn button button-secondary">Delete all shapes</button>
1379
+
1380
+ <small class="wpgmza-button-hint-small">
1381
+ <?php
1382
+ esc_html_e('This will delete all shapes.', 'wp-google-maps');
1383
+ ?>
1384
+ </small>
1385
+
1386
+ </label>
1387
+ </p>
1388
+
1389
+ </fieldset>
1390
+
1391
+
1392
+ <h3><?php esc_html_e('Miscellaneous Settings', 'wp-google-maps'); ?></h3>
1393
+
1394
+ <fieldset>
1395
+ <legend><?php esc_html_e('Disable Compressed Path Variables', 'wp-google-maps'); ?></legend>
1396
+ <label>
1397
+ <input name="disable_compressed_path_variables" type="checkbox"/>
1398
+
1399
+ <small>
1400
+ <?php
1401
+ esc_html_e('We recommend using this setting if you frequently experience HTTP 414 - Request URI too long. We do not recommend using this setting if your site uses REST caching or a CDN.', 'wp-google-maps');
1402
+ ?>
1403
+ </small>
1404
+
1405
+ </label>
1406
+ </fieldset>
1407
+
1408
+ <fieldset>
1409
+ <legend><?php esc_html_e("Disable Autoptimize Compatibility Fix", "wp-google-maps"); ?></legend>
1410
+ <label>
1411
+ <input name="disable_autoptimize_compatibility_fix" type="checkbox"/>
1412
+
1413
+ <small>
1414
+ <?php
1415
+ esc_html_e("Use this setting if you are experiencing issues with Autoptimize's CSS aggregation. This may cause issues on setups with a large amount of marker data.", "wp-google-maps");
1416
+ ?>
1417
+ </small>
1418
+
1419
+ </label>
1420
+ </fieldset>
1421
+
1422
+ <fieldset id="wpgmza-disable-automatic-backups" class="wpgmza-pro-feature">
1423
+ <legend><?php esc_html_e("Disable Automatic Backups (beta)", "wp-google-maps"); ?></legend>
1424
+ <label>
1425
+ <input name="disable_automatic_backups" type="checkbox"/>
1426
+
1427
+ <small>
1428
+ <?php
1429
+ esc_html_e('We recommend leaving automatic backups enabled. We will automatically backup your data before an import or update to our plugin.', 'wp-google-maps');
1430
+ ?>
1431
+ </small>
1432
+
1433
+ </label>
1434
+ </fieldset>
1435
+
1436
+ <fieldset id="wpgmza-developer-mode">
1437
+ <legend><?php esc_html_e("Developer Mode", "wp-google-maps"); ?></legend>
1438
+ <label>
1439
+ <input name="wpgmza_developer_mode" type="checkbox"/>
1440
+
1441
+ <small>
1442
+ <?php
1443
+ esc_html_e('Always rebuilds combined script files and script cache, does not load combined and minified scripts. Includes database query SQL with REST API responses.', 'wp-google-maps');
1444
+ ?>
1445
+ </small>
1446
+
1447
+ </label>
1448
+ </fieldset>
1449
+
1450
+
1451
+
1452
+ </div>
1453
+
1454
+ <div id="gdpr-compliance">
1455
+ <div id="wpgmza-gdpr-compliance">
1456
+
1457
+ <div>
1458
+ <h3><?php _e( 'GDPR Compliance', 'wp-google-maps' ); ?></h3>
1459
+ <p>
1460
+ <?php
1461
+ _e('Our GDPR notice will be displayed whenever the agreement cookie is not set. Agreeing to the notice will set this cookie.', 'wp-google-maps');
1462
+ ?>
1463
+ </p>
1464
+ <p>
1465
+ <?php
1466
+ _e('Some caching and optimization plugins will continue to serve your map page with the GDPR agreement, disregarding this cookie. In this instance, clicking "I Agree" will reload the page and appear to have no effect. To solve this issue, we recommend you exclude your map page from caching and optimization.', 'wp-google-maps');
1467
+ ?>
1468
+ </p>
1469
+ </div>
1470
+
1471
+
1472
+ <div id="wpgmza-gpdr-general-compliance">
1473
+
1474
+ <h2>
1475
+ <?php _e('General Complicance', 'wp-google-maps'); ?>
1476
+ </h2>
1477
+
1478
+
1479
+ <fieldset>
1480
+
1481
+ <label for="wpgmza_gdpr_require_consent_before_load">
1482
+ <?php
1483
+ _e('Require consent before loading Maps API', 'wp-google-maps');
1484
+ ?>
1485
+ <i class="fa fa-question-circle"
1486
+ title="<?php _e('The GDPR views IP Addresses as Personal Data, which requires consent before being processed. Loading the Google Maps API stores some user information, such as IP Addresses. WP Google Maps endeavours to uphold the spirit of data protection as per the GDPR. Enable this to option to prevent the Maps API from loading, until a user has consented to it.', 'wp-google-maps'); ?>"/>
1487
+ </label>
1488
+ <input name="wpgmza_gdpr_require_consent_before_load" type="checkbox"/>
1489
+ </fieldset>
1490
+
1491
+ <span class="notice notice-error wpgmza-complianz-notice wpgmza-hidden" style="margin-left: 0; display: block;">
1492
+ <strong><?php _e("Important Note", "wp-google-maps"); ?>:</strong>
1493
+ <?php
1494
+ _e('GDPR consent automatically enabled and configured by Complianz', 'wp-google-maps');
1495
+ ?>
1496
+ <br><br>
1497
+ <?php
1498
+ _e('WP Google Maps GDPR options have been disabled as they are fully controlled by Complianz', 'wp-google-maps');
1499
+ ?>
1500
+ </span>
1501
+ </div>
1502
+
1503
+
1504
+ <div id="wpgmza-gdpr-compliance-notice" style="display: none;">
1505
+
1506
+ <h2>
1507
+ <?php _e('GDPR Consent Notice', 'wp-google-maps'); ?>
1508
+ </h2>
1509
+
1510
+ <fieldset>
1511
+ <legend>
1512
+ <label for="wpgmza_gdpr_default_notice">
1513
+ <?php
1514
+ _e('GDPR Notice', 'wp-google-maps');
1515
+ ?>
1516
+ <i class="fa fa-question-circle"
1517
+ title="<?php _e('Users will be asked to accept the notice shown here, in the form of a check box.', 'wp-google-maps'); ?>"></i>
1518
+ </label>
1519
+ </legend>
1520
+ <div name="wpgmza_gdpr_default_notice"></div>
1521
+ </fieldset>
1522
+
1523
+ <fieldset>
1524
+ <legend>
1525
+ <label for="wpgmza_gdpr_company_name">
1526
+ <?php
1527
+ _e('Company Name', 'wp-google-maps');
1528
+ ?>
1529
+ </label>
1530
+ </legend>
1531
+ <span class="settings-group">
1532
+ <input name="wpgmza_gdpr_company_name"/>
1533
+ </span>
1534
+ </fieldset>
1535
+
1536
+
1537
+ <fieldset>
1538
+ <legend>
1539
+ <label for="wpgmza_gdpr_retention_purpose">
1540
+ <?php
1541
+ _e('Retention Purpose(s)', 'wp-google-maps');
1542
+ ?>
1543
+ </label>
1544
+ </legend>
1545
+ <span class="settings-group">
1546
+ <div>
1547
+ <input name="wpgmza_gdpr_retention_purpose"/>
1548
+ <br/>
1549
+ <small>
1550
+ <?php
1551
+ _e('The GDPR regulates that you need to state why you are processing data.', 'wp-google-maps');
1552
+ ?>
1553
+ </small>
1554
+ </div>
1555
+ </span>
1556
+ </fieldset>
1557
+
1558
+ <fieldset>
1559
+ <legend>
1560
+ <label for="wpgmza_gdpr_override_notice">
1561
+ <?php
1562
+ _e('Override GDPR Notice', 'wp-google-maps');
1563
+ ?>
1564
+ <input name="wpgmza_gdpr_override_notice" type="checkbox" id="wpgmza_gdpr_override_notice"/>
1565
+ </label>
1566
+ </legend>
1567
+ </fieldset>
1568
+
1569
+ <span class="notice notice-error" style="padding: 0.5em; display: block;">
1570
+ <?php
1571
+ _e('By checking this box, you agree to take sole responsibility for GDPR Compliance with regards to this plugin.', 'wp-google-maps');
1572
+ ?>
1573
+ </span>
1574
+
1575
+ <fieldset id="wpgmza_gdpr_override_notice_text">
1576
+ <legend>
1577
+ <label for="wpgmza_gdpr_override_notice_text">
1578
+ <?php
1579
+ _e('Override Text', 'wp-google-maps');
1580
+ ?>
1581
+ </label>
1582
+ </legend>
1583
+ <span class="settings-group">
1584
+ <textarea name="wpgmza_gdpr_notice_override_text"></textarea>
1585
+ </span>
1586
+ </fieldset>
1587
+
1588
+
1589
+ </div>
1590
+
1591
+ <p>
1592
+ <?php
1593
+ _e('For more information about WPGM and GDPR compliance, please refer to our <a href="https://www.wpgmaps.com/gdpr/">GDPR information page</a> and our <a href="https://www.wpgmaps.com/privacy-policy/">Privacy Policy</a>', 'wp-google-maps');
1594
+ ?>
1595
+ </p>
1596
+ </div>
1597
+ </div>
1598
+
1599
+ <div class="addition-tabs">
1600
+
1601
+ </div>
1602
+
1603
+ <p style="text-align: right;">
1604
+ <button type="submit" class="button button-primary">
1605
+ <?php
1606
+ esc_html_e("Save Settings", "wp-google-maps");
1607
+ ?>
1608
+ </button>
1609
+ </p>
1610
+
1611
  </form>
html/support.html.php CHANGED
@@ -1,102 +1,102 @@
1
- <div class="wrap">
2
- <h1><?php _e("WP Google Maps Support","wp-google-maps"); ?></h1>
3
- <div id="wpgmza-support__row" class="wpgmza_row">
4
- <div class='wpgmza_row_col wpgmza-support__col'>
5
- <div class="wpgmza-card">
6
- <h2>
7
- <i class="fa fa-book"></i>
8
- <?php _e("Documentation","wp-google-maps"); ?>
9
- </h2>
10
- <p>
11
- <?php _e("Getting started? Read through some of these articles to help you along your way.","wp-google-maps"); ?>
12
- </p>
13
- <p>
14
- <strong>
15
- <?php _e("Documentation:","wp-google-maps"); ?>
16
- </strong>
17
- </p>
18
- <ul>
19
- <li>
20
- <a href='https://www.wpgmaps.com/documentation/creating-your-first-map/'
21
- target='_BLANK'
22
- title='<?php _e("Creating your first map","wp-google-maps"); ?>'>
23
- <?php
24
- _e("Creating your first map","wp-google-maps");
25
- ?>
26
- </a>
27
- </li>
28
- <li>
29
- <a href='https://www.wpgmaps.com/documentation/using-your-map-in-a-widget/'
30
- target='_BLANK'
31
- title='<?php _e("Using your map as a Widget","wp-google-maps"); ?>'>
32
- <?php
33
- _e("Using your map as a Widget","wp-google-maps");
34
- ?>
35
- </a>
36
- </li>
37
- <li>
38
- <a href='https://www.wpgmaps.com/documentation/changing-the-google-maps-language/'
39
- target='_BLANK'
40
- title='<?php _e("Changing the Google Maps language","wp-google-maps"); ?>'>
41
- <?php
42
- _e("Changing the Google Maps language","wp-google-maps");
43
- ?>
44
- </a>
45
- </li>
46
- <li>
47
- <a href='https://www.wpgmaps.com/documentation/'
48
- target='_BLANK'
49
- title='<?php _e("WP Google Maps Documentation","wp-google-maps"); ?>'>
50
- <?php
51
- _e("View all documentation.","wp-google-maps");
52
- ?>
53
- </a>
54
- </li>
55
- </ul>
56
- </div>
57
- </div>
58
- <div class='wpgmza_row_col wpgmza-support__col'>
59
- <div class="wpgmza-card">
60
- <h2>
61
- <i class="fa fa-exclamation-circle"></i>
62
- <?php
63
- _e("Troubleshooting","wp-google-maps");
64
- ?>
65
- </h2>
66
- <p>
67
- <?php
68
- _e("WP Google Maps has a diverse and wide range of features which may, from time to time, run into conflicts with the thousands of themes and other plugins on the market.","wp-google-maps");
69
- ?>
70
- </p>
71
- <p>
72
- <strong>
73
- <?php _e("Common issues:","wp-google-maps"); ?>
74
- </strong>
75
- </p>
76
- <ul>
77
- <li>
78
- <a href='https://www.wpgmaps.com/documentation/troubleshooting/my-map-is-not-showing-on-my-website/' target='_BLANK' title='<?php _e("My map is not showing on my website","wp-google-maps"); ?>'><?php _e("My map is not showing on my website","wp-google-maps"); ?></a>
79
- </li>
80
- <li>
81
- <a href='https://www.wpgmaps.com/documentation/troubleshooting/my-markers-are-not-showing-on-my-map/' target='_BLANK' title='<?php _e("My markers are not showing on my map in the front-end","wp-google-maps"); ?>'><?php _e("My markers are not showing on my map in the front-end","wp-google-maps"); ?></a>
82
- </li>
83
- <li>
84
- <a href='https://www.wpgmaps.com/documentation/troubleshooting/im-getting-jquery-errors-showing-on-my-website/' target='_BLANK' title='<?php esc_attr_e("I'm getting jQuery errors showing on my website","wp-google-maps"); ?>'><?php _e("I'm getting jQuery errors showing on my website","wp-google-maps"); ?></a>
85
- </li>
86
- </ul>
87
- </div>
88
- </div>
89
- <div class='wpgmza_row_col wpgmza-support__col'>
90
- <div class="wpgmza-card">
91
- <h2><i class="fa fa-bullhorn "></i> <?php _e("Support","wp-google-maps"); ?></h2>
92
- <p><?php _e("Still need help? Use one of these links below.","wp-google-maps"); ?></p>
93
- <ul>
94
- <li><a href='https://www.wpgmaps.com/forums/' target='_BLANK' title='<?php _e("Support forum","wp-google-maps"); ?>'><?php _e("Support forum","wp-google-maps"); ?></a></li>
95
- <li><a href='https://www.facebook.com/groups/wpgooglemaps' target='_BLANK' title='<?php _e("Support forum","wp-google-maps"); ?>'><?php _e("Facebook Community","wp-google-maps"); ?></a></li>
96
- <li><a href='https://www.reddit.com/r/wpgooglemaps/' target='_BLANK' title='<?php _e("Support forum","wp-google-maps"); ?>'><?php _e("Reddit Community","wp-google-maps"); ?></a></li>
97
- <li><a href='https://www.wpgmaps.com/contact-us/' target='_BLANK' title='<?php _e("Contact us","wp-google-maps"); ?>'><?php _e("Contact us","wp-google-maps"); ?></a></li>
98
- </ul>
99
- </div>
100
- </div>
101
- </div>
102
- </div>
1
+ <div class="wrap">
2
+ <h1><?php _e("WP Google Maps Support","wp-google-maps"); ?></h1>
3
+ <div id="wpgmza-support__row" class="wpgmza_row">
4
+ <div class='wpgmza_row_col wpgmza-support__col'>
5
+ <div class="wpgmza-card">
6
+ <h2>
7
+ <i class="fa fa-book"></i>
8
+ <?php _e("Documentation","wp-google-maps"); ?>
9
+ </h2>
10
+ <p>
11
+ <?php _e("Getting started? Read through some of these articles to help you along your way.","wp-google-maps"); ?>
12
+ </p>
13
+ <p>
14
+ <strong>
15
+ <?php _e("Documentation:","wp-google-maps"); ?>
16
+ </strong>
17
+ </p>
18
+ <ul>
19
+ <li>
20
+ <a href='https://www.wpgmaps.com/documentation/creating-your-first-map/'
21
+ target='_BLANK'
22
+ title='<?php _e("Creating your first map","wp-google-maps"); ?>'>
23
+ <?php
24
+ _e("Creating your first map","wp-google-maps");
25
+ ?>
26
+ </a>
27
+ </li>
28
+ <li>
29
+ <a href='https://www.wpgmaps.com/documentation/using-your-map-in-a-widget/'
30
+ target='_BLANK'
31
+ title='<?php _e("Using your map as a Widget","wp-google-maps"); ?>'>
32
+ <?php
33
+ _e("Using your map as a Widget","wp-google-maps");
34
+ ?>
35
+ </a>
36
+ </li>
37
+ <li>
38
+ <a href='https://www.wpgmaps.com/documentation/changing-the-google-maps-language/'
39
+ target='_BLANK'
40
+ title='<?php _e("Changing the Google Maps language","wp-google-maps"); ?>'>
41
+ <?php
42
+ _e("Changing the Google Maps language","wp-google-maps");
43
+ ?>
44
+ </a>
45
+ </li>
46
+ <li>
47
+ <a href='https://www.wpgmaps.com/documentation/'
48
+ target='_BLANK'
49
+ title='<?php _e("WP Google Maps Documentation","wp-google-maps"); ?>'>
50
+ <?php
51
+ _e("View all documentation.","wp-google-maps");
52
+ ?>
53
+ </a>
54
+ </li>
55
+ </ul>
56
+ </div>
57
+ </div>
58
+ <div class='wpgmza_row_col wpgmza-support__col'>
59
+ <div class="wpgmza-card">
60
+ <h2>
61
+ <i class="fa fa-exclamation-circle"></i>
62
+ <?php
63
+ _e("Troubleshooting","wp-google-maps");
64
+ ?>
65
+ </h2>
66
+ <p>
67
+ <?php
68
+ _e("WP Google Maps has a diverse and wide range of features which may, from time to time, run into conflicts with the thousands of themes and other plugins on the market.","wp-google-maps");
69
+ ?>
70
+ </p>
71
+ <p>
72
+ <strong>
73
+ <?php _e("Common issues:","wp-google-maps"); ?>
74
+ </strong>
75
+ </p>
76
+ <ul>
77
+ <li>
78
+ <a href='https://www.wpgmaps.com/documentation/troubleshooting/my-map-is-not-showing-on-my-website/' target='_BLANK' title='<?php _e("My map is not showing on my website","wp-google-maps"); ?>'><?php _e("My map is not showing on my website","wp-google-maps"); ?></a>
79
+ </li>
80
+ <li>
81
+ <a href='https://www.wpgmaps.com/documentation/troubleshooting/my-markers-are-not-showing-on-my-map/' target='_BLANK' title='<?php _e("My markers are not showing on my map in the front-end","wp-google-maps"); ?>'><?php _e("My markers are not showing on my map in the front-end","wp-google-maps"); ?></a>
82
+ </li>
83
+ <li>
84
+ <a href='https://www.wpgmaps.com/documentation/troubleshooting/im-getting-jquery-errors-showing-on-my-website/' target='_BLANK' title='<?php esc_attr_e("I'm getting jQuery errors showing on my website","wp-google-maps"); ?>'><?php _e("I'm getting jQuery errors showing on my website","wp-google-maps"); ?></a>
85
+ </li>
86
+ </ul>
87
+ </div>
88
+ </div>
89
+ <div class='wpgmza_row_col wpgmza-support__col'>
90
+ <div class="wpgmza-card">
91
+ <h2><i class="fa fa-bullhorn "></i> <?php _e("Support","wp-google-maps"); ?></h2>
92
+ <p><?php _e("Still need help? Use one of these links below.","wp-google-maps"); ?></p>
93
+ <ul>
94
+ <li><a href='https://www.wpgmaps.com/forums/' target='_BLANK' title='<?php _e("Support forum","wp-google-maps"); ?>'><?php _e("Support forum","wp-google-maps"); ?></a></li>
95
+ <li><a href='https://www.facebook.com/groups/wpgooglemaps' target='_BLANK' title='<?php _e("Support forum","wp-google-maps"); ?>'><?php _e("Facebook Community","wp-google-maps"); ?></a></li>
96
+ <li><a href='https://www.reddit.com/r/wpgooglemaps/' target='_BLANK' title='<?php _e("Support forum","wp-google-maps"); ?>'><?php _e("Reddit Community","wp-google-maps"); ?></a></li>
97
+ <li><a href='https://www.wpgmaps.com/contact-us/' target='_BLANK' title='<?php _e("Contact us","wp-google-maps"); ?>'><?php _e("Contact us","wp-google-maps"); ?></a></li>
98
+ </ul>
99
+ </div>
100
+ </div>
101
+ </div>
102
+ </div>
html/welcome.html.php CHANGED
@@ -1,164 +1,164 @@
1
- <?php
2
-
3
- if(!defined('ABSPATH'))
4
- exit;
5
-
6
- ?>
7
-
8
- <?php global $wpgmza_global_array; ?>
9
- <div id="wpgmza-welcome-page" class="wrap about-wrap">
10
- <p>&nbsp;</p>
11
-
12
- <img style="width: 512px;" src="<?php echo WPGMZA_PLUGIN_DIR_URL . 'images/new-banner.png'; ?>" alt="WP Google Maps"/>
13
-
14
- <h1><?php
15
-
16
- global $wpgmza;
17
- printf(__("Welcome to WP Google Maps version %s","wp-google-maps"), $wpgmza->getBasicVersion());
18
-
19
- ?></h1>
20
-
21
- <div class="about-text"><?php _e("Build amazing maps through a simple interface and powerful functionality along with world class support.","wp-google-maps"); ?></div>
22
-
23
- <a class="button-primary" style='padding:5px; padding-right:15px; padding-left:15px; height:inherit;' href="admin.php?page=wp-google-maps-menu&amp;override=1"><?php echo __("Skip intro and create a map","wp-google-maps"); ?></a>
24
- <p>&nbsp;</p>
25
-
26
-
27
- <h2 class="nav-tab-wrapper wp-clearfix">
28
- <a href="admin.php?page=wp-google-maps-menu&amp;action=welcome_page" class="nav-tab nav-tab-active"><?php _e("Welcome","wp-google-maps"); ?></a>
29
- <a href="admin.php?page=wp-google-maps-menu&amp;action=credits" class="nav-tab"><?php _e("Credits","wp-google-maps"); ?></a>
30
-
31
- </h2>
32
-
33
- <div id="wpgmza-support__row" class="feature-section three-col">
34
- <div class='col wpgmza-support__col wpgmza-margin-0'>
35
- <div class="wpgmza-card">
36
- <h4><?php _e("Facebook Group","wp-google-maps"); ?></h4>
37
- <p><?php _e("Join our Facebook Community","wp-google-maps"); ?></p>
38
-
39
- <a href="https://www.facebook.com/groups/wpgooglemaps" class="button-primary" target="_BLANK"><?php _e("Join Facebook", "wp-google-maps"); ?></a>
40
- <br><br>
41
- <small style="opacity: 0.8;"><?php _e("Get to know other WP Google Maps users, receive updates on upcoming features, and share your maps with the community", "wp-google-maps"); ?></small>
42
- </div>
43
- </div>
44
- <div class='col wpgmza-support__col wpgmza-margin-0'>
45
- <div class="wpgmza-card">
46
- <h4><?php _e("Reddit","wp-google-maps"); ?></h4>
47
- <p><?php _e("Join our Reddit Community","wp-google-maps"); ?></p>
48
-
49
- <a href="https://www.reddit.com/r/wpgooglemaps/" class="button-primary" target="_BLANK"><?php _e("Join Subreddit", "wp-google-maps"); ?></a>
50
- <br><br>
51
- <small style="opacity: 0.8;"><?php _e("Share your maps, speak to the development team, receive updates on upcoming features, and view release specific changelogs", "wp-google-maps"); ?></small>
52
- </div>
53
- </div>
54
- <div class='col wpgmza-support__col wpgmza-margin-0'>
55
- <div class="wpgmza-card">
56
- <h4><?php _e("Newsletters","wp-google-maps"); ?></h4>
57
- <p><?php _e("Receive specials, guides and latest news", "wp-google-maps"); ?></p>
58
-
59
- <a href="admin.php?page=wp-google-maps-menu&amp;action=newsletter_opt_in" class="button-primary" target="_BLANK"><?php _e("Join Newsletter", "wp-google-maps"); ?></a>
60
- <br><br>
61
- <small style="opacity: 0.8;"><?php printf(__("* Clicking this button will send your email address (%s) to our server and automatically sign you up to the newsletter","wp-google-maps"), get_option('admin_email')); ?></small>
62
- </div>
63
- </div>
64
- </div>
65
-
66
- <div class="wpgmza-flex feature-section two-col">
67
- <div class="col wpgmza-flex-grid__item">
68
- <div class="wpgmza-card">
69
- <h4><?php _e("Unlimited Markers","wp-google-maps"); ?></h4>
70
- <p><?php _e("Create as many markers as you like","wp-google-maps"); ?></p>
71
- <img src='<?php echo WPGMZA_PLUGIN_DIR_URL . 'images/unlimited-markers.png'; ?>' style="border:1px solid #ccc;" />
72
- </div>
73
- </div>
74
- <div class="col wpgmza-flex-grid__item">
75
- <div class="wpgmza-card">
76
- <h4><?php _e("Store Locator","wp-google-maps"); ?></h4>
77
- <p><?php _e("Let users search for products, branches and stores near them","wp-google-maps"); ?></p>
78
- <img src='<?php echo WPGMZA_PLUGIN_DIR_URL . 'images/store-locator.png'; ?>' style="border:1px solid #ccc;" />
79
- </div>
80
- </div>
81
- </div>
82
- <div class="wpgmza-flex feature-section two-col">
83
- <div class="col wpgmza-flex-grid__item">
84
- <div class="wpgmza-card">
85
- <h4><?php _e("Themes","wp-google-maps"); ?></h4>
86
- <p><?php _e("Select from various <a href='http://wpgmaps.com/map-themes/' target='_BLANK'>map themes</a>, or make your own.","wp-google-maps"); ?></p>
87
- <img src='<?php echo WPGMZA_PLUGIN_DIR_URL . 'images/themes.png' ?>;' style="border:1px solid #ccc;" />
88
- </div>
89
- </div>
90
- <div class="col wpgmza-flex-grid__item">
91
- <div class="wpgmza-card">
92
- <h4><?php _e("Polylines","wp-google-maps"); ?>, <?php _e("Polygons","wp-google-maps"); ?>, <?php _e("Circles","wp-google-maps"); ?>, <?php _e("and Squares","wp-google-maps"); ?></h4>
93
- <p><?php _e("Add custom shapes such as polygons, polylines, circles and squares!","wp-google-maps"); ?></p>
94
- <img src='<?php echo WPGMZA_PLUGIN_DIR_URL . 'images/polygons-and-polylines.png' ?>;' style="border:1px solid #ccc;" />
95
- </div>
96
- </div>
97
- </div>
98
-
99
- <div class="feature-section normal clear" >
100
- <div class="changelog ">
101
-
102
- <?php if (false) {
103
-
104
- // NB: GDPR
105
- ?>
106
-
107
- <!--<h3 style='margin-top:20px;'><?php _e("How did you find out about us?","wp-google-maps"); ?></h3>
108
-
109
- <div class="feature-section normal">
110
- <form action='' method='POST' name='wpgmaps_feedback'>
111
- <p><ul class="wpgmza_welcome_poll" style="list-style: none outside none;">
112
- <li style="list-style: none outside none;">
113
- <input type="radio" id="wpgmaps_findus_repository" value="repository" name="wpgmaps_findus">
114
- <label for="wpgmaps_search_term"><?php _e("WordPress.org plugin repository","wp-google-maps"); ?></label>
115
- <br /><input type="text" id="wpgmaps_search_term" class="regular-text" style='margin-top:5px; margin-left:40px;' name="wpgmaps_search_term" placeholder="<?php _e("What search term did you use?","wp-google-maps"); ?>">
116
- </li>
117
- <li style="list-style: none outside none;">
118
- <input type="radio" id="wpgmaps_findus_searchengine" value="search_engine" name="wpgmaps_findus">
119
- <label for="wpgmaps_findus_searchengine"><?php _e("Google or other search engine","wp-google-maps"); ?></label>
120
- </li>
121
- <li style="list-style: none outside none;">
122
- <input type="radio" id="wpgmaps_findus_friend" value="friend" name="wpgmaps_findus">
123
- <label for="wpgmaps_findus_friend"><?php _e("Friend recommendation","wp-google-maps"); ?></label>
124
- </li>
125
- <li style="list-style: none outside none;">
126
- <input type="radio" id="wpgmaps_findus_other" value="other" name="wpgmaps_findus">
127
- <label for="wpgmaps_findus_other"><?php _e("Other","wp-google-maps"); ?></label>
128
- <br /><input type="text" id="wpgmaps_findus_other_url" class="regular-text" style='margin-top:5px; margin-left:40px;' name="wpgmaps_findus_other_url" placeholder="<?php _e("Please explain","wp-google-maps"); ?>">
129
-
130
- </li>
131
-
132
-
133
- </ul></p>
134
- <input class='button-primary' type='submit' name='wpgmza_save_feedback' value='<?php _e("Submit and create a map","wp-google-maps"); ?>'>
135
-
136
- </form>-->
137
- </div>
138
- <?php } ?>
139
-
140
- <div id="wpgmza-support__row" class="feature-section three-col">
141
- <div class='col wpgmza-support__col'>
142
- <div class="wpgmza-card">
143
- <h4><?php _e("New to WP Google Maps?","wp-google-maps"); ?></h4>
144
- <p><?php _e("You may want to","wp-google-maps"); ?> <a href='http://wpgmaps.com/documentation/' target='_blank' title='Documentation'><?php _e("review our documentation","wp-google-maps"); ?></a> <?php _e("before you get started. If you're a tech-savvy individual, you may skip this step.","wp-google-maps"); ?></p>
145
- </div>
146
- </div>
147
- <div class='col wpgmza-support__col'>
148
- <div class="wpgmza-card">
149
- <h4><?php _e("Help me!","wp-google-maps"); ?></h4>
150
- <p><?php _e("Visit our","wp-google-maps"); ?> <a title='Support Desk' target='_blank' href='http://www.wpgmaps.com/support/'><?php _e("Support Desk","wp-google-maps"); ?></a> <?php _e("for quick and friendly help. We'll answer your request within 24hours.","wp-google-maps"); ?></p>
151
- </div>
152
- </div>
153
- <div class='col wpgmza-support__col'>
154
- <div class="wpgmza-card">
155
- <h4><?php _e("Feedback","wp-google-maps"); ?></h4>
156
- <p><?php _e("We need you to help us make this plugin better.","wp-google-maps"); ?> <a href='http://www.wpgmaps.com/contact-us/' title='Feedback' target='_BLANK'><?php _e("Send us your feedback","wp-google-maps"); ?></a> <?php _e("and we'll act on it as soon as humanly possible.","wp-google-maps"); ?></p>
157
- </div>
158
- </div>
159
- </div>
160
-
161
- <a class="button-primary" style='padding:5px; padding-right:15px; padding-left:15px; height:inherit;' href="admin.php?page=wp-google-maps-menu&amp;override=1"><?php echo __("OK! Let's start","wp-google-maps"); ?></a>
162
-
163
- </div>
164
- </div>
1
+ <?php
2
+
3
+ if(!defined('ABSPATH'))
4
+ exit;
5
+
6
+ ?>
7
+
8
+ <?php global $wpgmza_global_array; ?>
9
+ <div id="wpgmza-welcome-page" class="wrap about-wrap">
10
+ <p>&nbsp;</p>
11
+
12
+ <img style="width: 512px;" src="<?php echo WPGMZA_PLUGIN_DIR_URL . 'images/new-banner.png'; ?>" alt="WP Google Maps"/>
13
+
14
+ <h1><?php
15
+
16
+ global $wpgmza;
17
+ printf(__("Welcome to WP Google Maps version %s","wp-google-maps"), $wpgmza->getBasicVersion());
18
+
19
+ ?></h1>
20
+
21
+ <div class="about-text"><?php _e("Build amazing maps through a simple interface and powerful functionality along with world class support.","wp-google-maps"); ?></div>
22
+
23
+ <a class="button-primary" style='padding:5px; padding-right:15px; padding-left:15px; height:inherit;' href="admin.php?page=wp-google-maps-menu&amp;override=1"><?php echo __("Skip intro and create a map","wp-google-maps"); ?></a>
24
+ <p>&nbsp;</p>
25
+
26
+
27
+ <h2 class="nav-tab-wrapper wp-clearfix">
28
+ <a href="admin.php?page=wp-google-maps-menu&amp;action=welcome_page" class="nav-tab nav-tab-active"><?php _e("Welcome","wp-google-maps"); ?></a>
29
+ <a href="admin.php?page=wp-google-maps-menu&amp;action=credits" class="nav-tab"><?php _e("Credits","wp-google-maps"); ?></a>
30
+
31
+ </h2>
32
+
33
+ <div id="wpgmza-support__row" class="feature-section three-col">
34
+ <div class='col wpgmza-support__col wpgmza-margin-0'>
35
+ <div class="wpgmza-card">
36
+ <h4><?php _e("Facebook Group","wp-google-maps"); ?></h4>
37
+ <p><?php _e("Join our Facebook Community","wp-google-maps"); ?></p>
38
+
39
+ <a href="https://www.facebook.com/groups/wpgooglemaps" class="button-primary" target="_BLANK"><?php _e("Join Facebook", "wp-google-maps"); ?></a>
40
+ <br><br>
41
+ <small style="opacity: 0.8;"><?php _e("Get to know other WP Google Maps users, receive updates on upcoming features, and share your maps with the community", "wp-google-maps"); ?></small>
42
+ </div>
43
+ </div>
44
+ <div class='col wpgmza-support__col wpgmza-margin-0'>
45
+ <div class="wpgmza-card">
46
+ <h4><?php _e("Reddit","wp-google-maps"); ?></h4>
47
+ <p><?php _e("Join our Reddit Community","wp-google-maps"); ?></p>
48
+
49
+ <a href="https://www.reddit.com/r/wpgooglemaps/" class="button-primary" target="_BLANK"><?php _e("Join Subreddit", "wp-google-maps"); ?></a>
50
+ <br><br>
51
+ <small style="opacity: 0.8;"><?php _e("Share your maps, speak to the development team, receive updates on upcoming features, and view release specific changelogs", "wp-google-maps"); ?></small>
52
+ </div>
53
+ </div>
54
+ <div class='col wpgmza-support__col wpgmza-margin-0'>
55
+ <div class="wpgmza-card">
56
+ <h4><?php _e("Newsletters","wp-google-maps"); ?></h4>
57
+ <p><?php _e("Receive specials, guides and latest news", "wp-google-maps"); ?></p>
58
+
59
+ <a href="admin.php?page=wp-google-maps-menu&amp;action=newsletter_opt_in" class="button-primary" target="_BLANK"><?php _e("Join Newsletter", "wp-google-maps"); ?></a>
60
+ <br><br>
61
+ <small style="opacity: 0.8;"><?php printf(__("* Clicking this button will send your email address (%s) to our server and automatically sign you up to the newsletter","wp-google-maps"), get_option('admin_email')); ?></small>
62
+ </div>
63
+ </div>
64
+ </div>
65
+
66
+ <div class="wpgmza-flex feature-section two-col">
67
+ <div class="col wpgmza-flex-grid__item">
68
+ <div class="wpgmza-card">
69
+ <h4><?php _e("Unlimited Markers","wp-google-maps"); ?></h4>
70
+ <p><?php _e("Create as many markers as you like","wp-google-maps"); ?></p>
71
+ <img src='<?php echo WPGMZA_PLUGIN_DIR_URL . 'images/unlimited-markers.png'; ?>' style="border:1px solid #ccc;" />
72
+ </div>
73
+ </div>
74
+ <div class="col wpgmza-flex-grid__item">
75
+ <div class="wpgmza-card">
76
+ <h4><?php _e("Store Locator","wp-google-maps"); ?></h4>
77
+ <p><?php _e("Let users search for products, branches and stores near them","wp-google-maps"); ?></p>
78
+ <img src='<?php echo WPGMZA_PLUGIN_DIR_URL . 'images/store-locator.png'; ?>' style="border:1px solid #ccc;" />
79
+ </div>
80
+ </div>
81
+ </div>
82
+ <div class="wpgmza-flex feature-section two-col">
83
+ <div class="col wpgmza-flex-grid__item">
84
+ <div class="wpgmza-card">
85
+ <h4><?php _e("Themes","wp-google-maps"); ?></h4>
86
+ <p><?php _e("Select from various <a href='http://wpgmaps.com/map-themes/' target='_BLANK'>map themes</a>, or make your own.","wp-google-maps"); ?></p>
87
+ <img src='<?php echo WPGMZA_PLUGIN_DIR_URL . 'images/themes.png' ?>;' style="border:1px solid #ccc;" />
88
+ </div>
89
+ </div>
90
+ <div class="col wpgmza-flex-grid__item">
91
+ <div class="wpgmza-card">
92
+ <h4><?php _e("Polylines","wp-google-maps"); ?>, <?php _e("Polygons","wp-google-maps"); ?>, <?php _e("Circles","wp-google-maps"); ?>, <?php _e("and Squares","wp-google-maps"); ?></h4>
93
+ <p><?php _e("Add custom shapes such as polygons, polylines, circles and squares!","wp-google-maps"); ?></p>
94
+ <img src='<?php echo WPGMZA_PLUGIN_DIR_URL . 'images/polygons-and-polylines.png' ?>;' style="border:1px solid #ccc;" />
95
+ </div>
96
+ </div>
97
+ </div>
98
+
99
+ <div class="feature-section normal clear" >
100
+ <div class="changelog ">
101
+
102
+ <?php if (false) {
103
+
104
+ // NB: GDPR
105
+ ?>
106
+
107
+ <!--<h3 style='margin-top:20px;'><?php _e("How did you find out about us?","wp-google-maps"); ?></h3>
108
+
109
+ <div class="feature-section normal">
110
+ <form action='' method='POST' name='wpgmaps_feedback'>
111
+ <p><ul class="wpgmza_welcome_poll" style="list-style: none outside none;">
112
+ <li style="list-style: none outside none;">
113
+ <input type="radio" id="wpgmaps_findus_repository" value="repository" name="wpgmaps_findus">
114
+ <label for="wpgmaps_search_term"><?php _e("WordPress.org plugin repository","wp-google-maps"); ?></label>
115
+ <br /><input type="text" id="wpgmaps_search_term" class="regular-text" style='margin-top:5px; margin-left:40px;' name="wpgmaps_search_term" placeholder="<?php _e("What search term did you use?","wp-google-maps"); ?>">
116
+ </li>
117
+ <li style="list-style: none outside none;">
118
+ <input type="radio" id="wpgmaps_findus_searchengine" value="search_engine" name="wpgmaps_findus">
119
+ <label for="wpgmaps_findus_searchengine"><?php _e("Google or other search engine","wp-google-maps"); ?></label>
120
+ </li>
121
+ <li style="list-style: none outside none;">
122
+ <input type="radio" id="wpgmaps_findus_friend" value="friend" name="wpgmaps_findus">
123
+ <label for="wpgmaps_findus_friend"><?php _e("Friend recommendation","wp-google-maps"); ?></label>
124
+ </li>
125
+ <li style="list-style: none outside none;">
126
+ <input type="radio" id="wpgmaps_findus_other" value="other" name="wpgmaps_findus">
127
+ <label for="wpgmaps_findus_other"><?php _e("Other","wp-google-maps"); ?></label>
128
+ <br /><input type="text" id="wpgmaps_findus_other_url" class="regular-text" style='margin-top:5px; margin-left:40px;' name="wpgmaps_findus_other_url" placeholder="<?php _e("Please explain","wp-google-maps"); ?>">
129
+
130
+ </li>
131
+
132
+
133
+ </ul></p>
134
+ <input class='button-primary' type='submit' name='wpgmza_save_feedback' value='<?php _e("Submit and create a map","wp-google-maps"); ?>'>
135
+
136
+ </form>-->
137
+ </div>
138
+ <?php } ?>
139
+
140
+ <div id="wpgmza-support__row" class="feature-section three-col">
141
+ <div class='col wpgmza-support__col'>
142
+ <div class="wpgmza-card">
143
+ <h4><?php _e("New to WP Google Maps?","wp-google-maps"); ?></h4>
144
+ <p><?php _e("You may want to","wp-google-maps"); ?> <a href='http://wpgmaps.com/documentation/' target='_blank' title='Documentation'><?php _e("review our documentation","wp-google-maps"); ?></a> <?php _e("before you get started. If you're a tech-savvy individual, you may skip this step.","wp-google-maps"); ?></p>
145
+ </div>
146
+ </div>
147
+ <div class='col wpgmza-support__col'>
148
+ <div class="wpgmza-card">
149
+ <h4><?php _e("Help me!","wp-google-maps"); ?></h4>
150
+ <p><?php _e("Visit our","wp-google-maps"); ?> <a title='Support Desk' target='_blank' href='http://www.wpgmaps.com/support/'><?php _e("Support Desk","wp-google-maps"); ?></a> <?php _e("for quick and friendly help. We'll answer your request within 24hours.","wp-google-maps"); ?></p>
151
+ </div>
152
+ </div>
153
+ <div class='col wpgmza-support__col'>
154
+ <div class="wpgmza-card">
155
+ <h4><?php _e("Feedback","wp-google-maps"); ?></h4>
156
+ <p><?php _e("We need you to help us make this plugin better.","wp-google-maps"); ?> <a href='http://www.wpgmaps.com/contact-us/' title='Feedback' target='_BLANK'><?php _e("Send us your feedback","wp-google-maps"); ?></a> <?php _e("and we'll act on it as soon as humanly possible.","wp-google-maps"); ?></p>
157
+ </div>
158
+ </div>
159
+ </div>
160
+
161
+ <a class="button-primary" style='padding:5px; padding-right:15px; padding-left:15px; height:inherit;' href="admin.php?page=wp-google-maps-menu&amp;override=1"><?php echo __("OK! Let's start","wp-google-maps"); ?></a>
162
+
163
+ </div>
164
+ </div>
includes/class.admin-ui.php CHANGED
@@ -1,140 +1,140 @@
1
- <?php
2
-
3
- namespace WPGMZA\UI;
4
-
5
- class Admin extends \WPGMZA\Factory
6
- {
7
- public function __construct()
8
- {
9
- add_action( 'admin_menu', array($this, 'onAdminMenu') );
10
- add_action( 'admin_enqueue_scripts', array($this, 'onAdminEnqueueScripts') );
11
- }
12
-
13
- public function onAdminEnqueueScripts()
14
- {
15
- global $wpgmza;
16
-
17
- $wpgmza->loadScripts(false);
18
- }
19
-
20
- public function onAdminMenu()
21
- {
22
- global $wpgmza;
23
- global $wpgmza_pro_version;
24
-
25
- if(!empty($wpgmza_pro_version) && version_compare($wpgmza_pro_version, '8.1.0', '<'))
26
- {
27
- return wpgmaps_admin_menu();
28
- }
29
-
30
- $access_level = $wpgmza->getAccessCapability();
31
-
32
- add_menu_page(
33
- 'WPGoogle Maps',
34
- __('Maps', 'wp-google-maps'),
35
- $access_level,
36
- 'wp-google-maps-menu',
37
- 'WPGMZA\\UI\\legacy_on_main_menu',
38
- WPGMZA_PLUGIN_DIR_URL . "images/menu-icon.png"
39
- );
40
-
41
- add_submenu_page(
42
- 'wp-google-maps-menu',
43
- 'WP Google Maps - Settings',
44
- __('Settings', 'wp-google-maps'),
45
- $access_level,
46
- 'wp-google-maps-menu-settings',
47
- 'WPGMZA\\UI\\legacy_on_sub_menu',
48
- 1
49
- );
50
-
51
- add_submenu_page(
52
- 'wp-google-maps-menu',
53
- 'WP Google Maps - Support',
54
- __('Support','wp-google-maps'),
55
- $access_level ,
56
- 'wp-google-maps-menu-support',
57
- 'WPGMZA\\UI\\legacy_on_sub_menu',
58
- 999
59
- );
60
- }
61
-
62
- public function onMainMenu()
63
- {
64
- global $wpgmza;
65
-
66
- $action = (isset($_GET['action']) ? $_GET['action'] : null);
67
-
68
- switch($action)
69
- {
70
- case "welcome_page":
71
- $document = new \WPGMZA\DOMDocument();
72
- $document->loadPHPFile(WPGMZA_PLUGIN_DIR_PATH . 'html/welcome.html.php');
73
- echo $document->html;
74
- break;
75
-
76
- case "credits":
77
- $document = new \WPGMZA\DOMDocument();
78
- $document->loadPHPFile(WPGMZA_PLUGIN_DIR_PATH . 'html/credits.html.php');
79
- echo $document->html;
80
- break;
81
-
82
- case "newsletter_opt_in":
83
- /* This block only runs if the user opts-in to the newsletter */
84
- $document = new \WPGMZA\DOMDocument();
85
- $document->loadPHPFile(WPGMZA_PLUGIN_DIR_PATH . 'html/newsletter-opt-in.html.php');
86
- echo $document->html;
87
- break;
88
-
89
- default:
90
-
91
- if($action == 'edit')
92
- $page = \WPGMZA\MapEditPage::createInstance();
93
- else if ($action == 'create-map-page')
94
- $page = \WPGMZA\MapEditPage::createMapPage();
95
- else
96
- $page = \WPGMZA\MapListPage::createInstance();
97
-
98
- echo $page->html;
99
-
100
- break;
101
- }
102
-
103
- $document = new \WPGMZA\DOMDocument();
104
- $document->loadPHPFile(WPGMZA_PLUGIN_DIR_PATH . 'html/footer.html.php');
105
- echo $document->html;
106
-
107
- do_action("wpgmza_check_map_editor_backwards_compat");
108
- }
109
-
110
- public function onSubMenu()
111
- {
112
- switch($_GET['page'])
113
- {
114
- case 'wp-google-maps-menu-settings':
115
- $page = \WPGMZA\SettingsPage::createInstance();
116
- echo $page->html;
117
- break;
118
-
119
- case 'wp-google-maps-menu-support':
120
- $document = new \WPGMZA\DOMDocument();
121
- $document->loadPHPFile(WPGMZA_PLUGIN_DIR_PATH . 'html/support.html.php');
122
- echo $document->html;
123
- break;
124
- }
125
- }
126
- }
127
-
128
- function legacy_on_main_menu()
129
- {
130
- global $wpgmza;
131
- $wpgmza->adminUI->onMainMenu();
132
- }
133
-
134
- function legacy_on_sub_menu()
135
- {
136
- global $wpgmza;
137
- $wpgmza->adminUI->onSubMenu();
138
- }
139
-
140
-
1
+ <?php
2
+
3
+ namespace WPGMZA\UI;
4
+
5
+ class Admin extends \WPGMZA\Factory
6
+ {
7
+ public function __construct()
8
+ {
9
+ add_action( 'admin_menu', array($this, 'onAdminMenu') );
10
+ add_action( 'admin_enqueue_scripts', array($this, 'onAdminEnqueueScripts') );
11
+ }
12
+
13
+ public function onAdminEnqueueScripts()
14
+ {
15
+ global $wpgmza;
16
+
17
+ $wpgmza->loadScripts(false);
18
+ }
19
+
20
+ public function onAdminMenu()
21
+ {
22
+ global $wpgmza;
23
+ global $wpgmza_pro_version;
24
+
25
+ if(!empty($wpgmza_pro_version) && version_compare($wpgmza_pro_version, '8.1.0', '<'))
26
+ {
27
+ return wpgmaps_admin_menu();
28
+ }
29
+
30
+ $access_level = $wpgmza->getAccessCapability();
31
+
32
+ add_menu_page(
33
+ 'WPGoogle Maps',
34
+ __('Maps', 'wp-google-maps'),
35
+ $access_level,
36
+ 'wp-google-maps-menu',
37
+ 'WPGMZA\\UI\\legacy_on_main_menu',
38
+ WPGMZA_PLUGIN_DIR_URL . "images/menu-icon.png"
39
+ );
40
+
41
+ add_submenu_page(
42
+ 'wp-google-maps-menu',
43
+ 'WP Google Maps - Settings',
44
+ __('Settings', 'wp-google-maps'),
45
+ $access_level,
46
+ 'wp-google-maps-menu-settings',
47
+ 'WPGMZA\\UI\\legacy_on_sub_menu',
48
+ 1
49
+ );
50
+
51
+ add_submenu_page(
52
+ 'wp-google-maps-menu',
53
+ 'WP Google Maps - Support',
54
+ __('Support','wp-google-maps'),
55
+ $access_level ,
56
+ 'wp-google-maps-menu-support',
57
+ 'WPGMZA\\UI\\legacy_on_sub_menu',
58
+ 999
59
+ );
60
+ }
61
+
62
+ public function onMainMenu()
63
+ {
64
+ global $wpgmza;
65
+
66
+ $action = (isset($_GET['action']) ? $_GET['action'] : null);
67
+
68
+ switch($action)
69
+ {
70
+ case "welcome_page":
71
+ $document = new \WPGMZA\DOMDocument();
72
+ $document->loadPHPFile(WPGMZA_PLUGIN_DIR_PATH . 'html/welcome.html.php');
73
+ echo $document->html;
74
+ break;
75
+
76
+ case "credits":
77
+ $document = new \WPGMZA\DOMDocument();
78
+ $document->loadPHPFile(WPGMZA_PLUGIN_DIR_PATH . 'html/credits.html.php');
79
+ echo $document->html;
80
+ break;
81
+
82
+ case "newsletter_opt_in":
83
+ /* This block only runs if the user opts-in to the newsletter */
84
+ $document = new \WPGMZA\DOMDocument();
85
+ $document->loadPHPFile(WPGMZA_PLUGIN_DIR_PATH . 'html/newsletter-opt-in.html.php');
86
+ echo $document->html;
87
+ break;
88
+
89
+ default:
90
+
91
+ if($action == 'edit')
92
+ $page = \WPGMZA\MapEditPage::createInstance();
93
+ else if ($action == 'create-map-page')
94
+ $page = \WPGMZA\MapEditPage::createMapPage();
95
+ else
96
+ $page = \WPGMZA\MapListPage::createInstance();
97
+
98
+ echo $page->html;
99
+
100
+ break;
101
+ }
102
+
103
+ $document = new \WPGMZA\DOMDocument();
104
+ $document->loadPHPFile(WPGMZA_PLUGIN_DIR_PATH . 'html/footer.html.php');
105
+ echo $document->html;
106
+
107
+ do_action("wpgmza_check_map_editor_backwards_compat");
108
+ }
109
+
110
+ public function onSubMenu()
111
+ {
112
+ switch($_GET['page'])
113
+ {
114
+ case 'wp-google-maps-menu-settings':
115
+ $page = \WPGMZA\SettingsPage::createInstance();
116
+ echo $page->html;
117
+ break;
118
+
119
+ case 'wp-google-maps-menu-support':
120
+ $document = new \WPGMZA\DOMDocument();
121
+ $document->loadPHPFile(WPGMZA_PLUGIN_DIR_PATH . 'html/support.html.php');
122
+ echo $document->html;
123
+ break;
124
+ }
125
+ }
126
+ }
127
+
128
+ function legacy_on_main_menu()
129
+ {
130
+ global $wpgmza;
131
+ $wpgmza->adminUI->onMainMenu();
132
+ }
133
+
134
+ function legacy_on_sub_menu()
135
+ {
136
+ global $wpgmza;
137
+ $wpgmza->adminUI->onSubMenu();
138
+ }
139
+
140
+
includes/class.crud.php CHANGED
@@ -1,742 +1,742 @@
1
- <?php
2
-
3
- namespace WPGMZA;
4
-
5
- if(!defined('ABSPATH'))
6
- return;
7
-
8
- /**
9
- * The CRUD class is a base class which acts as an interface between any
10
- * objects which are stored on in the database and represented in server
11
- * side logic, for example Map, Marker, Polygon
12
- */
13
- class Crud extends Factory implements \IteratorAggregate, \JsonSerializable
14
- {
15
- const SINGLE_READ = "single-read";
16
- const BULK_READ = "bulk-read";
17
-
18
- private static $cached_columns_by_table_name;
19
- private static $cached_column_name_map_by_table_name;
20
-
21
- private $id;
22
- private $table_name;
23
- private $fields;
24
- private $overrides;
25
- private $modified;
26
-
27
- private $trashed = false;
28
-
29
- /**
30
- * Constructor
31
- * @param string $table_name The table name for this object type
32
- * @param int|array|object $id_or_fields The ID of the object to read, or an object or array of data to insert.
33
- */
34
- public function __construct($table_name, $id_or_fields=-1, $read_mode=Crud::SINGLE_READ)
35
- {
36
- global $wpdb;
37
-
38
- $this->table_name = $table_name;
39
- Crud::cacheColumnsByTableName($table_name);
40
-
41
- $this->fields = array();
42
- $this->overrides = array();
43
-
44
- if(is_object($id_or_fields) || is_array($id_or_fields))
45
- {
46
- foreach($id_or_fields as $key => $value)
47
- {
48
- if($key == "id")
49
- continue;
50
-
51
- $this->fields[$key] = $value;
52
- }
53
-
54
- $obj = (object)$id_or_fields;
55
-
56
- if($read_mode == Crud::BULK_READ)
57
- {
58
- if(!isset($obj->id))
59
- throw new \Exception('Cannot bulk read without ID');
60
-
61
- $id = $this->id = $obj->id;
62
- }
63
- else if(!isset($obj->id))
64
- $id = -1;
65
-
66
- // NB: Relaxed handling to avoid accidental duplication
67
- if($read_mode != Crud::BULK_READ && isset($obj->id))
68
- {
69
- trigger_error('Crud class receieved data including an ID in single read mode. Did you mean to use bulk read, or single read and update?', E_USER_WARNING);
70
- }
71
- }
72
- else if(preg_match('/^-?\d+$/', $id_or_fields))
73
- $id = (int)$id_or_fields;
74
- else
75
- throw new \Exception('Invalid ID');
76
-
77
- $this->id = $id;
78
-
79
- if($read_mode != Crud::BULK_READ){
80
- if($this->id == -1){
81
- $this->create();
82
- } else {
83
- if(!empty($this->id)){
84
- // Only attempt a read if not empty as this can lead to erroneous error being thrown
85
- $this->read(Marker::SINGLE_READ);
86
- }
87
- }
88
- } else {
89
- $arbitraryDataColumnName = $this->get_arbitrary_data_column_name();
90
-
91
- if(!empty($arbitraryDataColumnName) && !empty($this->fields[$arbitraryDataColumnName]))
92
- $this->parse_arbitrary_data($this->fields[$arbitraryDataColumnName]);
93
- }
94
-
95
- $this->onCrudInitialized();
96
- }
97
-
98
- protected function onCrudInitialized()
99
- {
100
-
101
- }
102
-
103
- private static function cacheColumnsByTableName($table_name)
104
- {
105
- global $wpdb;
106
-
107
- if(!isset(Crud::$cached_columns_by_table_name))
108
- Crud::$cached_columns_by_table_name = array();
109
-
110
- if(isset(Crud::$cached_columns_by_table_name[$table_name]))
111
- return;
112
-
113
- $columns = $wpdb->get_results("SHOW COLUMNS FROM $table_name");
114
-
115
- Crud::$cached_column_name_map_by_table_name[$table_name] = array();
116
- foreach($columns as $col)
117
- {
118
- Crud::$cached_column_name_map_by_table_name[$table_name][$col->Field] = $col;
119
- }
120
-
121
- Crud::$cached_columns_by_table_name[$table_name] = $columns;
122
- }
123
-
124
- protected static function getColumnsByTableName($table_name)
125
- {
126
- Crud::cacheColumnsByTableName($table_name);
127
-
128
- return Crud::$cached_columns_by_table_name[$table_name];
129
- }
130
-
131
- public static function bulk_read($data, $constructor)
132
- {
133
- if(!is_array($data))
134
- throw new \Exception('Argument must be an array of objects');
135
-
136
- $result = array();
137
-
138
- foreach($data as $row)
139
- $result[] = new $constructor($row, Crud::BULK_READ);
140
-
141
- return $result;
142
- }
143
-
144
- public static function bulk_trash($ids)
145
- {
146
- global $wpdb;
147
-
148
- if(!is_array($ids))
149
- throw new \Exception('Arugment must be an array of integer IDs');
150
-
151
- if(empty($ids))
152
- return;
153
-
154
- $table_name = static::get_table_name_static();
155
-
156
- $count = count($ids);
157
- $placeholders = implode(',', array_fill(0, $count, '%d'));
158
- $stmt = $wpdb->prepare("DELETE FROM `{$table_name}` WHERE id IN ($placeholders)", $ids);
159
- $wpdb->query($stmt);
160
- }
161
-
162
-
163
- /**
164
- * Gets the table name for this object type
165
- * @return string
166
- */
167
- public function get_table_name()
168
- {
169
- return $this->table_name;
170
- }
171
-
172
- /**
173
- * Gets the column information (name, type, etc.)
174
- * @return array
175
- */
176
- public function get_columns()
177
- {
178
- return Crud::$cached_columns_by_table_name[$this->table_name];
179
- }
180
-
181
- /**
182
- * Returns an array of the column names represented as strings
183
- * @return array
184
- */
185
- public function get_column_names()
186
- {
187
- return array_keys( Crud::$cached_column_name_map_by_table_name[$this->table_name] );
188
- }
189
-
190
- public function get_columns_by_name()
191
- {
192
- return Crud::$cached_column_name_map_by_table_name[$this->table_name];
193
- }
194
-
195
- /**
196
- * Return the SQL field type of the specified column
197
- * @return string
198
- */
199
- public function get_column_type($name)
200
- {
201
- $columns = $this->get_columns();
202
-
203
- foreach($columns as $index => $column)
204
- {
205
- if($column->Field == $name)
206
- return $column->Type;
207
- }
208
-
209
- return Crud::$cached_columns_by_table_name[$this->table_name];
210
- }
211
-
212
- /**
213
- * Gets the placeholder for a prepared statement based on the SQL column type specified.
214
- * @param string $type The SQL data type
215
- * @return string A placeholder, such as %s, %d or %f
216
- */
217
- protected function get_placeholder_by_type($type)
218
- {
219
- $type = strtolower(preg_replace('/\(\d+\)$/', '', $type));
220
-
221
- switch($type)
222
- {
223
- case 'tinyint':
224
- case 'smallint':
225
- case 'mediumint':
226
- case 'int':
227
- case 'bigint':
228
- case 'bit':
229
- case 'boolean':
230
- $placeholder = '%d';
231
- break;
232
-
233
- case 'decimal':
234
- case 'float':
235
- case 'double':
236
- case 'real':
237
- $placeholder = '%f';
238
- break;
239
-
240
- default:
241
- $placeholder = '%s';
242
- break;
243
- }
244
-
245
- return $placeholder;
246
- }
247
-
248
- /**
249
- * Gets the parameter to be passed to a prepared statement, from this object, by the name of the DB column given.
250
- * @param string $name The database column name
251
- * @return mixed The value of the specified field name from this object
252
- */
253
- protected function get_column_parameter($name)
254
- {
255
- if(array_key_exists($name, $this->fields))
256
- return $this->fields[$name];
257
-
258
- return '';
259
- }
260
-
261
- /**
262
- * Gets all the placeholders for a prepared statement
263
- * @return array An array of string placeholders
264
- */
265
- protected function get_column_placeholders()
266
- {
267
- $columns = $this->get_columns();
268
- $placeholders = array();
269
-
270
- foreach($columns as $index => $column)
271
- {
272
- if($column->Field == 'id')
273
- continue;
274
-
275
- $placeholders[] = $this->get_placeholder_by_type($column->Type);
276
- }
277
-
278
- return $placeholders;
279
- }
280
-
281
- /**
282
- * Gets all the values to be passed to a prepared statement from this object
283
- * @return array An array of the values from this object
284
- */
285
- protected function get_column_parameters()
286
- {
287
- $columns = $this->get_columns();
288
- $params = array();
289
-
290
- foreach($columns as $index => $column)
291
- {
292
- if($column->Field == 'id')
293
- continue;
294
-
295
- $params[] = $this->get_column_parameter($column->Field);
296
- }
297
-
298
- return $params;
299
- }
300
-
301
- /**
302
- * Gets the column name used to store arbitrary data, for instance, other_data, or NULL for tables which do not have such a field.
303
- * @return string The name of the column used to store arbitrary data
304
- */
305
- protected function get_arbitrary_data_column_name()
306
- {
307
- return null;
308
- }
309
-
310
- /**
311
- * Asserts that this object hasn't been trashed and throws an exception if it has
312
- * @throws \Exception
313
- * @return void
314
- */
315
- protected function assert_not_trashed()
316
- {
317
- if($this->trashed)
318
- throw new \Exception('Operation on trashed map object');
319
- }
320
-
321
- /**
322
- * Returns true if the named column exists on this map objects table
323
- * @return bool
324
- */
325
- protected function column_exists($name)
326
- {
327
- return isset($cached_column_name_map_by_table_name[$this->table_name]);
328
- }
329
-
330
- /**
331
- * Parses arbitrary data following a DB read, for example by unserializing strings or decoding JSON.
332
- * @return void
333
- */
334
- protected function parse_arbitrary_data($data)
335
- {
336
- if(!$this->get_arbitrary_data_column_name())
337
- throw new \Exception('No arbitrary data field on this table');
338
-
339
- $data = maybe_unserialize($data);
340
-
341
- if(!is_object($data) && !is_array($data))
342
- return;
343
-
344
- foreach($data as $key => $value)
345
- $this->fields[$key] = $value;
346
-
347
- $name = $this->get_arbitrary_data_column_name();
348
- unset($this->fields[$name]);
349
- }
350
-
351
- /**
352
- * Stores arbitrary data. This is not currently used.
353
- * @return void
354
- */
355
- protected function store_arbitrary_data($key, $value)
356
- {
357
- if(!$this->get_arbitrary_data_column_name())
358
- throw new \Exception('No arbitrary data field on this table');
359
-
360
-
361
- }
362
-
363
- /**
364
- * Creates the map object in the database
365
- * @throws \Exception The object has been trashed
366
- * @return void
367
- */
368
- protected function create()
369
- {
370
- global $wpdb;
371
-
372
- $this->assert_not_trashed();
373
-
374
- // TODO: Support arbitrary data
375
-
376
- $column_names = array_flip( $this->get_column_names() );
377
- unset($column_names['id']);
378
- $column_names = implode(',', array_keys($column_names));
379
-
380
- $placeholders = implode(',', $this->get_column_placeholders());
381
- $parameters = $this->get_column_parameters();
382
-
383
- $qstr = "INSERT INTO `{$this->table_name}` ($column_names) VALUES ($placeholders)";
384
-
385
- $stmt = $wpdb->prepare($qstr, $parameters);
386
- $wpdb->query($stmt);
387
-
388
- $this->id = $wpdb->insert_id;
389
- }
390
-
391
- protected function getReadColumns()
392
- {
393
- return array("*");
394
- }
395
-
396
- /**
397
- * Reads the data from the database into this object
398
- * @throws \Exception The object has been trashed
399
- * @return void
400
- */
401
- protected function read($mode)
402
- {
403
- global $wpdb;
404
-
405
- $this->assert_not_trashed();
406
-
407
- $columns = implode(', ', $this->getReadColumns());
408
-
409
- $stmt = $wpdb->prepare("SELECT $columns FROM " . $this->get_table_name() . " WHERE id = %d", array($this->id));
410
-
411
- $results = $wpdb->get_results($stmt);
412
-
413
- if(empty($results))
414
- throw new \Exception(get_called_class() . " ID '{$this->id}' not found");
415
-
416
- $this->fields = (array)$results[0];
417
- unset($this->fields['id']);
418
-
419
- $arbitrary_data_column_name = $this->get_arbitrary_data_column_name();
420
-
421
- if($arbitrary_data_column_name && isset($this->fields[$arbitrary_data_column_name]))
422
- {
423
- $this->parse_arbitrary_data($this->fields[$arbitrary_data_column_name]);
424
- unset($this->fields[$arbitrary_data_column_name]);
425
- }
426
- }
427
-
428
- /**
429
- * Returns true if the specified property is read only
430
- * @return bool Whether or not the property is read only
431
- */
432
- protected function is_read_only($key)
433
- {
434
- switch($key)
435
- {
436
- case 'id':
437
- case 'table_name':
438
- case 'fields':
439
- case 'modified':
440
- case 'trashed':
441
- return true;
442
- break;
443
- }
444
-
445
- return false;
446
- }
447
-
448
- /**
449
- * Updates the map object in the database
450
- * @throws \Exception The object has been trashed
451
- * @return $this
452
- */
453
- public function update()
454
- {
455
- global $wpdb;
456
-
457
- $this->assert_not_trashed();
458
-
459
- $column_names = array_flip( $this->get_column_names() );
460
- unset($column_names['id']);
461
- $column_names = array_keys($column_names);
462
-
463
- $placeholders = $this->get_column_placeholders();
464
- $parameters = $this->get_column_parameters();
465
-
466
- $assignments = array();
467
- for($i = 0; $i < count($column_names); $i++)
468
- $assignments[] = $column_names[$i] . '=' . $placeholders[$i];
469
- $assignments = implode(',', $assignments);
470
-
471
- $parameters[] = $this->id;
472
-
473
- $qstr = "UPDATE {$this->table_name} SET $assignments WHERE id=%d";
474
- $stmt = $wpdb->prepare($qstr, $parameters);
475
- $wpdb->query($stmt);
476
-
477
- // Arbitrary data
478
- $data = array();
479
-
480
- foreach($this->fields as $key => $value)
481
- {
482
- if(array_search($key, $column_names) !== false)
483
- continue;
484
-
485
- $data[$key] = $value;
486
- }
487
-
488
- $arbitrary_data_column_name = $this->get_arbitrary_data_column_name();
489
-
490
- if(!empty($data) && !$arbitrary_data_column_name)
491
- trigger_error('Arbitrary data cannot be stored on this column - the following fields will be lost: ' . implode(', ', array_keys($data)), E_USER_WARNING);
492
- else if($arbitrary_data_column_name)
493
- {
494
- $data = serialize($data);
495
-
496
- $stmt = $wpdb->prepare("UPDATE {$this->table_name} SET $arbitrary_data_column_name=%s WHERE id=%d", array($data, $this->id));
497
-
498
- $wpdb->query($stmt);
499
- }
500
-
501
- return $this;
502
- }
503
-
504
- /**
505
- * Deletes the object from the database and sets the trashed flag
506
- * @throws \Exception The object has been trashed
507
- * @return void
508
- */
509
- public function trash()
510
- {
511
- global $wpdb;
512
-
513
- $this->assert_not_trashed();
514
-
515
- $stmt = $wpdb->prepare("DELETE FROM {$this->table_name} WHERE id=%d", array($this->id));
516
-
517
- $wpdb->query($stmt);
518
-
519
- $this->trashed = true;
520
- }
521
-
522
- public function duplicate()
523
- {
524
- global $wpdb;
525
-
526
- $columns = array();
527
-
528
- foreach($wpdb->get_col("SHOW COLUMNS FROM `{$this->table_name}`") as $name)
529
- {
530
- if($name == 'id')
531
- continue;
532
-
533
- $columns []= $name;
534
- }
535
-
536
- $imploded = implode(',', $columns);
537
-
538
- $query = "INSERT INTO {$this->table_name} ($imploded) SELECT $imploded FROM {$this->table_name} WHERE id=%d";
539
-
540
- $stmt = $wpdb->prepare($query, $this->id);
541
-
542
- $wpdb->query($stmt);
543
-
544
- $class = get_class($this);
545
-
546
- return $class::createInstance($wpdb->insert_id);
547
- }
548
-
549
- /**
550
- * Set variables in bulk, this reduces the number of database calls
551
- * @param string|array|object Either a string naming the property to be set (with a second argument which is the value), or an array or object of key and value pairs to be set on this object
552
- * @throws \Exception The object has been trashed
553
- * @return $this
554
- */
555
- public function set($arg, $val=null)
556
- {
557
- $this->assert_not_trashed();
558
-
559
- if(is_string($arg)){
560
- if(is_string($val)){
561
- $val = wp_kses_post($val);
562
- }
563
- $this->__set($arg, $val);
564
- } else if(is_array($arg) || is_object($arg)){
565
- foreach($arg as $key => $value){
566
- if($this->is_read_only($key)){
567
- throw new \Exception('Property is read only');
568
- }
569
-
570
- if(is_string($value)){
571
- $value = wp_kses_post($value);
572
- }
573
- $this->fields[$key] = $value;
574
- }
575
-
576
- $this->update();
577
- } else{
578
- throw new \Exception('Invalid argument');
579
- }
580
-
581
- return $this;
582
- }
583
-
584
- /**
585
- * Sets a variable on the object without writing to the database. Useful for overriding properties
586
- */
587
- public function override($key, $value)
588
- {
589
- $this->assert_not_trashed();
590
-
591
- $this->overrides[$key] = $value;
592
-
593
- return $this;
594
- }
595
-
596
- /**
597
- * Get's the iterator for iterating over map object properties
598
- * @throws \Exception The object has been trashed
599
- * @return \ArrayIterator
600
- */
601
- public function getIterator()
602
- {
603
- $this->assert_not_trashed();
604
-
605
- return new \ArrayIterator($this->fields);
606
- }
607
-
608
- /**
609
- * Returns the objects properties to be serialized as JSON
610
- * @throws \Exception
611
- * @return array
612
- */
613
- public function jsonSerialize()
614
- {
615
- $this->assert_not_trashed();
616
-
617
- if(!is_array($this->fields))
618
- throw new \Exception("Field data is not an array");
619
-
620
- return array_merge($this->fields, array('id' => $this->id));
621
- }
622
-
623
- /**
624
- * Magic method to get map object fields
625
- * @params string $name The name of the property to read
626
- * @throws \Exception The object has been trashed
627
- * @return mixed
628
- */
629
- public function __get($name)
630
- {
631
- $this->assert_not_trashed();
632
-
633
- if(isset($this->fields[$name]))
634
- return $this->fields[$name];
635
-
636
- switch($name)
637
- {
638
- case 'id':
639
- case 'modified':
640
- case 'custom_fields':
641
- return $this->{$name};
642
- break;
643
- }
644
-
645
- return null;
646
- }
647
-
648
- /**
649
- * Checks if a field is set by name
650
- * @params string $name The name of the property to check
651
- * @throws \Exception The object has been trashed.
652
- * @return boolean
653
- */
654
- public function __isset($name)
655
- {
656
- $this->assert_not_trashed();
657
-
658
- if($name == 'id')
659
- return true;
660
-
661
- return isset($this->fields[$name]);
662
- }
663
-
664
- /**
665
- * Sets the property value by name and updates the database
666
- * @param string $name The property name
667
- * @param mixed $value The value to set on the specified property
668
- * @throws \Exception The object has been trashed
669
- * @throws \Exception The specified property is read-only
670
- * @return void
671
- */
672
- public function __set($name, $value)
673
- {
674
- global $wpdb;
675
-
676
- $this->assert_not_trashed();
677
-
678
- if($this->is_read_only($name))
679
- throw new \Exception('Property is read only');
680
-
681
- if(is_string($value)){
682
- $value = htmlspecialchars_decode(wp_kses_post($value));
683
- }
684
-
685
- $this->fields[$name] = $value;
686
-
687
- $columns = $this->get_columns();
688
-
689
- // TODO: This loop could be replaced with a placeholder cache
690
- foreach($columns as $column)
691
- {
692
- if($column->Field != $name)
693
- continue;
694
-
695
- $placeholder = $this->get_placeholder_by_type($column->Type);
696
- $params = array($value, $this->id);
697
-
698
- $stmt = $wpdb->prepare("UPDATE {$this->table_name} SET $name = $placeholder WHERE id = %d", $params);
699
- $wpdb->query($stmt);
700
-
701
- return;
702
- }
703
-
704
- $arbitrary_data_column_name = $this->get_arbitrary_data_column_name();
705
-
706
- if(!$arbitrary_data_column_name)
707
- throw new \Exception('Cannot store arbitrary data on this table');
708
-
709
- $stmt = $wpdb->prepare("SELECT $arbitrary_data_column_name FROM {$this->table_name} WHERE id=%d", array($this->id));
710
-
711
- $raw = $wpdb->get_var($stmt);
712
- $data = maybe_unserialize($raw);
713
-
714
- if(empty($data))
715
- $data = array();
716
-
717
- $data[$name] = $value;
718
-
719
- $data = serialize($data);
720
-
721
- $stmt = $wpdb->prepare("UPDATE {$this->table_name} SET $arbitrary_data_column_name=%s WHERE id=%d", array($data, $this->id));
722
-
723
- $wpdb->query($stmt);
724
- }
725
-
726
- /**
727
- * Unsets the named variable, only valid for arbitrary data
728
- * @throws \Exception when attempting to unset a column, as opposed to arbitrary data.
729
- * @return void
730
- */
731
- public function __unset($name)
732
- {
733
- $column_names = $this->get_column_names();
734
-
735
- if(array_search($name, $column_names) !== false)
736
- throw new \Exception('Only arbitrary data can be unset. Columns must be set to NULL instead');
737
-
738
- unset($this->fields[$name]);
739
-
740
- $this->update();
741
- }
742
- }
1
+ <?php
2
+
3
+ namespace WPGMZA;
4
+
5
+ if(!defined('ABSPATH'))
6
+ return;
7
+
8
+ /**
9
+ * The CRUD class is a base class which acts as an interface between any
10
+ * objects which are stored on in the database and represented in server
11
+ * side logic, for example Map, Marker, Polygon
12
+ */
13
+ class Crud extends Factory implements \IteratorAggregate, \JsonSerializable
14
+ {
15
+ const SINGLE_READ = "single-read";
16
+ const BULK_READ = "bulk-read";
17
+
18
+ private static $cached_columns_by_table_name;
19
+ private static $cached_column_name_map_by_table_name;
20
+
21
+ private $id;
22
+ private $table_name;
23
+ private $fields;
24
+ private $overrides;
25
+ private $modified;
26
+
27
+ private $trashed = false;
28
+
29
+ /**
30
+ * Constructor
31
+ * @param string $table_name The table name for this object type
32
+ * @param int|array|object $id_or_fields The ID of the object to read, or an object or array of data to insert.
33
+ */
34
+ public function __construct($table_name, $id_or_fields=-1, $read_mode=Crud::SINGLE_READ)
35
+ {
36
+ global $wpdb;
37
+
38
+ $this->table_name = $table_name;
39
+ Crud::cacheColumnsByTableName($table_name);
40
+
41
+ $this->fields = array();
42
+ $this->overrides = array();
43
+
44
+ if(is_object($id_or_fields) || is_array($id_or_fields))
45
+ {
46
+ foreach($id_or_fields as $key => $value)
47
+ {
48
+ if($key == "id")
49
+ continue;
50
+
51
+ $this->fields[$key] = $value;
52
+ }
53
+
54
+ $obj = (object)$id_or_fields;
55
+
56
+ if($read_mode == Crud::BULK_READ)
57
+ {
58
+ if(!isset($obj->id))
59
+ throw new \Exception('Cannot bulk read without ID');
60
+
61
+ $id = $this->id = $obj->id;
62
+ }
63
+ else if(!isset($obj->id))
64
+ $id = -1;
65
+
66
+ // NB: Relaxed handling to avoid accidental duplication
67
+ if($read_mode != Crud::BULK_READ && isset($obj->id))
68
+ {
69
+ trigger_error('Crud class receieved data including an ID in single read mode. Did you mean to use bulk read, or single read and update?', E_USER_WARNING);
70
+ }
71
+ }
72
+ else if(preg_match('/^-?\d+$/', $id_or_fields))
73
+ $id = (int)$id_or_fields;
74
+ else
75
+ throw new \Exception('Invalid ID');
76
+
77
+ $this->id = $id;
78
+
79
+ if($read_mode != Crud::BULK_READ){
80
+ if($this->id == -1){
81
+ $this->create();
82
+ } else {
83
+ if(!empty($this->id)){
84
+ // Only attempt a read if not empty as this can lead to erroneous error being thrown
85
+ $this->read(Marker::SINGLE_READ);
86
+ }
87
+ }
88
+ } else {
89
+ $arbitraryDataColumnName = $this->get_arbitrary_data_column_name();
90
+
91
+ if(!empty($arbitraryDataColumnName) && !empty($this->fields[$arbitraryDataColumnName]))
92
+ $this->parse_arbitrary_data($this->fields[$arbitraryDataColumnName]);
93
+ }
94
+
95
+ $this->onCrudInitialized();
96
+ }
97
+
98
+ protected function onCrudInitialized()
99
+ {
100
+
101
+ }
102
+
103
+ private static function cacheColumnsByTableName($table_name)
104
+ {
105
+ global $wpdb;
106
+
107
+ if(!isset(Crud::$cached_columns_by_table_name))
108
+ Crud::$cached_columns_by_table_name = array();
109
+
110
+ if(isset(Crud::$cached_columns_by_table_name[$table_name]))
111
+ return;
112
+
113
+ $columns = $wpdb->get_results("SHOW COLUMNS FROM $table_name");
114
+
115
+ Crud::$cached_column_name_map_by_table_name[$table_name] = array();
116
+ foreach($columns as $col)
117
+ {
118
+ Crud::$cached_column_name_map_by_table_name[$table_name][$col->Field] = $col;
119
+ }
120
+
121
+ Crud::$cached_columns_by_table_name[$table_name] = $columns;
122
+ }
123
+
124
+ protected static function getColumnsByTableName($table_name)
125
+ {
126
+ Crud::cacheColumnsByTableName($table_name);
127
+
128
+ return Crud::$cached_columns_by_table_name[$table_name];
129
+ }
130
+
131
+ public static function bulk_read($data, $constructor)
132
+ {
133
+ if(!is_array($data))
134
+ throw new \Exception('Argument must be an array of objects');
135
+
136
+ $result = array();
137
+
138
+ foreach($data as $row)
139
+ $result[] = new $constructor($row, Crud::BULK_READ);
140
+
141
+ return $result;
142
+ }
143
+
144
+ public static function bulk_trash($ids)
145
+ {
146
+ global $wpdb;
147
+
148
+ if(!is_array($ids))
149
+ throw new \Exception('Arugment must be an array of integer IDs');
150
+
151
+ if(empty($ids))
152
+ return;
153
+
154
+ $table_name = static::get_table_name_static();
155
+
156
+ $count = count($ids);
157
+ $placeholders = implode(',', array_fill(0, $count, '%d'));
158
+ $stmt = $wpdb->prepare("DELETE FROM `{$table_name}` WHERE id IN ($placeholders)", $ids);
159
+ $wpdb->query($stmt);
160
+ }
161
+
162
+
163
+ /**
164
+ * Gets the table name for this object type
165
+ * @return string
166
+ */
167
+ public function get_table_name()
168
+ {
169
+ return $this->table_name;
170
+ }
171
+
172
+ /**
173
+ * Gets the column information (name, type, etc.)
174
+ * @return array
175
+ */
176
+ public function get_columns()
177
+ {
178
+ return Crud::$cached_columns_by_table_name[$this->table_name];
179
+ }
180
+
181
+ /**
182
+ * Returns an array of the column names represented as strings
183
+ * @return array
184
+ */
185
+ public function get_column_names()
186
+ {
187
+ return array_keys( Crud::$cached_column_name_map_by_table_name[$this->table_name] );
188
+ }
189
+
190
+ public function get_columns_by_name()
191
+ {
192
+ return Crud::$cached_column_name_map_by_table_name[$this->table_name];
193
+ }
194
+
195
+ /**
196
+ * Return the SQL field type of the specified column
197
+ * @return string
198
+ */
199
+ public function get_column_type($name)
200
+ {
201
+ $columns = $this->get_columns();
202
+
203
+ foreach($columns as $index => $column)
204
+ {
205
+ if($column->Field == $name)
206
+ return $column->Type;
207
+ }
208
+
209
+ return Crud::$cached_columns_by_table_name[$this->table_name];
210
+ }
211
+
212
+ /**
213
+ * Gets the placeholder for a prepared statement based on the SQL column type specified.
214
+ * @param string $type The SQL data type
215
+ * @return string A placeholder, such as %s, %d or %f
216
+ */
217
+ protected function get_placeholder_by_type($type)
218
+ {
219
+ $type = strtolower(preg_replace('/\(\d+\)$/', '', $type));
220
+
221
+ switch($type)
222
+ {
223
+ case 'tinyint':
224
+ case 'smallint':
225
+ case 'mediumint':
226
+ case 'int':
227
+ case 'bigint':
228
+ case 'bit':
229
+ case 'boolean':
230
+ $placeholder = '%d';
231
+ break;
232
+
233
+ case 'decimal':
234
+ case 'float':
235
+ case 'double':
236
+ case 'real':
237
+ $placeholder = '%f';
238
+ break;
239
+
240
+ default:
241
+ $placeholder = '%s';
242
+ break;
243
+ }
244
+
245
+ return $placeholder;
246
+ }
247
+
248
+ /**
249
+ * Gets the parameter to be passed to a prepared statement, from this object, by the name of the DB column given.
250
+ * @param string $name The database column name
251
+ * @return mixed The value of the specified field name from this object
252
+ */
253
+ protected function get_column_parameter($name)
254
+ {
255
+ if(array_key_exists($name, $this->fields))
256
+ return $this->fields[$name];
257
+
258
+ return '';
259
+ }
260
+
261
+ /**
262
+ * Gets all the placeholders for a prepared statement
263
+ * @return array An array of string placeholders
264
+ */
265
+ protected function get_column_placeholders()
266
+ {
267
+ $columns = $this->get_columns();
268
+ $placeholders = array();
269
+
270
+ foreach($columns as $index => $column)
271
+ {
272
+ if($column->Field == 'id')
273
+ continue;
274
+
275
+ $placeholders[] = $this->get_placeholder_by_type($column->Type);
276
+ }
277
+
278
+ return $placeholders;
279
+ }
280
+
281
+ /**
282
+ * Gets all the values to be passed to a prepared statement from this object
283
+ * @return array An array of the values from this object
284
+ */
285
+ protected function get_column_parameters()
286
+ {
287
+ $columns = $this->get_columns();
288
+ $params = array();
289
+
290
+ foreach($columns as $index => $column)
291
+ {
292
+ if($column->Field == 'id')
293
+ continue;
294
+
295
+ $params[] = $this->get_column_parameter($column->Field);
296
+ }
297
+
298
+ return $params;
299
+ }
300
+
301
+ /**
302
+ * Gets the column name used to store arbitrary data, for instance, other_data, or NULL for tables which do not have such a field.
303
+ * @return string The name of the column used to store arbitrary data
304
+ */
305
+ protected function get_arbitrary_data_column_name()
306
+ {
307
+ return null;
308
+ }
309
+
310
+ /**
311
+ * Asserts that this object hasn't been trashed and throws an exception if it has
312
+ * @throws \Exception
313
+ * @return void
314
+ */
315
+ protected function assert_not_trashed()
316
+ {
317
+ if($this->trashed)
318
+ throw new \Exception('Operation on trashed map object');
319
+ }
320
+
321
+ /**
322
+ * Returns true if the named column exists on this map objects table
323
+ * @return bool
324
+ */
325
+ protected function column_exists($name)
326
+ {
327
+ return isset($cached_column_name_map_by_table_name[$this->table_name]);
328
+ }
329
+
330
+ /**
331
+ * Parses arbitrary data following a DB read, for example by unserializing strings or decoding JSON.
332
+ * @return void
333
+ */
334
+ protected function parse_arbitrary_data($data)
335
+ {
336
+ if(!$this->get_arbitrary_data_column_name())
337
+ throw new \Exception('No arbitrary data field on this table');
338
+
339
+ $data = maybe_unserialize($data);
340
+
341
+ if(!is_object($data) && !is_array($data))
342
+ return;
343
+
344
+ foreach($data as $key => $value)
345
+ $this->fields[$key] = $value;
346
+
347
+ $name = $this->get_arbitrary_data_column_name();
348
+ unset($this->fields[$name]);
349
+ }
350
+
351
+ /**
352
+ * Stores arbitrary data. This is not currently used.
353
+ * @return void
354
+ */
355
+ protected function store_arbitrary_data($key, $value)
356
+ {
357
+ if(!$this->get_arbitrary_data_column_name())
358
+ throw new \Exception('No arbitrary data field on this table');
359
+
360
+
361
+ }
362
+
363
+ /**
364
+ * Creates the map object in the database
365
+ * @throws \Exception The object has been trashed
366
+ * @return void
367
+ */
368
+ protected function create()
369
+ {
370
+ global $wpdb;
371
+
372
+ $this->assert_not_trashed();
373
+
374
+ // TODO: Support arbitrary data
375
+
376
+ $column_names = array_flip( $this->get_column_names() );
377
+ unset($column_names['id']);
378
+ $column_names = implode(',', array_keys($column_names));
379
+
380
+ $placeholders = implode(',', $this->get_column_placeholders());
381
+ $parameters = $this->get_column_parameters();
382
+
383
+ $qstr = "INSERT INTO `{$this->table_name}` ($column_names) VALUES ($placeholders)";
384
+
385
+ $stmt = $wpdb->prepare($qstr, $parameters);
386
+ $wpdb->query($stmt);
387
+
388
+ $this->id = $wpdb->insert_id;
389
+ }
390
+
391
+ protected function getReadColumns()
392
+ {
393
+ return array("*");
394
+ }
395
+
396
+ /**
397
+ * Reads the data from the database into this object
398
+ * @throws \Exception The object has been trashed
399
+ * @return void
400
+ */
401
+ protected function read($mode)
402
+ {
403
+ global $wpdb;
404
+
405
+ $this->assert_not_trashed();
406
+
407
+ $columns = implode(', ', $this->getReadColumns());
408
+
409
+ $stmt = $wpdb->prepare("SELECT $columns FROM " . $this->get_table_name() . " WHERE id = %d", array($this->id));
410
+
411
+ $results = $wpdb->get_results($stmt);
412
+
413
+ if(empty($results))
414
+ throw new \Exception(get_called_class() . " ID '{$this->id}' not found");
415
+
416
+ $this->fields = (array)$results[0];
417
+ unset($this->fields['id']);
418
+
419
+ $arbitrary_data_column_name = $this->get_arbitrary_data_column_name();
420
+
421
+ if($arbitrary_data_column_name && isset($this->fields[$arbitrary_data_column_name]))
422
+ {
423
+ $this->parse_arbitrary_data($this->fields[$arbitrary_data_column_name]);
424
+ unset($this->fields[$arbitrary_data_column_name]);
425
+ }
426
+ }
427
+
428
+ /**
429
+ * Returns true if the specified property is read only
430
+ * @return bool Whether or not the property is read only
431
+ */
432
+ protected function is_read_only($key)
433
+ {
434
+ switch($key)
435
+ {
436
+ case 'id':
437
+ case 'table_name':
438
+ case 'fields':
439
+ case 'modified':
440
+ case 'trashed':
441
+ return true;
442
+ break;
443
+ }
444
+
445
+ return false;
446
+ }
447
+
448
+ /**
449
+ * Updates the map object in the database
450
+ * @throws \Exception The object has been trashed
451
+ * @return $this
452
+ */
453
+ public function update()
454
+ {
455
+ global $wpdb;
456
+
457
+ $this->assert_not_trashed();
458
+
459
+ $column_names = array_flip( $this->get_column_names() );
460
+ unset($column_names['id']);
461
+ $column_names = array_keys($column_names);
462
+
463
+ $placeholders = $this->get_column_placeholders();
464
+ $parameters = $this->get_column_parameters();
465
+
466
+ $assignments = array();
467
+ for($i = 0; $i < count($column_names); $i++)
468
+ $assignments[] = $column_names[$i] . '=' . $placeholders[$i];
469
+ $assignments = implode(',', $assignments);
470
+
471
+ $parameters[] = $this->id;
472
+
473
+ $qstr = "UPDATE {$this->table_name} SET $assignments WHERE id=%d";
474
+ $stmt = $wpdb->prepare($qstr, $parameters);
475
+ $wpdb->query($stmt);
476
+
477
+ // Arbitrary data
478
+ $data = array();
479
+
480
+ foreach($this->fields as $key => $value)
481
+ {
482
+ if(array_search($key, $column_names) !== false)
483
+ continue;
484
+
485
+ $data[$key] = $value;
486
+ }
487
+
488
+ $arbitrary_data_column_name = $this->get_arbitrary_data_column_name();
489
+
490
+ if(!empty($data) && !$arbitrary_data_column_name)
491
+ trigger_error('Arbitrary data cannot be stored on this column - the following fields will be lost: ' . implode(', ', array_keys($data)), E_USER_WARNING);
492
+ else if($arbitrary_data_column_name)
493
+ {
494
+ $data = serialize($data);
495
+
496
+ $stmt = $wpdb->prepare("UPDATE {$this->table_name} SET $arbitrary_data_column_name=%s WHERE id=%d", array($data, $this->id));
497
+
498
+ $wpdb->query($stmt);
499
+ }
500
+
501
+ return $this;
502
+ }
503
+
504
+ /**
505
+ * Deletes the object from the database and sets the trashed flag
506
+ * @throws \Exception The object has been trashed
507
+ * @return void
508
+ */
509
+ public function trash()
510
+ {
511
+ global $wpdb;
512
+
513
+ $this->assert_not_trashed();
514
+
515
+ $stmt = $wpdb->prepare("DELETE FROM {$this->table_name} WHERE id=%d", array($this->id));
516
+
517
+ $wpdb->query($stmt);
518
+
519
+ $this->trashed = true;
520
+ }
521
+
522
+ public function duplicate()
523
+ {
524
+ global $wpdb;
525
+
526
+ $columns = array();
527
+
528
+ foreach($wpdb->get_col("SHOW COLUMNS FROM `{$this->table_name}`") as $name)
529
+ {
530
+ if($name == 'id')
531
+ continue;
532
+
533
+ $columns []= $name;
534
+ }
535
+
536
+ $imploded = implode(',', $columns);
537
+
538
+ $query = "INSERT INTO {$this->table_name} ($imploded) SELECT $imploded FROM {$this->table_name} WHERE id=%d";
539
+
540
+ $stmt = $wpdb->prepare($query, $this->id);
541
+
542
+ $wpdb->query($stmt);
543
+
544
+ $class = get_class($this);
545
+
546
+ return $class::createInstance($wpdb->insert_id);
547
+ }
548
+
549
+ /**
550
+ * Set variables in bulk, this reduces the number of database calls
551
+ * @param string|array|object Either a string naming the property to be set (with a second argument which is the value), or an array or object of key and value pairs to be set on this object
552
+ * @throws \Exception The object has been trashed
553
+ * @return $this
554
+ */
555
+ public function set($arg, $val=null)
556
+ {
557
+ $this->assert_not_trashed();
558
+
559
+ if(is_string($arg)){
560
+ if(is_string($val)){
561
+ $val = wp_kses_post($val);
562
+ }
563
+ $this->__set($arg, $val);
564
+ } else if(is_array($arg) || is_object($arg)){
565
+ foreach($arg as $key => $value){
566
+ if($this->is_read_only($key)){
567
+ throw new \Exception('Property is read only');
568
+ }
569
+
570
+ if(is_string($value)){
571
+ $value = wp_kses_post($value);
572
+ }
573
+ $this->fields[$key] = $value;
574
+ }
575
+
576
+ $this->update();
577
+ } else{
578
+ throw new \Exception('Invalid argument');
579
+ }
580
+
581
+ return $this;
582
+ }
583
+
584
+ /**
585
+ * Sets a variable on the object without writing to the database. Useful for overriding properties
586
+ */
587
+ public function override($key, $value)
588
+ {
589
+ $this->assert_not_trashed();
590
+
591
+ $this->overrides[$key] = $value;
592
+
593
+ return $this;
594
+ }
595
+
596
+ /**
597
+ * Get's the iterator for iterating over map object properties
598
+ * @throws \Exception The object has been trashed
599
+ * @return \ArrayIterator
600
+ */
601
+ public function getIterator()
602
+ {
603
+ $this->assert_not_trashed();
604
+
605
+ return new \ArrayIterator($this->fields);
606
+ }
607
+
608
+ /**
609
+ * Returns the objects properties to be serialized as JSON
610
+ * @throws \Exception
611
+ * @return array
612
+ */
613
+ public function jsonSerialize()
614
+ {
615
+ $this->assert_not_trashed();
616
+
617
+ if(!is_array($this->fields))
618
+ throw new \Exception("Field data is not an array");
619
+
620
+ return array_merge($this->fields, array('id' => $this->id));
621
+ }
622
+
623
+ /**
624
+ * Magic method to get map object fields
625
+ * @params string $name The name of the property to read
626
+ * @throws \Exception The object has been trashed
627
+ * @return mixed
628
+ */
629
+ public function __get($name)
630
+ {
631
+ $this->assert_not_trashed();
632
+
633
+ if(isset($this->fields[$name]))
634
+ return $this->fields[$name];
635
+
636
+ switch($name)
637
+ {
638
+ case 'id':
639
+ case 'modified':
640
+ case 'custom_fields':
641
+ return $this->{$name};
642
+ break;
643
+ }
644
+
645
+ return null;
646
+ }
647
+
648
+ /**
649
+ * Checks if a field is set by name
650
+ * @params string $name The name of the property to check
651
+ * @throws \Exception The object has been trashed.
652
+ * @return boolean
653
+ */
654
+ public function __isset($name)
655
+ {
656
+ $this->assert_not_trashed();
657
+
658
+ if($name == 'id')
659
+ return true;
660
+
661
+ return isset($this->fields[$name]);
662
+ }
663
+
664
+ /**
665
+ * Sets the property value by name and updates the database
666
+ * @param string $name The property name
667
+ * @param mixed $value The value to set on the specified property
668
+ * @throws \Exception The object has been trashed
669
+ * @throws \Exception The specified property is read-only
670
+ * @return void
671
+ */
672
+ public function __set($name, $value)
673
+ {
674
+ global $wpdb;
675
+
676
+ $this->assert_not_trashed();
677
+
678
+ if($this->is_read_only($name))
679
+ throw new \Exception('Property is read only');
680
+
681
+ if(is_string($value)){
682
+ $value = htmlspecialchars_decode(wp_kses_post($value));
683
+ }
684
+
685
+ $this->fields[$name] = $value;
686
+
687
+ $columns = $this->get_columns();
688
+
689
+ // TODO: This loop could be replaced with a placeholder cache
690
+ foreach($columns as $column)
691
+ {
692
+ if($column->Field != $name)
693
+ continue;
694
+
695
+ $placeholder = $this->get_placeholder_by_type($column->Type);
696
+ $params = array($value, $this->id);
697
+
698
+ $stmt = $wpdb->prepare("UPDATE {$this->table_name} SET $name = $placeholder WHERE id = %d", $params);
699
+ $wpdb->query($stmt);
700
+
701
+ return;
702
+ }
703
+
704
+ $arbitrary_data_column_name = $this->get_arbitrary_data_column_name();
705
+
706
+ if(!$arbitrary_data_column_name)
707
+ throw new \Exception('Cannot store arbitrary data on this table');
708
+
709
+ $stmt = $wpdb->prepare("SELECT $arbitrary_data_column_name FROM {$this->table_name} WHERE id=%d", array($this->id));
710
+
711
+ $raw = $wpdb->get_var($stmt);
712
+ $data = maybe_unserialize($raw);
713
+
714
+ if(empty($data))
715
+ $data = array();
716
+
717
+ $data[$name] = $value;
718
+
719
+ $data = serialize($data);
720
+
721
+ $stmt = $wpdb->prepare("UPDATE {$this->table_name} SET $arbitrary_data_column_name=%s WHERE id=%d", array($data, $this->id));
722
+
723
+ $wpdb->query($stmt);
724
+ }
725
+
726
+ /**
727
+ * Unsets the named variable, only valid for arbitrary data
728
+ * @throws \Exception when attempting to unset a column, as opposed to arbitrary data.
729
+ * @return void
730
+ */
731
+ public function __unset($name)
732
+ {
733
+ $column_names = $this->get_column_names();
734
+
735
+ if(array_search($name, $column_names) !== false)
736
+ throw new \Exception('Only arbitrary data can be unset. Columns must be set to NULL instead');
737
+
738
+ unset($this->fields[$name]);
739
+
740
+ $this->update();
741
+ }
742
+ }
includes/class.dom-element.php CHANGED
@@ -71,41 +71,6 @@ class DOMElement extends \DOMElement
71
  return new DOMQueryResults($results);
72
  }
73
 
74
- /**
75
- * Prepends the subject to this element.
76
- * @param $subject element or array of elements
77
- * @return $this element
78
- */
79
- public function prepend($subject)
80
- {
81
- if(is_array($subject))
82
- {
83
- $originalFirst = $this->firstChild;
84
-
85
- foreach($subject as $el)
86
- $this->insertBefore($el, $originalFirst);
87
- }
88
- else
89
- $this->insertBefore($subject, $this->firstChild);
90
-
91
- return $this;
92
- }
93
-
94
- /**
95
- * Appends the subject to this element.
96
- */
97
- public function append($subject)
98
- {
99
- if(is_array($subject))
100
- {
101
- foreach($subject as $el)
102
- $this->appendChild($subject);
103
- }
104
- else
105
- $this->appendChild($subject);
106
-
107
- return $this;
108
- }
109
 
110
  /**
111
  * Traverses from this node up it's ancestors and returns the first node that matches the given selector
@@ -740,11 +705,11 @@ class DOMElement extends \DOMElement
740
  * Removes this element from it's parent
741
  * @return \Smart\Element This element
742
  */
743
- public function remove()
744
  {
745
  if($this->parentNode)
746
  $this->parentNode->removeChild($this);
747
- return $this;
748
  }
749
  }
750
 
71
  return new DOMQueryResults($results);
72
  }
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
  /**
76
  * Traverses from this node up it's ancestors and returns the first node that matches the given selector
705
  * Removes this element from it's parent
706
  * @return \Smart\Element This element
707
  */
708
+ public function remove(): void
709
  {
710
  if($this->parentNode)
711
  $this->parentNode->removeChild($this);
712
+ // return $this;
713
  }
714
  }
715
 
includes/class.maps-engine-dialog.php CHANGED
@@ -1,174 +1,174 @@
1
- <?php
2
-
3
- namespace WPGMZA;
4
-
5
- if(!defined('ABSPATH'))
6
- return;
7
-
8
- /**
9
- * This class represents the map engine selection dialog, which is presented to the user on the map edit page.
10
- */
11
- class MapsEngineDialog
12
- {
13
- /**
14
- * Processes AJAX POST when the user makes a selection
15
- * @return void
16
- */
17
- public static function post(){
18
- global $wpgmza;
19
-
20
- if(!wp_verify_nonce($_POST['nonce'], 'wpgmza_maps_engine_dialog_set_engine')){
21
- http_response_code(403);
22
- exit;
23
- }
24
-
25
- if(!$wpgmza->isUserAllowedToEdit()){
26
- http_response_code(401);
27
- exit;
28
- }
29
-
30
- $settings = get_option('WPGMZA_OTHER_SETTINGS');
31
-
32
- $settings['wpgmza_maps_engine'] = sanitize_text_field($_POST['engine']);
33
- $settings['wpgmza_maps_engine_dialog_done'] = true;
34
-
35
- update_option('WPGMZA_OTHER_SETTINGS', $settings);
36
-
37
- wp_send_json(array('success' => 1));
38
- exit;
39
- }
40
-
41
- /**
42
- * Echos the dialog HTML
43
- * @return void
44
- */
45
- public function html(){
46
- ob_start();
47
-
48
- ?>
49
- <div
50
- id="wpgmza-maps-engine-dialog" style="display: none;"
51
- data-ajax-nonce="<?php echo wp_create_nonce('wpgmza_maps_engine_dialog_set_engine'); ?>"
52
- >
53
- <h1>
54
- <?php
55
- _e('Choose a maps engine', 'wp-google-maps');
56
- ?>
57
- </h1>
58
-
59
- <div class="wpgmza-inner">
60
- <div class="wpgmza-border-box__option">
61
- <input type="radio"
62
- name="wpgmza_maps_engine"
63
- id="wpgmza_maps_engine_open-layers"
64
- value="open-layers"
65
- />
66
- <label for="wpgmza_maps_engine_open-layers">
67
- <div>
68
- <!--<h3>
69
- <?php
70
- _e('OpenLayers', 'wp-google-maps');
71
- ?>
72
- </h3>-->
73
-
74
- <img class="wpgmza-engine-logo" src="<?php echo plugin_dir_url(__DIR__) . 'images/OpenLayers_logo.svg.png'?>"/>
75
-
76
- <ul>
77
- <li>
78
- <?php _e('No API keys required', 'wp-google-maps'); ?>
79
- </li>
80
- </ul>
81
- </div>
82
-
83
- <!--<p class="wpgmza-centered">
84
- <button class="button button-primary" data-maps-engine="open-layers">
85
- <?php
86
- _e('Use OpenLayers', 'wp-google-maps');
87
- ?>
88
-
89
- </button>
90
- </p>-->
91
-
92
- <p class="wpgmza-mock-radio wpgmza-centered">
93
- <span class="wpgmza-mock-radio-button"></span>
94
- <img class="wpgmza-mock-radio-label"
95
- src="<?php echo plugin_dir_url(__DIR__); ?>images/openlayers_logo.png"
96
- />
97
- </p>
98
- </label>
99
- </div>
100
-
101
- <div class="wpgmza-border-box__option">
102
- <input type="radio"
103
- name="wpgmza_maps_engine"
104
- id="wpgmza_maps_engine_google-maps"
105
- value="google-maps"
106
- />
107
- <label for="wpgmza_maps_engine_google-maps">
108
- <div>
109
- <!--<h3>
110
- <?php
111
- _e('Google Maps', 'wp-google-maps');
112
- ?>
113
- </h3>-->
114
-
115
- <img class="wpgmza-engine-logo" src="<?php echo plugin_dir_url(__DIR__) . 'images/icons8-google-maps-500.png'?>"/>
116
-
117
- <!--<ul class="wpgmza-pros">
118
- <li>
119
- <?php _e('Full functionality', 'wp-google-maps'); ?>
120
- </li>
121
- </ul>-->
122
-
123
- <ul>
124
- <li>
125
- <?php _e('API Key required', 'wp-google-maps'); ?>
126
- </li>
127
- </ul>
128
- </div>
129
-
130
- <!--<p class="wpgmza-centered">
131
- <button class="button button-primary" data-maps-engine="google-maps">
132
- <?php
133
- _e('Use Google Maps', 'wp-google-maps');
134
- ?>
135
- </button>
136
- </p>-->
137
-
138
- <p class="wpgmza-mock-radio wpgmza-centered">
139
- <span class="wpgmza-mock-radio-button"></span>
140
- <img class="wpgmza-mock-radio-label"
141
- src="<?php echo plugin_dir_url(__DIR__); ?>images/Google_maps_logo.png"
142
- />
143
- </p>
144
- </label>
145
- </div>
146
- </div>
147
-
148
- <p class="wpgmza-centered">
149
- <button class="button button-primary" id="wpgmza-confirm-engine" disabled style="display: none">
150
- <?php
151
- _e('Select Engine', 'wp-google-maps');
152
- ?>
153
- </button>
154
- </p>
155
-
156
- <!--<footer>
157
- <img src="<?php echo plugin_dir_url(__DIR__); ?>images/WP-google-maps-logo-1-B-transparent.png"
158
- alt="<?php _e('WP Google Maps', 'wp-google-maps'); ?>"
159
- />
160
- <img src="<?php echo plugin_dir_url(__DIR__); ?>images/codecabin.png"
161
- alt="by CODECABIN_"
162
- />
163
- </footer>-->
164
- </div>
165
- <?php
166
-
167
- $html = ob_get_contents();
168
- ob_end_clean();
169
-
170
- return $html;
171
- }
172
- }
173
-
174
  add_action('wp_ajax_wpgmza_maps_engine_dialog_set_engine', array('WPGMZA\\MapsEngineDialog', 'post'));
1
+ <?php
2
+
3
+ namespace WPGMZA;
4
+
5
+ if(!defined('ABSPATH'))
6
+ return;
7
+
8
+ /**
9
+ * This class represents the map engine selection dialog, which is presented to the user on the map edit page.
10
+ */
11
+ class MapsEngineDialog
12
+ {
13
+ /**
14
+ * Processes AJAX POST when the user makes a selection
15
+ * @return void
16
+ */
17
+ public static function post(){
18
+ global $wpgmza;
19
+
20
+ if(!wp_verify_nonce($_POST['nonce'], 'wpgmza_maps_engine_dialog_set_engine')){
21
+ http_response_code(403);
22
+ exit;
23
+ }
24
+
25
+ if(!$wpgmza->isUserAllowedToEdit()){
26
+ http_response_code(401);
27
+ exit;
28
+ }
29
+
30
+ $settings = get_option('WPGMZA_OTHER_SETTINGS');
31
+
32
+ $settings['wpgmza_maps_engine'] = sanitize_text_field($_POST['engine']);
33
+ $settings['wpgmza_maps_engine_dialog_done'] = true;
34
+
35
+ update_option('WPGMZA_OTHER_SETTINGS', $settings);
36
+
37
+ wp_send_json(array('success' => 1));
38
+ exit;
39
+ }
40
+
41
+ /**
42
+ * Echos the dialog HTML
43
+ * @return void
44
+ */
45
+ public function html(){
46
+ ob_start();
47
+
48
+ ?>
49
+ <div
50
+ id="wpgmza-maps-engine-dialog" style="display: none;"
51
+ data-ajax-nonce="<?php echo wp_create_nonce('wpgmza_maps_engine_dialog_set_engine'); ?>"
52
+ >
53
+ <h1>
54
+ <?php
55
+ _e('Choose a maps engine', 'wp-google-maps');
56
+ ?>
57
+ </h1>
58
+
59
+ <div class="wpgmza-inner">
60
+ <div class="wpgmza-border-box__option">
61
+ <input type="radio"
62
+ name="wpgmza_maps_engine"
63
+ id="wpgmza_maps_engine_open-layers"
64
+ value="open-layers"
65
+ />
66
+ <label for="wpgmza_maps_engine_open-layers">
67
+ <div>
68
+ <!--<h3>
69
+ <?php
70
+ _e('OpenLayers', 'wp-google-maps');
71
+ ?>
72
+ </h3>-->
73
+
74
+ <img class="wpgmza-engine-logo" src="<?php echo plugin_dir_url(__DIR__) . 'images/OpenLayers_logo.svg.png'?>"/>
75
+
76
+ <ul>
77
+ <li>
78
+ <?php _e('No API keys required', 'wp-google-maps'); ?>
79
+ </li>
80
+ </ul>
81
+ </div>
82
+
83
+ <!--<p class="wpgmza-centered">
84
+ <button class="button button-primary" data-maps-engine="open-layers">
85
+ <?php
86
+ _e('Use OpenLayers', 'wp-google-maps');
87
+ ?>
88
+
89
+ </button>
90
+ </p>-->
91
+
92
+ <p class="wpgmza-mock-radio wpgmza-centered">
93
+ <span class="wpgmza-mock-radio-button"></span>
94
+ <img class="wpgmza-mock-radio-label"
95
+ src="<?php echo plugin_dir_url(__DIR__); ?>images/openlayers_logo.png"
96
+ />
97
+ </p>
98
+ </label>
99
+ </div>
100
+
101
+ <div class="wpgmza-border-box__option">
102
+ <input type="radio"
103
+ name="wpgmza_maps_engine"
104
+ id="wpgmza_maps_engine_google-maps"
105
+ value="google-maps"
106
+ />
107
+ <label for="wpgmza_maps_engine_google-maps">
108
+ <div>
109
+ <!--<h3>
110
+ <?php
111
+ _e('Google Maps', 'wp-google-maps');
112
+ ?>
113
+ </h3>-->
114
+
115
+ <img class="wpgmza-engine-logo" src="<?php echo plugin_dir_url(__DIR__) . 'images/icons8-google-maps-500.png'?>"/>
116
+
117
+ <!--<ul class="wpgmza-pros">
118
+ <li>
119
+ <?php _e('Full functionality', 'wp-google-maps'); ?>
120
+ </li>
121
+ </ul>-->
122
+
123
+ <ul>
124
+ <li>
125
+ <?php _e('API Key required', 'wp-google-maps'); ?>
126
+ </li>
127
+ </ul>
128
+ </div>
129
+
130
+ <!--<p class="wpgmza-centered">
131
+ <button class="button button-primary" data-maps-engine="google-maps">
132
+ <?php
133
+ _e('Use Google Maps', 'wp-google-maps');
134
+ ?>
135
+ </button>
136
+ </p>-->
137
+
138
+ <p class="wpgmza-mock-radio wpgmza-centered">
139
+ <span class="wpgmza-mock-radio-button"></span>
140
+ <img class="wpgmza-mock-radio-label"
141
+ src="<?php echo plugin_dir_url(__DIR__); ?>images/Google_maps_logo.png"
142
+ />
143
+ </p>
144
+ </label>
145
+ </div>
146
+ </div>
147
+
148
+ <p class="wpgmza-centered">
149
+ <button class="button button-primary" id="wpgmza-confirm-engine" disabled style="display: none">
150
+ <?php
151
+ _e('Select Engine', 'wp-google-maps');
152
+ ?>
153
+ </button>
154
+ </p>
155
+
156
+ <!--<footer>
157
+ <img src="<?php echo plugin_dir_url(__DIR__); ?>images/WP-google-maps-logo-1-B-transparent.png"
158
+ alt="<?php _e('WP Google Maps', 'wp-google-maps'); ?>"
159
+ />
160
+ <img src="<?php echo plugin_dir_url(__DIR__); ?>images/codecabin.png"
161
+ alt="by CODECABIN_"
162
+ />
163
+ </footer>-->
164
+ </div>
165
+ <?php
166
+
167
+ $html = ob_get_contents();
168
+ ob_end_clean();
169
+
170
+ return $html;
171
+ }
172
+ }
173
+
174
  add_action('wp_ajax_wpgmza_maps_engine_dialog_set_engine', array('WPGMZA\\MapsEngineDialog', 'post'));
includes/class.rest-api.php CHANGED
@@ -1,974 +1,974 @@
1
- <?php
2
-
3
- namespace WPGMZA;
4
-
5
- if(!defined('ABSPATH'))
6
- return;
7
-
8
- /**
9
- * This class facilitates all communication between the client and any server side modules which can be interacted with through the WordPress REST API.
10
- */
11
- class RestAPI extends Factory
12
- {
13
- /**
14
- * @const The plugins REST API namespace
15
- */
16
- const NS = 'wpgmza/v1';
17
- const CUSTOM_BASE64_REGEX = '/base64[A-Za-z0-9+\- ]+(={0,3})?(\/[A-Za-z0-9+\- ]+(={0,3})?)?/';
18
-
19
- private $fallbackRoutesByRegex;
20
- private $nonceTable;
21
-
22
- /**
23
- * Constructor
24
- */
25
- public function __construct()
26
- {
27
- $this->fallbackRoutesByRegex = array();
28
- $this->nonceTable = array();
29
-
30
- // REST API init
31
- add_action('rest_api_init', array($this, 'onRestAPIInit'));
32
-
33
- add_action('parse_request', array($this, 'onParseRequest'));
34
- add_action('init', array($this, 'onInit'));
35
-
36
- // WP REST Cache integration
37
- add_filter('wp_rest_cache/allowed_endpoints', array($this, 'onWPRestCacheAllowedEndpoints'));
38
- add_filter('wp_rest_cache/determine_object_type', array($this, 'onWPRestCacheDetermineObjectType'), 10, 4);
39
-
40
- // AJAX callbacks for when REST API is blocked
41
- add_action('wp_ajax_wpgmza_report_rest_api_blocked', array($this, 'onReportRestAPIBlocked'));
42
- add_action('wp_ajax_nopriv_wpgmza_report_rest_api_blocked', array($this, 'onReportRestAPIBlocked'));
43
-
44
- // AJAX fallback for when REST API is blocked
45
- add_action('wp_ajax_wpgmza_rest_api_request', array($this, 'onAJAXRequest'));
46
- add_action('wp_ajax_nopriv_wpgmza_rest_api_request', array($this, 'onAJAXRequest'));
47
- }
48
-
49
- public static function isCompressedPathVariableSupported()
50
- {
51
- return function_exists('zlib_decode');
52
- }
53
-
54
- public static function isRequestURIUsingCompressedPathVariable()
55
- {
56
- return preg_match(RestAPI::CUSTOM_BASE64_REGEX, $_SERVER['REQUEST_URI']);
57
- }
58
-
59
- public static function isDoingAjax()
60
- {
61
- if(function_exists('wp_doing_ajax'))
62
- return wp_doing_ajax();
63
-
64
- return apply_filters( 'wp_doing_ajax', defined( 'DOING_AJAX' ) && DOING_AJAX );
65
- }
66
-
67
- protected function addRestNonce($route)
68
- {
69
- $this->nonceTable[$route] = wp_create_nonce('wpgmza_' . $route);
70
- }
71
-
72
- public function getNonceTable()
73
- {
74
- return $this->nonceTable;
75
- }
76
-
77
- protected function checkActionNonce($route)
78
- {
79
- $route = preg_replace('#^/wpgmza/v1#', '', $route);
80
- $nonce = $_SERVER['HTTP_X_WPGMZA_ACTION_NONCE'];
81
-
82
- $result = wp_verify_nonce($nonce, 'wpgmza_' . $route);
83
-
84
- return $result !== false;
85
- }
86
-
87
- public function registerRoute($route, $args)
88
- {
89
- $methodIsOnlyGET = true;
90
-
91
- if(!empty($args['methods']))
92
- {
93
- $methods = $args['methods'];
94
-
95
- if(is_string($methods))
96
- $methodIsOnlyGET = $methods == 'GET';
97
- else if(is_array($methods))
98
- {
99
- foreach($methods as $method)
100
- {
101
- if($method == 'GET')
102
- continue;
103
-
104
- $methodIsOnlyGET = false;
105
- break;
106
- }
107
- }
108
- }
109
-
110
- if(!defined('REST_REQUEST'))
111
- {
112
- if($methodIsOnlyGET)
113
- {
114
- $this->fallbackRoutesByRegex["#$route#"] = $args;
115
- return; // No need to add nonces for GET requests to the nonce table
116
- }
117
-
118
- $this->addRestNonce($route);
119
-
120
- if(!RestAPI::isDoingAjax())
121
- return;
122
- }
123
-
124
- $callback = $args['callback'];
125
-
126
- $args['callback'] = function($request) use ($route, $args, $callback, $methodIsOnlyGET)
127
- {
128
- global $wpgmza;
129
-
130
- $doActionNonceCheck =
131
- empty($args['skipNonceCheck']) &&
132
- !$methodIsOnlyGET &&
133
- (
134
- !$wpgmza->isProVersion()
135
- ||
136
- version_compare($wpgmza->getProVersion(), '7.11.47', '>=')
137
- );
138
-
139
- $skipNonceRoutes = array('features', 'markers', 'marker-listing', 'datatables');
140
- if(in_array(str_replace('/', '', $route), $skipNonceRoutes)){
141
- $doActionNonceCheck = false;
142
- }
143
-
144
- if($doActionNonceCheck && !$this->checkActionNonce($route))
145
- return new \WP_Error('wpgmza_action_not_allowed', 'You do not have permission to perform this action', array('status' => 403));
146
-
147
- return $callback($request);
148
- };
149
-
150
- if(defined('REST_REQUEST'))
151
- {
152
- register_rest_route(RestAPI::NS, $route, $args);
153
-
154
- if(isset($args['useCompressedPathVariable']) && $args['useCompressedPathVariable'])
155
- {
156
- $compressedRoute = preg_replace('#/$#', '', $route) . RestAPI::CUSTOM_BASE64_REGEX;
157
- register_rest_route(RestAPI::NS, $compressedRoute, $args);
158
- }
159
- }
160
-
161
- $this->fallbackRoutesByRegex["#$route#"] = $args;
162
- }
163
-
164
- protected function parseCompressedParameters($param)
165
- {
166
- $parts = explode('/', $param);
167
-
168
- if(empty($parts))
169
- throw new \Exception('Failed to explode compressed parameters');
170
-
171
- $data = $parts[0];
172
-
173
- $data = preg_replace('/^base64/', '', $data);
174
- $data = preg_replace('/-/', '/', $data);
175
- $data = preg_replace('/ /', '+', $data);
176
- $data = base64_decode($data);
177
-
178
-
179
- if(!function_exists('zlib_decode'))
180
- throw new \Exception('Server does not support inflate');
181
-
182
- if(!($string = zlib_decode($data)))
183
- throw new \Exception('The server failed to inflate the request');
184
-
185
-
186
- // TODO: Maybe $string should have stripslashes applied here
187
-
188
- if(!($request = json_decode($string, JSON_OBJECT_AS_ARRAY)))
189
- throw new \Exception('The decompressed request could not be interpreted as JSON');
190
- if(count($parts) == 2) {
191
- if(!isset($request['midcbp']))
192
- throw new \Exception('No compressed buffer pointer supplied for marker IDs');
193
-
194
- // Marker IDs
195
- $compressed = $parts[1];
196
-
197
- $compressed = preg_replace('/-/', '/', $compressed);
198
- $compressed = base64_decode($compressed);
199
- $compressed = zlib_decode($compressed);
200
- $compressed = array_values( unpack('C' . strlen($compressed), $compressed) );
201
-
202
- $pointer = (int)$request['midcbp'];
203
-
204
- $eliasFano = new EliasFano();
205
- $markerIDs = $eliasFano->decode($compressed, (int)$request['midcbp']);
206
- // TODO: Legacy markerIDs was a string, because this was historically more compact than POSTing an array. This can be altered, but the marker listing modules will have to be adjusted to cater for that
207
- $request['markerIDs'] = implode(',', $markerIDs);
208
- }
209
-
210
- return $request;
211
- }
212
-
213
- /**
214
- * This function will interpret the request parameters either from a compressed base64 string,
215
- * or from the $_REQUEST array when no compressed string is present
216
- * @return array The request parameters
217
- */
218
- public function getRequestParameters()
219
- {
220
- switch($_SERVER['REQUEST_METHOD'])
221
- {
222
- case 'GET':
223
-
224
- $uri = $_SERVER['REQUEST_URI'];
225
-
226
- if(preg_match(RestAPI::CUSTOM_BASE64_REGEX, $_SERVER['REQUEST_URI'], $m))
227
- return $this->parseCompressedParameters($m[0]);
228
-
229
- return $_GET;
230
-
231
- break;
232
-
233
- case 'POST':
234
-
235
- return $_POST;
236
-
237
- break;
238
-
239
- case 'DELETE':
240
- case 'PUT':
241
-
242
- $request = array();
243
- $body = file_get_contents('php://input');
244
- parse_str($body, $request);
245
-
246
- return $request;
247
-
248
- break;
249
-
250
- default:
251
-
252
- return $_REQUEST;
253
-
254
- break;
255
- }
256
- }
257
-
258
- protected function getFeatureTables()
259
- {
260
- global $wpdb;
261
-
262
- return array(
263
- 'polygons' => "{$wpdb->prefix}wpgmza_polygon",
264
- 'polylines' => "{$wpdb->prefix}wpgmza_polylines",
265
- 'circles' => "{$wpdb->prefix}wpgmza_circles",
266
- 'rectangles' => "{$wpdb->prefix}wpgmza_rectangles"
267
- );
268
- }
269
-
270
- protected function registerRoutes()
271
- {
272
- global $wpgmza;
273
-
274
- $this->registerRoute('/maps(\/\d+)?/', array(
275
- 'methods' => 'GET',
276
- 'callback' => array($this, 'maps')
277
- ));
278
-
279
- $this->registerRoute('/markers/\d+/', array(
280
- 'methods' => array('GET'),
281
- 'callback' => array($this, 'markers'),
282
- ));
283
-
284
- $this->registerRoute('/markers', array(
285
- 'methods' => array('GET'),
286
- 'callback' => array($this, 'markers'),
287
- 'useCompressedPathVariable' => true
288
- ));
289
-
290
- $this->registerRoute('/(features|polygons|polylines|circles|rectangles)(\/\d+)?/', array(
291
- 'methods' => array('GET'),
292
- 'callback' => array($this, 'features'),
293
- 'useCompressedPathVariable' => true,
294
- ));
295
-
296
- $this->registerRoute('/(polygons|polylines|circles|rectangles)(\/\d+)?/', array(
297
- 'methods' => array('DELETE', 'POST'),
298
- 'callback' => array($this, 'features'),
299
- 'permission_callback' => array($wpgmza, 'isUserAllowedToEdit')
300
- ));
301
-
302
- $this->registerRoute('/markers(\/\d+)?/', array(
303
- 'methods' => array('DELETE', 'POST'),
304
- 'callback' => array($this, 'markers'),
305
- 'permission_callback' => array($wpgmza, 'isUserAllowedToEdit')
306
- ));
307
-
308
- $this->registerRoute('/datatables', array(
309
- 'methods' => array('GET'),
310
- 'callback' => array($this, 'datatables'),
311
- 'useCompressedPathVariable' => true
312
- ));
313
-
314
- $this->registerRoute('/datatables', array(
315
- 'methods' => array('POST'),
316
- 'callback' => array($this, 'datatables')
317
- ));
318
-
319
- $this->registerRoute('/geocode-cache', array(
320
- 'methods' => array('GET'),
321
- 'callback' => array($this, 'geocodeCache'),
322
- 'useCompressedPathVariable' => true
323
- ));
324
-
325
- $this->registerRoute('/decompress', array(
326
- 'methods' => array('GET'),
327
- 'callback' => array($this, 'decompress'),
328
- 'useCompressedPathVariable' => true
329
- ));
330
-
331
- do_action('wpgmza_register_rest_api_routes');
332
- }
333
-
334
- /**
335
- * Callback for the rest_api_init action, this function registers the plugins REST API routes.
336
- * @return void
337
- */
338
- public function onRestAPIInit()
339
- {
340
- // NB: Permalink Manager Lite compatibility. This fix prevents the plugin from causing POST REST requests being redirected to GET
341
- // NB: We also check the plugin is active to mitigate any potential effects to other plugins. This could be removed, as an optimization
342
- global $wp_query;
343
-
344
- $active_plugins = get_option('active_plugins');
345
- if(!empty($wp_query->query_vars) && array_search('permalink-manager/permalink-manager.php', $active_plugins))
346
- $wp_query->query_vars['do_not_redirect'] = 1;
347
-
348
- $this->registerRoutes();
349
- }
350
-
351
- public function onParseRequest()
352
- {
353
- // Register routes for the nonce table
354
- if(!defined('REST_REQUEST'))
355
- $this->registerRoutes();
356
- }
357
-
358
- public function onInit()
359
- {
360
- $this->registerRoutes();
361
- }
362
-
363
- protected function sendAJAXResponse($result, $code=200)
364
- {
365
- if($code != 200)
366
- http_response_code($code);
367
-
368
- header('Content-type: application/json');
369
-
370
- echo json_encode($result);
371
- }
372
-
373
- public function onAJAXRequest()
374
- {
375
- $this->onRestAPIInit();
376
-
377
- // Check route is specified
378
- if(empty($_REQUEST['route']))
379
- {
380
- $this->sendAJAXResponse(array(
381
- 'code' => 'rest_no_route',
382
- 'message' => 'No route was found matching the URL request method',
383
- 'data' => array(
384
- 'status' => 404
385
- )
386
- ), 404);
387
- return;
388
- }
389
-
390
- // Try to match the route
391
- $args = null;
392
-
393
- foreach($this->fallbackRoutesByRegex as $regex => $value)
394
- {
395
- if(preg_match($regex, $_REQUEST['route']))
396
- {
397
- $args = $value;
398
- break;
399
- }
400
- }
401
-
402
- if(!$args)
403
- {
404
- $this->sendAJAXResponse(array(
405
- 'code' => 'rest_no_route',
406
- 'message' => 'No route was found matching the URL request method',
407
- 'data' => array(
408
- 'status' => 404
409
- )
410
- ), 404);
411
- exit;
412
- }
413
-
414
- // Check permissions
415
- if(!empty($args['permission_callback']))
416
- {
417
- $allowed = $args['permission_callback']();
418
-
419
- if(!$allowed)
420
- {
421
- $this->sendAJAXResponse(array(
422
- 'code' => 'rest_forbidden',
423
- 'message' => 'You are not authorized to use this method',
424
- 'data' => array(
425
- 'status' => 403
426
- )
427
- ), 403);
428
- exit;
429
- }
430
- }
431
-
432
- // Temporary fallback for the /features/ endpoint as this will not function as expected when moving to ajax
433
- // This helps with some nonce cache issues we see
434
- if(!empty($_REQUEST['route']) && $_REQUEST['route'] === '/features/'){
435
- $_SERVER['REQUEST_URI'] = "wpgmza/v1/features/";
436
- }
437
-
438
- // Fire callback
439
- $result = $args['callback'](null);
440
- $this->sendAJAXResponse($result);
441
-
442
- exit;
443
- }
444
-
445
- public function onWPRestCacheAllowedEndpoints($allowed_endpoints)
446
- {
447
- $cachable_endpoints = array(
448
- 'markers',
449
- 'datatables',
450
- 'geocode-cache',
451
- 'marker-listing',
452
- 'features'
453
- );
454
-
455
- foreach($cachable_endpoints as $endpoint)
456
- {
457
- if(!isset($allowed_endpoints[RestAPI::NS]) || !in_array($endpoint, $allowed_endpoints[RestAPI::NS]))
458
- $allowed_endpoints[RestAPI::NS][] = $endpoint;
459
- }
460
-
461
- return $allowed_endpoints;
462
- }
463
-
464
- public function onWPRestCacheDetermineObjectType($type, $cache_key, $data, $uri){
465
- if(strpos($uri, 'wpgmza') !== FALSE){
466
- return "WP Google Maps Data";
467
- }
468
- return $type;
469
- }
470
-
471
- public function maps($request)
472
- {
473
- global $wpdb;
474
- global $WPGMZA_TABLE_NAME_MAPS;
475
-
476
- $route = $_SERVER['REQUEST_URI'];
477
-
478
- switch($_SERVER['REQUEST_METHOD'])
479
- {
480
- case 'GET':
481
- if(preg_match('#/wpgmza/v1/maps/(\d+)#', $route, $m))
482
- {
483
- $map = Map::createInstance($m[1]);
484
- return $map;
485
- }
486
-
487
- $ids = $wpdb->get_col("SELECT id FROM $WPGMZA_TABLE_NAME_MAPS WHERE active=0");
488
-
489
- $result = array();
490
-
491
- if(empty($ids))
492
- return $result;
493
-
494
- foreach($ids as $id)
495
- $result[] = Map::createInstance($id);
496
-
497
- return $result;
498
-
499
- break;
500
-
501
- default:
502
- return new \WP_Error('wpgmza_invalid_request_method', 'Invalid request method');
503
- break;
504
- }
505
- }
506
-
507
- protected function sanitizeFieldNames($fields, $table)
508
- {
509
- global $wpdb;
510
-
511
- $whitelist = $wpdb->get_col("SHOW COLUMNS FROM $table");
512
- $result = array();
513
-
514
- foreach($fields as $name)
515
- {
516
- if(array_search($name, $whitelist) !== false)
517
- $result[] = $name;
518
- }
519
-
520
- return $result;
521
- }
522
-
523
- public function features($request)
524
- {
525
- global $wpdb;
526
-
527
- $route = $_SERVER['REQUEST_URI'];
528
-
529
-
530
- // NB: Not sure if this is intentional, but it works
531
- if(!preg_match('#wpgmza/v1/(\w+)(/\d+)?#', $_SERVER['REQUEST_URI'], $m)) {
532
- if(!preg_match('/(\w+)s(\/(\d+))?(\/?\?.+)?$/', $route, $m)) {
533
-
534
- return new \WP_Error('wpgmza_invalid_route', 'Invalid route');
535
- }
536
- }
537
-
538
-
539
- $feature_type = $m[1];
540
- $qualified = "WPGMZA\\" . rtrim( ucwords($feature_type), 's' );
541
-
542
- $this->checkForDeleteSimulation();
543
-
544
-
545
- switch($_SERVER['REQUEST_METHOD'])
546
- {
547
- case 'GET':
548
- $multiple_types = preg_match('/features(\/(\d+))?$/', $route);
549
- $features = array();
550
-
551
- $feature_id = (!empty($m[3]) ? ltrim($m[3], '/') : (!empty($m[2]) ? ltrim($m[2], '/') : null));
552
-
553
- $plural_feature_type = preg_replace('/s$/', '', $feature_type) . 's';
554
-
555
- if($multiple_types) {
556
- if($feature_id !== null)
557
- return new \WP_Error('wpgmza_id_invalid_on_route', 'Cannot fetch generic features with ID. You must call a specific route to fetch by ID.');
558
- }
559
- else if($feature_id) {
560
- // $qualified = "WPGMZA\\" . ucwords($feature_type);
561
- $instance = new $qualified($feature_id);
562
- return $instance;
563
- }
564
-
565
- $params = $this->getRequestParameters();
566
- $filteringParameters = $this->getFilteringParameters($params);
567
-
568
- $subclasses = Feature::getSubclasses();
569
- $types = array_map(function($str) { return strtolower($str) . 's'; }, $subclasses);
570
- $result = array(
571
- 'request' => $this->cleanRequestOutput($params)
572
- );
573
-
574
-
575
- if($filteringParameters)
576
- $result['request']['filter'] = $filteringParameters;
577
-
578
- $tables = $this->getFeatureTables();
579
-
580
-
581
-
582
-
583
- $exclude = array();
584
- if(isset($params['exclude']))
585
- $exclude = explode(',', $params['exclude']);
586
-
587
-
588
- $include = null;
589
- if(isset($params['include']))
590
- $include = explode(',', $params['include']);
591
-
592
-
593
-
594
- if($plural_feature_type != 'features') {
595
- foreach($types as $plural_type)
596
- {
597
- if($plural_type != $plural_feature_type)
598
- $exclude[] = $plural_type;
599
- }
600
- }
601
-
602
-
603
- foreach($types as $name) {
604
-
605
- if(array_search($name, $exclude) !== false) {
606
-
607
- continue;
608
- }
609
-
610
- if($include != null && array_search($name, $include) === false) {
611
-
612
- continue;
613
- }
614
-
615
- $features = array();
616
-
617
-
618
-
619
- if(method_exists($this, $name)) {
620
- $features = $this->$name($request);
621
- } else {
622
- $qualified = 'WPGMZA\\' . preg_replace('/s$/', '', ucwords($name));
623
- $table = $tables[$name];
624
- $map_ids = array();
625
-
626
- $columns = implode(', ', Feature::getBulkReadColumns($table));
627
-
628
- if(!empty($filteringParameters['map_id'])){
629
- $map_ids[] = $filteringParameters['map_id'];
630
- }
631
-
632
- if(!empty($filteringParameters['mashup_ids'])){
633
- $map_ids = array_merge($map_ids, $filteringParameters['mashup_ids']);
634
- }
635
-
636
- if(!empty($filteringParameters['mashupIDs'])){
637
- $map_ids = array_merge($map_ids, $filteringParameters['mashupIDs']);
638
- }
639
-
640
- $queryParams = array();
641
- $qstr = "SELECT $columns FROM $table";
642
-
643
- if(!empty($map_ids)){
644
- $queryParams = array_merge($queryParams, $map_ids);
645
- $placeholders = implode(',', array_fill(0, count($map_ids), '%d'));
646
-
647
- $qstr .= " WHERE map_id IN (" . $placeholders . ")";
648
- $stmt = $wpdb->prepare($qstr, $queryParams);
649
- } else {
650
- $stmt = $qstr;
651
- }
652
-
653
- foreach($wpdb->get_results($stmt) as $row)
654
- {
655
- $instance = new $qualified($row, Crud::BULK_READ);
656
-
657
- // NB: Not sure why we have to explicitly call jsonSerialize here, but if you don't, inheritence doesn't seem to work properly (eg Crud::jsonSerialize is used but Feature::jsonSerialize is ignored)
658
- $features[] = $instance->jsonSerialize();
659
- }
660
- }
661
-
662
- $result[$name] = $features;
663
- }
664
-
665
- return $result;
666
- break;
667
-
668
- case 'POST':
669
- $data = stripslashes_deep($_POST);
670
- $id = ( isset($m[3]) ? ltrim($m[3], '/') : ( isset($m[2]) ? ltrim($m[2], '/') : -1 ) );
671
- if(isset($data['id'])) {
672
- if($data['id'] != $id)
673
- trigger_error('Mismatch between REST route ID and request body ID', E_USER_WARNING);
674
-
675
- unset($data['id']);
676
- }
677
-
678
- $instance = new $qualified($id);
679
- $instance->set($data);
680
-
681
- return $instance;
682
-
683
- break;
684
-
685
- case 'DELETE':
686
-
687
- $id = ( isset($m[3]) ? ltrim($m[3], '/') : ( isset($m[2]) ? ltrim($m[2], '/') : -1) );
688
-
689
-
690
-
691
- $instance = new $qualified($id);
692
- $instance->trash();
693
-
694
- return array('success' => true);
695
-
696
- break;
697
-
698
- default:
699
- return new \WP_Error('wpgmza_invalid_request_method', 'Invalid request method');
700
- break;
701
- }
702
- }
703
-
704
- protected function getFilteringParameters($params)
705
- {
706
- $filteringParameters = array();
707
-
708
- if(!empty($params['filter']))
709
- {
710
- if(is_object($params['filter']))
711
- $filteringParameters = (array)$params['filter'];
712
- else if(is_array($params['filter']))
713
- $filteringParameters = $params['filter'];
714
- else if(is_string($params['filter']))
715
- {
716
- if(!($filteringParameters = json_decode( stripslashes($params['filter']) )))
717
- throw new \Exception("Invalid JSON in filtering parameters");
718
- }
719
- else
720
- throw new \Exception("Failed to interpret filtering parameters");
721
- }
722
-
723
- return (array)$filteringParameters;
724
- }
725
-
726
- protected function checkForDeleteSimulation(){
727
- if(!empty($_POST) && !empty($_POST['simulateDelete'])){
728
- $_SERVER['REQUEST_METHOD'] = "DELETE";
729
- unset($_POST['simulateDelete']);
730
- }
731
- }
732
-
733
- /**
734
- * Callback for the /markers REST API route.
735
- * @param \WP_REST_Request The REST request.
736
- * @return mixed Where an ID is specified on the URL, a single marker is returned. Where no ID is specified, an array of all markers are returned.
737
- */
738
- public function markers($request)
739
- {
740
- global $wpdb;
741
- global $wpgmza_tblname;
742
-
743
- $route = $_SERVER['REQUEST_URI'];
744
- $params = $this->getRequestParameters();
745
-
746
- $this->checkForDeleteSimulation();
747
-
748
- switch($_SERVER['REQUEST_METHOD'])
749
- {
750
- case 'GET':
751
- if(preg_match('#/wpgmza/v1/markers/(\d+)#', $route, $m)) {
752
-
753
- $marker = Marker::createInstance($m[1], Crud::SINGLE_READ, isset($_GET['raw_data']));
754
- return $marker;
755
- }
756
-
757
- $fields = null;
758
-
759
-
760
- if(isset($params['fields']) && is_string($params['fields']))
761
- $fields = explode(',', $params['fields']);
762
- else if(!empty($params['fields']))
763
- $fields = $params['fields'];
764
-
765
-
766
-
767
- if(!empty($fields))
768
- $fields = $this->sanitizeFieldNames($fields, $wpgmza_tblname);
769
-
770
- $filteringParameters = $this->getFilteringParameters($params);
771
-
772
- $markerFilter = MarkerFilter::createInstance($filteringParameters);
773
-
774
- foreach($filteringParameters as $key => $value)
775
- $markerFilter->{$key} = $value;
776
-
777
-
778
- $results = $markerFilter->getFilteredMarkers($fields);
779
- $arr = array();
780
-
781
- // We call this here so that caching doesn't try to serialize markers, resulting in bad characters
782
- // NB: A better approach might be to implement serializable, however I didn't have much luck doing that
783
- $classImplementsJsonSerializableCache = array();
784
-
785
- if(!empty($results)){
786
- foreach($results as $marker){
787
- if($marker instanceof Marker)
788
- {
789
- // Convert the marker to a plain array, so that it can be properly cached by REST API cache
790
- $json = $marker->jsonSerialize();
791
-
792
- foreach($json as $key => $value)
793
- {
794
- if(!is_object($value))
795
- continue;
796
-
797
- if(!isset($classImplementsJsonSerializableCache[$key]))
798
- {
799
- $reflection = new \ReflectionClass($value);
800
- $classImplementsJsonSerializableCache[$key] = $reflection->implementsInterface('JsonSerializable');
801
- }
802
-
803
- if(!$classImplementsJsonSerializableCache[$key])
804
- continue;
805
-
806
- $json[$key] = $value->jsonSerialize();
807
- }
808
-
809
- $arr[] = $json;
810
- }
811
- else
812
- $arr[] = $marker;
813
- }
814
- }
815
-
816
- // TODO: Select all custom field data too, in one query, and add that to the marker data in the following loop. Ideally we could add a bulk get function to the CRUD classes which takes IDs?
817
- // NB: Such a function has been implemented, just need to hook that up
818
-
819
- return $arr;
820
- break;
821
-
822
- case 'POST':
823
-
824
- if(preg_match('#/wpgmza/v1/markers/(\d+)#', $route, $m))
825
- $id = $m[1];
826
- else
827
- $id = -1;
828
-
829
- $marker = Marker::createInstance($id);
830
-
831
- foreach($_POST as $key => $value){
832
- if($key == 'id')
833
- continue;
834
-
835
- if($key == 'gallery'){
836
- $gallery = new MarkerGallery($_POST[$key]);
837
- $marker->gallery = $gallery;
838
- } else {
839
- $marker->{$key} = stripslashes($value);
840
- }
841
- }
842
-
843
- if(empty($_POST['gallery']) && !empty($marker->gallery)){
844
- $marker->gallery = false;
845
- }
846
-
847
- $map = Map::createInstance($marker->map_id);
848
- $map->updateXMLFile();
849
-
850
- return $marker;
851
-
852
- break;
853
-
854
- case 'DELETE':
855
-
856
- // Workaround for PHP not populating $_REQUEST
857
- $request = array();
858
- $body = file_get_contents('php://input');
859
- parse_str($body, $request);
860
-
861
- $id = null;
862
- if(isset($request['id']))
863
- $id = $request['id'];
864
- else if(preg_match('/markers\/(\d+)/', $route, $m))
865
- $id = $m[1];
866
-
867
- if($id){
868
- $marker = Marker::createInstance($id);
869
-
870
- $mapId = $marker->map_id;
871
-
872
- $marker->trash();
873
-
874
- $map = Map::createInstance($mapId);
875
- $map->updateXMLFile();
876
- } else if(isset($request['ids'])) {
877
- Marker::bulk_trash($request['ids']);
878
- } else{
879
- http_response_code(400);
880
- return (object)array(
881
- 'message' => "No ID(s) specified",
882
- 'success' => false
883
- );
884
- }
885
-
886
- return (object)array(
887
- 'success' => true
888
- );
889
-
890
- break;
891
-
892
- default:
893
- return new \WP_Error('wpgmza_invalid_request_method', 'Invalid request method');
894
- break;
895
- }
896
-
897
-
898
- }
899
-
900
- public function datatables()
901
- {
902
- $request = $this->getRequestParameters();
903
-
904
- // NB: Legacy support
905
- if(isset($request['wpgmzaDataTableRequestData']))
906
- $request = $request['wpgmzaDataTableRequestData'];
907
-
908
-
909
- if(RestAPI::isRequestURIUsingCompressedPathVariable())
910
- $class = '\\' . $request['phpClass'];
911
- else
912
- $class = '\\' . stripslashes( $request['phpClass'] );
913
-
914
- try{
915
- $reflection = new \ReflectionClass($class);
916
- }catch(Exception $e) {
917
- return new \WP_Error('wpgmza_invalid_datatable_class', 'Invalid class specified', array('status' => 403));
918
- }
919
-
920
- if((class_exists('\\WPGMZA\\MarkerListing') && $reflection->isSubclassOf('\\WPGMZA\\MarkerListing'))
921
- || (class_exists('\\WPGMZA\\MarkerListing\\AdvancedTable') && ($class == '\\WPGMZA\\MarkerListing\\AdvancedTable' || $reflection->isSubclassOf('\\WPGMZA\\MarkerListing\\AdvancedTable')))){
922
-
923
- $map_id = $request['map_id'];
924
- $instance = $class::createInstance($map_id);
925
- } else {
926
- $instance = $class::createInstance();
927
- }
928
-
929
- if(!($instance instanceof DataTable))
930
- return new \WP_Error('wpgmza_invalid_datatable_class', 'Specified PHP class must extend WPGMZA\\DataTable', array('status' => 403));
931
-
932
- $result = $instance->data($request);
933
-
934
- return $result;
935
- }
936
-
937
- public function geocodeCache($request)
938
- {
939
- $params = $this->getRequestParameters();
940
- $cache = new NominatimGeocodeCache();
941
-
942
- $record = $cache->get(addslashes($params['query']));
943
-
944
- if(!$record)
945
- $record = array();
946
-
947
- return $record;
948
- }
949
-
950
- public function decompress($request)
951
- {
952
- $params = $this->getRequestParameters();
953
-
954
- return $params;
955
- }
956
-
957
- public function onReportRestAPIBlocked()
958
- {
959
- $now = new \DateTime();
960
-
961
- update_option('wpgmza_last_rest_api_blocked', $now->format(\DateTime::ISO8601));
962
- }
963
-
964
- public function cleanRequestOutput($requestData){
965
- if(!empty($requestData) && is_array($requestData)){
966
- foreach($requestData as $key => $value){
967
- if(is_string($value)){
968
- $requestData[$key] = sanitize_text_field($value);
969
- }
970
- }
971
- }
972
- return $requestData;
973
- }
974
  }
1
+ <?php
2
+
3
+ namespace WPGMZA;
4
+
5
+ if(!defined('ABSPATH'))
6
+ return;
7
+
8
+ /**
9
+ * This class facilitates all communication between the client and any server side modules which can be interacted with through the WordPress REST API.
10
+ */
11
+ class RestAPI extends Factory
12
+ {
13
+ /**
14
+ * @const The plugins REST API namespace
15
+ */
16
+ const NS = 'wpgmza/v1';
17
+ const CUSTOM_BASE64_REGEX = '/base64[A-Za-z0-9+\- ]+(={0,3})?(\/[A-Za-z0-9+\- ]+(={0,3})?)?/';
18
+
19
+ private $fallbackRoutesByRegex;
20
+ private $nonceTable;
21
+
22
+ /**
23
+ * Constructor
24
+ */
25
+ public function __construct()
26
+ {
27
+ $this->fallbackRoutesByRegex = array();
28
+ $this->nonceTable = array();
29
+
30
+ // REST API init
31
+ add_action('rest_api_init', array($this, 'onRestAPIInit'));
32
+
33
+ add_action('parse_request', array($this, 'onParseRequest'));
34
+ add_action('init', array($this, 'onInit'));
35
+
36
+ // WP REST Cache integration
37
+ add_filter('wp_rest_cache/allowed_endpoints', array($this, 'onWPRestCacheAllowedEndpoints'));
38
+ add_filter('wp_rest_cache/determine_object_type', array($this, 'onWPRestCacheDetermineObjectType'), 10, 4);
39
+
40
+ // AJAX callbacks for when REST API is blocked
41
+ add_action('wp_ajax_wpgmza_report_rest_api_blocked', array($this, 'onReportRestAPIBlocked'));
42
+ add_action('wp_ajax_nopriv_wpgmza_report_rest_api_blocked', array($this, 'onReportRestAPIBlocked'));
43
+
44
+ // AJAX fallback for when REST API is blocked
45
+ add_action('wp_ajax_wpgmza_rest_api_request', array($this, 'onAJAXRequest'));
46
+ add_action('wp_ajax_nopriv_wpgmza_rest_api_request', array($this, 'onAJAXRequest'));
47
+ }
48
+
49
+ public static function isCompressedPathVariableSupported()
50
+ {
51
+ return function_exists('zlib_decode');
52
+ }
53
+
54
+ public static function isRequestURIUsingCompressedPathVariable()
55
+ {
56
+ return preg_match(RestAPI::CUSTOM_BASE64_REGEX, $_SERVER['REQUEST_URI']);
57
+ }
58
+
59
+ public static function isDoingAjax()
60
+ {
61
+ if(function_exists('wp_doing_ajax'))
62
+ return wp_doing_ajax();
63
+
64
+ return apply_filters( 'wp_doing_ajax', defined( 'DOING_AJAX' ) && DOING_AJAX );
65
+ }
66
+
67
+ protected function addRestNonce($route)
68
+ {
69
+ $this->nonceTable[$route] = wp_create_nonce('wpgmza_' . $route);
70
+ }
71
+
72
+ public function getNonceTable()
73
+ {
74
+ return $this->nonceTable;
75
+ }
76
+
77
+ protected function checkActionNonce($route)
78
+ {
79
+ $route = preg_replace('#^/wpgmza/v1#', '', $route);
80
+ $nonce = $_SERVER['HTTP_X_WPGMZA_ACTION_NONCE'];
81
+
82
+ $result = wp_verify_nonce($nonce, 'wpgmza_' . $route);
83
+
84
+ return $result !== false;
85
+ }
86
+
87
+ public function registerRoute($route, $args)
88
+ {
89
+ $methodIsOnlyGET = true;
90
+
91
+ if(!empty($args['methods']))
92
+ {
93
+ $methods = $args['methods'];
94
+
95
+ if(is_string($methods))
96
+ $methodIsOnlyGET = $methods == 'GET';
97
+ else if(is_array($methods))
98
+ {
99
+ foreach($methods as $method)
100
+ {
101
+ if($method == 'GET')
102
+ continue;
103
+
104
+ $methodIsOnlyGET = false;
105
+ break;
106
+ }
107
+ }
108
+ }
109
+
110
+ if(!defined('REST_REQUEST'))
111
+ {
112
+ if($methodIsOnlyGET)
113
+ {
114
+ $this->fallbackRoutesByRegex["#$route#"] = $args;
115
+ return; // No need to add nonces for GET requests to the nonce table
116
+ }
117
+
118
+ $this->addRestNonce($route);
119
+
120
+ if(!RestAPI::isDoingAjax())
121
+ return;
122
+ }
123
+
124
+ $callback = $args['callback'];
125
+
126
+ $args['callback'] = function($request) use ($route, $args, $callback, $methodIsOnlyGET)
127
+ {
128
+ global $wpgmza;
129
+
130
+ $doActionNonceCheck =
131
+ empty($args['skipNonceCheck']) &&
132
+ !$methodIsOnlyGET &&
133
+ (
134
+ !$wpgmza->isProVersion()
135
+ ||
136
+ version_compare($wpgmza->getProVersion(), '7.11.47', '>=')
137
+ );
138
+
139
+ $skipNonceRoutes = array('features', 'markers', 'marker-listing', 'datatables');
140
+ if(in_array(str_replace('/', '', $route), $skipNonceRoutes)){
141
+ $doActionNonceCheck = false;
142
+ }
143
+
144
+ if($doActionNonceCheck && !$this->checkActionNonce($route))
145
+ return new \WP_Error('wpgmza_action_not_allowed', 'You do not have permission to perform this action', array('status' => 403));
146
+
147
+ return $callback($request);
148
+ };
149
+
150
+ if(defined('REST_REQUEST'))
151
+ {
152
+ register_rest_route(RestAPI::NS, $route, $args);
153
+
154
+ if(isset($args['useCompressedPathVariable']) && $args['useCompressedPathVariable'])
155
+ {
156
+ $compressedRoute = preg_replace('#/$#', '', $route) . RestAPI::CUSTOM_BASE64_REGEX;
157
+ register_rest_route(RestAPI::NS, $compressedRoute, $args);
158
+ }
159
+ }
160
+
161
+ $this->fallbackRoutesByRegex["#$route#"] = $args;
162
+ }
163
+
164
+ protected function parseCompressedParameters($param)
165
+ {
166
+ $parts = explode('/', $param);
167
+
168
+ if(empty($parts))
169
+ throw new \Exception('Failed to explode compressed parameters');
170
+
171
+ $data = $parts[0];
172
+
173
+ $data = preg_replace('/^base64/', '', $data);
174
+ $data = preg_replace('/-/', '/', $data);
175
+ $data = preg_replace('/ /', '+', $data);
176
+ $data = base64_decode($data);
177
+
178
+
179
+ if(!function_exists('zlib_decode'))
180
+ throw new \Exception('Server does not support inflate');
181
+
182
+ if(!($string = zlib_decode($data)))
183
+ throw new \Exception('The server failed to inflate the request');
184
+
185
+
186
+ // TODO: Maybe $string should have stripslashes applied here
187
+
188
+ if(!($request = json_decode($string, JSON_OBJECT_AS_ARRAY)))
189
+ throw new \Exception('The decompressed request could not be interpreted as JSON');
190
+ if(count($parts) == 2) {
191
+ if(!isset($request['midcbp']))
192
+ throw new \Exception('No compressed buffer pointer supplied for marker IDs');
193
+
194
+ // Marker IDs
195
+ $compressed = $parts[1];
196
+
197
+ $compressed = preg_replace('/-/', '/', $compressed);
198
+ $compressed = base64_decode($compressed);
199
+ $compressed = zlib_decode($compressed);
200
+ $compressed = array_values( unpack('C' . strlen($compressed), $compressed) );
201
+
202
+ $pointer = (int)$request['midcbp'];
203
+
204
+ $eliasFano = new EliasFano();
205
+ $markerIDs = $eliasFano->decode($compressed, (int)$request['midcbp']);
206
+ // TODO: Legacy markerIDs was a string, because this was historically more compact than POSTing an array. This can be altered, but the marker listing modules will have to be adjusted to cater for that
207
+ $request['markerIDs'] = implode(',', $markerIDs);
208
+ }
209
+
210
+ return $request;
211
+ }
212
+
213
+ /**
214
+ * This function will interpret the request parameters either from a compressed base64 string,
215
+ * or from the $_REQUEST array when no compressed string is present
216
+ * @return array The request parameters
217
+ */
218
+ public function getRequestParameters()
219
+ {
220
+ switch($_SERVER['REQUEST_METHOD'])
221
+ {
222
+ case 'GET':
223
+
224
+ $uri = $_SERVER['REQUEST_URI'];
225
+
226
+ if(preg_match(RestAPI::CUSTOM_BASE64_REGEX, $_SERVER['REQUEST_URI'], $m))
227
+ return $this->parseCompressedParameters($m[0]);
228
+
229
+ return $_GET;
230
+
231
+ break;
232
+
233
+ case 'POST':
234
+
235
+ return $_POST;
236
+
237
+ break;
238
+
239
+ case 'DELETE':
240
+ case 'PUT':
241
+
242
+ $request = array();
243
+ $body = file_get_contents('php://input');
244
+ parse_str($body, $request);
245
+
246
+ return $request;
247
+
248
+ break;
249
+
250
+ default:
251
+
252
+ return $_REQUEST;
253
+
254
+ break;
255
+ }
256
+ }
257
+
258
+ protected function getFeatureTables()
259
+ {
260
+ global $wpdb;
261
+
262
+ return array(
263
+ 'polygons' => "{$wpdb->prefix}wpgmza_polygon",
264
+ 'polylines' => "{$wpdb->prefix}wpgmza_polylines",
265
+ 'circles' => "{$wpdb->prefix}wpgmza_circles",
266
+ 'rectangles' => "{$wpdb->prefix}wpgmza_rectangles"
267
+ );
268
+ }
269
+
270
+ protected function registerRoutes()
271
+ {
272
+ global $wpgmza;
273
+
274
+ $this->registerRoute('/maps(\/\d+)?/', array(
275
+ 'methods' => 'GET',
276
+ 'callback' => array($this, 'maps')
277
+ ));
278
+
279
+ $this->registerRoute('/markers/\d+/', array(
280
+ 'methods' => array('GET'),
281
+ 'callback' => array($this, 'markers'),
282
+ ));
283
+
284
+ $this->registerRoute('/markers', array(
285
+ 'methods' => array('GET'),
286
+ 'callback' => array($this, 'markers'),
287
+ 'useCompressedPathVariable' => true
288
+ ));
289
+
290
+ $this->registerRoute('/(features|polygons|polylines|circles|rectangles)(\/\d+)?/', array(
291
+ 'methods' => array('GET'),
292
+ 'callback' => array($this, 'features'),
293
+ 'useCompressedPathVariable' => true,
294
+ ));
295
+
296
+ $this->registerRoute('/(polygons|polylines|circles|rectangles)(\/\d+)?/', array(
297
+ 'methods' => array('DELETE', 'POST'),
298
+ 'callback' => array($this, 'features'),
299
+ 'permission_callback' => array($wpgmza, 'isUserAllowedToEdit')
300
+ ));
301
+
302
+ $this->registerRoute('/markers(\/\d+)?/', array(
303
+ 'methods' => array('DELETE', 'POST'),
304
+ 'callback' => array($this, 'markers'),
305
+ 'permission_callback' => array($wpgmza, 'isUserAllowedToEdit')
306
+ ));
307
+
308
+ $this->registerRoute('/datatables', array(
309
+ 'methods' => array('GET'),
310
+ 'callback' => array($this, 'datatables'),
311
+ 'useCompressedPathVariable' => true
312
+ ));
313
+
314
+ $this->registerRoute('/datatables', array(
315
+ 'methods' => array('POST'),
316
+ 'callback' => array($this, 'datatables')
317
+ ));
318
+
319
+ $this->registerRoute('/geocode-cache', array(
320
+ 'methods' => array('GET'),
321
+ 'callback' => array($this, 'geocodeCache'),
322
+ 'useCompressedPathVariable' => true
323
+ ));
324
+
325
+ $this->registerRoute('/decompress', array(
326
+ 'methods' => array('GET'),
327
+ 'callback' => array($this, 'decompress'),
328
+ 'useCompressedPathVariable' => true
329
+ ));
330
+
331
+ do_action('wpgmza_register_rest_api_routes');
332
+ }
333
+
334
+ /**
335
+ * Callback for the rest_api_init action, this function registers the plugins REST API routes.
336
+ * @return void
337
+ */
338
+ public function onRestAPIInit()
339
+ {
340
+ // NB: Permalink Manager Lite compatibility. This fix prevents the plugin from causing POST REST requests being redirected to GET
341
+ // NB: We also check the plugin is active to mitigate any potential effects to other plugins. This could be removed, as an optimization
342
+ global $wp_query;
343
+
344
+ $active_plugins = get_option('active_plugins');
345
+ if(!empty($wp_query->query_vars) && array_search('permalink-manager/permalink-manager.php', $active_plugins))
346
+ $wp_query->query_vars['do_not_redirect'] = 1;
347
+
348
+ $this->registerRoutes();
349
+ }
350
+
351
+ public function onParseRequest()
352
+ {
353
+ // Register routes for the nonce table
354
+ if(!defined('REST_REQUEST'))
355
+ $this->registerRoutes();
356
+ }
357
+
358
+ public function onInit()
359
+ {
360
+ $this->registerRoutes();
361
+ }
362
+
363
+ protected function sendAJAXResponse($result, $code=200)
364
+ {
365
+ if($code != 200)
366
+ http_response_code($code);
367
+
368
+ header('Content-type: application/json');
369
+
370
+ echo json_encode($result);
371
+ }
372
+
373
+ public function onAJAXRequest()
374
+ {
375
+ $this->onRestAPIInit();
376
+
377
+ // Check route is specified
378
+ if(empty($_REQUEST['route']))
379
+ {
380
+ $this->sendAJAXResponse(array(
381
+ 'code' => 'rest_no_route',
382
+ 'message' => 'No route was found matching the URL request method',
383
+ 'data' => array(
384
+ 'status' => 404
385
+ )
386
+ ), 404);
387
+ return;
388
+ }
389
+
390
+ // Try to match the route
391
+ $args = null;
392
+
393
+ foreach($this->fallbackRoutesByRegex as $regex => $value)
394
+ {
395
+ if(preg_match($regex, $_REQUEST['route']))
396
+ {
397
+ $args = $value;
398
+ break;
399
+ }
400
+ }
401
+
402
+ if(!$args)
403
+ {
404
+ $this->sendAJAXResponse(array(
405
+ 'code' => 'rest_no_route',
406
+ 'message' => 'No route was found matching the URL request method',
407
+ 'data' => array(
408
+ 'status' => 404
409
+ )
410
+ ), 404);
411
+ exit;
412
+ }
413
+
414
+ // Check permissions
415
+ if(!empty($args['permission_callback']))
416
+ {
417
+ $allowed = $args['permission_callback']();
418
+
419
+ if(!$allowed)
420
+ {
421
+ $this->sendAJAXResponse(array(
422
+ 'code' => 'rest_forbidden',
423
+ 'message' => 'You are not authorized to use this method',
424
+ 'data' => array(
425
+ 'status' => 403
426
+ )
427
+ ), 403);
428
+ exit;
429
+ }
430
+ }
431
+
432
+ // Temporary fallback for the /features/ endpoint as this will not function as expected when moving to ajax
433
+ // This helps with some nonce cache issues we see
434
+ if(!empty($_REQUEST['route']) && $_REQUEST['route'] === '/features/'){
435
+ $_SERVER['REQUEST_URI'] = "wpgmza/v1/features/";
436
+ }
437
+
438
+ // Fire callback
439
+ $result = $args['callback'](null);
440
+ $this->sendAJAXResponse($result);
441
+
442
+ exit;
443
+ }
444
+
445
+ public function onWPRestCacheAllowedEndpoints($allowed_endpoints)
446
+ {
447
+ $cachable_endpoints = array(
448
+ 'markers',
449
+ 'datatables',
450
+ 'geocode-cache',
451
+ 'marker-listing',
452
+ 'features'
453
+ );
454
+
455
+ foreach($cachable_endpoints as $endpoint)
456
+ {
457
+ if(!isset($allowed_endpoints[RestAPI::NS]) || !in_array($endpoint, $allowed_endpoints[RestAPI::NS]))
458
+ $allowed_endpoints[RestAPI::NS][] = $endpoint;
459
+ }
460
+
461
+ return $allowed_endpoints;
462
+ }
463
+
464
+ public function onWPRestCacheDetermineObjectType($type, $cache_key, $data, $uri){
465
+ if(strpos($uri, 'wpgmza') !== FALSE){
466
+ return "WP Google Maps Data";
467
+ }
468
+ return $type;
469
+ }
470
+
471
+ public function maps($request)
472
+ {
473
+ global $wpdb;
474
+ global $WPGMZA_TABLE_NAME_MAPS;
475
+
476
+ $route = $_SERVER['REQUEST_URI'];
477
+
478
+ switch($_SERVER['REQUEST_METHOD'])
479
+ {
480
+ case 'GET':
481
+ if(preg_match('#/wpgmza/v1/maps/(\d+)#', $route, $m))
482
+ {
483
+ $map = Map::createInstance($m[1]);
484
+ return $map;
485
+ }
486
+
487
+ $ids = $wpdb->get_col("SELECT id FROM $WPGMZA_TABLE_NAME_MAPS WHERE active=0");
488
+
489
+ $result = array();
490
+
491
+ if(empty($ids))
492
+ return $result;
493
+
494
+ foreach($ids as $id)
495
+ $result[] = Map::createInstance($id);
496
+
497
+ return $result;
498
+
499
+ break;
500
+
501
+ default:
502
+ return new \WP_Error('wpgmza_invalid_request_method', 'Invalid request method');
503
+ break;
504
+ }
505
+ }
506
+
507
+ protected function sanitizeFieldNames($fields, $table)
508
+ {
509
+ global $wpdb;
510
+
511
+ $whitelist = $wpdb->get_col("SHOW COLUMNS FROM $table");
512
+ $result = array();
513
+
514
+ foreach($fields as $name)
515
+ {
516
+ if(array_search($name, $whitelist) !== false)
517
+ $result[] = $name;
518
+ }
519
+
520
+ return $result;
521
+ }
522
+
523
+ public function features($request)
524
+ {
525
+ global $wpdb;
526
+
527
+ $route = $_SERVER['REQUEST_URI'];
528
+
529
+
530
+ // NB: Not sure if this is intentional, but it works
531
+ if(!preg_match('#wpgmza/v1/(\w+)(/\d+)?#', $_SERVER['REQUEST_URI'], $m)) {
532
+ if(!preg_match('/(\w+)s(\/(\d+))?(\/?\?.+)?$/', $route, $m)) {
533
+
534
+ return new \WP_Error('wpgmza_invalid_route', 'Invalid route');
535
+ }
536
+ }
537
+
538
+
539
+ $feature_type = $m[1];
540
+ $qualified = "WPGMZA\\" . rtrim( ucwords($feature_type), 's' );
541
+
542
+ $this->checkForDeleteSimulation();
543
+
544
+
545
+ switch($_SERVER['REQUEST_METHOD'])
546
+ {
547
+ case 'GET':
548
+ $multiple_types = preg_match('/features(\/(\d+))?$/', $route);
549
+ $features = array();
550
+
551
+ $feature_id = (!empty($m[3]) ? ltrim($m[3], '/') : (!empty($m[2]) ? ltrim($m[2], '/') : null));
552
+
553
+ $plural_feature_type = preg_replace('/s$/', '', $feature_type) . 's';
554
+
555
+ if($multiple_types) {
556
+ if($feature_id !== null)
557
+ return new \WP_Error('wpgmza_id_invalid_on_route', 'Cannot fetch generic features with ID. You must call a specific route to fetch by ID.');
558
+ }
559
+ else if($feature_id) {
560
+ // $qualified = "WPGMZA\\" . ucwords($feature_type);
561
+ $instance = new $qualified($feature_id);
562
+ return $instance;
563
+ }
564
+
565
+ $params = $this->getRequestParameters();
566
+ $filteringParameters = $this->getFilteringParameters($params);
567
+
568
+ $subclasses = Feature::getSubclasses();
569
+ $types = array_map(function($str) { return strtolower($str) . 's'; }, $subclasses);
570
+ $result = array(
571
+ 'request' => $this->cleanRequestOutput($params)
572
+ );
573
+
574
+
575
+ if($filteringParameters)
576
+ $result['request']['filter'] = $filteringParameters;
577
+
578
+ $tables = $this->getFeatureTables();
579
+
580
+
581
+
582
+
583
+ $exclude = array();
584
+ if(isset($params['exclude']))
585
+ $exclude = explode(',', $params['exclude']);
586
+
587
+
588
+ $include = null;
589
+ if(isset($params['include']))
590
+ $include = explode(',', $params['include']);
591
+
592
+
593
+
594
+ if($plural_feature_type != 'features') {
595
+ foreach($types as $plural_type)
596
+ {
597
+ if($plural_type != $plural_feature_type)
598
+ $exclude[] = $plural_type;
599
+ }
600
+ }
601
+
602
+
603
+ foreach($types as $name) {
604
+
605
+ if(array_search($name, $exclude) !== false) {
606
+
607
+ continue;
608
+ }
609
+
610
+ if($include != null && array_search($name, $include) === false) {
611
+
612
+ continue;
613
+ }
614
+
615
+ $features = array();
616
+
617
+
618
+
619
+ if(method_exists($this, $name)) {
620
+ $features = $this->$name($request);
621
+ } else {
622
+ $qualified = 'WPGMZA\\' . preg_replace('/s$/', '', ucwords($name));
623
+ $table = $tables[$name];
624
+ $map_ids = array();
625
+
626
+ $columns = implode(', ', Feature::getBulkReadColumns($table));
627
+
628
+ if(!empty($filteringParameters['map_id'])){
629
+ $map_ids[] = $filteringParameters['map_id'];
630
+ }
631
+
632
+ if(!empty($filteringParameters['mashup_ids'])){
633
+ $map_ids = array_merge($map_ids, $filteringParameters['mashup_ids']);
634
+ }
635
+
636
+ if(!empty($filteringParameters['mashupIDs'])){
637
+ $map_ids = array_merge($map_ids, $filteringParameters['mashupIDs']);
638
+ }
639
+
640
+ $queryParams = array();
641
+ $qstr = "SELECT $columns FROM $table";
642
+
643
+ if(!empty($map_ids)){
644
+ $queryParams = array_merge($queryParams, $map_ids);
645
+ $placeholders = implode(',', array_fill(0, count($map_ids), '%d'));
646
+
647
+ $qstr .= " WHERE map_id IN (" . $placeholders . ")";
648
+ $stmt = $wpdb->prepare($qstr, $queryParams);
649
+ } else {
650
+ $stmt = $qstr;
651
+ }
652
+
653
+ foreach($wpdb->get_results($stmt) as $row)
654
+ {
655
+ $instance = new $qualified($row, Crud::BULK_READ);
656
+
657
+ // NB: Not sure why we have to explicitly call jsonSerialize here, but if you don't, inheritence doesn't seem to work properly (eg Crud::jsonSerialize is used but Feature::jsonSerialize is ignored)
658
+ $features[] = $instance->jsonSerialize();
659
+ }
660
+ }
661
+
662
+ $result[$name] = $features;
663
+ }
664
+
665
+ return $result;
666
+ break;
667
+
668
+ case 'POST':
669
+ $data = stripslashes_deep($_POST);
670
+ $id = ( isset($m[3]) ? ltrim($m[3], '/') : ( isset($m[2]) ? ltrim($m[2], '/') : -1 ) );
671
+ if(isset($data['id'])) {
672
+ if($data['id'] != $id)
673
+ trigger_error('Mismatch between REST route ID and request body ID', E_USER_WARNING);
674
+
675
+ unset($data['id']);
676
+ }
677
+
678
+ $instance = new $qualified($id);
679
+ $instance->set($data);
680
+
681
+ return $instance;
682
+
683
+ break;
684
+
685
+ case 'DELETE':
686
+
687
+ $id = ( isset($m[3]) ? ltrim($m[3], '/') : ( isset($m[2]) ? ltrim($m[2], '/') : -1) );
688
+
689
+
690
+
691
+ $instance = new $qualified($id);
692
+ $instance->trash();
693
+
694
+ return array('success' => true);
695
+
696
+ break;
697
+
698
+ default:
699
+ return new \WP_Error('wpgmza_invalid_request_method', 'Invalid request method');
700
+ break;
701
+ }
702
+ }
703
+
704
+ protected function getFilteringParameters($params)
705
+ {
706
+ $filteringParameters = array();
707
+
708
+ if(!empty($params['filter']))
709
+ {
710
+ if(is_object($params['filter']))
711
+ $filteringParameters = (array)$params['filter'];
712
+ else if(is_array($params['filter']))
713
+ $filteringParameters = $params['filter'];
714
+ else if(is_string($params['filter']))
715
+ {
716
+ if(!($filteringParameters = json_decode( stripslashes($params['filter']) )))
717
+ throw new \Exception("Invalid JSON in filtering parameters");
718
+ }
719
+ else
720
+ throw new \Exception("Failed to interpret filtering parameters");
721
+ }
722
+
723
+ return (array)$filteringParameters;
724
+ }
725
+
726
+ protected function checkForDeleteSimulation(){
727
+ if(!empty($_POST) && !empty($_POST['simulateDelete'])){
728
+ $_SERVER['REQUEST_METHOD'] = "DELETE";
729
+ unset($_POST['simulateDelete']);
730
+ }
731
+ }
732
+
733
+ /**
734
+ * Callback for the /markers REST API route.
735
+ * @param \WP_REST_Request The REST request.
736
+ * @return mixed Where an ID is specified on the URL, a single marker is returned. Where no ID is specified, an array of all markers are returned.
737
+ */
738
+ public function markers($request)
739
+ {
740
+ global $wpdb;
741
+ global $wpgmza_tblname;
742
+
743
+ $route = $_SERVER['REQUEST_URI'];
744
+ $params = $this->getRequestParameters();
745
+
746
+ $this->checkForDeleteSimulation();
747
+
748
+ switch($_SERVER['REQUEST_METHOD'])
749
+ {
750
+ case 'GET':
751
+ if(preg_match('#/wpgmza/v1/markers/(\d+)#', $route, $m)) {
752
+
753
+ $marker = Marker::createInstance($m[1], Crud::SINGLE_READ, isset($_GET['raw_data']));
754
+ return $marker;
755
+ }
756
+
757
+ $fields = null;
758
+
759
+
760
+ if(isset($params['fields']) && is_string($params['fields']))
761
+ $fields = explode(',', $params['fields']);
762
+ else if(!empty($params['fields']))
763
+ $fields = $params['fields'];
764
+
765
+
766
+
767
+ if(!empty($fields))
768
+ $fields = $this->sanitizeFieldNames($fields, $wpgmza_tblname);
769
+
770
+ $filteringParameters = $this->getFilteringParameters($params);
771
+
772
+ $markerFilter = MarkerFilter::createInstance($filteringParameters);
773
+
774
+ foreach($filteringParameters as $key => $value)
775
+ $markerFilter->{$key} = $value;
776
+
777
+
778
+ $results = $markerFilter->getFilteredMarkers($fields);
779
+ $arr = array();
780
+
781
+ // We call this here so that caching doesn't try to serialize markers, resulting in bad characters
782
+ // NB: A better approach might be to implement serializable, however I didn't have much luck doing that
783
+ $classImplementsJsonSerializableCache = array();
784
+
785
+ if(!empty($results)){
786
+ foreach($results as $marker){
787
+ if($marker instanceof Marker)
788
+ {
789
+ // Convert the marker to a plain array, so that it can be properly cached by REST API cache
790
+ $json = $marker->jsonSerialize();
791
+
792
+ foreach($json as $key => $value)
793
+ {
794
+ if(!is_object($value))
795
+ continue;
796
+
797
+ if(!isset($classImplementsJsonSerializableCache[$key]))
798
+ {
799
+ $reflection = new \ReflectionClass($value);
800
+ $classImplementsJsonSerializableCache[$key] = $reflection->implementsInterface('JsonSerializable');
801
+ }
802
+
803
+ if(!$classImplementsJsonSerializableCache[$key])
804
+ continue;
805
+
806
+ $json[$key] = $value->jsonSerialize();
807
+ }
808
+
809
+ $arr[] = $json;
810
+ }
811
+ else
812
+ $arr[] = $marker;
813
+ }
814
+ }
815
+
816
+ // TODO: Select all custom field data too, in one query, and add that to the marker data in the following loop. Ideally we could add a bulk get function to the CRUD classes which takes IDs?
817
+ // NB: Such a function has been implemented, just need to hook that up
818
+
819
+ return $arr;
820
+ break;
821
+
822
+ case 'POST':
823
+
824
+ if(preg_match('#/wpgmza/v1/markers/(\d+)#', $route, $m))
825
+ $id = $m[1];
826
+ else
827
+ $id = -1;
828
+
829
+ $marker = Marker::createInstance($id);
830
+
831
+ foreach($_POST as $key => $value){
832
+ if($key == 'id')
833
+ continue;
834
+
835
+ if($key == 'gallery'){
836
+ $gallery = new MarkerGallery($_POST[$key]);
837
+ $marker->gallery = $gallery;
838
+ } else {
839
+ $marker->{$key} = stripslashes($value);
840
+ }
841
+ }
842
+
843
+ if(empty($_POST['gallery']) && !empty($marker->gallery)){
844
+ $marker->gallery = false;
845
+ }
846
+
847
+ $map = Map::createInstance($marker->map_id);
848
+ $map->updateXMLFile();
849
+
850
+ return $marker;
851
+
852
+ break;
853
+
854
+ case 'DELETE':
855
+
856
+ // Workaround for PHP not populating $_REQUEST
857
+ $request = array();
858
+ $body = file_get_contents('php://input');
859
+ parse_str($body, $request);
860
+
861
+ $id = null;
862
+ if(isset($request['id']))
863
+ $id = $request['id'];
864
+ else if(preg_match('/markers\/(\d+)/', $route, $m))
865
+ $id = $m[1];
866
+
867
+ if($id){
868
+ $marker = Marker::createInstance($id);
869
+
870
+ $mapId = $marker->map_id;
871
+
872
+ $marker->trash();
873
+
874
+ $map = Map::createInstance($mapId);
875
+ $map->updateXMLFile();
876
+ } else if(isset($request['ids'])) {
877
+ Marker::bulk_trash($request['ids']);
878
+ } else{
879
+ http_response_code(400);
880
+ return (object)array(
881
+ 'message' => "No ID(s) specified",
882
+ 'success' => false
883
+ );
884
+ }
885
+
886
+ return (object)array(
887
+ 'success' => true
888
+ );
889
+
890
+ break;
891
+
892
+ default:
893
+ return new \WP_Error('wpgmza_invalid_request_method', 'Invalid request method');
894
+ break;
895
+ }
896
+
897
+
898
+ }
899
+
900
+ public function datatables()
901
+ {
902
+ $request = $this->getRequestParameters();
903
+
904
+ // NB: Legacy support
905
+ if(isset($request['wpgmzaDataTableRequestData']))
906
+ $request = $request['wpgmzaDataTableRequestData'];
907
+
908
+
909
+ if(RestAPI::isRequestURIUsingCompressedPathVariable())
910
+ $class = '\\' . $request['phpClass'];
911
+ else
912
+ $class = '\\' . stripslashes( $request['phpClass'] );
913
+
914
+ try{
915
+ $reflection = new \ReflectionClass($class);
916
+ }catch(Exception $e) {
917
+ return new \WP_Error('wpgmza_invalid_datatable_class', 'Invalid class specified', array('status' => 403));
918
+ }
919
+
920
+ if((class_exists('\\WPGMZA\\MarkerListing') && $reflection->isSubclassOf('\\WPGMZA\\MarkerListing'))
921
+ || (class_exists('\\WPGMZA\\MarkerListing\\AdvancedTable') && ($class == '\\WPGMZA\\MarkerListing\\AdvancedTable' || $reflection->isSubclassOf('\\WPGMZA\\MarkerListing\\AdvancedTable')))){
922
+
923
+ $map_id = $request['map_id'];
924
+ $instance = $class::createInstance($map_id);
925
+ } else {
926
+ $instance = $class::createInstance();
927
+ }
928
+
929
+ if(!($instance instanceof DataTable))
930
+ return new \WP_Error('wpgmza_invalid_datatable_class', 'Specified PHP class must extend WPGMZA\\DataTable', array('status' => 403));
931
+
932
+ $result = $instance->data($request);
933
+
934
+ return $result;
935
+ }
936
+
937
+ public function geocodeCache($request)
938
+ {
939
+ $params = $this->getRequestParameters();
940
+ $cache = new NominatimGeocodeCache();
941
+
942
+ $record = $cache->get(addslashes($params['query']));
943
+
944
+ if(!$record)
945
+ $record = array();
946
+
947
+ return $record;
948
+ }
949
+
950
+ public function decompress($request)
951
+ {
952
+ $params = $this->getRequestParameters();
953
+
954
+ return $params;
955
+ }
956
+
957
+ public function onReportRestAPIBlocked()
958
+ {
959
+ $now = new \DateTime();
960
+
961
+ update_option('wpgmza_last_rest_api_blocked', $now->format(\DateTime::ISO8601));
962
+ }
963
+
964
+ public function cleanRequestOutput($requestData){
965
+ if(!empty($requestData) && is_array($requestData)){
966
+ foreach($requestData as $key => $value){
967
+ if(is_string($value)){
968
+ $requestData[$key] = sanitize_text_field($value);
969
+ }
970
+ }
971
+ }
972
+ return $requestData;
973
+ }
974
  }
includes/class.selector-to-xpath.php CHANGED
@@ -1,1107 +1,1107 @@
1
- <?php
2
- /**
3
- * This file contains several classes used by DOMDocument to parse CSS selectors and return their XPath equivalents.
4
- * These modules are mostly for internal use, however are documented here for convenience.
5
- */
6
-
7
- namespace WPGMZA\Selector;
8
-
9
- if(!defined('ABSPATH'))
10
- return;
11
-
12
- /**
13
- * Useful when debugging CSS selector to XPath query conversion
14
- * @param string $str The string to output
15
- */
16
- function trace($str)
17
- {
18
- echo esc_html($str) . "\r\n";
19
- }
20
-
21
- /**
22
- * An exception thrown when parsing a CSS selector fails (ie failed to interpret the selector, before conversion starts)
23
- */
24
- class ParseException extends \Exception
25
- {
26
- /**
27
- * @var The CSS selector that caused this exception
28
- */
29
- public $css;
30
-
31
- /**
32
- * Constructor.
33
- * @param string $message The error message
34
- * @param int $code Unused, the error code
35
- * @param \Exception $previous The previous exception, used for exception chaining
36
- */
37
- public function __construct($message, $code = 0, \Exception $previous = null) {
38
- \Exception::__construct($message, $code, $previous);
39
- }
40
- }
41
-
42
- /**
43
- * An exception thrown when conversion from a CSS selector to an XPath query failed (ie the selector was successfully parsed, but conversion to it's XPath equivalent failed).
44
- */
45
- class ConvertException extends \Exception
46
- {
47
- /**
48
- * Constructor.
49
- * @param string $message The error message
50
- * @param int $code Unused, the error code
51
- * @param \Exception $previous The previous exception, used for exception chaining
52
- */
53
- public function __construct($message, $code = 0, Exception $previous = null) {
54
- \Exception::__construct($message, $code, $previous);
55
- }
56
- }
57
-
58
- /**
59
- * This class represents a CSS selector token
60
- * @method __toString The "friendly" type of this token, tabs and then the raw string.
61
- */
62
- class Token
63
- {
64
- const OPEN_BRACKET = '[';
65
- const CLOSE_BRACKET = ']';
66
- const OPEN_PARENTHES = '(';
67
- const CLOSE_PARENTHES = ')';
68
- const CLASS_SHORTHAND = '.';
69
- const ID_SHORTHAND = '#';
70
- const SINGLE_QUOTE = "'";
71
- const ANY_ELEMENT = '*';
72
- const DOUBLE_QUOTE = '"';
73
- const PSEUDO = ':';
74
- const UNION_OPERATOR = ',';
75
- const DESCENDANT_COMBINATOR = ' ';
76
- const CHILD_COMBINATOR = '>';
77
- const ADJACENT_SIBLING_COMBINATOR = '+';
78
- const GENERAL_SIBLING_COMBINATOR = '~';
79
- const ATTRIBUTE_EQUAL_TO = '=';
80
- const ATTRIBUTE_WHITESPACE_LIST_CONTAINS = '~=';
81
- const ATTRIBUTE_BEGINS_WITH = '^=';
82
- const ATTRIBUTE_ENDS_WITH = '$=';
83
- const ATTRIBUTE_CONTAINS_SUBSTRING = '*=';
84
- const ATTRIBUTE_HYPHEN_LIST_BEGINS_WITH = '|=';
85
-
86
- const IDENTIFIER = -1;
87
- const STRING = -2;
88
- const EXPRESSION = -3;
89
-
90
- public $type = null;
91
- public $string;
92
-
93
- /**
94
- * Constructor.
95
- * @param string $type Any of the constants defined in this class.
96
- * @param string $string Either a string matching the values of the constants defined in this class, or where $type is IDENTIFIER, STRING or EXPRESSION, the string representing that element of the selector
97
- */
98
- public function __construct($type, $string)
99
- {
100
- if(empty($string) && $string !== '0' || $string === '')
101
- throw new \Exception('Token string cannot be empty');
102
-
103
- $this->type = $type;
104
- $this->string = $string;
105
-
106
- //trace("Created token '$string' with type " . $this->getFriendlyType() . "\r\n");
107
- }
108
-
109
- /**
110
- * Retuns true if this token is a CSS combinator (eg > + ~)
111
- * @return bool
112
- */
113
- public function isCombinator()
114
- {
115
- switch($this->type)
116
- {
117
- case Token::DESCENDANT_COMBINATOR:
118
- case Token::CHILD_COMBINATOR:
119
- case Token::ADJACENT_SIBLING_COMBINATOR:
120
- case Token::GENERAL_SIBLING_COMBINATOR:
121
- return true;
122
- }
123
- return false;
124
- }
125
-
126
- /**
127
- * Returns true if this token is a CSS attribute operator (eg ^= *= |=)
128
- * @return bool
129
- */
130
- public function isAttributeOperator()
131
- {
132
- switch($this->type)
133
- {
134
- case Token::ATTRIBUTE_EQUAL_TO:
135
- case Token::ATTRIBUTE_WHITESPACE_LIST_CONTAINS:
136
- case Token::ATTRIBUTE_BEGINS_WITH:
137
- case Token::ATTRIBUTE_ENDS_WITH:
138
- case Token::ATTRIBUTE_CONTAINS_SUBSTRING:
139
- case Token::ATTRIBUTE_HYPHEN_LIST_BEGINS_WITH:
140
- return true;
141
- break;
142
- }
143
- return false;
144
- }
145
-
146
- /**
147
- * Returns the "friendly" type name, eg "IDENTIFIER" for -1, "DOUBLE_QUOTE" for ".
148
- * @return string The constant name based on type value.
149
- */
150
- public function getFriendlyType()
151
- {
152
- $ref = new \ReflectionClass(__CLASS__);
153
- $constants = $ref->getConstants();
154
-
155
- foreach($constants as $type => $string)
156
- {
157
- if($string == $this->type)
158
- {
159
- return $type;
160
- }
161
- }
162
-
163
- return "NULL";
164
- }
165
-
166
- public function __toString()
167
- {
168
- $friendly = $this->getFriendlyType();
169
- $spaces = 36 - strlen($friendly);
170
- return $friendly . str_repeat(" ", $spaces) . $this->string;
171
- }
172
- }
173
-
174
- /**
175
- * This class provides stream functions to navigate an array of tokens
176
- */
177
- class TokenStream
178
- {
179
- protected $tokens;
180
- protected $cursor;
181
-
182
- /**
183
- * Constructor
184
- * @param Token[] An array of tokens
185
- */
186
- public function __construct($arr)
187
- {
188
- $this->tokens = $arr;
189
- $this->cursor = 0;
190
- }
191
-
192
- /**
193
- * Peeks at the next token in the stream, without advancing the cursor
194
- * @param string|null $expectedType The token type to expect.
195
- * @param int $calledByRead Used for internal debug logging.
196
- * @throws ParseException If $expectedType is non-null, and the peeked token is null or not the expected type.
197
- * @return Token|null The peeked token, or null at the end of the stream.
198
- */
199
- public function peek($expectedType=null, $calledByRead=0)
200
- {
201
- //$backtrace = debug_backtrace();
202
- $token = (isset($this->tokens[$this->cursor]) ? $this->tokens[$this->cursor] : null);
203
-
204
- if($expectedType !== null)
205
- {
206
- if($token == null)
207
- throw new ParseException('Unexpected end');
208
- if($token->type != $expectedType)
209
- throw new ParseException('Unexpected ' . $token->getFriendlyType() . ' "' . $token->string . '", expecting "' . $expectedType . '"');
210
- }
211
-
212
- $action = ($calledByRead ? 'Read' : 'Peeked at');
213
- //trace($backtrace[1+$calledByRead]["class"] . '::' . $backtrace[1+$calledByRead]["function"] . "() [" . $backtrace[0+$calledByRead]["line"] . "]\t:- $action token $token");
214
- return $token;
215
- }
216
-
217
- /**
218
- * Reads the next token in the stream. This performs the same actions as peek, but will advance the cursor before returning the token. The cursor may not advance past the token count.
219
- * @param string|null $expectedType The token type to expect.
220
- * @throws ParseException If $expectedType is non-null, and the peeked token is null or not the expected type.
221
- * @return Token|null The peeked token, or null at the end of the stream.
222
- */
223
- public function read($expectedType=null)
224
- {
225
- $token = $this->peek($expectedType, 1);
226
-
227
- if(++$this->cursor >= count($this->tokens))
228
- $this->cursor = count($this->tokens);
229
-
230
- return $token;
231
- }
232
-
233
- /**
234
- * Returns true if the cursor has reached the end of the token stream
235
- * @return bool
236
- */
237
- public function eof()
238
- {
239
- return ($this->cursor >= count($this->tokens));
240
- }
241
- }
242
-
243
- /**
244
- * This class is used to convert CSS strings into an array of CSS tokens
245
- */
246
- class Tokenizer
247
- {
248
- protected $tokens;
249
- protected $prevToken;
250
-
251
- /**
252
- * Pushes a new token to the token array
253
- * @param string $type The token type, @see Token
254
- * @param string $char The character(s) to initialize the new token with
255
- */
256
- protected function pushToken($type, $char)
257
- {
258
- return array_push($this->tokens, new Token($type, $char));
259
- }
260
-
261
- /**
262
- * Either pushes the specified character to the current token if the current token is a string, or initializes and pushes a new token to the token array.
263
- * @param string $char The character(s) to push
264
- */
265
- protected function pushCharToString($char)
266
- {
267
- //trace("Pushing '$char'\r\n");
268
-
269
- if(($curr = $this->getCurrToken()) && $curr->type == Token::STRING)
270
- $curr->string .= $char;
271
- else
272
- $this->pushToken(Token::STRING, $char);
273
- }
274
-
275
- /**
276
- * Either pushes the specified character to the current token if the current token is an identifier, or initializes and pushes a new token to the token array.
277
- * @param string $char The character(s) to push
278
- */
279
- protected function pushCharToIdentifier($char)
280
- {
281
- //trace("Pushing '$char'\r\n");
282
-
283
- if(($curr = $this->getCurrToken()) && $curr->type == Token::IDENTIFIER)
284
- $curr->string .= $char;
285
- else
286
- $this->pushToken(Token::IDENTIFIER, $char);
287
- }
288
-
289
- /**
290
- * Either pushes the specified character to the current token if the current token is an expression, or initializes and pushes a new token to the token array.
291
- * @param string $char The character(s) to push
292
- */
293
- protected function pushCharToExpression($char)
294
- {
295
- //trace("Pushing '$char'\r\n");
296
-
297
- if(($curr = $this->getCurrToken()) && $curr->type == Token::EXPRESSION)
298
- $curr->string .= $char;
299
- else
300
- $this->pushToken(Token::EXPRESSION, $char);
301
- }
302
-
303
- /**
304
- * Pops a token from the end of the token array
305
- * @return Token the popped token
306
- */
307
- protected function popToken()
308
- {
309
- $result = array_pop($this->tokens);
310
- //trace("Popped token " . $result . "\r\n");
311
- return $result;
312
- }
313
-
314
- /**
315
- * Gets the current token (the last token in the token array)
316
- * @return Token|null The current token, or null if no tokens are in the array
317
- */
318
- protected function getCurrToken()
319
- {
320
- if(empty($this->tokens))
321
- return null;
322
- return $this->tokens[ count($this->tokens) - 1 ];
323
- }
324
-
325
- /**
326
- * Attempts to tokenize the specified string
327
- * @param string $str The input string
328
- * @throws ParseException When parsing the string fails due to invalid CSS
329
- * @return Token[] An array of tokens parsed from the string
330
- */
331
- public function tokenize($str)
332
- {
333
- // Tokenize
334
- $str = preg_replace('/\s+/', ' ', trim($str));
335
- $length = strlen($str);
336
-
337
- $cursor = 0;
338
- $flags = (object)array(
339
- 'brackets' => 0,
340
- 'parentheses' => array(),
341
- 'string' => false,
342
- 'escaped' => false
343
- );
344
-
345
- $this->tokens = array();
346
-
347
- for($cursor = 0; $cursor < $length; $cursor++)
348
- {
349
- $curr = $this->getCurrToken();
350
- $char = substr($str, $cursor, 1);
351
- $next_two_chars = substr($str, $cursor, 2);
352
-
353
- //trace(preg_replace('/\r?\n/', ' ', $str) . "\r\n" . str_repeat(' ', $cursor) . "^ $cursor");
354
- //trace("Current token: " . $curr);
355
-
356
- if(!$flags->escaped)
357
- {
358
- switch($next_two_chars)
359
- {
360
- case Token::ATTRIBUTE_WHITESPACE_LIST_CONTAINS:
361
- case Token::ATTRIBUTE_BEGINS_WITH:
362
- case Token::ATTRIBUTE_ENDS_WITH:
363
- case Token::ATTRIBUTE_CONTAINS_SUBSTRING:
364
- case Token::ATTRIBUTE_HYPHEN_LIST_BEGINS_WITH:
365
- $this->pushToken($next_two_chars, $next_two_chars);
366
- $cursor++;
367
- continue 2;
368
- }
369
- }
370
-
371
- if($char == "\\")
372
- {
373
- if($flags->escaped)
374
- $this->pushCharToString($char);
375
-
376
- $flags->escaped = !$flags->escaped;
377
- //trace($flags->escaped ? "Escaped" : "Unescaped");
378
- }
379
- else if($flags->string)
380
- {
381
- //trace("Reading {$flags->string} quoted string");
382
- switch($char)
383
- {
384
- case Token::SINGLE_QUOTE:
385
- case Token::DOUBLE_QUOTE:
386
- if($flags->escaped)
387
- {
388
- $this->pushCharToString($char);
389
- break;
390
- }
391
-
392
- $double = ($char == '"');
393
-
394
- if(($double && $flags->string == 'double') || (!$double && $flags->string == 'single'))
395
- {
396
- $flags->string = false;
397
- $this->pushToken(
398
- $double ? Token::DOUBLE_QUOTE : Token::SINGLE_QUOTE,
399
- $char
400
- );
401
- //trace("Exited {$flags->string} quoted string");
402
- }
403
- else
404
- $this->pushCharToString($char);
405
- break;
406
-
407
- default:
408
- $this->pushCharToString($char);
409
- break;
410
- }
411
-
412
- if($flags->escaped)
413
- {
414
- $flags->escaped = false;
415
- //trace("Unescaped at end of reading string");
416
- }
417
- }
418
- else if($flags->escaped)
419
- {
420
- $this->pushCharToIdentifier($char);
421
- $flags->escaped = false;
422
- //trace("Unescaped in else-if clause");
423
- }
424
- else
425
- {
426
- switch($char)
427
- {
428
- case Token::SINGLE_QUOTE:
429
- case Token::DOUBLE_QUOTE:
430
- if($flags->escaped)
431
- {
432
- $this->pushCharToIdentifier($char);
433
- break;
434
- }
435
-
436
- $double = ($char == '"');
437
-
438
- $flags->string = ($double ? 'double' : 'single');
439
- $this->pushToken(
440
- $double ? Token::DOUBLE_QUOTE : Token::SINGLE_QUOTE,
441
- $char
442
- );
443
-
444
- //trace("Entered {$flags->string} quoted string");
445
- break;
446
-
447
- case Token::OPEN_BRACKET:
448
- $var = ($char == Token::OPEN_BRACKET ? 'brackets' : 'parentheses');
449
-
450
- $flags->brackets++;
451
-
452
- if($flags->brackets > 1)
453
- throw new ParseException('Unexpected ' . $char);
454
-
455
- $this->pushToken($char, $char);
456
- //trace("Entered brackets");
457
-
458
- break;
459
-
460
- case Token::CLOSE_BRACKET:
461
- $flags->brackets--;
462
-
463
- if($flags->brackets < 0)
464
- throw new ParseException('Unexpected ' . $char);
465
-
466
- $this->pushToken($char, $char);
467
- //trace("Exited brackets");
468
-
469
- break;
470
-
471
- case Token::OPEN_PARENTHES:
472
- array_push($flags->parentheses, $curr->string);
473
- $this->pushToken($char, $char);
474
- //trace("Entered brackets");
475
- break;
476
-
477
- case Token::CLOSE_PARENTHES:
478
- array_pop($flags->parentheses);
479
- $this->pushToken($char, $char);
480
- //trace("Exited brackets");
481
- break;
482
-
483
- case Token::UNION_OPERATOR:
484
- case Token::CLASS_SHORTHAND:
485
- case Token::ID_SHORTHAND:
486
- case Token::ANY_ELEMENT:
487
- case Token::PSEUDO:
488
- case Token::UNION_OPERATOR:
489
- case Token::ATTRIBUTE_EQUAL_TO:
490
- if($flags->escaped)
491
- break;
492
-
493
- $this->pushToken($char, $char);
494
-
495
- break;
496
-
497
- case Token::ADJACENT_SIBLING_COMBINATOR:
498
- if(count($flags->parentheses) > 0)
499
- {
500
- $this->pushCharToExpression($char);
501
- break;
502
- }
503
- case Token::CHILD_COMBINATOR:
504
- case Token::GENERAL_SIBLING_COMBINATOR:
505
- $curr = $this->getCurrToken();
506
- if($curr && $curr->type == Token::DESCENDANT_COMBINATOR)
507
- $this->popToken();
508
-
509
- $this->pushToken($char, $char);
510
-
511
- break;
512
-
513
- case " ":
514
- case "\r":
515
- case "\n":
516
- case "\t":
517
- $curr = $this->getCurrToken();
518
-
519
- if($flags->brackets > 0 || count($flags->parentheses) > 0)
520
- {
521
- break;
522
- }
523
- if($curr)
524
- {
525
- if($curr->type == Token::UNION_OPERATOR)
526
- break;
527
- if($curr->isCombinator())
528
- break;
529
- }
530
- else
531
- break;
532
-
533
- $this->pushToken(Token::DESCENDANT_COMBINATOR, $char);
534
-
535
- break;
536
-
537
- default:
538
- if(count($flags->parentheses) > 0 && !preg_match('/not/i', $flags->parentheses[count($flags->parentheses) - 1]))
539
- $this->pushCharToExpression($char);
540
- else
541
- $this->pushCharToIdentifier($char);
542
- break;
543
- }
544
- }
545
-
546
- //trace("");
547
- }
548
-
549
- return $this->tokens;
550
- }
551
- }
552
-
553
- /**
554
- * This class represents a CSS pseudo selector, for example, :nth-child, :empty, :not
555
- */
556
- class PseudoSelector
557
- {
558
- public $name;
559
- public $expression;
560
- public $selector;
561
-
562
- /**
563
- * Parses this selector from the given stream, on the supplied selector
564
- * @param TokenStream $stream The token stream to read from
565
- * @param Selector $selector The CSS selector this pseudo-selector is part of
566
- * @throws ParseException Pseudo selector not supported server side
567
- * @throws ParseException Pseudo selector not yet implemented
568
- * @throws ParseException Unknown pseudo selector
569
- * @throws ParseException :not pseudo selector cannot be nested (as per the CSS specs)
570
- * @throws ParseException Invalid CSS in the selector
571
- * @return void
572
- */
573
- public function parse($stream, $selector)
574
- {
575
- $first = $stream->read(Token::PSEUDO);
576
- $token = $stream->read(Token::IDENTIFIER);
577
-
578
- $this->name = strtolower($token->string);
579
- switch($this->name)
580
- {
581
- case 'nth-child':
582
- case 'nth-last-child':
583
- case 'nth-of-type':
584
- case 'nth-last-of-type':
585
- case 'not':
586
- break;
587
-
588
- case 'first-child':
589
- case 'last-child':
590
- case 'first-of-type':
591
- case 'last-of-type':
592
- case 'only-child':
593
- case 'only-of-type':
594
- case 'empty':
595
- case 'enabled':
596
- case 'disabled':
597
- case 'checked':
598
- return;
599
- break;
600
-
601
- case 'link':
602
- case 'visited':
603
- case 'active':
604
- case 'hover':
605
- case 'focus':
606
- case 'target':
607
- throw new ParseException('Pseudo selector not supported server side');
608
- break;
609
-
610
- case 'root':
611
- // See https://en.wikibooks.org/wiki/XPath/CSS_Equivalents for root. Will need to pop descendant:: off stack
612
-
613
- case 'lang':
614
- throw new ParseException('Pseudo selector not yet implemented');
615
- break;
616
-
617
- default:
618
- throw new ParseException('Unknown pseudo selector');
619
- break;
620
- }
621
-
622
- $stream->read(Token::OPEN_PARENTHES);
623
- if($this->name == 'not')
624
- {
625
- if($selector->parent)
626
- {
627
- foreach($selector->parent->selector->pseudos as $parent_pseudo)
628
- {
629
- if($parent_pseudo->name == 'not')
630
- throw new ParseException(':not pseudo selector cannot be nested');
631
- }
632
- }
633
-
634
- $this->selector = new Selector($stream);
635
- $this->selector->parent = $this;
636
- $this->selector->parse($stream, $this);
637
- }
638
- else
639
- $this->expression = $stream->read(Token::EXPRESSION);
640
- $stream->read(Token::CLOSE_PARENTHES);
641
- }
642
- }
643
-
644
- /**
645
- * A CSS attribute selector, such as [data-example], [data-example="value"] or [data-example$="ends-with"]
646
- */
647
- class AttributeSelector
648
- {
649
- public $name;
650
- public $operator;
651
- public $value;
652
-
653
- /**
654
- * Parses the attribute selector from the supplied stream. Please note these classes expect attribute selectors to be enclosed in quotes.
655
- * @param TokenStream $stream The token stream to read from
656
- * @throws ParseException Unexpected end in attribute
657
- * @throws ParseException Expected either close bracket or attribute operator
658
- * @throws ParseException Unexpected end in attribute
659
- * @throws ParseException Expected quote to open string after attribute operator
660
- * @throws ParseException Unexpected end in attribute
661
- * @throws ParseException Expected quote to terminate string after attribute operator
662
- * @throws ParseException Invalid CSS eg unexpected tokens
663
- */
664
- public function parse($stream)
665
- {
666
- // Expect [ first
667
- $stream->read(Token::OPEN_BRACKET);
668
-
669
- // Read name
670
- $token = $stream->read(Token::IDENTIFIER);
671
- $this->name = $token->string;
672
-
673
- // Read operator
674
- $token = $stream->read();
675
- if(!$token)
676
- throw new ParseException('Unexpected end in attribute');
677
- if($token->type == Token::CLOSE_BRACKET)
678
- return; // has attribute
679
- if(!$token->isAttributeOperator())
680
- throw new ParseException('Expected either close bracket or attribute operator');
681
- $this->operator = $token->string;
682
-
683
- // Read string value
684
- $token = $stream->read();
685
- if(!$token)
686
- throw new ParseException('Unexpected end in attribute');
687
- if($token->type != Token::SINGLE_QUOTE && $token->type != Token::DOUBLE_QUOTE)
688
- throw new ParseException('Expected quote to open string after attribute operator');
689
- $openQuoteType = $token->type;
690
-
691
- $after = $stream->peek();
692
- if($after->type == $openQuoteType)
693
- {
694
- // Empty string
695
- $this->value = '';
696
- }
697
- else
698
- {
699
- // Read value
700
- $token = $stream->read(Token::STRING);
701
- $this->value = $token->string;
702
- }
703
-
704
- $token = $stream->read();
705
- if(!$token)
706
- throw new ParseException('Unexpected end in attribute');
707
- if($token->type != Token::SINGLE_QUOTE && $token->type != Token::DOUBLE_QUOTE)
708
- throw new ParseException('Expected quote to terminate string after attribute operator');
709
-
710
- // Expect ]
711
- $stream->read(Token::CLOSE_BRACKET);
712
- }
713
- }
714
-
715
- /**
716
- * Represents a single selector, either standalone or as part of a compound selector
717
- */
718
- class Selector
719
- {
720
- public $element = '*';
721
- public $id;
722
- public $classes;
723
- public $attributes;
724
- public $pseudos;
725
-
726
- public $parent;
727
-
728
- /**
729
- * Parses this selector from the given stream.
730
- * @param TokenStream $stream The token stream to read from.
731
- * @param PseudoSelector $not The :not pseudo selector that contains this selector.
732
- * @throws ParseException Unexpected end in attribute
733
- * @throws ParseException Expected either close bracket or attribute operator
734
- * @throws ParseException Unexpected end in attribute
735
- * @throws ParseException Expected quote to open string after attribute operator
736
- * @throws ParseException Unexpected end in attribute
737
- * @throws ParseException Expected quote to terminate string after attribute operator
738
- * @throws ParseException Invalid CSS eg unexpected tokens
739
- */
740
- public function parse($stream, $not=null)
741
- {
742
- $first = $stream->peek();
743
-
744
- switch($first->type)
745
- {
746
- case Token::ANY_ELEMENT:
747
- case Token::IDENTIFIER:
748
- $this->element = $stream->read()->string;
749
- break;
750
-
751
- case Token::OPEN_BRACKET:
752
- case Token::PSEUDO:
753
- case Token::ID_SHORTHAND:
754
- case Token::CLASS_SHORTHAND:
755
- break;
756
-
757
- default:
758
- throw new ParseException("Unexpected token '{$token->string}'");
759
- break;
760
- }
761
-
762
- while($token = $stream->peek())
763
- {
764
- if($token->isCombinator() || $token->type == Token::UNION_OPERATOR)
765
- return;
766
-
767
- switch($token->type)
768
- {
769
- case Token::ID_SHORTHAND:
770
- if($this->id != null)
771
- throw new ParseExcepton('Selector can only have one ID');
772
- $stream->read(Token::ID_SHORTHAND);
773
- $this->id = $stream->read(Token::IDENTIFIER)->string;
774
- //trace("Read ID as {$this->id}");
775
- continue 2;
776
- break;
777
-
778
- case Token::CLASS_SHORTHAND:
779
- if(!$this->classes)
780
- $this->classes = array();
781
- $stream->read(Token::CLASS_SHORTHAND);
782
- array_push($this->classes, $stream->read(Token::IDENTIFIER)->string);
783
- continue 2;
784
- break;
785
-
786
- case Token::OPEN_BRACKET:
787
- if(!$this->attributes)
788
- $this->attributes = array();
789
-
790
- $attributeSelector = new AttributeSelector();
791
- array_push($this->attributes, $attributeSelector);
792
- $attributeSelector->parse($stream);
793
- continue 2;
794
- break;
795
-
796
- case Token::PSEUDO:
797
- if(!$this->pseudos)
798
- $this->pseudos = array();
799
-
800
- $pseudoSelector = new PseudoSelector();
801
- array_push($this->pseudos, $pseudoSelector);
802
- $pseudoSelector->parse($stream, $this);
803
- continue 2;
804
- break;
805
-
806
- case Token::CLOSE_PARENTHES:
807
- if($not != null)
808
- return;
809
-
810
- default:
811
- throw new ParseException("Unexpected token '{$token->string}'");
812
- break;
813
- }
814
-
815
- $stream->read();
816
- }
817
-
818
-
819
- }
820
- }
821
-
822
- /**
823
- * Used to parse a selector or compound selectors
824
- */
825
- class Parser
826
- {
827
- protected $tokenizer;
828
- protected $elements;
829
-
830
- /**
831
- * Constructor.
832
- */
833
- public function __construct()
834
- {
835
- $this->tokenizer = new Tokenizer();
836
- }
837
-
838
- /**
839
- * Parses the selector(s) supplied
840
- * @param string $selector The string of selector(s) to parse
841
- * @return Selector[] An array of selectors parsed from the string
842
- */
843
- public function parse($selector)
844
- {
845
- $tokens = $this->tokenizer->tokenize($selector);
846
- $stream = new TokenStream($tokens);
847
- $this->elements = array();
848
-
849
- while(!$stream->eof())
850
- {
851
- $token = $stream->peek();
852
- if($token->isCombinator() || $token->type == Token::UNION_OPERATOR)
853
- {
854
- if(empty($this->elements))
855
- throw new ParseException('Expected selector before combinator or union operator');
856
- array_push($this->elements, $stream->read());
857
- }
858
-
859
- $selector = new Selector();
860
- $selector->parse($stream);
861
- array_push($this->elements, $selector);
862
-
863
- //trace(print_r($selector, true));
864
- }
865
-
866
- return $this->elements;
867
- }
868
-
869
-
870
- }
871
-
872
- /**
873
- * Used to convert CSS selectors to XPath queries
874
- */
875
- class XPathConverter
876
- {
877
- protected $parser;
878
- protected $xpath;
879
-
880
- /**
881
- * Constructor.
882
- */
883
- public function __construct()
884
- {
885
- $this->parser = new Parser();
886
- }
887
-
888
- /**
889
- * Converts a CSS attribute selector to its XPath equivalent and pushes the XPath query string to memory
890
- * @param AttributeSelector $attr The CSS attribute selector
891
- * @throws ConvertException Unrecognised attribute operator
892
- * @return void
893
- */
894
- protected function convertAttribute($attr)
895
- {
896
- $name = $attr->name;
897
- $value = addslashes($attr->value);
898
-
899
- switch($attr->operator)
900
- {
901
- case null:
902
- $inner = "@{$name}";
903
- break;
904
-
905
- case Token::ATTRIBUTE_EQUAL_TO:
906
- $inner = "@$name=\"$value\"";
907
- break;
908
-
909
- case Token::ATTRIBUTE_WHITESPACE_LIST_CONTAINS:
910
- $inner = "conatins(concat(\" \", normalize-space(@$name), \" \"), \" $value \")";
911
- break;
912
-
913
- case Token::ATTRIBUTE_BEGINS_WITH:
914
- $inner = "starts-with(@$name, \"$value\")";
915
- break;
916
-
917
- case Token::ATTRIBUTE_ENDS_WITH:
918
- $inner = "substring(@$name, string-length(@$name) - string-length(\"$value\") + 1) = \"$value\"";
919
- break;
920
-
921
- case Token::ATTRIBUTE_CONTAINS_SUBSTRING:
922
- $inner = "contains(@$name, \"$value\")";
923
- break;
924
-
925
- case Token::ATTRIBUTE_HYPHEN_LIST_BEGINS_WITH:
926
- $inner = "@$name=\"@$value\" | starts-with(@$name, \"@$value-\")";
927
- break;
928
-
929
- default:
930
- throw new ConvertException("Don't know how to convert operator {$attr->operator}");
931
- break;
932
- }
933
- array_push($this->xpath, "[$inner]");
934
- }
935
-
936
- /**
937
- * Converts a CSS pseudo selector to its XPath equivalent and pushes the XPath query string to memory
938
- * @param AttributeSelector $pseudo The CSS pseudo selector
939
- * @throws ConvertException Don't know how to convert selector (may not be implemented)
940
- * @return void
941
- */
942
- protected function convertPseudo($pseudo)
943
- {
944
- $name = $pseudo->name;
945
-
946
- // TODO: The "of type" selectors should change the parent selector element to *, and should use that type in their xpath
947
- // TODO: Test with a live domdocument in here (or smartdocument even)
948
-
949
- switch($name)
950
- {
951
- case 'nth-child':
952
- case 'nth-last-child':
953
- case 'nth-of-type':
954
- case 'nth-last-of-type':
955
- // TODO: Support formulas / expressions
956
- throw new ConvertException('Not yet implemented');
957
- break;
958
-
959
- case 'first-child':
960
- case 'first-of-type':
961
- $inner = '1';
962
- break;
963
-
964
- case 'last-child':
965
- case 'last-of-type':
966
- $inner = 'last()';
967
- break;
968
-
969
- case 'only-child':
970
- case 'only-of-type':
971
- $inner = 'count(*)=1'; // TODO: might need to swap * with node name
972
- break;
973
-
974
- case 'empty':
975
- $inner = 'count(./*)=0 and string-length(text())=0';
976
- break;
977
-
978
- case 'enabled':
979
- $inner = "not(@disabled)";
980
- break;
981
-
982
- case 'disabled':
983
- case 'checked':
984
- $inner = "@$name";
985
- break;
986
-
987
- case 'not':
988
- throw new ConvertException('Not yet implemented');
989
- break;
990
-
991
- default:
992
- throw new ConvertException("Don't know how to convert pseudo selector {$pseudo->name}");
993
- break;
994
- }
995
-
996
- array_push($this->xpath, "[$inner]");
997
- }
998
-
999
- /**
1000
- * Converts a CSS selector to its XPath equivalent and pushes the XPath query string to memory
1001
- * @param Selector $selector The CSS selector to convert.
1002
- * @return void
1003
- */
1004
- protected function convertSelector($selector)
1005
- {
1006
- //trace("Converting selector " . print_r($selector, true));
1007
-
1008
- $prev = null;
1009
- if(!empty($this->xpath))
1010
- $prev = &$this->xpath[ count($this->xpath) - 1 ];
1011
-
1012
- if($prev == 'following-sibling::*[1]')
1013
- $prev = preg_replace('/\*/', $selector->element, $prev);
1014
- else
1015
- array_push($this->xpath, $selector->element);
1016
-
1017
- if($selector->id != null)
1018
- array_push($this->xpath, '[@id="' . $selector->id . '"]');
1019
-
1020
- if($selector->classes)
1021
- foreach($selector->classes as $class)
1022
- {
1023
- array_push($this->xpath,
1024
- '[contains(concat(" ", normalize-space(@class), " "), " ' . $class . ' ")]'
1025
- );
1026
- }
1027
-
1028
- if($selector->attributes)
1029
- foreach($selector->attributes as $attr)
1030
- $this->convertAttribute($attr);
1031
-
1032
- if($selector->pseudos)
1033
- foreach($selector->pseudos as $pseudo)
1034
- $this->convertPseudo($pseudo);
1035
- }
1036
-
1037
- /**
1038
- * Converts an element (eg a single, non-compound CSS selector) to it's XPath equivalent
1039
- * @param Selector $element The selector to convert
1040
- * @throws ConvertException Unexpected element
1041
- */
1042
- protected function convertElement($element)
1043
- {
1044
- //trace("Converting element " . print_r($element, true));
1045
-
1046
- $prev = null;
1047
- if(!empty($this->xpath))
1048
- $prev = $this->xpath[ count($this->xpath) - 1 ];
1049
-
1050
- if($element instanceof Token)
1051
- {
1052
- if($prev != "\r\n|\r\n" && $element->type != Token::UNION_OPERATOR)
1053
- array_push($this->xpath, '/');
1054
-
1055
- switch($element->type)
1056
- {
1057
- case Token::UNION_OPERATOR:
1058
- array_push($this->xpath, "\r\n|\r\n");
1059
-
1060
- case Token::DESCENDANT_COMBINATOR:
1061
- array_push($this->xpath, 'descendant::');
1062
- return;
1063
-
1064
- case Token::CHILD_COMBINATOR:
1065
- array_push($this->xpath, 'child::');
1066
- return;
1067
-
1068
- case Token::GENERAL_SIBLING_COMBINATOR:
1069
- array_push($this->xpath, 'following-sibling::');
1070
- return;
1071
-
1072
- case Token::ADJACENT_SIBLING_COMBINATOR:
1073
- array_push($this->xpath, 'following-sibling::*[1]');
1074
- return;
1075
-
1076
- default:
1077
- throw new ConvertException('Unexpected token');
1078
- break;
1079
- }
1080
- }
1081
- else if($element instanceof Selector)
1082
- $this->convertSelector($element);
1083
- else
1084
- throw new ConvertException('Unexpected element');
1085
- }
1086
-
1087
- /**
1088
- * Converts the given CSS selector string into it's XPath equivalent
1089
- * @param string $str The input CSS selector to convert
1090
- * @return string The XPath equivalent of the supplied selector
1091
- */
1092
- public function convert($str)
1093
- {
1094
- //trace("=== Parsing $str ===\r\n");
1095
-
1096
- $this->xpath = array('descendant::');
1097
- $elements = $this->parser->parse($str);
1098
-
1099
- //trace("=== Converting $str ===\r\n");
1100
- foreach($elements as $el)
1101
- $this->convertElement($el);
1102
-
1103
- return implode('', $this->xpath);
1104
- }
1105
- }
1106
-
1107
  ?>
1
+ <?php
2
+ /**
3
+ * This file contains several classes used by DOMDocument to parse CSS selectors and return their XPath equivalents.
4
+ * These modules are mostly for internal use, however are documented here for convenience.
5
+ */
6
+
7
+ namespace WPGMZA\Selector;
8
+
9
+ if(!defined('ABSPATH'))
10
+ return;
11
+
12
+ /**
13
+ * Useful when debugging CSS selector to XPath query conversion
14
+ * @param string $str The string to output
15
+ */
16
+ function trace($str)
17
+ {
18
+ echo esc_html($str) . "\r\n";
19
+ }
20
+
21
+ /**
22
+ * An exception thrown when parsing a CSS selector fails (ie failed to interpret the selector, before conversion starts)
23
+ */
24
+ class ParseException extends \Exception
25
+ {
26
+ /**
27
+ * @var The CSS selector that caused this exception
28
+ */
29
+ public $css;
30
+
31
+ /**
32
+ * Constructor.
33
+ * @param string $message The error message
34
+ * @param int $code Unused, the error code
35
+ * @param \Exception $previous The previous exception, used for exception chaining
36
+ */
37
+ public function __construct($message, $code = 0, \Exception $previous = null) {
38
+ \Exception::__construct($message, $code, $previous);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * An exception thrown when conversion from a CSS selector to an XPath query failed (ie the selector was successfully parsed, but conversion to it's XPath equivalent failed).
44
+ */
45
+ class ConvertException extends \Exception
46
+ {
47
+ /**
48
+ * Constructor.
49
+ * @param string $message The error message
50
+ * @param int $code Unused, the error code
51
+ * @param \Exception $previous The previous exception, used for exception chaining
52
+ */
53
+ public function __construct($message, $code = 0, Exception $previous = null) {
54
+ \Exception::__construct($message, $code, $previous);
55
+ }
56
+ }
57
+
58
+ /**
59
+ * This class represents a CSS selector token
60
+ * @method __toString The "friendly" type of this token, tabs and then the raw string.
61
+ */
62
+ class Token
63
+ {
64
+ const OPEN_BRACKET = '[';
65
+ const CLOSE_BRACKET = ']';
66
+ const OPEN_PARENTHES = '(';
67
+ const CLOSE_PARENTHES = ')';
68
+ const CLASS_SHORTHAND = '.';
69
+ const ID_SHORTHAND = '#';
70
+ const SINGLE_QUOTE = "'";
71
+ const ANY_ELEMENT = '*';
72
+ const DOUBLE_QUOTE = '"';
73
+ const PSEUDO = ':';
74
+ const UNION_OPERATOR = ',';
75
+ const DESCENDANT_COMBINATOR = ' ';
76
+ const CHILD_COMBINATOR = '>';
77
+ const ADJACENT_SIBLING_COMBINATOR = '+';
78
+ const GENERAL_SIBLING_COMBINATOR = '~';
79
+ const ATTRIBUTE_EQUAL_TO = '=';
80
+ const ATTRIBUTE_WHITESPACE_LIST_CONTAINS = '~=';
81
+ const ATTRIBUTE_BEGINS_WITH = '^=';
82
+ const ATTRIBUTE_ENDS_WITH = '$=';
83
+ const ATTRIBUTE_CONTAINS_SUBSTRING = '*=';
84
+ const ATTRIBUTE_HYPHEN_LIST_BEGINS_WITH = '|=';
85
+
86
+ const IDENTIFIER = -1;
87
+ const STRING = -2;
88
+ const EXPRESSION = -3;
89
+
90
+ public $type = null;
91
+ public $string;
92
+
93
+ /**
94
+ * Constructor.
95
+ * @param string $type Any of the constants defined in this class.
96
+ * @param string $string Either a string matching the values of the constants defined in this class, or where $type is IDENTIFIER, STRING or EXPRESSION, the string representing that element of the selector
97
+ */
98
+ public function __construct($type, $string)
99
+ {
100
+ if(empty($string) && $string !== '0' || $string === '')
101
+ throw new \Exception('Token string cannot be empty');
102
+
103
+ $this->type = $type;
104
+ $this->string = $string;
105
+
106
+ //trace("Created token '$string' with type " . $this->getFriendlyType() . "\r\n");
107
+ }
108
+
109
+ /**
110
+ * Retuns true if this token is a CSS combinator (eg > + ~)
111
+ * @return bool
112
+ */
113
+ public function isCombinator()
114
+ {
115
+ switch($this->type)
116
+ {
117
+ case Token::DESCENDANT_COMBINATOR:
118
+ case Token::CHILD_COMBINATOR:
119
+ case Token::ADJACENT_SIBLING_COMBINATOR:
120
+ case Token::GENERAL_SIBLING_COMBINATOR:
121
+ return true;
122
+ }
123
+ return false;
124
+ }
125
+
126
+ /**
127
+ * Returns true if this token is a CSS attribute operator (eg ^= *= |=)
128
+ * @return bool
129
+ */
130
+ public function isAttributeOperator()
131
+ {
132
+ switch($this->type)
133
+ {
134
+ case Token::ATTRIBUTE_EQUAL_TO:
135
+ case Token::ATTRIBUTE_WHITESPACE_LIST_CONTAINS:
136
+ case Token::ATTRIBUTE_BEGINS_WITH:
137
+ case Token::ATTRIBUTE_ENDS_WITH:
138
+ case Token::ATTRIBUTE_CONTAINS_SUBSTRING:
139
+ case Token::ATTRIBUTE_HYPHEN_LIST_BEGINS_WITH:
140
+ return true;
141
+ break;
142
+ }
143
+ return false;
144
+ }
145
+
146
+ /**
147
+ * Returns the "friendly" type name, eg "IDENTIFIER" for -1, "DOUBLE_QUOTE" for ".
148
+ * @return string The constant name based on type value.
149
+ */
150
+ public function getFriendlyType()
151
+ {
152
+ $ref = new \ReflectionClass(__CLASS__);
153
+ $constants = $ref->getConstants();
154
+
155
+ foreach($constants as $type => $string)
156
+ {
157
+ if($string == $this->type)
158
+ {
159
+ return $type;
160
+ }
161
+ }
162
+
163
+ return "NULL";
164
+ }
165
+
166
+ public function __toString()
167
+ {
168
+ $friendly = $this->getFriendlyType();
169
+ $spaces = 36 - strlen($friendly);
170
+ return $friendly . str_repeat(" ", $spaces) . $this->string;
171
+ }
172
+ }
173
+
174
+ /**
175
+ * This class provides stream functions to navigate an array of tokens
176
+ */
177
+ class TokenStream
178
+ {
179
+ protected $tokens;
180
+ protected $cursor;
181
+
182
+ /**
183
+ * Constructor
184
+ * @param Token[] An array of tokens
185
+ */
186
+ public function __construct($arr)
187
+ {
188
+ $this->tokens = $arr;
189
+ $this->cursor = 0;
190
+ }
191
+
192
+ /**
193
+ * Peeks at the next token in the stream, without advancing the cursor
194
+ * @param string|null $expectedType The token type to expect.
195
+ * @param int $calledByRead Used for internal debug logging.
196
+ * @throws ParseException If $expectedType is non-null, and the peeked token is null or not the expected type.
197
+ * @return Token|null The peeked token, or null at the end of the stream.
198
+ */
199
+ public function peek($expectedType=null, $calledByRead=0)
200
+ {
201
+ //$backtrace = debug_backtrace();
202
+ $token = (isset($this->tokens[$this->cursor]) ? $this->tokens[$this->cursor] : null);
203
+
204
+ if($expectedType !== null)
205
+ {
206
+ if($token == null)
207
+ throw new ParseException('Unexpected end');
208
+ if($token->type != $expectedType)
209
+ throw new ParseException('Unexpected ' . $token->getFriendlyType() . ' "' . $token->string . '", expecting "' . $expectedType . '"');
210
+ }
211
+
212
+ $action = ($calledByRead ? 'Read' : 'Peeked at');
213
+ //trace($backtrace[1+$calledByRead]["class"] . '::' . $backtrace[1+$calledByRead]["function"] . "() [" . $backtrace[0+$calledByRead]["line"] . "]\t:- $action token $token");
214
+ return $token;
215
+ }
216
+
217
+ /**
218
+ * Reads the next token in the stream. This performs the same actions as peek, but will advance the cursor before returning the token. The cursor may not advance past the token count.
219
+ * @param string|null $expectedType The token type to expect.
220
+ * @throws ParseException If $expectedType is non-null, and the peeked token is null or not the expected type.
221
+ * @return Token|null The peeked token, or null at the end of the stream.
222
+ */
223
+ public function read($expectedType=null)
224
+ {
225
+ $token = $this->peek($expectedType, 1);
226
+
227
+ if(++$this->cursor >= count($this->tokens))
228
+ $this->cursor = count($this->tokens);
229
+
230
+ return $token;
231
+ }
232
+
233
+ /**
234
+ * Returns true if the cursor has reached the end of the token stream
235
+ * @return bool
236
+ */
237
+ public function eof()
238
+ {
239
+ return ($this->cursor >= count($this->tokens));
240
+ }
241
+ }
242
+
243
+ /**
244
+ * This class is used to convert CSS strings into an array of CSS tokens
245
+ */
246
+ class Tokenizer
247
+ {
248
+ protected $tokens;
249
+ protected $prevToken;
250
+
251
+ /**
252
+ * Pushes a new token to the token array
253
+ * @param string $type The token type, @see Token
254
+ * @param string $char The character(s) to initialize the new token with
255
+ */
256
+ protected function pushToken($type, $char)
257
+ {
258
+ return array_push($this->tokens, new Token($type, $char));
259
+ }
260
+
261
+ /**
262
+ * Either pushes the specified character to the current token if the current token is a string, or initializes and pushes a new token to the token array.
263
+ * @param string $char The character(s) to push
264
+ */
265
+ protected function pushCharToString($char)
266
+ {
267
+ //trace("Pushing '$char'\r\n");
268
+
269
+ if(($curr = $this->getCurrToken()) && $curr->type == Token::STRING)
270
+ $curr->string .= $char;
271
+ else
272
+ $this->pushToken(Token::STRING, $char);
273
+ }
274
+
275
+ /**
276
+ * Either pushes the specified character to the current token if the current token is an identifier, or initializes and pushes a new token to the token array.
277
+ * @param string $char The character(s) to push
278
+ */
279
+ protected function pushCharToIdentifier($char)
280
+ {
281
+ //trace("Pushing '$char'\r\n");
282
+
283
+ if(($curr = $this->getCurrToken()) && $curr->type == Token::IDENTIFIER)
284
+ $curr->string .= $char;
285
+ else
286
+ $this->pushToken(Token::IDENTIFIER, $char);
287
+ }
288
+
289
+ /**
290
+ * Either pushes the specified character to the current token if the current token is an expression, or initializes and pushes a new token to the token array.
291
+ * @param string $char The character(s) to push
292
+ */
293
+ protected function pushCharToExpression($char)
294
+ {
295
+ //trace("Pushing '$char'\r\n");
296
+
297
+ if(($curr = $this->getCurrToken()) && $curr->type == Token::EXPRESSION)
298
+ $curr->string .= $char;
299
+ else
300
+ $this->pushToken(Token::EXPRESSION, $char);
301
+ }
302
+
303
+ /**
304
+ * Pops a token from the end of the token array
305
+ * @return Token the popped token
306
+ */
307
+ protected function popToken()
308
+ {
309
+ $result = array_pop($this->tokens);
310
+ //trace("Popped token " . $result . "\r\n");
311
+ return $result;
312
+ }
313
+
314
+ /**
315
+ * Gets the current token (the last token in the token array)
316
+ * @return Token|null The current token, or null if no tokens are in the array
317
+ */
318
+ protected function getCurrToken()
319
+ {
320
+ if(empty($this->tokens))
321
+ return null;
322
+ return $this->tokens[ count($this->tokens) - 1 ];
323
+ }
324
+
325
+ /**
326
+ * Attempts to tokenize the specified string
327
+ * @param string $str The input string
328
+ * @throws ParseException When parsing the string fails due to invalid CSS
329
+ * @return Token[] An array of tokens parsed from the string
330
+ */
331
+ public function tokenize($str)
332
+ {
333
+ // Tokenize
334
+ $str = preg_replace('/\s+/', ' ', trim($str));
335
+ $length = strlen($str);
336
+
337
+ $cursor = 0;
338
+ $flags = (object)array(
339
+ 'brackets' => 0,
340
+ 'parentheses' => array(),
341
+ 'string' => false,
342
+ 'escaped' => false
343
+ );
344
+
345
+ $this->tokens = array();
346
+
347
+ for($cursor = 0; $cursor < $length; $cursor++)
348
+ {
349
+ $curr = $this->getCurrToken();
350
+ $char = substr($str, $cursor, 1);
351
+ $next_two_chars = substr($str, $cursor, 2);
352
+
353
+ //trace(preg_replace('/\r?\n/', ' ', $str) . "\r\n" . str_repeat(' ', $cursor) . "^ $cursor");
354
+ //trace("Current token: " . $curr);
355
+
356
+ if(!$flags->escaped)
357
+ {
358
+ switch($next_two_chars)
359
+ {
360
+ case Token::ATTRIBUTE_WHITESPACE_LIST_CONTAINS:
361
+ case Token::ATTRIBUTE_BEGINS_WITH:
362
+ case Token::ATTRIBUTE_ENDS_WITH:
363
+ case Token::ATTRIBUTE_CONTAINS_SUBSTRING:
364
+ case Token::ATTRIBUTE_HYPHEN_LIST_BEGINS_WITH:
365
+ $this->pushToken($next_two_chars, $next_two_chars);
366
+ $cursor++;
367
+ continue 2;
368
+ }
369
+ }
370
+
371
+ if($char == "\\")
372
+ {
373
+ if($flags->escaped)
374
+ $this->pushCharToString($char);
375
+
376
+ $flags->escaped = !$flags->escaped;
377
+ //trace($flags->escaped ? "Escaped" : "Unescaped");
378
+ }
379
+ else if($flags->string)
380
+ {
381
+ //trace("Reading {$flags->string} quoted string");
382
+ switch($char)
383
+ {
384
+ case Token::SINGLE_QUOTE:
385
+ case Token::DOUBLE_QUOTE:
386
+ if($flags->escaped)
387
+ {
388
+ $this->pushCharToString($char);
389
+ break;
390
+ }
391
+
392
+ $double = ($char == '"');
393
+
394
+ if(($double && $flags->string == 'double') || (!$double && $flags->string == 'single'))
395
+ {
396
+ $flags->string = false;
397
+ $this->pushToken(
398
+ $double ? Token::DOUBLE_QUOTE : Token::SINGLE_QUOTE,
399
+ $char
400
+ );
401
+ //trace("Exited {$flags->string} quoted string");
402
+ }
403
+ else
404
+ $this->pushCharToString($char);
405
+ break;
406
+
407
+ default:
408
+ $this->pushCharToString($char);
409
+ break;
410
+ }
411
+
412
+ if($flags->escaped)
413
+ {
414
+ $flags->escaped = false;
415
+ //trace("Unescaped at end of reading string");
416
+ }
417
+ }
418
+ else if($flags->escaped)
419
+ {
420
+ $this->pushCharToIdentifier($char);
421
+ $flags->escaped = false;
422
+ //trace("Unescaped in else-if clause");
423
+ }
424
+ else
425
+ {
426
+ switch($char)
427
+ {
428
+ case Token::SINGLE_QUOTE:
429
+ case Token::DOUBLE_QUOTE:
430
+ if($flags->escaped)
431
+ {
432
+ $this->pushCharToIdentifier($char);
433
+ break;
434
+ }
435
+
436
+ $double = ($char == '"');
437
+
438
+ $flags->string = ($double ? 'double' : 'single');
439
+ $this->pushToken(
440
+ $double ? Token::DOUBLE_QUOTE : Token::SINGLE_QUOTE,
441
+ $char
442
+ );
443
+
444
+ //trace("Entered {$flags->string} quoted string");
445
+ break;
446
+
447
+ case Token::OPEN_BRACKET:
448
+ $var = ($char == Token::OPEN_BRACKET ? 'brackets' : 'parentheses');
449
+
450
+ $flags->brackets++;
451
+
452
+ if($flags->brackets > 1)
453
+ throw new ParseException('Unexpected ' . $char);
454
+
455
+ $this->pushToken($char, $char);
456
+ //trace("Entered brackets");
457
+
458
+ break;
459
+
460
+ case Token::CLOSE_BRACKET:
461
+ $flags->brackets--;
462
+
463
+ if($flags->brackets < 0)
464
+ throw new ParseException('Unexpected ' . $char);
465
+
466
+ $this->pushToken($char, $char);
467
+ //trace("Exited brackets");
468
+
469
+ break;
470
+
471
+ case Token::OPEN_PARENTHES:
472
+ array_push($flags->parentheses, $curr->string);
473
+ $this->pushToken($char, $char);
474
+ //trace("Entered brackets");
475
+ break;
476
+
477
+ case Token::CLOSE_PARENTHES:
478
+ array_pop($flags->parentheses);
479
+ $this->pushToken($char, $char);
480
+ //trace("Exited brackets");
481
+ break;
482
+
483
+ case Token::UNION_OPERATOR:
484
+ case Token::CLASS_SHORTHAND:
485
+ case Token::ID_SHORTHAND:
486
+ case Token::ANY_ELEMENT:
487
+ case Token::PSEUDO:
488
+ case Token::UNION_OPERATOR:
489
+ case Token::ATTRIBUTE_EQUAL_TO:
490
+ if($flags->escaped)
491
+ break;
492
+
493
+ $this->pushToken($char, $char);
494
+
495
+ break;
496
+
497
+ case Token::ADJACENT_SIBLING_COMBINATOR:
498
+ if(count($flags->parentheses) > 0)
499
+ {
500
+ $this->pushCharToExpression($char);
501
+ break;
502
+ }
503
+ case Token::CHILD_COMBINATOR:
504
+ case Token::GENERAL_SIBLING_COMBINATOR:
505
+ $curr = $this->getCurrToken();
506
+ if($curr && $curr->type == Token::DESCENDANT_COMBINATOR)
507
+ $this->popToken();
508
+
509
+ $this->pushToken($char, $char);
510
+
511
+ break;
512
+
513
+ case " ":
514
+ case "\r":
515
+ case "\n":
516
+ case "\t":
517
+ $curr = $this->getCurrToken();
518
+
519
+ if($flags->brackets > 0 || count($flags->parentheses) > 0)
520
+ {
521
+ break;
522
+ }
523
+ if($curr)
524
+ {
525
+ if($curr->type == Token::UNION_OPERATOR)
526
+ break;
527
+ if($curr->isCombinator())
528
+ break;
529
+ }
530
+ else
531
+ break;
532
+
533
+ $this->pushToken(Token::DESCENDANT_COMBINATOR, $char);
534
+
535
+ break;
536
+
537
+ default:
538
+ if(count($flags->parentheses) > 0 && !preg_match('/not/i', $flags->parentheses[count($flags->parentheses) - 1]))
539
+ $this->pushCharToExpression($char);
540
+ else
541
+ $this->pushCharToIdentifier($char);
542
+ break;
543
+ }
544
+ }
545
+
546
+ //trace("");
547
+ }
548
+
549
+ return $this->tokens;
550
+ }
551
+ }
552
+
553
+ /**
554
+ * This class represents a CSS pseudo selector, for example, :nth-child, :empty, :not
555
+ */
556
+ class PseudoSelector
557
+ {
558
+ public $name;
559
+ public $expression;
560
+ public $selector;
561
+
562
+ /**
563
+ * Parses this selector from the given stream, on the supplied selector
564
+ * @param TokenStream $stream The token stream to read from
565
+ * @param Selector $selector The CSS selector this pseudo-selector is part of
566
+ * @throws ParseException Pseudo selector not supported server side
567
+ * @throws ParseException Pseudo selector not yet implemented
568
+ * @throws ParseException Unknown pseudo selector
569
+ * @throws ParseException :not pseudo selector cannot be nested (as per the CSS specs)
570
+ * @throws ParseException Invalid CSS in the selector
571
+ * @return void
572
+ */
573
+ public function parse($stream, $selector)
574
+ {
575
+ $first = $stream->read(Token::PSEUDO);
576
+ $token = $stream->read(Token::IDENTIFIER);
577
+
578
+ $this->name = strtolower($token->string);
579
+ switch($this->name)
580
+ {
581
+ case 'nth-child':
582
+ case 'nth-last-child':
583
+ case 'nth-of-type':
584
+ case 'nth-last-of-type':
585
+ case 'not':
586
+ break;
587
+
588
+ case 'first-child':
589
+ case 'last-child':
590
+ case 'first-of-type':
591
+ case 'last-of-type':
592
+ case 'only-child':
593
+ case 'only-of-type':
594
+ case 'empty':
595
+ case 'enabled':
596
+ case 'disabled':
597
+ case 'checked':
598
+ return;
599
+ break;
600
+
601
+ case 'link':
602
+ case 'visited':
603
+ case 'active':
604
+ case 'hover':
605
+ case 'focus':
606
+ case 'target':
607
+ throw new ParseException('Pseudo selector not supported server side');
608
+ break;
609
+
610
+ case 'root':
611
+ // See https://en.wikibooks.org/wiki/XPath/CSS_Equivalents for root. Will need to pop descendant:: off stack
612
+
613
+ case 'lang':
614
+ throw new ParseException('Pseudo selector not yet implemented');
615
+ break;
616
+
617
+ default:
618
+ throw new ParseException('Unknown pseudo selector');
619
+ break;
620
+ }
621
+
622
+ $stream->read(Token::OPEN_PARENTHES);
623
+ if($this->name == 'not')
624
+ {
625
+ if($selector->parent)
626
+ {
627
+ foreach($selector->parent->selector->pseudos as $parent_pseudo)
628
+ {
629
+ if($parent_pseudo->name == 'not')
630
+ throw new ParseException(':not pseudo selector cannot be nested');
631
+ }
632
+ }
633
+
634
+ $this->selector = new Selector($stream);
635
+ $this->selector->parent = $this;
636
+ $this->selector->parse($stream, $this);
637
+ }
638
+ else
639
+ $this->expression = $stream->read(Token::EXPRESSION);
640
+ $stream->read(Token::CLOSE_PARENTHES);
641
+ }
642
+ }
643
+
644
+ /**
645
+ * A CSS attribute selector, such as [data-example], [data-example="value"] or [data-example$="ends-with"]
646
+ */
647
+ class AttributeSelector
648
+ {
649
+ public $name;
650
+ public $operator;
651
+ public $value;
652
+
653
+ /**
654
+ * Parses the attribute selector from the supplied stream. Please note these classes expect attribute selectors to be enclosed in quotes.
655
+ * @param TokenStream $stream The token stream to read from
656
+ * @throws ParseException Unexpected end in attribute
657
+ * @throws ParseException Expected either close bracket or attribute operator
658
+ * @throws ParseException Unexpected end in attribute
659
+ * @throws ParseException Expected quote to open string after attribute operator
660
+ * @throws ParseException Unexpected end in attribute
661
+ * @throws ParseException Expected quote to terminate string after attribute operator
662
+ * @throws ParseException Invalid CSS eg unexpected tokens
663
+ */
664
+ public function parse($stream)
665
+ {
666
+ // Expect [ first
667
+ $stream->read(Token::OPEN_BRACKET);
668
+
669
+ // Read name
670
+ $token = $stream->read(Token::IDENTIFIER);
671
+ $this->name = $token->string;
672
+
673
+ // Read operator
674
+ $token = $stream->read();
675
+ if(!$token)
676
+ throw new ParseException('Unexpected end in attribute');
677
+ if($token->type == Token::CLOSE_BRACKET)
678
+ return; // has attribute
679
+ if(!$token->isAttributeOperator())
680
+ throw new ParseException('Expected either close bracket or attribute operator');
681
+ $this->operator = $token->string;
682
+
683
+ // Read string value
684
+ $token = $stream->read();
685
+ if(!$token)
686
+ throw new ParseException('Unexpected end in attribute');
687
+ if($token->type != Token::SINGLE_QUOTE && $token->type != Token::DOUBLE_QUOTE)
688
+ throw new ParseException('Expected quote to open string after attribute operator');
689
+ $openQuoteType = $token->type;
690
+
691
+ $after = $stream->peek();
692
+ if($after->type == $openQuoteType)
693
+ {
694
+ // Empty string
695
+ $this->value = '';
696
+ }
697
+ else
698
+ {
699
+ // Read value
700
+ $token = $stream->read(Token::STRING);
701
+ $this->value = $token->string;
702
+ }
703
+
704
+ $token = $stream->read();
705
+ if(!$token)
706
+ throw new ParseException('Unexpected end in attribute');
707
+ if($token->type != Token::SINGLE_QUOTE && $token->type != Token::DOUBLE_QUOTE)
708
+ throw new ParseException('Expected quote to terminate string after attribute operator');
709
+
710
+ // Expect ]
711
+ $stream->read(Token::CLOSE_BRACKET);
712
+ }
713
+ }
714
+
715
+ /**
716
+ * Represents a single selector, either standalone or as part of a compound selector
717
+ */
718
+ class Selector
719
+ {
720
+ public $element = '*';
721
+ public $id;
722
+ public $classes;
723
+ public $attributes;
724
+ public $pseudos;
725
+
726
+ public $parent;
727
+
728
+ /**
729
+ * Parses this selector from the given stream.
730
+ * @param TokenStream $stream The token stream to read from.
731
+ * @param PseudoSelector $not The :not pseudo selector that contains this selector.
732
+ * @throws ParseException Unexpected end in attribute
733
+ * @throws ParseException Expected either close bracket or attribute operator
734
+ * @throws ParseException Unexpected end in attribute
735
+ * @throws ParseException Expected quote to open string after attribute operator
736
+ * @throws ParseException Unexpected end in attribute
737
+ * @throws ParseException Expected quote to terminate string after attribute operator
738
+ * @throws ParseException Invalid CSS eg unexpected tokens
739
+ */
740
+ public function parse($stream, $not=null)
741
+ {
742
+ $first = $stream->peek();
743
+
744
+ switch($first->type)
745
+ {
746
+ case Token::ANY_ELEMENT:
747
+ case Token::IDENTIFIER:
748
+ $this->element = $stream->read()->string;
749
+ break;
750
+
751
+ case Token::OPEN_BRACKET:
752
+ case Token::PSEUDO:
753
+ case Token::ID_SHORTHAND:
754
+ case Token::CLASS_SHORTHAND:
755
+ break;
756
+
757
+ default:
758
+ throw new ParseException("Unexpected token '{$token->string}'");
759
+ break;
760
+ }
761
+
762
+ while($token = $stream->peek())
763
+ {
764
+ if($token->isCombinator() || $token->type == Token::UNION_OPERATOR)
765
+ return;
766
+
767
+ switch($token->type)
768
+ {
769
+ case Token::ID_SHORTHAND:
770
+ if($this->id != null)
771
+ throw new ParseExcepton('Selector can only have one ID');
772
+ $stream->read(Token::ID_SHORTHAND);
773
+ $this->id = $stream->read(Token::IDENTIFIER)->string;
774
+ //trace("Read ID as {$this->id}");
775
+ continue 2;
776
+ break;
777
+
778
+ case Token::CLASS_SHORTHAND:
779
+ if(!$this->classes)
780
+ $this->classes = array();
781
+ $stream->read(Token::CLASS_SHORTHAND);
782
+ array_push($this->classes, $stream->read(Token::IDENTIFIER)->string);
783
+ continue 2;
784
+ break;
785
+
786
+ case Token::OPEN_BRACKET:
787
+ if(!$this->attributes)
788
+ $this->attributes = array();
789
+
790
+ $attributeSelector = new AttributeSelector();
791
+ array_push($this->attributes, $attributeSelector);
792
+ $attributeSelector->parse($stream);
793
+ continue 2;
794
+ break;
795
+
796
+ case Token::PSEUDO:
797
+ if(!$this->pseudos)
798
+ $this->pseudos = array();
799
+
800
+ $pseudoSelector = new PseudoSelector();
801
+ array_push($this->pseudos, $pseudoSelector);
802
+ $pseudoSelector->parse($stream, $this);
803
+ continue 2;
804
+ break;
805
+
806
+ case Token::CLOSE_PARENTHES:
807
+ if($not != null)
808
+ return;
809
+
810
+ default:
811
+ throw new ParseException("Unexpected token '{$token->string}'");
812
+ break;
813
+ }
814
+
815
+ $stream->read();
816
+ }
817
+
818
+
819
+ }
820
+ }
821
+
822
+ /**
823
+ * Used to parse a selector or compound selectors
824
+ */
825
+ class Parser
826
+ {
827
+ protected $tokenizer;
828
+ protected $elements;
829
+
830
+ /**
831
+ * Constructor.
832
+ */
833
+ public function __construct()
834
+ {
835
+ $this->tokenizer = new Tokenizer();
836
+ }
837
+
838
+ /**
839
+ * Parses the selector(s) supplied
840
+ * @param string $selector The string of selector(s) to parse
841
+ * @return Selector[] An array of selectors parsed from the string
842
+ */
843
+ public function parse($selector)
844
+ {
845
+ $tokens = $this->tokenizer->tokenize($selector);
846
+ $stream = new TokenStream($tokens);
847
+ $this->elements = array();
848
+
849
+ while(!$stream->eof())
850
+ {
851
+ $token = $stream->peek();
852
+ if($token->isCombinator() || $token->type == Token::UNION_OPERATOR)
853
+ {
854
+ if(empty($this->elements))
855
+ throw new ParseException('Expected selector before combinator or union operator');
856
+ array_push($this->elements, $stream->read());
857
+ }
858
+
859
+ $selector = new Selector();
860
+ $selector->parse($stream);
861
+ array_push($this->elements, $selector);
862
+
863
+ //trace(print_r($selector, true));
864
+ }
865
+
866
+ return $this->elements;
867
+ }
868
+
869
+
870
+ }
871
+
872
+ /**
873
+ * Used to convert CSS selectors to XPath queries
874
+ */
875
+ class XPathConverter
876
+ {
877
+ protected $parser;
878
+ protected $xpath;
879
+
880
+ /**
881
+ * Constructor.
882
+ */
883
+ public function __construct()
884
+ {
885
+ $this->parser = new Parser();
886
+ }
887
+
888
+ /**
889
+ * Converts a CSS attribute selector to its XPath equivalent and pushes the XPath query string to memory
890
+ * @param AttributeSelector $attr The CSS attribute selector
891
+ * @throws ConvertException Unrecognised attribute operator
892
+ * @return void
893
+ */
894
+ protected function convertAttribute($attr)
895
+ {
896
+ $name = $attr->name;
897
+ $value = addslashes($attr->value);
898
+
899
+ switch($attr->operator)
900
+ {
901
+ case null:
902
+ $inner = "@{$name}";
903
+ break;
904
+
905
+ case Token::ATTRIBUTE_EQUAL_TO:
906
+ $inner = "@$name=\"$value\"";
907
+ break;
908
+
909
+ case Token::ATTRIBUTE_WHITESPACE_LIST_CONTAINS:
910
+ $inner = "conatins(concat(\" \", normalize-space(@$name), \" \"), \" $value \")";
911
+ break;
912
+
913
+ case Token::ATTRIBUTE_BEGINS_WITH:
914
+ $inner = "starts-with(@$name, \"$value\")";
915
+ break;
916
+
917
+ case Token::ATTRIBUTE_ENDS_WITH:
918
+ $inner = "substring(@$name, string-length(@$name) - string-length(\"$value\") + 1) = \"$value\"";
919
+ break;
920
+
921
+ case Token::ATTRIBUTE_CONTAINS_SUBSTRING:
922
+ $inner = "contains(@$name, \"$value\")";
923
+ break;
924
+
925
+ case Token::ATTRIBUTE_HYPHEN_LIST_BEGINS_WITH:
926
+ $inner = "@$name=\"@$value\" | starts-with(@$name, \"@$value-\")";
927
+ break;
928
+
929
+ default:
930
+ throw new ConvertException("Don't know how to convert operator {$attr->operator}");
931
+ break;
932
+ }
933
+ array_push($this->xpath, "[$inner]");
934
+ }
935
+
936
+ /**
937
+ * Converts a CSS pseudo selector to its XPath equivalent and pushes the XPath query string to memory
938
+ * @param AttributeSelector $pseudo The CSS pseudo selector
939
+ * @throws ConvertException Don't know how to convert selector (may not be implemented)
940
+ * @return void
941
+ */
942
+ protected function convertPseudo($pseudo)
943
+ {
944
+ $name = $pseudo->name;
945
+
946
+ // TODO: The "of type" selectors should change the parent selector element to *, and should use that type in their xpath
947
+ // TODO: Test with a live domdocument in here (or smartdocument even)
948
+
949
+ switch($name)
950
+ {
951
+ case 'nth-child':
952
+ case 'nth-last-child':
953
+ case 'nth-of-type':
954
+ case 'nth-last-of-type':
955
+ // TODO: Support formulas / expressions
956
+ throw new ConvertException('Not yet implemented');
957
+ break;
958
+
959
+ case 'first-child':
960
+ case 'first-of-type':
961
+ $inner = '1';
962
+ break;
963
+
964
+ case 'last-child':
965
+ case 'last-of-type':
966
+ $inner = 'last()';
967
+ break;
968
+
969
+ case 'only-child':
970
+ case 'only-of-type':
971
+ $inner = 'count(*)=1'; // TODO: might need to swap * with node name
972
+ break;
973
+
974
+ case 'empty':
975
+ $inner = 'count(./*)=0 and string-length(text())=0';
976
+ break;
977
+
978
+ case 'enabled':
979
+ $inner = "not(@disabled)";
980
+ break;
981
+
982
+ case 'disabled':
983
+ case 'checked':
984
+ $inner = "@$name";
985
+ break;
986
+
987
+ case 'not':
988
+ throw new ConvertException('Not yet implemented');
989
+ break;
990
+
991
+ default:
992
+ throw new ConvertException("Don't know how to convert pseudo selector {$pseudo->name}");
993
+ break;
994
+ }
995
+
996
+ array_push($this->xpath, "[$inner]");
997
+ }
998
+
999
+ /**
1000
+ * Converts a CSS selector to its XPath equivalent and pushes the XPath query string to memory
1001
+ * @param Selector $selector The CSS selector to convert.
1002
+ * @return void
1003
+ */
1004
+ protected function convertSelector($selector)
1005
+ {
1006
+ //trace("Converting selector " . print_r($selector, true));
1007
+
1008
+ $prev = null;
1009
+ if(!empty($this->xpath))
1010
+ $prev = &$this->xpath[ count($this->xpath) - 1 ];
1011
+
1012
+ if($prev == 'following-sibling::*[1]')
1013
+ $prev = preg_replace('/\*/', $selector->element, $prev);
1014
+ else
1015
+ array_push($this->xpath, $selector->element);
1016
+
1017
+ if($selector->id != null)
1018
+ array_push($this->xpath, '[@id="' . $selector->id . '"]');
1019
+
1020
+ if($selector->classes)
1021
+ foreach($selector->classes as $class)
1022
+ {
1023
+ array_push($this->xpath,
1024
+ '[contains(concat(" ", normalize-space(@class), " "), " ' . $class . ' ")]'
1025
+ );
1026
+ }
1027
+
1028
+ if($selector->attributes)
1029
+ foreach($selector->attributes as $attr)
1030
+ $this->convertAttribute($attr);
1031
+
1032
+ if($selector->pseudos)
1033
+ foreach($selector->pseudos as $pseudo)
1034
+ $this->convertPseudo($pseudo);
1035
+ }
1036
+
1037
+ /**
1038
+ * Converts an element (eg a single, non-compound CSS selector) to it's XPath equivalent
1039
+ * @param Selector $element The selector to convert
1040
+ * @throws ConvertException Unexpected element
1041
+ */
1042
+ protected function convertElement($element)
1043
+ {
1044
+ //trace("Converting element " . print_r($element, true));
1045
+
1046
+ $prev = null;
1047
+ if(!empty($this->xpath))
1048
+ $prev = $this->xpath[ count($this->xpath) - 1 ];
1049
+
1050
+ if($element instanceof Token)
1051
+ {
1052
+ if($prev != "\r\n|\r\n" && $element->type != Token::UNION_OPERATOR)
1053
+ array_push($this->xpath, '/');
1054
+
1055
+ switch($element->type)
1056
+ {
1057
+ case Token::UNION_OPERATOR:
1058
+ array_push($this->xpath, "\r\n|\r\n");
1059
+
1060
+ case Token::DESCENDANT_COMBINATOR:
1061
+ array_push($this->xpath, 'descendant::');
1062
+ return;
1063
+
1064
+ case Token::CHILD_COMBINATOR:
1065
+ array_push($this->xpath, 'child::');
1066
+ return;
1067
+
1068
+ case Token::GENERAL_SIBLING_COMBINATOR:
1069
+ array_push($this->xpath, 'following-sibling::');
1070
+ return;
1071
+
1072
+ case Token::ADJACENT_SIBLING_COMBINATOR:
1073
+ array_push($this->xpath, 'following-sibling::*[1]');
1074
+ return;
1075
+
1076
+ default:
1077
+ throw new ConvertException('Unexpected token');
1078
+ break;
1079
+ }
1080
+ }
1081
+ else if($element instanceof Selector)
1082
+ $this->convertSelector($element);
1083
+ else
1084
+ throw new ConvertException('Unexpected element');
1085
+ }
1086
+
1087
+ /**
1088
+ * Converts the given CSS selector string into it's XPath equivalent
1089
+ * @param string $str The input CSS selector to convert
1090
+ * @return string The XPath equivalent of the supplied selector
1091
+ */
1092
+ public function convert($str)
1093
+ {
1094
+ //trace("=== Parsing $str ===\r\n");
1095
+
1096
+ $this->xpath = array('descendant::');
1097
+ $elements = $this->parser->parse($str);
1098
+
1099
+ //trace("=== Converting $str ===\r\n");
1100
+ foreach($elements as $el)
1101
+ $this->convertElement($el);
1102
+
1103
+ return implode('', $this->xpath);
1104
+ }
1105
+ }
1106
+
1107
  ?>
includes/class.settings-page.php CHANGED
@@ -1,110 +1,110 @@
1
- <?php
2
-
3
- namespace WPGMZA;
4
-
5
- class SettingsPage extends Page {
6
- public function __construct() {
7
- global $wpgmza;
8
-
9
- Page::__construct();
10
-
11
- $this->document->loadPHPFile(plugin_dir_path(__DIR__) . 'html/settings-page.html.php');
12
-
13
- $this->disableProFeatures();
14
- $this->hideSelectedProFeatures();
15
-
16
- $this->form = $this->document->querySelector('form');
17
-
18
- $addOnTabs = apply_filters("wpgmza_global_settings_tabs", "");
19
- if(!empty($addOnTabs)){
20
- $this->form->querySelector('.settings-tabs-nav')->import($addOnTabs);
21
- }
22
-
23
- $addOnContent = apply_filters("wpgmza_global_settings_tab_content", "");
24
- if(!empty($addOnContent)){
25
- $this->form->querySelector('.addition-tabs')->import($addOnContent);
26
- }
27
-
28
- if(class_exists("COMPLIANZ")){
29
- $this->form->querySelector('.wpgmza-complianz-notice')->removeClass('wpgmza-hidden');
30
- $this->form->querySelector('#wpgmza-gdpr-compliance-notice')->addClass('wpgmza-hidden');
31
- $this->form->querySelector('input[name="wpgmza_gdpr_require_consent_before_load"]')->setAttribute('disabled', 'disabled');
32
- }
33
-
34
- if(empty($_POST)) {
35
- $this->document->populate($wpgmza->settings);
36
- $this->addFormNonces();
37
- }
38
- else
39
- {
40
- if(!$this->isNonceValid($this->form, $_POST['nonce']))
41
- throw new \Exception("Invalid nonce");
42
-
43
- $oldPullMethod = $wpgmza->settings->wpgmza_settings_marker_pull;
44
-
45
- // NB: Prevent slashes accumulating in paths on Windows machines
46
- $data = array_map('stripslashes', $_POST);
47
-
48
- // Improved KSES cleanup to support the custom scripts, while still cleaning text inputs like the GDPR overrides
49
- foreach($data as $key => $value){
50
- if(is_string($value)){
51
- if($key === "wpgmza_custom_css" || $key === "wpgmza_custom_js"){
52
- // Skip custom scripts, they should not be KSES cleaned
53
- continue;
54
- }
55
-
56
- $data[$key] = wp_kses_post($value);
57
- }
58
- }
59
-
60
- $this->document->populate($data);
61
-
62
- $data = $this->form->serializeFormData();
63
-
64
- $data = apply_filters("wpgmza_global_settings_save_redux", $data);
65
-
66
- foreach($data as $key => $value)
67
- $wpgmza->settings->{$key} = $value;
68
-
69
- // Update XML caches if we've just switched to XML mode
70
- if($wpgmza->settings->wpgmza_settings_marker_pull == Plugin::MARKER_PULL_XML && $oldPullMethod != Plugin::MARKER_PULL_XML)
71
- $wpgmza->updateAllMarkerXMLFiles();
72
-
73
- wp_redirect($_SERVER['HTTP_REFERER']);
74
- return;
75
- }
76
- }
77
-
78
- public static function dangerZoneDelete(){
79
- global $wpgmza;
80
-
81
- if(!wp_verify_nonce($_POST['nonce'], 'wpgmza_maps_settings_danger_zone_delete_data')){
82
- http_response_code(403);
83
- exit;
84
- }
85
-
86
- if(!$wpgmza->isUserAllowedToEdit()){
87
- http_response_code(401);
88
- exit;
89
- }
90
-
91
- $type = sanitize_text_field($_POST['type']);
92
- $wpgmza->deleteAllData($type);
93
-
94
- wp_send_json(array('success' => 1));
95
- exit;
96
- }
97
-
98
-
99
-
100
-
101
- }
102
-
103
- add_action('admin_post_wpgmza_save_settings', function() {
104
-
105
- $settingsPage = SettingsPage::createInstance();
106
-
107
- });
108
-
109
- add_action('wp_ajax_wpgmza_maps_settings_danger_zone_delete_data', array('WPGMZA\\SettingsPage', 'dangerZoneDelete'));
110
-
1
+ <?php
2
+
3
+ namespace WPGMZA;
4
+
5
+ class SettingsPage extends Page {
6
+ public function __construct() {
7
+ global $wpgmza;
8
+
9
+ Page::__construct();
10
+
11
+ $this->document->loadPHPFile(plugin_dir_path(__DIR__) . 'html/settings-page.html.php');
12
+
13
+ $this->disableProFeatures();
14
+ $this->hideSelectedProFeatures();
15
+
16
+ $this->form = $this->document->querySelector('form');
17
+
18
+ $addOnTabs = apply_filters("wpgmza_global_settings_tabs", "");
19
+ if(!empty($addOnTabs)){
20
+ $this->form->querySelector('.settings-tabs-nav')->import($addOnTabs);
21
+ }
22
+
23
+ $addOnContent = apply_filters("wpgmza_global_settings_tab_content", "");
24
+ if(!empty($addOnContent)){
25
+ $this->form->querySelector('.addition-tabs')->import($addOnContent);
26
+ }
27
+
28
+ if(class_exists("COMPLIANZ")){
29
+ $this->form->querySelector('.wpgmza-complianz-notice')->removeClass('wpgmza-hidden');
30
+ $this->form->querySelector('#wpgmza-gdpr-compliance-notice')->addClass('wpgmza-hidden');
31
+ $this->form->querySelector('input[name="wpgmza_gdpr_require_consent_before_load"]')->setAttribute('disabled', 'disabled');
32
+ }
33
+
34
+ if(empty($_POST)) {
35
+ $this->document->populate($wpgmza->settings);
36
+ $this->addFormNonces();
37
+ }
38
+ else
39
+ {
40
+ if(!$this->isNonceValid($this->form, $_POST['nonce']))
41
+ throw new \Exception("Invalid nonce");
42
+
43
+ $oldPullMethod = $wpgmza->settings->wpgmza_settings_marker_pull;
44
+
45
+ // NB: Prevent slashes accumulating in paths on Windows machines
46
+ $data = array_map('stripslashes', $_POST);
47
+
48
+ // Improved KSES cleanup to support the custom scripts, while still cleaning text inputs like the GDPR overrides
49
+ foreach($data as $key => $value){
50
+ if(is_string($value)){
51
+ if($key === "wpgmza_custom_css" || $key === "wpgmza_custom_js"){
52
+ // Skip custom scripts, they should not be KSES cleaned
53
+ continue;
54
+ }
55
+
56
+ $data[$key] = wp_kses_post($value);
57
+ }
58
+ }
59
+
60
+ $this->document->populate($data);
61
+
62
+ $data = $this->form->serializeFormData();
63
+
64
+ $data = apply_filters("wpgmza_global_settings_save_redux", $data);
65
+
66
+ foreach($data as $key => $value)
67
+ $wpgmza->settings->{$key} = $value;
68
+
69
+ // Update XML caches if we've just switched to XML mode
70
+ if($wpgmza->settings->wpgmza_settings_marker_pull == Plugin::MARKER_PULL_XML && $oldPullMethod != Plugin::MARKER_PULL_XML)
71
+ $wpgmza->updateAllMarkerXMLFiles();
72
+
73
+ wp_redirect($_SERVER['HTTP_REFERER']);
74
+ return;
75
+ }
76
+ }
77
+
78
+ public static function dangerZoneDelete(){
79
+ global $wpgmza;
80
+
81
+ if(!wp_verify_nonce($_POST['nonce'], 'wpgmza_maps_settings_danger_zone_delete_data')){
82
+ http_response_code(403);
83
+ exit;
84
+ }
85
+
86
+ if(!$wpgmza->isUserAllowedToEdit()){
87
+ http_response_code(401);
88
+ exit;
89
+ }
90
+
91
+ $type = sanitize_text_field($_POST['type']);
92
+ $wpgmza->deleteAllData($type);
93
+
94
+ wp_send_json(array('success' => 1));
95
+ exit;
96
+ }
97
+
98
+
99
+
100
+
101
+ }
102
+
103
+ add_action('admin_post_wpgmza_save_settings', function() {
104
+
105
+ $settingsPage = SettingsPage::createInstance();
106
+
107
+ });
108
+
109
+ add_action('wp_ajax_wpgmza_maps_settings_danger_zone_delete_data', array('WPGMZA\\SettingsPage', 'dangerZoneDelete'));
110
+
includes/class.theme-panel.php CHANGED
@@ -1,33 +1,33 @@
1
- <?php
2
-
3
- namespace WPGMZA;
4
-
5
- class ThemePanel extends DOMDocument
6
- {
7
- public function __construct($map=null)
8
- {
9
- global $wpgmza;
10
-
11
- DOMDocument::__construct();
12
-
13
- $this->loadPHPFile(plugin_dir_path(__DIR__) . 'html/theme-panel.html.php');
14
-
15
- $base = plugin_dir_url(__DIR__);
16
-
17
- wp_enqueue_script('owl-carousel', $base . 'lib/owl.carousel.min.js', array('jquery'), $wpgmza->getBasicVersion());
18
- wp_enqueue_style('owl-carousel', $base . 'lib/owl.carousel.css', array(), $wpgmza->getBasicVersion());
19
- wp_enqueue_style('owl-carousel_theme', $base . 'lib/owl.theme.css', array(), $wpgmza->getBasicVersion());
20
-
21
-
22
- /*
23
- * Deprecating code mirror enqueue, we don't actually use this with V8
24
- *
25
- * This will be reintroduced with V9, but we will need to use the included version from WordPress core
26
- *
27
- * Since 8.1.18, code removed, comment left as placeholder
28
- */
29
-
30
- if($map)
31
- $this->populate($map);
32
- }
33
- }
1
+ <?php
2
+
3
+ namespace WPGMZA;
4
+
5
+ class ThemePanel extends DOMDocument
6
+ {
7
+ public function __construct($map=null)
8
+ {
9
+ global $wpgmza;
10
+
11
+ DOMDocument::__construct();
12
+
13
+ $this->loadPHPFile(plugin_dir_path(__DIR__) . 'html/theme-panel.html.php');
14
+
15
+ $base = plugin_dir_url(__DIR__);
16
+
17
+ wp_enqueue_script('owl-carousel', $base . 'lib/owl.carousel.min.js', array('jquery'), $wpgmza->getBasicVersion());
18
+ wp_enqueue_style('owl-carousel', $base . 'lib/owl.carousel.css', array(), $wpgmza->getBasicVersion());
19
+ wp_enqueue_style('owl-carousel_theme', $base . 'lib/owl.theme.css', array(), $wpgmza->getBasicVersion());
20
+
21
+
22
+ /*
23
+ * Deprecating code mirror enqueue, we don't actually use this with V8
24
+ *
25
+ * This will be reintroduced with V9, but we will need to use the included version from WordPress core
26
+ *
27
+ * Since 8.1.18, code removed, comment left as placeholder
28
+ */
29
+
30
+ if($map)
31
+ $this->populate($map);
32
+ }
33
+ }
includes/compat/backwards_compat_v6.php CHANGED
@@ -1,132 +1,132 @@
1
- <?php
2
-
3
- if(!defined('ABSPATH'))
4
- return;
5
-
6
- /**
7
- * Handles Backwards Compatibility
8
- */
9
-
10
- add_action('admin_head', 'wpgmza_check_admin_head_backwards_compat_v6');
11
- /**
12
- * Runs the head functions if backwards compat is in the motions
13
- */
14
- function wpgmza_check_admin_head_backwards_compat_v6(){
15
- if(wpgmza_check_pro_compat_required_v6()){
16
- if (isset($_POST['wpgmza_save_circle'])){
17
- if(function_exists("wpgmaps_head")){
18
- wpgmaps_head();
19
- }
20
- } else if (isset($_POST['wpgmza_save_rectangle'])){
21
- if(function_exists("wpgmaps_head")){
22
- wpgmaps_head();
23
- }
24
- }
25
- }
26
- }
27
-
28
-
29
- add_action('wpgooglemaps_hook_user_js_after_core', 'wpgmza_check_user_backwards_compat_v6');
30
- /**
31
- * Checks if user end needs backwards compat code
32
- */
33
- function wpgmza_check_user_backwards_compat_v6(){
34
- if(wpgmza_check_pro_compat_required_v6()){
35
-
36
- wp_register_script('wpgmaps-user-backwards-compat', plugins_url('js/backwards_compat_user_v6.js', __FILE__), array('jquery'), '1.0', true);
37
-
38
- wp_localize_script('wpgmaps-user-backwards-compat', 'wpgmza_circle_data_array', wpgmza_backwards_compat_get_all_circle_data());
39
- wp_localize_script('wpgmaps-user-backwards-compat', 'wpgmza_rectangle_data_array', wpgmza_backwards_compat_get_all_rectangle_data());
40
-
41
- wp_enqueue_script('wpgmaps-user-backwards-compat');
42
- }
43
- }
44
-
45
-
46
-
47
- add_action("wpgmza_check_map_editor_backwards_compat", "wpgmza_check_map_editor_backwards_compat_v6");
48
- /**
49
- * Checks if the Pro version is less than the last v6
50
- * Set's up backwards compatibility if this is the case
51
- */
52
- function wpgmza_check_map_editor_backwards_compat_v6()
53
- {
54
- $map_id = isset($_GET['map_id']) ? (int) intval($_GET['map_id']) : null;
55
-
56
- if(isset($_GET['action'])){
57
- if ($_GET['action'] == "edit" && isset($_GET['map_id']) && wpgmza_check_pro_compat_required_v6()) {
58
- wp_register_script('wpgmaps-admin-backwards-compat', plugins_url('js/backwards_compat_v6.js', __FILE__), array('jquery', "jquery-ui-core"), '1.0', true);
59
-
60
- $tab_heading = "<li><a href=\"#tabs-circles\">".__("Circles","wp-google-maps")."</a></li>
61
- <li><a href=\"#tabs-rectangles\">".__("Rectangles","wp-google-maps")."</a></li>";
62
-
63
- $tab_content = "<div id=\"tabs-circles\">
64
- <h2>
65
- " . __('Add a Circle', 'wp-google-maps') . "
66
- </h2>
67
- <span><a class=\"button-primary\" href=\"" . get_option('siteurl') . "/wp-admin/admin.php?page=wp-google-maps-menu&action=add_circle&map_id=" . $map_id . "\">" . __("Add a Circle", "wp-google-maps") . "</a></span>
68
- " . wpgmza_get_circles_table($map_id) . "
69
- </div>
70
-
71
- <div id=\"tabs-rectangles\">
72
- <h2>
73
- " . __('Add a Rectangle', 'wp-google-maps') . "
74
- </h2>
75
- <span><a class=\"button-primary\" href=\"" . get_option('siteurl') . "/wp-admin/admin.php?page=wp-google-maps-menu&action=add_rectangle&map_id=" . $map_id . "\">" . __("Add a Rectangle", "wp-google-maps") . "</a></span>
76
- " . wpgmza_get_rectangles_table($map_id) . "
77
- </div>";
78
-
79
- wp_localize_script('wpgmaps-admin-backwards-compat', 'wpgmza_backwards_compat_v6_marker_tab_headings', $tab_heading);
80
- wp_localize_script('wpgmaps-admin-backwards-compat', 'wpgmza_backwards_compat_v6_marker_tab_content', $tab_content);
81
-
82
- wp_localize_script('wpgmaps-admin-backwards-compat', 'wpgmza_circle_data_array', wpgmza_get_circle_data($map_id));
83
- wp_localize_script('wpgmaps-admin-backwards-compat', 'wpgmza_rectangle_data_array', wpgmza_get_rectangle_data($map_id));
84
-
85
- wp_enqueue_script('wpgmaps-admin-backwards-compat');
86
- }
87
- }
88
- }
89
-
90
- /**
91
- * Check if backwards compat code is needed for this version
92
- */
93
- function wpgmza_check_pro_compat_required_v6(){
94
- if(function_exists("wpgmza_register_pro_version")){
95
- global $wpgmza_pro_version;
96
-
97
- if(version_compare($wpgmza_pro_version, '7.0.0', '<')) {
98
- return true;
99
- }
100
- }
101
- return false;
102
- }
103
-
104
- function wpgmza_backwards_compat_get_all_circle_data(){
105
- global $wpdb;
106
- global $wpgmza_tblname_circles;
107
- global $wpgmza;
108
-
109
- $stmt = "SELECT *, {$wpgmza->spatialFunctionPrefix}AsText(center) AS center FROM $wpgmza_tblname_circles";
110
- $results = $wpdb->get_results($stmt);
111
-
112
- $circles = array();
113
- foreach($results as $obj)
114
- $circles[$obj->id] = $obj;
115
-
116
- return $circles;
117
- }
118
-
119
- function wpgmza_backwards_compat_get_all_rectangle_data(){
120
- global $wpdb;
121
- global $wpgmza_tblname_rectangles;
122
- global $wpgmza;
123
-
124
- $stmt = "SELECT *, {$wpgmza->spatialFunctionPrefix}AsText(cornerA) AS cornerA, {$wpgmza->spatialFunctionPrefix}AsText(cornerB) AS cornerB FROM $wpgmza_tblname_rectangles";
125
- $results = $wpdb->get_results($stmt);
126
-
127
- $rectangles = array();
128
- foreach($results as $obj)
129
- $rectangles[$obj->id] = $obj;
130
-
131
- return $rectangles;
132
- }
1
+ <?php
2
+
3
+ if(!defined('ABSPATH'))
4
+ return;
5
+
6
+ /**
7
+ * Handles Backwards Compatibility
8
+ */
9
+
10
+ add_action('admin_head', 'wpgmza_check_admin_head_backwards_compat_v6');
11
+ /**
12
+ * Runs the head functions if backwards compat is in the motions
13
+ */
14
+ function wpgmza_check_admin_head_backwards_compat_v6(){
15
+ if(wpgmza_check_pro_compat_required_v6()){
16
+ if (isset($_POST['wpgmza_save_circle'])){
17
+ if(function_exists("wpgmaps_head")){
18
+ wpgmaps_head();
19
+ }
20
+ } else if (isset($_POST['wpgmza_save_rectangle'])){
21
+ if(function_exists("wpgmaps_head")){
22
+ wpgmaps_head();
23
+ }
24
+ }
25
+ }
26
+ }
27
+
28
+
29
+ add_action('wpgooglemaps_hook_user_js_after_core', 'wpgmza_check_user_backwards_compat_v6');
30
+ /**
31
+ * Checks if user end needs backwards compat code
32
+ */
33
+ function wpgmza_check_user_backwards_compat_v6(){
34
+ if(wpgmza_check_pro_compat_required_v6()){
35
+
36
+ wp_register_script('wpgmaps-user-backwards-compat', plugins_url('js/backwards_compat_user_v6.js', __FILE__), array('jquery'), '1.0', true);
37
+
38
+ wp_localize_script('wpgmaps-user-backwards-compat', 'wpgmza_circle_data_array', wpgmza_backwards_compat_get_all_circle_data());
39
+ wp_localize_script('wpgmaps-user-backwards-compat', 'wpgmza_rectangle_data_array', wpgmza_backwards_compat_get_all_rectangle_data());
40
+
41
+ wp_enqueue_script('wpgmaps-user-backwards-compat');
42
+ }
43
+ }
44
+
45
+
46
+
47
+ add_action("wpgmza_check_map_editor_backwards_compat", "wpgmza_check_map_editor_backwards_compat_v6");
48
+ /**
49
+ * Checks if the Pro version is less than the last v6
50
+ * Set's up backwards compatibility if this is the case
51
+ */
52
+ function wpgmza_check_map_editor_backwards_compat_v6()
53
+ {
54
+ $map_id = isset($_GET['map_id']) ? (int) intval($_GET['map_id']) : null;
55
+
56
+ if(isset($_GET['action'])){
57
+ if ($_GET['action'] == "edit" && isset($_GET['map_id']) && wpgmza_check_pro_compat_required_v6()) {
58
+ wp_register_script('wpgmaps-admin-backwards-compat', plugins_url('js/backwards_compat_v6.js', __FILE__), array('jquery', "jquery-ui-core"), '1.0', true);
59
+
60
+ $tab_heading = "<li><a href=\"#tabs-circles\">".__("Circles","wp-google-maps")."</a></li>
61
+ <li><a href=\"#tabs-rectangles\">".__("Rectangles","wp-google-maps")."</a></li>";
62
+
63
+ $tab_content = "<div id=\"tabs-circles\">
64
+ <h2>
65
+ " . __('Add a Circle', 'wp-google-maps') . "
66
+ </h2>
67
+ <span><a class=\"button-primary\" href=\"" . get_option('siteurl') . "/wp-admin/admin.php?page=wp-google-maps-menu&action=add_circle&map_id=" . $map_id . "\">" . __("Add a Circle", "wp-google-maps") . "</a></span>
68
+ " . wpgmza_get_circles_table($map_id) . "
69
+ </div>
70
+
71
+ <div id=\"tabs-rectangles\">
72
+ <h2>
73
+ " . __('Add a Rectangle', 'wp-google-maps') . "
74
+ </h2>
75
+ <span><a class=\"button-primary\" href=\"" . get_option('siteurl') . "/wp-admin/admin.php?page=wp-google-maps-menu&action=add_rectangle&map_id=" . $map_id . "\">" . __("Add a Rectangle", "wp-google-maps") . "</a></span>
76
+ " . wpgmza_get_rectangles_table($map_id) . "
77
+ </div>";
78
+
79
+ wp_localize_script('wpgmaps-admin-backwards-compat', 'wpgmza_backwards_compat_v6_marker_tab_headings', $tab_heading);
80
+ wp_localize_script('wpgmaps-admin-backwards-compat', 'wpgmza_backwards_compat_v6_marker_tab_content', $tab_content);
81
+
82
+ wp_localize_script('wpgmaps-admin-backwards-compat', 'wpgmza_circle_data_array', wpgmza_get_circle_data($map_id));
83
+ wp_localize_script('wpgmaps-admin-backwards-compat', 'wpgmza_rectangle_data_array', wpgmza_get_rectangle_data($map_id));
84
+
85
+ wp_enqueue_script('wpgmaps-admin-backwards-compat');
86
+ }
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Check if backwards compat code is needed for this version
92
+ */
93
+ function wpgmza_check_pro_compat_required_v6(){
94
+ if(function_exists("wpgmza_register_pro_version")){
95
+ global $wpgmza_pro_version;
96
+
97
+ if(version_compare($wpgmza_pro_version, '7.0.0', '<')) {
98
+ return true;
99
+ }
100
+ }
101
+ return false;
102
+ }
103
+
104
+ function wpgmza_backwards_compat_get_all_circle_data(){
105
+ global $wpdb;
106
+ global $wpgmza_tblname_circles;
107
+ global $wpgmza;
108
+
109
+ $stmt = "SELECT *, {$wpgmza->spatialFunctionPrefix}AsText(center) AS center FROM $wpgmza_tblname_circles";
110
+ $results = $wpdb->get_results($stmt);
111
+
112
+ $circles = array();
113
+ foreach($results as $obj)
114
+ $circles[$obj->id] = $obj;
115
+
116
+ return $circles;
117
+ }
118
+
119
+ function wpgmza_backwards_compat_get_all_rectangle_data(){
120
+ global $wpdb;
121
+ global $wpgmza_tblname_rectangles;
122
+ global $wpgmza;
123
+
124
+ $stmt = "SELECT *, {$wpgmza->spatialFunctionPrefix}AsText(cornerA) AS cornerA, {$wpgmza->spatialFunctionPrefix}AsText(cornerB) AS cornerB FROM $wpgmza_tblname_rectangles";
125
+ $results = $wpdb->get_results($stmt);
126
+
127
+ $rectangles = array();
128
+ foreach($results as $obj)
129
+ $rectangles[$obj->id] = $obj;
130
+
131
+ return $rectangles;
132
+ }
includes/compat/class.pro-below-8.1-compatibility.php CHANGED
@@ -1,2505 +1,2505 @@
1
- <?php
2
-
3
- function wpgmza_get_legacy_pro_shape_editor_dependencies() {
4
- $scriptLoader = new \WPGMZA\ScriptLoader();
5
- $handles = array_keys($scriptLoader->getPluginScripts());
6
-
7
- return $handles;
8
- }
9
-
10
- function wpgmza_convert_json_geometry_to_legacy_format($json) {
11
- $arr = array();
12
- if (is_array($json)) {
13
- foreach($json as $obj)
14
- $arr []= "{$obj->lat},{$obj->lng}";
15
- }
16
-
17
- return $arr;
18
- }
19
-
20
- function wpgmza_convert_shape_options_to_legacy_format($data) {
21
- // Convert new format colors to legacy format colors
22
- foreach($data as $key => $value) {
23
- if(preg_match('/color/', $key))
24
- $data->{$key} = preg_replace("/^#/", "", $value);
25
- }
26
-
27
- return $data;
28
- }
29
-
30
- if(!function_exists('wpgmza_get_marker_columns')) {
31
- function wpgmza_get_marker_columns() {
32
- global $wpdb;
33
- global $wpgmza;
34
- global $wpgmza_tblname;
35
- global $wpgmza_pro_version;
36
-
37
- $useSpatialData = empty($wpgmza_pro_version) || version_compare($wpgmza_pro_version, '7.0.0', '>=');
38
-
39
- $columns = $wpdb->get_col("SHOW COLUMNS FROM $wpgmza_tblname");
40
-
41
- if($useSpatialData)
42
- {
43
- if(($index = array_search('lat', $columns)) !== false)
44
- array_splice($columns, $index, 1);
45
- if(($index = array_search('lng', $columns)) !== false)
46
- array_splice($columns, $index, 1);
47
- }
48
-
49
- for($i = count($columns) - 1; $i >= 0; $i--)
50
- $columns[$i] = '`' . trim($columns[$i], '`') . '`';
51
-
52
- if($useSpatialData)
53
- {
54
- $columns[] = "{$wpgmza->spatialFunctionPrefix}X(latlng) AS lat";
55
- $columns[] = "{$wpgmza->spatialFunctionPrefix}Y(latlng) AS lng";
56
- }
57
-
58
- return $columns;
59
- }
60
- }
61
-
62
- /**
63
- * Render polygon editor HTML
64
- * @param integer $mid Map ID
65
- * @return string HTML outut
66
- */
67
- function wpgmza_b_pro_add_poly($mid) {
68
-
69
- global $wpgmza_tblname_maps;
70
- global $wpdb;
71
- if ($_GET['action'] == "add_poly" && isset($mid)) {
72
-
73
- if( function_exists('google_maps_api_key_warning' ) ){ google_maps_api_key_warning(); }
74
-
75
- $mid = sanitize_text_field($mid);
76
- $res = wpgmza_get_map_data($mid);
77
- echo "
78
-
79
-
80
-
81
-
82
- <div class='wrap'>
83
- <h1>WP Google Maps</h1>
84
- <div class='wide'>
85
-
86
- <h2>".__("Add a Polygon","wp-google-maps")."</h2>
87
- <form action='?page=wp-google-maps-menu&action=edit&map_id=".esc_attr($mid)."' method='post' id='wpgmaps_add_poly_form'>
88
- <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".esc_attr($mid)."' />
89
- <input type='hidden' name='wpgmaps_polygon-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_polygon-nonce' )."' />
90
-
91
- <table class='wpgmza-listing-comp' style='width:30%;float:left; height:400px;'>
92
- <tr>
93
- <td>".__("Name","wp-google-maps")."</td><td><input type=\"text\" value=\"\" name=\"poly_name\" placeholder='".__("Name","wp-google-maps")."'/></td>
94
- </tr>
95
- <tr>
96
- <td>".__("Title","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\" /><i class='wpgmza-info__small'><a href='".wpgm_pro_link("http://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&utm_medium=link&utm_campaign=polygons")."' title='".__("Pro Version","wp-google-maps")."'>".__("Get the Pro add-on","wp-google-maps")."</a></i></td>
97
- </tr>
98
- <tr>
99
- <td>".__("Link","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"Pro version only\" /></td>
100
- </tr>
101
- <tr>
102
- <td>".__("Line Color","wp-google-maps")."</td><td><input id=\"poly_line\" name=\"poly_line\" type=\"text\" class=\"color\" value=\"000000\" /></td>
103
- </tr>
104
- <tr>
105
- <td>".__("Line Opacity","wp-google-maps")."</td><td><input id=\"poly_line_opacity\" name=\"poly_line_opacity\" type=\"text\" value=\"0.5\" /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.5 for 50%</small></td>
106
- </tr>
107
- <tr>
108
- <td>".__("Fill Color","wp-google-maps")."</td><td><input id=\"poly_fill\" name=\"poly_fill\" type=\"text\" class=\"color\" value=\"66ff00\" /></td>
109
- </tr>
110
- <tr>
111
- <td>".__("Opacity","wp-google-maps")."</td><td><input id=\"poly_opacity\" name=\"poly_opacity\" type=\"text\" value=\"0.5\" /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.5 for 50%</small></td>
112
- </tr>
113
- <tr>
114
- <td>".__("On Hover Line Color","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\"/></td>
115
- </tr>
116
- <tr>
117
- <td>".__("On Hover Fill Color","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\"/></td>
118
- </tr>
119
- <tr>
120
- <td>".__("On Hover Opacity","wp-google-maps")."</td><td><input disabled type=\"text\"value=\"".__("Pro version only","wp-google-maps")."\" /></td>
121
- </tr>
122
-
123
-
124
- </table>
125
-
126
- <div class='wpgmza_map_seventy'>
127
- <div id=\"wpgmza_map\">&nbsp;</div>
128
-
129
- <p>
130
- <ul style=\"list-style:initial;\" class='update-nag update-blue update-slim update-map-overlay'>
131
-
132
- <li style=\"margin-left:30px;\">".__("Click on the map to insert a vertex.","wp-google-maps")."</li>
133
- <li style=\"margin-left:30px;\">".__("Click on a vertex to remove it.","wp-google-maps")."</li>
134
- <li style=\"margin-left:30px;\">".__("Drag a vertex to move it.","wp-google-maps")."</li>
135
- </ul>
136
- </p>
137
- </div>
138
-
139
- <div id='wpgmza-polygon-textarea' style='clear: both;'><label>Polygon data:</label><br /><textarea name=\"wpgmza_polygon\" id=\"poly_line_list\" style=\"width:90%; height:100px; border:1px solid #ccc; background-color:#FFF; padding:5px; overflow:auto;\"></textarea>
140
- </div>
141
- <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_save_poly' class='button-primary' value='".__("Save Polygon","wp-google-maps")." &raquo;' /></p>
142
-
143
- </form>
144
- </div>
145
- </div>
146
- ";
147
- }
148
- }
149
-
150
-
151
- /**
152
- * Render polygon editor HTML (edit mode)
153
- * @param integer $mid Map ID
154
- * @return string HTML outut
155
- */
156
- function wpgmza_b_pro_edit_poly($mid) {
157
- global $wpgmza_tblname_maps;
158
- global $wpdb;
159
-
160
- if ($_GET['action'] == "edit_poly" && isset($mid)) {
161
- $mid = sanitize_text_field($mid);;
162
- $res = wpgmza_get_map_data($mid);
163
- $pol = wpgmza_b_return_poly_options(sanitize_text_field($_GET['poly_id']));
164
-
165
- echo "
166
-
167
-
168
- <div class='wrap'>
169
- <h1>WP Google Maps</h1>
170
- <div class='wide'>
171
-
172
- <h2>".__("Edit Polygon","wp-google-maps")."</h2>
173
- <form action='?page=wp-google-maps-menu&action=edit&map_id=".esc_attr($mid)."' method='post' id='wpgmaps_edit_poly_form'>
174
- <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".esc_attr($mid)."' />
175
- <input type='hidden' name='wpgmaps_poly_id' id='wpgmaps_poly_id' value='".esc_attr(intval($_GET['poly_id']))."' />
176
- <input type='hidden' name='wpgmaps_polygon-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_polygon-nonce' )."' />
177
-
178
- <table class='wpgmza-listing-comp' style='width:30%;float:left; height:400px;'>
179
- <tr>
180
- <td>".__("Name","wp-google-maps")."</td><td><input type=\"text\" value=\"".esc_attr(stripslashes($pol->polyname))."\" name=\"poly_name\" /></td>
181
- </tr>
182
- <tr>
183
- <td>".__("Title","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\" /><i><a href='".wpgm_pro_link("http://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&utm_medium=link&utm_campaign=polygons")."' title='".__("Pro Version","wp-google-maps")."'>".__("Get the Pro add-on","wp-google-maps")."</a></i></td>
184
- </tr>
185
- <tr>
186
- <td>".__("Description","wp-google-maps")."</td><td><textarea disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\"></textarea><i><a href='".wpgm_pro_link("http://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&utm_medium=link&utm_campaign=polygons")."' title='".__("Pro Version","wp-google-maps")."'>".__("Get the Pro add-on","wp-google-maps")."</a></i></td>
187
- </tr>
188
- <tr>
189
- <td>".__("Link","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"pro version only\" /></td>
190
- </tr>
191
- <tr>
192
- <td>".__("Line Color","wp-google-maps")."</td><td><input id=\"poly_line\" name=\"poly_line\" type=\"text\" class=\"color\" value=\"".esc_attr($pol->linecolor)."\" /></td>
193
- </tr>
194
- <tr>
195
- <td>".__("Line Opacity","wp-google-maps")."</td><td><input id=\"poly_line_opacity\" name=\"poly_line_opacity\" type=\"text\" value=\"".esc_attr($pol->lineopacity)."\" /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.5 for 50%</small></td>
196
- </tr>
197
- <tr>
198
- <td>".__("Fill Color","wp-google-maps")."</td><td><input id=\"poly_fill\" name=\"poly_fill\" type=\"text\" class=\"color\" value=\"".esc_attr($pol->fillcolor)."\" /></td>
199
- </tr>
200
- <tr>
201
- <td>".__("Opacity","wp-google-maps")."</td><td><input id=\"poly_opacity\" name=\"poly_opacity\" type=\"text\" value=\"".esc_attr($pol->opacity)."\" /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.5 for 50%</small></td>
202
- </tr>
203
- <tr>
204
- <td>".__("On Hover Line Color","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\"/></td>
205
- </tr>
206
- <tr>
207
- <td>".__("On Hover Fill Color","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\"/></td>
208
- </tr>
209
- <tr>
210
- <td>".__("On Hover Opacity","wp-google-maps")."</td><td><input disabled type=\"text\"value=\"".__("Pro version only","wp-google-maps")."\" /></td>
211
- </tr>
212
- <tr>
213
- <td>".__("Show Polygon","wp-google-maps")."</td>
214
- <td>
215
- <button id='fit-bounds-to-shape'
216
- class='button button-secondary'
217
- type='button'
218
- title='" . __('Fit map bounds to shape', 'wp-google-maps') . "'
219
- data-fit-bounds-to-shape='poly'>
220
- <i class='fas fa-eye'></i>
221
- </button>
222
- </td>
223
- </tr>
224
- </table>
225
-
226
- <div class='wpgmza_map_seventy'>
227
- <div id=\"wpgmza_map\" >&nbsp;</div>
228
- <p>
229
- <ul style=\"list-style:initial;\" class='update-nag update-blue update-slim update-map-overlay'>
230
-
231
- <li style=\"margin-left:30px;\">Click on the map to insert a vertex.</li>
232
- <li style=\"margin-left:30px;\">Click on a vertex to remove it.</li>
233
- <li style=\"margin-left:30px;\">Drag a vertex to move it.</li>
234
- </ul>
235
- </p>
236
- </div>
237
-
238
- <div class='clear'></div>
239
- <p style='clear: both;' >Polygon data:<br /><textarea name=\"wpgmza_polygon\" id=\"poly_line_list\" style=\"height:100px; background-color:#FFF; padding:5px; overflow:auto;\"></textarea>
240
- <!-- <p style='clear: both;' >Polygon data (inner):<br /><textarea name=\"wpgmza_polygon_inner\" id=\"poly_line_list_inner\" style=\"width:90%; height:100px; border:1px solid #ccc; background-color:#FFF; padding:5px; overflow:auto;\">".esc_textarea($pol->innerpolydata)."</textarea> -->
241
- <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_edit_poly' class='button-primary' value='".__("Save Polygon","wp-google-maps")." &raquo;' /></p>
242
-
243
- </form>
244
- </div>
245
-
246
-
247
- </div>
248
-
249
-
250
-
251
- ";
252
-
253
- }
254
-
255
-
256
-
257
- }
258
-
259
- /**
260
- * Render polygons JS
261
- *
262
- * @todo This needs to be converted to a native JS file with localized variables
263
- *
264
- * @param integer $mapid Map ID
265
- *
266
- * @return void
267
- */
268
- function wpgmaps_b_admin_add_poly_javascript($mapid)
269
- {
270
- $res = wpgmza_get_map_data(sanitize_text_field($_GET['map_id']));
271
- $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
272
-
273
-
274
- $wpgmza_lat = $res->map_start_lat;
275
- $wpgmza_lng = $res->map_start_lng;
276
- $wpgmza_map_type = $res->type;
277
- $wpgmza_width = $res->map_width;
278
- $wpgmza_height = $res->map_height;
279
- $wpgmza_width_type = $res->map_width_type;
280
- $wpgmza_height_type = $res->map_height_type;
281
- if (!$wpgmza_map_type || $wpgmza_map_type == "" || $wpgmza_map_type == "1") { $wpgmza_map_type = "ROADMAP"; }
282
- else if ($wpgmza_map_type == "2") { $wpgmza_map_type = "SATELLITE"; }
283
- else if ($wpgmza_map_type == "3") { $wpgmza_map_type = "HYBRID"; }
284
- else if ($wpgmza_map_type == "4") { $wpgmza_map_type = "TERRAIN"; }
285
- else { $wpgmza_map_type = "ROADMAP"; }
286
- $start_zoom = $res->map_start_zoom;
287
- if ($start_zoom < 1 || !$start_zoom) {
288
- $start_zoom = 5;
289
- }
290
-
291
- if (isset($res->kml)) { $kml = $res->kml; } else { $kml = false; }
292
-
293
- $localized_data = array(
294
- 'wpgmza_lat' => $wpgmza_lat,
295
- 'wpgmza_lng' => $wpgmza_lng,
296
- 'start_zoom' => $start_zoom,
297
- 'wpgmza_width' => $wpgmza_width,
298
- 'wpgmza_width_type' => $wpgmza_width_type,
299
- 'wpgmza_height' => $wpgmza_height,
300
- 'wpgmza_height_type' => $wpgmza_height_type,
301
- 'wpgmza_map_type' => $wpgmza_map_type,
302
- 'polygon_data' => array()
303
- );
304
-
305
- $total_poly_array = wpgmza_b_return_polygon_id_array(sanitize_text_field($_GET['map_id']));
306
-
307
- foreach ($total_poly_array as $poly_id)
308
- {
309
- $polyoptions = wpgmza_b_return_poly_options($poly_id);
310
- $linecolor = $polyoptions->linecolor;
311
- $fillcolor = $polyoptions->fillcolor;
312
- $fillopacity = $polyoptions->opacity;
313
- $lineopacity = $polyoptions->lineopacity;
314
- $title = $polyoptions->title;
315
- $link = $polyoptions->link;
316
- $ohlinecolor = $polyoptions->ohlinecolor;
317
- $ohfillcolor = $polyoptions->ohfillcolor;
318
- $ohopacity = $polyoptions->ohopacity;
319
- if (!$linecolor) { $linecolor = "000000"; }
320
- if (!$fillcolor) { $fillcolor = "66FF00"; }
321
- if ($fillopacity == "") { $fillopacity = "0.5"; }
322
- if ($lineopacity == "") { $lineopacity = "1.0"; }
323
- if ($ohlinecolor == "") { $ohlinecolor = $linecolor; }
324
- if ($ohfillcolor == "") { $ohfillcolor = $fillcolor; }
325
- if ($ohopacity == "") { $ohopacity = $fillopacity; }
326
- $linecolor = "#".$linecolor;
327
- $fillcolor = "#".$fillcolor;
328
- $ohlinecolor = "#".$ohlinecolor;
329
- $ohfillcolor = "#".$ohfillcolor;
330
-
331
- $poly_array = wpgmza_b_return_polygon_array($poly_id);
332
- $path_data = array();
333
-
334
- foreach($poly_array as $single_poly)
335
- {
336
- $poly_data_raw = str_replace(" ","",$single_poly);
337
- $poly_data_raw = explode(",",$poly_data_raw);
338
- $lat = $poly_data_raw[0];
339
- $lng = $poly_data_raw[1];
340
-
341
- $path_data[] = array(
342
- 'lat' => $lat,
343
- 'lng' => $lng
344
- );
345
- }
346
-
347
- $localized_data['polygon_data'][$poly_id] = array(
348
- 'strokeColor' => $linecolor,
349
- 'fillOpacity' => $fillopacity,
350
- 'strokeOpacity' => $lineopacity,
351
- 'fillColor' => $fillcolor,
352
- 'path' => $path_data
353
- );
354
- }
355
-
356
- $dependencies = wpgmza_get_legacy_pro_shape_editor_dependencies();
357
-
358
- wp_enqueue_style('wpgooglemaps-css', wpgmaps_get_plugin_url() . 'css/wpgmza_style.css');
359
- wp_enqueue_script('wpgmza-legacy-polygon-panel', wpgmaps_get_plugin_url() . 'js/legacy/legacy-polygon-panel.js', $dependencies);
360
- wp_localize_script('wpgmza-legacy-polygon-panel', 'wpgmza_legacy_polygon_panel_vars', $localized_data);
361
- }
362
-
363
- /**
364
- * Render polygon edit JS
365
- *
366
- * @todo This needs to be converted to a native JS file with localized variables
367
- *
368
- * @param integer $mapid Map ID
369
- * @param integer $polyid Polygon ID
370
- *
371
- * @return void
372
- */
373
- function wpgmaps_b_admin_edit_poly_javascript($mapid,$polyid)
374
- {
375
- $res = wpgmza_get_map_data($mapid);
376
- $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
377
- $wpgmza_lat = $res->map_start_lat;
378
- $wpgmza_lng = $res->map_start_lng;
379
- $wpgmza_map_type = $res->type;
380
- $wpgmza_width = $res->map_width;
381
- $wpgmza_height = $res->map_height;
382
- $wpgmza_width_type = $res->map_width_type;
383
- $wpgmza_height_type = $res->map_height_type;
384
-
385
- if (!$wpgmza_map_type || $wpgmza_map_type == "" || $wpgmza_map_type == "1") { $wpgmza_map_type = "ROADMAP"; }
386
- else if ($wpgmza_map_type == "2") { $wpgmza_map_type = "SATELLITE"; }
387
- else if ($wpgmza_map_type == "3") { $wpgmza_map_type = "HYBRID"; }
388
- else if ($wpgmza_map_type == "4") { $wpgmza_map_type = "TERRAIN"; }
389
- else { $wpgmza_map_type = "ROADMAP"; }
390
- $start_zoom = $res->map_start_zoom;
391
- if ($start_zoom < 1 || !$start_zoom) {
392
- $start_zoom = 5;
393
- }
394
- if (isset($res->kml)) { $kml = $res->kml; } else { $kml = false; }
395
-
396
- $localized_data = array(
397
- 'wpgmza_lat' => $wpgmza_lat,
398
- 'wpgmza_lng' => $wpgmza_lng,
399
- 'start_zoom' => $start_zoom,
400
- 'wpgmza_width' => $wpgmza_width,
401
- 'wpgmza_width_type' => $wpgmza_width_type,
402
- 'wpgmza_height' => $wpgmza_height,
403
- 'wpgmza_height_type' => $wpgmza_height_type,
404
- 'wpgmza_map_type' => $wpgmza_map_type,
405
- 'polygon_data' => array()
406
- );
407
-
408
- $total_poly_array = wpgmza_b_return_polygon_id_array(sanitize_text_field($_GET['map_id']));
409
-
410
- foreach ($total_poly_array as $poly_id)
411
- {
412
- $polyoptions = wpgmza_b_return_poly_options($poly_id);
413
- $linecolor = $polyoptions->linecolor;
414
- $fillcolor = $polyoptions->fillcolor;
415
- $fillopacity = $polyoptions->opacity;
416
- $lineopacity = $polyoptions->lineopacity;
417
- $title = $polyoptions->title;
418
- $link = $polyoptions->link;
419
- $ohlinecolor = $polyoptions->ohlinecolor;
420
- $ohfillcolor = $polyoptions->ohfillcolor;
421
- $ohopacity = $polyoptions->ohopacity;
422
- if (!$linecolor) { $linecolor = "000000"; }
423
- if (!$fillcolor) { $fillcolor = "66FF00"; }
424
- if ($fillopacity == "") { $fillopacity = "0.5"; }
425
- if ($lineopacity == "") { $lineopacity = "1.0"; }
426
- if ($ohlinecolor == "") { $ohlinecolor = $linecolor; }
427
- if ($ohfillcolor == "") { $ohfillcolor = $fillcolor; }
428
- if ($ohopacity == "") { $ohopacity = $fillopacity; }
429
- $linecolor = "#".$linecolor;
430
- $fillcolor = "#".$fillcolor;
431
- $ohlinecolor = "#".$ohlinecolor;
432
- $ohfillcolor = "#".$ohfillcolor;
433
-
434
- $poly_array = wpgmza_b_return_polygon_array($poly_id);
435
- $path_data = array();
436
-
437
- foreach($poly_array as $single_poly)
438
- {
439
- $poly_data_raw = str_replace(" ","",$single_poly);
440
- $poly_data_raw = explode(",",$poly_data_raw);
441
- $lat = $poly_data_raw[0];
442
- $lng = $poly_data_raw[1];
443
-
444
- $path_data[] = array(
445
- 'lat' => $lat,
446
- 'lng' => $lng
447
- );
448
- }
449
-
450
- $localized_data['polygon_data'][$poly_id] = array(
451
- 'storkeColor' => $linecolor,
452
- 'fillOpacity' => $fillopacity,
453
- 'strokeOpacity' => $lineopacity,
454
- 'fillColor' => $fillcolor,
455
- 'path' => $path_data
456
- );
457
- }
458
-
459
- $dependencies = wpgmza_get_legacy_pro_shape_editor_dependencies();
460
-
461
- wp_enqueue_style('wpgooglemaps-css', wpgmaps_get_plugin_url() . 'css/wpgmza_style.css');
462
- wp_enqueue_script('wpgmza-legacy-polygon-panel', wpgmaps_get_plugin_url() . 'js/legacy/legacy-polygon-panel.js', $dependencies);
463
- wp_localize_script('wpgmza-legacy-polygon-panel', 'wpgmza_legacy_polygon_panel_vars', $localized_data);
464
- }
465
-
466
- /**
467
- * Returns the list of polygons displayed in the map editor
468
- *
469
- * @todo Build this as a hook or filter instead of a function call
470
- *
471
- * @param integer $map_id Map ID
472
- * @param boolean $admin Identify if user is admin or not
473
- * @param string $width Width to be used for HTML output
474
- * @return string List HTML
475
- */
476
- function wpgmza_b_return_polygon_list($map_id,$admin = true,$width = "100%") {
477
- wpgmaps_debugger("return_marker_start");
478
-
479
- global $wpdb;
480
- global $wpgmza_tblname_poly;
481
- $wpgmza_tmp = "";
482
-
483
- $results = $wpdb->get_results( $wpdb->prepare("SELECT * FROM $wpgmza_tblname_poly WHERE `map_id` = %d ORDER BY `id` DESC", intval($map_id)) );
484
-
485
- $wpgmza_tmp .= "
486
-
487
- <table id=\"wpgmza_table_poly\" class=\"display\" cellspacing=\"0\" cellpadding=\"0\" style=\"width:$width;\">
488
- <thead>
489
- <tr>
490
- <th align='left'><strong>".__("ID","wp-google-maps")."</strong></th>
491
- <th align='left'><strong>".__("Name","wp-google-maps")."</strong></th>
492
- <th align='left' style='width:182px;'><strong>".__("Action","wp-google-maps")."</strong></th>
493
- </tr>
494
- </thead>
495
- <tbody>
496
- ";
497
- $res = wpgmza_get_map_data($map_id);
498
- $default_marker = "<img src='".$res->default_marker."' />";
499
-
500
- //$wpgmza_data = get_option('WPGMZA');
501
- //if ($wpgmza_data['map_default_marker']) { $default_icon = "<img src='".$wpgmza_data['map_default_marker']."' />"; } else { $default_icon = "<img src='".wpgmaps_get_plugin_url()."/images/marker.png' />"; }
502
-
503
- foreach ( $results as $result ) {
504
- unset($poly_data);
505
- unset($poly_array);
506
- $poly_data = '';
507
- $poly_array = wpgmza_b_return_polygon_array($result->id);
508
- if (is_array($poly_array)) {
509
- foreach ($poly_array as $poly_single) {
510
- $poly_data .= $poly_single.",";
511
- }
512
- }
513
- if (isset($result->polyname) && $result->polyname != "") { $polygon_name = $result->polyname; } else { $polygon_name = "Polygon".$result->id; }
514
-
515
- $wpgmza_tmp .= "
516
- <tr id=\"wpgmza_poly_tr_".intval($result->id)."\">
517
- <td height=\"40\">".intval($result->id)."</td>
518
- <td height=\"40\">".esc_attr(stripslashes($polygon_name))."</td>
519
- <td width='170' align='left'>
520
- <a href=\"".esc_url(get_option('siteurl'))."/wp-admin/admin.php?page=wp-google-maps-menu&action=edit_poly&map_id=".intval($map_id)."&poly_id=".intval($result->id)."\" title=\"".__("Edit","wp-google-maps")."\" class=\"wpgmza_edit_poly_btn button\" id=\"".intval($result->id)."\"><i class=\"fa fa-edit\"> </i></a>
521
- <a href=\"javascript:void(0);\" title=\"".__("Delete this polygon","wp-google-maps")."\" class=\"wpgmza_poly_del_btn button\" id=\"".intval($result->id)."\"><i class=\"fa fa-times\"> </i></a>
522
- </td>
523
- </tr>";
524
-
525
- }
526
- $wpgmza_tmp .= "</tbody></table>";
527
-
528
-
529
- return $wpgmza_tmp;
530
-
531
- }
532
-
533
- /**
534
- * Retrieve polygon options from DB
535
- *
536
- * @param integer $poly_id Polygon ID
537
- * @return array MYSQL Array
538
- */
539
- function wpgmza_b_return_poly_options($poly_id) {
540
- global $wpdb;
541
- global $wpgmza_tblname_poly;
542
-
543
- $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_poly WHERE `id` = %d LIMIT 1",intval($poly_id)) );
544
-
545
- if(empty($results))
546
- return;
547
-
548
- $data = $results[0];
549
-
550
- return wpgmza_convert_shape_options_to_legacy_format($data);
551
- }
552
-
553
- /**
554
- * Return the polygon data in the correct format
555
- *
556
- * @param integer $poly_id Polygon ID
557
- * @return array Poly data array
558
- */
559
- function wpgmza_b_return_polygon_array($poly_id) {
560
- global $wpdb;
561
- global $wpgmza_tblname_poly;
562
-
563
- $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_poly WHERE `id` = %d LIMIT 1",intval($poly_id)) );
564
-
565
- if(empty($results))
566
- return null;
567
-
568
- $polyline = $results[0];
569
- $polydata = $polyline->polydata;
570
-
571
- if(($json = json_decode($polydata)) !== false)
572
- return wpgmza_convert_json_geometry_to_legacy_format($json);
573
-
574
- $regex = '/-?(\d+)(\.\d+)?,\s*-?(\d+)(\.\d+)?/';
575
-
576
- if(!preg_match_all($regex, $polydata, $m))
577
- return array();
578
-
579
- return $m[0];
580
- }
581
-
582
- /**
583
- * Return polygon ID array
584
- *
585
- * This is used when creating the JSON array of all the polygons and their unique options
586
- *
587
- * @param integer $map_id Map ID
588
- * @return array Array of IDs
589
- */
590
- function wpgmza_b_return_polygon_id_array($map_id) {
591
- global $wpdb;
592
- global $wpgmza_tblname_poly;
593
- $ret = array();
594
- $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_poly WHERE `map_id` = %d",intval($map_id)) );
595
- foreach ( $results as $result ) {
596
- $current_id = $result->id;
597
- $ret[] = $current_id;
598
-
599
- }
600
- return $ret;
601
- }
602
-
603
- function wpgmza_b_pro_add_polyline($mid) {
604
- global $wpgmza_tblname_maps;
605
- global $wpdb;
606
- if ($_GET['action'] == "add_polyline" && isset($mid)) {
607
-
608
- if( function_exists('google_maps_api_key_warning' ) ){ google_maps_api_key_warning(); }
609
-
610
- $res = wpgmza_get_map_data($mid);
611
- echo "
612
-
613
-
614
-
615
-
616
- <div class='wrap'>
617
- <h1>WP Google Maps</h1>
618
- <div class='wide'>
619
-
620
- <h2>".__("Add a Polyline","wp-google-maps")."</h2>
621
- <form action='?page=wp-google-maps-menu&action=edit&map_id=".intval($mid)."' method='post' id='wpgmaps_add_polyline_form'>
622
- <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".intval($mid)."' />
623
- <input type='hidden' name='wpgmaps_polyline-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_polyline-nonce' )."' />
624
- <table class='wpgmza-listing-comp' style='width:30%;float:left;'>
625
- <tr>
626
- <td>
627
- ".__("Name","wp-google-maps")."
628
- </td>
629
- <td>
630
- <input id=\"poly_name\" name=\"poly_name\" type=\"text\" value=\"\" />
631
- </td>
632
- </tr>
633
- <tr>
634
- <td>
635
- ".__("Line Color","wp-google-maps")."
636
- </td>
637
- <td>
638
- <input id=\"poly_line\" name=\"poly_line\" type=\"text\" class=\"color\" value=\"000000\" />
639
- </td>
640
- </tr>
641
- <tr>
642
- <td>
643
- ".__("Opacity","wp-google-maps")."
644
- </td>
645
- <td>
646
- <input id=\"poly_opacity\" name=\"poly_opacity\" type=\"text\" value=\"0.8\" /> (0 - 1.0) example: 0.8 for 80%
647
- </td>
648
- </tr>
649
- <tr>
650
- <td>
651
- ".__("Line Thickness","wp-google-maps")."
652
- </td>
653
- <td>
654
- <input id=\"poly_thickness\" name=\"poly_thickness\" type=\"text\" value=\"4\" /> (0 - 50) example: 4
655
- </td>
656
-
657
- </tr>
658
-
659
-
660
-
661
- </table>
662
- <div class='wpgmza_map_seventy'>
663
- <div id=\"wpgmza_map\">&nbsp;</div>
664
- <p>
665
-
666
- <ul style=\"list-style:initial;\" class='update-nag update-blue update-slim update-map-overlay'>
667
-
668
- <li style=\"margin-left:30px;\">Click on the map to insert a vertex.</li>
669
- <li style=\"margin-left:30px;\">Click on a vertex to remove it.</li>
670
- <li style=\"margin-left:30px;\">Drag a vertex to move it.</li>
671
- </ul>
672
- </p>
673
- </div>
674
-
675
-
676
- <p style='clear: both;'>Polyline data:<br /><textarea name=\"wpgmza_polyline\" id=\"poly_line_list\" style=\" height:100px; background-color:#FFF; padding:5px; overflow:auto;\"></textarea>
677
- <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_save_polyline' class='button-primary' value='".__("Save Polyline","wp-google-maps")." &raquo;' /></p>
678
-
679
- </form>
680
- </div>
681
-
682
-
683
- </div>
684
-
685
-
686
-
687
- ";
688
-
689
- }
690
-
691
-
692
-
693
- }
694
-
695
-
696
- /**
697
- * Render polyline editor HTML (edit mode)
698
- * @param integer $mid Map ID
699
- * @return string HTML outut
700
- */
701
- function wpgmza_b_pro_edit_polyline($mid) {
702
- global $wpgmza_tblname_maps;
703
- global $wpdb;
704
- if ($_GET['action'] == "edit_polyline" && isset($mid)) {
705
- $res = wpgmza_get_map_data($mid);
706
- $pol = wpgmza_b_return_polyline_options(sanitize_text_field($_GET['poly_id']));
707
-
708
- $pol->polydata = esc_textarea($pol->polydata);
709
-
710
- echo "
711
-
712
-
713
- <div class='wrap'>
714
- <h1>WP Google Maps</h1>
715
- <div class='wide'>
716
-
717
- <h2>".__("Edit Polyline","wp-google-maps")."</h2>
718
- <form action='?page=wp-google-maps-menu&action=edit&map_id=".esc_attr($mid)."' method='post' id='wpgmaps_edit_poly_form'>
719
- <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".esc_attr($mid)."' />
720
- <input type='hidden' name='wpgmaps_poly_id' id='wpgmaps_poly_id' value='".esc_attr(intval($_GET['poly_id']))."' />
721
- <input type='hidden' name='wpgmaps_polyline-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_polyline-nonce' )."' />
722
- <table class='wpgmza-listing-comp' style='width:30%;float:left;'>
723
- <tr>
724
- <td>
725
- ".__("Name","wp-google-maps")."
726
- </td>
727
- <td>
728
- <input id=\"poly_name\" name=\"poly_name\" type=\"text\" value=\"".esc_attr(stripslashes($pol->polyname))."\" />
729
- </td>
730
- </tr>
731
- <tr>
732
- <td>
733
- ".__("Line Color","wp-google-maps")."
734
- </td>
735
- <td>
736
- <input id=\"poly_line\" name=\"poly_line\" type=\"text\" class=\"color\" value=\"".esc_attr($pol->linecolor)."\" />
737
- </td>
738
- </tr>
739
- <tr>
740
- <td>
741
- ".__("Opacity","wp-google-maps")."
742
- </td>
743
- <td>
744
- <input id=\"poly_opacity\" name=\"poly_opacity\" type=\"text\" value=\"".esc_attr($pol->opacity)."\" /> (0 - 1.0) example: 0.8 for 80%
745
- </td>
746
- </tr>
747
- <tr>
748
- <td>
749
- ".__("Line Thickness","wp-google-maps")."
750
- </td>
751
- <td>
752
- <input id=\"poly_thickness\" name=\"poly_thickness\" type=\"text\" value=\"".esc_attr($pol->linethickness)."\" /> (0 - 50) example: 4
753
- </td>
754
- </tr>
755
-
756
- <tr>
757
-
758
- <td>
759
- ".__('Show Polyline', 'wp-google-maps')."
760
- </td>
761
- <td>
762
- <button id='fit-bounds-to-shape'
763
- class='button button-secondary'
764
- type='button'
765
- title='" . __('Fit map bounds to shape', 'wp-google-maps') . "'
766
- data-fit-bounds-to-shape='poly'>
767
- <i class='fas fa-eye'></i>
768
- </button>
769
- </td>
770
-
771
- </tr>
772
-
773
- </table>
774
- <div class='wpgmza_map_seventy'>
775
- <div id=\"wpgmza_map\">&nbsp;</div>
776
- <p>
777
- <ul style=\"list-style:initial;\" class='update-nag update-blue update-slim update-map-overlay'>
778
-
779
- <li style=\"margin-left:30px;\">Click on the map to insert a vertex.</li>
780
- <li style=\"margin-left:30px;\">Click on a vertex to remove it.</li>
781
- <li style=\"margin-left:30px;\">Drag a vertex to move it.</li>
782
- </ul>
783
- </p>
784
- </div>
785
-
786
- <p style='clear: both;'>Polyline data:<br /><textarea name=\"wpgmza_polyline\" id=\"poly_line_list\" style=\"height:100px; background-color:#FFF; padding:5px; overflow:auto;\">{$pol->polydata}</textarea>
787
- <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_edit_polyline' class='button-primary' value='".__("Save Polyline","wp-google-maps")." &raquo;' /></p>
788
-
789
- </form>
790
- </div>
791
-
792
-
793
- </div>
794
-
795
-
796
-
797
- ";
798
-
799
- }
800
-
801
-
802
-
803
- }
804
- /**
805
- * Render polyline JS
806
- *
807
- * @todo This needs to be converted to a native JS file with localized variables
808
- *
809
- * @param integer $mapid Map ID
810
- *
811
- * @return void
812
- */
813
- function wpgmaps_b_admin_add_polyline_javascript($mapid)
814
- {
815
- $res = wpgmza_get_map_data(sanitize_text_field($_GET['map_id']));
816
- $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
817
-
818
-
819
- $wpgmza_lat = $res->map_start_lat;
820
- $wpgmza_lng = $res->map_start_lng;
821
- $wpgmza_map_type = $res->type;
822
- $wpgmza_width = $res->map_width;
823
- $wpgmza_height = $res->map_height;
824
- $wpgmza_width_type = $res->map_width_type;
825
- $wpgmza_height_type = $res->map_height_type;
826
- if (!$wpgmza_map_type || $wpgmza_map_type == "" || $wpgmza_map_type == "1") { $wpgmza_map_type = "ROADMAP"; }
827
- else if ($wpgmza_map_type == "2") { $wpgmza_map_type = "SATELLITE"; }
828
- else if ($wpgmza_map_type == "3") { $wpgmza_map_type = "HYBRID"; }
829
- else if ($wpgmza_map_type == "4") { $wpgmza_map_type = "TERRAIN"; }
830
- else { $wpgmza_map_type = "ROADMAP"; }
831
- $start_zoom = $res->map_start_zoom;
832
- if ($start_zoom < 1 || !$start_zoom) {
833
- $start_zoom = 5;
834
- }
835
- if (isset($res->kml)) { $kml = $res->kml; } else { $kml = false; }
836
-
837
- $localized_data = array(
838
- 'wpgmza_lat' => $wpgmza_lat,
839
- 'wpgmza_lng' => $wpgmza_lng,
840
- 'start_zoom' => $start_zoom,
841
- 'wpgmza_width' => $wpgmza_width,
842
- 'wpgmza_width_type' => $wpgmza_width_type,
843
- 'wpgmza_height' => $wpgmza_height,
844
- 'wpgmza_height_type' => $wpgmza_height_type,
845
- 'wpgmza_map_type' => $wpgmza_map_type,
846
- 'polygon_data' => array()
847
- );
848
-
849
- $total_poly_array = wpgmza_b_return_polyline_id_array(sanitize_text_field($_GET['map_id']));
850
-
851
- foreach ($total_poly_array as $poly_id)
852
- {
853
- $polyoptions = wpgmza_b_return_polyline_options($poly_id);
854
- $linecolor = $polyoptions->linecolor;
855
- $lineopacity = $polyoptions->opacity;
856
-
857
- if (!$linecolor) { $linecolor = "000000"; }
858
- if ($lineopacity == "") { $lineopacity = "1.0"; }
859
-
860
- $linecolor = "#".$linecolor;
861
- $poly_array = wpgmza_b_return_polyline_array($poly_id);
862
- $path_data = array();
863
-
864
- foreach($poly_array as $single_poly)
865
- {
866
- $poly_data_raw = str_replace(" ","",$single_poly);
867
- $poly_data_raw = explode(",",$poly_data_raw);
868
- $lat = $poly_data_raw[0];
869
- $lng = $poly_data_raw[1];
870
-
871
- $path_data[] = array(
872
- 'lat' => $lat,
873
- 'lng' => $lng
874
- );
875
- }
876
-
877
- $localized_data['polyline_data'][$poly_id] = array(
878
- 'strokeColor' => $linecolor,
879
- 'strokeOpacity' => $lineopacity,
880
- 'path' => $path_data
881
- );
882
- }
883
-
884
- $dependencies = wpgmza_get_legacy_pro_shape_editor_dependencies();
885
-
886
- wp_enqueue_style('wpgooglemaps-css', wpgmaps_get_plugin_url() . 'css/wpgmza_style.css');
887
- wp_enqueue_script('wpgmza-legacy-polyline-panel', wpgmaps_get_plugin_url() . 'js/legacy/legacy-polyline-panel.js', $dependencies);
888
- wp_localize_script('wpgmza-legacy-polyline-panel', 'wpgmza_legacy_polyline_panel_vars', $localized_data);
889
- }
890
-
891
- /**
892
- * Render polyline edit JS
893
- *
894
- * @todo This needs to be converted to a native JS file with localized variables
895
- *
896
- * @param integer $mapid Map ID
897
- * @param integer $polyid Polygon ID
898
- *
899
- * @return void
900
- */
901
- function wpgmaps_b_admin_edit_polyline_javascript($mapid,$polyid) {
902
- $res = wpgmza_get_map_data($mapid);
903
-
904
- $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
905
-
906
-
907
- $wpgmza_lat = $res->map_start_lat;
908
-
909
- $wpgmza_lng = $res->map_start_lng;
910
- $wpgmza_map_type = $res->type;
911
- $wpgmza_width = $res->map_width;
912
- $wpgmza_height = $res->map_height;
913
- $wpgmza_width_type = $res->map_width_type;
914
- $wpgmza_height_type = $res->map_height_type;
915
- if (!$wpgmza_map_type || $wpgmza_map_type == "" || $wpgmza_map_type == "1") { $wpgmza_map_type = "ROADMAP"; }
916
- else if ($wpgmza_map_type == "2") { $wpgmza_map_type = "SATELLITE"; }
917
- else if ($wpgmza_map_type == "3") { $wpgmza_map_type = "HYBRID"; }
918
- else if ($wpgmza_map_type == "4") { $wpgmza_map_type = "TERRAIN"; }
919
- else { $wpgmza_map_type = "ROADMAP"; }
920
- $start_zoom = $res->map_start_zoom;
921
- if ($start_zoom < 1 || !$start_zoom) {
922
- $start_zoom = 5;
923
- }
924
- if (isset($res->kml)) { $kml = $res->kml; } else { $kml = false; }
925
-
926
- $localized_data = array(
927
- 'wpgmza_lat' => $wpgmza_lat,
928
- 'wpgmza_lng' => $wpgmza_lng,
929
- 'start_zoom' => $start_zoom,
930
- 'wpgmza_width' => $wpgmza_width,
931
- 'wpgmza_width_type' => $wpgmza_width_type,
932
- 'wpgmza_height' => $wpgmza_height,
933
- 'wpgmza_height_type' => $wpgmza_height_type,
934
- 'wpgmza_map_type' => $wpgmza_map_type,
935
- 'polygon_data' => array()
936
- );
937
-
938
- $total_poly_array = wpgmza_b_return_polyline_id_array(sanitize_text_field($_GET['map_id']));
939
-
940
- foreach ($total_poly_array as $poly_id)
941
- {
942
-
943
-
944
- $polyoptions = wpgmza_b_return_polyline_options($poly_id);
945
-
946
- $linecolor = $polyoptions->linecolor;
947
- $lineopacity = $polyoptions->opacity;
948
-
949
- if (!$linecolor) { $linecolor = "000000"; }
950
- if ($lineopacity == "") { $lineopacity = "1.0"; }
951
-
952
- $linecolor = "#".$linecolor;
953
- $poly_array = wpgmza_b_return_polyline_array($poly_id);
954
- $path_data = array();
955
-
956
- foreach($poly_array as $single_poly)
957
- {
958
- $poly_data_raw = str_replace(" ","",$single_poly);
959
- $poly_data_raw = explode(",",$poly_data_raw);
960
- $lat = $poly_data_raw[0];
961
- $lng = $poly_data_raw[1];
962
-
963
- $path_data[] = array(
964
- 'lat' => $lat,
965
- 'lng' => $lng
966
- );
967
- }
968
-
969
- $localized_data['polyline_data'][$poly_id] = array(
970
- 'strokeColor' => $linecolor,
971
- 'strokeOpacity' => $lineopacity,
972
- 'path' => $path_data
973
- );
974
- }
975
-
976
- $dependencies = wpgmza_get_legacy_pro_shape_editor_dependencies();
977
-
978
- wp_enqueue_style('wpgooglemaps-css', wpgmaps_get_plugin_url() . 'css/wpgmza_style.css');
979
- wp_enqueue_script('wpgmza-legacy-polyline-panel', wpgmaps_get_plugin_url() . 'js/legacy/legacy-polyline-panel.js', $dependencies);
980
- wp_localize_script('wpgmza-legacy-polyline-panel', 'wpgmza_legacy_polyline_panel_vars', $localized_data);
981
- }
982
- /**
983
- * Returns the list of polylines displayed in the map editor
984
- *
985
- * @todo Build this as a hook or filter instead of a function call
986
- *
987
- * @param integer $map_id Map ID
988
- * @param boolean $admin Identify if user is admin or not
989
- * @param string $width Width to be used for HTML output
990
- * @return string List HTML
991
- */
992
- function wpgmza_b_return_polyline_list($map_id,$admin = true,$width = "100%") {
993
- wpgmaps_debugger("return_marker_start");
994
-
995
- global $wpdb;
996
- global $wpgmza_tblname_polylines;
997
- $wpgmza_tmp = "";
998
-
999
- $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_polylines WHERE `map_id` = %d ORDER BY `id` DESC",intval($map_id)) );
1000
-
1001
- $wpgmza_tmp .= "
1002
-
1003
- <table id=\"wpgmza_table_polyline\" class=\"display\" cellspacing=\"0\" cellpadding=\"0\" style=\"width:$width;\">
1004
- <thead>
1005
- <tr>
1006
- <th align='left'><strong>".__("ID","wp-google-maps")."</strong></th>
1007
- <th align='left'><strong>".__("Name","wp-google-maps")."</strong></th>
1008
- <th align='left' style='width:182px;'><strong>".__("Action","wp-google-maps")."</strong></th>
1009
- </tr>
1010
- </thead>
1011
- <tbody>
1012
- ";
1013
- $res = wpgmza_get_map_data($map_id);
1014
- $default_marker = "<img src='".$res->default_marker."' />";
1015
-
1016
- //$wpgmza_data = get_option('WPGMZA');
1017
- //if ($wpgmza_data['map_default_marker']) { $default_icon = "<img src='".$wpgmza_data['map_default_marker']."' />"; } else { $default_icon = "<img src='".wpgmaps_get_plugin_url()."/images/marker.png' />"; }
1018
-
1019
- foreach ( $results as $result ) {
1020
- unset($poly_data);
1021
- unset($poly_array);
1022
- $poly_data = '';
1023
- $poly_array = wpgmza_b_return_polyline_array($result->id);
1024
- foreach ($poly_array as $poly_single) {
1025
- $poly_data .= $poly_single.",";
1026
- }
1027
- if (isset($result->polyname) && $result->polyname != "") { $poly_name = $result->polyname; } else { $poly_name = "Polyline".$result->id; }
1028
-
1029
- $wpgmza_tmp .= "
1030
- <tr id=\"wpgmza_poly_tr_".intval($result->id)."\">
1031
- <td height=\"40\">".intval($result->id)."</td>
1032
- <td height=\"40\">".esc_attr(stripslashes($poly_name))."</td>
1033
- <td width='170' align='left'>
1034
- <a href=\"".esc_url(get_option('siteurl'))."/wp-admin/admin.php?page=wp-google-maps-menu&action=edit_polyline&map_id=".intval($map_id)."&poly_id=".intval($result->id)."\" title=\"".__("Edit","wp-google-maps")."\" class=\"wpgmza_edit_poly_btn button\" id=\"".intval($result->id)."\"><i class=\"fa fa-edit\"> </i></a>
1035
- <a href=\"javascript:void(0);\" title=\"".__("Delete this polyline","wp-google-maps")."\" class=\"wpgmza_polyline_del_btn button\" id=\"".intval($result->id)."\"><i class=\"fa fa-times\"> </i></a>
1036
- </td>
1037
- </tr>";
1038
-
1039
- }
1040
- $wpgmza_tmp .= "</tbody></table>";
1041
-
1042
-
1043
- return $wpgmza_tmp;
1044
-
1045
- }
1046
- /**
1047
- * Retrieve polyline options from DB
1048
- *
1049
- * @param integer $poly_id Polyline ID
1050
- * @return array MYSQL Array
1051
- */
1052
- function wpgmza_b_return_polyline_options($poly_id) {
1053
- global $wpdb;
1054
- global $wpgmza_tblname_polylines;
1055
-
1056
- $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_polylines WHERE `id` = %d LIMIT 1",intval($poly_id)) );
1057
-
1058
- if(empty($results))
1059
- return;
1060
-
1061
- $data = $results[0];
1062
-
1063
- return wpgmza_convert_shape_options_to_legacy_format($data);
1064
- }
1065
-
1066
- /**
1067
- * Return the polyline data in the format of an array of coordinate-pair strings
1068
- *
1069
- * @param integer $poly_id Polyline ID
1070
- * @return array Poly data array of coordinate-pair strings
1071
- */
1072
- function wpgmza_b_return_polyline_array($poly_id) {
1073
- global $wpdb;
1074
- global $wpgmza_tblname_polylines;
1075
-
1076
- $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_polylines WHERE `id` = %d LIMIT 1",intval($poly_id)) );
1077
-
1078
- if(empty($results))
1079
- return null;
1080
-
1081
- $polyline = $results[0];
1082
- $polydata = $polyline->polydata;
1083
-
1084
- if(($json = json_decode($polydata)) !== false)
1085
- return wpgmza_convert_json_geometry_to_legacy_format($json);
1086
-
1087
- $regex = '/-?(\d+)(\.\d+)?,\s*-?(\d+)(\.\d+)?/';
1088
-
1089
- if(!preg_match_all($regex, $polydata, $m))
1090
- return array();
1091
-
1092
- return $m[0];
1093
- }
1094
-
1095
- /**
1096
- * Return polyline ID array
1097
- *
1098
- * This is used when creating the JSON array of all the polylines and their unique options
1099
- *
1100
- * @param integer $map_id Map ID
1101
- * @return array Array of IDs
1102
- */
1103
- function wpgmza_b_return_polyline_id_array($map_id) {
1104
- global $wpdb;
1105
- global $wpgmza_tblname_polylines;
1106
- $ret = array();
1107
- $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_polylines WHERE `map_id` = %d",intval($map_id)) );
1108
- foreach ( $results as $result ) {
1109
- $current_id = $result->id;
1110
- $ret[] = $current_id;
1111
-
1112
- }
1113
- return $ret;
1114
- }
1115
-
1116
- /*
1117
- * Legacy admin menu
1118
- */
1119
- function wpgmaps_admin_menu() {
1120
- $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
1121
-
1122
- if (isset($wpgmza_settings['wpgmza_settings_access_level'])) { $access_level = $wpgmza_settings['wpgmza_settings_access_level']; } else { $access_level = "manage_options"; }
1123
-
1124
- add_menu_page('WP Google Maps', __('Maps','wp-google-maps'), $access_level, 'wp-google-maps-menu', 'wpgmaps_menu_layout', wpgmaps_get_plugin_url()."images/menu-icon.png");
1125
-
1126
- add_submenu_page(
1127
- 'wp-google-maps-menu',
1128
- 'WP Google Maps - Maps',
1129
- __('Maps', 'wp-google-maps'),
1130
- $access_level,
1131
- 'wp-google-maps-menu',
1132
- 'wpgmaps_menu_layout'
1133
- );
1134
-
1135
- if (function_exists('wpgmaps_menu_category_layout')) { add_submenu_page('wp-google-maps-menu', 'WP Google Maps - Categories', __('Categories','wp-google-maps'), $access_level , 'wp-google-maps-menu-categories', 'wpgmaps_menu_category_layout'); }
1136
-
1137
- if (function_exists('wpgmza_register_pro_version'))
1138
- {
1139
- add_submenu_page(
1140
- 'wp-google-maps-menu',
1141
- 'WP Google Maps - Advanced Options',
1142
- __('Advanced','wp-google-maps'),
1143
- $access_level ,
1144
- 'wp-google-maps-menu-advanced',
1145
- 'wpgmaps_menu_advanced_layout'
1146
- );
1147
-
1148
- remove_submenu_page("wp-google-maps-menu", "wp-google-maps-menu-custom-fields");
1149
-
1150
- add_submenu_page(
1151
- 'wp-google-maps-menu',
1152
- 'WP Google Maps - Custom Fields',
1153
- __('Custom Fields', 'wp-google-maps'),
1154
- $access_level,
1155
- 'wp-google-maps-menu-custom-fields',
1156
- 'WPGMZA\\show_custom_fields_page'
1157
- );
1158
- }
1159
-
1160
- add_submenu_page('wp-google-maps-menu', 'WP Google Maps - Settings', __('Settings','wp-google-maps'), $access_level , 'wp-google-maps-menu-settings', 'wpgmaps_menu_settings_layout');
1161
- add_submenu_page('wp-google-maps-menu', 'WP Google Maps - Support', __('Support','wp-google-maps'), $access_level , 'wp-google-maps-menu-support', 'wpgmaps_menu_support_layout');
1162
-
1163
- // add_submenu_page('wp-google-maps-menu', 'WP Google Maps - Credits', __('Credits', 'wp-google-maps'), $access_level, 'wp-google-maps-menu-credits', 'wpgmaps_menu_layout');
1164
-
1165
- }
1166
-
1167
- function wpgmaps_menu_layout() {
1168
-
1169
- $map_id = isset($_GET['map_id']) ? (int) intval($_GET['map_id']) : null;
1170
- $nonce = wp_create_nonce('wpgmza_menu_layout_nonce');
1171
-
1172
- $handle = 'avia-google-maps-api';
1173
- $list = 'enqueued';
1174
-
1175
- if (wp_script_is( $handle, $list )) {
1176
- wp_deregister_script('avia-google-maps-api');
1177
- }
1178
-
1179
- /*check to see if we have write permissions to the plugin folder*/
1180
- if (!isset($_GET['action'])) {
1181
- wpgmza_map_page();
1182
- } else {
1183
-
1184
- if ($_GET['action'] == "welcome_page" || $_GET['action'] == "credits") { } else {
1185
- echo"<div class='wpgmza-support-notice' style='float:right; display:block; width:250px; height:65px; padding:6px; text-align:center; background-color: white; border-top: 4px solid #0073AA; margin-right:17px;'><strong>".__("Experiencing problems with the plugin?","wp-google-maps")."</strong><br /><a href='http://www.wpgmaps.com/documentation/troubleshooting/' title='WP Google Maps Troubleshooting Section' target='_BLANK'>".__("See the troubleshooting manual.","wp-google-maps")."</a> <br />".__("Or ask a question on our ","wp-google-maps")." <a href='http://www.wpgmaps.com/forums/forum/support-forum/' title='WP Google Maps Support Forum' target='_BLANK'>".__("Support forum.","wp-google-maps")."</a></div>
1186
- <div class='wpgmza-clear'></div>";
1187
- }
1188
-
1189
- if ($_GET['action'] == "trash" && $map_id) {
1190
- if (isset( $_GET['s'] ) && $_GET['s'] == "1") {
1191
-
1192
- if(!wp_verify_nonce($_GET['nonce'], 'wpgmza_menu_layout_nonce'))
1193
- {
1194
- http_response_code(401);
1195
- exit;
1196
- }
1197
-
1198
- wpgmaps_trash_map($map_id);
1199
-
1200
- $url = esc_url(get_option('siteurl') . "/wp-admin/admin.php?page=wp-google-maps-menu");
1201
-
1202
- echo "<script>window.location = \"$url\";</script>";
1203
-
1204
- return;
1205
-
1206
- } else {
1207
- $res = wpgmza_get_map_data($map_id);
1208
- echo "<h2>".__("Delete your map","wp-google-maps")."</h2><p>".__("Are you sure you want to delete the map","wp-google-maps")." <strong>\"".strip_tags($res->map_title)."?\"</strong> <br /><a href='?page=wp-google-maps-menu&s=1&action=trash&map_id=".$map_id."&s=1&nonce=$nonce'>".__("Yes","wp-google-maps")."</a> | <a href='?page=wp-google-maps-menu'>".__("No","wp-google-maps")."</a></p>";
1209
- return;
1210
- }
1211
- }
1212
-
1213
- if (isset($_GET['action']) && $_GET['action'] == "duplicate" && $map_id) {
1214
- if (function_exists('wpgmaps_duplicate_map')) {
1215
-
1216
- if(!wp_verify_nonce($_GET['nonce'], 'wpgmza_list_maps_pro_nonce'))
1217
- {
1218
- http_response_code(403);
1219
- exit;
1220
- }
1221
-
1222
- $new_id = wpgmaps_duplicate_map($map_id);
1223
-
1224
- if ($new_id > 0) {
1225
- wpgmza_map_page();
1226
- } else {
1227
- _e("There was a problem duplicating the map.","wp-google-maps");
1228
- wpgmza_map_page();
1229
- }
1230
- }
1231
- }
1232
-
1233
- else if ($_GET['action'] == "edit_marker" && isset($_GET['id'])) {
1234
-
1235
- wpgmza_edit_marker(sanitize_text_field($_GET['id']));
1236
-
1237
- }
1238
- elseif ($_GET['action'] == "add_poly" && $map_id) {
1239
-
1240
- if (function_exists("wpgmza_b_real_pro_add_poly")) {
1241
- wpgmza_b_real_pro_add_poly($map_id);
1242
- } else {
1243
- wpgmza_b_pro_add_poly($map_id);
1244
- }
1245
-
1246
- }
1247
- else if ($_GET['action'] == "edit_poly" && $map_id) {
1248
-
1249
- if (function_exists("wpgmza_b_real_pro_edit_poly")) {
1250
- wpgmza_b_real_pro_edit_poly($map_id);
1251
- } else {
1252
- wpgmza_b_pro_edit_poly($map_id);
1253
- }
1254
-
1255
-
1256
- }
1257
- else if ($_GET['action'] == "add_polyline" && $map_id) {
1258
-
1259
- wpgmza_b_pro_add_polyline($map_id);
1260
-
1261
- }
1262
- else if ($_GET['action'] == "edit_polyline" && $map_id) {
1263
-
1264
- wpgmza_b_pro_edit_polyline($map_id);
1265
- }
1266
- else if ($_GET['action'] == "add_heatmap" && $map_id) {
1267
- if (function_exists("wpgmza_b_pro_add_heatmap")) { wpgmza_b_pro_add_heatmap($map_id); }
1268
- }
1269
- else if ($_GET['action'] == "edit_heatmap" && $map_id) {
1270
- if (function_exists("wpgmza_b_pro_edit_heatmap")) { wpgmza_b_pro_edit_heatmap($map_id); }
1271
- }
1272
- else if ($_GET['action'] == "add_circle" && $map_id) {
1273
- wpgmza_b_add_circle($map_id);
1274
- }
1275
- else if ($_GET['action'] == "edit_circle" && $map_id) {
1276
- wpgmza_b_edit_circle($map_id);
1277
- }
1278
- else if ($_GET['action'] == "add_rectangle" && $map_id) {
1279
- wpgmza_b_add_rectangle($map_id);
1280
- }
1281
- else if ($_GET['action'] == "edit_rectangle" && $map_id) {
1282
- wpgmza_b_edit_rectangle($map_id);
1283
- }
1284
- else if ($_GET['action'] == 'welcome_page') {
1285
- $file = dirname(__FILE__).'/base/classes/WPGM_templates.php';
1286
- include ($file);
1287
- $wpgmc = new WPGMAPS_templates();
1288
- $wpgmc->welcome_page_v6();
1289
-
1290
- }
1291
-
1292
- else if ($_GET['action'] == 'credits') {
1293
- $file = dirname(__FILE__).'/base/classes/WPGM_templates.php';
1294
- include ($file);
1295
- $wpgmc = new WPGMAPS_templates();
1296
- $wpgmc->welcome_page_credits();
1297
-
1298
- }
1299
- else {
1300
-
1301
- if (function_exists('wpgmza_register_pro_version')) {
1302
- wpgmza_pro_menu();
1303
- } else {
1304
- wpgmza_basic_menu();
1305
- }
1306
-
1307
- }
1308
- }
1309
-
1310
- do_action("wpgmza_check_map_editor_backwards_compat");
1311
-
1312
-
1313
- }
1314
-
1315
- function wpgmaps_list_maps() {
1316
- global $wpdb;
1317
- global $wpgmza_tblname_maps;
1318
-
1319
- if (function_exists('wpgmaps_list_maps_pro')) { wpgmaps_list_maps_pro(); return; }
1320
-
1321
- if ($wpgmza_tblname_maps) { $table_name = $wpgmza_tblname_maps; } else { $table_name = $wpdb->prefix . "wpgmza_maps"; }
1322
-
1323
-
1324
- $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE `active` = %d ORDER BY `id` DESC",0));
1325
- echo "
1326
-
1327
- <table class=\"wp-list-table widefat wpgmza-listing\" cellspacing=\"0\">
1328
- <thead>
1329
- <tr>
1330
- <th scope='col' id='id' class='manage-column column-id sortable desc' style='width:50px;'><span>".__("ID","wp-google-maps")."</span></th>
1331
- <th scope='col' id='map_title' class='manage-column column-map_title sortable desc'><span>".__("Title","wp-google-maps")."</span></th>
1332
- <th scope='col' id='map_width' class='manage-column column-map_width' style=\"\">".__("Width","wp-google-maps")."</th>
1333
- <th scope='col' id='map_height' class='manage-column column-map_height' style=\"\">".__("Height","wp-google-maps")."</th>
1334
- <th scope='col' id='type' class='manage-column column-type sortable desc' style=\"\"><span>".__("Type","wp-google-maps")."</span></th>
1335
- <th scope='col' id='type' class='manage-column column-type sortable desc' style=\"\"><span>".__("Action","wp-google-maps")."</span></th>
1336
- <th scope='col' id='type' class='manage-column column-type sortable desc' style=\"\"><span>".__("Shortcode","wp-google-maps")."</span></th>
1337
- </tr>
1338
- </thead>
1339
- <tbody id=\"the-list\" class='list:wp_list_text_link'>
1340
- ";
1341
- foreach ( $results as $result ) {
1342
- if ($result->type == "1") { $map_type = __("Roadmap","wp-google-maps"); }
1343
- else if ($result->type == "2") { $map_type = __("Satellite","wp-google-maps"); }
1344
- else if ($result->type == "3") { $map_type = __("Hybrid","wp-google-maps"); }
1345
- else if ($result->type == "4") { $map_type = __("Terrain","wp-google-maps"); }
1346
- if (function_exists('wpgmza_register_pro_version')) {
1347
- $trashlink = "<a class='page-title-action' href=\"?page=wp-google-maps-menu&action=trash&map_id=".$result->id."\" title=\"Trash\">".__("Trash","wp-google-maps")."</a>";
1348
- } else {
1349
- $trashlink = "";
1350
- }
1351
- echo "<tr id=\"record_".intval($result->id)."\">";
1352
- echo "<td class='id column-id'>".intval($result->id)."</td>";
1353
- echo "<td class='map_title column-map_title'><strong><big><a href=\"?page=wp-google-maps-menu&action=edit&map_id=".intval($result->id)."\" title=\"".__("Edit","wp-google-maps")."\">".stripslashes(strip_tags($result->map_title))."</a></big></strong><br /></td>";
1354
- echo "<td class='map_width column-map_width'>".esc_html($result->map_width)."".stripslashes(esc_html($result->map_width_type))."</td>";
1355
- echo "<td class='map_width column-map_height'>".esc_html($result->map_height)."".stripslashes(esc_html($result->map_height_type))."</td>";
1356
- echo "<td class='type column-type'>".$map_type."</td>";
1357
- echo "<td class='type column-type'><a class='page-title-action' href=\"?page=wp-google-maps-menu&action=edit&map_id=".intval($result->id)."\" title=\"".__("Edit","wp-google-maps")."\">".__("Edit","wp-google-maps")."</a> $trashlink</td>";
1358
- echo "<td class='type column-type'><input class='wpgmza_copy_shortcode' type='text' readonly value='[wpgmza id=\"".intval($result->id)."\"]'/></td>";
1359
- echo "</tr>";
1360
-
1361
-
1362
- }
1363
- echo "</table>";
1364
- }
1365
-
1366
- if(!function_exists('wpgmza_return_marker_list'))
1367
- {
1368
- function wpgmza_return_marker_list($map_id,$admin = true,$width = "100%",$mashup = false,$mashup_ids = false) {
1369
- global $wpdb;
1370
- global $wpgmza_tblname;
1371
-
1372
- $columns = implode(', ', wpgmza_get_marker_columns());
1373
-
1374
- if ($mashup) {
1375
- $map_ids = $mashup_ids;
1376
- $wpgmza_cnt = 0;
1377
-
1378
- if ($mashup_ids[0] == "ALL") {
1379
-
1380
- $wpgmza_sql1 = "SELECT $columns FROM $wpgmza_tblname ORDER BY `id` DESC";
1381
- }
1382
- else {
1383
- $wpgmza_id_cnt = count($map_ids);
1384
- $sql_string1 = "";
1385
- foreach ($map_ids as $wpgmza_map_id) {
1386
- $wpgmza_cnt++;
1387
- if ($wpgmza_cnt == 1) { $sql_string1 .= $wpdb->prepare("`map_id` = %d ",$wpgmza_map_id); }
1388
- elseif ($wpgmza_cnt > 1 && $wpgmza_cnt < $wpgmza_id_cnt) { $sql_string1 .= $wpdb->prepare("OR `map_id` = %d ",$wpgmza_map_id); }
1389
- else { $sql_string1 .= $wpdb->prepare("OR `map_id` = %d ",$wpgmza_map_id); }
1390
-
1391
- }
1392
- $wpgmza_sql1 = "SELECT $columns FROM $wpgmza_tblname WHERE $sql_string1 ORDER BY `id` DESC";
1393
-
1394
- }
1395
-
1396
- } else {
1397
- $wpgmza_sql1 = $wpdb->prepare("SELECT $columns FROM $wpgmza_tblname WHERE `map_id` = %d ORDER BY `id` DESC",intval($map_id));
1398
-
1399
- }
1400
- $marker_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpgmza_tblname WHERE map_id = %d",$map_id ) );
1401
-
1402
- $results = $wpdb->get_results($wpgmza_sql1);
1403
- $wpgmza_tmp_body = "";
1404
- $wpgmza_tmp_head = "";
1405
- $wpgmza_tmp_footer = "";
1406
-
1407
- $res = wpgmza_get_map_data($map_id);
1408
- if (!$res->default_marker) {
1409
- $default_marker = "<img src='".wpgmaps_get_plugin_url()."images/marker.png' width='27' height='43'/>";
1410
- } else {
1411
- $default_marker = "<img src='".$res->default_marker."' />";
1412
- }
1413
-
1414
-
1415
- foreach ( $results as $result ) {
1416
- $img = $result->pic;
1417
- $link = $result->link;
1418
- $icon = $result->icon;
1419
-
1420
-
1421
- if (isset($result->approved)) {
1422
- $approved = $result->approved;
1423
- if ($approved == 0) {
1424
- $show_approval_button = true;
1425
- } else {
1426
- $show_approval_button = false;
1427
- }
1428
- } else {
1429
- $show_approval_button = false;
1430
- }
1431
-
1432
- $category_icon = wpgmza_get_category_icon($result->category);
1433
-
1434
- if (!$img) { $pic = ""; } else { $pic = "<img src=\"".$result->pic."\" width=\"40\" />"; }
1435
-
1436
- if (!$category_icon) {
1437
- if (!$icon) {
1438
- $icon = $default_marker;
1439
- } else {
1440
- $icon = "<img src='".$result->icon."' />";
1441
- }
1442
- } else {
1443
- if (!$icon) {
1444
- $icon = "<img src='".$category_icon."' />";
1445
- } else {
1446
- $icon = "<img src='".$result->icon."' />";
1447
- }
1448
-
1449
- }
1450
-
1451
- if (!$link) { $linktd = ""; } else { $linktd = "<a href=\"".$result->link."\" target=\"_BLANK\" title=\"".__("View this link","wp-google-maps")."\">&gt;&gt;</a>"; }
1452
-
1453
- if ($admin) {
1454
- $wpgmza_tmp_body .= "<tr id=\"wpgmza_tr_".$result->id."\" class=\"gradeU\">";
1455
-
1456
- $wpgmza_tmp_body .= '<td><input type="checkbox" name="mark"/></td>';
1457
-
1458
- $wpgmza_tmp_body .= "<td height=\"40\">".$result->id."</td>";
1459
- $wpgmza_tmp_body .= "<td height=\"40\">".$icon."<input type=\"hidden\" id=\"wpgmza_hid_marker_icon_".$result->id."\" value=\"".$result->icon."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_anim_".$result->id."\" value=\"".$result->anim."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_category_".$result->id."\" value=\"".$result->category."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_infoopen_".$result->id."\" value=\"".$result->infoopen."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_approved_".$result->id."\" value=\"".$result->approved."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_retina_".$result->id."\" value=\"".$result->retina."\" />";
1460
-
1461
- if(defined('WPGMZA_PRO_FILE') && file_exists(plugin_dir_path(WPGMZA_PRO_FILE) . 'includes/custom-fields/class.custom-marker-fields.php'))
1462
- {
1463
- wpgmza_require_once(plugin_dir_path(WPGMZA_PRO_FILE) . 'includes/custom-fields/class.custom-marker-fields.php');
1464
- $custom_fields = new WPGMZA\CustomMarkerFields($result->id);
1465
- $custom_fields_json = json_encode($custom_fields);
1466
- $custom_fields_json = htmlspecialchars($custom_fields_json);
1467
-
1468
- $wpgmza_tmp_body .= '<input type="hidden" id="wpgmza_hid_marker_custom_fields_json_' . $result->id . '" value="' . $custom_fields_json . '"/>';
1469
- }
1470
-
1471
- $wpgmza_tmp_body .= "</td>";
1472
- $wpgmza_tmp_body .= "<td>".stripslashes($result->title)."<input type=\"hidden\" id=\"wpgmza_hid_marker_title_".$result->id."\" value=\"".stripslashes($result->title)."\" /></td>";
1473
- $wpgmza_tmp_body .= "<td>".wpgmza_return_category_name($result->category)."<input type=\"hidden\" id=\"wpgmza_hid_marker_category_".$result->id."\" value=\"".$result->category."\" /></td>";
1474
- $wpgmza_tmp_body .= "<td>".stripslashes($result->address)."<input type=\"hidden\" id=\"wpgmza_hid_marker_address_".$result->id."\" value=\"".stripslashes($result->address)."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_lat_".$result->id."\" value=\"".$result->lat."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_lng_".$result->id."\" value=\"".$result->lng."\" /></td>";
1475
- $wpgmza_tmp_body .= "<td>".stripslashes($result->description)."<input type=\"hidden\" id=\"wpgmza_hid_marker_desc_".$result->id."\" value=\"". htmlspecialchars(stripslashes($result->description))."\" /></td>";
1476
- $wpgmza_tmp_body .= "<td>$pic<input type=\"hidden\" id=\"wpgmza_hid_marker_pic_".$result->id."\" value=\"".$result->pic."\" /></td>";
1477
- $wpgmza_tmp_body .= "<td>$linktd<input type=\"hidden\" id=\"wpgmza_hid_marker_link_".$result->id."\" value=\"".$result->link."\" /></td>";
1478
- $wpgmza_tmp_body .= "<td width='170' align='center'><div class='wpgmza-flex'>";
1479
- $wpgmza_tmp_body .= " <a title=\"".__("Edit this marker","wp-google-maps")."\" class=\"wpgmza_edit_btn button\" id=\"".$result->id."\"><i class=\"fa fa-edit\"> </i> </a> ";
1480
- $wpgmza_tmp_body .= " <a href=\"?page=wp-google-maps-menu&action=edit_marker&id=".$result->id."\" title=\"".__("Edit this marker location","wp-google-maps")."\" class=\"wpgmza_edit_btn button\" id=\"".$result->id."\"><i class=\"fa fa-map-marker\"> </i></a> ";
1481
- if ($show_approval_button) {
1482
- $wpgmza_tmp_body .= " <a href=\"javascript:void(0);\" title=\"".__("Approve this marker","wp-google-maps")."\" class=\"wpgmza_approve_btn button\" id=\"".$result->id."\"><i class=\"fa fa-check\"> </i> </a> ";
1483
- }
1484
- $wpgmza_tmp_body .= " <a href=\"javascript:void(0);\" title=\"".__("Delete this marker","wp-google-maps")."\" class=\"wpgmza_del_btn button\" id=\"".$result->id."\"><i class=\"fa fa-times\"> </i></a>";
1485
- $wpgmza_tmp_body .= "</div></td>";
1486
- $wpgmza_tmp_body .= "</tr>";
1487
- } else {
1488
- $wpgmza_tmp_body .= "<tr id=\"wpgmza_marker_".$result->id."\" mid=\"".$result->id."\" mapid=\"".$result->map_id."\" class=\"wpgmaps_mlist_row\">";
1489
- $wpgmza_tmp_body .= " <td width='1px;' style='display:none; width:1px !important;'><span style='display:none;'>".sprintf('%02d', $result->id)."</span></td>";
1490
- $wpgmza_tmp_body .= " <td class='wpgmza_table_marker' height=\"40\">".str_replace("'","\"",$icon)."</td>";
1491
- $wpgmza_tmp_body .= " <td class='wpgmza_table_title'>".stripslashes($result->title)."</td>";
1492
- $wpgmza_tmp_body .= " <td class='wpgmza_table_category'>".wpgmza_return_category_name($result->category)."</td>";
1493
- $wpgmza_tmp_body .= " <td class='wpgmza_table_address'>".stripslashes($result->address)."</td>";
1494
- $wpgmza_tmp_body .= " <td class='wpgmza_table_description'>".stripslashes($result->description)."</td>";
1495
- $wpgmza_tmp_body .= "</tr>";
1496
- }
1497
- }
1498
- if ($admin) {
1499
-
1500
- $wpgmza_tmp_head .= "<table id=\"wpgmza_table\" class=\"display\" cellspacing=\"0\" cellpadding=\"0\" style=\"width:$width;\">";
1501
- $wpgmza_tmp_head .= "<thead>";
1502
- $wpgmza_tmp_head .= "<tr>";
1503
- $wpgmza_tmp_head .= " <td><strong>".__("Mark","wp-google-maps")."</strong></td>";
1504
- $wpgmza_tmp_head .= " <th><strong>".__("ID","wp-google-maps")."</strong></th>";
1505
- $wpgmza_tmp_head .= " <th><strong>".__("Icon","wp-google-maps")."</strong></th>";
1506
- $wpgmza_tmp_head .= " <th><strong>".apply_filters("wpgmza_filter_title_name",__("Title","wp-google-maps"))."</strong></th>";
1507
- $wpgmza_tmp_head .= " <th><strong>".apply_filters("wpgmza_filter_category_name",__("Category","wp-google-maps"))."</strong></th>";
1508
- $wpgmza_tmp_head .= " <th><strong>".apply_filters("wpgmza_filter_address_name",__("Address","wp-google-maps"))."</strong></th>";
1509
- $wpgmza_tmp_head .= " <th><strong>".apply_filters("wpgmza_filter_description_name",__("Description","wp-google-maps"))."</strong></th>";
1510
- $wpgmza_tmp_head .= " <th><strong>".__("Image","wp-google-maps")."</strong></th>";
1511
- $wpgmza_tmp_head .= " <th><strong>".__("Link","wp-google-maps")."</strong></th>";
1512
- $wpgmza_tmp_head .= " <th style='width:182px;'><strong>".__("Action","wp-google-maps")."</strong></th>";
1513
- $wpgmza_tmp_head .= "</tr>";
1514
- $wpgmza_tmp_head .= "</thead>";
1515
- $wpgmza_tmp_head .= "<tbody>";
1516
-
1517
- } else {
1518
-
1519
- $wpgmza_tmp_head .= "<div id=\"wpgmza_marker_holder_".$map_id."\" style=\"width:$width;\">";
1520
- $wpgmza_tmp_head .= "<table id=\"wpgmza_table_".$map_id."\" class=\"wpgmza_table\" cellspacing=\"0\" cellpadding=\"0\" style=\"width:$width;\">";
1521
- $wpgmza_tmp_head .= "<thead>";
1522
- $wpgmza_tmp_head .= "<tr>";
1523
- $wpgmza_tmp_head .= " <th width='1' style='display:none; width:1px !important;'></th>";
1524
- $wpgmza_tmp_head .= " <th class='wpgmza_table_marker'><strong></strong></th>";
1525
- $wpgmza_tmp_head .= " <th class='wpgmza_table_title'><strong>".apply_filters("wpgmza_filter_title_name",__("Title","wp-google-maps"))."</strong></th>";
1526
- $wpgmza_tmp_head .= " <th class='wpgmza_table_category'><strong>".apply_filters("wpgmza_filter_category_name",__("Category","wp-google-maps"))."</strong></th>";
1527
- $wpgmza_tmp_head .= " <th class='wpgmza_table_address'><strong>".apply_filters("wpgmza_filter_address_name",__("Address","wp-google-maps"))."</strong></th>";
1528
- $wpgmza_tmp_head .= " <th class='wpgmza_table_description'><strong>".apply_filters("wpgmza_filter_description_name",__("Description","wp-google-maps"))."</strong></th>";
1529
- $wpgmza_tmp_head .= "</tr>";
1530
- $wpgmza_tmp_head .= "</thead>";
1531
- $wpgmza_tmp_head .= "<tbody>";
1532
- }
1533
-
1534
- $wpgmza_tmp_footer .= "</tbody></table>";
1535
-
1536
- $wpgmza_tmp_footer .= '
1537
- <div class="wpgmza-marker-listing__actions">
1538
- &#x21b3;
1539
- <button class="wpgmza button select_all_markers" type="button">Select All</button>
1540
- <button class="wpgmza button bulk_delete" type="button">Bulk Delete</button>
1541
- </div>
1542
- ';
1543
-
1544
- if(!$admin)
1545
- $wpgmza_tmp_footer .= '</div>';
1546
-
1547
- return $wpgmza_tmp_head.$wpgmza_tmp_body.$wpgmza_tmp_footer;
1548
- }
1549
- }
1550
-
1551
- if(!function_exists('wpgmza_return_category_name'))
1552
- {
1553
- function wpgmza_return_category_name($cid) {
1554
-
1555
- global $wpdb;
1556
- global $wpgmza_tblname_categories;
1557
- $pos = strpos($cid, ",");
1558
- if ($pos === false) {
1559
- $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM `$wpgmza_tblname_categories` WHERE `id` = %d LIMIT 1",intval($cid)) );
1560
- foreach ( $results as $result ) {
1561
- return $result->category_name;
1562
- }
1563
- } else {
1564
- $categories = explode(",",$cid);
1565
- $ret_cat = "";
1566
- $tot_cnt = count($categories);
1567
- $countr = 0;
1568
- foreach ($categories as $cid) {
1569
- $countr++;
1570
- $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM `$wpgmza_tblname_categories` WHERE `id` = %d LIMIT 1",intval($cid)) );
1571
- foreach ( $results as $result ) {
1572
- if ($countr >= $tot_cnt) {
1573
- $ret_cat .= $result->category_name;
1574
- } else { $ret_cat .= $result->category_name.","; }
1575
- }
1576
-
1577
- }
1578
- return stripslashes($ret_cat);
1579
- }
1580
- }
1581
- }
1582
-
1583
- /**
1584
- * Outputs the JavaScript for the front end
1585
- * @deprecated 6.3.10 Moved into the wpgmaps_tag_basic function
1586
- * @return void
1587
- */
1588
- function wpgmaps_user_javascript_basic() {
1589
-
1590
- global $short_code_active;
1591
- global $wpgmza_current_map_id;
1592
- global $wpgmza_version;
1593
-
1594
- $ajax_nonce = wp_create_nonce("wpgmza");
1595
-
1596
- $res = array();
1597
- $res[$wpgmza_current_map_id] = wpgmza_get_map_data($wpgmza_current_map_id);
1598
- $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
1599
-
1600
- $api_version_string = 'quarterly';
1601
-
1602
- $map_other_settings = maybe_unserialize($res[$wpgmza_current_map_id]->other_settings);
1603
- $res[$wpgmza_current_map_id]->other_settings = $map_other_settings;
1604
- $res[$wpgmza_current_map_id]->map_width_type = stripslashes($res[$wpgmza_current_map_id]->map_width_type);
1605
-
1606
-
1607
- if ($res[$wpgmza_current_map_id]->other_settings['wpgmza_theme_data'] != '') {
1608
- $res[$wpgmza_current_map_id]->other_settings['wpgmza_theme_data'] = html_entity_decode(stripslashes($res[$wpgmza_current_map_id]->other_settings['wpgmza_theme_data']));
1609
- }
1610
-
1611
- $polygonoptions = array();
1612
- $total_poly_array = wpgmza_b_return_polygon_id_array($wpgmza_current_map_id);
1613
-
1614
- if ($total_poly_array > 0) {
1615
- foreach ($total_poly_array as $poly_id) {
1616
- $polygonoptions[$poly_id] = wpgmza_b_return_poly_options($poly_id);
1617
-
1618
- $tmp_poly_array = wpgmza_b_return_polygon_array($poly_id);
1619
- $poly_data_raw_array = array();
1620
- foreach ($tmp_poly_array as $single_poly) {
1621
- $poly_data_raw = str_replace(" ","",$single_poly);
1622
- $poly_data_raw = explode(",",$poly_data_raw);
1623
- $lat = $poly_data_raw[0];
1624
- $lng = $poly_data_raw[1];
1625
- $poly_data_raw_array[] = $poly_data_raw;
1626
- }
1627
- $polygonoptions[$poly_id]->polydata = $poly_data_raw_array;
1628
-
1629
- $linecolor = $polygonoptions[$poly_id]->linecolor;
1630
- $fillcolor = $polygonoptions[$poly_id]->fillcolor;
1631
- $fillopacity = $polygonoptions[$poly_id]->opacity;
1632
- if (!$linecolor) { $polygonoptions[$poly_id]->linecolor = "000000"; }
1633
- if (!$fillcolor) { $polygonoptions[$poly_id]->fillcolor = "66FF00"; }
1634
- if (!$fillopacity) { $polygonoptions[$poly_id]->opacity = "0.5"; }
1635
- }
1636
- } else { $polygonoptions = array(); }
1637
-
1638
-
1639
- $polylineoptions = array();
1640
-
1641
- $total_poly_array = wpgmza_b_return_polyline_id_array($wpgmza_current_map_id);
1642
- if ($total_poly_array > 0) {
1643
- foreach ($total_poly_array as $poly_id) {
1644
- $polylineoptions[$poly_id] = wpgmza_b_return_polyline_options($poly_id);
1645
-
1646
- $tmp_poly_array = wpgmza_b_return_polyline_array($poly_id);
1647
- $poly_data_raw_array = array();
1648
- foreach ($tmp_poly_array as $single_poly) {
1649
- $poly_data_raw = str_replace(" ","",$single_poly);
1650
- $poly_data_raw = str_replace(")","",$poly_data_raw );
1651
- $poly_data_raw = str_replace("(","",$poly_data_raw );
1652
- $poly_data_raw = explode(",",$poly_data_raw);
1653
- $lat = $poly_data_raw[0];
1654
- $lng = $poly_data_raw[1];
1655
- $poly_data_raw_array[] = $poly_data_raw;
1656
- }
1657
- $polylineoptions[$poly_id]->polydata = $poly_data_raw_array;
1658
-
1659
-
1660
- if (isset($polylineoptions[$poly_id]->linecolor)) { $linecolor = $polylineoptions[$poly_id]->linecolor; } else { $linecolor = false; }
1661
- if (isset($polylineoptions[$poly_id]->fillcolor)) { $fillcolor = $polylineoptions[$poly_id]->fillcolor; } else { $fillcolor = false; }
1662
- if (isset($polylineoptions[$poly_id]->opacity)) { $fillopacity = $polylineoptions[$poly_id]->opacity; } else { $fillopacity = false; }
1663
- if (!$linecolor) { $polylineoptions[$poly_id]->linecolor = "000000"; }
1664
- if (!$fillcolor) { $polylineoptions[$poly_id]->fillcolor = "66FF00"; }
1665
- if (!$fillopacity) { $polylineoptions[$poly_id]->opacity = "0.5"; }
1666
- }
1667
- } else { $polylineoptions = array(); }
1668
-
1669
- if (isset($wpgmza_settings['wpgmza_settings_marker_pull']) && $wpgmza_settings['wpgmza_settings_marker_pull'] == "0") {
1670
- $markers = wpgmaps_return_markers($wpgmza_current_map_id);
1671
- }
1672
-
1673
- wp_enqueue_script( 'wpgmaps_core' );
1674
-
1675
- do_action("wpgooglemaps_basic_hook_user_js_after_core");
1676
-
1677
- wp_localize_script( 'wpgmaps_core', 'wpgmaps_mapid', $wpgmza_current_map_id );
1678
-
1679
- wp_localize_script( 'wpgmaps_core', 'wpgmaps_localize', $res);
1680
- wp_localize_script( 'wpgmaps_core', 'wpgmaps_localize_polygon_settings', $polygonoptions);
1681
- wp_localize_script( 'wpgmaps_core', 'wpgmaps_localize_polyline_settings', $polylineoptions);
1682
-
1683
- wp_localize_script( 'wpgmaps_core', 'wpgmaps_markerurl', wpgmaps_get_marker_url($wpgmza_current_map_id));
1684
-
1685
-
1686
- if ($wpgmza_settings['wpgmza_settings_marker_pull'] == "0") {
1687
- wp_localize_script( 'wpgmaps_core', 'wpgmaps_localize_marker_data', $markers);
1688
- }
1689
-
1690
- $wpgmza_settings = apply_filters("wpgmza_basic_filter_localize_settings",$wpgmza_settings);
1691
-
1692
- wp_localize_script( 'wpgmaps_core', 'wpgmaps_localize_global_settings', $wpgmza_settings);
1693
-
1694
- wp_localize_script( 'wpgmaps_core', 'wpgmaps_lang_km_away', __("km away","wp-google-maps"));
1695
- wp_localize_script( 'wpgmaps_core', 'wpgmaps_lang_m_away', __("miles away","wp-google-maps"));
1696
-
1697
- }
1698
-
1699
- /**
1700
- * Return an array of markers with relevant data.
1701
- * Used by AJAX calls throughout sections the plugin
1702
- * @param boolean $mapid Map ID
1703
- * @param boolean $markerid (optional) will only pull that marker ID if selected
1704
- * @return array Array of marker data
1705
- */
1706
- function wpgmaps_return_markers($mapid = false,$marker_id = false) {
1707
-
1708
- if (!$mapid) {
1709
- return;
1710
- }
1711
- global $wpdb;
1712
- global $wpgmza_tblname;
1713
-
1714
- $table_name = $wpgmza_tblname;
1715
-
1716
- $columns = implode(', ', wpgmza_get_marker_columns());
1717
-
1718
- if ($marker_id) {
1719
- $results = $wpdb->get_results($wpdb->prepare("SELECT $columns FROM $table_name WHERE `map_id` = %d AND `id` = %d",intval($mapid),intval($marker_id)) );
1720
- } else {
1721
- $results = $wpdb->get_results($wpdb->prepare("SELECT $columns FROM $table_name WHERE `map_id` = %d AND `approved` = 1",intval($mapid)) );
1722
- }
1723
-
1724
- $m_array = array();
1725
- $cnt = 0;
1726
- foreach ( $results as $result ) {
1727
-
1728
- $id = $result->id;
1729
- $address = stripslashes($result->address);
1730
- $description = do_shortcode(stripslashes($result->description));
1731
- $pic = $result->pic;
1732
- if (!$pic) { $pic = ""; }
1733
- $icon = $result->icon;
1734
- if (!$icon) { $icon = ""; }
1735
- $link_url = $result->link;
1736
- if ($link_url) { } else { $link_url = ""; }
1737
- $lat = $result->lat;
1738
- $lng = $result->lng;
1739
- $anim = $result->anim;
1740
- $retina = $result->retina;
1741
- $category = $result->category;
1742
- $other_data = $result->other_data;
1743
-
1744
- if ($icon == "") {
1745
- if (function_exists('wpgmza_get_category_data')) {
1746
- $category_data = wpgmza_get_category_data($category);
1747
- if (isset($category_data->category_icon) && isset($category_data->category_icon) != "") {
1748
- $icon = $category_data->category_icon;
1749
- } else {
1750
- $icon = "";
1751
- }
1752
- if (isset($category_data->retina)) {
1753
- $retina = $category_data->retina;
1754
- }
1755
- }
1756
- }
1757
- $infoopen = $result->infoopen;
1758
-
1759
- $mtitle = stripslashes($result->title);
1760
- $map_id = $result->map_id;
1761
-
1762
- $m_array[$id] = array(
1763
- 'map_id' => $map_id,
1764
- 'marker_id' => $id,
1765
- 'title' => $mtitle,
1766
- 'address' => $address,
1767
- 'desc' => $description,
1768
- 'pic' => $pic,
1769
- 'icon' => $icon,
1770
- 'linkd' => $link_url,
1771
- 'lat' => $lat,
1772
- 'lng' => $lng,
1773
- 'anim' => $anim,
1774
- 'retina' => $retina,
1775
- 'category' => $category,
1776
- 'infoopen' => $infoopen,
1777
- 'other_data'=> maybe_unserialize($other_data),
1778
- 'infoopen' => $infoopen
1779
- );
1780
-
1781
- //$custom_fields = new WPGMZA\CustomMarkerFields();
1782
- if(class_exists('WPGMZA\\CustomMarkerFields'))
1783
- {
1784
- $custom_fields = new WPGMZA\CustomMarkerFields($id);
1785
- $m_array[$id]['custom_fields_json'] = json_encode($custom_fields);
1786
- $m_array[$id]['custom_fields_html'] = $custom_fields->html();
1787
- }
1788
-
1789
- $cnt++;
1790
-
1791
- }
1792
-
1793
- return $m_array;
1794
-
1795
- }
1796
-
1797
- /**
1798
- * Handles the bulk of the POST data for the plugin
1799
- * @return void
1800
- */
1801
- function wpgmaps_head() {
1802
-
1803
- global $wpgmza;
1804
- global $wpgmza_tblname_maps;
1805
- global $wpgmza_version;
1806
-
1807
- if (!$wpgmza->isUserAllowedToEdit())
1808
- return false;
1809
-
1810
- if ((isset($_GET['page']) && $_GET['page'] == "wp-google-maps-menu") || (isset($_GET['page']) && $_GET['page'] == "wp-google-maps-menu-settings")) {
1811
- wpgmaps_folder_check();
1812
- }
1813
-
1814
-
1815
- if (isset($_POST['wpgmza_savemap'])){
1816
-
1817
- var_dump("Woo!");
1818
- exit;
1819
-
1820
- if ( !isset( $_POST['wpgmaps_main-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_main-nonce'], 'wpgmaps_main-nonce' ) ) {
1821
- wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
1822
- }
1823
-
1824
- global $wpdb;
1825
-
1826
-
1827
-
1828
- $map_id = intval(sanitize_text_field($_POST['wpgmza_id']));
1829
- $map_title = sanitize_text_field(esc_attr($_POST['wpgmza_title']));
1830
- $map_height = sanitize_text_field($_POST['wpgmza_height']);
1831
- $map_width = sanitize_text_field($_POST['wpgmza_width']);
1832
- $map_width_type = sanitize_text_field($_POST['wpgmza_map_width_type']);
1833
- if ($map_width_type == "%") { $map_width_type = "\%"; }
1834
- $map_height_type = sanitize_text_field($_POST['wpgmza_map_height_type']);
1835
- if ($map_height_type == "%") { $map_height_type = "\%"; }
1836
- $map_start_location = sanitize_text_field($_POST['wpgmza_start_location']);
1837
- $map_start_zoom = intval(sanitize_text_field($_POST['wpgmza_start_zoom']));
1838
- $type = intval(sanitize_text_field($_POST['wpgmza_map_type']));
1839
- $alignment = intval(sanitize_text_field($_POST['wpgmza_map_align']));
1840
- $bicycle_enabled = isset($_POST['wpgmza_bicycle']) ? 1 : 2;
1841
- $traffic_enabled = isset($_POST['wpgmza_traffic']) ? 1 : 2;
1842
- $wpgmza_auto_night_enabled = isset($_POST['wpgmza_auto_night']);
1843
-
1844
-
1845
- $map_max_zoom = intval(sanitize_text_field($_POST['wpgmza_max_zoom']));
1846
-
1847
- $gps = explode(",",$map_start_location);
1848
- $map_start_lat = $gps[0];
1849
- $map_start_lng = $gps[1];
1850
-
1851
- $other_settings = array();
1852
- /*$other_settings['store_locator_enabled'] = intval(sanitize_text_field($_POST['wpgmza_store_locator']));
1853
- $other_settings['store_locator_distance'] = intval(sanitize_text_field($_POST['wpgmza_store_locator_distance']));
1854
- $other_settings['store_locator_bounce'] = intval(sanitize_text_field($_POST['wpgmza_store_locator_bounce']));*/
1855
-
1856
- $other_settings['store_locator_enabled'] = isset($_POST['wpgmza_store_locator']) ? 1 : 2;
1857
- $other_settings['store_locator_distance'] = isset($_POST['wpgmza_store_locator_distance']) ? 1 : 2;
1858
-
1859
- if (isset($_POST['wpgmza_store_locator_default_radius']))
1860
- $other_settings['store_locator_default_radius'] = intval($_POST['wpgmza_store_locator_default_radius']);
1861
-
1862
- if (isset($_POST['wpgmza_store_locator_not_found_message'])) { $other_settings['store_locator_not_found_message'] = sanitize_text_field( $_POST['wpgmza_store_locator_not_found_message'] ); }
1863
- $other_settings['store_locator_bounce'] = isset($_POST['wpgmza_store_locator_bounce']) ? 1 : 2;
1864
-
1865
- $other_settings['store_locator_query_string'] = sanitize_text_field($_POST['wpgmza_store_locator_query_string']);
1866
- if (isset($_POST['wpgmza_store_locator_default_address'])) { $other_settings['store_locator_default_address'] = sanitize_text_field($_POST['wpgmza_store_locator_default_address']); }
1867
- if (isset($_POST['wpgmza_store_locator_restrict'])) { $other_settings['wpgmza_store_locator_restrict'] = sanitize_text_field($_POST['wpgmza_store_locator_restrict']); }
1868
-
1869
- if(isset($_POST['store_locator_style']))
1870
- $other_settings['store_locator_style'] = sanitize_text_field($_POST['store_locator_style']);
1871
-
1872
- if(isset($_POST['wpgmza_store_locator_radius_style']))
1873
- $other_settings['wpgmza_store_locator_radius_style'] = sanitize_text_field($_POST['wpgmza_store_locator_radius_style']);
1874
-
1875
- $other_settings['map_max_zoom'] = sanitize_text_field($map_max_zoom);
1876
-
1877
- $other_settings['transport_layer'] = isset($_POST['wpgmza_transport']) ? 1 : 2;
1878
-
1879
-
1880
-
1881
-
1882
- if (isset($_POST['wpgmza_theme'])) {
1883
- $theme = intval(sanitize_text_field($_POST['wpgmza_theme']));
1884
- $theme_data = sanitize_text_field($_POST['wpgmza_theme_data_'.$theme]);
1885
- $other_settings['wpgmza_theme_data'] = $theme_data;
1886
- $other_settings['wpgmza_theme_selection'] = $theme;
1887
- }
1888
-
1889
- if(isset($_POST['wpgmza_theme_data']))
1890
- $other_settings['wpgmza_theme_data'] = sanitize_text_field(stripslashes($_POST['wpgmza_theme_data']));
1891
-
1892
- $other_settings['wpgmza_show_points_of_interest'] = (isset($_POST['wpgmza_show_points_of_interest']) ? 1 : 0);
1893
-
1894
- $other_settings['wpgmza_auto_night'] = $wpgmza_auto_night_enabled ? 1 : 0;
1895
-
1896
- $other_settings_data = maybe_serialize($other_settings);
1897
-
1898
- $data['map_default_starting_lat'] = $map_start_lat;
1899
- $data['map_default_starting_lng'] = $map_start_lng;
1900
- $data['map_default_height'] = $map_height;
1901
- $data['map_default_width'] = $map_width;
1902
- $data['map_default_zoom'] = $map_start_zoom;
1903
- $data['map_default_max_zoom'] = $map_max_zoom;
1904
- $data['map_default_type'] = $type;
1905
- $data['map_default_alignment'] = $alignment;
1906
- $data['map_default_width_type'] = $map_width_type;
1907
- $data['map_default_height_type'] = $map_height_type;
1908
-
1909
-
1910
-
1911
- $rows_affected = $wpdb->query( $wpdb->prepare(
1912
- "UPDATE $wpgmza_tblname_maps SET
1913
- map_title = %s,
1914
- map_width = %s,
1915
- map_height = %s,
1916
- map_start_lat = %f,
1917
- map_start_lng = %f,
1918
- map_start_location = %s,
1919
- map_start_zoom = %d,
1920
- type = %d,
1921
- bicycle = %d,
1922
- traffic = %d,
1923
- alignment = %d,
1924
- map_width_type = %s,
1925
- map_height_type = %s,
1926
- other_settings = %s
1927
- WHERE id = %d",
1928
-
1929
- $map_title,
1930
- $map_width,
1931
- $map_height,
1932
- $map_start_lat,
1933
- $map_start_lng,
1934
- $map_start_location,
1935
- $map_start_zoom,
1936
- $type,
1937
- $bicycle_enabled,
1938
- $traffic_enabled,
1939
- $alignment,
1940
- $map_width_type,
1941
- $map_height_type,
1942
- $other_settings_data,
1943
- $map_id)
1944
- );
1945
- update_option('WPGMZA_SETTINGS', $data);
1946
- echo "<div class='updated'>";
1947
- _e("Your settings have been saved.","wp-google-maps");
1948
- echo "</div>";
1949
- if( function_exists( 'wpgmza_caching_notice_changes' ) ){
1950
- add_action( 'admin_notices', 'wpgmza_caching_notice_changes' );
1951
- }
1952
-
1953
- }
1954
-
1955
- else if (isset($_POST['wpgmza_save_maker_location'])){
1956
- if ( !isset( $_POST['wpgmaps_marker-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_marker-nonce'], 'wpgmaps_marker-nonce' ) ) {
1957
- wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
1958
- }
1959
-
1960
- $marker = \WPGMZA\Marker::createInstance($_POST['wpgmaps_marker_id']);
1961
- $latlng = new \WPGMZA\LatLng(floatval($_POST['wpgmaps_marker_lat']), floatval($_POST['wpgmaps_marker_lng']));
1962
-
1963
- if(preg_match(\WPGMZA\LatLng::REGEXP, $marker->address))
1964
- {
1965
- $currentAddressPosition = new \WPGMZA\LatLng($marker->address);
1966
- $distance = \WPGMZA\Distance::between($currentAddressPosition, $marker->getPosition());
1967
- $meters = $distance / 1000;
1968
-
1969
- if($meters < 1)
1970
- {
1971
- // The marker has an address which looks like coordinates, and they're very close to the markers latitude and longitude
1972
- // Therefore, it would seem that the user has placed this with coordinates and is now looking to move those coordinates here
1973
- // Because of this, we'll update the address with the new coordinates
1974
- $marker->address = (string)$latlng;
1975
- }
1976
- }
1977
-
1978
- $lat = floatval($_POST['wpgmaps_marker_lat']);
1979
- $lng = floatval($_POST['wpgmaps_marker_lng']);
1980
-
1981
- $marker->lat = $lat;
1982
- $marker->lng = $lng;
1983
-
1984
- echo "<div class='updated'>";
1985
- _e("Your marker location has been saved.","wp-google-maps");
1986
- echo "</div>";
1987
-
1988
- }
1989
- else if (isset($_POST['wpgmza_save_poly'])){
1990
- if ( !isset( $_POST['wpgmaps_polygon-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_polygon-nonce'], 'wpgmaps_polygon-nonce' ) ) {
1991
- wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
1992
- }
1993
- global $wpdb;
1994
- global $wpgmza_tblname_poly;
1995
- $mid = sanitize_text_field($_POST['wpgmaps_map_id']);
1996
- if (!isset($_POST['wpgmza_polygon']) || $_POST['wpgmza_polygon'] == "") {
1997
- echo "<div class='error'>";
1998
- _e("You cannot save a blank polygon","wp-google-maps");
1999
- echo "</div>";
2000
-
2001
- } else {
2002
- $wpgmaps_polydata = sanitize_text_field($_POST['wpgmza_polygon']);
2003
- if ($wpgmaps_polydata !== "") {
2004
-
2005
- if (isset($_POST['poly_name'])) { $polyname = sanitize_text_field($_POST['poly_name']); } else { $polyname = "Polyline"; }
2006
- if (isset($_POST['poly_line'])) { $linecolor = sanitize_text_field($_POST['poly_line']); } else { $linecolor = "000000"; }
2007
- if (isset($_POST['poly_fill'])) { $fillcolor = sanitize_text_field($_POST['poly_fill']); } else { $fillcolor = "66FF00"; }
2008
- if (isset($_POST['poly_opacity'])) { $opacity = sanitize_text_field($_POST['poly_opacity']); } else { $opacity = "0.5"; }
2009
- if (isset($_POST['poly_line_opacity'])) { $line_opacity = sanitize_text_field($_POST['poly_line_opacity']); } else { $line_opacity = "0.5"; }
2010
- if (isset($_POST['poly_line_hover_line_color'])) { $ohlinecolor = sanitize_text_field($_POST['poly_line_hover_line_color']); } else { $ohlinecolor = ""; }
2011
- if (isset($_POST['poly_hover_fill_color'])) { $ohfillcolor = sanitize_text_field($_POST['poly_hover_fill_color']); } else { $ohfillcolor = ""; }
2012
- if (isset($_POST['poly_hover_opacity'])) { $ohopacity = sanitize_text_field($_POST['poly_hover_opacity']); } else { $ohopacity = ""; }
2013
- if (isset($_POST['wpgmza_polygon_inner'])) { $wpgmaps_polydatainner = sanitize_text_field($_POST['wpgmza_polygon_inner']); } else { $wpgmaps_polydatainner = ""; }
2014
-
2015
-
2016
- $rows_affected = $wpdb->query( $wpdb->prepare(
2017
- "INSERT INTO $wpgmza_tblname_poly SET
2018
- map_id = %d,
2019
- polydata = %s,
2020
- innerpolydata = %s,
2021
- polyname = %s,
2022
- linecolor = %s,
2023
- lineopacity = %s,
2024
- fillcolor = %s,
2025
- opacity = %s,
2026
- ohlinecolor = %s,
2027
- ohfillcolor = %s,
2028
- ohopacity = %s
2029
- ",
2030
-
2031
- $mid,
2032
- $wpgmaps_polydata,
2033
- $wpgmaps_polydatainner,
2034
- $polyname,
2035
- $linecolor,
2036
- $line_opacity,
2037
- $fillcolor,
2038
- $opacity,
2039
- $ohlinecolor,
2040
- $ohfillcolor,
2041
- $ohopacity
2042
- )
2043
- );
2044
- echo "<div class='updated'>";
2045
- _e("Your polygon has been created.","wp-google-maps");
2046
- echo "</div>";
2047
- }
2048
- }
2049
-
2050
-
2051
- }
2052
- else if (isset($_POST['wpgmza_edit_poly'])){
2053
- if ( !isset( $_POST['wpgmaps_polygon-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_polygon-nonce'], 'wpgmaps_polygon-nonce' ) ) {
2054
- wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
2055
- }
2056
-
2057
- global $wpdb;
2058
- global $wpgmza_tblname_poly;
2059
- $mid = sanitize_text_field($_POST['wpgmaps_map_id']);
2060
- $pid = sanitize_text_field($_POST['wpgmaps_poly_id']);
2061
- if (!isset($_POST['wpgmza_polygon']) || $_POST['wpgmza_polygon'] == "") {
2062
- echo "<div class='error'>";
2063
- _e("You cannot save a blank polygon","wp-google-maps");
2064
- echo "</div>";
2065
-
2066
- } else {
2067
- $wpgmaps_polydata = sanitize_text_field($_POST['wpgmza_polygon']);
2068
-
2069
- if (isset($_POST['poly_name'])) { $polyname = sanitize_text_field($_POST['poly_name']); } else { $polyname = "Polyline"; }
2070
- if (isset($_POST['poly_line'])) { $linecolor = sanitize_text_field($_POST['poly_line']); } else { $linecolor = "000000"; }
2071
- if (isset($_POST['poly_fill'])) { $fillcolor = sanitize_text_field($_POST['poly_fill']); } else { $fillcolor = "66FF00"; }
2072
- if (isset($_POST['poly_opacity'])) { $opacity = sanitize_text_field($_POST['poly_opacity']); } else { $opacity = "0.5"; }
2073
- if (isset($_POST['poly_line_opacity'])) { $line_opacity = sanitize_text_field($_POST['poly_line_opacity']); } else { $line_opacity = "0.5"; }
2074
- if (isset($_POST['poly_line_hover_line_color'])) { $ohlinecolor = sanitize_text_field($_POST['poly_line_hover_line_color']); } else { $ohlinecolor = ""; }
2075
- if (isset($_POST['poly_hover_fill_color'])) { $ohfillcolor = sanitize_text_field($_POST['poly_hover_fill_color']); } else { $ohfillcolor = ""; }
2076
- if (isset($_POST['poly_hover_opacity'])) { $ohopacity = sanitize_text_field($_POST['poly_hover_opacity']); } else { $ohopacity = ""; }
2077
- if (isset($_POST['wpgmza_polygon_inner'])) { $wpgmaps_polydatainner = sanitize_text_field($_POST['wpgmza_polygon_inner']); } else { $wpgmaps_polydatainner = ""; }
2078
-
2079
-
2080
-
2081
- $rows_affected = $wpdb->query( $wpdb->prepare(
2082
- "UPDATE $wpgmza_tblname_poly SET
2083
- polydata = %s,
2084
- innerpolydata = %s,
2085
- polyname = %s,
2086
- linecolor = %s,
2087
- lineopacity = %s,
2088
- fillcolor = %s,
2089
- opacity = %s,
2090
- ohlinecolor = %s,
2091
- ohfillcolor = %s,
2092
- ohopacity = %s
2093
- WHERE `id` = %d"
2094
- ,
2095
-
2096
- $wpgmaps_polydata,
2097
- $wpgmaps_polydatainner,
2098
- $polyname,
2099
- $linecolor,
2100
- $line_opacity,
2101
- $fillcolor,
2102
- $opacity,
2103
- $ohlinecolor,
2104
- $ohfillcolor,
2105
- $ohopacity,
2106
- $pid
2107
- )
2108
- );
2109
- echo "<div class='updated'>";
2110
- _e("Your polygon has been saved.","wp-google-maps");
2111
- echo "</div>";
2112
-
2113
- }
2114
-
2115
-
2116
- }
2117
- else if (isset($_POST['wpgmza_save_polyline'])){
2118
-
2119
- if ( !isset( $_POST['wpgmaps_polyline-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_polyline-nonce'], 'wpgmaps_polyline-nonce' ) ) {
2120
- wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
2121
- }
2122
-
2123
- global $wpdb;
2124
- global $wpgmza_tblname_polylines;
2125
- $mid = sanitize_text_field($_POST['wpgmaps_map_id']);
2126
- if (!isset($_POST['wpgmza_polyline']) || $_POST['wpgmza_polyline'] == "") {
2127
- echo "<div class='error'>";
2128
- _e("You cannot save a blank polyline","wp-google-maps");
2129
- echo "</div>";
2130
-
2131
- } else {
2132
- $wpgmaps_polydata = sanitize_text_field($_POST['wpgmza_polyline']);
2133
- if ($wpgmaps_polydata !== "") {
2134
-
2135
-
2136
- if (isset($_POST['poly_name'])) { $polyname = sanitize_text_field($_POST['poly_name']); } else { $polyname = ""; }
2137
- if (isset($_POST['poly_line'])) { $linecolor = sanitize_text_field($_POST['poly_line']); } else { $linecolor = "000000"; }
2138
- if (isset($_POST['poly_thickness'])) { $linethickness = sanitize_text_field($_POST['poly_thickness']); } else { $linethickness = "0"; }
2139
- if (isset($_POST['poly_opacity'])) { $opacity = sanitize_text_field($_POST['poly_opacity']); } else { $opacity = "1"; }
2140
-
2141
- $rows_affected = $wpdb->query( $wpdb->prepare(
2142
- "INSERT INTO $wpgmza_tblname_polylines SET
2143
- map_id = %d,
2144
- polydata = %s,
2145
- polyname = %s,
2146
- linecolor = %s,
2147
- linethickness = %s,
2148
- opacity = %s
2149
- ",
2150
-
2151
- $mid,
2152
- $wpgmaps_polydata,
2153
- $polyname,
2154
- $linecolor,
2155
- $linethickness,
2156
- $opacity
2157
- )
2158
- );
2159
- echo "<div class='updated'>";
2160
- _e("Your polyline has been created.","wp-google-maps");
2161
- echo "</div>";
2162
- }
2163
- }
2164
-
2165
-
2166
- }
2167
- else if (isset($_POST['wpgmza_edit_polyline'])){
2168
-
2169
- if ( !isset( $_POST['wpgmaps_polyline-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_polyline-nonce'], 'wpgmaps_polyline-nonce' ) ) {
2170
- wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
2171
- }
2172
-
2173
-
2174
- global $wpdb;
2175
- global $wpgmza_tblname_polylines;
2176
- $mid = sanitize_text_field($_POST['wpgmaps_map_id']);
2177
- $pid = sanitize_text_field($_POST['wpgmaps_poly_id']);
2178
- if (!isset($_POST['wpgmza_polyline']) || $_POST['wpgmza_polyline'] == "") {
2179
- echo "<div class='error'>";
2180
- _e("You cannot save a blank polyline","wp-google-maps");
2181
- echo "</div>";
2182
-
2183
- } else {
2184
- $wpgmaps_polydata = sanitize_text_field($_POST['wpgmza_polyline']);
2185
- if (isset($_POST['poly_name'])) { $polyname = sanitize_text_field($_POST['poly_name']); } else { $polyname = ""; }
2186
- if (isset($_POST['poly_line'])) { $linecolor = sanitize_text_field($_POST['poly_line']); } else { $linecolor = "000000"; }
2187
- if (isset($_POST['poly_thickness'])) { $linethickness = sanitize_text_field($_POST['poly_thickness']); } else { $linethickness = "0"; }
2188
- if (isset($_POST['poly_opacity'])) { $opacity = sanitize_text_field($_POST['poly_opacity']); } else { $opacity = "1"; }
2189
-
2190
- $rows_affected = $wpdb->query( $wpdb->prepare(
2191
- "UPDATE $wpgmza_tblname_polylines SET
2192
- polydata = %s,
2193
- polyname = %s,
2194
- linecolor = %s,
2195
- linethickness = %s,
2196
- opacity = %s
2197
- WHERE `id` = %d"
2198
- ,
2199
-
2200
- $wpgmaps_polydata,
2201
- $polyname,
2202
- $linecolor,
2203
- $linethickness,
2204
- $opacity,
2205
- $pid
2206
- )
2207
- );
2208
- echo "<div class='updated'>";
2209
- _e("Your polyline has been saved.","wp-google-maps");
2210
- echo "</div>";
2211
- }
2212
-
2213
-
2214
- }
2215
- else if (isset($_POST['wpgmza_save_circle'])){
2216
-
2217
- if ( !isset( $_POST['wpgmaps_circle-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_circle-nonce'], 'wpgmaps_circle-nonce' ) ) {
2218
- wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
2219
- }
2220
-
2221
- global $wpdb;
2222
- global $wpgmza_tblname_circles;
2223
-
2224
- $center = preg_replace('/[(),]/', '', sanitize_text_field($_POST['center']));
2225
-
2226
- if(isset($_POST['circle_id']))
2227
- {
2228
- $stmt = $wpdb->prepare("
2229
- UPDATE $wpgmza_tblname_circles SET
2230
- center = {$wpgmza->spatialFunctionPrefix}GeomFromText(%s),
2231
- name = %s,
2232
- color = %s,
2233
- opacity = %f,
2234
- radius = %f
2235
- WHERE id = %d
2236
- ", array(
2237
- "POINT($center)",
2238
- sanitize_text_field($_POST['circle_name']),
2239
- sanitize_hex_color($_POST['circle_color']),
2240
- floatval($_POST['circle_opacity']),
2241
- intval($_POST['circle_radius']),
2242
- intval($_POST['circle_id'])
2243
- ));
2244
- }
2245
- else
2246
- {
2247
- $stmt = $wpdb->prepare("
2248
- INSERT INTO $wpgmza_tblname_circles
2249
- (center, map_id, name, color, opacity, radius)
2250
- VALUES
2251
- ({$wpgmza->spatialFunctionPrefix}GeomFromText(%s), %d, %s, %s, %f, %f)
2252
- ", array(
2253
- "POINT($center)",
2254
- intval($_POST['wpgmaps_map_id']),
2255
- sanitize_text_field($_POST['circle_name']),
2256
- sanitize_hex_color($_POST['circle_color']),
2257
- floatval($_POST['circle_opacity']),
2258
- intval($_POST['circle_radius'])
2259
- ));
2260
- }
2261
-
2262
- $wpdb->query($stmt);
2263
-
2264
- }
2265
- else if (isset($_POST['wpgmza_save_rectangle'])){
2266
-
2267
- if ( !isset( $_POST['wpgmaps_rectangle-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_rectangle-nonce'], 'wpgmaps_rectangle-nonce' ) ) {
2268
- wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
2269
- }
2270
-
2271
- global $wpdb;
2272
- global $wpgmza_tblname_rectangles;
2273
-
2274
- $m = null;
2275
- preg_match_all('/-?\d+(\.\d+)?/', sanitize_text_field($_POST['bounds']), $m);
2276
-
2277
- $north = $m[0][0];
2278
- $east = $m[0][1];
2279
- $south = $m[0][2];
2280
- $west = $m[0][3];
2281
-
2282
- $cornerA = "POINT($north $east)";
2283
- $cornerB = "POINT($south $west)";
2284
-
2285
- if(isset($_POST['rectangle_id']))
2286
- {
2287
- $stmt = $wpdb->prepare("
2288
- UPDATE $wpgmza_tblname_rectangles SET
2289
- name = %s,
2290
- color = %s,
2291
- opacity = %f,
2292
- cornerA = {$wpgmza->spatialFunctionPrefix}GeomFromText(%s),
2293
- cornerB = {$wpgmza->spatialFunctionPrefix}GeomFromText(%s)
2294
- WHERE id = %d
2295
- ", array(
2296
- sanitize_text_field($_POST['rectangle_name']),
2297
- sanitize_hex_color($_POST['rectangle_color']),
2298
- floatval($_POST['rectangle_opacity']),
2299
- $cornerA,
2300
- $cornerB,
2301
- intval($_POST['rectangle_id'])
2302
- ));
2303
- }
2304
- else
2305
- {
2306
- $stmt = $wpdb->prepare("
2307
- INSERT INTO $wpgmza_tblname_rectangles
2308
- (map_id, name, color, opacity, cornerA, cornerB)
2309
- VALUES
2310
- (%d, %s, %s, %f, {$wpgmza->spatialFunctionPrefix}GeomFromText(%s), {$wpgmza->spatialFunctionPrefix}GeomFromText(%s))
2311
- ", array(
2312
- intval($_POST['wpgmaps_map_id']),
2313
- sanitize_text_field($_POST['rectangle_name']),
2314
- sanitize_hex_color($_POST['rectangle_color']),
2315
- floatval($_POST['rectangle_opacity']),
2316
- $cornerA,
2317
- $cornerB
2318
- ));
2319
- }
2320
-
2321
- $rows = $wpdb->query($stmt);
2322
- }
2323
- }
2324
-
2325
- /**
2326
- * Handle POST for settings page
2327
- * @return void
2328
- */
2329
- add_action('admin_post_wpgmza_settings_page_post', 'wpgmza_settings_page_post');
2330
-
2331
- function wpgmza_settings_page_post()
2332
- {
2333
- global $wpdb;
2334
- global $wpgmza;
2335
-
2336
- if(!wp_verify_nonce($_POST['wpgmza_settings_page_post_nonce'], 'wpgmza_settings_page_post'))
2337
- {
2338
- http_response_code(403);
2339
- exit;
2340
- }
2341
-
2342
- if(!$wpgmza->isUserAllowedToEdit())
2343
- {
2344
- http_response_code(401);
2345
- exit;
2346
- }
2347
-
2348
- if($wpgmza)
2349
- $wpgmza->gdprCompliance->onPOST();
2350
-
2351
- $checkboxes = array("wpgmza_settings_map_full_screen_control",
2352
- "wpgmza_settings_map_streetview",
2353
- "wpgmza_settings_map_zoom",
2354
- "wpgmza_settings_map_pan",
2355
- "wpgmza_settings_map_type",
2356
- "wpgmza_settings_map_scroll",
2357
- "wpgmza_settings_map_draggable",
2358
- "wpgmza_settings_map_clickzoom",
2359
- "wpgmza_settings_cat_display_qty",
2360
- "wpgmza_settings_force_jquery",
2361
- "wpgmza_settings_remove_api",
2362
- "wpgmza_force_greedy_gestures",
2363
- "wpgmza_settings_image_resizing",
2364
- "wpgmza_settings_infowindow_links",
2365
- "wpgmza_settings_infowindow_address",
2366
- "wpgmza_settings_disable_infowindows",
2367
- "carousel_lazyload",
2368
- "carousel_autoheight",
2369
- "carousel_pagination",
2370
- "carousel_navigation",
2371
- "wpgmza_gdpr_enabled",
2372
- "wpgmza_gdpr_require_consent_before_load",
2373
- "wpgmza_developer_mode",
2374
- 'wpgmza_prevent_other_plugins_and_theme_loading_api',
2375
- "wpgmza_gdpr_override_notice",
2376
- "wpgmza_gdpr_require_consent_before_vgm_submit",
2377
- "disable_autoptimize_compatibility_fix",
2378
- "disable_compressed_path_variables"
2379
- );
2380
-
2381
- foreach($checkboxes as $name) {
2382
- $remap = $name;
2383
-
2384
- switch($name)
2385
- {
2386
- case 'wpgmza_developer_mode':
2387
- $remap = preg_replace('/^wpgmza_/', '', $name);
2388
- break;
2389
- }
2390
-
2391
- if(!empty($_POST[$name]))
2392
- {
2393
- $wpgmza->settings[$remap] = sanitize_text_field( $_POST[$name] );
2394
- }
2395
- else if(isset($wpgmza->settings[$remap]))
2396
- {
2397
- unset($wpgmza->settings[$remap]);
2398
- }
2399
- }
2400
-
2401
- if(isset($_POST['tile_server_url']))
2402
- $wpgmza->settings['tile_server_url'] = sanitize_text_field($_POST['tile_server_url']);
2403
-
2404
- if(isset($_POST['wpgmza_load_engine_api_condition']))
2405
- $wpgmza->settings['wpgmza_load_engine_api_condition'] = sanitize_text_field($_POST['wpgmza_load_engine_api_condition']);
2406
-
2407
- if(isset($_POST['wpgmza_always_include_engine_api_on_pages']))
2408
- $wpgmza->settings['wpgmza_always_include_engine_api_on_pages'] = sanitize_text_field($_POST['wpgmza_always_include_engine_api_on_pages']);
2409
-
2410
- if(isset($_POST['wpgmza_always_exclude_engine_api_on_pages']))
2411
- $wpgmza->settings['wpgmza_always_exclude_engine_api_on_pages'] = sanitize_text_field($_POST['wpgmza_always_exclude_engine_api_on_pages']);
2412
-
2413
- if(isset($_POST['wpgmza_use_fontawesome']))
2414
- $wpgmza->settings['use_fontawesome'] = sanitize_text_field($_POST['wpgmza_use_fontawesome']);
2415
-
2416
- if(isset($_POST['wpgmza_maps_engine']))
2417
- $wpgmza->settings['wpgmza_maps_engine'] = sanitize_text_field($_POST['wpgmza_maps_engine']);
2418
-
2419
-
2420
- if (isset($_POST['wpgmza_settings_map_open_marker_by'])) { $wpgmza->settings['wpgmza_settings_map_open_marker_by'] = sanitize_text_field($_POST['wpgmza_settings_map_open_marker_by']); }
2421
-
2422
- if (isset($_POST['wpgmza_api_version'])) { $wpgmza->settings['wpgmza_api_version'] = sanitize_text_field($_POST['wpgmza_api_version']); }
2423
- if (isset($_POST['wpgmza_custom_css'])) { $wpgmza->settings['wpgmza_custom_css'] = sanitize_text_field($_POST['wpgmza_custom_css']); }
2424
- if (isset($_POST['wpgmza_custom_js'])) { $wpgmza->settings['wpgmza_custom_js'] = sanitize_text_field($_POST['wpgmza_custom_js']); }
2425
-
2426
- if (isset($_POST['user_interface_style']))
2427
- $wpgmza->settings['user_interface_style'] = esc_attr(sanitize_text_field($_POST['user_interface_style']));
2428
-
2429
- if (isset($_POST['wpgmza_marker_xml_location'])) { update_option("wpgmza_xml_location",sanitize_text_field($_POST['wpgmza_marker_xml_location'])); }
2430
- if (isset($_POST['wpgmza_marker_xml_url'])) { update_option("wpgmza_xml_url",sanitize_text_field($_POST['wpgmza_marker_xml_url'])); }
2431
-
2432
- if(current_user_can('administrator'))
2433
- if (isset($_POST['wpgmza_access_level'])) { $wpgmza->settings['wpgmza_settings_access_level'] = sanitize_text_field($_POST['wpgmza_access_level']); }
2434
-
2435
- if (isset($_POST['wpgmza_settings_marker_pull'])) { $wpgmza->settings['wpgmza_settings_marker_pull'] = sanitize_text_field($_POST['wpgmza_settings_marker_pull']); }
2436
-
2437
- // Maps -> Settings -> Store Locator -> option Store Locator Radius
2438
- if (isset($_POST['wpgmza_store_locator_radii'])) { $wpgmza->settings['wpgmza_store_locator_radii'] = sanitize_text_field($_POST['wpgmza_store_locator_radii']); }
2439
-
2440
- if (isset($_POST['wpgmza_settings_enable_usage_tracking'])) { $wpgmza->settings['wpgmza_settings_enable_usage_tracking'] = sanitize_text_field($_POST['wpgmza_settings_enable_usage_tracking']); }
2441
-
2442
- $arr = apply_filters("wpgooglemaps_filter_save_settings", $wpgmza->settings);
2443
-
2444
- $wpgmza->settings->set($arr);
2445
-
2446
- if( isset( $_POST['wpgmza_google_maps_api_key'] ) ){ update_option( 'wpgmza_google_maps_api_key', sanitize_text_field( trim($_POST['wpgmza_google_maps_api_key'] )) ); }
2447
-
2448
- if($_POST['wpgmza_settings_marker_pull'] == 1)
2449
- wpgmaps_update_all_xml_file();
2450
-
2451
- wp_redirect(get_admin_url() . 'admin.php?page=wp-google-maps-menu-settings');
2452
- exit;
2453
- }
2454
-
2455
- add_action('wp_ajax_add_marker', 'wpgmaps_action_callback_pro');
2456
- add_action('wp_ajax_delete_marker', 'wpgmaps_action_callback_pro');
2457
- add_action('wp_ajax_edit_marker', 'wpgmaps_action_callback_pro');
2458
- add_action('wp_ajax_approve_marker', 'wpgmaps_action_callback_pro');
2459
- add_action('wp_ajax_delete_marker', 'wpgmaps_action_callback_pro'); // NB: Legacy support
2460
- add_action('wp_ajax_delete_poly', 'wpgmaps_action_callback_pro');
2461
- add_action('wp_ajax_delete_polyline', 'wpgmaps_action_callback_pro');
2462
- add_action('wp_ajax_delete_dataset', 'wpgmaps_action_callback_pro');
2463
- add_action('wp_ajax_delete_circle', 'wpgmaps_action_callback_pro');
2464
- add_action('wp_ajax_delete_rectangle', 'wpgmaps_action_callback_pro');
2465
-
2466
- if (function_exists('wpgmaps_head_pro' )) {
2467
- add_action( 'admin_head', 'wpgmaps_head_pro' );
2468
- } else {
2469
-
2470
- if (function_exists( 'wpgmaps_pro_activate' ) && floatval($wpgmza_version) < 5.24) {
2471
- add_action( 'admin_notices', function() {
2472
-
2473
- ?>
2474
- <div class="notice notice-error">
2475
- <p>
2476
- <?php
2477
- _e('<strong>WP Google Maps:</strong> The Pro add-on is not compatible with this version of WP Google Maps. Please update your Pro addon to 5.24 or above', 'wp-google-maps');
2478
- ?>
2479
- </p>
2480
- </div>
2481
- <?php
2482
-
2483
- });
2484
- } else {
2485
- add_action( 'admin_head', 'wpgmaps_head' );
2486
- }
2487
-
2488
- }
2489
-
2490
- if(!function_exists('wpgmaps_trash_map'))
2491
- {
2492
- function wpgmaps_trash_map($map_id) {
2493
- global $wpdb;
2494
- global $wpgmza_tblname_maps;
2495
- if (isset($map_id)) {
2496
- $wpdb->query(
2497
- $wpdb->prepare('DELETE FROM wp_wpgmza WHERE map_id=%d', (int)$map_id)
2498
- );
2499
- $rows_affected = $wpdb->query( $wpdb->prepare( "UPDATE $wpgmza_tblname_maps SET active = %d WHERE id = %d", 1, $map_id) );
2500
- return true;
2501
- } else {
2502
- return false;
2503
- }
2504
- }
2505
  }
1
+ <?php
2
+
3
+ function wpgmza_get_legacy_pro_shape_editor_dependencies() {
4
+ $scriptLoader = new \WPGMZA\ScriptLoader();
5
+ $handles = array_keys($scriptLoader->getPluginScripts());
6
+
7
+ return $handles;
8
+ }
9
+
10
+ function wpgmza_convert_json_geometry_to_legacy_format($json) {
11
+ $arr = array();
12
+ if (is_array($json)) {
13
+ foreach($json as $obj)
14
+ $arr []= "{$obj->lat},{$obj->lng}";
15
+ }
16
+
17
+ return $arr;
18
+ }
19
+
20
+ function wpgmza_convert_shape_options_to_legacy_format($data) {
21
+ // Convert new format colors to legacy format colors
22
+ foreach($data as $key => $value) {
23
+ if(preg_match('/color/', $key))
24
+ $data->{$key} = preg_replace("/^#/", "", $value);
25
+ }
26
+
27
+ return $data;
28
+ }
29
+
30
+ if(!function_exists('wpgmza_get_marker_columns')) {
31
+ function wpgmza_get_marker_columns() {
32
+ global $wpdb;
33
+ global $wpgmza;
34
+ global $wpgmza_tblname;
35
+ global $wpgmza_pro_version;
36
+
37
+ $useSpatialData = empty($wpgmza_pro_version) || version_compare($wpgmza_pro_version, '7.0.0', '>=');
38
+
39
+ $columns = $wpdb->get_col("SHOW COLUMNS FROM $wpgmza_tblname");
40
+
41
+ if($useSpatialData)
42
+ {
43
+ if(($index = array_search('lat', $columns)) !== false)
44
+ array_splice($columns, $index, 1);
45
+ if(($index = array_search('lng', $columns)) !== false)
46
+ array_splice($columns, $index, 1);
47
+ }
48
+
49
+ for($i = count($columns) - 1; $i >= 0; $i--)
50
+ $columns[$i] = '`' . trim($columns[$i], '`') . '`';
51
+
52
+ if($useSpatialData)
53
+ {
54
+ $columns[] = "{$wpgmza->spatialFunctionPrefix}X(latlng) AS lat";
55
+ $columns[] = "{$wpgmza->spatialFunctionPrefix}Y(latlng) AS lng";
56
+ }
57
+
58
+ return $columns;
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Render polygon editor HTML
64
+ * @param integer $mid Map ID
65
+ * @return string HTML outut
66
+ */
67
+ function wpgmza_b_pro_add_poly($mid) {
68
+
69
+ global $wpgmza_tblname_maps;
70
+ global $wpdb;
71
+ if ($_GET['action'] == "add_poly" && isset($mid)) {
72
+
73
+ if( function_exists('google_maps_api_key_warning' ) ){ google_maps_api_key_warning(); }
74
+
75
+ $mid = sanitize_text_field($mid);
76
+ $res = wpgmza_get_map_data($mid);
77
+ echo "
78
+
79
+
80
+
81
+
82
+ <div class='wrap'>
83
+ <h1>WP Google Maps</h1>
84
+ <div class='wide'>
85
+
86
+ <h2>".__("Add a Polygon","wp-google-maps")."</h2>
87
+ <form action='?page=wp-google-maps-menu&action=edit&map_id=".esc_attr($mid)."' method='post' id='wpgmaps_add_poly_form'>
88
+ <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".esc_attr($mid)."' />
89
+ <input type='hidden' name='wpgmaps_polygon-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_polygon-nonce' )."' />
90
+
91
+ <table class='wpgmza-listing-comp' style='width:30%;float:left; height:400px;'>
92
+ <tr>
93
+ <td>".__("Name","wp-google-maps")."</td><td><input type=\"text\" value=\"\" name=\"poly_name\" placeholder='".__("Name","wp-google-maps")."'/></td>
94
+ </tr>
95
+ <tr>
96
+ <td>".__("Title","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\" /><i class='wpgmza-info__small'><a href='".wpgm_pro_link("http://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&utm_medium=link&utm_campaign=polygons")."' title='".__("Pro Version","wp-google-maps")."'>".__("Get the Pro add-on","wp-google-maps")."</a></i></td>
97
+ </tr>
98
+ <tr>
99
+ <td>".__("Link","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"Pro version only\" /></td>
100
+ </tr>
101
+ <tr>
102
+ <td>".__("Line Color","wp-google-maps")."</td><td><input id=\"poly_line\" name=\"poly_line\" type=\"text\" class=\"color\" value=\"000000\" /></td>
103
+ </tr>
104
+ <tr>
105
+ <td>".__("Line Opacity","wp-google-maps")."</td><td><input id=\"poly_line_opacity\" name=\"poly_line_opacity\" type=\"text\" value=\"0.5\" /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.5 for 50%</small></td>
106
+ </tr>
107
+ <tr>
108
+ <td>".__("Fill Color","wp-google-maps")."</td><td><input id=\"poly_fill\" name=\"poly_fill\" type=\"text\" class=\"color\" value=\"66ff00\" /></td>
109
+ </tr>
110
+ <tr>
111
+ <td>".__("Opacity","wp-google-maps")."</td><td><input id=\"poly_opacity\" name=\"poly_opacity\" type=\"text\" value=\"0.5\" /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.5 for 50%</small></td>
112
+ </tr>
113
+ <tr>
114
+ <td>".__("On Hover Line Color","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\"/></td>
115
+ </tr>
116
+ <tr>
117
+ <td>".__("On Hover Fill Color","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\"/></td>
118
+ </tr>
119
+ <tr>
120
+ <td>".__("On Hover Opacity","wp-google-maps")."</td><td><input disabled type=\"text\"value=\"".__("Pro version only","wp-google-maps")."\" /></td>
121
+ </tr>
122
+
123
+
124
+ </table>
125
+
126
+ <div class='wpgmza_map_seventy'>
127
+ <div id=\"wpgmza_map\">&nbsp;</div>
128
+
129
+ <p>
130
+ <ul style=\"list-style:initial;\" class='update-nag update-blue update-slim update-map-overlay'>
131
+
132
+ <li style=\"margin-left:30px;\">".__("Click on the map to insert a vertex.","wp-google-maps")."</li>
133
+ <li style=\"margin-left:30px;\">".__("Click on a vertex to remove it.","wp-google-maps")."</li>
134
+ <li style=\"margin-left:30px;\">".__("Drag a vertex to move it.","wp-google-maps")."</li>
135
+ </ul>
136
+ </p>
137
+ </div>
138
+
139
+ <div id='wpgmza-polygon-textarea' style='clear: both;'><label>Polygon data:</label><br /><textarea name=\"wpgmza_polygon\" id=\"poly_line_list\" style=\"width:90%; height:100px; border:1px solid #ccc; background-color:#FFF; padding:5px; overflow:auto;\"></textarea>
140
+ </div>
141
+ <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_save_poly' class='button-primary' value='".__("Save Polygon","wp-google-maps")." &raquo;' /></p>
142
+
143
+ </form>
144
+ </div>
145
+ </div>
146
+ ";
147
+ }
148
+ }
149
+
150
+
151
+ /**
152
+ * Render polygon editor HTML (edit mode)
153
+ * @param integer $mid Map ID
154
+ * @return string HTML outut
155
+ */
156
+ function wpgmza_b_pro_edit_poly($mid) {
157
+ global $wpgmza_tblname_maps;
158
+ global $wpdb;
159
+
160
+ if ($_GET['action'] == "edit_poly" && isset($mid)) {
161
+ $mid = sanitize_text_field($mid);;
162
+ $res = wpgmza_get_map_data($mid);
163
+ $pol = wpgmza_b_return_poly_options(sanitize_text_field($_GET['poly_id']));
164
+
165
+ echo "
166
+
167
+
168
+ <div class='wrap'>
169
+ <h1>WP Google Maps</h1>
170
+ <div class='wide'>
171
+
172
+ <h2>".__("Edit Polygon","wp-google-maps")."</h2>
173
+ <form action='?page=wp-google-maps-menu&action=edit&map_id=".esc_attr($mid)."' method='post' id='wpgmaps_edit_poly_form'>
174
+ <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".esc_attr($mid)."' />
175
+ <input type='hidden' name='wpgmaps_poly_id' id='wpgmaps_poly_id' value='".esc_attr(intval($_GET['poly_id']))."' />
176
+ <input type='hidden' name='wpgmaps_polygon-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_polygon-nonce' )."' />
177
+
178
+ <table class='wpgmza-listing-comp' style='width:30%;float:left; height:400px;'>
179
+ <tr>
180
+ <td>".__("Name","wp-google-maps")."</td><td><input type=\"text\" value=\"".esc_attr(stripslashes($pol->polyname))."\" name=\"poly_name\" /></td>
181
+ </tr>
182
+ <tr>
183
+ <td>".__("Title","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\" /><i><a href='".wpgm_pro_link("http://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&utm_medium=link&utm_campaign=polygons")."' title='".__("Pro Version","wp-google-maps")."'>".__("Get the Pro add-on","wp-google-maps")."</a></i></td>
184
+ </tr>
185
+ <tr>
186
+ <td>".__("Description","wp-google-maps")."</td><td><textarea disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\"></textarea><i><a href='".wpgm_pro_link("http://www.wpgmaps.com/purchase-professional-version/?utm_source=plugin&utm_medium=link&utm_campaign=polygons")."' title='".__("Pro Version","wp-google-maps")."'>".__("Get the Pro add-on","wp-google-maps")."</a></i></td>
187
+ </tr>
188
+ <tr>
189
+ <td>".__("Link","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"pro version only\" /></td>
190
+ </tr>
191
+ <tr>
192
+ <td>".__("Line Color","wp-google-maps")."</td><td><input id=\"poly_line\" name=\"poly_line\" type=\"text\" class=\"color\" value=\"".esc_attr($pol->linecolor)."\" /></td>
193
+ </tr>
194
+ <tr>
195
+ <td>".__("Line Opacity","wp-google-maps")."</td><td><input id=\"poly_line_opacity\" name=\"poly_line_opacity\" type=\"text\" value=\"".esc_attr($pol->lineopacity)."\" /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.5 for 50%</small></td>
196
+ </tr>
197
+ <tr>
198
+ <td>".__("Fill Color","wp-google-maps")."</td><td><input id=\"poly_fill\" name=\"poly_fill\" type=\"text\" class=\"color\" value=\"".esc_attr($pol->fillcolor)."\" /></td>
199
+ </tr>
200
+ <tr>
201
+ <td>".__("Opacity","wp-google-maps")."</td><td><input id=\"poly_opacity\" name=\"poly_opacity\" type=\"text\" value=\"".esc_attr($pol->opacity)."\" /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.5 for 50%</small></td>
202
+ </tr>
203
+ <tr>
204
+ <td>".__("On Hover Line Color","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\"/></td>
205
+ </tr>
206
+ <tr>
207
+ <td>".__("On Hover Fill Color","wp-google-maps")."</td><td><input disabled type=\"text\" value=\"".__("Pro version only","wp-google-maps")."\"/></td>
208
+ </tr>
209
+ <tr>
210
+ <td>".__("On Hover Opacity","wp-google-maps")."</td><td><input disabled type=\"text\"value=\"".__("Pro version only","wp-google-maps")."\" /></td>
211
+ </tr>
212
+ <tr>
213
+ <td>".__("Show Polygon","wp-google-maps")."</td>
214
+ <td>
215
+ <button id='fit-bounds-to-shape'
216
+ class='button button-secondary'
217
+ type='button'
218
+ title='" . __('Fit map bounds to shape', 'wp-google-maps') . "'
219
+ data-fit-bounds-to-shape='poly'>
220
+ <i class='fas fa-eye'></i>
221
+ </button>
222
+ </td>
223
+ </tr>
224
+ </table>
225
+
226
+ <div class='wpgmza_map_seventy'>
227
+ <div id=\"wpgmza_map\" >&nbsp;</div>
228
+ <p>
229
+ <ul style=\"list-style:initial;\" class='update-nag update-blue update-slim update-map-overlay'>
230
+
231
+ <li style=\"margin-left:30px;\">Click on the map to insert a vertex.</li>
232
+ <li style=\"margin-left:30px;\">Click on a vertex to remove it.</li>
233
+ <li style=\"margin-left:30px;\">Drag a vertex to move it.</li>
234
+ </ul>
235
+ </p>
236
+ </div>
237
+
238
+ <div class='clear'></div>
239
+ <p style='clear: both;' >Polygon data:<br /><textarea name=\"wpgmza_polygon\" id=\"poly_line_list\" style=\"height:100px; background-color:#FFF; padding:5px; overflow:auto;\"></textarea>
240
+ <!-- <p style='clear: both;' >Polygon data (inner):<br /><textarea name=\"wpgmza_polygon_inner\" id=\"poly_line_list_inner\" style=\"width:90%; height:100px; border:1px solid #ccc; background-color:#FFF; padding:5px; overflow:auto;\">".esc_textarea($pol->innerpolydata)."</textarea> -->
241
+ <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_edit_poly' class='button-primary' value='".__("Save Polygon","wp-google-maps")." &raquo;' /></p>
242
+
243
+ </form>
244
+ </div>
245
+
246
+
247
+ </div>
248
+
249
+
250
+
251
+ ";
252
+
253
+ }
254
+
255
+
256
+
257
+ }
258
+
259
+ /**
260
+ * Render polygons JS
261
+ *
262
+ * @todo This needs to be converted to a native JS file with localized variables
263
+ *
264
+ * @param integer $mapid Map ID
265
+ *
266
+ * @return void
267
+ */
268
+ function wpgmaps_b_admin_add_poly_javascript($mapid)
269
+ {
270
+ $res = wpgmza_get_map_data(sanitize_text_field($_GET['map_id']));
271
+ $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
272
+
273
+
274
+ $wpgmza_lat = $res->map_start_lat;
275
+ $wpgmza_lng = $res->map_start_lng;
276
+ $wpgmza_map_type = $res->type;
277
+ $wpgmza_width = $res->map_width;
278
+ $wpgmza_height = $res->map_height;
279
+ $wpgmza_width_type = $res->map_width_type;
280
+ $wpgmza_height_type = $res->map_height_type;
281
+ if (!$wpgmza_map_type || $wpgmza_map_type == "" || $wpgmza_map_type == "1") { $wpgmza_map_type = "ROADMAP"; }
282
+ else if ($wpgmza_map_type == "2") { $wpgmza_map_type = "SATELLITE"; }
283
+ else if ($wpgmza_map_type == "3") { $wpgmza_map_type = "HYBRID"; }
284
+ else if ($wpgmza_map_type == "4") { $wpgmza_map_type = "TERRAIN"; }
285
+ else { $wpgmza_map_type = "ROADMAP"; }
286
+ $start_zoom = $res->map_start_zoom;
287
+ if ($start_zoom < 1 || !$start_zoom) {
288
+ $start_zoom = 5;
289
+ }
290
+
291
+ if (isset($res->kml)) { $kml = $res->kml; } else { $kml = false; }
292
+
293
+ $localized_data = array(
294
+ 'wpgmza_lat' => $wpgmza_lat,
295
+ 'wpgmza_lng' => $wpgmza_lng,
296
+ 'start_zoom' => $start_zoom,
297
+ 'wpgmza_width' => $wpgmza_width,
298
+ 'wpgmza_width_type' => $wpgmza_width_type,
299
+ 'wpgmza_height' => $wpgmza_height,
300
+ 'wpgmza_height_type' => $wpgmza_height_type,
301
+ 'wpgmza_map_type' => $wpgmza_map_type,
302
+ 'polygon_data' => array()
303
+ );
304
+
305
+ $total_poly_array = wpgmza_b_return_polygon_id_array(sanitize_text_field($_GET['map_id']));
306
+
307
+ foreach ($total_poly_array as $poly_id)
308
+ {
309
+ $polyoptions = wpgmza_b_return_poly_options($poly_id);
310
+ $linecolor = $polyoptions->linecolor;
311
+ $fillcolor = $polyoptions->fillcolor;
312
+ $fillopacity = $polyoptions->opacity;
313
+ $lineopacity = $polyoptions->lineopacity;
314
+ $title = $polyoptions->title;
315
+ $link = $polyoptions->link;
316
+ $ohlinecolor = $polyoptions->ohlinecolor;
317
+ $ohfillcolor = $polyoptions->ohfillcolor;
318
+ $ohopacity = $polyoptions->ohopacity;
319
+ if (!$linecolor) { $linecolor = "000000"; }
320
+ if (!$fillcolor) { $fillcolor = "66FF00"; }
321
+ if ($fillopacity == "") { $fillopacity = "0.5"; }
322
+ if ($lineopacity == "") { $lineopacity = "1.0"; }
323
+ if ($ohlinecolor == "") { $ohlinecolor = $linecolor; }
324
+ if ($ohfillcolor == "") { $ohfillcolor = $fillcolor; }
325
+ if ($ohopacity == "") { $ohopacity = $fillopacity; }
326
+ $linecolor = "#".$linecolor;
327
+ $fillcolor = "#".$fillcolor;
328
+ $ohlinecolor = "#".$ohlinecolor;
329
+ $ohfillcolor = "#".$ohfillcolor;
330
+
331
+ $poly_array = wpgmza_b_return_polygon_array($poly_id);
332
+ $path_data = array();
333
+
334
+ foreach($poly_array as $single_poly)
335
+ {
336
+ $poly_data_raw = str_replace(" ","",$single_poly);
337
+ $poly_data_raw = explode(",",$poly_data_raw);
338
+ $lat = $poly_data_raw[0];
339
+ $lng = $poly_data_raw[1];
340
+
341
+ $path_data[] = array(
342
+ 'lat' => $lat,
343
+ 'lng' => $lng
344
+ );
345
+ }
346
+
347
+ $localized_data['polygon_data'][$poly_id] = array(
348
+ 'strokeColor' => $linecolor,
349
+ 'fillOpacity' => $fillopacity,
350
+ 'strokeOpacity' => $lineopacity,
351
+ 'fillColor' => $fillcolor,
352
+ 'path' => $path_data
353
+ );
354
+ }
355
+
356
+ $dependencies = wpgmza_get_legacy_pro_shape_editor_dependencies();
357
+
358
+ wp_enqueue_style('wpgooglemaps-css', wpgmaps_get_plugin_url() . 'css/wpgmza_style.css');
359
+ wp_enqueue_script('wpgmza-legacy-polygon-panel', wpgmaps_get_plugin_url() . 'js/legacy/legacy-polygon-panel.js', $dependencies);
360
+ wp_localize_script('wpgmza-legacy-polygon-panel', 'wpgmza_legacy_polygon_panel_vars', $localized_data);
361
+ }
362
+
363
+ /**
364
+ * Render polygon edit JS
365
+ *
366
+ * @todo This needs to be converted to a native JS file with localized variables
367
+ *
368
+ * @param integer $mapid Map ID
369
+ * @param integer $polyid Polygon ID
370
+ *
371
+ * @return void
372
+ */
373
+ function wpgmaps_b_admin_edit_poly_javascript($mapid,$polyid)
374
+ {
375
+ $res = wpgmza_get_map_data($mapid);
376
+ $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
377
+ $wpgmza_lat = $res->map_start_lat;
378
+ $wpgmza_lng = $res->map_start_lng;
379
+ $wpgmza_map_type = $res->type;
380
+ $wpgmza_width = $res->map_width;
381
+ $wpgmza_height = $res->map_height;
382
+ $wpgmza_width_type = $res->map_width_type;
383
+ $wpgmza_height_type = $res->map_height_type;
384
+
385
+ if (!$wpgmza_map_type || $wpgmza_map_type == "" || $wpgmza_map_type == "1") { $wpgmza_map_type = "ROADMAP"; }
386
+ else if ($wpgmza_map_type == "2") { $wpgmza_map_type = "SATELLITE"; }
387
+ else if ($wpgmza_map_type == "3") { $wpgmza_map_type = "HYBRID"; }
388
+ else if ($wpgmza_map_type == "4") { $wpgmza_map_type = "TERRAIN"; }
389
+ else { $wpgmza_map_type = "ROADMAP"; }
390
+ $start_zoom = $res->map_start_zoom;
391
+ if ($start_zoom < 1 || !$start_zoom) {
392
+ $start_zoom = 5;
393
+ }
394
+ if (isset($res->kml)) { $kml = $res->kml; } else { $kml = false; }
395
+
396
+ $localized_data = array(
397
+ 'wpgmza_lat' => $wpgmza_lat,
398
+ 'wpgmza_lng' => $wpgmza_lng,
399
+ 'start_zoom' => $start_zoom,
400
+ 'wpgmza_width' => $wpgmza_width,
401
+ 'wpgmza_width_type' => $wpgmza_width_type,
402
+ 'wpgmza_height' => $wpgmza_height,
403
+ 'wpgmza_height_type' => $wpgmza_height_type,
404
+ 'wpgmza_map_type' => $wpgmza_map_type,
405
+ 'polygon_data' => array()
406
+ );
407
+
408
+ $total_poly_array = wpgmza_b_return_polygon_id_array(sanitize_text_field($_GET['map_id']));
409
+
410
+ foreach ($total_poly_array as $poly_id)
411
+ {
412
+ $polyoptions = wpgmza_b_return_poly_options($poly_id);
413
+ $linecolor = $polyoptions->linecolor;
414
+ $fillcolor = $polyoptions->fillcolor;
415
+ $fillopacity = $polyoptions->opacity;
416
+ $lineopacity = $polyoptions->lineopacity;
417
+ $title = $polyoptions->title;
418
+ $link = $polyoptions->link;
419
+ $ohlinecolor = $polyoptions->ohlinecolor;
420
+ $ohfillcolor = $polyoptions->ohfillcolor;
421
+ $ohopacity = $polyoptions->ohopacity;
422
+ if (!$linecolor) { $linecolor = "000000"; }
423
+ if (!$fillcolor) { $fillcolor = "66FF00"; }
424
+ if ($fillopacity == "") { $fillopacity = "0.5"; }
425
+ if ($lineopacity == "") { $lineopacity = "1.0"; }
426
+ if ($ohlinecolor == "") { $ohlinecolor = $linecolor; }
427
+ if ($ohfillcolor == "") { $ohfillcolor = $fillcolor; }
428
+ if ($ohopacity == "") { $ohopacity = $fillopacity; }
429
+ $linecolor = "#".$linecolor;
430
+ $fillcolor = "#".$fillcolor;
431
+ $ohlinecolor = "#".$ohlinecolor;
432
+ $ohfillcolor = "#".$ohfillcolor;
433
+
434
+ $poly_array = wpgmza_b_return_polygon_array($poly_id);
435
+ $path_data = array();
436
+
437
+ foreach($poly_array as $single_poly)
438
+ {
439
+ $poly_data_raw = str_replace(" ","",$single_poly);
440
+ $poly_data_raw = explode(",",$poly_data_raw);
441
+ $lat = $poly_data_raw[0];
442
+ $lng = $poly_data_raw[1];
443
+
444
+ $path_data[] = array(
445
+ 'lat' => $lat,
446
+ 'lng' => $lng
447
+ );
448
+ }
449
+
450
+ $localized_data['polygon_data'][$poly_id] = array(
451
+ 'storkeColor' => $linecolor,
452
+ 'fillOpacity' => $fillopacity,
453
+ 'strokeOpacity' => $lineopacity,
454
+ 'fillColor' => $fillcolor,
455
+ 'path' => $path_data
456
+ );
457
+ }
458
+
459
+ $dependencies = wpgmza_get_legacy_pro_shape_editor_dependencies();
460
+
461
+ wp_enqueue_style('wpgooglemaps-css', wpgmaps_get_plugin_url() . 'css/wpgmza_style.css');
462
+ wp_enqueue_script('wpgmza-legacy-polygon-panel', wpgmaps_get_plugin_url() . 'js/legacy/legacy-polygon-panel.js', $dependencies);
463
+ wp_localize_script('wpgmza-legacy-polygon-panel', 'wpgmza_legacy_polygon_panel_vars', $localized_data);
464
+ }
465
+
466
+ /**
467
+ * Returns the list of polygons displayed in the map editor
468
+ *
469
+ * @todo Build this as a hook or filter instead of a function call
470
+ *
471
+ * @param integer $map_id Map ID
472
+ * @param boolean $admin Identify if user is admin or not
473
+ * @param string $width Width to be used for HTML output
474
+ * @return string List HTML
475
+ */
476
+ function wpgmza_b_return_polygon_list($map_id,$admin = true,$width = "100%") {
477
+ wpgmaps_debugger("return_marker_start");
478
+
479
+ global $wpdb;
480
+ global $wpgmza_tblname_poly;
481
+ $wpgmza_tmp = "";
482
+
483
+ $results = $wpdb->get_results( $wpdb->prepare("SELECT * FROM $wpgmza_tblname_poly WHERE `map_id` = %d ORDER BY `id` DESC", intval($map_id)) );
484
+
485
+ $wpgmza_tmp .= "
486
+
487
+ <table id=\"wpgmza_table_poly\" class=\"display\" cellspacing=\"0\" cellpadding=\"0\" style=\"width:$width;\">
488
+ <thead>
489
+ <tr>
490
+ <th align='left'><strong>".__("ID","wp-google-maps")."</strong></th>
491
+ <th align='left'><strong>".__("Name","wp-google-maps")."</strong></th>
492
+ <th align='left' style='width:182px;'><strong>".__("Action","wp-google-maps")."</strong></th>
493
+ </tr>
494
+ </thead>
495
+ <tbody>
496
+ ";
497
+ $res = wpgmza_get_map_data($map_id);
498
+ $default_marker = "<img src='".$res->default_marker."' />";
499
+
500
+ //$wpgmza_data = get_option('WPGMZA');
501
+ //if ($wpgmza_data['map_default_marker']) { $default_icon = "<img src='".$wpgmza_data['map_default_marker']."' />"; } else { $default_icon = "<img src='".wpgmaps_get_plugin_url()."/images/marker.png' />"; }
502
+
503
+ foreach ( $results as $result ) {
504
+ unset($poly_data);
505
+ unset($poly_array);
506
+ $poly_data = '';
507
+ $poly_array = wpgmza_b_return_polygon_array($result->id);
508
+ if (is_array($poly_array)) {
509
+ foreach ($poly_array as $poly_single) {
510
+ $poly_data .= $poly_single.",";
511
+ }
512
+ }
513
+ if (isset($result->polyname) && $result->polyname != "") { $polygon_name = $result->polyname; } else { $polygon_name = "Polygon".$result->id; }
514
+
515
+ $wpgmza_tmp .= "
516
+ <tr id=\"wpgmza_poly_tr_".intval($result->id)."\">
517
+ <td height=\"40\">".intval($result->id)."</td>
518
+ <td height=\"40\">".esc_attr(stripslashes($polygon_name))."</td>
519
+ <td width='170' align='left'>
520
+ <a href=\"".esc_url(get_option('siteurl'))."/wp-admin/admin.php?page=wp-google-maps-menu&action=edit_poly&map_id=".intval($map_id)."&poly_id=".intval($result->id)."\" title=\"".__("Edit","wp-google-maps")."\" class=\"wpgmza_edit_poly_btn button\" id=\"".intval($result->id)."\"><i class=\"fa fa-edit\"> </i></a>
521
+ <a href=\"javascript:void(0);\" title=\"".__("Delete this polygon","wp-google-maps")."\" class=\"wpgmza_poly_del_btn button\" id=\"".intval($result->id)."\"><i class=\"fa fa-times\"> </i></a>
522
+ </td>
523
+ </tr>";
524
+
525
+ }
526
+ $wpgmza_tmp .= "</tbody></table>";
527
+
528
+
529
+ return $wpgmza_tmp;
530
+
531
+ }
532
+
533
+ /**
534
+ * Retrieve polygon options from DB
535
+ *
536
+ * @param integer $poly_id Polygon ID
537
+ * @return array MYSQL Array
538
+ */
539
+ function wpgmza_b_return_poly_options($poly_id) {
540
+ global $wpdb;
541
+ global $wpgmza_tblname_poly;
542
+
543
+ $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_poly WHERE `id` = %d LIMIT 1",intval($poly_id)) );
544
+
545
+ if(empty($results))
546
+ return;
547
+
548
+ $data = $results[0];
549
+
550
+ return wpgmza_convert_shape_options_to_legacy_format($data);
551
+ }
552
+
553
+ /**
554
+ * Return the polygon data in the correct format
555
+ *
556
+ * @param integer $poly_id Polygon ID
557
+ * @return array Poly data array
558
+ */
559
+ function wpgmza_b_return_polygon_array($poly_id) {
560
+ global $wpdb;
561
+ global $wpgmza_tblname_poly;
562
+
563
+ $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_poly WHERE `id` = %d LIMIT 1",intval($poly_id)) );
564
+
565
+ if(empty($results))
566
+ return null;
567
+
568
+ $polyline = $results[0];
569
+ $polydata = $polyline->polydata;
570
+
571
+ if(($json = json_decode($polydata)) !== false)
572
+ return wpgmza_convert_json_geometry_to_legacy_format($json);
573
+
574
+ $regex = '/-?(\d+)(\.\d+)?,\s*-?(\d+)(\.\d+)?/';
575
+
576
+ if(!preg_match_all($regex, $polydata, $m))
577
+ return array();
578
+
579
+ return $m[0];
580
+ }
581
+
582
+ /**
583
+ * Return polygon ID array
584
+ *
585
+ * This is used when creating the JSON array of all the polygons and their unique options
586
+ *
587
+ * @param integer $map_id Map ID
588
+ * @return array Array of IDs
589
+ */
590
+ function wpgmza_b_return_polygon_id_array($map_id) {
591
+ global $wpdb;
592
+ global $wpgmza_tblname_poly;
593
+ $ret = array();
594
+ $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_poly WHERE `map_id` = %d",intval($map_id)) );
595
+ foreach ( $results as $result ) {
596
+ $current_id = $result->id;
597
+ $ret[] = $current_id;
598
+
599
+ }
600
+ return $ret;
601
+ }
602
+
603
+ function wpgmza_b_pro_add_polyline($mid) {
604
+ global $wpgmza_tblname_maps;
605
+ global $wpdb;
606
+ if ($_GET['action'] == "add_polyline" && isset($mid)) {
607
+
608
+ if( function_exists('google_maps_api_key_warning' ) ){ google_maps_api_key_warning(); }
609
+
610
+ $res = wpgmza_get_map_data($mid);
611
+ echo "
612
+
613
+
614
+
615
+
616
+ <div class='wrap'>
617
+ <h1>WP Google Maps</h1>
618
+ <div class='wide'>
619
+
620
+ <h2>".__("Add a Polyline","wp-google-maps")."</h2>
621
+ <form action='?page=wp-google-maps-menu&action=edit&map_id=".intval($mid)."' method='post' id='wpgmaps_add_polyline_form'>
622
+ <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".intval($mid)."' />
623
+ <input type='hidden' name='wpgmaps_polyline-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_polyline-nonce' )."' />
624
+ <table class='wpgmza-listing-comp' style='width:30%;float:left;'>
625
+ <tr>
626
+ <td>
627
+ ".__("Name","wp-google-maps")."
628
+ </td>
629
+ <td>
630
+ <input id=\"poly_name\" name=\"poly_name\" type=\"text\" value=\"\" />
631
+ </td>
632
+ </tr>
633
+ <tr>
634
+ <td>
635
+ ".__("Line Color","wp-google-maps")."
636
+ </td>
637
+ <td>
638
+ <input id=\"poly_line\" name=\"poly_line\" type=\"text\" class=\"color\" value=\"000000\" />
639
+ </td>
640
+ </tr>
641
+ <tr>
642
+ <td>
643
+ ".__("Opacity","wp-google-maps")."
644
+ </td>
645
+ <td>
646
+ <input id=\"poly_opacity\" name=\"poly_opacity\" type=\"text\" value=\"0.8\" /> (0 - 1.0) example: 0.8 for 80%
647
+ </td>
648
+ </tr>
649
+ <tr>
650
+ <td>
651
+ ".__("Line Thickness","wp-google-maps")."
652
+ </td>
653
+ <td>
654
+ <input id=\"poly_thickness\" name=\"poly_thickness\" type=\"text\" value=\"4\" /> (0 - 50) example: 4
655
+ </td>
656
+
657
+ </tr>
658
+
659
+
660
+
661
+ </table>
662
+ <div class='wpgmza_map_seventy'>
663
+ <div id=\"wpgmza_map\">&nbsp;</div>
664
+ <p>
665
+
666
+ <ul style=\"list-style:initial;\" class='update-nag update-blue update-slim update-map-overlay'>
667
+
668
+ <li style=\"margin-left:30px;\">Click on the map to insert a vertex.</li>
669
+ <li style=\"margin-left:30px;\">Click on a vertex to remove it.</li>
670
+ <li style=\"margin-left:30px;\">Drag a vertex to move it.</li>
671
+ </ul>
672
+ </p>
673
+ </div>
674
+
675
+
676
+ <p style='clear: both;'>Polyline data:<br /><textarea name=\"wpgmza_polyline\" id=\"poly_line_list\" style=\" height:100px; background-color:#FFF; padding:5px; overflow:auto;\"></textarea>
677
+ <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_save_polyline' class='button-primary' value='".__("Save Polyline","wp-google-maps")." &raquo;' /></p>
678
+
679
+ </form>
680
+ </div>
681
+
682
+
683
+ </div>
684
+
685
+
686
+
687
+ ";
688
+
689
+ }
690
+
691
+
692
+
693
+ }
694
+
695
+
696
+ /**
697
+ * Render polyline editor HTML (edit mode)
698
+ * @param integer $mid Map ID
699
+ * @return string HTML outut
700
+ */
701
+ function wpgmza_b_pro_edit_polyline($mid) {
702
+ global $wpgmza_tblname_maps;
703
+ global $wpdb;
704
+ if ($_GET['action'] == "edit_polyline" && isset($mid)) {
705
+ $res = wpgmza_get_map_data($mid);
706
+ $pol = wpgmza_b_return_polyline_options(sanitize_text_field($_GET['poly_id']));
707
+
708
+ $pol->polydata = esc_textarea($pol->polydata);
709
+
710
+ echo "
711
+
712
+
713
+ <div class='wrap'>
714
+ <h1>WP Google Maps</h1>
715
+ <div class='wide'>
716
+
717
+ <h2>".__("Edit Polyline","wp-google-maps")."</h2>
718
+ <form action='?page=wp-google-maps-menu&action=edit&map_id=".esc_attr($mid)."' method='post' id='wpgmaps_edit_poly_form'>
719
+ <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".esc_attr($mid)."' />
720
+ <input type='hidden' name='wpgmaps_poly_id' id='wpgmaps_poly_id' value='".esc_attr(intval($_GET['poly_id']))."' />
721
+ <input type='hidden' name='wpgmaps_polyline-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_polyline-nonce' )."' />
722
+ <table class='wpgmza-listing-comp' style='width:30%;float:left;'>
723
+ <tr>
724
+ <td>
725
+ ".__("Name","wp-google-maps")."
726
+ </td>
727
+ <td>
728
+ <input id=\"poly_name\" name=\"poly_name\" type=\"text\" value=\"".esc_attr(stripslashes($pol->polyname))."\" />
729
+ </td>
730
+ </tr>
731
+ <tr>
732
+ <td>
733
+ ".__("Line Color","wp-google-maps")."
734
+ </td>
735
+ <td>
736
+ <input id=\"poly_line\" name=\"poly_line\" type=\"text\" class=\"color\" value=\"".esc_attr($pol->linecolor)."\" />
737
+ </td>
738
+ </tr>
739
+ <tr>
740
+ <td>
741
+ ".__("Opacity","wp-google-maps")."
742
+ </td>
743
+ <td>
744
+ <input id=\"poly_opacity\" name=\"poly_opacity\" type=\"text\" value=\"".esc_attr($pol->opacity)."\" /> (0 - 1.0) example: 0.8 for 80%
745
+ </td>
746
+ </tr>
747
+ <tr>
748
+ <td>
749
+ ".__("Line Thickness","wp-google-maps")."
750
+ </td>
751
+ <td>
752
+ <input id=\"poly_thickness\" name=\"poly_thickness\" type=\"text\" value=\"".esc_attr($pol->linethickness)."\" /> (0 - 50) example: 4
753
+ </td>
754
+ </tr>
755
+
756
+ <tr>
757
+
758
+ <td>
759
+ ".__('Show Polyline', 'wp-google-maps')."
760
+ </td>
761
+ <td>
762
+ <button id='fit-bounds-to-shape'
763
+ class='button button-secondary'
764
+ type='button'
765
+ title='" . __('Fit map bounds to shape', 'wp-google-maps') . "'
766
+ data-fit-bounds-to-shape='poly'>
767
+ <i class='fas fa-eye'></i>
768
+ </button>
769
+ </td>
770
+
771
+ </tr>
772
+
773
+ </table>
774
+ <div class='wpgmza_map_seventy'>
775
+ <div id=\"wpgmza_map\">&nbsp;</div>
776
+ <p>
777
+ <ul style=\"list-style:initial;\" class='update-nag update-blue update-slim update-map-overlay'>
778
+
779
+ <li style=\"margin-left:30px;\">Click on the map to insert a vertex.</li>
780
+ <li style=\"margin-left:30px;\">Click on a vertex to remove it.</li>
781
+ <li style=\"margin-left:30px;\">Drag a vertex to move it.</li>
782
+ </ul>
783
+ </p>
784
+ </div>
785
+
786
+ <p style='clear: both;'>Polyline data:<br /><textarea name=\"wpgmza_polyline\" id=\"poly_line_list\" style=\"height:100px; background-color:#FFF; padding:5px; overflow:auto;\">{$pol->polydata}</textarea>
787
+ <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_edit_polyline' class='button-primary' value='".__("Save Polyline","wp-google-maps")." &raquo;' /></p>
788
+
789
+ </form>
790
+ </div>
791
+
792
+
793
+ </div>
794
+
795
+
796
+
797
+ ";
798
+
799
+ }
800
+
801
+
802
+
803
+ }
804
+ /**
805
+ * Render polyline JS
806
+ *
807
+ * @todo This needs to be converted to a native JS file with localized variables
808
+ *
809
+ * @param integer $mapid Map ID
810
+ *
811
+ * @return void
812
+ */
813
+ function wpgmaps_b_admin_add_polyline_javascript($mapid)
814
+ {
815
+ $res = wpgmza_get_map_data(sanitize_text_field($_GET['map_id']));
816
+ $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
817
+
818
+
819
+ $wpgmza_lat = $res->map_start_lat;
820
+ $wpgmza_lng = $res->map_start_lng;
821
+ $wpgmza_map_type = $res->type;
822
+ $wpgmza_width = $res->map_width;
823
+ $wpgmza_height = $res->map_height;
824
+ $wpgmza_width_type = $res->map_width_type;
825
+ $wpgmza_height_type = $res->map_height_type;
826
+ if (!$wpgmza_map_type || $wpgmza_map_type == "" || $wpgmza_map_type == "1") { $wpgmza_map_type = "ROADMAP"; }
827
+ else if ($wpgmza_map_type == "2") { $wpgmza_map_type = "SATELLITE"; }
828
+ else if ($wpgmza_map_type == "3") { $wpgmza_map_type = "HYBRID"; }
829
+ else if ($wpgmza_map_type == "4") { $wpgmza_map_type = "TERRAIN"; }
830
+ else { $wpgmza_map_type = "ROADMAP"; }
831
+ $start_zoom = $res->map_start_zoom;
832
+ if ($start_zoom < 1 || !$start_zoom) {
833
+ $start_zoom = 5;
834
+ }
835
+ if (isset($res->kml)) { $kml = $res->kml; } else { $kml = false; }
836
+
837
+ $localized_data = array(
838
+ 'wpgmza_lat' => $wpgmza_lat,
839
+ 'wpgmza_lng' => $wpgmza_lng,
840
+ 'start_zoom' => $start_zoom,
841
+ 'wpgmza_width' => $wpgmza_width,
842
+ 'wpgmza_width_type' => $wpgmza_width_type,
843
+ 'wpgmza_height' => $wpgmza_height,
844
+ 'wpgmza_height_type' => $wpgmza_height_type,
845
+ 'wpgmza_map_type' => $wpgmza_map_type,
846
+ 'polygon_data' => array()
847
+ );
848
+
849
+ $total_poly_array = wpgmza_b_return_polyline_id_array(sanitize_text_field($_GET['map_id']));
850
+
851
+ foreach ($total_poly_array as $poly_id)
852
+ {
853
+ $polyoptions = wpgmza_b_return_polyline_options($poly_id);
854
+ $linecolor = $polyoptions->linecolor;
855
+ $lineopacity = $polyoptions->opacity;
856
+
857
+ if (!$linecolor) { $linecolor = "000000"; }
858
+ if ($lineopacity == "") { $lineopacity = "1.0"; }
859
+
860
+ $linecolor = "#".$linecolor;
861
+ $poly_array = wpgmza_b_return_polyline_array($poly_id);
862
+ $path_data = array();
863
+
864
+ foreach($poly_array as $single_poly)
865
+ {
866
+ $poly_data_raw = str_replace(" ","",$single_poly);
867
+ $poly_data_raw = explode(",",$poly_data_raw);
868
+ $lat = $poly_data_raw[0];
869
+ $lng = $poly_data_raw[1];
870
+
871
+ $path_data[] = array(
872
+ 'lat' => $lat,
873
+ 'lng' => $lng
874
+ );
875
+ }
876
+
877
+ $localized_data['polyline_data'][$poly_id] = array(
878
+ 'strokeColor' => $linecolor,
879
+ 'strokeOpacity' => $lineopacity,
880
+ 'path' => $path_data
881
+ );
882
+ }
883
+
884
+ $dependencies = wpgmza_get_legacy_pro_shape_editor_dependencies();
885
+
886
+ wp_enqueue_style('wpgooglemaps-css', wpgmaps_get_plugin_url() . 'css/wpgmza_style.css');
887
+ wp_enqueue_script('wpgmza-legacy-polyline-panel', wpgmaps_get_plugin_url() . 'js/legacy/legacy-polyline-panel.js', $dependencies);
888
+ wp_localize_script('wpgmza-legacy-polyline-panel', 'wpgmza_legacy_polyline_panel_vars', $localized_data);
889
+ }
890
+
891
+ /**
892
+ * Render polyline edit JS
893
+ *
894
+ * @todo This needs to be converted to a native JS file with localized variables
895
+ *
896
+ * @param integer $mapid Map ID
897
+ * @param integer $polyid Polygon ID
898
+ *
899
+ * @return void
900
+ */
901
+ function wpgmaps_b_admin_edit_polyline_javascript($mapid,$polyid) {
902
+ $res = wpgmza_get_map_data($mapid);
903
+
904
+ $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
905
+
906
+
907
+ $wpgmza_lat = $res->map_start_lat;
908
+
909
+ $wpgmza_lng = $res->map_start_lng;
910
+ $wpgmza_map_type = $res->type;
911
+ $wpgmza_width = $res->map_width;
912
+ $wpgmza_height = $res->map_height;
913
+ $wpgmza_width_type = $res->map_width_type;
914
+ $wpgmza_height_type = $res->map_height_type;
915
+ if (!$wpgmza_map_type || $wpgmza_map_type == "" || $wpgmza_map_type == "1") { $wpgmza_map_type = "ROADMAP"; }
916
+ else if ($wpgmza_map_type == "2") { $wpgmza_map_type = "SATELLITE"; }
917
+ else if ($wpgmza_map_type == "3") { $wpgmza_map_type = "HYBRID"; }
918
+ else if ($wpgmza_map_type == "4") { $wpgmza_map_type = "TERRAIN"; }
919
+ else { $wpgmza_map_type = "ROADMAP"; }
920
+ $start_zoom = $res->map_start_zoom;
921
+ if ($start_zoom < 1 || !$start_zoom) {
922
+ $start_zoom = 5;
923
+ }
924
+ if (isset($res->kml)) { $kml = $res->kml; } else { $kml = false; }
925
+
926
+ $localized_data = array(
927
+ 'wpgmza_lat' => $wpgmza_lat,
928
+ 'wpgmza_lng' => $wpgmza_lng,
929
+ 'start_zoom' => $start_zoom,
930
+ 'wpgmza_width' => $wpgmza_width,
931
+ 'wpgmza_width_type' => $wpgmza_width_type,
932
+ 'wpgmza_height' => $wpgmza_height,
933
+ 'wpgmza_height_type' => $wpgmza_height_type,
934
+ 'wpgmza_map_type' => $wpgmza_map_type,
935
+ 'polygon_data' => array()
936
+ );
937
+
938
+ $total_poly_array = wpgmza_b_return_polyline_id_array(sanitize_text_field($_GET['map_id']));
939
+
940
+ foreach ($total_poly_array as $poly_id)
941
+ {
942
+
943
+
944
+ $polyoptions = wpgmza_b_return_polyline_options($poly_id);
945
+
946
+ $linecolor = $polyoptions->linecolor;
947
+ $lineopacity = $polyoptions->opacity;
948
+
949
+ if (!$linecolor) { $linecolor = "000000"; }
950
+ if ($lineopacity == "") { $lineopacity = "1.0"; }
951
+
952
+ $linecolor = "#".$linecolor;
953
+ $poly_array = wpgmza_b_return_polyline_array($poly_id);
954
+ $path_data = array();
955
+
956
+ foreach($poly_array as $single_poly)
957
+ {
958
+ $poly_data_raw = str_replace(" ","",$single_poly);
959
+ $poly_data_raw = explode(",",$poly_data_raw);
960
+ $lat = $poly_data_raw[0];
961
+ $lng = $poly_data_raw[1];
962
+
963
+ $path_data[] = array(
964
+ 'lat' => $lat,
965
+ 'lng' => $lng
966
+ );
967
+ }
968
+
969
+ $localized_data['polyline_data'][$poly_id] = array(
970
+ 'strokeColor' => $linecolor,
971
+ 'strokeOpacity' => $lineopacity,
972
+ 'path' => $path_data
973
+ );
974
+ }
975
+
976
+ $dependencies = wpgmza_get_legacy_pro_shape_editor_dependencies();
977
+
978
+ wp_enqueue_style('wpgooglemaps-css', wpgmaps_get_plugin_url() . 'css/wpgmza_style.css');
979
+ wp_enqueue_script('wpgmza-legacy-polyline-panel', wpgmaps_get_plugin_url() . 'js/legacy/legacy-polyline-panel.js', $dependencies);
980
+ wp_localize_script('wpgmza-legacy-polyline-panel', 'wpgmza_legacy_polyline_panel_vars', $localized_data);
981
+ }
982
+ /**
983
+ * Returns the list of polylines displayed in the map editor
984
+ *
985
+ * @todo Build this as a hook or filter instead of a function call
986
+ *
987
+ * @param integer $map_id Map ID
988
+ * @param boolean $admin Identify if user is admin or not
989
+ * @param string $width Width to be used for HTML output
990
+ * @return string List HTML
991
+ */
992
+ function wpgmza_b_return_polyline_list($map_id,$admin = true,$width = "100%") {
993
+ wpgmaps_debugger("return_marker_start");
994
+
995
+ global $wpdb;
996
+ global $wpgmza_tblname_polylines;
997
+ $wpgmza_tmp = "";
998
+
999
+ $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_polylines WHERE `map_id` = %d ORDER BY `id` DESC",intval($map_id)) );
1000
+
1001
+ $wpgmza_tmp .= "
1002
+
1003
+ <table id=\"wpgmza_table_polyline\" class=\"display\" cellspacing=\"0\" cellpadding=\"0\" style=\"width:$width;\">
1004
+ <thead>
1005
+ <tr>
1006
+ <th align='left'><strong>".__("ID","wp-google-maps")."</strong></th>
1007
+ <th align='left'><strong>".__("Name","wp-google-maps")."</strong></th>
1008
+ <th align='left' style='width:182px;'><strong>".__("Action","wp-google-maps")."</strong></th>
1009
+ </tr>
1010
+ </thead>
1011
+ <tbody>
1012
+ ";
1013
+ $res = wpgmza_get_map_data($map_id);
1014
+ $default_marker = "<img src='".$res->default_marker."' />";
1015
+
1016
+ //$wpgmza_data = get_option('WPGMZA');
1017
+ //if ($wpgmza_data['map_default_marker']) { $default_icon = "<img src='".$wpgmza_data['map_default_marker']."' />"; } else { $default_icon = "<img src='".wpgmaps_get_plugin_url()."/images/marker.png' />"; }
1018
+
1019
+ foreach ( $results as $result ) {
1020
+ unset($poly_data);
1021
+ unset($poly_array);
1022
+ $poly_data = '';
1023
+ $poly_array = wpgmza_b_return_polyline_array($result->id);
1024
+ foreach ($poly_array as $poly_single) {
1025
+ $poly_data .= $poly_single.",";
1026
+ }
1027
+ if (isset($result->polyname) && $result->polyname != "") { $poly_name = $result->polyname; } else { $poly_name = "Polyline".$result->id; }
1028
+
1029
+ $wpgmza_tmp .= "
1030
+ <tr id=\"wpgmza_poly_tr_".intval($result->id)."\">
1031
+ <td height=\"40\">".intval($result->id)."</td>
1032
+ <td height=\"40\">".esc_attr(stripslashes($poly_name))."</td>
1033
+ <td width='170' align='left'>
1034
+ <a href=\"".esc_url(get_option('siteurl'))."/wp-admin/admin.php?page=wp-google-maps-menu&action=edit_polyline&map_id=".intval($map_id)."&poly_id=".intval($result->id)."\" title=\"".__("Edit","wp-google-maps")."\" class=\"wpgmza_edit_poly_btn button\" id=\"".intval($result->id)."\"><i class=\"fa fa-edit\"> </i></a>
1035
+ <a href=\"javascript:void(0);\" title=\"".__("Delete this polyline","wp-google-maps")."\" class=\"wpgmza_polyline_del_btn button\" id=\"".intval($result->id)."\"><i class=\"fa fa-times\"> </i></a>
1036
+ </td>
1037
+ </tr>";
1038
+
1039
+ }
1040
+ $wpgmza_tmp .= "</tbody></table>";
1041
+
1042
+
1043
+ return $wpgmza_tmp;
1044
+
1045
+ }
1046
+ /**
1047
+ * Retrieve polyline options from DB
1048
+ *
1049
+ * @param integer $poly_id Polyline ID
1050
+ * @return array MYSQL Array
1051
+ */
1052
+ function wpgmza_b_return_polyline_options($poly_id) {
1053
+ global $wpdb;
1054
+ global $wpgmza_tblname_polylines;
1055
+
1056
+ $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_polylines WHERE `id` = %d LIMIT 1",intval($poly_id)) );
1057
+
1058
+ if(empty($results))
1059
+ return;
1060
+
1061
+ $data = $results[0];
1062
+
1063
+ return wpgmza_convert_shape_options_to_legacy_format($data);
1064
+ }
1065
+
1066
+ /**
1067
+ * Return the polyline data in the format of an array of coordinate-pair strings
1068
+ *
1069
+ * @param integer $poly_id Polyline ID
1070
+ * @return array Poly data array of coordinate-pair strings
1071
+ */
1072
+ function wpgmza_b_return_polyline_array($poly_id) {
1073
+ global $wpdb;
1074
+ global $wpgmza_tblname_polylines;
1075
+
1076
+ $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_polylines WHERE `id` = %d LIMIT 1",intval($poly_id)) );
1077
+
1078
+ if(empty($results))
1079
+ return null;
1080
+
1081
+ $polyline = $results[0];
1082
+ $polydata = $polyline->polydata;
1083
+
1084
+ if(($json = json_decode($polydata)) !== false)
1085
+ return wpgmza_convert_json_geometry_to_legacy_format($json);
1086
+
1087
+ $regex = '/-?(\d+)(\.\d+)?,\s*-?(\d+)(\.\d+)?/';
1088
+
1089
+ if(!preg_match_all($regex, $polydata, $m))
1090
+ return array();
1091
+
1092
+ return $m[0];
1093
+ }
1094
+
1095
+ /**
1096
+ * Return polyline ID array
1097
+ *
1098
+ * This is used when creating the JSON array of all the polylines and their unique options
1099
+ *
1100
+ * @param integer $map_id Map ID
1101
+ * @return array Array of IDs
1102
+ */
1103
+ function wpgmza_b_return_polyline_id_array($map_id) {
1104
+ global $wpdb;
1105
+ global $wpgmza_tblname_polylines;
1106
+ $ret = array();
1107
+ $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpgmza_tblname_polylines WHERE `map_id` = %d",intval($map_id)) );
1108
+ foreach ( $results as $result ) {
1109
+ $current_id = $result->id;
1110
+ $ret[] = $current_id;
1111
+
1112
+ }
1113
+ return $ret;
1114
+ }
1115
+
1116
+ /*
1117
+ * Legacy admin menu
1118
+ */
1119
+ function wpgmaps_admin_menu() {
1120
+ $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
1121
+
1122
+ if (isset($wpgmza_settings['wpgmza_settings_access_level'])) { $access_level = $wpgmza_settings['wpgmza_settings_access_level']; } else { $access_level = "manage_options"; }
1123
+
1124
+ add_menu_page('WP Google Maps', __('Maps','wp-google-maps'), $access_level, 'wp-google-maps-menu', 'wpgmaps_menu_layout', wpgmaps_get_plugin_url()."images/menu-icon.png");
1125
+
1126
+ add_submenu_page(
1127
+ 'wp-google-maps-menu',
1128
+ 'WP Google Maps - Maps',
1129
+ __('Maps', 'wp-google-maps'),
1130
+ $access_level,
1131
+ 'wp-google-maps-menu',
1132
+ 'wpgmaps_menu_layout'
1133
+ );
1134
+
1135
+ if (function_exists('wpgmaps_menu_category_layout')) { add_submenu_page('wp-google-maps-menu', 'WP Google Maps - Categories', __('Categories','wp-google-maps'), $access_level , 'wp-google-maps-menu-categories', 'wpgmaps_menu_category_layout'); }
1136
+
1137
+ if (function_exists('wpgmza_register_pro_version'))
1138
+ {
1139
+ add_submenu_page(
1140
+ 'wp-google-maps-menu',
1141
+ 'WP Google Maps - Advanced Options',
1142
+ __('Advanced','wp-google-maps'),
1143
+ $access_level ,
1144
+ 'wp-google-maps-menu-advanced',
1145
+ 'wpgmaps_menu_advanced_layout'
1146
+ );
1147
+
1148
+ remove_submenu_page("wp-google-maps-menu", "wp-google-maps-menu-custom-fields");
1149
+
1150
+ add_submenu_page(
1151
+ 'wp-google-maps-menu',
1152
+ 'WP Google Maps - Custom Fields',
1153
+ __('Custom Fields', 'wp-google-maps'),
1154
+ $access_level,
1155
+ 'wp-google-maps-menu-custom-fields',
1156
+ 'WPGMZA\\show_custom_fields_page'
1157
+ );
1158
+ }
1159
+
1160
+ add_submenu_page('wp-google-maps-menu', 'WP Google Maps - Settings', __('Settings','wp-google-maps'), $access_level , 'wp-google-maps-menu-settings', 'wpgmaps_menu_settings_layout');
1161
+ add_submenu_page('wp-google-maps-menu', 'WP Google Maps - Support', __('Support','wp-google-maps'), $access_level , 'wp-google-maps-menu-support', 'wpgmaps_menu_support_layout');
1162
+
1163
+ // add_submenu_page('wp-google-maps-menu', 'WP Google Maps - Credits', __('Credits', 'wp-google-maps'), $access_level, 'wp-google-maps-menu-credits', 'wpgmaps_menu_layout');
1164
+
1165
+ }
1166
+
1167
+ function wpgmaps_menu_layout() {
1168
+
1169
+ $map_id = isset($_GET['map_id']) ? (int) intval($_GET['map_id']) : null;
1170
+ $nonce = wp_create_nonce('wpgmza_menu_layout_nonce');
1171
+
1172
+ $handle = 'avia-google-maps-api';
1173
+ $list = 'enqueued';
1174
+
1175
+ if (wp_script_is( $handle, $list )) {
1176
+ wp_deregister_script('avia-google-maps-api');
1177
+ }
1178
+
1179
+ /*check to see if we have write permissions to the plugin folder*/
1180
+ if (!isset($_GET['action'])) {
1181
+ wpgmza_map_page();
1182
+ } else {
1183
+
1184
+ if ($_GET['action'] == "welcome_page" || $_GET['action'] == "credits") { } else {
1185
+ echo"<div class='wpgmza-support-notice' style='float:right; display:block; width:250px; height:65px; padding:6px; text-align:center; background-color: white; border-top: 4px solid #0073AA; margin-right:17px;'><strong>".__("Experiencing problems with the plugin?","wp-google-maps")."</strong><br /><a href='http://www.wpgmaps.com/documentation/troubleshooting/' title='WP Google Maps Troubleshooting Section' target='_BLANK'>".__("See the troubleshooting manual.","wp-google-maps")."</a> <br />".__("Or ask a question on our ","wp-google-maps")." <a href='http://www.wpgmaps.com/forums/forum/support-forum/' title='WP Google Maps Support Forum' target='_BLANK'>".__("Support forum.","wp-google-maps")."</a></div>
1186
+ <div class='wpgmza-clear'></div>";
1187
+ }
1188
+
1189
+ if ($_GET['action'] == "trash" && $map_id) {
1190
+ if (isset( $_GET['s'] ) && $_GET['s'] == "1") {
1191
+
1192
+ if(!wp_verify_nonce($_GET['nonce'], 'wpgmza_menu_layout_nonce'))
1193
+ {
1194
+ http_response_code(401);
1195
+ exit;
1196
+ }
1197
+
1198
+ wpgmaps_trash_map($map_id);
1199
+
1200
+ $url = esc_url(get_option('siteurl') . "/wp-admin/admin.php?page=wp-google-maps-menu");
1201
+
1202
+ echo "<script>window.location = \"$url\";</script>";
1203
+
1204
+ return;
1205
+
1206
+ } else {
1207
+ $res = wpgmza_get_map_data($map_id);
1208
+ echo "<h2>".__("Delete your map","wp-google-maps")."</h2><p>".__("Are you sure you want to delete the map","wp-google-maps")." <strong>\"".strip_tags($res->map_title)."?\"</strong> <br /><a href='?page=wp-google-maps-menu&s=1&action=trash&map_id=".$map_id."&s=1&nonce=$nonce'>".__("Yes","wp-google-maps")."</a> | <a href='?page=wp-google-maps-menu'>".__("No","wp-google-maps")."</a></p>";
1209
+ return;
1210
+ }
1211
+ }
1212
+
1213
+ if (isset($_GET['action']) && $_GET['action'] == "duplicate" && $map_id) {
1214
+ if (function_exists('wpgmaps_duplicate_map')) {
1215
+
1216
+ if(!wp_verify_nonce($_GET['nonce'], 'wpgmza_list_maps_pro_nonce'))
1217
+ {
1218
+ http_response_code(403);
1219
+ exit;
1220
+ }
1221
+
1222
+ $new_id = wpgmaps_duplicate_map($map_id);
1223
+
1224
+ if ($new_id > 0) {
1225
+ wpgmza_map_page();
1226
+ } else {
1227
+ _e("There was a problem duplicating the map.","wp-google-maps");
1228
+ wpgmza_map_page();
1229
+ }
1230
+ }
1231
+ }
1232
+
1233
+ else if ($_GET['action'] == "edit_marker" && isset($_GET['id'])) {
1234
+
1235
+ wpgmza_edit_marker(sanitize_text_field($_GET['id']));
1236
+
1237
+ }
1238
+ elseif ($_GET['action'] == "add_poly" && $map_id) {
1239
+
1240
+ if (function_exists("wpgmza_b_real_pro_add_poly")) {
1241
+ wpgmza_b_real_pro_add_poly($map_id);
1242
+ } else {
1243
+ wpgmza_b_pro_add_poly($map_id);
1244
+ }
1245
+
1246
+ }
1247
+ else if ($_GET['action'] == "edit_poly" && $map_id) {
1248
+
1249
+ if (function_exists("wpgmza_b_real_pro_edit_poly")) {
1250
+ wpgmza_b_real_pro_edit_poly($map_id);
1251
+ } else {
1252
+ wpgmza_b_pro_edit_poly($map_id);
1253
+ }
1254
+
1255
+
1256
+ }
1257
+ else if ($_GET['action'] == "add_polyline" && $map_id) {
1258
+
1259
+ wpgmza_b_pro_add_polyline($map_id);
1260
+
1261
+ }
1262
+ else if ($_GET['action'] == "edit_polyline" && $map_id) {
1263
+
1264
+ wpgmza_b_pro_edit_polyline($map_id);
1265
+ }
1266
+ else if ($_GET['action'] == "add_heatmap" && $map_id) {
1267
+ if (function_exists("wpgmza_b_pro_add_heatmap")) { wpgmza_b_pro_add_heatmap($map_id); }
1268
+ }
1269
+ else if ($_GET['action'] == "edit_heatmap" && $map_id) {
1270
+ if (function_exists("wpgmza_b_pro_edit_heatmap")) { wpgmza_b_pro_edit_heatmap($map_id); }
1271
+ }
1272
+ else if ($_GET['action'] == "add_circle" && $map_id) {
1273
+ wpgmza_b_add_circle($map_id);
1274
+ }
1275
+ else if ($_GET['action'] == "edit_circle" && $map_id) {
1276
+ wpgmza_b_edit_circle($map_id);
1277
+ }
1278
+ else if ($_GET['action'] == "add_rectangle" && $map_id) {
1279
+ wpgmza_b_add_rectangle($map_id);
1280
+ }
1281
+ else if ($_GET['action'] == "edit_rectangle" && $map_id) {
1282
+ wpgmza_b_edit_rectangle($map_id);
1283
+ }
1284
+ else if ($_GET['action'] == 'welcome_page') {
1285
+ $file = dirname(__FILE__).'/base/classes/WPGM_templates.php';
1286
+ include ($file);
1287
+ $wpgmc = new WPGMAPS_templates();
1288
+ $wpgmc->welcome_page_v6();
1289
+
1290
+ }
1291
+
1292
+ else if ($_GET['action'] == 'credits') {
1293
+ $file = dirname(__FILE__).'/base/classes/WPGM_templates.php';
1294
+ include ($file);
1295
+ $wpgmc = new WPGMAPS_templates();
1296
+ $wpgmc->welcome_page_credits();
1297
+
1298
+ }
1299
+ else {
1300
+
1301
+ if (function_exists('wpgmza_register_pro_version')) {
1302
+ wpgmza_pro_menu();
1303
+ } else {
1304
+ wpgmza_basic_menu();
1305
+ }
1306
+
1307
+ }
1308
+ }
1309
+
1310
+ do_action("wpgmza_check_map_editor_backwards_compat");
1311
+
1312
+
1313
+ }
1314
+
1315
+ function wpgmaps_list_maps() {
1316
+ global $wpdb;
1317
+ global $wpgmza_tblname_maps;
1318
+
1319
+ if (function_exists('wpgmaps_list_maps_pro')) { wpgmaps_list_maps_pro(); return; }
1320
+
1321
+ if ($wpgmza_tblname_maps) { $table_name = $wpgmza_tblname_maps; } else { $table_name = $wpdb->prefix . "wpgmza_maps"; }
1322
+
1323
+
1324
+ $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE `active` = %d ORDER BY `id` DESC",0));
1325
+ echo "
1326
+
1327
+ <table class=\"wp-list-table widefat wpgmza-listing\" cellspacing=\"0\">
1328
+ <thead>
1329
+ <tr>
1330
+ <th scope='col' id='id' class='manage-column column-id sortable desc' style='width:50px;'><span>".__("ID","wp-google-maps")."</span></th>
1331
+ <th scope='col' id='map_title' class='manage-column column-map_title sortable desc'><span>".__("Title","wp-google-maps")."</span></th>
1332
+ <th scope='col' id='map_width' class='manage-column column-map_width' style=\"\">".__("Width","wp-google-maps")."</th>
1333
+ <th scope='col' id='map_height' class='manage-column column-map_height' style=\"\">".__("Height","wp-google-maps")."</th>
1334
+ <th scope='col' id='type' class='manage-column column-type sortable desc' style=\"\"><span>".__("Type","wp-google-maps")."</span></th>
1335
+ <th scope='col' id='type' class='manage-column column-type sortable desc' style=\"\"><span>".__("Action","wp-google-maps")."</span></th>
1336
+ <th scope='col' id='type' class='manage-column column-type sortable desc' style=\"\"><span>".__("Shortcode","wp-google-maps")."</span></th>
1337
+ </tr>
1338
+ </thead>
1339
+ <tbody id=\"the-list\" class='list:wp_list_text_link'>
1340
+ ";
1341
+ foreach ( $results as $result ) {
1342
+ if ($result->type == "1") { $map_type = __("Roadmap","wp-google-maps"); }
1343
+ else if ($result->type == "2") { $map_type = __("Satellite","wp-google-maps"); }
1344
+ else if ($result->type == "3") { $map_type = __("Hybrid","wp-google-maps"); }
1345
+ else if ($result->type == "4") { $map_type = __("Terrain","wp-google-maps"); }
1346
+ if (function_exists('wpgmza_register_pro_version')) {
1347
+ $trashlink = "<a class='page-title-action' href=\"?page=wp-google-maps-menu&action=trash&map_id=".$result->id."\" title=\"Trash\">".__("Trash","wp-google-maps")."</a>";
1348
+ } else {
1349
+ $trashlink = "";
1350
+ }
1351
+ echo "<tr id=\"record_".intval($result->id)."\">";
1352
+ echo "<td class='id column-id'>".intval($result->id)."</td>";
1353
+ echo "<td class='map_title column-map_title'><strong><big><a href=\"?page=wp-google-maps-menu&action=edit&map_id=".intval($result->id)."\" title=\"".__("Edit","wp-google-maps")."\">".stripslashes(strip_tags($result->map_title))."</a></big></strong><br /></td>";
1354
+ echo "<td class='map_width column-map_width'>".esc_html($result->map_width)."".stripslashes(esc_html($result->map_width_type))."</td>";
1355
+ echo "<td class='map_width column-map_height'>".esc_html($result->map_height)."".stripslashes(esc_html($result->map_height_type))."</td>";
1356
+ echo "<td class='type column-type'>".$map_type."</td>";
1357
+ echo "<td class='type column-type'><a class='page-title-action' href=\"?page=wp-google-maps-menu&action=edit&map_id=".intval($result->id)."\" title=\"".__("Edit","wp-google-maps")."\">".__("Edit","wp-google-maps")."</a> $trashlink</td>";
1358
+ echo "<td class='type column-type'><input class='wpgmza_copy_shortcode' type='text' readonly value='[wpgmza id=\"".intval($result->id)."\"]'/></td>";
1359
+ echo "</tr>";
1360
+
1361
+
1362
+ }
1363
+ echo "</table>";
1364
+ }
1365
+
1366
+ if(!function_exists('wpgmza_return_marker_list'))
1367
+ {
1368
+ function wpgmza_return_marker_list($map_id,$admin = true,$width = "100%",$mashup = false,$mashup_ids = false) {
1369
+ global $wpdb;
1370
+ global $wpgmza_tblname;
1371
+
1372
+ $columns = implode(', ', wpgmza_get_marker_columns());
1373
+
1374
+ if ($mashup) {
1375
+ $map_ids = $mashup_ids;
1376
+ $wpgmza_cnt = 0;
1377
+
1378
+ if ($mashup_ids[0] == "ALL") {
1379
+
1380
+ $wpgmza_sql1 = "SELECT $columns FROM $wpgmza_tblname ORDER BY `id` DESC";
1381
+ }
1382
+ else {
1383
+ $wpgmza_id_cnt = count($map_ids);
1384
+ $sql_string1 = "";
1385
+ foreach ($map_ids as $wpgmza_map_id) {
1386
+ $wpgmza_cnt++;
1387
+ if ($wpgmza_cnt == 1) { $sql_string1 .= $wpdb->prepare("`map_id` = %d ",$wpgmza_map_id); }
1388
+ elseif ($wpgmza_cnt > 1 && $wpgmza_cnt < $wpgmza_id_cnt) { $sql_string1 .= $wpdb->prepare("OR `map_id` = %d ",$wpgmza_map_id); }
1389
+ else { $sql_string1 .= $wpdb->prepare("OR `map_id` = %d ",$wpgmza_map_id); }
1390
+
1391
+ }
1392
+ $wpgmza_sql1 = "SELECT $columns FROM $wpgmza_tblname WHERE $sql_string1 ORDER BY `id` DESC";
1393
+
1394
+ }
1395
+
1396
+ } else {
1397
+ $wpgmza_sql1 = $wpdb->prepare("SELECT $columns FROM $wpgmza_tblname WHERE `map_id` = %d ORDER BY `id` DESC",intval($map_id));
1398
+
1399
+ }
1400
+ $marker_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpgmza_tblname WHERE map_id = %d",$map_id ) );
1401
+
1402
+ $results = $wpdb->get_results($wpgmza_sql1);
1403
+ $wpgmza_tmp_body = "";
1404
+ $wpgmza_tmp_head = "";
1405
+ $wpgmza_tmp_footer = "";
1406
+
1407
+ $res = wpgmza_get_map_data($map_id);
1408
+ if (!$res->default_marker) {
1409
+ $default_marker = "<img src='".wpgmaps_get_plugin_url()."images/marker.png' width='27' height='43'/>";
1410
+ } else {
1411
+ $default_marker = "<img src='".$res->default_marker."' />";
1412
+ }
1413
+
1414
+
1415
+ foreach ( $results as $result ) {
1416
+ $img = $result->pic;
1417
+ $link = $result->link;
1418
+ $icon = $result->icon;
1419
+
1420
+
1421
+ if (isset($result->approved)) {
1422
+ $approved = $result->approved;
1423
+ if ($approved == 0) {
1424
+ $show_approval_button = true;
1425
+ } else {
1426
+ $show_approval_button = false;
1427
+ }
1428
+ } else {
1429
+ $show_approval_button = false;
1430
+ }
1431
+
1432
+ $category_icon = wpgmza_get_category_icon($result->category);
1433
+
1434
+ if (!$img) { $pic = ""; } else { $pic = "<img src=\"".$result->pic."\" width=\"40\" />"; }
1435
+
1436
+ if (!$category_icon) {
1437
+ if (!$icon) {
1438
+ $icon = $default_marker;
1439
+ } else {
1440
+ $icon = "<img src='".$result->icon."' />";
1441
+ }
1442
+ } else {
1443
+ if (!$icon) {
1444
+ $icon = "<img src='".$category_icon."' />";
1445
+ } else {
1446
+ $icon = "<img src='".$result->icon."' />";
1447
+ }
1448
+
1449
+ }
1450
+
1451
+ if (!$link) { $linktd = ""; } else { $linktd = "<a href=\"".$result->link."\" target=\"_BLANK\" title=\"".__("View this link","wp-google-maps")."\">&gt;&gt;</a>"; }
1452
+
1453
+ if ($admin) {
1454
+ $wpgmza_tmp_body .= "<tr id=\"wpgmza_tr_".$result->id."\" class=\"gradeU\">";
1455
+
1456
+ $wpgmza_tmp_body .= '<td><input type="checkbox" name="mark"/></td>';
1457
+
1458
+ $wpgmza_tmp_body .= "<td height=\"40\">".$result->id."</td>";
1459
+ $wpgmza_tmp_body .= "<td height=\"40\">".$icon."<input type=\"hidden\" id=\"wpgmza_hid_marker_icon_".$result->id."\" value=\"".$result->icon."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_anim_".$result->id."\" value=\"".$result->anim."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_category_".$result->id."\" value=\"".$result->category."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_infoopen_".$result->id."\" value=\"".$result->infoopen."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_approved_".$result->id."\" value=\"".$result->approved."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_retina_".$result->id."\" value=\"".$result->retina."\" />";
1460
+
1461
+ if(defined('WPGMZA_PRO_FILE') && file_exists(plugin_dir_path(WPGMZA_PRO_FILE) . 'includes/custom-fields/class.custom-marker-fields.php'))
1462
+ {
1463
+ wpgmza_require_once(plugin_dir_path(WPGMZA_PRO_FILE) . 'includes/custom-fields/class.custom-marker-fields.php');
1464
+ $custom_fields = new WPGMZA\CustomMarkerFields($result->id);
1465
+ $custom_fields_json = json_encode($custom_fields);
1466
+ $custom_fields_json = htmlspecialchars($custom_fields_json);
1467
+
1468
+ $wpgmza_tmp_body .= '<input type="hidden" id="wpgmza_hid_marker_custom_fields_json_' . $result->id . '" value="' . $custom_fields_json . '"/>';
1469
+ }
1470
+
1471
+ $wpgmza_tmp_body .= "</td>";
1472
+ $wpgmza_tmp_body .= "<td>".stripslashes($result->title)."<input type=\"hidden\" id=\"wpgmza_hid_marker_title_".$result->id."\" value=\"".stripslashes($result->title)."\" /></td>";
1473
+ $wpgmza_tmp_body .= "<td>".wpgmza_return_category_name($result->category)."<input type=\"hidden\" id=\"wpgmza_hid_marker_category_".$result->id."\" value=\"".$result->category."\" /></td>";
1474
+ $wpgmza_tmp_body .= "<td>".stripslashes($result->address)."<input type=\"hidden\" id=\"wpgmza_hid_marker_address_".$result->id."\" value=\"".stripslashes($result->address)."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_lat_".$result->id."\" value=\"".$result->lat."\" /><input type=\"hidden\" id=\"wpgmza_hid_marker_lng_".$result->id."\" value=\"".$result->lng."\" /></td>";
1475
+ $wpgmza_tmp_body .= "<td>".stripslashes($result->description)."<input type=\"hidden\" id=\"wpgmza_hid_marker_desc_".$result->id."\" value=\"". htmlspecialchars(stripslashes($result->description))."\" /></td>";
1476
+ $wpgmza_tmp_body .= "<td>$pic<input type=\"hidden\" id=\"wpgmza_hid_marker_pic_".$result->id."\" value=\"".$result->pic."\" /></td>";
1477
+ $wpgmza_tmp_body .= "<td>$linktd<input type=\"hidden\" id=\"wpgmza_hid_marker_link_".$result->id."\" value=\"".$result->link."\" /></td>";
1478
+ $wpgmza_tmp_body .= "<td width='170' align='center'><div class='wpgmza-flex'>";
1479
+ $wpgmza_tmp_body .= " <a title=\"".__("Edit this marker","wp-google-maps")."\" class=\"wpgmza_edit_btn button\" id=\"".$result->id."\"><i class=\"fa fa-edit\"> </i> </a> ";
1480
+ $wpgmza_tmp_body .= " <a href=\"?page=wp-google-maps-menu&action=edit_marker&id=".$result->id."\" title=\"".__("Edit this marker location","wp-google-maps")."\" class=\"wpgmza_edit_btn button\" id=\"".$result->id."\"><i class=\"fa fa-map-marker\"> </i></a> ";
1481
+ if ($show_approval_button) {
1482
+ $wpgmza_tmp_body .= " <a href=\"javascript:void(0);\" title=\"".__("Approve this marker","wp-google-maps")."\" class=\"wpgmza_approve_btn button\" id=\"".$result->id."\"><i class=\"fa fa-check\"> </i> </a> ";
1483
+ }
1484
+ $wpgmza_tmp_body .= " <a href=\"javascript:void(0);\" title=\"".__("Delete this marker","wp-google-maps")."\" class=\"wpgmza_del_btn button\" id=\"".$result->id."\"><i class=\"fa fa-times\"> </i></a>";
1485
+ $wpgmza_tmp_body .= "</div></td>";
1486
+ $wpgmza_tmp_body .= "</tr>";
1487
+ } else {
1488
+ $wpgmza_tmp_body .= "<tr id=\"wpgmza_marker_".$result->id."\" mid=\"".$result->id."\" mapid=\"".$result->map_id."\" class=\"wpgmaps_mlist_row\">";
1489
+ $wpgmza_tmp_body .= " <td width='1px;' style='display:none; width:1px !important;'><span style='display:none;'>".sprintf('%02d', $result->id)."</span></td>";
1490
+ $wpgmza_tmp_body .= " <td class='wpgmza_table_marker' height=\"40\">".str_replace("'","\"",$icon)."</td>";
1491
+ $wpgmza_tmp_body .= " <td class='wpgmza_table_title'>".stripslashes($result->title)."</td>";
1492
+ $wpgmza_tmp_body .= " <td class='wpgmza_table_category'>".wpgmza_return_category_name($result->category)."</td>";
1493
+ $wpgmza_tmp_body .= " <td class='wpgmza_table_address'>".stripslashes($result->address)."</td>";
1494
+ $wpgmza_tmp_body .= " <td class='wpgmza_table_description'>".stripslashes($result->description)."</td>";
1495
+ $wpgmza_tmp_body .= "</tr>";
1496
+ }
1497
+ }
1498
+ if ($admin) {
1499
+
1500
+ $wpgmza_tmp_head .= "<table id=\"wpgmza_table\" class=\"display\" cellspacing=\"0\" cellpadding=\"0\" style=\"width:$width;\">";
1501
+ $wpgmza_tmp_head .= "<thead>";
1502
+ $wpgmza_tmp_head .= "<tr>";
1503
+ $wpgmza_tmp_head .= " <td><strong>".__("Mark","wp-google-maps")."</strong></td>";
1504
+ $wpgmza_tmp_head .= " <th><strong>".__("ID","wp-google-maps")."</strong></th>";
1505
+ $wpgmza_tmp_head .= " <th><strong>".__("Icon","wp-google-maps")."</strong></th>";
1506
+ $wpgmza_tmp_head .= " <th><strong>".apply_filters("wpgmza_filter_title_name",__("Title","wp-google-maps"))."</strong></th>";
1507
+ $wpgmza_tmp_head .= " <th><strong>".apply_filters("wpgmza_filter_category_name",__("Category","wp-google-maps"))."</strong></th>";
1508
+ $wpgmza_tmp_head .= " <th><strong>".apply_filters("wpgmza_filter_address_name",__("Address","wp-google-maps"))."</strong></th>";
1509
+ $wpgmza_tmp_head .= " <th><strong>".apply_filters("wpgmza_filter_description_name",__("Description","wp-google-maps"))."</strong></th>";
1510
+ $wpgmza_tmp_head .= " <th><strong>".__("Image","wp-google-maps")."</strong></th>";
1511
+ $wpgmza_tmp_head .= " <th><strong>".__("Link","wp-google-maps")."</strong></th>";
1512
+ $wpgmza_tmp_head .= " <th style='width:182px;'><strong>".__("Action","wp-google-maps")."</strong></th>";
1513
+ $wpgmza_tmp_head .= "</tr>";
1514
+ $wpgmza_tmp_head .= "</thead>";
1515
+ $wpgmza_tmp_head .= "<tbody>";
1516
+
1517
+ } else {
1518
+
1519
+ $wpgmza_tmp_head .= "<div id=\"wpgmza_marker_holder_".$map_id."\" style=\"width:$width;\">";
1520
+ $wpgmza_tmp_head .= "<table id=\"wpgmza_table_".$map_id."\" class=\"wpgmza_table\" cellspacing=\"0\" cellpadding=\"0\" style=\"width:$width;\">";
1521
+ $wpgmza_tmp_head .= "<thead>";
1522
+ $wpgmza_tmp_head .= "<tr>";
1523
+ $wpgmza_tmp_head .= " <th width='1' style='display:none; width:1px !important;'></th>";
1524
+ $wpgmza_tmp_head .= " <th class='wpgmza_table_marker'><strong></strong></th>";
1525
+ $wpgmza_tmp_head .= " <th class='wpgmza_table_title'><strong>".apply_filters("wpgmza_filter_title_name",__("Title","wp-google-maps"))."</strong></th>";
1526
+ $wpgmza_tmp_head .= " <th class='wpgmza_table_category'><strong>".apply_filters("wpgmza_filter_category_name",__("Category","wp-google-maps"))."</strong></th>";
1527
+ $wpgmza_tmp_head .= " <th class='wpgmza_table_address'><strong>".apply_filters("wpgmza_filter_address_name",__("Address","wp-google-maps"))."</strong></th>";
1528
+ $wpgmza_tmp_head .= " <th class='wpgmza_table_description'><strong>".apply_filters("wpgmza_filter_description_name",__("Description","wp-google-maps"))."</strong></th>";
1529
+ $wpgmza_tmp_head .= "</tr>";
1530
+ $wpgmza_tmp_head .= "</thead>";
1531
+ $wpgmza_tmp_head .= "<tbody>";
1532
+ }
1533
+
1534
+ $wpgmza_tmp_footer .= "</tbody></table>";
1535
+
1536
+ $wpgmza_tmp_footer .= '
1537
+ <div class="wpgmza-marker-listing__actions">
1538
+ &#x21b3;
1539
+ <button class="wpgmza button select_all_markers" type="button">Select All</button>
1540
+ <button class="wpgmza button bulk_delete" type="button">Bulk Delete</button>
1541
+ </div>
1542
+ ';
1543
+
1544
+ if(!$admin)
1545
+ $wpgmza_tmp_footer .= '</div>';
1546
+
1547
+ return $wpgmza_tmp_head.$wpgmza_tmp_body.$wpgmza_tmp_footer;
1548
+ }
1549
+ }
1550
+
1551
+ if(!function_exists('wpgmza_return_category_name'))
1552
+ {
1553
+ function wpgmza_return_category_name($cid) {
1554
+
1555
+ global $wpdb;
1556
+ global $wpgmza_tblname_categories;
1557
+ $pos = strpos($cid, ",");
1558
+ if ($pos === false) {
1559
+ $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM `$wpgmza_tblname_categories` WHERE `id` = %d LIMIT 1",intval($cid)) );
1560
+ foreach ( $results as $result ) {
1561
+ return $result->category_name;
1562
+ }
1563
+ } else {
1564
+ $categories = explode(",",$cid);
1565
+ $ret_cat = "";
1566
+ $tot_cnt = count($categories);
1567
+ $countr = 0;
1568
+ foreach ($categories as $cid) {
1569
+ $countr++;
1570
+ $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM `$wpgmza_tblname_categories` WHERE `id` = %d LIMIT 1",intval($cid)) );
1571
+ foreach ( $results as $result ) {
1572
+ if ($countr >= $tot_cnt) {
1573
+ $ret_cat .= $result->category_name;
1574
+ } else { $ret_cat .= $result->category_name.","; }
1575
+ }
1576
+
1577
+ }
1578
+ return stripslashes($ret_cat);
1579
+ }
1580
+ }
1581
+ }
1582
+
1583
+ /**
1584
+ * Outputs the JavaScript for the front end
1585
+ * @deprecated 6.3.10 Moved into the wpgmaps_tag_basic function
1586
+ * @return void
1587
+ */
1588
+ function wpgmaps_user_javascript_basic() {
1589
+
1590
+ global $short_code_active;
1591
+ global $wpgmza_current_map_id;
1592
+ global $wpgmza_version;
1593
+
1594
+ $ajax_nonce = wp_create_nonce("wpgmza");
1595
+
1596
+ $res = array();
1597
+ $res[$wpgmza_current_map_id] = wpgmza_get_map_data($wpgmza_current_map_id);
1598
+ $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
1599
+
1600
+ $api_version_string = 'quarterly';
1601
+
1602
+ $map_other_settings = maybe_unserialize($res[$wpgmza_current_map_id]->other_settings);
1603
+ $res[$wpgmza_current_map_id]->other_settings = $map_other_settings;
1604
+ $res[$wpgmza_current_map_id]->map_width_type = stripslashes($res[$wpgmza_current_map_id]->map_width_type);
1605
+
1606
+
1607
+ if ($res[$wpgmza_current_map_id]->other_settings['wpgmza_theme_data'] != '') {
1608
+ $res[$wpgmza_current_map_id]->other_settings['wpgmza_theme_data'] = html_entity_decode(stripslashes($res[$wpgmza_current_map_id]->other_settings['wpgmza_theme_data']));
1609
+ }
1610
+
1611
+ $polygonoptions = array();
1612
+ $total_poly_array = wpgmza_b_return_polygon_id_array($wpgmza_current_map_id);
1613
+
1614
+ if ($total_poly_array > 0) {
1615
+ foreach ($total_poly_array as $poly_id) {
1616
+ $polygonoptions[$poly_id] = wpgmza_b_return_poly_options($poly_id);
1617
+
1618
+ $tmp_poly_array = wpgmza_b_return_polygon_array($poly_id);
1619
+ $poly_data_raw_array = array();
1620
+ foreach ($tmp_poly_array as $single_poly) {
1621
+ $poly_data_raw = str_replace(" ","",$single_poly);
1622
+ $poly_data_raw = explode(",",$poly_data_raw);
1623
+ $lat = $poly_data_raw[0];
1624
+ $lng = $poly_data_raw[1];
1625
+ $poly_data_raw_array[] = $poly_data_raw;
1626
+ }
1627
+ $polygonoptions[$poly_id]->polydata = $poly_data_raw_array;
1628
+
1629
+ $linecolor = $polygonoptions[$poly_id]->linecolor;
1630
+ $fillcolor = $polygonoptions[$poly_id]->fillcolor;
1631
+ $fillopacity = $polygonoptions[$poly_id]->opacity;
1632
+ if (!$linecolor) { $polygonoptions[$poly_id]->linecolor = "000000"; }
1633
+ if (!$fillcolor) { $polygonoptions[$poly_id]->fillcolor = "66FF00"; }
1634
+ if (!$fillopacity) { $polygonoptions[$poly_id]->opacity = "0.5"; }
1635
+ }
1636
+ } else { $polygonoptions = array(); }
1637
+
1638
+
1639
+ $polylineoptions = array();
1640
+
1641
+ $total_poly_array = wpgmza_b_return_polyline_id_array($wpgmza_current_map_id);
1642
+ if ($total_poly_array > 0) {
1643
+ foreach ($total_poly_array as $poly_id) {
1644
+ $polylineoptions[$poly_id] = wpgmza_b_return_polyline_options($poly_id);
1645
+
1646
+ $tmp_poly_array = wpgmza_b_return_polyline_array($poly_id);
1647
+ $poly_data_raw_array = array();
1648
+ foreach ($tmp_poly_array as $single_poly) {
1649
+ $poly_data_raw = str_replace(" ","",$single_poly);
1650
+ $poly_data_raw = str_replace(")","",$poly_data_raw );
1651
+ $poly_data_raw = str_replace("(","",$poly_data_raw );
1652
+ $poly_data_raw = explode(",",$poly_data_raw);
1653
+ $lat = $poly_data_raw[0];
1654
+ $lng = $poly_data_raw[1];
1655
+ $poly_data_raw_array[] = $poly_data_raw;
1656
+ }
1657
+ $polylineoptions[$poly_id]->polydata = $poly_data_raw_array;
1658
+
1659
+
1660
+ if (isset($polylineoptions[$poly_id]->linecolor)) { $linecolor = $polylineoptions[$poly_id]->linecolor; } else { $linecolor = false; }
1661
+ if (isset($polylineoptions[$poly_id]->fillcolor)) { $fillcolor = $polylineoptions[$poly_id]->fillcolor; } else { $fillcolor = false; }
1662
+ if (isset($polylineoptions[$poly_id]->opacity)) { $fillopacity = $polylineoptions[$poly_id]->opacity; } else { $fillopacity = false; }
1663
+ if (!$linecolor) { $polylineoptions[$poly_id]->linecolor = "000000"; }
1664
+ if (!$fillcolor) { $polylineoptions[$poly_id]->fillcolor = "66FF00"; }
1665
+ if (!$fillopacity) { $polylineoptions[$poly_id]->opacity = "0.5"; }
1666
+ }
1667
+ } else { $polylineoptions = array(); }
1668
+
1669
+ if (isset($wpgmza_settings['wpgmza_settings_marker_pull']) && $wpgmza_settings['wpgmza_settings_marker_pull'] == "0") {
1670
+ $markers = wpgmaps_return_markers($wpgmza_current_map_id);
1671
+ }
1672
+
1673
+ wp_enqueue_script( 'wpgmaps_core' );
1674
+
1675
+ do_action("wpgooglemaps_basic_hook_user_js_after_core");
1676
+
1677
+ wp_localize_script( 'wpgmaps_core', 'wpgmaps_mapid', $wpgmza_current_map_id );
1678
+
1679
+ wp_localize_script( 'wpgmaps_core', 'wpgmaps_localize', $res);
1680
+ wp_localize_script( 'wpgmaps_core', 'wpgmaps_localize_polygon_settings', $polygonoptions);
1681
+ wp_localize_script( 'wpgmaps_core', 'wpgmaps_localize_polyline_settings', $polylineoptions);
1682
+
1683
+ wp_localize_script( 'wpgmaps_core', 'wpgmaps_markerurl', wpgmaps_get_marker_url($wpgmza_current_map_id));
1684
+
1685
+
1686
+ if ($wpgmza_settings['wpgmza_settings_marker_pull'] == "0") {
1687
+ wp_localize_script( 'wpgmaps_core', 'wpgmaps_localize_marker_data', $markers);
1688
+ }
1689
+
1690
+ $wpgmza_settings = apply_filters("wpgmza_basic_filter_localize_settings",$wpgmza_settings);
1691
+
1692
+ wp_localize_script( 'wpgmaps_core', 'wpgmaps_localize_global_settings', $wpgmza_settings);
1693
+
1694
+ wp_localize_script( 'wpgmaps_core', 'wpgmaps_lang_km_away', __("km away","wp-google-maps"));
1695
+ wp_localize_script( 'wpgmaps_core', 'wpgmaps_lang_m_away', __("miles away","wp-google-maps"));
1696
+
1697
+ }
1698
+
1699
+ /**
1700
+ * Return an array of markers with relevant data.
1701
+ * Used by AJAX calls throughout sections the plugin
1702
+ * @param boolean $mapid Map ID
1703
+ * @param boolean $markerid (optional) will only pull that marker ID if selected
1704
+ * @return array Array of marker data
1705
+ */
1706
+ function wpgmaps_return_markers($mapid = false,$marker_id = false) {
1707
+
1708
+ if (!$mapid) {
1709
+ return;
1710
+ }
1711
+ global $wpdb;
1712
+ global $wpgmza_tblname;
1713
+
1714
+ $table_name = $wpgmza_tblname;
1715
+
1716
+ $columns = implode(', ', wpgmza_get_marker_columns());
1717
+
1718
+ if ($marker_id) {
1719
+ $results = $wpdb->get_results($wpdb->prepare("SELECT $columns FROM $table_name WHERE `map_id` = %d AND `id` = %d",intval($mapid),intval($marker_id)) );
1720
+ } else {
1721
+ $results = $wpdb->get_results($wpdb->prepare("SELECT $columns FROM $table_name WHERE `map_id` = %d AND `approved` = 1",intval($mapid)) );
1722
+ }
1723
+
1724
+ $m_array = array();
1725
+ $cnt = 0;
1726
+ foreach ( $results as $result ) {
1727
+
1728
+ $id = $result->id;
1729
+ $address = stripslashes($result->address);
1730
+ $description = do_shortcode(stripslashes($result->description));
1731
+ $pic = $result->pic;
1732
+ if (!$pic) { $pic = ""; }
1733
+ $icon = $result->icon;
1734
+ if (!$icon) { $icon = ""; }
1735
+ $link_url = $result->link;
1736
+ if ($link_url) { } else { $link_url = ""; }
1737
+ $lat = $result->lat;
1738
+ $lng = $result->lng;
1739
+ $anim = $result->anim;
1740
+ $retina = $result->retina;
1741
+ $category = $result->category;
1742
+ $other_data = $result->other_data;
1743
+
1744
+ if ($icon == "") {
1745
+ if (function_exists('wpgmza_get_category_data')) {
1746
+ $category_data = wpgmza_get_category_data($category);
1747
+ if (isset($category_data->category_icon) && isset($category_data->category_icon) != "") {
1748
+ $icon = $category_data->category_icon;
1749
+ } else {
1750
+ $icon = "";
1751
+ }
1752
+ if (isset($category_data->retina)) {
1753
+ $retina = $category_data->retina;
1754
+ }
1755
+ }
1756
+ }
1757
+ $infoopen = $result->infoopen;
1758
+
1759
+ $mtitle = stripslashes($result->title);
1760
+ $map_id = $result->map_id;
1761
+
1762
+ $m_array[$id] = array(
1763
+ 'map_id' => $map_id,
1764
+ 'marker_id' => $id,
1765
+ 'title' => $mtitle,
1766
+ 'address' => $address,
1767
+ 'desc' => $description,
1768
+ 'pic' => $pic,
1769
+ 'icon' => $icon,
1770
+ 'linkd' => $link_url,
1771
+ 'lat' => $lat,
1772
+ 'lng' => $lng,
1773
+ 'anim' => $anim,
1774
+ 'retina' => $retina,
1775
+ 'category' => $category,
1776
+ 'infoopen' => $infoopen,
1777
+ 'other_data'=> maybe_unserialize($other_data),
1778
+ 'infoopen' => $infoopen
1779
+ );
1780
+
1781
+ //$custom_fields = new WPGMZA\CustomMarkerFields();
1782
+ if(class_exists('WPGMZA\\CustomMarkerFields'))
1783
+ {
1784
+ $custom_fields = new WPGMZA\CustomMarkerFields($id);
1785
+ $m_array[$id]['custom_fields_json'] = json_encode($custom_fields);
1786
+ $m_array[$id]['custom_fields_html'] = $custom_fields->html();
1787
+ }
1788
+
1789
+ $cnt++;
1790
+
1791
+ }
1792
+
1793
+ return $m_array;
1794
+
1795
+ }
1796
+
1797
+ /**
1798
+ * Handles the bulk of the POST data for the plugin
1799
+ * @return void
1800
+ */
1801
+ function wpgmaps_head() {
1802
+
1803
+ global $wpgmza;
1804
+ global $wpgmza_tblname_maps;
1805
+ global $wpgmza_version;
1806
+
1807
+ if (!$wpgmza->isUserAllowedToEdit())
1808
+ return false;
1809
+
1810
+ if ((isset($_GET['page']) && $_GET['page'] == "wp-google-maps-menu") || (isset($_GET['page']) && $_GET['page'] == "wp-google-maps-menu-settings")) {
1811
+ wpgmaps_folder_check();
1812
+ }
1813
+
1814
+
1815
+ if (isset($_POST['wpgmza_savemap'])){
1816
+
1817
+ var_dump("Woo!");
1818
+ exit;
1819
+
1820
+ if ( !isset( $_POST['wpgmaps_main-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_main-nonce'], 'wpgmaps_main-nonce' ) ) {
1821
+ wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
1822
+ }
1823
+
1824
+ global $wpdb;
1825
+
1826
+
1827
+
1828
+ $map_id = intval(sanitize_text_field($_POST['wpgmza_id']));
1829
+ $map_title = sanitize_text_field(esc_attr($_POST['wpgmza_title']));
1830
+ $map_height = sanitize_text_field($_POST['wpgmza_height']);
1831
+ $map_width = sanitize_text_field($_POST['wpgmza_width']);
1832
+ $map_width_type = sanitize_text_field($_POST['wpgmza_map_width_type']);
1833
+ if ($map_width_type == "%") { $map_width_type = "\%"; }
1834
+ $map_height_type = sanitize_text_field($_POST['wpgmza_map_height_type']);
1835
+ if ($map_height_type == "%") { $map_height_type = "\%"; }
1836
+ $map_start_location = sanitize_text_field($_POST['wpgmza_start_location']);
1837
+ $map_start_zoom = intval(sanitize_text_field($_POST['wpgmza_start_zoom']));
1838
+ $type = intval(sanitize_text_field($_POST['wpgmza_map_type']));
1839
+ $alignment = intval(sanitize_text_field($_POST['wpgmza_map_align']));
1840
+ $bicycle_enabled = isset($_POST['wpgmza_bicycle']) ? 1 : 2;
1841
+ $traffic_enabled = isset($_POST['wpgmza_traffic']) ? 1 : 2;
1842
+ $wpgmza_auto_night_enabled = isset($_POST['wpgmza_auto_night']);
1843
+
1844
+
1845
+ $map_max_zoom = intval(sanitize_text_field($_POST['wpgmza_max_zoom']));
1846
+
1847
+ $gps = explode(",",$map_start_location);
1848
+ $map_start_lat = $gps[0];
1849
+ $map_start_lng = $gps[1];
1850
+
1851
+ $other_settings = array();
1852
+ /*$other_settings['store_locator_enabled'] = intval(sanitize_text_field($_POST['wpgmza_store_locator']));
1853
+ $other_settings['store_locator_distance'] = intval(sanitize_text_field($_POST['wpgmza_store_locator_distance']));
1854
+ $other_settings['store_locator_bounce'] = intval(sanitize_text_field($_POST['wpgmza_store_locator_bounce']));*/
1855
+
1856
+ $other_settings['store_locator_enabled'] = isset($_POST['wpgmza_store_locator']) ? 1 : 2;
1857
+ $other_settings['store_locator_distance'] = isset($_POST['wpgmza_store_locator_distance']) ? 1 : 2;
1858
+
1859
+ if (isset($_POST['wpgmza_store_locator_default_radius']))
1860
+ $other_settings['store_locator_default_radius'] = intval($_POST['wpgmza_store_locator_default_radius']);
1861
+
1862
+ if (isset($_POST['wpgmza_store_locator_not_found_message'])) { $other_settings['store_locator_not_found_message'] = sanitize_text_field( $_POST['wpgmza_store_locator_not_found_message'] ); }
1863
+ $other_settings['store_locator_bounce'] = isset($_POST['wpgmza_store_locator_bounce']) ? 1 : 2;
1864
+
1865
+ $other_settings['store_locator_query_string'] = sanitize_text_field($_POST['wpgmza_store_locator_query_string']);
1866
+ if (isset($_POST['wpgmza_store_locator_default_address'])) { $other_settings['store_locator_default_address'] = sanitize_text_field($_POST['wpgmza_store_locator_default_address']); }
1867
+ if (isset($_POST['wpgmza_store_locator_restrict'])) { $other_settings['wpgmza_store_locator_restrict'] = sanitize_text_field($_POST['wpgmza_store_locator_restrict']); }
1868
+
1869
+ if(isset($_POST['store_locator_style']))
1870
+ $other_settings['store_locator_style'] = sanitize_text_field($_POST['store_locator_style']);
1871
+
1872
+ if(isset($_POST['wpgmza_store_locator_radius_style']))
1873
+ $other_settings['wpgmza_store_locator_radius_style'] = sanitize_text_field($_POST['wpgmza_store_locator_radius_style']);
1874
+
1875
+ $other_settings['map_max_zoom'] = sanitize_text_field($map_max_zoom);
1876
+
1877
+ $other_settings['transport_layer'] = isset($_POST['wpgmza_transport']) ? 1 : 2;
1878
+
1879
+
1880
+
1881
+
1882
+ if (isset($_POST['wpgmza_theme'])) {
1883
+ $theme = intval(sanitize_text_field($_POST['wpgmza_theme']));
1884
+ $theme_data = sanitize_text_field($_POST['wpgmza_theme_data_'.$theme]);
1885
+ $other_settings['wpgmza_theme_data'] = $theme_data;
1886
+ $other_settings['wpgmza_theme_selection'] = $theme;
1887
+ }
1888
+
1889
+ if(isset($_POST['wpgmza_theme_data']))
1890
+ $other_settings['wpgmza_theme_data'] = sanitize_text_field(stripslashes($_POST['wpgmza_theme_data']));
1891
+
1892
+ $other_settings['wpgmza_show_points_of_interest'] = (isset($_POST['wpgmza_show_points_of_interest']) ? 1 : 0);
1893
+
1894
+ $other_settings['wpgmza_auto_night'] = $wpgmza_auto_night_enabled ? 1 : 0;
1895
+
1896
+ $other_settings_data = maybe_serialize($other_settings);
1897
+
1898
+ $data['map_default_starting_lat'] = $map_start_lat;
1899
+ $data['map_default_starting_lng'] = $map_start_lng;
1900
+ $data['map_default_height'] = $map_height;
1901
+ $data['map_default_width'] = $map_width;
1902
+ $data['map_default_zoom'] = $map_start_zoom;
1903
+ $data['map_default_max_zoom'] = $map_max_zoom;
1904
+ $data['map_default_type'] = $type;
1905
+ $data['map_default_alignment'] = $alignment;
1906
+ $data['map_default_width_type'] = $map_width_type;
1907
+ $data['map_default_height_type'] = $map_height_type;
1908
+
1909
+
1910
+
1911
+ $rows_affected = $wpdb->query( $wpdb->prepare(
1912
+ "UPDATE $wpgmza_tblname_maps SET
1913
+ map_title = %s,
1914
+ map_width = %s,
1915
+ map_height = %s,
1916
+ map_start_lat = %f,
1917
+ map_start_lng = %f,
1918
+ map_start_location = %s,
1919
+ map_start_zoom = %d,
1920
+ type = %d,
1921
+ bicycle = %d,
1922
+ traffic = %d,
1923
+ alignment = %d,
1924
+ map_width_type = %s,
1925
+ map_height_type = %s,
1926
+ other_settings = %s
1927
+ WHERE id = %d",
1928
+
1929
+ $map_title,
1930
+ $map_width,
1931
+ $map_height,
1932
+ $map_start_lat,
1933
+ $map_start_lng,
1934
+ $map_start_location,
1935
+ $map_start_zoom,
1936
+ $type,
1937
+ $bicycle_enabled,
1938
+ $traffic_enabled,
1939
+ $alignment,
1940
+ $map_width_type,
1941
+ $map_height_type,
1942
+ $other_settings_data,
1943
+ $map_id)
1944
+ );
1945
+ update_option('WPGMZA_SETTINGS', $data);
1946
+ echo "<div class='updated'>";
1947
+ _e("Your settings have been saved.","wp-google-maps");
1948
+ echo "</div>";
1949
+ if( function_exists( 'wpgmza_caching_notice_changes' ) ){
1950
+ add_action( 'admin_notices', 'wpgmza_caching_notice_changes' );
1951
+ }
1952
+
1953
+ }
1954
+
1955
+ else if (isset($_POST['wpgmza_save_maker_location'])){
1956
+ if ( !isset( $_POST['wpgmaps_marker-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_marker-nonce'], 'wpgmaps_marker-nonce' ) ) {
1957
+ wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
1958
+ }
1959
+
1960
+ $marker = \WPGMZA\Marker::createInstance($_POST['wpgmaps_marker_id']);
1961
+ $latlng = new \WPGMZA\LatLng(floatval($_POST['wpgmaps_marker_lat']), floatval($_POST['wpgmaps_marker_lng']));
1962
+
1963
+ if(preg_match(\WPGMZA\LatLng::REGEXP, $marker->address))
1964
+ {
1965
+ $currentAddressPosition = new \WPGMZA\LatLng($marker->address);
1966
+ $distance = \WPGMZA\Distance::between($currentAddressPosition, $marker->getPosition());
1967
+ $meters = $distance / 1000;
1968
+
1969
+ if($meters < 1)
1970
+ {
1971
+ // The marker has an address which looks like coordinates, and they're very close to the markers latitude and longitude
1972
+ // Therefore, it would seem that the user has placed this with coordinates and is now looking to move those coordinates here
1973
+ // Because of this, we'll update the address with the new coordinates
1974
+ $marker->address = (string)$latlng;
1975
+ }
1976
+ }
1977
+
1978
+ $lat = floatval($_POST['wpgmaps_marker_lat']);
1979
+ $lng = floatval($_POST['wpgmaps_marker_lng']);
1980
+
1981
+ $marker->lat = $lat;
1982
+ $marker->lng = $lng;
1983
+
1984
+ echo "<div class='updated'>";
1985
+ _e("Your marker location has been saved.","wp-google-maps");
1986
+ echo "</div>";
1987
+
1988
+ }
1989
+ else if (isset($_POST['wpgmza_save_poly'])){
1990
+ if ( !isset( $_POST['wpgmaps_polygon-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_polygon-nonce'], 'wpgmaps_polygon-nonce' ) ) {
1991
+ wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
1992
+ }
1993
+ global $wpdb;
1994
+ global $wpgmza_tblname_poly;
1995
+ $mid = sanitize_text_field($_POST['wpgmaps_map_id']);
1996
+ if (!isset($_POST['wpgmza_polygon']) || $_POST['wpgmza_polygon'] == "") {
1997
+ echo "<div class='error'>";
1998
+ _e("You cannot save a blank polygon","wp-google-maps");
1999
+ echo "</div>";
2000
+
2001
+ } else {
2002
+ $wpgmaps_polydata = sanitize_text_field($_POST['wpgmza_polygon']);
2003
+ if ($wpgmaps_polydata !== "") {
2004
+
2005
+ if (isset($_POST['poly_name'])) { $polyname = sanitize_text_field($_POST['poly_name']); } else { $polyname = "Polyline"; }
2006
+ if (isset($_POST['poly_line'])) { $linecolor = sanitize_text_field($_POST['poly_line']); } else { $linecolor = "000000"; }
2007
+ if (isset($_POST['poly_fill'])) { $fillcolor = sanitize_text_field($_POST['poly_fill']); } else { $fillcolor = "66FF00"; }
2008
+ if (isset($_POST['poly_opacity'])) { $opacity = sanitize_text_field($_POST['poly_opacity']); } else { $opacity = "0.5"; }
2009
+ if (isset($_POST['poly_line_opacity'])) { $line_opacity = sanitize_text_field($_POST['poly_line_opacity']); } else { $line_opacity = "0.5"; }
2010
+ if (isset($_POST['poly_line_hover_line_color'])) { $ohlinecolor = sanitize_text_field($_POST['poly_line_hover_line_color']); } else { $ohlinecolor = ""; }
2011
+ if (isset($_POST['poly_hover_fill_color'])) { $ohfillcolor = sanitize_text_field($_POST['poly_hover_fill_color']); } else { $ohfillcolor = ""; }
2012
+ if (isset($_POST['poly_hover_opacity'])) { $ohopacity = sanitize_text_field($_POST['poly_hover_opacity']); } else { $ohopacity = ""; }
2013
+ if (isset($_POST['wpgmza_polygon_inner'])) { $wpgmaps_polydatainner = sanitize_text_field($_POST['wpgmza_polygon_inner']); } else { $wpgmaps_polydatainner = ""; }
2014
+
2015
+
2016
+ $rows_affected = $wpdb->query( $wpdb->prepare(
2017
+ "INSERT INTO $wpgmza_tblname_poly SET
2018
+ map_id = %d,
2019
+ polydata = %s,
2020
+ innerpolydata = %s,
2021
+ polyname = %s,
2022
+ linecolor = %s,
2023
+ lineopacity = %s,
2024
+ fillcolor = %s,
2025
+ opacity = %s,
2026
+ ohlinecolor = %s,
2027
+ ohfillcolor = %s,
2028
+ ohopacity = %s
2029
+ ",
2030
+
2031
+ $mid,
2032
+ $wpgmaps_polydata,
2033
+ $wpgmaps_polydatainner,
2034
+ $polyname,
2035
+ $linecolor,
2036
+ $line_opacity,
2037
+ $fillcolor,
2038
+ $opacity,
2039
+ $ohlinecolor,
2040
+ $ohfillcolor,
2041
+ $ohopacity
2042
+ )
2043
+ );
2044
+ echo "<div class='updated'>";
2045
+ _e("Your polygon has been created.","wp-google-maps");
2046
+ echo "</div>";
2047
+ }
2048
+ }
2049
+
2050
+
2051
+ }
2052
+ else if (isset($_POST['wpgmza_edit_poly'])){
2053
+ if ( !isset( $_POST['wpgmaps_polygon-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_polygon-nonce'], 'wpgmaps_polygon-nonce' ) ) {
2054
+ wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
2055
+ }
2056
+
2057
+ global $wpdb;
2058
+ global $wpgmza_tblname_poly;
2059
+ $mid = sanitize_text_field($_POST['wpgmaps_map_id']);
2060
+ $pid = sanitize_text_field($_POST['wpgmaps_poly_id']);
2061
+ if (!isset($_POST['wpgmza_polygon']) || $_POST['wpgmza_polygon'] == "") {
2062
+ echo "<div class='error'>";
2063
+ _e("You cannot save a blank polygon","wp-google-maps");
2064
+ echo "</div>";
2065
+
2066
+ } else {
2067
+ $wpgmaps_polydata = sanitize_text_field($_POST['wpgmza_polygon']);
2068
+
2069
+ if (isset($_POST['poly_name'])) { $polyname = sanitize_text_field($_POST['poly_name']); } else { $polyname = "Polyline"; }
2070
+ if (isset($_POST['poly_line'])) { $linecolor = sanitize_text_field($_POST['poly_line']); } else { $linecolor = "000000"; }
2071
+ if (isset($_POST['poly_fill'])) { $fillcolor = sanitize_text_field($_POST['poly_fill']); } else { $fillcolor = "66FF00"; }
2072
+ if (isset($_POST['poly_opacity'])) { $opacity = sanitize_text_field($_POST['poly_opacity']); } else { $opacity = "0.5"; }
2073
+ if (isset($_POST['poly_line_opacity'])) { $line_opacity = sanitize_text_field($_POST['poly_line_opacity']); } else { $line_opacity = "0.5"; }
2074
+ if (isset($_POST['poly_line_hover_line_color'])) { $ohlinecolor = sanitize_text_field($_POST['poly_line_hover_line_color']); } else { $ohlinecolor = ""; }
2075
+ if (isset($_POST['poly_hover_fill_color'])) { $ohfillcolor = sanitize_text_field($_POST['poly_hover_fill_color']); } else { $ohfillcolor = ""; }
2076
+ if (isset($_POST['poly_hover_opacity'])) { $ohopacity = sanitize_text_field($_POST['poly_hover_opacity']); } else { $ohopacity = ""; }
2077
+ if (isset($_POST['wpgmza_polygon_inner'])) { $wpgmaps_polydatainner = sanitize_text_field($_POST['wpgmza_polygon_inner']); } else { $wpgmaps_polydatainner = ""; }
2078
+
2079
+
2080
+
2081
+ $rows_affected = $wpdb->query( $wpdb->prepare(
2082
+ "UPDATE $wpgmza_tblname_poly SET
2083
+ polydata = %s,
2084
+ innerpolydata = %s,
2085
+ polyname = %s,
2086
+ linecolor = %s,
2087
+ lineopacity = %s,
2088
+ fillcolor = %s,
2089
+ opacity = %s,
2090
+ ohlinecolor = %s,
2091
+ ohfillcolor = %s,
2092
+ ohopacity = %s
2093
+ WHERE `id` = %d"
2094
+ ,
2095
+
2096
+ $wpgmaps_polydata,
2097
+ $wpgmaps_polydatainner,
2098
+ $polyname,
2099
+ $linecolor,
2100
+ $line_opacity,
2101
+ $fillcolor,
2102
+ $opacity,
2103
+ $ohlinecolor,
2104
+ $ohfillcolor,
2105
+ $ohopacity,
2106
+ $pid
2107
+ )
2108
+ );
2109
+ echo "<div class='updated'>";
2110
+ _e("Your polygon has been saved.","wp-google-maps");
2111
+ echo "</div>";
2112
+
2113
+ }
2114
+
2115
+
2116
+ }
2117
+ else if (isset($_POST['wpgmza_save_polyline'])){
2118
+
2119
+ if ( !isset( $_POST['wpgmaps_polyline-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_polyline-nonce'], 'wpgmaps_polyline-nonce' ) ) {
2120
+ wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
2121
+ }
2122
+
2123
+ global $wpdb;
2124
+ global $wpgmza_tblname_polylines;
2125
+ $mid = sanitize_text_field($_POST['wpgmaps_map_id']);
2126
+ if (!isset($_POST['wpgmza_polyline']) || $_POST['wpgmza_polyline'] == "") {
2127
+ echo "<div class='error'>";
2128
+ _e("You cannot save a blank polyline","wp-google-maps");
2129
+ echo "</div>";
2130
+
2131
+ } else {
2132
+ $wpgmaps_polydata = sanitize_text_field($_POST['wpgmza_polyline']);
2133
+ if ($wpgmaps_polydata !== "") {
2134
+
2135
+
2136
+ if (isset($_POST['poly_name'])) { $polyname = sanitize_text_field($_POST['poly_name']); } else { $polyname = ""; }
2137
+ if (isset($_POST['poly_line'])) { $linecolor = sanitize_text_field($_POST['poly_line']); } else { $linecolor = "000000"; }
2138
+ if (isset($_POST['poly_thickness'])) { $linethickness = sanitize_text_field($_POST['poly_thickness']); } else { $linethickness = "0"; }
2139
+ if (isset($_POST['poly_opacity'])) { $opacity = sanitize_text_field($_POST['poly_opacity']); } else { $opacity = "1"; }
2140
+
2141
+ $rows_affected = $wpdb->query( $wpdb->prepare(
2142
+ "INSERT INTO $wpgmza_tblname_polylines SET
2143
+ map_id = %d,
2144
+ polydata = %s,
2145
+ polyname = %s,
2146
+ linecolor = %s,
2147
+ linethickness = %s,
2148
+ opacity = %s
2149
+ ",
2150
+
2151
+ $mid,
2152
+ $wpgmaps_polydata,
2153
+ $polyname,
2154
+ $linecolor,
2155
+ $linethickness,
2156
+ $opacity
2157
+ )
2158
+ );
2159
+ echo "<div class='updated'>";
2160
+ _e("Your polyline has been created.","wp-google-maps");
2161
+ echo "</div>";
2162
+ }
2163
+ }
2164
+
2165
+
2166
+ }
2167
+ else if (isset($_POST['wpgmza_edit_polyline'])){
2168
+
2169
+ if ( !isset( $_POST['wpgmaps_polyline-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_polyline-nonce'], 'wpgmaps_polyline-nonce' ) ) {
2170
+ wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
2171
+ }
2172
+
2173
+
2174
+ global $wpdb;
2175
+ global $wpgmza_tblname_polylines;
2176
+ $mid = sanitize_text_field($_POST['wpgmaps_map_id']);
2177
+ $pid = sanitize_text_field($_POST['wpgmaps_poly_id']);
2178
+ if (!isset($_POST['wpgmza_polyline']) || $_POST['wpgmza_polyline'] == "") {
2179
+ echo "<div class='error'>";
2180
+ _e("You cannot save a blank polyline","wp-google-maps");
2181
+ echo "</div>";
2182
+
2183
+ } else {
2184
+ $wpgmaps_polydata = sanitize_text_field($_POST['wpgmza_polyline']);
2185
+ if (isset($_POST['poly_name'])) { $polyname = sanitize_text_field($_POST['poly_name']); } else { $polyname = ""; }
2186
+ if (isset($_POST['poly_line'])) { $linecolor = sanitize_text_field($_POST['poly_line']); } else { $linecolor = "000000"; }
2187
+ if (isset($_POST['poly_thickness'])) { $linethickness = sanitize_text_field($_POST['poly_thickness']); } else { $linethickness = "0"; }
2188
+ if (isset($_POST['poly_opacity'])) { $opacity = sanitize_text_field($_POST['poly_opacity']); } else { $opacity = "1"; }
2189
+
2190
+ $rows_affected = $wpdb->query( $wpdb->prepare(
2191
+ "UPDATE $wpgmza_tblname_polylines SET
2192
+ polydata = %s,
2193
+ polyname = %s,
2194
+ linecolor = %s,
2195
+ linethickness = %s,
2196
+ opacity = %s
2197
+ WHERE `id` = %d"
2198
+ ,
2199
+
2200
+ $wpgmaps_polydata,
2201
+ $polyname,
2202
+ $linecolor,
2203
+ $linethickness,
2204
+ $opacity,
2205
+ $pid
2206
+ )
2207
+ );
2208
+ echo "<div class='updated'>";
2209
+ _e("Your polyline has been saved.","wp-google-maps");
2210
+ echo "</div>";
2211
+ }
2212
+
2213
+
2214
+ }
2215
+ else if (isset($_POST['wpgmza_save_circle'])){
2216
+
2217
+ if ( !isset( $_POST['wpgmaps_circle-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_circle-nonce'], 'wpgmaps_circle-nonce' ) ) {
2218
+ wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
2219
+ }
2220
+
2221
+ global $wpdb;
2222
+ global $wpgmza_tblname_circles;
2223
+
2224
+ $center = preg_replace('/[(),]/', '', sanitize_text_field($_POST['center']));
2225
+
2226
+ if(isset($_POST['circle_id']))
2227
+ {
2228
+ $stmt = $wpdb->prepare("
2229
+ UPDATE $wpgmza_tblname_circles SET
2230
+ center = {$wpgmza->spatialFunctionPrefix}GeomFromText(%s),
2231
+ name = %s,
2232
+ color = %s,
2233
+ opacity = %f,
2234
+ radius = %f
2235
+ WHERE id = %d
2236
+ ", array(
2237
+ "POINT($center)",
2238
+ sanitize_text_field($_POST['circle_name']),
2239
+ sanitize_hex_color($_POST['circle_color']),
2240
+ floatval($_POST['circle_opacity']),
2241
+ intval($_POST['circle_radius']),
2242
+ intval($_POST['circle_id'])
2243
+ ));
2244
+ }
2245
+ else
2246
+ {
2247
+ $stmt = $wpdb->prepare("
2248
+ INSERT INTO $wpgmza_tblname_circles
2249
+ (center, map_id, name, color, opacity, radius)
2250
+ VALUES
2251
+ ({$wpgmza->spatialFunctionPrefix}GeomFromText(%s), %d, %s, %s, %f, %f)
2252
+ ", array(
2253
+ "POINT($center)",
2254
+ intval($_POST['wpgmaps_map_id']),
2255
+ sanitize_text_field($_POST['circle_name']),
2256
+ sanitize_hex_color($_POST['circle_color']),
2257
+ floatval($_POST['circle_opacity']),
2258
+ intval($_POST['circle_radius'])
2259
+ ));
2260
+ }
2261
+
2262
+ $wpdb->query($stmt);
2263
+
2264
+ }
2265
+ else if (isset($_POST['wpgmza_save_rectangle'])){
2266
+
2267
+ if ( !isset( $_POST['wpgmaps_rectangle-nonce'] ) || !wp_verify_nonce( $_POST['wpgmaps_rectangle-nonce'], 'wpgmaps_rectangle-nonce' ) ) {
2268
+ wp_die( __( 'You do not have permission to perform this function', 'wp-google-maps' ) );
2269
+ }
2270
+
2271
+ global $wpdb;
2272
+ global $wpgmza_tblname_rectangles;
2273
+
2274
+ $m = null;
2275
+ preg_match_all('/-?\d+(\.\d+)?/', sanitize_text_field($_POST['bounds']), $m);
2276
+
2277
+ $north = $m[0][0];
2278
+ $east = $m[0][1];
2279
+ $south = $m[0][2];
2280
+ $west = $m[0][3];
2281
+
2282
+ $cornerA = "POINT($north $east)";
2283
+ $cornerB = "POINT($south $west)";
2284
+
2285
+ if(isset($_POST['rectangle_id']))
2286
+ {
2287
+ $stmt = $wpdb->prepare("
2288
+ UPDATE $wpgmza_tblname_rectangles SET
2289
+ name = %s,
2290
+ color = %s,
2291
+ opacity = %f,
2292
+ cornerA = {$wpgmza->spatialFunctionPrefix}GeomFromText(%s),
2293
+ cornerB = {$wpgmza->spatialFunctionPrefix}GeomFromText(%s)
2294
+ WHERE id = %d
2295
+ ", array(
2296
+ sanitize_text_field($_POST['rectangle_name']),
2297
+ sanitize_hex_color($_POST['rectangle_color']),
2298
+ floatval($_POST['rectangle_opacity']),
2299
+ $cornerA,
2300
+ $cornerB,
2301
+ intval($_POST['rectangle_id'])
2302
+ ));
2303
+ }
2304
+ else
2305
+ {
2306
+ $stmt = $wpdb->prepare("
2307
+ INSERT INTO $wpgmza_tblname_rectangles
2308
+ (map_id, name, color, opacity, cornerA, cornerB)
2309
+ VALUES
2310
+ (%d, %s, %s, %f, {$wpgmza->spatialFunctionPrefix}GeomFromText(%s), {$wpgmza->spatialFunctionPrefix}GeomFromText(%s))
2311
+ ", array(
2312
+ intval($_POST['wpgmaps_map_id']),
2313
+ sanitize_text_field($_POST['rectangle_name']),
2314
+ sanitize_hex_color($_POST['rectangle_color']),
2315
+ floatval($_POST['rectangle_opacity']),
2316
+ $cornerA,
2317
+ $cornerB
2318
+ ));
2319
+ }
2320
+
2321
+ $rows = $wpdb->query($stmt);
2322
+ }
2323
+ }
2324
+
2325
+ /**
2326
+ * Handle POST for settings page
2327
+ * @return void
2328
+ */
2329
+ add_action('admin_post_wpgmza_settings_page_post', 'wpgmza_settings_page_post');
2330
+
2331
+ function wpgmza_settings_page_post()
2332
+ {
2333
+ global $wpdb;
2334
+ global $wpgmza;
2335
+
2336
+ if(!wp_verify_nonce($_POST['wpgmza_settings_page_post_nonce'], 'wpgmza_settings_page_post'))
2337
+ {
2338
+ http_response_code(403);
2339
+ exit;
2340
+ }
2341
+
2342
+ if(!$wpgmza->isUserAllowedToEdit())
2343
+ {
2344
+ http_response_code(401);
2345
+ exit;
2346
+ }
2347
+
2348
+ if($wpgmza)
2349
+ $wpgmza->gdprCompliance->onPOST();
2350
+
2351
+ $checkboxes = array("wpgmza_settings_map_full_screen_control",
2352
+ "wpgmza_settings_map_streetview",
2353
+ "wpgmza_settings_map_zoom",
2354
+ "wpgmza_settings_map_pan",
2355
+ "wpgmza_settings_map_type",
2356
+ "wpgmza_settings_map_scroll",
2357
+ "wpgmza_settings_map_draggable",
2358
+ "wpgmza_settings_map_clickzoom",
2359
+ "wpgmza_settings_cat_display_qty",
2360
+ "wpgmza_settings_force_jquery",
2361
+ "wpgmza_settings_remove_api",
2362
+ "wpgmza_force_greedy_gestures",
2363
+ "wpgmza_settings_image_resizing",
2364
+ "wpgmza_settings_infowindow_links",
2365
+ "wpgmza_settings_infowindow_address",
2366
+ "wpgmza_settings_disable_infowindows",
2367
+ "carousel_lazyload",
2368
+ "carousel_autoheight",
2369
+ "carousel_pagination",
2370
+ "carousel_navigation",
2371
+ "wpgmza_gdpr_enabled",
2372
+ "wpgmza_gdpr_require_consent_before_load",
2373
+ "wpgmza_developer_mode",
2374
+ 'wpgmza_prevent_other_plugins_and_theme_loading_api',
2375
+ "wpgmza_gdpr_override_notice",
2376
+ "wpgmza_gdpr_require_consent_before_vgm_submit",
2377
+ "disable_autoptimize_compatibility_fix",
2378
+ "disable_compressed_path_variables"
2379
+ );
2380
+
2381
+ foreach($checkboxes as $name) {
2382
+ $remap = $name;
2383
+
2384
+ switch($name)
2385
+ {
2386
+ case 'wpgmza_developer_mode':
2387
+ $remap = preg_replace('/^wpgmza_/', '', $name);
2388
+ break;
2389
+ }
2390
+
2391
+ if(!empty($_POST[$name]))
2392
+ {
2393
+ $wpgmza->settings[$remap] = sanitize_text_field( $_POST[$name] );
2394
+ }
2395
+ else if(isset($wpgmza->settings[$remap]))
2396
+ {
2397
+ unset($wpgmza->settings[$remap]);
2398
+ }
2399
+ }
2400
+
2401
+ if(isset($_POST['tile_server_url']))
2402
+ $wpgmza->settings['tile_server_url'] = sanitize_text_field($_POST['tile_server_url']);
2403
+
2404
+ if(isset($_POST['wpgmza_load_engine_api_condition']))
2405
+ $wpgmza->settings['wpgmza_load_engine_api_condition'] = sanitize_text_field($_POST['wpgmza_load_engine_api_condition']);
2406
+
2407
+ if(isset($_POST['wpgmza_always_include_engine_api_on_pages']))
2408
+ $wpgmza->settings['wpgmza_always_include_engine_api_on_pages'] = sanitize_text_field($_POST['wpgmza_always_include_engine_api_on_pages']);
2409
+
2410
+ if(isset($_POST['wpgmza_always_exclude_engine_api_on_pages']))
2411
+ $wpgmza->settings['wpgmza_always_exclude_engine_api_on_pages'] = sanitize_text_field($_POST['wpgmza_always_exclude_engine_api_on_pages']);
2412
+
2413
+ if(isset($_POST['wpgmza_use_fontawesome']))
2414
+ $wpgmza->settings['use_fontawesome'] = sanitize_text_field($_POST['wpgmza_use_fontawesome']);
2415
+
2416
+ if(isset($_POST['wpgmza_maps_engine']))
2417
+ $wpgmza->settings['wpgmza_maps_engine'] = sanitize_text_field($_POST['wpgmza_maps_engine']);
2418
+
2419
+
2420
+ if (isset($_POST['wpgmza_settings_map_open_marker_by'])) { $wpgmza->settings['wpgmza_settings_map_open_marker_by'] = sanitize_text_field($_POST['wpgmza_settings_map_open_marker_by']); }
2421
+
2422
+ if (isset($_POST['wpgmza_api_version'])) { $wpgmza->settings['wpgmza_api_version'] = sanitize_text_field($_POST['wpgmza_api_version']); }
2423
+ if (isset($_POST['wpgmza_custom_css'])) { $wpgmza->settings['wpgmza_custom_css'] = sanitize_text_field($_POST['wpgmza_custom_css']); }
2424
+ if (isset($_POST['wpgmza_custom_js'])) { $wpgmza->settings['wpgmza_custom_js'] = sanitize_text_field($_POST['wpgmza_custom_js']); }
2425
+
2426
+ if (isset($_POST['user_interface_style']))
2427
+ $wpgmza->settings['user_interface_style'] = esc_attr(sanitize_text_field($_POST['user_interface_style']));
2428
+
2429
+ if (isset($_POST['wpgmza_marker_xml_location'])) { update_option("wpgmza_xml_location",sanitize_text_field($_POST['wpgmza_marker_xml_location'])); }
2430
+ if (isset($_POST['wpgmza_marker_xml_url'])) { update_option("wpgmza_xml_url",sanitize_text_field($_POST['wpgmza_marker_xml_url'])); }
2431
+
2432
+ if(current_user_can('administrator'))
2433
+ if (isset($_POST['wpgmza_access_level'])) { $wpgmza->settings['wpgmza_settings_access_level'] = sanitize_text_field($_POST['wpgmza_access_level']); }
2434
+
2435
+ if (isset($_POST['wpgmza_settings_marker_pull'])) { $wpgmza->settings['wpgmza_settings_marker_pull'] = sanitize_text_field($_POST['wpgmza_settings_marker_pull']); }
2436
+
2437
+ // Maps -> Settings -> Store Locator -> option Store Locator Radius
2438
+ if (isset($_POST['wpgmza_store_locator_radii'])) { $wpgmza->settings['wpgmza_store_locator_radii'] = sanitize_text_field($_POST['wpgmza_store_locator_radii']); }
2439
+
2440
+ if (isset($_POST['wpgmza_settings_enable_usage_tracking'])) { $wpgmza->settings['wpgmza_settings_enable_usage_tracking'] = sanitize_text_field($_POST['wpgmza_settings_enable_usage_tracking']); }
2441
+
2442
+ $arr = apply_filters("wpgooglemaps_filter_save_settings", $wpgmza->settings);
2443
+
2444
+ $wpgmza->settings->set($arr);
2445
+
2446
+ if( isset( $_POST['wpgmza_google_maps_api_key'] ) ){ update_option( 'wpgmza_google_maps_api_key', sanitize_text_field( trim($_POST['wpgmza_google_maps_api_key'] )) ); }
2447
+
2448
+ if($_POST['wpgmza_settings_marker_pull'] == 1)
2449
+ wpgmaps_update_all_xml_file();
2450
+
2451
+ wp_redirect(get_admin_url() . 'admin.php?page=wp-google-maps-menu-settings');
2452
+ exit;
2453
+ }
2454
+
2455
+ add_action('wp_ajax_add_marker', 'wpgmaps_action_callback_pro');
2456
+ add_action('wp_ajax_delete_marker', 'wpgmaps_action_callback_pro');
2457
+ add_action('wp_ajax_edit_marker', 'wpgmaps_action_callback_pro');
2458
+ add_action('wp_ajax_approve_marker', 'wpgmaps_action_callback_pro');
2459
+ add_action('wp_ajax_delete_marker', 'wpgmaps_action_callback_pro'); // NB: Legacy support
2460
+ add_action('wp_ajax_delete_poly', 'wpgmaps_action_callback_pro');
2461
+ add_action('wp_ajax_delete_polyline', 'wpgmaps_action_callback_pro');
2462
+ add_action('wp_ajax_delete_dataset', 'wpgmaps_action_callback_pro');
2463
+ add_action('wp_ajax_delete_circle', 'wpgmaps_action_callback_pro');
2464
+ add_action('wp_ajax_delete_rectangle', 'wpgmaps_action_callback_pro');
2465
+
2466
+ if (function_exists('wpgmaps_head_pro' )) {
2467
+ add_action( 'admin_head', 'wpgmaps_head_pro' );
2468
+ } else {
2469
+
2470
+ if (function_exists( 'wpgmaps_pro_activate' ) && floatval($wpgmza_version) < 5.24) {
2471
+ add_action( 'admin_notices', function() {
2472
+
2473
+ ?>
2474
+ <div class="notice notice-error">
2475
+ <p>
2476
+ <?php
2477
+ _e('<strong>WP Google Maps:</strong> The Pro add-on is not compatible with this version of WP Google Maps. Please update your Pro addon to 5.24 or above', 'wp-google-maps');
2478
+ ?>
2479
+ </p>
2480
+ </div>
2481
+ <?php
2482
+
2483
+ });
2484
+ } else {
2485
+ add_action( 'admin_head', 'wpgmaps_head' );
2486
+ }
2487
+
2488
+ }
2489
+
2490
+ if(!function_exists('wpgmaps_trash_map'))
2491
+ {
2492
+ function wpgmaps_trash_map($map_id) {
2493
+ global $wpdb;
2494
+ global $wpgmza_tblname_maps;
2495
+ if (isset($map_id)) {
2496
+ $wpdb->query(
2497
+ $wpdb->prepare('DELETE FROM wp_wpgmza WHERE map_id=%d', (int)$map_id)
2498
+ );
2499
+ $rows_affected = $wpdb->query( $wpdb->prepare( "UPDATE $wpgmza_tblname_maps SET active = %d WHERE id = %d", 1, $map_id) );
2500
+ return true;
2501
+ } else {
2502
+ return false;
2503
+ }
2504
+ }
2505
  }
includes/legacy/functions.circle.php CHANGED
@@ -1,330 +1,330 @@
1
- <?php
2
-
3
- if(!function_exists('wpgmza_get_circle_data'))
4
- {
5
- function wpgmza_get_circle_data($map_id)
6
- {
7
- global $wpgmza;
8
- global $wpdb;
9
- global $wpgmza_tblname_circles;
10
-
11
- $stmt = $wpdb->prepare("SELECT *, {$wpgmza->spatialFunctionPrefix}AsText(center) AS center FROM $wpgmza_tblname_circles WHERE map_id=%d", array($map_id));
12
- $results = $wpdb->get_results($stmt);
13
-
14
- $circles = array();
15
- foreach($results as $obj)
16
- $circles[$obj->id] = $obj;
17
-
18
- return $circles;
19
- }
20
- }
21
-
22
- function wpgmza_b_add_circle($mid)
23
- {
24
- global $wpgmza_tblname_maps;
25
- global $wpdb;
26
-
27
- wpgmaps_b_admin_add_circle_javascript();
28
-
29
- if ($_GET['action'] == "add_circle" && isset($mid)) {
30
- $mid = intval($mid);
31
- $res = wpgmza_get_map_data($mid);
32
- echo "
33
-
34
-
35
-
36
-
37
- <div class='wrap'>
38
- <h1>WP Google Maps</h1>
39
- <div class='wide'>
40
-
41
- <h2>".__("Add circle","wp-google-maps")."</h2>
42
- <form action='?page=wp-google-maps-menu&action=edit&map_id=".$mid."' method='post' id='wpgmaps_add_circle_form'>
43
- <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".$mid."' />
44
- <input type='hidden' name='wpgmaps_circle-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_circle-nonce' )."' />
45
- <input type='hidden' name='center'/>
46
-
47
- <table class='wpgmza-listing-comp' style='width:30%;float:left;'>
48
- <tr>
49
- <td>
50
- ".__("Name","wp-google-maps")."
51
- </td>
52
- <td>
53
- <input id=\"circle\" name=\"circle_name\" type=\"text\" value=\"\" />
54
- </td>
55
- </tr>
56
- <tr>
57
- <td>
58
- ".__("Color","wp-google-maps")."
59
- </td>
60
- <td>
61
- <input id=\"circle_color\" name=\"circle_color\" type=\"color\" value=\"#ff0000\" />
62
- </td>
63
- </tr>
64
- <tr>
65
- <td>
66
- ".__("Opacity","wp-google-maps")."
67
- </td>
68
- <td>
69
- <input id=\"circle_opacity\" name=\"circle_opacity\" type=\"text\" value=\"0.6\" /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.6 for 60%</small>
70
- </td>
71
- </tr>
72
- <tr>
73
- <td>
74
- ".__("Radius","wp-google-maps")."
75
- </td>
76
- <td>
77
- <input id=\"circle_radius\" name=\"circle_radius\" type=\"text\" value=\"20\" />
78
- </td>
79
- </tr>
80
- <tr>
81
- <td></td>
82
- <td>
83
- <p id='circle-radius-visibility-warning' class='notice notice-warning'>
84
- " . __('Please note your circle may be too small to be visible at this zoom level', 'wp-google-maps') . "
85
- </p>
86
- </td>
87
- </tr>
88
- </table>
89
- <div class='wpgmza_map_seventy'>
90
- <div id=\"wpgmza_map\">&nbsp;</div>
91
- <p>
92
- <ul style=\"list-style:initial; margin-top: -145px !important;\" class='update-nag update-blue update-slim update-map-overlay'>
93
- <li style=\"margin-left:30px;\">" . __('Click on the map to insert a circle.', 'wp-google-maps') . "</li>
94
- <li style=\"margin-left:30px;\">" . __('Click or drag the circle to move it.', 'wp-google-maps') . "</li>
95
- </ul>
96
- </p>
97
- </div>
98
-
99
- <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_save_circle' class='button-primary' value='".__("Save Circle","wp-google-maps")." &raquo;' /></p>
100
-
101
- </form>
102
- </div>
103
-
104
-
105
- </div>
106
-
107
-
108
-
109
- ";
110
-
111
- }
112
- }
113
-
114
- function wpgmza_b_edit_circle($mid)
115
- {
116
- global $wpgmza;
117
- global $wpgmza_tblname_maps;
118
- global $wpgmza_tblname_circles;
119
- global $wpdb;
120
-
121
- wpgmaps_b_admin_add_circle_javascript();
122
-
123
- if ($_GET['action'] == "edit_circle" && isset($mid)) {
124
- $mid = intval($mid);
125
- $res = wpgmza_get_map_data($mid);
126
- $circle_id = (int) intval($_GET['circle_id']);
127
-
128
- $results = $wpdb->get_results("SELECT *, {$wpgmza->spatialFunctionPrefix}AsText(center) AS center FROM $wpgmza_tblname_circles WHERE id = $circle_id");
129
-
130
- if(empty($results))
131
- {
132
- echo "<p class='notice notice-error'>" . __('Invalid circle ID', 'wp-google-maps') . "</p>";
133
- return;
134
- }
135
-
136
- $circle = $results[0];
137
-
138
- $name = addcslashes($circle->name, '"');
139
- $center = preg_replace('/POINT\(|[,)]/', '', $circle->center);
140
-
141
- echo "
142
- <div class='wrap'>
143
- <h1>WP Google Maps</h1>
144
- <div class='wide'>
145
-
146
- <h2>".__("Edit circle","wp-google-maps")."</h2>
147
- <form action='?page=wp-google-maps-menu&action=edit&map_id=".$mid."' method='post' id='wpgmaps_add_circle_form'>
148
- <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".$mid."' />
149
- <input type='hidden' name='circle_id' value='{$circle_id}'/>
150
- <input type='hidden' name='wpgmaps_circle-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_circle-nonce' )."' />
151
-
152
-
153
- <input type='hidden' name='center' value='{$center}'/>
154
-
155
- <table class='wpgmza-listing-comp' style='width:30%;float:left;'>
156
- <tr>
157
- <td>
158
- " . __("Name","wp-google-maps") . "
159
- </td>
160
- <td>
161
- <input id=\"circle\" name=\"circle_name\" type=\"text\" value=\"$name\" />
162
- </td>
163
- </tr>
164
- <tr>
165
- <td>
166
- " . __('Center', 'wp-google-maps') . "
167
- </td>
168
- <td>
169
- <input name='center' value='" . esc_attr($center) . "'/>
170
- <button id='fit-bounds-to-shape'
171
- class='button button-secondary'
172
- type='button'
173
- title='" . __('Fit map bounds to shape', 'wp-google-maps') . "'
174
- data-fit-bounds-to-shape='circle'>
175
- <i class='fas fa-eye'></i>
176
- </button>
177
- </td>
178
- </tr>
179
- <tr>
180
- <td>
181
- ".__("Color","wp-google-maps")."
182
- </td>
183
- <td>
184
- <input id=\"circle_color\" name=\"circle_color\" type=\"color\" value=\"{$circle->color}\" />
185
- </td>
186
- </tr>
187
- <tr>
188
- <td>
189
- ".__("Opacity","wp-google-maps")."
190
- </td>
191
- <td>
192
- <input id=\"circle_opacity\" name=\"circle_opacity\" type=\"text\" value=\"{$circle->opacity}\" type='number' step='any' /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.6 for 60%</small>
193
- </td>
194
- </tr>
195
- <tr>
196
- <td>
197
- ".__("Radius","wp-google-maps")."
198
- </td>
199
- <td>
200
- <input id=\"circle_radius\" name=\"circle_radius\" type=\"text\" value=\"{$circle->radius}\" type='number' step='any' />
201
- </td>
202
- </tr>
203
- <tr>
204
- <td></td>
205
- <td>
206
- <p id='circle-radius-visibility-warning' class='notice notice-warning'>
207
- " . __('Please note your circle may be too small to be visible at this zoom level', 'wp-google-maps') . "
208
- </p>
209
- </td>
210
- </tr>
211
- </table>
212
- <div class='wpgmza_map_seventy'>
213
- <div id=\"wpgmza_map\">&nbsp;</div>
214
- <p>
215
- <ul style=\"list-style:initial; margin-top: -145px !important;\" class='update-nag update-blue update-slim update-map-overlay'>
216
- <li style=\"margin-left:30px;\">" . __('Click or drag the circle to move it.', 'wp-google-maps') . "</li>
217
- </ul>
218
- </p>
219
- </div>
220
-
221
- <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_save_circle' class='button-primary' value='".__("Save Circle","wp-google-maps")." &raquo;' /></p>
222
-
223
- </form>
224
- </div>
225
-
226
-
227
- </div>
228
-
229
-
230
-
231
- ";
232
-
233
- }
234
- }
235
-
236
- function wpgmaps_b_admin_add_circle_javascript()
237
- {
238
- $res = wpgmza_get_map_data(sanitize_text_field($_GET['map_id']));
239
- $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
240
-
241
- $wpgmza_lat = $res->map_start_lat;
242
- $wpgmza_lng = $res->map_start_lng;
243
- $wpgmza_map_type = $res->type;
244
- $wpgmza_width = $res->map_width;
245
- $wpgmza_height = $res->map_height;
246
- $wpgmza_width_type = $res->map_width_type;
247
- $wpgmza_height_type = $res->map_height_type;
248
- if (!$wpgmza_map_type || $wpgmza_map_type == "" || $wpgmza_map_type == "1") { $wpgmza_map_type = "ROADMAP"; }
249
- else if ($wpgmza_map_type == "2") { $wpgmza_map_type = "SATELLITE"; }
250
- else if ($wpgmza_map_type == "3") { $wpgmza_map_type = "HYBRID"; }
251
- else if ($wpgmza_map_type == "4") { $wpgmza_map_type = "TERRAIN"; }
252
- else { $wpgmza_map_type = "ROADMAP"; }
253
- $start_zoom = $res->map_start_zoom;
254
- if ($start_zoom < 1 || !$start_zoom) {
255
- $start_zoom = 5;
256
- }
257
-
258
- $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
259
- global $api_version_string;
260
-
261
- $localized_data = array(
262
- 'wpgmza_lat' => $wpgmza_lat,
263
- 'wpgmza_lng' => $wpgmza_lng,
264
- 'start_zoom' => $start_zoom,
265
- 'wpgmza_width' => $wpgmza_width,
266
- 'wpgmza_width_type' => $wpgmza_width_type,
267
- 'wpgmza_height' => $wpgmza_height,
268
- 'wpgmza_height_type' => $wpgmza_height_type,
269
- 'wpgmza_map_type' => $wpgmza_map_type
270
- );
271
-
272
- wp_enqueue_style('wpgooglemaps-css', wpgmaps_get_plugin_url() . 'css/wpgmza_style.css');
273
- wp_enqueue_script('wpgmza-legacy-circle-panel', plugin_dir_url(WPGMZA_FILE) . 'js/legacy/legacy-circle-panel.js');
274
- wp_localize_script('wpgmza-legacy-circle-panel', 'wpgmza_legacy', $localized_data);
275
- }
276
-
277
- if(!function_exists('wpgmza_get_circles_table'))
278
- {
279
- function wpgmza_get_circles_table($map_id)
280
- {
281
- global $wpdb;
282
- global $wpgmza_tblname_circles;
283
-
284
- $map_id = intval($map_id);
285
-
286
- $circles_table = "
287
- <table>
288
- <thead>
289
- <tr>
290
- <th>" . __('ID', 'wp-google-maps') . "</th>
291
- <th>" . __('Name', 'wp-google-maps') . "</th>
292
- <th>" . __('Action', 'wp-google-maps') . "</th>
293
- </tr>
294
- </thead>
295
- <tbody>
296
- ";
297
-
298
- $stmt = $wpdb->prepare("SELECT * FROM $wpgmza_tblname_circles WHERE map_id = %d", array($map_id));
299
- $circles = $wpdb->get_results($stmt);
300
- foreach($circles as $circle)
301
- {
302
- $circle->id = intval($circle->id);
303
-
304
- $circles_table .= "
305
- <tr>
306
- <td>{$circle->id}</td>
307
- <td>{$circle->name}</td>
308
- <td width='170' align='left'>
309
- <a href='" . esc_url(get_option('siteurl')) . "/wp-admin/admin.php?page=wp-google-maps-menu&amp;action=edit_circle&amp;map_id={$map_id}&amp;circle_id={$circle->id}'
310
- title='" . __('Edit', 'wp-google-maps') . "'
311
- class='wpgmza_edit_circle_btn button'
312
- id='{$circle->id}'>
313
- <i class='fa fa-edit'> </i>
314
- </a>
315
- <a href='javascript:void(0);'
316
- title='" . __('Delete this circle', 'wp-google-maps') . "' class='wpgmza_circle_del_btn button' id='{$circle->id}'><i class='fa fa-times'> </i>
317
- </a>
318
- </td>
319
- </tr>
320
- ";
321
- }
322
-
323
- $circles_table .= "
324
- </tbody>
325
- </table>
326
- ";
327
-
328
- return $circles_table;
329
- }
330
  }
1
+ <?php
2
+
3
+ if(!function_exists('wpgmza_get_circle_data'))
4
+ {
5
+ function wpgmza_get_circle_data($map_id)
6
+ {
7
+ global $wpgmza;
8
+ global $wpdb;
9
+ global $wpgmza_tblname_circles;
10
+
11
+ $stmt = $wpdb->prepare("SELECT *, {$wpgmza->spatialFunctionPrefix}AsText(center) AS center FROM $wpgmza_tblname_circles WHERE map_id=%d", array($map_id));
12
+ $results = $wpdb->get_results($stmt);
13
+
14
+ $circles = array();
15
+ foreach($results as $obj)
16
+ $circles[$obj->id] = $obj;
17
+
18
+ return $circles;
19
+ }
20
+ }
21
+
22
+ function wpgmza_b_add_circle($mid)
23
+ {
24
+ global $wpgmza_tblname_maps;
25
+ global $wpdb;
26
+
27
+ wpgmaps_b_admin_add_circle_javascript();
28
+
29
+ if ($_GET['action'] == "add_circle" && isset($mid)) {
30
+ $mid = intval($mid);
31
+ $res = wpgmza_get_map_data($mid);
32
+ echo "
33
+
34
+
35
+
36
+
37
+ <div class='wrap'>
38
+ <h1>WP Google Maps</h1>
39
+ <div class='wide'>
40
+
41
+ <h2>".__("Add circle","wp-google-maps")."</h2>
42
+ <form action='?page=wp-google-maps-menu&action=edit&map_id=".$mid."' method='post' id='wpgmaps_add_circle_form'>
43
+ <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".$mid."' />
44
+ <input type='hidden' name='wpgmaps_circle-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_circle-nonce' )."' />
45
+ <input type='hidden' name='center'/>
46
+
47
+ <table class='wpgmza-listing-comp' style='width:30%;float:left;'>
48
+ <tr>
49
+ <td>
50
+ ".__("Name","wp-google-maps")."
51
+ </td>
52
+ <td>
53
+ <input id=\"circle\" name=\"circle_name\" type=\"text\" value=\"\" />
54
+ </td>
55
+ </tr>
56
+ <tr>
57
+ <td>
58
+ ".__("Color","wp-google-maps")."
59
+ </td>
60
+ <td>
61
+ <input id=\"circle_color\" name=\"circle_color\" type=\"color\" value=\"#ff0000\" />
62
+ </td>
63
+ </tr>
64
+ <tr>
65
+ <td>
66
+ ".__("Opacity","wp-google-maps")."
67
+ </td>
68
+ <td>
69
+ <input id=\"circle_opacity\" name=\"circle_opacity\" type=\"text\" value=\"0.6\" /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.6 for 60%</small>
70
+ </td>
71
+ </tr>
72
+ <tr>
73
+ <td>
74
+ ".__("Radius","wp-google-maps")."
75
+ </td>
76
+ <td>
77
+ <input id=\"circle_radius\" name=\"circle_radius\" type=\"text\" value=\"20\" />
78
+ </td>
79
+ </tr>
80
+ <tr>
81
+ <td></td>
82
+ <td>
83
+ <p id='circle-radius-visibility-warning' class='notice notice-warning'>
84
+ " . __('Please note your circle may be too small to be visible at this zoom level', 'wp-google-maps') . "
85
+ </p>
86
+ </td>
87
+ </tr>
88
+ </table>
89
+ <div class='wpgmza_map_seventy'>
90
+ <div id=\"wpgmza_map\">&nbsp;</div>
91
+ <p>
92
+ <ul style=\"list-style:initial; margin-top: -145px !important;\" class='update-nag update-blue update-slim update-map-overlay'>
93
+ <li style=\"margin-left:30px;\">" . __('Click on the map to insert a circle.', 'wp-google-maps') . "</li>
94
+ <li style=\"margin-left:30px;\">" . __('Click or drag the circle to move it.', 'wp-google-maps') . "</li>
95
+ </ul>
96
+ </p>
97
+ </div>
98
+
99
+ <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_save_circle' class='button-primary' value='".__("Save Circle","wp-google-maps")." &raquo;' /></p>
100
+
101
+ </form>
102
+ </div>
103
+
104
+
105
+ </div>
106
+
107
+
108
+
109
+ ";
110
+
111
+ }
112
+ }
113
+
114
+ function wpgmza_b_edit_circle($mid)
115
+ {
116
+ global $wpgmza;
117
+ global $wpgmza_tblname_maps;
118
+ global $wpgmza_tblname_circles;
119
+ global $wpdb;
120
+
121
+ wpgmaps_b_admin_add_circle_javascript();
122
+
123
+ if ($_GET['action'] == "edit_circle" && isset($mid)) {
124
+ $mid = intval($mid);
125
+ $res = wpgmza_get_map_data($mid);
126
+ $circle_id = (int) intval($_GET['circle_id']);
127
+
128
+ $results = $wpdb->get_results("SELECT *, {$wpgmza->spatialFunctionPrefix}AsText(center) AS center FROM $wpgmza_tblname_circles WHERE id = $circle_id");
129
+
130
+ if(empty($results))
131
+ {
132
+ echo "<p class='notice notice-error'>" . __('Invalid circle ID', 'wp-google-maps') . "</p>";
133
+ return;
134
+ }
135
+
136
+ $circle = $results[0];
137
+
138
+ $name = addcslashes($circle->name, '"');
139
+ $center = preg_replace('/POINT\(|[,)]/', '', $circle->center);
140
+
141
+ echo "
142
+ <div class='wrap'>
143
+ <h1>WP Google Maps</h1>
144
+ <div class='wide'>
145
+
146
+ <h2>".__("Edit circle","wp-google-maps")."</h2>
147
+ <form action='?page=wp-google-maps-menu&action=edit&map_id=".$mid."' method='post' id='wpgmaps_add_circle_form'>
148
+ <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".$mid."' />
149
+ <input type='hidden' name='circle_id' value='{$circle_id}'/>
150
+ <input type='hidden' name='wpgmaps_circle-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_circle-nonce' )."' />
151
+
152
+
153
+ <input type='hidden' name='center' value='{$center}'/>
154
+
155
+ <table class='wpgmza-listing-comp' style='width:30%;float:left;'>
156
+ <tr>
157
+ <td>
158
+ " . __("Name","wp-google-maps") . "
159
+ </td>
160
+ <td>
161
+ <input id=\"circle\" name=\"circle_name\" type=\"text\" value=\"$name\" />
162
+ </td>
163
+ </tr>
164
+ <tr>
165
+ <td>
166
+ " . __('Center', 'wp-google-maps') . "
167
+ </td>
168
+ <td>
169
+ <input name='center' value='" . esc_attr($center) . "'/>
170
+ <button id='fit-bounds-to-shape'
171
+ class='button button-secondary'
172
+ type='button'
173
+ title='" . __('Fit map bounds to shape', 'wp-google-maps') . "'
174
+ data-fit-bounds-to-shape='circle'>
175
+ <i class='fas fa-eye'></i>
176
+ </button>
177
+ </td>
178
+ </tr>
179
+ <tr>
180
+ <td>
181
+ ".__("Color","wp-google-maps")."
182
+ </td>
183
+ <td>
184
+ <input id=\"circle_color\" name=\"circle_color\" type=\"color\" value=\"{$circle->color}\" />
185
+ </td>
186
+ </tr>
187
+ <tr>
188
+ <td>
189
+ ".__("Opacity","wp-google-maps")."
190
+ </td>
191
+ <td>
192
+ <input id=\"circle_opacity\" name=\"circle_opacity\" type=\"text\" value=\"{$circle->opacity}\" type='number' step='any' /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.6 for 60%</small>
193
+ </td>
194
+ </tr>
195
+ <tr>
196
+ <td>
197
+ ".__("Radius","wp-google-maps")."
198
+ </td>
199
+ <td>
200
+ <input id=\"circle_radius\" name=\"circle_radius\" type=\"text\" value=\"{$circle->radius}\" type='number' step='any' />
201
+ </td>
202
+ </tr>
203
+ <tr>
204
+ <td></td>
205
+ <td>
206
+ <p id='circle-radius-visibility-warning' class='notice notice-warning'>
207
+ " . __('Please note your circle may be too small to be visible at this zoom level', 'wp-google-maps') . "
208
+ </p>
209
+ </td>
210
+ </tr>
211
+ </table>
212
+ <div class='wpgmza_map_seventy'>
213
+ <div id=\"wpgmza_map\">&nbsp;</div>
214
+ <p>
215
+ <ul style=\"list-style:initial; margin-top: -145px !important;\" class='update-nag update-blue update-slim update-map-overlay'>
216
+ <li style=\"margin-left:30px;\">" . __('Click or drag the circle to move it.', 'wp-google-maps') . "</li>
217
+ </ul>
218
+ </p>
219
+ </div>
220
+
221
+ <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_save_circle' class='button-primary' value='".__("Save Circle","wp-google-maps")." &raquo;' /></p>
222
+
223
+ </form>
224
+ </div>
225
+
226
+
227
+ </div>
228
+
229
+
230
+
231
+ ";
232
+
233
+ }
234
+ }
235
+
236
+ function wpgmaps_b_admin_add_circle_javascript()
237
+ {
238
+ $res = wpgmza_get_map_data(sanitize_text_field($_GET['map_id']));
239
+ $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
240
+
241
+ $wpgmza_lat = $res->map_start_lat;
242
+ $wpgmza_lng = $res->map_start_lng;
243
+ $wpgmza_map_type = $res->type;
244
+ $wpgmza_width = $res->map_width;
245
+ $wpgmza_height = $res->map_height;
246
+ $wpgmza_width_type = $res->map_width_type;
247
+ $wpgmza_height_type = $res->map_height_type;
248
+ if (!$wpgmza_map_type || $wpgmza_map_type == "" || $wpgmza_map_type == "1") { $wpgmza_map_type = "ROADMAP"; }
249
+ else if ($wpgmza_map_type == "2") { $wpgmza_map_type = "SATELLITE"; }
250
+ else if ($wpgmza_map_type == "3") { $wpgmza_map_type = "HYBRID"; }
251
+ else if ($wpgmza_map_type == "4") { $wpgmza_map_type = "TERRAIN"; }
252
+ else { $wpgmza_map_type = "ROADMAP"; }
253
+ $start_zoom = $res->map_start_zoom;
254
+ if ($start_zoom < 1 || !$start_zoom) {
255
+ $start_zoom = 5;
256
+ }
257
+
258
+ $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
259
+ global $api_version_string;
260
+
261
+ $localized_data = array(
262
+ 'wpgmza_lat' => $wpgmza_lat,
263
+ 'wpgmza_lng' => $wpgmza_lng,
264
+ 'start_zoom' => $start_zoom,
265
+ 'wpgmza_width' => $wpgmza_width,
266
+ 'wpgmza_width_type' => $wpgmza_width_type,
267
+ 'wpgmza_height' => $wpgmza_height,
268
+ 'wpgmza_height_type' => $wpgmza_height_type,
269
+ 'wpgmza_map_type' => $wpgmza_map_type
270
+ );
271
+
272
+ wp_enqueue_style('wpgooglemaps-css', wpgmaps_get_plugin_url() . 'css/wpgmza_style.css');
273
+ wp_enqueue_script('wpgmza-legacy-circle-panel', plugin_dir_url(WPGMZA_FILE) . 'js/legacy/legacy-circle-panel.js');
274
+ wp_localize_script('wpgmza-legacy-circle-panel', 'wpgmza_legacy', $localized_data);
275
+ }
276
+
277
+ if(!function_exists('wpgmza_get_circles_table'))
278
+ {
279
+ function wpgmza_get_circles_table($map_id)
280
+ {
281
+ global $wpdb;
282
+ global $wpgmza_tblname_circles;
283
+
284
+ $map_id = intval($map_id);
285
+
286
+ $circles_table = "
287
+ <table>
288
+ <thead>
289
+ <tr>
290
+ <th>" . __('ID', 'wp-google-maps') . "</th>
291
+ <th>" . __('Name', 'wp-google-maps') . "</th>
292
+ <th>" . __('Action', 'wp-google-maps') . "</th>
293
+ </tr>
294
+ </thead>
295
+ <tbody>
296
+ ";
297
+
298
+ $stmt = $wpdb->prepare("SELECT * FROM $wpgmza_tblname_circles WHERE map_id = %d", array($map_id));
299
+ $circles = $wpdb->get_results($stmt);
300
+ foreach($circles as $circle)
301
+ {
302
+ $circle->id = intval($circle->id);
303
+
304
+ $circles_table .= "
305
+ <tr>
306
+ <td>{$circle->id}</td>
307
+ <td>{$circle->name}</td>
308
+ <td width='170' align='left'>
309
+ <a href='" . esc_url(get_option('siteurl')) . "/wp-admin/admin.php?page=wp-google-maps-menu&amp;action=edit_circle&amp;map_id={$map_id}&amp;circle_id={$circle->id}'
310
+ title='" . __('Edit', 'wp-google-maps') . "'
311
+ class='wpgmza_edit_circle_btn button'
312
+ id='{$circle->id}'>
313
+ <i class='fa fa-edit'> </i>
314
+ </a>
315
+ <a href='javascript:void(0);'
316
+ title='" . __('Delete this circle', 'wp-google-maps') . "' class='wpgmza_circle_del_btn button' id='{$circle->id}'><i class='fa fa-times'> </i>
317
+ </a>
318
+ </td>
319
+ </tr>
320
+ ";
321
+ }
322
+
323
+ $circles_table .= "
324
+ </tbody>
325
+ </table>
326
+ ";
327
+
328
+ return $circles_table;
329
+ }
330
  }
includes/legacy/functions.rectangle.php CHANGED
@@ -1,299 +1,299 @@
1
- <?php
2
-
3
- if(!function_exists('wpgmza_get_rectangle_data'))
4
- {
5
- function wpgmza_get_rectangle_data($map_id)
6
- {
7
- global $wpgmza;
8
- global $wpdb;
9
- global $wpgmza_tblname_rectangles;
10
-
11
- $stmt = $wpdb->prepare("SELECT *, {$wpgmza->spatialFunctionPrefix}AsText(cornerA) AS cornerA, {$wpgmza->spatialFunctionPrefix}AsText(cornerB) AS cornerB FROM $wpgmza_tblname_rectangles WHERE map_id=%d", array($map_id));
12
- $results = $wpdb->get_results($stmt);
13
-
14
- $rectangles = array();
15
- foreach($results as $obj)
16
- $rectangles[$obj->id] = $obj;
17
-
18
- return $rectangles;
19
- }
20
- }
21
-
22
- function wpgmza_b_add_rectangle($mid)
23
- {
24
- global $wpgmza_tblname_maps;
25
- global $wpdb;
26
-
27
- wpgmaps_b_admin_add_rectangle_javascript();
28
-
29
- if ($_GET['action'] == "add_rectangle" && isset($mid)) {
30
- $mid = intval($mid);
31
- $res = wpgmza_get_map_data($mid);
32
- echo "
33
-
34
-
35
-
36
-
37
- <div class='wrap'>
38
- <h1>WP Google Maps</h1>
39
- <div class='wide'>
40
-
41
- <h2>".__("Add rectangle","wp-google-maps")."</h2>
42
- <form action='?page=wp-google-maps-menu&action=edit&map_id=".$mid."' method='post' id='wpgmaps_add_rectangle_form'>
43
- <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".$mid."' />
44
- <input type='hidden' name='wpgmaps_rectangle-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_rectangle-nonce' )."' />
45
- <input type='hidden' name='bounds'/>
46
-
47
- <table class='wpgmza-listing-comp' style='width:30%;float:left;'>
48
- <tr>
49
- <td>
50
- ".__("Name","wp-google-maps")."
51
- </td>
52
- <td>
53
- <input id=\"rectangle\" name=\"rectangle_name\" type=\"text\" value=\"\" />
54
- </td>
55
- </tr>
56
- <tr>
57
- <td>
58
- ".__("Color","wp-google-maps")."
59
- </td>
60
- <td>
61
- <input id=\"rectangle_color\" name=\"rectangle_color\" type=\"color\" value=\"#ff0000\" />
62
- </td>
63
- </tr>
64
- <tr>
65
- <td>
66
- ".__("Opacity","wp-google-maps")."
67
- </td>
68
- <td>
69
- <input id=\"rectangle_opacity\" name=\"rectangle_opacity\" type=\"text\" value=\"0.6\" /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.6 for 60%</small>
70
- </td>
71
- </tr>
72
-
73
- </table>
74
- <div class='wpgmza_map_seventy'>
75
- <div id=\"wpgmza_map\">&nbsp;</div>
76
- <p>
77
- <ul style=\"list-style:initial; margin-top: -145px !important;\" class='update-nag update-blue update-slim update-map-overlay'>
78
- <li style=\"margin-left:30px;\">" . __('Click on the map to insert a rectangle.', 'wp-google-maps') . "</li>
79
- <li style=\"margin-left:30px;\">" . __('Click or drag the rectangle to move it.', 'wp-google-maps') . "</li>
80
- </ul>
81
- </p>
82
- </div>
83
-
84
- <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_save_rectangle' class='button-primary' value='".__("Save rectangle","wp-google-maps")." &raquo;' /></p>
85
-
86
- </form>
87
- </div>
88
-
89
-
90
- </div>
91
-
92
-
93
-
94
- ";
95
-
96
- }
97
- }
98
-
99
- function wpgmza_b_edit_rectangle($mid)
100
- {
101
- global $wpgmza;
102
- global $wpgmza_tblname_maps;
103
- global $wpgmza_tblname_rectangles;
104
- global $wpdb;
105
-
106
- wpgmaps_b_admin_add_rectangle_javascript();
107
-
108
- if ($_GET['action'] == "edit_rectangle" && isset($mid)) {
109
- $mid = intval($mid);
110
- $res = wpgmza_get_map_data($mid);
111
- $rectangle_id = (int) intval($_GET['rectangle_id']);
112
-
113
- $results = $wpdb->get_results("SELECT *, {$wpgmza->spatialFunctionPrefix}AsText(cornerA) AS cornerA, {$wpgmza->spatialFunctionPrefix}AsText(cornerB) AS cornerB FROM $wpgmza_tblname_rectangles WHERE id = $rectangle_id");
114
-
115
- if(empty($results))
116
- {
117
- echo "<p class='notice notice-error'>" . __('Invalid rectangle ID', 'wp-google-maps') . "</p>";
118
- return;
119
- }
120
-
121
- $rectangle = $results[0];
122
-
123
- $name = addcslashes($rectangle->name, '"');
124
- preg_match_all('/-?\d+(\.\d+)?/', $rectangle->cornerA . $rectangle->cornerB, $m);
125
-
126
- $north = $m[0][0];
127
- $west = $m[0][1];
128
- $south = $m[0][2];
129
- $east = $m[0][3];
130
-
131
- echo "
132
- <div class='wrap'>
133
- <h1>WP Google Maps</h1>
134
- <div class='wide'>
135
-
136
- <h2>".__("Edit rectangle","wp-google-maps")."</h2>
137
- <form action='?page=wp-google-maps-menu&action=edit&map_id=".$mid."' method='post' id='wpgmaps_add_rectangle_form'>
138
- <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".$mid."' />
139
- <input type='hidden' name='rectangle_id' value='{$rectangle_id}'/>
140
- <input type='hidden' name='wpgmaps_rectangle-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_rectangle-nonce' )."' />
141
- <input type='hidden' name='bounds' value='$north $west $south $east'/>
142
-
143
- <table class='wpgmza-listing-comp' style='width:30%;float:left;'>
144
- <tr>
145
- <td>
146
- " . __("Name","wp-google-maps") . "
147
- </td>
148
- <td>
149
- <input id=\"rectangle\" name=\"rectangle_name\" type=\"text\" value=\"$name\" />
150
- </td>
151
- </tr>
152
- <tr>
153
- <td>
154
- ".__("Color","wp-google-maps")."
155
- </td>
156
- <td>
157
- <input id=\"rectangle_color\" name=\"rectangle_color\" type=\"color\" value=\"{$rectangle->color}\" />
158
- </td>
159
- </tr>
160
- <tr>
161
- <td>
162
- ".__("Opacity","wp-google-maps")."
163
- </td>
164
- <td>
165
- <input id=\"rectangle_opacity\" name=\"rectangle_opacity\" type=\"text\" value=\"{$rectangle->opacity}\" type='number' step='any' /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.6 for 60%</small>
166
- </td>
167
- </tr>
168
- <tr>
169
- <td>
170
- ".__('Show Rectangle', 'wp-google-maps')."
171
- </td>
172
- <td>
173
- <button id='fit-bounds-to-shape'
174
- class='button button-secondary'
175
- type='button'
176
- title='" . __('Fit map bounds to shape', 'wp-google-maps') . "'
177
- data-fit-bounds-to-shape='rectangle'>
178
- <i class='fas fa-eye'></i>
179
- </button>
180
- </td>
181
- </tr>
182
- </table>
183
- <div class='wpgmza_map_seventy'>
184
- <div id=\"wpgmza_map\">&nbsp;</div>
185
- <p>
186
- <ul style=\"list-style:initial; margin-top: -145px !important;\" class='update-nag update-blue update-slim update-map-overlay'>
187
- <li style=\"margin-left:30px;\">" . __('Click or drag the rectangle to move it.', 'wp-google-maps') . "</li>
188
- </ul>
189
- </p>
190
- </div>
191
-
192
- <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_save_rectangle' class='button-primary' value='".__("Save rectangle","wp-google-maps")." &raquo;' /></p>
193
-
194
- </form>
195
- </div>
196
-
197
-
198
- </div>
199
-
200
-
201
-
202
- ";
203
-
204
- }
205
- }
206
-
207
- function wpgmaps_b_admin_add_rectangle_javascript()
208
- {
209
- $res = wpgmza_get_map_data(sanitize_text_field($_GET['map_id']));
210
- $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
211
-
212
-
213
- $wpgmza_lat = $res->map_start_lat;
214
- $wpgmza_lng = $res->map_start_lng;
215
- $wpgmza_map_type = $res->type;
216
- $wpgmza_width = $res->map_width;
217
- $wpgmza_height = $res->map_height;
218
- $wpgmza_width_type = $res->map_width_type;
219
- $wpgmza_height_type = $res->map_height_type;
220
- if (!$wpgmza_map_type || $wpgmza_map_type == "" || $wpgmza_map_type == "1") { $wpgmza_map_type = "ROADMAP"; }
221
- else if ($wpgmza_map_type == "2") { $wpgmza_map_type = "SATELLITE"; }
222
- else if ($wpgmza_map_type == "3") { $wpgmza_map_type = "HYBRID"; }
223
- else if ($wpgmza_map_type == "4") { $wpgmza_map_type = "TERRAIN"; }
224
- else { $wpgmza_map_type = "ROADMAP"; }
225
- $start_zoom = $res->map_start_zoom;
226
- if ($start_zoom < 1 || !$start_zoom) {
227
- $start_zoom = 5;
228
- }
229
-
230
- $localized_data = array(
231
- 'wpgmza_lat' => $wpgmza_lat,
232
- 'wpgmza_lng' => $wpgmza_lng,
233
- 'start_zoom' => $start_zoom,
234
- 'wpgmza_width' => $wpgmza_width,
235
- 'wpgmza_width_type' => $wpgmza_width_type,
236
- 'wpgmza_height' => $wpgmza_height,
237
- 'wpgmza_height_type' => $wpgmza_height_type,
238
- 'wpgmza_map_type' => $wpgmza_map_type
239
- );
240
-
241
- wp_enqueue_style('wpgooglemaps-css', wpgmaps_get_plugin_url() . 'css/wpgmza_style.css');
242
- wp_enqueue_script('wpgmza-legacy-rectangle-panel', plugin_dir_url(WPGMZA_FILE) . 'js/legacy/legacy-rectangle-panel.js');
243
- wp_localize_script('wpgmza-legacy-rectangle-panel', 'wpgmza_legacy', $localized_data);
244
- }
245
-
246
- if(!function_exists('wpgmza_get_rectangles_table'))
247
- {
248
- function wpgmza_get_rectangles_table($map_id)
249
- {
250
- global $wpdb;
251
- global $wpgmza_tblname_rectangles;
252
-
253
- $map_id = intval($map_id);
254
-
255
- $rectangles_table = "
256
- <table>
257
- <thead>
258
- <tr>
259
- <th>" . __('ID', 'wp-google-maps') . "</th>
260
- <th>" . __('Name', 'wp-google-maps') . "</th>
261
- <th>" . __('Action', 'wp-google-maps') . "</th>
262
- </tr>
263
- </thead>
264
- <tbody>
265
- ";
266
-
267
- $stmt = $wpdb->prepare("SELECT * FROM $wpgmza_tblname_rectangles WHERE map_id = %d", array($map_id));
268
- $rectangles = $wpdb->get_results($stmt);
269
- foreach($rectangles as $rectangle)
270
- {
271
- $rectangle->id = intval($rectangle->id);
272
-
273
- $rectangles_table .= "
274
- <tr>
275
- <td>{$rectangle->id}</td>
276
- <td>{$rectangle->name}</td>
277
- <td width='170' align='left'>
278
- <a href='" . get_option('siteurl') . "/wp-admin/admin.php?page=wp-google-maps-menu&amp;action=edit_rectangle&amp;map_id={$map_id}&amp;rectangle_id={$rectangle->id}'
279
- title='" . __('Edit', 'wp-google-maps') . "'
280
- class='wpgmza_edit_rectangle_btn button'
281
- id='{$rectangle->id}'>
282
- <i class='fa fa-edit'> </i>
283
- </a>
284
- <a href='javascript:void(0);'
285
- title='" . __('Delete this rectangle', 'wp-google-maps') . "' class='wpgmza_rectangle_del_btn button' id='{$rectangle->id}'><i class='fa fa-times'> </i>
286
- </a>
287
- </td>
288
- </tr>
289
- ";
290
- }
291
-
292
- $rectangles_table .= "
293
- </tbody>
294
- </table>
295
- ";
296
-
297
- return $rectangles_table;
298
- }
299
  }
1
+ <?php
2
+
3
+ if(!function_exists('wpgmza_get_rectangle_data'))
4
+ {
5
+ function wpgmza_get_rectangle_data($map_id)
6
+ {
7
+ global $wpgmza;
8
+ global $wpdb;
9
+ global $wpgmza_tblname_rectangles;
10
+
11
+ $stmt = $wpdb->prepare("SELECT *, {$wpgmza->spatialFunctionPrefix}AsText(cornerA) AS cornerA, {$wpgmza->spatialFunctionPrefix}AsText(cornerB) AS cornerB FROM $wpgmza_tblname_rectangles WHERE map_id=%d", array($map_id));
12
+ $results = $wpdb->get_results($stmt);
13
+
14
+ $rectangles = array();
15
+ foreach($results as $obj)
16
+ $rectangles[$obj->id] = $obj;
17
+
18
+ return $rectangles;
19
+ }
20
+ }
21
+
22
+ function wpgmza_b_add_rectangle($mid)
23
+ {
24
+ global $wpgmza_tblname_maps;
25
+ global $wpdb;
26
+
27
+ wpgmaps_b_admin_add_rectangle_javascript();
28
+
29
+ if ($_GET['action'] == "add_rectangle" && isset($mid)) {
30
+ $mid = intval($mid);
31
+ $res = wpgmza_get_map_data($mid);
32
+ echo "
33
+
34
+
35
+
36
+
37
+ <div class='wrap'>
38
+ <h1>WP Google Maps</h1>
39
+ <div class='wide'>
40
+
41
+ <h2>".__("Add rectangle","wp-google-maps")."</h2>
42
+ <form action='?page=wp-google-maps-menu&action=edit&map_id=".$mid."' method='post' id='wpgmaps_add_rectangle_form'>
43
+ <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".$mid."' />
44
+ <input type='hidden' name='wpgmaps_rectangle-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_rectangle-nonce' )."' />
45
+ <input type='hidden' name='bounds'/>
46
+
47
+ <table class='wpgmza-listing-comp' style='width:30%;float:left;'>
48
+ <tr>
49
+ <td>
50
+ ".__("Name","wp-google-maps")."
51
+ </td>
52
+ <td>
53
+ <input id=\"rectangle\" name=\"rectangle_name\" type=\"text\" value=\"\" />
54
+ </td>
55
+ </tr>
56
+ <tr>
57
+ <td>
58
+ ".__("Color","wp-google-maps")."
59
+ </td>
60
+ <td>
61
+ <input id=\"rectangle_color\" name=\"rectangle_color\" type=\"color\" value=\"#ff0000\" />
62
+ </td>
63
+ </tr>
64
+ <tr>
65
+ <td>
66
+ ".__("Opacity","wp-google-maps")."
67
+ </td>
68
+ <td>
69
+ <input id=\"rectangle_opacity\" name=\"rectangle_opacity\" type=\"text\" value=\"0.6\" /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.6 for 60%</small>
70
+ </td>
71
+ </tr>
72
+
73
+ </table>
74
+ <div class='wpgmza_map_seventy'>
75
+ <div id=\"wpgmza_map\">&nbsp;</div>
76
+ <p>
77
+ <ul style=\"list-style:initial; margin-top: -145px !important;\" class='update-nag update-blue update-slim update-map-overlay'>
78
+ <li style=\"margin-left:30px;\">" . __('Click on the map to insert a rectangle.', 'wp-google-maps') . "</li>
79
+ <li style=\"margin-left:30px;\">" . __('Click or drag the rectangle to move it.', 'wp-google-maps') . "</li>
80
+ </ul>
81
+ </p>
82
+ </div>
83
+
84
+ <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_save_rectangle' class='button-primary' value='".__("Save rectangle","wp-google-maps")." &raquo;' /></p>
85
+
86
+ </form>
87
+ </div>
88
+
89
+
90
+ </div>
91
+
92
+
93
+
94
+ ";
95
+
96
+ }
97
+ }
98
+
99
+ function wpgmza_b_edit_rectangle($mid)
100
+ {
101
+ global $wpgmza;
102
+ global $wpgmza_tblname_maps;
103
+ global $wpgmza_tblname_rectangles;
104
+ global $wpdb;
105
+
106
+ wpgmaps_b_admin_add_rectangle_javascript();
107
+
108
+ if ($_GET['action'] == "edit_rectangle" && isset($mid)) {
109
+ $mid = intval($mid);
110
+ $res = wpgmza_get_map_data($mid);
111
+ $rectangle_id = (int) intval($_GET['rectangle_id']);
112
+
113
+ $results = $wpdb->get_results("SELECT *, {$wpgmza->spatialFunctionPrefix}AsText(cornerA) AS cornerA, {$wpgmza->spatialFunctionPrefix}AsText(cornerB) AS cornerB FROM $wpgmza_tblname_rectangles WHERE id = $rectangle_id");
114
+
115
+ if(empty($results))
116
+ {
117
+ echo "<p class='notice notice-error'>" . __('Invalid rectangle ID', 'wp-google-maps') . "</p>";
118
+ return;
119
+ }
120
+
121
+ $rectangle = $results[0];
122
+
123
+ $name = addcslashes($rectangle->name, '"');
124
+ preg_match_all('/-?\d+(\.\d+)?/', $rectangle->cornerA . $rectangle->cornerB, $m);
125
+
126
+ $north = $m[0][0];
127
+ $west = $m[0][1];
128
+ $south = $m[0][2];
129
+ $east = $m[0][3];
130
+
131
+ echo "
132
+ <div class='wrap'>
133
+ <h1>WP Google Maps</h1>
134
+ <div class='wide'>
135
+
136
+ <h2>".__("Edit rectangle","wp-google-maps")."</h2>
137
+ <form action='?page=wp-google-maps-menu&action=edit&map_id=".$mid."' method='post' id='wpgmaps_add_rectangle_form'>
138
+ <input type='hidden' name='wpgmaps_map_id' id='wpgmaps_map_id' value='".$mid."' />
139
+ <input type='hidden' name='rectangle_id' value='{$rectangle_id}'/>
140
+ <input type='hidden' name='wpgmaps_rectangle-nonce' id='wpgmaps_b_nonce' value='".wp_create_nonce( 'wpgmaps_rectangle-nonce' )."' />
141
+ <input type='hidden' name='bounds' value='$north $west $south $east'/>
142
+
143
+ <table class='wpgmza-listing-comp' style='width:30%;float:left;'>
144
+ <tr>
145
+ <td>
146
+ " . __("Name","wp-google-maps") . "
147
+ </td>
148
+ <td>
149
+ <input id=\"rectangle\" name=\"rectangle_name\" type=\"text\" value=\"$name\" />
150
+ </td>
151
+ </tr>
152
+ <tr>
153
+ <td>
154
+ ".__("Color","wp-google-maps")."
155
+ </td>
156
+ <td>
157
+ <input id=\"rectangle_color\" name=\"rectangle_color\" type=\"color\" value=\"{$rectangle->color}\" />
158
+ </td>
159
+ </tr>
160
+ <tr>
161
+ <td>
162
+ ".__("Opacity","wp-google-maps")."
163
+ </td>
164
+ <td>
165
+ <input id=\"rectangle_opacity\" name=\"rectangle_opacity\" type=\"text\" value=\"{$rectangle->opacity}\" type='number' step='any' /> <small class='wpgmza-info__small'>(0 - 1.0) example: 0.6 for 60%</small>
166
+ </td>
167
+ </tr>
168
+ <tr>
169
+ <td>
170
+ ".__('Show Rectangle', 'wp-google-maps')."
171
+ </td>
172
+ <td>
173
+ <button id='fit-bounds-to-shape'
174
+ class='button button-secondary'
175
+ type='button'
176
+ title='" . __('Fit map bounds to shape', 'wp-google-maps') . "'
177
+ data-fit-bounds-to-shape='rectangle'>
178
+ <i class='fas fa-eye'></i>
179
+ </button>
180
+ </td>
181
+ </tr>
182
+ </table>
183
+ <div class='wpgmza_map_seventy'>
184
+ <div id=\"wpgmza_map\">&nbsp;</div>
185
+ <p>
186
+ <ul style=\"list-style:initial; margin-top: -145px !important;\" class='update-nag update-blue update-slim update-map-overlay'>
187
+ <li style=\"margin-left:30px;\">" . __('Click or drag the rectangle to move it.', 'wp-google-maps') . "</li>
188
+ </ul>
189
+ </p>
190
+ </div>
191
+
192
+ <p class='submit'><a href='javascript:history.back();' class='button button-secondary' title='".__("Cancel")."'>".__("Cancel")."</a> <input type='submit' name='wpgmza_save_rectangle' class='button-primary' value='".__("Save rectangle","wp-google-maps")." &raquo;' /></p>
193
+
194
+ </form>
195
+ </div>
196
+
197
+
198
+ </div>
199
+
200
+
201
+
202
+ ";
203
+
204
+ }
205
+ }
206
+
207
+ function wpgmaps_b_admin_add_rectangle_javascript()
208
+ {
209
+ $res = wpgmza_get_map_data(sanitize_text_field($_GET['map_id']));
210
+ $wpgmza_settings = get_option("WPGMZA_OTHER_SETTINGS");
211
+
212
+
213
+ $wpgmza_lat = $res->map_start_lat;
214
+ $wpgmza_lng = $res->map_start_lng;
215
+ $wpgmza_map_type = $res->type;
216
+ $wpgmza_width = $res->map_width;
217
+ $wpgmza_height = $res->map_height;
218
+ $wpgmza_width_type = $res->map_width_type;
219
+ $wpgmza_height_type = $res->map_height_type;
220
+ if (!$wpgmza_map_type || $wpgmza_map_type == "" || $wpgmza_map_type == "1") { $wpgmza_map_type = "ROADMAP"; }
221
+ else if ($wpgmza_map_type == "2") { $wpgmza_map_type = "SATELLITE"; }
222
+ else if ($wpgmza_map_type == "3") { $wpgmza_map_type = "HYBRID"; }
223
+ else if ($wpgmza_map_type == "4") { $wpgmza_map_type = "TERRAIN"; }
224
+ else { $wpgmza_map_type = "ROADMAP"; }
225
+ $start_zoom = $res->map_start_zoom;
226
+ if ($start_zoom < 1 || !$start_zoom) {
227
+ $start_zoom = 5;
228
+ }
229
+
230
+ $localized_data = array(
231
+ 'wpgmza_lat' => $wpgmza_lat,
232
+ 'wpgmza_lng' => $wpgmza_lng,
233
+ 'start_zoom' => $start_zoom,
234
+ 'wpgmza_width' => $wpgmza_width,
235
+ 'wpgmza_width_type' => $wpgmza_width_type,
236
+ 'wpgmza_height' => $wpgmza_height,
237
+ 'wpgmza_height_type' => $wpgmza_height_type,
238
+ 'wpgmza_map_type' => $wpgmza_map_type
239
+ );
240
+
241
+ wp_enqueue_style('wpgooglemaps-css', wpgmaps_get_plugin_url() . 'css/wpgmza_style.css');
242
+ wp_enqueue_script('wpgmza-legacy-rectangle-panel', plugin_dir_url(WPGMZA_FILE) . 'js/legacy/legacy-rectangle-panel.js');
243
+ wp_localize_script('wpgmza-legacy-rectangle-panel', 'wpgmza_legacy', $localized_data);
244
+ }
245
+
246
+ if(!function_exists('wpgmza_get_rectangles_table'))
247
+ {
248
+ function wpgmza_get_rectangles_table($map_id)
249
+ {
250
+ global $wpdb;
251
+ global $wpgmza_tblname_rectangles;
252
+
253
+ $map_id = intval($map_id);
254
+
255
+ $rectangles_table = "
256
+ <table>
257
+ <thead>
258
+ <tr>
259
+ <th>" . __('ID', 'wp-google-maps') . "</th>
260
+ <th>" . __('Name', 'wp-google-maps') . "</th>
261
+ <th>" . __('Action', 'wp-google-maps') . "</th>
262
+ </tr>
263
+ </thead>
264
+ <tbody>
265
+ ";
266
+
267
+ $stmt = $wpdb->prepare("SELECT * FROM $wpgmza_tblname_rectangles WHERE map_id = %d", array($map_id));
268
+ $rectangles = $wpdb->get_results($stmt);
269
+ foreach($rectangles as $rectangle)
270
+ {
271
+ $rectangle->id = intval($rectangle->id);
272
+
273
+ $rectangles_table .= "
274
+ <tr>
275
+ <td>{$rectangle->id}</td>
276
+ <td>{$rectangle->name}</td>
277
+ <td width='170' align='left'>
278
+ <a href='" . get_option('siteurl') . "/wp-admin/admin.php?page=wp-google-maps-menu&amp;action=edit_rectangle&amp;map_id={$map_id}&amp;rectangle_id={$rectangle->id}'
279
+ title='" . __('Edit', 'wp-google-maps') . "'
280
+ class='wpgmza_edit_rectangle_btn button'
281
+ id='{$rectangle->id}'>
282
+ <i class='fa fa-edit'> </i>
283
+ </a>
284
+ <a href='javascript:void(0);'
285
+ title='" . __('Delete this rectangle', 'wp-google-maps') . "' class='wpgmza_rectangle_del_btn button' id='{$rectangle->id}'><i class='fa fa-times'> </i>
286
+ </a>
287
+ </td>
288
+ </tr>
289
+ ";
290
+ }
291
+
292
+ $rectangles_table .= "
293
+ </tbody>
294
+ </table>
295
+ ";
296
+
297
+ return $rectangles_table;
298
+ }
299
  }
includes/map-edit-page/class.map-edit-page.php CHANGED
@@ -1,341 +1,341 @@
1
- <?php
2
-
3
- namespace WPGMZA;
4
-
5
- class MapEditPage extends Page
6
- {
7
- protected $_document;
8
- protected $form;
9
-
10
- public function __construct($map_id = null) {
11
- global $wpgmza;
12
- global $wpgmza_pro_version;
13
-
14
- if($map_id === null)
15
- $map_id = intval($_REQUEST['map_id']);
16
-
17
-
18
-
19
- $map = $this->map = Map::createInstance($map_id);
20
- $map->element->setInlineStyle('min-height', '400px'); // Safeguard for map edit page zero height
21
- $map->element->setAttribute('id', 'wpgmza_map'); // Legacy HTML
22
-
23
-
24
-
25
-
26
- // Load the document
27
- $this->_document = $document = new DOMDocument();
28
- $this->_document->loadPHPFile(WPGMZA_PLUGIN_DIR_PATH . 'html/map-edit-page/map-edit-page.html.php');
29
-
30
- // Add-on span
31
- if(!$wpgmza->isProVersion())
32
- $document->querySelectorAll("#wpgmza-title-label, .add-new-editor")->remove();
33
-
34
- // HTTP referrer input
35
- if($element = $document->querySelector("input[name='http_referer']"))
36
- // NB: Used to be PHP_SELF. We're going to alter this to the current URI. Shouldn't be used, will need checking
37
- $element->setAttribute('value', $_SERVER['REQUEST_URI']);
38
-
39
- // Map ID
40
- if($element = $document->querySelector('#wpgmza_id'))
41
- $element->setAttribute('value', $map_id);
42
-
43
- // Shortcode
44
- if($element = $document->querySelector('.wpgmza_copy_shortcode'))
45
- $element->setAttribute('value', "[wpgmza id=\"$map_id\"]");
46
-
47
-
48
-
49
-
50
- // Theme panel
51
- if($element = $document->querySelector('.wpgmza-theme-panel'))
52
- {
53
- if($wpgmza->settings->engine != "open-layers")
54
- {
55
- $themePanel = new ThemePanel($map);
56
- $element->import($themePanel);
57
- }
58
- }
59
-
60
- // User interface style logic
61
- if($wpgmza->settings->user_interface_style == "legacy")
62
- {
63
- foreach($document->querySelectorAll("[data-require-legacy-user-interface-style='false']") as $element)
64
- $element->remove();
65
- }
66
- else
67
- {
68
- foreach($document->querySelectorAll("[data-require-legacy-user-interface-style='true']") as $element)
69
- $element->remove();
70
- }
71
-
72
- // Store locator radius dropdown
73
- if($element = $document->querySelector('.wpgmza-store-locator-default-radius'))
74
- {
75
- $suffix = ($map->store_locator_distance == 1 ? __('mi', 'wp-google-maps') : __('km', 'wp-google-maps'));
76
-
77
- $default = 10;
78
-
79
- if(!empty($map->store_locator_default_radius))
80
- $default = $map->store_locator_default_radius;
81
-
82
- $radii = StoreLocator::DEFAULT_RADII;
83
-
84
- if(!empty($wpgmza->settings->wpgmza_store_locator_radii) && preg_match_all('/\d+/', $wpgmza->settings->wpgmza_store_locator_radii, $m))
85
- $radii = $m[0];
86
-
87
- foreach($radii as $radius)
88
- {
89
- $option = $document->createElement('option');
90
-
91
- $option->setAttribute('value', $radius);
92
- $option->appendText($radius);
93
-
94
- if($radius == $default)
95
- $option->setAttribute('selected', 'selected');
96
-
97
- $element->appendChild($option);
98
- }
99
-
100
- $element->parentNode->appendText($suffix);
101
- }
102
-
103
- // Now populate from the map, we need to wait until now so that all the controls are ready
104
- // NB: Do NOT populate from the map when POSTing - because checkboxes will get stuck ON
105
- if($_SERVER["REQUEST_METHOD"] != "POST")
106
- @$document->populate($map);
107
-
108
- $document->populate(array(
109
- 'map_id' => $map_id,
110
- 'real_post_nonce' => wp_create_nonce('wpgmza')
111
- ));
112
-
113
- // Form setup
114
- $this->form = $document->querySelector('form');
115
- $this->form->setAttribute('action', admin_url('admin-post.php'));
116
- $this->form->querySelector("input[name='redirect_to']")->setAttribute('value', $_SERVER['REQUEST_URI']);
117
-
118
- $this->addFormNonces();
119
-
120
- // The map itself
121
- $document->querySelector("#wpgmza-map-container")->import($map->element);
122
-
123
- // Feature accordions
124
- $containers = $document->querySelectorAll(".wpgmza-feature-accordion");
125
-
126
- foreach($containers as $container)
127
- {
128
- $featureTypePlural = rtrim(ucwords($container->getAttribute('id')), 's');
129
- $featureTypeSingle = preg_replace('/s$/', '', $featureTypePlural);
130
-
131
- // Panel
132
- $featurePanelClass = "WPGMZA\\{$featureTypeSingle}Panel";
133
- $panel = new $featurePanelClass($map_id);
134
-
135
-
136
- $container->querySelector('.wpgmza-feature-panel-container')->import($panel);
137
-
138
-
139
-
140
- // Table
141
- $featureTableClass = "WPGMZA\\Admin{$featureTypePlural}DataTable";
142
-
143
- if($featureTypePlural === "Heatmap" && !$wpgmza->isProVersion()){
144
- //We require a more elegant solution. Move this to Pro entirely, to be addressed later
145
- continue;
146
- }
147
-
148
- $table = new $featureTableClass(array(
149
- 'map_id' => $map_id
150
- ));
151
-
152
-
153
- $document->querySelector("#wpgmza-table-container-".$featureTypePlural)->import($table->element);
154
-
155
- }
156
-
157
- if(empty($wpgmza->settings->wpgmza_google_maps_api_key) && $wpgmza->settings->engine == "google-maps"){
158
- $document->querySelector(".wpgmza-missing-key-notice")->removeClass('wpgmza-hidden');
159
- }
160
-
161
- $engineDialog = new MapsEngineDialog();
162
- @$document->querySelector("#wpgmza-map-container")->import($engineDialog->html());
163
-
164
-
165
-
166
-
167
-
168
-
169
- $this->disableProFeatures();
170
- $this->hideSelectedProFeatures();
171
- $this->removeProMarkerFeatures();
172
- $this->handleEngineSpecificFeatures();
173
-
174
- $this->populateAdvancedMarkersPanel();
175
-
176
-
177
- }
178
-
179
-
180
-
181
- public static function createMapPage() {
182
- if (isset($_GET) && $_GET['action'] == 'create-map-page' && isset($_GET['map_id'])) {
183
-
184
- // NB: Suggest using $this->map->id, global functions should be dropped
185
- $res = wpgmza_get_map_data(intval($_GET['map_id']));
186
-
187
- // Set the post ID to -1. This sets to no action at moment
188
- $post_id = -1;
189
-
190
- // Set the Author, Slug, title and content of the new post
191
- $author_id = get_current_user_id();
192
- if ($author_id) {
193
- $slug = 'map';
194
- $title = $res->map_title;
195
- $content = '[wpgmza id="'.$res->id.'"]';
196
-
197
-
198
- // do we have this slug?
199
- $args_posts = array(
200
- 'post_type' => 'page',
201
- 'post_status' => 'any',
202
- 'name' => $slug,
203
- 'posts_per_page' => 1,
204
- );
205
-
206
- $loop_posts = new \WP_Query( $args_posts );
207
- if ( ! $loop_posts->have_posts() ) {
208
-
209
- // we dont
210
- $post_id = wp_insert_post(
211
- array(
212
- 'comment_status' => 'closed',
213
- 'ping_status' => 'closed',
214
- 'post_author' => $author_id,
215
- 'post_name' => $slug,
216
- 'post_title' => $title,
217
- 'post_content' => $content,
218
- 'post_status' => 'publish',
219
- 'post_type' => 'page'
220
- )
221
- );
222
- echo '<script>window.location.href = "post.php?post='.intval($post_id).'&action=edit";</script>';
223
- return;
224
- } else {
225
- $loop_posts->the_post();
226
-
227
- // we do!
228
- $post_id = wp_insert_post(
229
- array(
230
- 'comment_status' => 'closed',
231
- 'ping_status' => 'closed',
232
- 'post_author' => $author_id,
233
- 'post_name' => $slug."-".$res->id,
234
- 'post_title' => $title,
235
- 'post_content' => $content,
236
- 'post_status' => 'publish',
237
- 'post_type' => 'page'
238
- )
239
- );
240
-
241
- echo '<script>window.location.href = "post.php?post='.intval($post_id).'&action=edit";</script>';
242
- return;
243
- }
244
- } else {
245
- echo "There was a problem creating the map page.";
246
- return;
247
- }
248
-
249
- return;
250
- }
251
- }
252
-
253
- // NB: This function is static because only the >= 8.1.0 admin UI manager will instantiate MapEditPage. Called by ScriptLoader.
254
- public static function enqueueLegacyScripts()
255
- {
256
- // NB: Legacy map edit page JavaScript support. This was historically called from basic, which is why it resides here now.
257
- add_action('admin_head', 'wpgmaps_admin_javascript_pro');
258
- }
259
-
260
- protected function removeProMarkerFeatures()
261
- {
262
- $this->document->querySelectorAll(".wpgmza-marker-panel .wpgmza-pro-feature")->remove();
263
- }
264
-
265
- protected function handleEngineSpecificFeatures()
266
- {
267
- global $wpgmza;
268
-
269
- if($wpgmza->settings->engine == "open-layers")
270
- $this->document->querySelectorAll("[data-wpgmza-require-engine='google-maps']")->remove();
271
- else
272
- $this->document->querySelectorAll("[data-wpgmza-require-engine='open-layers']")->remove();
273
- }
274
-
275
- protected function populateAdvancedMarkersPanel() {
276
- $panel = new MarkerPanel($this->map->id);
277
- $container = $this->document->querySelector("#advanced-markers");
278
-
279
-
280
-
281
-
282
-
283
-
284
- $source = $panel->querySelector(".wpgmza-feature-panel.wpgmza-marker-panel");
285
-
286
- $source->removeAttribute("data-wpgmza-feature-type");
287
- $source->removeAttribute("class");
288
-
289
- $container->import($source);
290
-
291
- $container->querySelectorAll("input, select, textarea")
292
- ->setAttribute("disabled", "disabled")
293
- ->setAttribute("title", __('Enable this feature with WP Google Maps - Pro add-on', 'wp-google-maps'));
294
- }
295
-
296
- public function onSubmit()
297
- {
298
- $ignore = array(
299
- 'redirect_to',
300
- 'shortcode',
301
- 'nonce',
302
- 'wpgmza_savemap'
303
- );
304
-
305
- // Check nonces
306
- if(!$this->isNonceValid($this->form, $_POST['nonce']))
307
- throw new \Exception("Invalid nonce");
308
-
309
- // Copy the data
310
- $data = stripslashes_deep($_POST);
311
-
312
- // Don't write "redirect_to" to the map settings
313
- foreach($ignore as $key)
314
- unset($data[$key]);
315
-
316
- // Patch for XSS report (Will be rebuilt later)
317
- if(!empty($data['map_title'])){
318
- $data['map_title'] = sanitize_text_field($data['map_title']);
319
- }
320
-
321
- // Fill out the form
322
- $this->form->populate($data);
323
-
324
- // Get the form data back
325
- $data = $this->form->serializeFormData();
326
-
327
- // Set the data on the map settings
328
- $this->map->set($data);
329
-
330
- // Done! Redirect to the specified URL
331
- wp_redirect(strip_tags($_POST['redirect_to']));
332
- }
333
-
334
- }
335
-
336
- add_action('admin_post_wpgmza_save_map', function() {
337
-
338
- $mapEditPage = MapEditPage::createInstance();
339
- $mapEditPage->onSubmit();
340
-
341
- });
1
+ <?php
2
+
3
+ namespace WPGMZA;
4
+
5
+ class MapEditPage extends Page
6
+ {
7
+ protected $_document;
8
+ protected $form;
9
+
10
+ public function __construct($map_id = null) {
11
+ global $wpgmza;
12
+ global $wpgmza_pro_version;
13
+
14
+ if($map_id === null)
15
+ $map_id = intval($_REQUEST['map_id']);
16
+
17
+
18
+
19
+ $map = $this->map = Map::createInstance($map_id);
20
+ $map->element->setInlineStyle('min-height', '400px'); // Safeguard for map edit page zero height
21
+ $map->element->setAttribute('id', 'wpgmza_map'); // Legacy HTML
22
+
23
+
24
+
25
+
26
+ // Load the document
27
+ $this->_document = $document = new DOMDocument();
28
+ $this->_document->loadPHPFile(WPGMZA_PLUGIN_DIR_PATH . 'html/map-edit-page/map-edit-page.html.php');
29
+
30
+ // Add-on span
31
+ if(!$wpgmza->isProVersion())
32
+ $document->querySelectorAll("#wpgmza-title-label, .add-new-editor")->remove();
33
+
34
+ // HTTP referrer input
35
+ if($element = $document->querySelector("input[name='http_referer']"))
36
+ // NB: Used to be PHP_SELF. We're going to alter this to the current URI. Shouldn't be used, will need checking
37
+ $element->setAttribute('value', $_SERVER['REQUEST_URI']);
38
+
39
+ // Map ID
40
+ if($element = $document->querySelector('#wpgmza_id'))
41
+ $element->setAttribute('value', $map_id);
42
+
43
+ // Shortcode
44
+ if($element = $document->querySelector('.wpgmza_copy_shortcode'))
45
+ $element->setAttribute('value', "[wpgmza id=\"$map_id\"]");
46
+
47
+
48
+
49
+
50
+ // Theme panel
51
+ if($element = $document->querySelector('.wpgmza-theme-panel'))
52
+ {
53
+ if($wpgmza->settings->engine != "open-layers")
54
+ {
55
+ $themePanel = new ThemePanel($map);
56
+ $element->import($themePanel);
57
+ }
58
+ }
59
+
60
+ // User interface style logic
61
+ if($wpgmza->settings->user_interface_style == "legacy")
62
+ {
63
+ foreach($document->querySelectorAll("[data-require-legacy-user-interface-style='false']") as $element)
64
+ $element->remove();
65
+ }
66
+ else
67
+ {
68
+ foreach($document->querySelectorAll("[data-require-legacy-user-interface-style='true']") as $element)
69
+ $element->remove();
70
+ }
71
+
72
+ // Store locator radius dropdown
73
+ if($element = $document->querySelector('.wpgmza-store-locator-default-radius'))
74
+ {
75
+ $suffix = ($map->store_locator_distance == 1 ? __('mi', 'wp-google-maps') : __('km', 'wp-google-maps'));
76
+
77
+ $default = 10;
78
+
79
+ if(!empty($map->store_locator_default_radius))
80
+ $default = $map->store_locator_default_radius;
81
+
82
+ $radii = StoreLocator::DEFAULT_RADII;
83
+
84
+ if(!empty($wpgmza->settings->wpgmza_store_locator_radii) && preg_match_all('/\d+/', $wpgmza->settings->wpgmza_store_locator_radii, $m))
85
+ $radii = $m[0];
86
+
87
+ foreach($radii as $radius)
88
+ {
89
+ $option = $document->createElement('option');
90
+
91
+ $option->setAttribute('value', $radius);
92
+ $option->appendText($radius);
93
+
94
+ if($radius == $default)
95
+ $option->setAttribute('selected', 'selected');
96
+
97
+ $element->appendChild($option);
98
+ }
99
+
100
+ $element->parentNode->appendText($suffix);
101
+ }
102
+
103
+ // Now populate from the map, we need to wait until now so that all the controls are ready
104
+ // NB: Do NOT populate from the map when POSTing - because checkboxes will get stuck ON
105
+ if($_SERVER["REQUEST_METHOD"] != "POST")
106
+ @$document->populate($map);
107
+
108
+ $document->populate(array(
109
+ 'map_id' => $map_id,
110
+ 'real_post_nonce' => wp_create_nonce('wpgmza')
111
+ ));
112
+
113
+ // Form setup
114
+ $this->form = $document->querySelector('form');
115
+ $this->form->setAttribute('action', admin_url('admin-post.php'));
116
+ $this->form->querySelector("input[name='redirect_to']")->setAttribute('value', $_SERVER['REQUEST_URI']);
117
+
118
+ $this->addFormNonces();
119
+
120
+ // The map itself
121
+ $document->querySelector("#wpgmza-map-container")->import($map->element);
122
+
123
+ // Feature accordions
124
+ $containers = $document->querySelectorAll(".wpgmza-feature-accordion");
125
+
126
+ foreach($containers as $container)
127
+ {
128
+ $featureTypePlural = rtrim(ucwords($container->getAttribute('id')), 's');
129
+ $featureTypeSingle = preg_replace('/s$/', '', $featureTypePlural);
130
+
131
+ // Panel
132
+ $featurePanelClass = "WPGMZA\\{$featureTypeSingle}Panel";
133
+ $panel = new $featurePanelClass($map_id);
134
+
135
+
136
+ $container->querySelector('.wpgmza-feature-panel-container')->import($panel);
137
+
138
+
139
+
140
+ // Table
141
+ $featureTableClass = "WPGMZA\\Admin{$featureTypePlural}DataTable";
142
+
143
+ if($featureTypePlural === "Heatmap" && !$wpgmza->isProVersion()){
144
+ //We require a more elegant solution. Move this to Pro entirely, to be addressed later
145
+ continue;
146
+ }
147
+
148
+ $table = new $featureTableClass(array(
149
+ 'map_id' => $map_id
150
+ ));
151
+
152
+
153
+ $document->querySelector("#wpgmza-table-container-".$featureTypePlural)->import($table->element);
154
+
155
+ }
156
+
157
+ if(empty($wpgmza->settings->wpgmza_google_maps_api_key) && $wpgmza->settings->engine == "google-maps"){
158
+ $document->querySelector(".wpgmza-missing-key-notice")->removeClass('wpgmza-hidden');
159
+ }
160
+
161
+ $engineDialog = new MapsEngineDialog();
162
+ @$document->querySelector("#wpgmza-map-container")->import($engineDialog->html());
163
+
164
+
165
+
166
+
167
+
168
+
169
+ $this->disableProFeatures();
170
+ $this->hideSelectedProFeatures();
171
+ $this->removeProMarkerFeatures();
172
+ $this->handleEngineSpecificFeatures();
173
+
174
+ $this->populateAdvancedMarkersPanel();
175
+
176
+
177
+ }
178
+
179
+
180
+
181
+ public static function createMapPage() {
182
+ if (isset($_GET) && $_GET['action'] == 'create-map-page' && isset($_GET['map_id'])) {
183
+
184
+ // NB: Suggest using $this->map->id, global functions should be dropped
185
+ $res = wpgmza_get_map_data(intval($_GET['map_id']));
186
+
187
+ // Set the post ID to -1. This sets to no action at moment
188
+ $post_id = -1;
189
+
190
+ // Set the Author, Slug, title and content of the new post
191
+ $author_id = get_current_user_id();
192
+ if ($author_id) {
193
+ $slug = 'map';
194
+ $title = $res->map_title;
195
+ $content = '[wpgmza id="'.$res->id.'"]';
196
+
197
+
198
+ // do we have this slug?
199
+ $args_posts = array(
200
+ 'post_type' => 'page',
201
+ 'post_status' => 'any',
202
+ 'name' => $slug,
203
+ 'posts_per_page' => 1,
204
+ );
205
+
206
+ $loop_posts = new \WP_Query( $args_posts );
207
+ if ( ! $loop_posts->have_posts() ) {
208
+
209
+ // we dont
210
+ $post_id = wp_insert_post(
211
+ array(
212
+ 'comment_status' => 'closed',
213
+ 'ping_status' => 'closed',
214
+ 'post_author' => $author_id,
215
+ 'post_name' => $slug,
216
+ 'post_title' => $title,
217
+ 'post_content' => $content,
218
+ 'post_status' => 'publish',
219
+ 'post_type' => 'page'
220
+ )
221
+ );
222
+ echo '<script>window.location.href = "post.php?post='.intval($post_id).'&action=edit";</script>';
223
+ return;
224
+ } else {
225
+ $loop_posts->the_post();
226
+
227
+ // we do!
228
+ $post_id = wp_insert_post(
229
+ array(
230
+ 'comment_status' => 'closed',
231
+ 'ping_status' => 'closed',
232
+ 'post_author' => $author_id,
233
+ 'post_name' => $slug."-".$res->id,
234
+ 'post_title' => $title,
235
+ 'post_content' => $content,
236
+ 'post_status' => 'publish',
237
+ 'post_type' => 'page'
238
+ )
239
+ );
240
+
241
+ echo '<script>window.location.href = "post.php?post='.intval($post_id).'&action=edit";</script>';
242
+ return;
243
+ }
244
+ } else {
245
+ echo "There was a problem creating the map page.";
246
+ return;
247
+ }
248
+
249
+ return;
250
+ }
251
+ }
252
+
253
+ // NB: This function is static because only the >= 8.1.0 admin UI manager will instantiate MapEditPage. Called by ScriptLoader.
254
+ public static function enqueueLegacyScripts()
255
+ {
256
+ // NB: Legacy map edit page JavaScript support. This was historically called from basic, which is why it resides here now.
257
+ add_action('admin_head', 'wpgmaps_admin_javascript_pro');
258
+ }
259
+
260
+ protected function removeProMarkerFeatures()
261
+ {
262
+ $this->document->querySelectorAll(".wpgmza-marker-panel .wpgmza-pro-feature")->remove();
263
+ }
264
+
265
+ protected function handleEngineSpecificFeatures()
266
+ {
267
+ global $wpgmza;
268
+
269
+ if($wpgmza->settings->engine == "open-layers")
270
+ $this->document->querySelectorAll("[data-wpgmza-require-engine='google-maps']")->remove();
271
+ else
272
+ $this->document->querySelectorAll("[data-wpgmza-require-engine='open-layers']")->remove();
273
+ }
274
+
275
+ protected function populateAdvancedMarkersPanel() {
276
+ $panel = new MarkerPanel($this->map->id);
277
+ $container = $this->document->querySelector("#advanced-markers");
278
+
279
+
280
+
281
+
282
+
283
+
284
+ $source = $panel->querySelector(".wpgmza-feature-panel.wpgmza-marker-panel");
285
+
286
+ $source->removeAttribute("data-wpgmza-feature-type");
287
+ $source->removeAttribute("class");
288
+
289
+ $container->import($source);
290
+
291
+ $container->querySelectorAll("input, select, textarea")
292
+ ->setAttribute("disabled", "disabled")
293
+ ->setAttribute("title", __('Enable this feature with WP Google Maps - Pro add-on', 'wp-google-maps'));
294
+ }
295
+
296
+ public function onSubmit()
297
+ {
298
+ $ignore = array(
299
+ 'redirect_to',
300
+ 'shortcode',
301
+ 'nonce',
302
+ 'wpgmza_savemap'
303
+ );
304
+
305
+ // Check nonces
306
+ if(!$this->isNonceValid($this->form, $_POST['nonce']))
307
+ throw new \Exception("Invalid nonce");
308
+
309
+ // Copy the data
310
+ $data = stripslashes_deep($_POST);
311
+
312
+ // Don't write "redirect_to" to the map settings
313
+ foreach($ignore as $key)
314
+ unset($data[$key]);
315
+
316
+ // Patch for XSS report (Will be rebuilt later)
317
+ if(!empty($data['map_title'])){
318
+ $data['map_title'] = sanitize_text_field($data['map_title']);
319
+ }
320
+
321
+ // Fill out the form
322
+ $this->form->populate($data);
323
+
324
+ // Get the form data back
325
+ $data = $this->form->serializeFormData();
326
+
327
+ // Set the data on the map settings
328
+ $this->map->set($data);
329
+
330
+ // Done! Redirect to the specified URL
331
+ wp_redirect(strip_tags($_POST['redirect_to']));
332
+ }
333
+
334
+ }
335
+
336
+ add_action('admin_post_wpgmza_save_map', function() {
337
+
338
+ $mapEditPage = MapEditPage::createInstance();
339
+ $mapEditPage->onSubmit();
340
+
341
+ });
includes/open-layers/class.nominatim-geocode-cache.php CHANGED
@@ -1,151 +1,151 @@
1
- <?php
2
-
3
- namespace WPGMZA;
4
-
5
- if(!defined('ABSPATH'))
6
- return;
7
-
8
- /**
9
- * Used to facilitate communication and caching between the client and the Nominatim Geocoding service
10
- */
11
- class NominatimGeocodeCache
12
- {
13
- /**
14
- * Constructor.
15
- */
16
- public function __construct()
17
- {
18
- global $wpdb;
19
-
20
- $this->table = $wpdb->prefix . "wpgmza_nominatim_geocode_cache";
21
-
22
- if(!$wpdb->get_var("SHOW TABLES LIKE '{$this->table}'"))
23
- {
24
- require_once(ABSPATH . '/wp-admin/includes/upgrade.php');
25
-
26
- \dbDelta("CREATE TABLE {$this->table} (
27
- id int(11) NOT NULL AUTO_INCREMENT,
28
- query VARCHAR(512),
29
- response TEXT,
30
- PRIMARY KEY (id)
31
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1");
32
- }
33
- }
34
-
35
- /**
36
- * Returns the cached result from the local geocode cache
37
- * @param string $query The address being queried
38
- * @return object|null The cached geocode result, or null where no result is found
39
- */
40
- public function get($query)
41
- {
42
- global $wpdb;
43
-
44
- // Check the cache first, as per the nominatim usage policy
45
- $stmt = $wpdb->prepare("SELECT response FROM {$this->table} WHERE query=%s LIMIT 1", array($query));
46
-
47
- $stmt = apply_filters( 'wpgmza_ol_nomination_cache_query_get', $stmt, $query );
48
-
49
- $string = $wpdb->get_var($stmt);
50
- $json = null;
51
-
52
- if(!empty($string))
53
- $json = json_decode(stripslashes($string));
54
-
55
- return $json;
56
- }
57
-
58
- /**
59
- * Caches the supplied response, from the supplied query
60
- * @param string $query The queried address
61
- * @param string $response The returned response to cache
62
- */
63
- public function set($query, $response)
64
- {
65
- global $wpdb;
66
-
67
- if(empty($query))
68
- throw new \Exception("First argument cannot be empty");
69
-
70
- $stmt = $wpdb->prepare("INSERT INTO {$this->table} (query, response) VALUES (%s, %s)", array(
71
- $query,
72
- $response
73
- ));
74
-
75
- $stmt = apply_filters( 'wpgmza_ol_nomination_cache_query_set', $stmt, $query, $response );
76
-
77
- $wpdb->query($stmt);
78
- }
79
-
80
- /**
81
- * Clears the cache
82
- */
83
- public function clear()
84
- {
85
- global $wpdb;
86
-
87
- $stmt = $wpdb->query("TRUNCATE TABLE {$this->table}");
88
- }
89
- }
90
-
91
- /**
92
- * Bind function to query Nominatim cache.
93
- * @deprecated This will be moved to the REST API in the future
94
- */
95
- function query_nominatim_cache()
96
- {
97
- $cache = new NominatimGeocodeCache();
98
- $record = $cache->get(sanitize_text_field($_GET['query']));
99
-
100
- if(!$record)
101
- $record = array();
102
-
103
- wp_send_json($record);
104
- exit;
105
- }
106
-
107
- /**
108
- * Bind function to store a response on the Nominatim cache.
109
- * @deprecated This will be moved to the REST API in the future
110
- */
111
- function store_nominatim_cache()
112
- {
113
- $cache = new NominatimGeocodeCache();
114
- $cache->set(sanitize_text_field($_POST['query']), $_POST['response']);
115
-
116
- wp_send_json(array(
117
- 'success' => 1
118
- ));
119
- exit;
120
- }
121
-
122
- /**
123
- * Bind function to clear the Nominatim cache.
124
- * @deprecated This will be moved to the REST API in the future
125
- */
126
- function clear_nominatim_cache()
127
- {
128
- global $wpgmza;
129
-
130
- if(!$wpgmza->isUserAllowedToEdit())
131
- {
132
- http_response_code(401);
133
- return;
134
- }
135
-
136
- $cache = new NominatimGeocodeCache();
137
- $cache->clear();
138
-
139
- wp_send_json(array(
140
- 'success' => 1
141
- ));
142
- exit;
143
- }
144
-
145
- add_action('wp_ajax_wpgmza_query_nominatim_cache', 'WPGMZA\\query_nominatim_cache');
146
- add_action('wp_ajax_nopriv_wpgmza_query_nominatim_cache', 'WPGMZA\\query_nominatim_cache');
147
-
148
- add_action('wp_ajax_wpgmza_store_nominatim_cache', 'WPGMZA\\store_nominatim_cache');
149
- add_action('wp_ajax_nopriv_wpgmza_store_nominatim_cache', 'WPGMZA\\store_nominatim_cache');
150
-
151
- add_action('wp_ajax_wpgmza_clear_nominatim_cache', 'WPGMZA\\clear_nominatim_cache');
1
+ <?php
2
+
3
+ namespace WPGMZA;
4
+
5
+ if(!defined('ABSPATH'))
6
+ return;
7
+
8
+ /**
9
+ * Used to facilitate communication and caching between the client and the Nominatim Geocoding service
10
+ */
11
+ class NominatimGeocodeCache
12
+ {
13
+ /**
14
+ * Constructor.
15
+ */
16
+ public function __construct()
17
+ {
18
+ global $wpdb;
19
+
20
+ $this->table = $wpdb->prefix . "wpgmza_nominatim_geocode_cache";
21
+
22
+ if(!$wpdb->get_var("SHOW TABLES LIKE '{$this->table}'"))
23
+ {
24
+ require_once(ABSPATH . '/wp-admin/includes/upgrade.php');
25
+
26
+ \dbDelta("CREATE TABLE {$this->table} (
27
+ id int(11) NOT NULL AUTO_INCREMENT,
28
+ query VARCHAR(512),
29
+ response TEXT,
30
+ PRIMARY KEY (id)
31
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1");
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Returns the cached result from the local geocode cache
37
+ * @param string $query The address being queried
38
+ * @return object|null The cached geocode result, or null where no result is found
39
+ */
40
+ public function get($query)
41
+ {
42
+ global $wpdb;
43
+
44
+ // Check the cache first, as per the nominatim usage policy
45
+ $stmt = $wpdb->prepare("SELECT response FROM {$this->table} WHERE query=%s LIMIT 1", array($query));
46
+
47
+ $stmt = apply_filters( 'wpgmza_ol_nomination_cache_query_get', $stmt, $query );
48
+
49
+ $string = $wpdb->get_var($stmt);
50
+ $json = null;
51
+
52
+ if(!empty($string))
53
+ $json = json_decode(stripslashes($string));
54
+
55
+ return $json;
56
+ }
57
+
58
+ /**
59
+ * Caches the supplied response, from the supplied query
60
+ * @param string $query The queried address
61
+ * @param string $response The returned response to cache
62
+ */
63
+ public function set($query, $response)
64
+ {
65
+ global $wpdb;
66
+
67
+ if(empty($query))
68
+ throw new \Exception("First argument cannot be empty");
69
+
70
+ $stmt = $wpdb->prepare("INSERT INTO {$this->table} (query, response) VALUES (%s, %s)", array(
71
+ $query,
72
+ $response
73
+ ));
74
+
75
+ $stmt = apply_filters( 'wpgmza_ol_nomination_cache_query_set', $stmt, $query, $response );
76
+
77
+ $wpdb->query($stmt);
78
+ }
79
+
80
+ /**
81
+ * Clears the cache
82
+ */
83
+ public function clear()
84
+ {
85
+ global $wpdb;
86
+
87
+ $stmt = $wpdb->query("TRUNCATE TABLE {$this->table}");
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Bind function to query Nominatim cache.
93
+ * @deprecated This will be moved to the REST API in the future
94
+ */
95
+ function query_nominatim_cache()
96
+ {
97
+ $cache = new NominatimGeocodeCache();
98
+ $record = $cache->get(sanitize_text_field($_GET['query']));
99
+
100
+ if(!$record)
101
+ $record = array();
102
+
103
+ wp_send_json($record);
104
+ exit;
105
+ }
106
+
107
+ /**
108
+ * Bind function to store a response on the Nominatim cache.
109
+ * @deprecated This will be moved to the REST API in the future
110
+ */
111
+ function store_nominatim_cache()
112
+ {
113
+ $cache = new NominatimGeocodeCache();
114
+ $cache->set(sanitize_text_field($_POST['query']), $_POST['response']);
115
+
116
+ wp_send_json(array(
117
+ 'success' => 1
118
+ ));
119
+ exit;
120
+ }
121
+
122
+ /**
123
+ * Bind function to clear the Nominatim cache.
124
+ * @deprecated This will be moved to the REST API in the future
125
+ */
126
+ function clear_nominatim_cache()
127
+ {
128
+ global $wpgmza;
129
+
130
+ if(!$wpgmza->isUserAllowedToEdit())
131
+ {
132
+ http_response_code(401);
133
+ return;
134
+ }
135
+
136
+ $cache = new NominatimGeocodeCache();
137
+ $cache->clear();
138
+
139
+ wp_send_json(array(
140
+ 'success' => 1
141
+ ));
142
+ exit;
143
+ }
144
+
145
+ add_action('wp_ajax_wpgmza_query_nominatim_cache', 'WPGMZA\\query_nominatim_cache');
146
+ add_action('wp_ajax_nopriv_wpgmza_query_nominatim_cache', 'WPGMZA\\query_nominatim_cache');
147
+
148
+ add_action('wp_ajax_wpgmza_store_nominatim_cache', 'WPGMZA\\store_nominatim_cache');
149
+ add_action('wp_ajax_nopriv_wpgmza_store_nominatim_cache', 'WPGMZA\\store_nominatim_cache');
150
+
151
+ add_action('wp_ajax_wpgmza_clear_nominatim_cache', 'WPGMZA\\clear_nominatim_cache');
includes/php8/class.dom-element.php CHANGED
@@ -1,718 +1,718 @@
1
- <?php
2
-
3
- namespace WPGMZA;
4
-
5
- if(!defined('ABSPATH'))
6
- return;
7
-
8
- require_once(plugin_dir_path(__FILE__) . '../class.selector-to-xpath.php');
9
-
10
- /**
11
- * Direct replacement for the defauly class.dom-element.php
12
- *
13
- * Due to the fact it is located in the php8 sub directory, we will only load it for PHP 8 users
14
- */
15
- class DOMElement extends \DOMElement
16
- {
17
- protected static $xpathConverter;
18
-
19
- public function __construct()
20
- {
21
- \DOMElement::__construct();
22
- }
23
-
24
- public function __get($name)
25
- {
26
- switch($name)
27
- {
28
- case "html":
29
-
30
- return $this->ownerDocument->saveHTML( $this );
31
-
32
- break;
33
- }
34
-
35
- return \DOMElement::__get($name);
36
- }
37
-
38
- /**
39
- * Runs a CSS selector on the element. This is equivilant to Javascripts querySelector
40
- * @param string $query a CSS selector
41
- * @return mixed The first descendant element that matches the selector, or NULL if there is no match
42
- */
43
- public function querySelector($query)
44
- {
45
- $results = $this->querySelectorAll($query);
46
-
47
- if(empty($results))
48
- return null;
49
-
50
- return $results[0];
51
- }
52
-
53
- /**
54
- * Runs a CSS selector on the element. This is equivilant to Javascripts querySelectorAll
55
- * @return mixed Any descendant element's that match the selector, or NULL if there is no match
56
- */
57
- public function querySelectorAll($query, $sort=true)
58
- {
59
- $xpath = new \DOMXPath($this->ownerDocument);
60
-
61
- try{
62
- $expr = DOMElement::selectorToXPath($query);
63
- }catch(Exception $e) {
64
- echo "<p class='notice notice-warning'>Failed to convert CSS selector to XPath (" . $e->getMessage() . ")</p>";
65
- }
66
-
67
- $list = $xpath->query($expr, $this);
68
- $results = array();
69
-
70
- for($i = 0; $i < $list->length; $i++)
71
- array_push($results, $list->item($i));
72
-
73
- if($sort)
74
- usort($results, array('WPGMZA\DOMElement', 'sortByDOMPosition'));
75
-
76
- return new DOMQueryResults($results);
77
- }
78
-
79
- /**
80
- * Traverses from this node up it's ancestors and returns the first node that matches the given selector
81
- * @param mixed $selector Either this node the first ancestor that matches this selector, or NULL if no match is found
82
- */
83
- public function closest($selector)
84
- {
85
- if($this === $this->ownerDocument->getDocumentElementSafe())
86
- throw new \Exception('Method not valid on document element');
87
-
88
- for($el = $this; $el->parentNode != null; $el = $el->parentNode)
89
- {
90
- $m = $el->parentNode->querySelectorAll($selector);
91
- if(array_search($el, $m, true) !== false)
92
- return $el;
93
- }
94
-
95
- return null;
96
- }
97
-
98
- /**
99
- * Wraps this element in the element passed in, then replaces this nodes original position
100
- * @param DOMElement The element to wrap this element in
101
- */
102
- public function wrap($wrapper)
103
- {
104
- $this->parentNode->replaceChild($wrapper, $this);
105
- $wrapper->appendChild($this);
106
- }
107
-
108
- /**
109
- * Test if this element comes before the other element in the DOM tree
110
- * @return boolean TRUE if this element comes before the other, FALSE if not
111
- */
112
- public function isBefore($other)
113
- {
114
- if($this->parentNode === $other->parentNode)
115
- return ($this->getBreadth() < $other->getBreadth());
116
-
117
- $this_depth = $this->getDepth();
118
- $other_depth = $other->getDepth();
119
-
120
- if($this_depth == $other_depth)
121
- return $this->parentNode->isBefore($other->parentNode);
122
-
123
- if($this_depth > $other_depth)
124
- {
125
- $ancestor = $this;
126
- $ancestor_depth = $this_depth;
127
-
128
- while($ancestor_depth > $other_depth)
129
- {
130
- $ancestor = $ancestor->parentNode;
131
- $ancestor_depth--;
132
- }
133
-
134
- return $ancestor->isBefore($other);
135
- }
136
-
137
- if($this_depth < $other_depth)
138
- {
139
- $ancestor = $other;
140
- $ancestor_depth = $other_depth;
141
-
142
- while($ancestor_depth > $this_depth)
143
- {
144
- $ancestor = $ancestor->parentNode;
145
- $ancestor_depth--;
146
- }
147
-
148
- return $this->isBefore($ancestor);
149
- }
150
- }
151
-
152
- /**
153
- * Returns the breadth (sometimes called child index) of this node in regards to it's siblings
154
- * @return int The index of this node
155
- */
156
- public function getBreadth()
157
- {
158
- $breadth = 0;
159
- for($node = $this->previousSibling; $node != null; $node = $node->previousSibling)
160
- $breadth++;
161
- return $breadth;
162
- }
163
-
164
- /**
165
- * Returns the depth of this node in regards to it's ancestors
166
- * @return int The depth of this node
167
- */
168
- public function getDepth()
169
- {
170
- $depth = 0;
171
- for($node = $this->parentNode; $node != null; $node = $node->parentNode)
172
- $depth++;
173
- return $depth;
174
- }
175
-
176
- /**
177
- * @internal sort function for DOM position sort
178
- */
179
- private static function sortByDOMPosition($a, $b)
180
- {
181
- return ($a->isBefore($b) ? -1 : 1);
182
- }
183
-
184
- /**
185
- * @internal Calls the CSS to XPath converter on the specified selector
186
- * @param string $selector The CSS selector
187
- * @return string The resulting XPath expression
188
- */
189
- public static function selectorToXPath($selector)
190
- {
191
- if(!DOMElement::$xpathConverter)
192
- DOMElement::$xpathConverter = new Selector\XPathConverter();
193
-
194
- $xpath = DOMElement::$xpathConverter->convert($selector);
195
-
196
- return $xpath;
197
- }
198
-
199
- /**
200
- * Imports the supplied subject into this node.
201
- * @param mixed $subject. Either a \DOMDocument, \DOMNode, .html filename, or string containing HTML/text. The function will attempt to detect which. If you import HTML that contains a <body> element, it will only import the inner body
202
- * @throws \Exception the subject was not recognised as any of the types above
203
- * @return $this element
204
- */
205
- public function import($subject, $forcePHP=false)
206
- {
207
- global $wpgmza;
208
-
209
- $node = null;
210
-
211
- if($subject instanceof \DOMDocument)
212
- {
213
- if(!$subject->getDocumentElementSafe())
214
- throw new \Exception('Document is empty');
215
-
216
- $node = $this->ownerDocument->importNode($subject->getDocumentElementSafe(), true);
217
-
218
- }
219
- else if($subject instanceof \DOMNode)
220
- {
221
- $node = $this->ownerDocument->importNode($subject, true);
222
- }
223
- else if(preg_match('/(\.html|\.php)$/i', $subject, $m))
224
- {
225
- // Subject is a filename
226
- if(!file_exists($subject))
227
- throw new \Exception('HTML file not found');
228
-
229
- $temp = new DOMDocument('1.0', 'UTF-8');
230
- if($forcePHP || preg_match('/\.php$/i', $m[1]))
231
- $temp->loadPHPFile($subject);
232
- else
233
- $temp->load($subject);
234
-
235
- $node = $this->ownerDocument->importNode($temp->getDocumentElementSafe(), true);
236
- }
237
- else if(is_string($subject))
238
- {
239
- if(empty($subject))
240
- return;
241
-
242
- if($subject != strip_tags($subject) || preg_match('/&.+;/', $subject))
243
- {
244
- // Subject is a HTML string
245
- $html = DOMDocument::convertUTF8ToHTMLEntities($subject);
246
-
247
- $temp = new DOMDocument('1.0', 'UTF-8');
248
- $str = "<div id='domdocument-import-payload___'>" . $html . "</div>";
249
-
250
- if($wpgmza->isInDeveloperMode()){
251
- $temp->loadHTML($str);
252
- } else {
253
- @$temp->loadHTML($str);
254
- }
255
-
256
- $body = $temp->querySelector('#domdocument-import-payload___');
257
- for($child = $body->firstChild; $child != null; $child = $child->nextSibling)
258
- {
259
- $node = $this->ownerDocument->importNode($child, true);
260
- $this->appendChild($node);
261
- }
262
- }
263
- else
264
- // Subject is a plain string
265
- $this->appendText($subject);
266
-
267
- return;
268
- }
269
- else if(empty($subject))
270
- {
271
- return;
272
- }
273
- else
274
- throw new \Exception('Don\'t know how to import "' . print_r($subject, true) . '" in ' . $this->ownerDocument->documentURI . ' on line ' . $this->getLineNo());
275
-
276
- if($body = $node->querySelector("body"))
277
- {
278
- // TODO: I don't think a query selector is necessary here. Iterating over the bodies children should be more optimal
279
- $results = $node->querySelectorAll("body>*");
280
-
281
- foreach($results as $child)
282
- $this->appendChild($child);
283
-
284
- return $results;
285
- }
286
- else
287
- {
288
- $this->appendChild($node);
289
- return $node;
290
- }
291
-
292
- return null;
293
- }
294
-
295
- /**
296
- * Sets an inline CSS style on this element. If it's already set, the old value will be removed first
297
- * @param string $name the CSS property name eg 'background-color'
298
- * @param string $value the value of the property eg '#ff4400'
299
- * @return $this
300
- */
301
- public function setInlineStyle($name, $value)
302
- {
303
- $this->removeInlineStyle($name);
304
- $style = $this->getAttribute('style');
305
- $this->setAttribute('style', $style . $name . ':' . $value . ';');
306
- return $this;
307
- }
308
-
309
- /**
310
- * Removes the inline CSS style specified by name
311
- * @param string $name the name of the CSS property eg 'background-color'
312
- * @return $this
313
- */
314
- public function removeInlineStyle($name)
315
- {
316
- if(!$this->hasAttribute('style'))
317
- return;
318
- $style = $this->getAttribute('style');
319
-
320
- $rules = preg_split('/\s*;\s*/', $style);
321
-
322
- for($i = count($rules) - 1; $i >= 0; $i--)
323
- {
324
- $param = preg_quote($name);
325
-
326
- if(preg_match("/^$param\s*:/", trim($rules[$i])))
327
- unset($rules[$i]);
328
- }
329
-
330
- $this->setAttribute('style', implode(';', $rules));
331
- return $this;
332
- }
333
-
334
- /**
335
- * Check if this element has an inline style by name
336
- * @param string $name the name of the CSS property to test for
337
- */
338
- public function hasInlineStyle($name)
339
- {
340
- if(!$this->hasAttribute('style'))
341
- return false;
342
- return preg_match("/\s*$name:.*?((;\s*)|$)/", $this->getAttribute('style'));
343
- }
344
-
345
- /**
346
- * Gets the value of the inline style by name
347
- * @param string $name the name of the CSS property you want the value for
348
- * @return mixed FALSE if there is no style property or no style with that name exists, or a string containing the property value if it does
349
- */
350
- public function getInlineStyle($name)
351
- {
352
- if(!$this->hasAttribute('style'))
353
- return false;
354
-
355
- $m = null;
356
- if(!preg_match("/\s*$name:(.*?)((;\s*)|$)/", $this->getAttribute('style')))
357
- return false;
358
-
359
- return $m[1];
360
- }
361
-
362
- /**
363
- * Adds a class to this elements class attribute. It will be ignored if the class already exists
364
- * @param string $name The classname
365
- * @return $this
366
- */
367
- public function addClass($name)
368
- {
369
- if($this->hasClass($name))
370
- return;
371
-
372
- $class = ($this->hasAttribute('class') ? $this->getAttribute('class') : '');
373
- $this->setAttribute('class', $class . (strlen($class) > 0 ? ' ' : '') . $name);
374
-
375
- return $this;
376
- }
377
-
378
- /**
379
- * Removes the specified class from this nodes class attribute
380
- * @param string $name The classname
381
- * @return $this
382
- */
383
- public function removeClass($name)
384
- {
385
- if(!$this->hasAttribute('class'))
386
- return;
387
-
388
- $class = trim(
389
- preg_replace('/\s{2,}/', ' ',
390
- preg_replace('/\\b' . $name . '\\b/', ' ', $this->getAttribute('class'))
391
- )
392
- );
393
-
394
- $this->setAttribute('class', $class);
395
-
396
- return $this;
397
- }
398
-
399
- /**
400
- * Tests if the specified class exists on this elements class attribute
401
- * @param string $name The classname
402
- * @return boolean FALSE if no such class existst, TRUE if it does
403
- */
404
- public function hasClass($name)
405
- {
406
- if(!$this->hasAttribute('class'))
407
- return false;
408
-
409
- return preg_match('/\\b' . $name . '\\b/', $this->getAttribute('class'));
410
- }
411
-
412
- /**
413
- * Populates the target element. If it is a form element, the value will be set according to the elements type/nodeName. If not, the value will be imported instead.
414
- * @param The target element. Usually a descendant of this element
415
- * @param string $key the key of the value we're populating with, used for formatting
416
- * @param string $value the value to populate with
417
- * @param array $formatters an array associative of functions to format certain values with, functions should be specified by key
418
- * @return void
419
- */
420
- protected function populateElement($target, $key, $value, $formatters)
421
- {
422
- if(!($target instanceof \DOMElement))
423
- throw new \Exception('Argument must be a DOMElement');
424
-
425
- switch(strtolower($target->nodeName))
426
- {
427
- case 'textarea':
428
- case 'select':
429
- case 'input':
430
- $target->setValue($value);
431
- break;
432
-
433
- case 'img':
434
- $target->setAttribute('src', $value);
435
- break;
436
-
437
- default:
438
- if(!is_null($formatters) && isset($formatters[$key]))
439
- $value = $formatters[$key]($value);
440
-
441
- if($value instanceof \DateTime)
442
- $value = $value->format('D jS M \'y g:ia');
443
-
444
- if($key == 'price')
445
- $value = number_format($value, 2, '.', '');
446
-
447
- if(is_object($value))
448
- throw new \Exception('Expected simple type in "'.$key.'" => "'.print_r($value,true).'"');
449
-
450
- $target->import( $value );
451
-
452
- break;
453
- }
454
- }
455
-
456
- /**
457
- * Takes a source object or associative array and optional array of formatting functions, and populates descendant named elements with the values from that source.
458
- * @param mixed $src Associative array or object with the keys and values
459
- * @param array $formatters Optional associative array of functions to format values with. The keys on this array correspond with the keys on $src
460
- * @return DOMElement This element
461
- */
462
- public function populate($src=null, $formatters=null)
463
- {
464
- $x = new \DOMXPath($this->ownerDocument);
465
-
466
- if(!$src)
467
- return $this;
468
-
469
- if(is_scalar($src))
470
- {
471
- $this->appendText($src);
472
- return $this;
473
- }
474
-
475
- foreach($src as $key => $value)
476
- {
477
- if(is_array($value))
478
- {
479
- $m = $x->query('descendant-or-self::*[@name="' . $key . '[]"]', $this);
480
-
481
- if($m->length > 0 && count($value) != $m->length)
482
- {
483
- if($src = $m->item(0)->closest('li,tr'))
484
- {
485
- for($i = $m->length; $i < count($value); $i++)
486
- {
487
- $item = $src->cloneNode(true);
488
- $src->parentNode->appendChild($item);
489
- }
490
- $m = $x->query('descendant-or-self::*[@name="' . $key . '[]"]', $this);
491
- }
492
- else
493
- throw new \Exception('Number of elements must match (' . count($value) . ' != ' . $m->length . ')');
494
- }
495
-
496
- for($i = 0; $i < $m->length; $i++)
497
- $this->populateElement($m->item($i), $key, $value[$i], $formatters);
498
- }
499
- else
500
- {
501
- $m = $x->query('descendant-or-self::*[@name="' . $key . '" or @data-name="' . $key . '"]', $this);
502
-
503
- for($i = 0; $i < $m->length; $i++)
504
- $this->populateElement($m->item($i), $key, $value, $formatters);
505
- }
506
- }
507
-
508
- return $this;
509
- }
510
-
511
- public function serializeFormData()
512
- {
513
- $data = array();
514
-
515
- foreach($this->querySelectorAll('input, select, textarea') as $input)
516
- {
517
- $name = $input->getAttribute('name');
518
-
519
- if(!$name)
520
- continue;
521
-
522
- if(preg_match('/nonce/i', $name))
523
- continue; // NB: Do not serialize nonce values
524
-
525
- switch($input->getAttribute('type'))
526
- {
527
- case 'checkbox':
528
-
529
- if($input->getValue())
530
- $data[$name] = true;
531
- else
532
- $data[$name] = false;
533
-
534
- break;
535
-
536
- case 'radio':
537
-
538
- if($input->getAttribute('checked'))
539
- $data[$name] = $input->getAttribute('value');
540
-
541
- break;
542
-
543
- default:
544
- $data[$name] = $input->getValue();
545
- break;
546
- }
547
- }
548
-
549
- return $data;
550
- }
551
-
552
- /**
553
- * Gets the value of this element
554
- * @return mixed A string if the element a text input, textarea or plain node, a boolean if the element is a checkbox or radio, or the value of the selected option if this element is a select
555
- */
556
- public function getValue()
557
- {
558
- switch(strtolower($this->nodeName))
559
- {
560
- case 'input':
561
- $type = ($this->hasAttribute('type') ? $this->getAttribute('type') : 'text');
562
- switch($type)
563
- {
564
- case 'radio':
565
- case 'checkbox':
566
- return $this->hasAttribute('checked');
567
- break;
568
-
569
- default:
570
- return $this->getAttribute('value');
571
- break;
572
- }
573
- break;
574
-
575
- case 'select':
576
- $option = $this->querySelector('option[selected]');
577
- if(!$option)
578
- return null;
579
-
580
- if($option->hasAttribute('value'))
581
- return $option->getAttribute('value');
582
-
583
- default:
584
- return $this->nodeValue;
585
- break;
586
- }
587
- }
588
-
589
- /**
590
- * Sets the value of this element. Intended for form elements only. If this element is a textarea, it will be appended as plain text. If this element is a select, it will attempt to select the option with the specified value. If the input is a radio or checkbox, it will set it accordingly. Otherwise, the value will be put into the value attribute
591
- * @throws \Exception If this element is a select, SMART_STRICT_MODE is declared and no option with that value exists
592
- * @throws \Exception If you call this method on a non-form element
593
- * @return This element
594
- */
595
- public function setValue($value)
596
- {
597
- /*if($this->getAttribute("name") == "wpgmza_gdpr_require_consent_before_load")
598
- {
599
-
600
- echo "<pre>";
601
- debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
602
- exit;
603
- }*/
604
-
605
- switch(strtolower($this->nodeName))
606
- {
607
- case 'textarea':
608
- $this->clear();
609
- $this->appendText( $value );
610
- break;
611
-
612
- case 'select':
613
- $deselect = $this->querySelectorAll('option[selected]');
614
- foreach($deselect as $d)
615
- $d->removeAttribute('selected');
616
-
617
- if($value === null)
618
- return $this;
619
-
620
- $option = $this->querySelector('option[value="' . $value . '"]');
621
-
622
- if(!$option)
623
- trigger_error('Option with value "' . $value . '" not found in "' . ($this->getAttribute('name')) . '"', E_USER_WARNING);
624
- else
625
- $option->setAttribute('selected', 'selected');
626
-
627
- break;
628
-
629
- case 'input':
630
- if(!$this->hasAttribute('type') || $this->getAttribute('type') == 'text')
631
- {
632
- if(is_string($value))
633
- $this->setAttribute('value', $value);
634
- }
635
- else switch(strtolower($this->getAttribute('type')))
636
- {
637
- case 'radio':
638
- if($this->hasAttribute('value') && $this->getAttribute('value') == $value)
639
- $this->setAttribute('checked', 'checked');
640
- else
641
- $this->removeAttribute('checked');
642
- break;
643
-
644
- case 'checkbox':
645
- if(!empty($value) && $value != false)
646
- $this->setAttribute('checked', 'checked');
647
- else
648
- $this->removeAttribute('checked');
649
- break;
650
-
651
- default:
652
- $this->setAttribute('value', $value);
653
- break;
654
- }
655
- break;
656
-
657
- default:
658
- throw new \Exception('Not yet implemented');
659
-
660
- $this->nodeValue = $value;
661
- break;
662
- }
663
-
664
- return $this;
665
- }
666
-
667
- /**
668
- * Appends the specified text to this element, shorthand utility function
669
- * @return \Smart\Element This element
670
- */
671
- public function appendText($text)
672
- {
673
- $this->appendChild( $this->ownerDocument->createTextNode( $text ) );
674
- return $this;
675
- }
676
-
677
- /**
678
- * Utility function to append the specified element after one of this elements children. Will append at the end if after is null
679
- * @param \Smart\Element the element to insert
680
- * @param \Smart\Element one of this elements children, or null
681
- * *@return \Smart\Element this element
682
- */
683
- public function insertAfter($elem, $after=null)
684
- {
685
- if($after->parentNode && $after->parentNode !== $this)
686
- throw new \Exception('Hierarchy error');
687
-
688
- if($after->nextSibling)
689
- $this->insertBefore($elem, $after->nextSibling);
690
- else
691
- $this->appendChild($elem);
692
-
693
- return $this;
694
- }
695
-
696
- /**
697
- * Clears this element, completely removing all it's contents
698
- * @return \Smart\Element This element
699
- */
700
- public function clear()
701
- {
702
-
703
- while($this->childNodes->length)
704
- $this->removeChild($this->firstChild);
705
- return $this;
706
- }
707
-
708
- /**
709
- * Removes this element from it's parent
710
- * @return \Smart\Element This element
711
- */
712
- public function remove() : void
713
- {
714
- if($this->parentNode)
715
- $this->parentNode->removeChild($this);
716
- }
717
- }
718
-
1
+ <?php
2
+
3
+ namespace WPGMZA;
4
+
5
+ if(!defined('ABSPATH'))
6
+ return;
7
+
8
+ require_once(plugin_dir_path(__FILE__) . '../class.selector-to-xpath.php');
9
+
10
+ /**
11
+ * Direct replacement for the defauly class.dom-element.php
12
+ *
13
+ * Due to the fact it is located in the php8 sub directory, we will only load it for PHP 8 users
14
+ */
15
+ class DOMElement extends \DOMElement
16
+ {
17
+ protected static $xpathConverter;
18
+
19
+ public function __construct()
20
+ {
21
+ \DOMElement::__construct();
22
+ }
23
+
24
+ public function __get($name)
25
+ {
26
+ switch($name)
27
+ {
28
+ case "html":
29
+
30
+ return $this->ownerDocument->saveHTML( $this );
31
+
32
+ break;
33
+ }
34
+
35
+ return \DOMElement::__get($name);
36
+ }
37
+
38
+ /**
39
+ * Runs a CSS selector on the element. This is equivilant to Javascripts querySelector
40
+ * @param string $query a CSS selector
41
+ * @return mixed The first descendant element that matches the selector, or NULL if there is no match
42
+ */
43
+ public function querySelector($query)
44
+ {
45
+ $results = $this->querySelectorAll($query);
46
+
47
+ if(empty($results))
48
+ return null;
49
+
50
+ return $results[0];
51
+ }
52
+
53
+ /**
54
+ * Runs a CSS selector on the element. This is equivilant to Javascripts querySelectorAll
55
+ * @return mixed Any descendant element's that match the selector, or NULL if there is no match
56
+ */
57
+ public function querySelectorAll($query, $sort=true)
58
+ {
59
+ $xpath = new \DOMXPath($this->ownerDocument);
60
+
61
+ try{
62
+ $expr = DOMElement::selectorToXPath($query);
63
+ }catch(Exception $e) {
64
+ echo "<p class='notice notice-warning'>Failed to convert CSS selector to XPath (" . $e->getMessage() . ")</p>";
65
+ }
66
+
67
+ $list = $xpath->query($expr, $this);
68
+ $results = array();
69
+
70
+ for($i = 0; $i < $list->length; $i++)
71
+ array_push($results, $list->item($i));
72
+
73
+ if($sort)
74
+ usort($results, array('WPGMZA\DOMElement', 'sortByDOMPosition'));
75
+
76
+ return new DOMQueryResults($results);
77
+ }
78
+
79
+ /**
80
+ * Traverses from this node up it's ancestors and returns the first node that matches the given selector
81
+ * @param mixed $selector Either this node the first ancestor that matches this selector, or NULL if no match is found
82
+ */
83
+ public function closest($selector)
84
+ {
85
+ if($this === $this->ownerDocument->getDocumentElementSafe())
86
+ throw new \Exception('Method not valid on document element');
87
+
88
+ for($el = $this; $el->parentNode != null; $el = $el->parentNode)
89
+ {
90
+ $m = $el->parentNode->querySelectorAll($selector);
91
+ if(array_search($el, $m, true) !== false)
92
+ return $el;
93
+ }
94
+
95
+ return null;
96
+ }
97
+
98
+ /**
99
+ * Wraps this element in the element passed in, then replaces this nodes original position
100
+ * @param DOMElement The element to wrap this element in
101
+ */
102
+ public function wrap($wrapper)
103
+ {
104
+ $this->parentNode->replaceChild($wrapper, $this);
105
+ $wrapper->appendChild($this);
106
+ }
107
+
108
+ /**
109
+ * Test if this element comes before the other element in the DOM tree
110
+ * @return boolean TRUE if this element comes before the other, FALSE if not
111
+ */
112
+ public function isBefore($other)
113
+ {
114
+ if($this->parentNode === $other->parentNode)
115
+ return ($this->getBreadth() < $other->getBreadth());
116
+
117
+ $this_depth = $this->getDepth();
118
+ $other_depth = $other->getDepth();
119
+
120
+ if($this_depth == $other_depth)
121
+ return $this->parentNode->isBefore($other->parentNode);
122
+
123
+ if($this_depth > $other_depth)
124
+ {
125
+ $ancestor = $this;
126
+ $ancestor_depth = $this_depth;
127
+
128
+ while($ancestor_depth > $other_depth)
129
+ {
130
+ $ancestor = $ancestor->parentNode;
131
+ $ancestor_depth--;
132
+ }
133
+
134
+ return $ancestor->isBefore($other);
135
+ }
136
+
137
+ if($this_depth < $other_depth)
138
+ {
139
+ $ancestor = $other;
140
+ $ancestor_depth = $other_depth;
141
+
142
+ while($ancestor_depth > $this_depth)
143
+ {
144
+ $ancestor = $ancestor->parentNode;
145
+ $ancestor_depth--;
146
+ }
147
+
148
+ return $this->isBefore($ancestor);
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Returns the breadth (sometimes called child index) of this node in regards to it's siblings
154
+ * @return int The index of this node
155
+ */
156
+ public function getBreadth()
157
+ {
158
+ $breadth = 0;
159
+ for($node = $this->previousSibling; $node != null; $node = $node->previousSibling)
160
+ $breadth++;
161
+ return $breadth;
162
+ }
163
+
164
+ /**
165
+ * Returns the depth of this node in regards to it's ancestors
166
+ * @return int The depth of this node
167
+ */
168
+ public function getDepth()
169
+ {
170
+ $depth = 0;
171
+ for($node = $this->parentNode; $node != null; $node = $node->parentNode)
172
+ $depth++;
173
+ return $depth;
174
+ }
175
+
176
+ /**
177
+ * @internal sort function for DOM position sort
178
+ */
179
+ private static function sortByDOMPosition($a, $b)
180
+ {
181
+ return ($a->isBefore($b) ? -1 : 1);
182
+ }
183
+
184
+ /**
185
+ * @internal Calls the CSS to XPath converter on the specified selector
186
+ * @param string $selector The CSS selector
187
+ * @return string The resulting XPath expression
188
+ */
189
+ public static function selectorToXPath($selector)
190
+ {
191
+ if(!DOMElement::$xpathConverter)
192
+ DOMElement::$xpathConverter = new Selector\XPathConverter();
193
+
194
+ $xpath = DOMElement::$xpathConverter->convert($selector);
195
+
196
+ return $xpath;
197
+ }
198
+
199
+ /**
200
+ * Imports the supplied subject into this node.
201
+ * @param mixed $subject. Either a \DOMDocument, \DOMNode, .html filename, or string containing HTML/text. The function will attempt to detect which. If you import HTML that contains a <body> element, it will only import the inner body
202
+ * @throws \Exception the subject was not recognised as any of the types above
203
+ * @return $this element
204
+ */
205
+ public function import($subject, $forcePHP=false)
206
+ {
207
+ global $wpgmza;
208
+
209
+ $node = null;
210
+
211
+ if($subject instanceof \DOMDocument)
212
+ {
213
+ if(!$subject->getDocumentElementSafe())
214
+ throw new \Exception('Document is empty');
215
+
216
+ $node = $this->ownerDocument->importNode($subject->getDocumentElementSafe(), true);
217
+
218
+ }
219
+ else if($subject instanceof \DOMNode)
220
+ {
221
+ $node = $this->ownerDocument->importNode($subject, true);
222
+ }
223
+ else if(preg_match('/(\.html|\.php)$/i', $subject, $m))
224
+ {
225
+ // Subject is a filename
226
+ if(!file_exists($subject))
227
+ throw new \Exception('HTML file not found');
228
+
229
+ $temp = new DOMDocument('1.0', 'UTF-8');
230
+ if($forcePHP || preg_match('/\.php$/i', $m[1]))
231
+ $temp->loadPHPFile($subject);
232
+ else
233
+ $temp->load($subject);
234
+
235
+ $node = $this->ownerDocument->importNode($temp->getDocumentElementSafe(), true);
236
+ }
237
+ else if(is_string($subject))
238
+ {
239
+ if(empty($subject))
240
+ return;
241
+
242
+ if($subject != strip_tags($subject) || preg_match('/&.+;/', $subject))
243
+ {
244
+ // Subject is a HTML string
245
+ $html = DOMDocument::convertUTF8ToHTMLEntities($subject);
246
+
247
+ $temp = new DOMDocument('1.0', 'UTF-8');
248
+ $str = "<div id='domdocument-import-payload___'>" . $html . "</div>";
249
+
250
+ if($wpgmza->isInDeveloperMode()){
251
+ $temp->loadHTML($str);
252
+ } else {
253
+ @$temp->loadHTML($str);
254
+ }
255
+
256
+ $body = $temp->querySelector('#domdocument-import-payload___');
257
+ for($child = $body->firstChild; $child != null; $child = $child->nextSibling)
258
+ {
259
+ $node = $this->ownerDocument->importNode($child, true);
260
+ $this->appendChild($node);
261
+ }
262
+ }
263
+ else
264
+ // Subject is a plain string
265
+ $this->appendText($subject);
266
+
267
+ return;
268
+ }
269
+ else if(empty($subject))
270
+ {
271
+ return;
272
+ }
273
+ else
274
+ throw new \Exception('Don\'t know how to import "' . print_r($subject, true) . '" in ' . $this->ownerDocument->documentURI . ' on line ' . $this->getLineNo());
275
+
276
+ if($body = $node->querySelector("body"))
277
+ {
278
+ // TODO: I don't think a query selector is necessary here. Iterating over the bodies children should be more optimal
279
+ $results = $node->querySelectorAll("body>*");
280
+
281
+ foreach($results as $child)
282
+ $this->appendChild($child);
283
+
284
+ return $results;
285
+ }
286
+ else
287
+ {
288
+ $this->appendChild($node);
289
+ return $node;
290
+ }
291
+
292
+ return null;
293
+ }
294
+
295
+ /**
296
+ * Sets an inline CSS style on this element. If it's already set, the old value will be removed first
297
+ * @param string $name the CSS property name eg 'background-color'
298
+ * @param string $value the value of the property eg '#ff4400'
299
+ * @return $this
300
+ */
301
+ public function setInlineStyle($name, $value)
302
+ {
303
+ $this->removeInlineStyle($name);
304
+ $style = $this->getAttribute('style');
305
+ $this->setAttribute('style', $style . $name . ':' . $value . ';');
306
+ return $this;
307
+ }
308
+
309
+ /**
310
+ * Removes the inline CSS style specified by name
311
+ * @param string $name the name of the CSS property eg 'background-color'
312
+ * @return $this
313
+ */
314
+ public function removeInlineStyle($name)
315
+ {
316
+ if(!$this->hasAttribute('style'))
317
+ return;
318
+ $style = $this->getAttribute('style');
319
+
320
+ $rules = preg_split('/\s*;\s*/', $style);
321
+
322
+ for($i = count($rules) - 1; $i >= 0; $i--)
323
+ {
324
+ $param = preg_quote($name);
325
+
326
+ if(preg_match("/^$param\s*:/", trim($rules[$i])))
327
+ unset($rules[$i]);
328
+ }
329
+
330
+ $this->setAttribute('style', implode(';', $rules));
331
+ return $this;
332
+ }
333
+
334
+ /**
335
+ * Check if this element has an inline style by name
336
+ * @param string $name the name of the CSS property to test for
337
+ */
338
+ public function hasInlineStyle($name)
339
+ {
340
+ if(!$this->hasAttribute('style'))
341
+ return false;
342
+ return preg_match("/\s*$name:.*?((;\s*)|$)/", $this->getAttribute('style'));
343
+ }
344
+
345
+ /**
346
+ * Gets the value of the inline style by name
347
+ * @param string $name the name of the CSS property you want the value for
348
+ * @return mixed FALSE if there is no style property or no style with that name exists, or a string containing the property value if it does
349
+ */
350
+ public function getInlineStyle($name)
351
+ {
352
+ if(!$this->hasAttribute('style'))
353
+ return false;
354
+
355
+ $m = null;
356
+ if(!preg_match("/\s*$name:(.*?)((;\s*)|$)/", $this->getAttribute('style')))
357
+ return false;
358
+
359
+ return $m[1];
360
+ }
361
+
362
+ /**
363
+ * Adds a class to this elements class attribute. It will be ignored if the class already exists
364
+ * @param string $name The classname
365
+ * @return $this
366
+ */
367
+ public function addClass($name)
368
+ {
369
+ if($this->hasClass($name))
370
+ return;
371
+
372
+ $class = ($this->hasAttribute('class') ? $this->getAttribute('class') : '');
373
+ $this->setAttribute('class', $class . (strlen($class) > 0 ? ' ' : '') . $name);
374
+
375
+ return $this;
376
+ }
377
+
378
+ /**
379
+ * Removes the specified class from this nodes class attribute
380
+ * @param string $name The classname
381
+ * @return $this
382
+ */
383
+ public function removeClass($name)
384
+ {
385
+ if(!$this->hasAttribute('class'))
386
+ return;
387
+
388
+ $class = trim(
389
+ preg_replace('/\s{2,}/', ' ',
390
+ preg_replace('/\\b' . $name . '\\b/', ' ', $this->getAttribute('class'))
391
+ )
392
+ );
393
+
394
+ $this->setAttribute('class', $class);
395
+
396
+ return $this;
397
+ }
398
+
399
+ /**
400
+ * Tests if the specified class exists on this elements class attribute
401
+ * @param string $name The classname
402
+ * @return boolean FALSE if no such class existst, TRUE if it does
403
+ */
404
+ public function hasClass($name)
405
+ {
406
+ if(!$this->hasAttribute('class'))
407
+ return false;
408
+
409
+ return preg_match('/\\b' . $name . '\\b/', $this->getAttribute('class'));
410
+ }
411
+
412
+ /**
413
+ * Populates the target element. If it is a form element, the value will be set according to the elements type/nodeName. If not, the value will be imported instead.
414
+ * @param The target element. Usually a descendant of this element
415
+ * @param string $key the key of the value we're populating with, used for formatting
416
+ * @param string $value the value to populate with
417
+ * @param array $formatters an array associative of functions to format certain values with, functions should be specified by key
418
+ * @return void
419
+ */
420
+ protected function populateElement($target, $key, $value, $formatters)
421
+ {
422
+ if(!($target instanceof \DOMElement))
423
+ throw new \Exception('Argument must be a DOMElement');
424
+
425
+ switch(strtolower($target->nodeName))
426
+ {
427
+ case 'textarea':
428
+ case 'select':
429
+ case 'input':
430
+ $target->setValue($value);
431
+ break;
432
+
433
+ case 'img':
434
+ $target->setAttribute('src', $value);
435
+ break;
436
+
437
+ default:
438
+ if(!is_null($formatters) && isset($formatters[$key]))
439
+ $value = $formatters[$key]($value);
440
+
441
+ if($value instanceof \DateTime)
442
+ $value = $value->format('D jS M \'y g:ia');
443
+
444
+ if($key == 'price')
445
+ $value = number_format($value, 2, '.', '');
446
+
447
+ if(is_object($value))
448
+ throw new \Exception('Expected simple type in "'.$key.'" => "'.print_r($value,true).'"');
449
+
450
+ $target->import( $value );
451
+
452
+ break;
453
+ }
454
+ }
455
+
456
+ /**
457
+ * Takes a source object or associative array and optional array of formatting functions, and populates descendant named elements with the values from that source.
458
+ * @param mixed $src Associative array or object with the keys and values
459
+ * @param array $formatters Optional associative array of functions to format values with. The keys on this array correspond with the keys on $src
460
+ * @return DOMElement This element
461
+ */
462
+ public function populate($src=null, $formatters=null)
463
+ {
464
+ $x = new \DOMXPath($this->ownerDocument);
465
+
466
+ if(!$src)
467
+ return $this;
468
+
469
+ if(is_scalar($src))
470
+ {
471
+ $this->appendText($src);
472
+ return $this;
473
+ }
474
+
475
+ foreach($src as $key => $value)
476
+ {
477
+ if(is_array($value))
478
+ {
479
+ $m = $x->query('descendant-or-self::*[@name="' . $key . '[]"]', $this);
480
+
481
+ if($m->length > 0 && count($value) != $m->length)
482
+ {
483
+ if($src = $m->item(0)->closest('li,tr'))
484
+ {
485
+ for($i = $m->length; $i < count($value); $i++)
486
+ {
487
+ $item = $src->cloneNode(true);
488
+ $src->parentNode->appendChild($item);
489
+ }
490
+ $m = $x->query('descendant-or-self::*[@name="' . $key . '[]"]', $this);
491
+ }
492
+ else
493
+ throw new \Exception('Number of elements must match (' . count($value) . ' != ' . $m->length . ')');
494
+ }
495
+
496
+ for($i = 0; $i < $m->length; $i++)
497
+ $this->populateElement($m->item($i), $key, $value[$i], $formatters);
498
+ }
499
+ else
500
+ {
501
+ $m = $x->query('descendant-or-self::*[@name="' . $key . '" or @data-name="' . $key . '"]', $this);
502
+
503
+ for($i = 0; $i < $m->length; $i++)
504
+ $this->populateElement($m->item($i), $key, $value, $formatters);
505
+ }
506
+ }
507
+
508
+ return $this;
509
+ }
510
+
511
+ public function serializeFormData()
512
+ {
513
+ $data = array();
514
+
515
+ foreach($this->querySelectorAll('input, select, textarea') as $input)
516
+ {
517
+ $name = $input->getAttribute('name');
518
+
519
+ if(!$name)
520
+ continue;
521
+
522
+ if(preg_match('/nonce/i', $name))
523
+ continue; // NB: Do not serialize nonce values
524
+
525
+ switch($input->getAttribute('type'))
526
+ {
527
+ case 'checkbox':
528
+
529
+ if($input->getValue())
530
+ $data[$name] = true;
531
+ else
532
+ $data[$name] = false;
533
+
534
+ break;
535
+
536
+ case 'radio':
537
+
538
+ if($input->getAttribute('checked'))
539
+ $data[$name] = $input->getAttribute('value');
540
+
541
+ break;
542
+
543
+ default:
544
+ $data[$name] = $input->getValue();
545
+ break;
546
+ }
547
+ }
548
+
549
+ return $data;
550
+ }
551
+
552
+ /**
553
+ * Gets the value of this element
554
+ * @return mixed A string if the element a text input, textarea or plain node, a boolean if the element is a checkbox or radio, or the value of the selected option if this element is a select
555
+ */
556
+ public function getValue()
557
+ {
558
+ switch(strtolower($this->nodeName))
559
+ {
560
+ case 'input':
561
+ $type = ($this->hasAttribute('type') ? $this->getAttribute('type') : 'text');
562
+ switch($type)
563
+ {
564
+ case 'radio':
565
+ case 'checkbox':
566
+ return $this->hasAttribute('checked');
567
+ break;
568
+
569
+ default:
570
+ return $this->getAttribute('value');
571
+ break;
572
+ }
573
+ break;
574
+
575
+ case 'select':
576
+ $option = $this->querySelector('option[selected]');
577
+ if(!$option)
578
+ return null;
579
+
580
+ if($option->hasAttribute('value'))
581
+ return $option->getAttribute('value');
582
+
583
+ default:
584
+ return $this->nodeValue;
585
+ break;
586
+ }
587
+ }
588
+
589
+ /**
590
+ * Sets the value of this element. Intended for form elements only. If this element is a textarea, it will be appended as plain text. If this element is a select, it will attempt to select the option with the specified value. If the input is a radio or checkbox, it will set it accordingly. Otherwise, the value will be put into the value attribute
591
+ * @throws \Exception If this element is a select, SMART_STRICT_MODE is declared and no option with that value exists
592
+ * @throws \Exception If you call this method on a non-form element
593
+ * @return This element
594
+ */
595
+ public function setValue($value)
596
+ {
597
+ /*if($this->getAttribute("name") == "wpgmza_gdpr_require_consent_before_load")
598
+ {
599
+
600
+ echo "<pre>";
601
+ debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
602
+ exit;
603
+ }*/
604
+
605
+ switch(strtolower($this->nodeName))
606
+ {
607
+ case 'textarea':
608
+ $this->clear();
609
+ $this->appendText( $value );
610
+ break;
611
+
612
+ case 'select':
613
+ $deselect = $this->querySelectorAll('option[selected]');
614
+ foreach($deselect as $d)
615
+ $d->removeAttribute('selected');
616
+
617
+ if($value === null)
618
+ return $this;
619
+
620
+ $option = $this->querySelector('option[value="' . $value . '"]');
621
+
622
+ if(!$option)
623
+ trigger_error('Option with value "' . $value . '" not found in "' . ($this->getAttribute('name')) . '"', E_USER_WARNING);
624
+ else
625
+ $option->setAttribute('selected', 'selected');
626
+
627
+ break;
628
+
629
+ case 'input':
630
+ if(!$this->hasAttribute('type') || $this->getAttribute('type') == 'text')
631
+ {
632
+ if(is_string($value))
633
+ $this->setAttribute('value', $value);
634
+ }
635
+ else switch(strtolower($this->getAttribute('type')))
636
+ {
637
+ case 'radio':
638
+ if($this->hasAttribute('value') && $this->getAttribute('value') == $value)
639
+ $this->setAttribute('checked', 'checked');
640
+ else
641
+ $this->removeAttribute('checked');
642
+ break;
643
+
644
+ case 'checkbox':
645
+ if(!empty($value) && $value != false)
646
+ $this->setAttribute('checked', 'checked');
647
+ else
648
+ $this->removeAttribute('checked');
649
+ break;
650
+
651
+ default:
652
+ $this->setAttribute('value', $value);
653
+ break;
654
+ }
655
+ break;
656
+
657
+ default:
658
+ throw new \Exception('Not yet implemented');
659
+
660
+ $this->nodeValue = $value;
661
+ break;
662
+ }
663
+
664
+ return $this;
665
+ }
666
+
667
+ /**
668
+ * Appends the specified text to this element, shorthand utility function
669
+ * @return \Smart\Element This element
670
+ */
671
+ public function appendText($text)
672
+ {
673
+ $this->appendChild( $this->ownerDocument->createTextNode( $text ) );
674
+ return $this;
675
+ }
676
+
677
+ /**
678
+ * Utility function to append the specified element after one of this elements children. Will append at the end if after is null
679
+ * @param \Smart\Element the element to insert
680
+ * @param \Smart\Element one of this elements children, or null
681
+ * *@return \Smart\Element this element
682
+ */
683
+ public function insertAfter($elem, $after=null)
684
+ {
685
+ if($after->parentNode && $after->parentNode !== $this)
686
+ throw new \Exception('Hierarchy error');
687
+
688
+ if($after->nextSibling)
689
+ $this->insertBefore($elem, $after->nextSibling);
690
+ else
691
+ $this->appendChild($elem);
692
+
693
+ return $this;
694
+ }
695
+
696
+ /**
697
+ * Clears this element, completely removing all it's contents
698
+ * @return \Smart\Element This element
699
+ */
700
+ public function clear()
701
+ {
702
+
703
+ while($this->childNodes->length)
704
+ $this->removeChild($this->firstChild);
705
+ return $this;
706
+ }
707
+
708
+ /**
709
+ * Removes this element from it's parent
710
+ * @return \Smart\Element This element
711
+ */
712
+ public function remove() : void
713
+ {
714
+ if($this->parentNode)
715
+ $this->parentNode->removeChild($this);
716
+ }
717
+ }
718
+
includes/tables/class.ajax-table.php CHANGED
@@ -1,391 +1,391 @@
1
- <?php
2
-
3
- namespace WPGMZA;
4
-
5
- if(!defined('ABSPATH'))
6
- return;
7
-
8
- class AjaxTable extends Table
9
- {
10
- protected $lastInputParams;
11
-
12
- public function __construct($table_name, $rest_api_route, $ajax_parameters=null)
13
- {
14
- Table::__construct($table_name);
15
-
16
- $this->element->setAttribute('data-wpgmza-php-class', get_called_class());
17
-
18
- $this->setRestAPIRoute($rest_api_route);
19
-
20
- if($ajax_parameters)
21
- $this->setAjaxParameters($ajax_parameters);
22
- }
23
-
24
- public function getAjaxParameters()
25
- {
26
- return $this->getAttributeParams('data-wpgmza-ajax-parameters');
27
- }
28
-
29
- public function setAjaxParameters($ajax_parameters)
30
- {
31
- $this->setAttributeParams('data-wpgmza-ajax-parameters', $ajax_parameters);
32
- }
33
-
34
- protected function getAttributeParams($name)
35
- {
36
- if(!$this->element->hasAttribute($name))
37
- return (object)array();
38
-
39
- return json_decode($this->element->getAttribute($name));
40
- }
41
-
42
- protected function setAttributeParams($name, $params)
43
- {
44
- if(!(is_array($params) || is_object($params)))
45
- throw new \Exception('Parameters must be JSON serializable');
46
-
47
- $obj = $this->getAttributeParams($name);
48
-
49
- foreach($params as $key => $value)
50
- $obj->{$key} = $value;
51
-
52
- $this->element->setAttribute($name, json_encode($obj));
53
- }
54
-
55
- protected function getRestAPIRoute()
56
- {
57
- return $this->element->getAttribute('data-wpgmza-rest-api-route');
58
- }
59
-
60
- protected function setRestAPIRoute($route)
61
- {
62
- if(!is_string($route))
63
- throw new \Exception('Invalid REST API route');
64
-
65
- $this->element->setAttribute('data-wpgmza-rest-api-route', $route);
66
- }
67
-
68
- protected function getColumns()
69
- {
70
- throw new \Exception('Abstract function called');
71
- }
72
-
73
- protected function getColumnNameByIndex($index)
74
- {
75
- $i = 0;
76
- $columns = $this->getColumns();
77
-
78
- foreach($columns as $key => $value)
79
- {
80
- if($i++ == $index)
81
- return $key;
82
- }
83
-
84
- return null;
85
- }
86
-
87
- protected function getOrderBy($input_params, $column_keys)
88
- {
89
- return 'id';
90
- }
91
-
92
- protected function getOrderDirection($input_params)
93
- {
94
- return 'DESC';
95
- }
96
-
97
- protected function getWhereClause($input_params, &$query_params, $clause_for_total=false)
98
- {
99
- global $wpgmza;
100
-
101
- $clauses = array();
102
-
103
- if(isset($input_params['overrideMarkerIDs']))
104
- {
105
- $markerIDs = $input_params['overrideMarkerIDs'];
106
-
107
- if(is_string($markerIDs))
108
- $markerIDs = explode(',', $markerIDs);
109
-
110
- if(empty($markerIDs))
111
- return '0';
112
- else
113
- return 'id IN (' . implode(', ', array_map('intval', $markerIDs)) . ')';
114
- }
115
-
116
- if(isset($input_params['mashup_ids']))
117
- {
118
- // NB: This is Pro logic and should be moved ideally
119
- $mashup_ids = $input_params['mashup_ids'];
120
- $placeholders = implode(',', array_fill(0, count($mashup_ids), '%d'));
121
-
122
- $clauses['mashup_ids'] = 'map_id IN (' . $placeholders. ')';
123
-
124
- for($i = 0; $i < count($mashup_ids); $i++)
125
- $query_params[] = $mashup_ids[$i];
126
- }
127
- else if(isset($input_params['map_id']))
128
- {
129
- $clauses['map_id'] = 'map_id=%d';
130
- $query_params[] = $input_params['map_id'];
131
- }
132
-
133
- // NB: Moved approval check to MarkerDataTable
134
-
135
- if(!$clause_for_total)
136
- {
137
- $search_clause = $this->getSearchClause($input_params, $query_params);
138
- if(!empty($search_clause))
139
- $clauses['search'] = $search_clause;
140
- }
141
-
142
- if(empty($clauses))
143
- return '1';
144
-
145
- return implode(' AND ', $clauses);
146
- }
147
-
148
- protected function getSearchClause($input_params, &$query_params, $exclude_columns=null)
149
- {
150
- global $wpdb;
151
-
152
- if(isset($input_params['overrideMarkerIDs']))
153
- return "";
154
-
155
- if(empty($input_params['search']['value']))
156
- return "";
157
-
158
- $columns = $this->getColumns();
159
-
160
- $clauses = array();
161
- $term = $input_params['search']['value'];
162
- $subclauses = array();
163
-
164
- foreach($columns as $key => $label)
165
- {
166
- if($exclude_columns && array_search($key, $exclude_columns) !== false)
167
- continue;
168
-
169
- array_push($subclauses, "$key LIKE %s");
170
- array_push($query_params, "%%" . $wpdb->esc_like($term) . "%%");
171
- }
172
-
173
- if(empty($subclauses))
174
- return '';
175
-
176
- $result = "(" . implode(' OR ', $subclauses) . ")";
177
-
178
- return $result;
179
- }
180
-
181
- /**
182
- * Gets the HAVING clause for the table query
183
- * @return string
184
- */
185
- protected function getHavingClause($input_params, &$query_params, $exclude_columns=null)
186
- {
187
- return '';
188
- }
189
-
190
- /**
191
- * Override this function to add additional columns to the query
192
- * @return array
193
- */
194
- protected function filterColumns(&$columns, $input_params)
195
- {
196
- foreach($columns as $key => $value)
197
- {
198
- if($value == 'mark')
199
- $columns[$key] = '\'<input type="checkbox" name="mark"/>\' AS mark';
200
- //else
201
- //$columns[$key] = "`$value`";
202
- }
203
-
204
- return $columns;
205
- }
206
-
207
- /**
208
- * Override this function to manipulate data before it's converted to datatables numeric array format
209
- * @return array
210
- */
211
- protected function filterResults(&$rows)
212
- {
213
- return $rows;
214
- }
215
-
216
- /**
217
- * Function can be used to override order by column
218
- * @return string
219
- */
220
- protected function filterOrderBy($orderBy, $keys)
221
- {
222
- return $orderBy;
223
- }
224
-
225
- /**
226
- * Function can be used to override order by column
227
- * @return string
228
- */
229
- protected function filterOrderDirection($orderDirection)
230
- {
231
- return $orderDirection;
232
- }
233
-
234
- protected function filterOrderClause($clause)
235
- {
236
- return $clause;
237
- }
238
-
239
- protected function getSQLBeforeWhere($input_params, &$query_params)
240
- {
241
- return "";
242
- }
243
-
244
- protected function getSQLAfterWhere($input_params, &$query_params)
245
- {
246
- return "";
247
- }
248
-
249
- protected function buildQueryString($columns, $where, $having, $input_params, &$query_params)
250
- {
251
- $imploded = implode(',', $columns);
252
- /**
253
- * Modified: 2021-10-11
254
- * Change: Remove 'SQL_CALC_FOUND_ROWS' as it is being deprecated
255
- * Reason: Some sites experiencing issues with this modifier and subsequent "FOUND_ROWS()" calls as it is being deprecated
256
- * Author: Dylan Auty
257
- */
258
- $qstr = "SELECT $imploded FROM {$this->table_name} " . $this->getSQLBeforeWhere($input_params, $query_params) . " WHERE $where " . $this->getSQLAfterWhere($input_params, $query_params, $where);
259
-
260
- if(!empty($having))
261
- $qstr .= " HAVING $having";
262
-
263
- return $qstr;
264
- }
265
-
266
- protected function buildCountQueryString($input_params, &$count_query_params)
267
- {
268
- $count_where = $this->getWhereClause($input_params, $count_query_params, true);
269
-
270
- return "SELECT COUNT(id) FROM {$this->table_name} WHERE $count_where";
271
- }
272
-
273
- protected function buildFilteredCountQueryString($input_params, &$count_query_params){
274
- $count_where = $this->getWhereClause($input_params, $count_query_params, false);
275
- return "SELECT COUNT(id) FROM {$this->table_name} WHERE $count_where";
276
- }
277
-
278
- public function getRecords($input_params)
279
- {
280
- global $wpdb;
281
- global $wpgmza;
282
-
283
- // Remember input parameters
284
- $this->lastInputParams = $input_params;
285
-
286
- // Build query
287
- $columns = $this->getColumns();
288
- $keys = array_keys($columns);
289
-
290
- $query_params = array();
291
- $total_query_params = array();
292
-
293
- // Where / Having
294
- $where = $this->getWhereClause($input_params, $query_params);
295
- $having = $this->getHavingClause($input_params, $query_params);
296
-
297
- // Order by
298
- $order_column = $this->filterOrderBy( $this->getOrderBy($input_params, $keys), $keys );
299
- $order_dir = $this->filterOrderDirection( $this->getOrderDirection($input_params) );
300
-
301
- // Columns to select
302
- $columns = $this->filterColumns($keys, $input_params);
303
-
304
- // Build query string
305
- $qstr = $this->buildQueryString($columns, $where, $having, $input_params, $query_params);
306
-
307
- // This code allows for more natural numeric sorting on text fields, not just numeric fields
308
- if(empty($order_column))
309
- $order_column = 'id';
310
- if(empty($order_dir))
311
- $order_dir = 'ASC';
312
-
313
- // NB: Removed ISNULL({$order_column}), {$order_column}+0 {$order_dir}, as this was giving unpredictable results
314
- $qstr .= " ORDER BY " . $this->filterOrderClause($order_column) . " {$order_dir}";
315
- //$qstr .= " ORDER BY " . $this->filterOrderClause("ISNULL({$order_column}), {$order_column}+0 {$order_dir}, {$order_column} {$order_dir}");
316
-
317
- // Limit
318
- if(isset($input_params['length']))
319
- {
320
- $length = $input_params['length'];
321
- if(isset($length) &&
322
- $length != '-1' &&
323
- !preg_match('/^all$/i', $length))
324
- {
325
- $qstr .= " LIMIT " . intval($input_params['length']);
326
-
327
- if(isset($input_params['start']))
328
- $qstr .= " OFFSET " . intval($input_params['start']);
329
- }
330
- }
331
-
332
- // Total count
333
- $count_query_params = array();
334
- $count_qstr = $this->buildCountQueryString($input_params, $count_query_params);
335
-
336
- if(!empty($query_params)){
337
- $stmt = $wpdb->prepare($count_qstr, $count_query_params);
338
- } else {
339
- $stmt = $count_qstr;
340
- }
341
-
342
- $total_count = (int)$wpdb->get_var($stmt);
343
-
344
- // Body
345
- if(!empty($query_params)){
346
- $stmt = $wpdb->prepare($qstr, $query_params);
347
- } else{
348
- $stmt = $qstr;
349
- }
350
-
351
- $rows = $wpdb->get_results($stmt);
352
-
353
- $this->filterResults($rows);
354
-
355
- // Found rows
356
- // DEPRECATED AS PER NOTES RE: MySQL 8.0.17 -> This now requires a separate count query as seen
357
- // $found_rows = $wpdb->get_var('SELECT FOUND_ROWS()');
358
- $filtered_query_params = array();
359
- $filtered_count_qstr = $this->buildFilteredCountQueryString($input_params, $filtered_query_params);
360
- if(!empty($filtered_query_params)){
361
- $stmt = $wpdb->prepare($filtered_count_qstr, $filtered_query_params);
362
- } else {
363
- $stmt = $filtered_count_qstr;
364
- }
365
-
366
- $found_rows = (int)$wpdb->get_var($stmt);
367
-
368
- // Meta
369
- $meta = array();
370
- foreach($rows as $key => $value){
371
- $meta[$key] = (array) $value;
372
- }
373
-
374
- $result = (object)array(
375
- 'recordsTotal' => $total_count,
376
- 'recordsFiltered' => $found_rows,
377
- 'data' => apply_filters('wpgmza_ajax_table_records', $rows),
378
- 'meta' => apply_filters('wpgmza_ajax_table_meta', $meta)
379
- );
380
-
381
- if($wpgmza->isInDeveloperMode())
382
- $result->query = $stmt;
383
-
384
- return $result;
385
- }
386
-
387
- public function data($input_params)
388
- {
389
- return $this->getRecords($input_params);
390
- }
391
- }
1
+ <?php
2
+
3
+ namespace WPGMZA;
4
+
5
+ if(!defined('ABSPATH'))
6
+ return;
7
+
8
+ class AjaxTable extends Table
9
+ {
10
+ protected $lastInputParams;
11
+
12
+ public function __construct($table_name, $rest_api_route, $ajax_parameters=null)
13
+ {
14
+ Table::__construct($table_name);
15
+
16
+ $this->element->setAttribute('data-wpgmza-php-class', get_called_class());
17
+
18
+ $this->setRestAPIRoute($rest_api_route);
19
+
20
+ if($ajax_parameters)
21
+ $this->setAjaxParameters($ajax_parameters);
22
+ }
23
+
24
+ public function getAjaxParameters()
25
+ {
26
+ return $this->getAttributeParams('data-wpgmza-ajax-parameters');
27
+ }
28
+
29
+ public function setAjaxParameters($ajax_parameters)
30
+ {
31
+ $this->setAttributeParams('data-wpgmza-ajax-parameters', $ajax_parameters);
32
+ }
33
+
34
+ protected function getAttributeParams($name)
35
+ {
36
+ if(!$this->element->hasAttribute($name))
37
+ return (object)array();
38
+
39
+ return json_decode($this->element->getAttribute($name));
40
+ }
41
+
42
+ protected function setAttributeParams($name, $params)
43
+ {
44
+ if(!(is_array($params) || is_object($params)))
45
+ throw new \Exception('Parameters must be JSON serializable');
46
+
47
+ $obj = $this->getAttributeParams($name);
48
+
49
+ foreach($params as $key => $value)
50
+ $obj->{$key} = $value;
51
+
52
+ $this->element->setAttribute($name, json_encode($obj));
53
+ }
54
+
55
+ protected function getRestAPIRoute()
56
+ {
57
+ return $this->element->getAttribute('data-wpgmza-rest-api-route');
58
+ }
59
+
60
+ protected function setRestAPIRoute($route)
61
+ {
62
+ if(!is_string($route))
63
+ throw new \Exception('Invalid REST API route');
64
+
65
+ $this->element->setAttribute('data-wpgmza-rest-api-route', $route);
66
+ }
67
+
68
+ protected function getColumns()
69
+ {
70
+ throw new \Exception('Abstract function called');
71
+ }
72
+
73
+ protected function getColumnNameByIndex($index)
74
+ {
75
+ $i = 0;
76
+ $columns = $this->getColumns();
77
+
78
+ foreach($columns as $key => $value)
79
+ {
80
+ if($i++ == $index)
81
+ return $key;
82
+ }
83
+
84
+ return null;
85
+ }
86
+
87
+ protected function getOrderBy($input_params, $column_keys)
88
+ {
89
+ return 'id';
90
+ }
91
+
92
+ protected function getOrderDirection($input_params)
93
+ {
94
+ return 'DESC';
95
+ }
96
+
97
+ protected function getWhereClause($input_params, &$query_params, $clause_for_total=false)
98
+ {
99
+ global $wpgmza;
100
+
101
+ $clauses = array();
102
+
103
+ if(isset($input_params['overrideMarkerIDs']))
104
+ {
105
+ $markerIDs = $input_params['overrideMarkerIDs'];
106
+
107
+ if(is_string($markerIDs))
108
+ $markerIDs = explode(',', $markerIDs);
109
+
110
+ if(empty($markerIDs))
111
+ return '0';
112
+ else
113
+ return 'id IN (' . implode(', ', array_map('intval', $markerIDs)) . ')';
114
+ }
115
+
116
+ if(isset($input_params['mashup_ids']))
117
+ {
118
+ // NB: This is Pro logic and should be moved ideally
119
+ $mashup_ids = $input_params['mashup_ids'];
120
+ $placeholders = implode(',', array_fill(0, count($mashup_ids), '%d'));
121
+
122
+ $clauses['mashup_ids'] = 'map_id IN (' . $placeholders. ')';
123
+
124
+ for($i = 0; $i < count($mashup_ids); $i++)
125
+ $query_params[] = $mashup_ids[$i];
126
+ }
127
+ else if(isset($input_params['map_id']))
128
+ {
129
+ $clauses['map_id'] = 'map_id=%d';
130
+ $query_params[] = $input_params['map_id'];
131
+ }
132
+
133
+ // NB: Moved approval check to MarkerDataTable
134
+
135
+ if(!$clause_for_total)
136
+ {
137
+ $search_clause = $this->getSearchClause($input_params, $query_params);
138
+ if(!empty($search_clause))
139
+ $clauses['search'] = $search_clause;
140
+ }
141
+
142
+ if(empty($clauses))
143
+ return '1';
144
+
145
+ return implode(' AND ', $clauses);
146
+ }
147
+
148
+ protected function getSearchClause($input_params, &$query_params, $exclude_columns=null)
149
+ {
150
+ global $wpdb;
151
+
152
+ if(isset($input_params['overrideMarkerIDs']))
153
+ return "";
154
+
155
+ if(empty($input_params['search']['value']))
156
+ return "";
157
+
158
+ $columns = $this->getColumns();
159
+
160
+ $clauses = array();
161
+ $term = $input_params['search']['value'];
162
+ $subclauses = array();
163
+
164
+ foreach($columns as $key => $label)
165
+ {
166
+ if($exclude_columns && array_search($key, $exclude_columns) !== false)
167
+ continue;
168
+
169
+ array_push($subclauses, "$key LIKE %s");
170
+ array_push($query_params, "%%" . $wpdb->esc_like($term) . "%%");
171
+ }
172
+
173
+ if(empty($subclauses))
174
+ return '';
175
+
176
+ $result = "(" . implode(' OR ', $subclauses) . ")";
177
+
178
+ return $result;
179
+ }
180
+
181
+ /**
182
+ * Gets the HAVING clause for the table query
183
+ * @return string
184
+ */
185
+ protected function getHavingClause($input_params, &$query_params, $exclude_columns=null)
186
+ {
187
+ return '';
188
+ }
189
+
190
+ /**
191
+ * Override this function to add additional columns to the query
192
+ * @return array
193
+ */
194
+ protected function filterColumns(&$columns, $input_params)
195
+ {
196
+ foreach($columns as $key => $value)
197
+ {
198
+ if($value == 'mark')
199
+ $columns[$key] = '\'<input type="checkbox" name="mark"/>\' AS mark';
200
+ //else
201
+ //$columns[$key] = "`$value`";
202
+ }
203
+
204
+ return $columns;
205
+ }
206
+
207
+ /**
208
+ * Override this function to manipulate data before it's converted to datatables numeric array format
209
+ * @return array
210
+ */
211
+ protected function filterResults(&$rows)
212
+ {
213
+ return $rows;
214
+ }
215
+
216
+ /**
217
+ * Function can be used to override order by column
218
+ * @return string
219
+ */
220
+ protected function filterOrderBy($orderBy, $keys)
221
+ {
222
+ return $orderBy;
223
+ }
224
+
225
+ /**
226
+ * Function can be used to override order by column
227
+ * @return string
228
+ */
229
+ protected function filterOrderDirection($orderDirection)
230
+ {
231
+ return $orderDirection;
232
+ }
233
+
234
+ protected function filterOrderClause($clause)
235
+ {
236
+ return $clause;
237
+ }
238
+
239
+ protected function getSQLBeforeWhere($input_params, &$query_params)
240
+ {
241
+ return "";
242
+ }
243
+
244
+ protected function getSQLAfterWhere($input_params, &$query_params)
245
+ {
246
+ return "";
247
+ }
248
+
249
+ protected function buildQueryString($columns, $where, $having, $input_params, &$query_params)
250
+ {
251
+ $imploded = implode(',', $columns);
252
+ /**
253
+ * Modified: 2021-10-11
254
+ * Change: Remove 'SQL_CALC_FOUND_ROWS' as it is being deprecated
255
+ * Reason: Some sites experiencing issues with this modifier and subsequent "FOUND_ROWS()" calls as it is being deprecated
256
+ * Author: Dylan Auty
257
+ */
258
+ $qstr = "SELECT $imploded FROM {$this->table_name} " . $this->getSQLBeforeWhere($input_params, $query_params) . " WHERE $where " . $this->getSQLAfterWhere($input_params, $query_params, $where);
259
+
260
+ if(!empty($having))
261
+ $qstr .= " HAVING $having";
262
+
263
+ return $qstr;
264
+ }
265
+
266
+ protected function buildCountQueryString($input_params, &$count_query_params)
267
+ {
268
+ $count_where = $this->getWhereClause($input_params, $count_query_params, true);
269
+
270
+ return "SELECT COUNT(id) FROM {$this->table_name} WHERE $count_where";
271
+ }
272
+
273
+ protected function buildFilteredCountQueryString($input_params, &$count_query_params){
274
+ $count_where = $this->getWhereClause($input_params, $count_query_params, false);
275
+ return "SELECT COUNT(id) FROM {$this->table_name} WHERE $count_where";
276
+ }
277
+
278
+ public function getRecords($input_params)
279
+ {
280
+ global $wpdb;
281
+ global $wpgmza;
282
+
283
+ // Remember input parameters
284
+ $this->lastInputParams = $input_params;
285
+
286
+ // Build query
287
+ $columns = $this->getColumns();
288
+ $keys = array_keys($columns);
289
+
290
+ $query_params = array();
291
+ $total_query_params = array();
292
+
293
+ // Where / Having
294
+ $where = $this->getWhereClause($input_params, $query_params);
295
+ $having = $this->getHavingClause($input_params, $query_params);
296
+
297
+ // Order by
298
+ $order_column = $this->filterOrderBy( $this->getOrderBy($input_params, $keys), $keys );
299
+ $order_dir = $this->filterOrderDirection( $this->getOrderDirection($input_params) );
300
+
301
+ // Columns to select
302
+ $columns = $this->filterColumns($keys, $input_params);
303
+
304
+ // Build query string
305
+ $qstr = $this->buildQueryString($columns, $where, $having, $input_params, $query_params);
306
+
307
+ // This code allows for more natural numeric sorting on text fields, not just numeric fields
308
+ if(empty($order_column))
309
+ $order_column = 'id';
310
+ if(empty($order_dir))
311
+ $order_dir = 'ASC';
312
+
313
+ // NB: Removed ISNULL({$order_column}), {$order_column}+0 {$order_dir}, as this was giving unpredictable results
314
+ $qstr .= " ORDER BY " . $this->filterOrderClause($order_column) . " {$order_dir}";
315
+ //$qstr .= " ORDER BY " . $this->filterOrderClause("ISNULL({$order_column}), {$order_column}+0 {$order_dir}, {$order_column} {$order_dir}");
316
+
317
+ // Limit
318
+ if(isset($input_params['length']))
319
+ {
320
+ $length = $input_params['length'];
321
+ if(isset($length) &&
322
+ $length != '-1' &&
323
+ !preg_match('/^all$/i', $length))
324
+ {
325
+ $qstr .= " LIMIT " . intval($input_params['length']);
326
+
327
+ if(isset($input_params['start']))
328
+ $qstr .= " OFFSET " . intval($input_params['start']);
329
+ }
330
+ }
331
+
332
+ // Total count
333
+ $count_query_params = array();
334
+ $count_qstr = $this->buildCountQueryString($input_params, $count_query_params);
335
+
336
+ if(!empty($query_params)){
337
+ $stmt = $wpdb->prepare($count_qstr, $count_query_params);
338
+ } else {
339
+ $stmt = $count_qstr;
340
+ }
341
+
342
+ $total_count = (int)$wpdb->get_var($stmt);
343
+
344
+ // Body
345
+ if(!empty($query_params)){
346
+ $stmt = $wpdb->prepare($qstr, $query_params);
347
+ } else{
348
+ $stmt = $qstr;
349
+ }
350
+
351
+ $rows = $wpdb->get_results($stmt);
352
+
353
+ $this->filterResults($rows);
354
+
355
+ // Found rows
356
+ // DEPRECATED AS PER NOTES RE: MySQL 8.0.17 -> This now requires a separate count query as seen
357
+ // $found_rows = $wpdb->get_var('SELECT FOUND_ROWS()');
358
+ $filtered_query_params = array();
359
+ $filtered_count_qstr = $this->buildFilteredCountQueryString($input_params, $filtered_query_params);
360
+ if(!empty($filtered_query_params)){
361
+ $stmt = $wpdb->prepare($filtered_count_qstr, $filtered_query_params);
362
+ } else {
363
+ $stmt = $filtered_count_qstr;
364
+ }
365
+
366
+ $found_rows = (int)$wpdb->get_var($stmt);
367
+
368
+ // Meta
369
+ $meta = array();
370
+ foreach($rows as $key => $value){
371
+ $meta[$key] = (array) $value;
372
+ }
373
+
374
+ $result = (object)array(
375
+ 'recordsTotal' => $total_count,
376
+ 'recordsFiltered' => $found_rows,
377
+ 'data' => apply_filters('wpgmza_ajax_table_records', $rows),
378
+ 'meta' => apply_filters('wpgmza_ajax_table_meta', $meta)
379
+ );
380
+
381
+ if($wpgmza->isInDeveloperMode())
382
+ $result->query = $stmt;
383
+
384
+ return $result;
385
+ }
386
+
387
+ public function data($input_params)
388
+ {
389
+ return $this->getRecords($input_params);
390
+ }
391
+ }
js/v8/core.js CHANGED
@@ -1,924 +1,924 @@
1
- /**
2
- * @module WPGMZA
3
- * @summary This is the core Javascript module. Some code exists in ../core.js, the functionality there will slowly be handed over to this module.
4
- */
5
- jQuery(function($) {
6
-
7
- var core = {
8
- MARKER_PULL_DATABASE: "0",
9
- MARKER_PULL_XML: "1",
10
-
11
- PAGE_MAP_LIST: "map-list",
12
- PAGE_MAP_EDIT: "map-edit",
13
- PAGE_SETTINGS: "map-settings",
14
- PAGE_SUPPORT: "map-support",
15
-
16
- PAGE_CATEGORIES: "categories",
17
- PAGE_ADVANCED: "advanced",
18
- PAGE_CUSTOM_FIELDS: "custom-fields",
19
-
20
- /**
21
- * Indexed array of map instances
22
- * @constant {array} maps
23
- * @static
24
- */
25
- maps: [],
26
-
27
- /**
28
- * Global EventDispatcher used to listen for global plugin events
29
- * @constant {EventDispatcher} events
30
- * @static
31
- */
32
- events: null,
33
-
34
- /**
35
- * Settings, passed from the server
36
- * @constant {object} settings
37
- * @static
38
- */
39
- settings: null,
40
-
41
- /**
42
- * Instance of the restAPI. Not to be confused with WPGMZA.RestAPI, which is the instances constructor
43
- * @constant {RestAPI} restAPI
44
- * @static
45
- */
46
- restAPI: null,
47
-
48
- /**
49
- * Key and value pairs of localized strings passed from the server
50
- * @constant {object} localized_strings
51
- * @static
52
- */
53
- localized_strings: null,
54
-
55
- // NB: Legacy
56
- loadingHTML: '<div class="wpgmza-preloader"><div class="wpgmza-loader">...</div></div>',
57
-
58
- // NB: Correct
59
- preloaderHTML: "<div class='wpgmza-preloader'><div></div><div></div><div></div><div></div></div>",
60
-
61
- getCurrentPage: function() {
62
-
63
- switch(WPGMZA.getQueryParamValue("page"))
64
- {
65
- case "wp-google-maps-menu":
66
- if(window.location.href.match(/action=edit/) && window.location.href.match(/map_id=\d+/))
67
- return WPGMZA.PAGE_MAP_EDIT;
68
-
69
- return WPGMZA.PAGE_MAP_LIST;
70
- break;
71
-
72
- case 'wp-google-maps-menu-settings':
73
- return WPGMZA.PAGE_SETTINGS;
74
- break;
75
-
76
- case 'wp-google-maps-menu-support':
77
- return WPGMZA.PAGE_SUPPORT;
78
- break;
79
-
80
- case 'wp-google-maps-menu-categories':
81
- return WPGMZA.PAGE_CATEGORIES;
82
- break;
83
-
84
- case 'wp-google-maps-menu-advanced':
85
- return WPGMZA.PAGE_ADVANCED;
86
- break;
87
-
88
- case 'wp-google-maps-menu-custom-fields':
89
- return WPGMZA.PAGE_CUSTOM_FIELDS;
90
- break;
91
-
92
- default:
93
- return null;
94
- break;
95
- }
96
-
97
- },
98
-
99
- /**
100
- * Override this method to add a scroll offset when using animated scroll, useful for sites with fixed headers.
101
- * @method getScrollAnimationOffset
102
- * @static
103
- * @return {number} The scroll offset
104
- */
105
- getScrollAnimationOffset: function() {
106
- return (WPGMZA.settings.scroll_animation_offset || 0) + ($("#wpadminbar").height() || 0);
107
- },
108
-
109
- getScrollAnimationDuration: function() {
110
- if(WPGMZA.settings.scroll_animation_milliseconds)
111
- return WPGMZA.settings.scroll_animation_milliseconds;
112
- else
113
- return 500;
114
- },
115
-
116
- /**
117
- * Animated scroll, accounts for animation settings and fixed header height
118
- * @method animateScroll
119
- * @static
120
- * @param {HTMLElement} element The element to scroll to
121
- * @param {number} [milliseconds] The time in milliseconds to scroll over. Defaults to 500 if no value is specified.
122
- * @return void
123
- */
124
- animateScroll: function(element, milliseconds) {
125
-
126
- var offset = WPGMZA.getScrollAnimationOffset();
127
-
128
- if(!milliseconds)
129
- milliseconds = WPGMZA.getScrollAnimationDuration();
130
-
131
- $("html, body").animate({
132
- scrollTop: $(element).offset().top - offset
133
- }, milliseconds);
134
-
135
- },
136
-
137
- extend: function(child, parent) {
138
-
139
- var constructor = child;
140
-
141
- child.prototype = Object.create(parent.prototype);
142
- child.prototype.constructor = constructor;
143
-
144
- },
145
-
146
- /**
147
- * Generates and returns a GUID
148
- * @method guid
149
- * @static
150
- * @return {string} The GUID
151
- */
152
- guid: function() { // Public Domain/MIT
153
- var d = new Date().getTime();
154
- if (typeof performance !== 'undefined' && typeof performance.now === 'function'){
155
- d += performance.now(); //use high-precision timer if available
156
- }
157
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
158
- var r = (d + Math.random() * 16) % 16 | 0;
159
- d = Math.floor(d / 16);
160
- return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
161
- });
162
- },
163
-
164
- /**
165
- * Takes a hex string and opacity value and converts it to Openlayers RGBA format
166
- * @method hexOpacityToRGBA
167
- * @static
168
- * @param {string} colour The hex color string
169
- * @param {number} opacity The opacity from 0.0 - 1.0
170
- * @return {array} RGBA array where color components are 0 - 255 and opacity is 0.0 - 1.0
171
- */
172
- hexOpacityToRGBA: function(colour, opacity)
173
- {
174
- var hex = parseInt(colour.replace(/^#/, ""), 16);
175
- return [
176
- (hex & 0xFF0000) >> 16,
177
- (hex & 0xFF00) >> 8,
178
- hex & 0xFF,
179
- parseFloat(opacity)
180
- ];
181
- },
182
-
183
- hexOpacityToString: function(colour, opacity)
184
- {
185
- var arr = WPGMZA.hexOpacityToRGBA(colour, opacity);
186
- return "rgba(" + arr[0] + ", " + arr[1] + ", " + arr[2] + ", " + arr[3] + ")";
187
- },
188
-
189
- /**
190
- * Takes a hex color string and converts it to an RGBA object.
191
- * @method hexToRgba
192
- * @static
193
- * @param {string} hex The hex color string
194
- * @return {object} Object with r, g, b and a properties, or 0 if the input is invalid.
195
- */
196
- hexToRgba: function(hex) {
197
- var c;
198
- if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
199
- c= hex.substring(1).split('');
200
- if(c.length== 3){
201
- c= [c[0], c[0], c[1], c[1], c[2], c[2]];
202
- }
203
- c= '0x'+c.join('');
204
-
205
- return {
206
- r: (c>>16)&255,
207
- g: (c>>8)&255,
208
- b: c&255,
209
- a: 1
210
- };
211
- }
212
-
213
- return 0;
214
-
215
- //throw new Error('Bad Hex');
216
- },
217
-
218
- /**
219
- * Takes an object with r, g, b and a properties and returns a CSS rgba color string
220
- * @method rgbaToString
221
- * @static
222
- * @param {string} rgba The input object
223
- * @return {string} The CSS rgba color string
224
- */
225
- rgbaToString: function(rgba) {
226
- return "rgba(" + rgba.r + ", " + rgba.g + ", " + rgba.b + ", " + rgba.a + ")";
227
- },
228
-
229
- /**
230
- * A regular expression that matches a latitude / longitude coordinate pair
231
- * @constant {RegExp} latLngRegexp
232
- * @static
233
- */
234
- latLngRegexp: /^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$/,
235
-
236
- /**
237
- * Utility function returns true is string is a latitude and longitude
238
- * @method isLatLngString
239
- * @deprecated Moved to WPGMZA.LatLng.isLatLngString
240
- * @static
241
- * @param str {string} The string to attempt to parse as coordinates
242
- * @return {array} the matched latitude and longitude or null if no match
243
- */
244
- isLatLngString: function(str)
245
- {
246
- if(typeof str != "string")
247
- return null;
248
-
249
- // Remove outer brackets
250
- if(str.match(/^\(.+\)$/))
251
- str = str.replace(/^\(|\)$/, "");
252
-
253
- var m = str.match(WPGMZA.latLngRegexp);
254
-
255
- if(!m)
256
- return null;
257
-
258
- return new WPGMZA.LatLng({
259
- lat: parseFloat(m[1]),
260
- lng: parseFloat(m[3])
261
- });
262
- },
263
-
264
- /**
265
- * Utility function returns a latLng literal given a valid latLng string
266
- * @method stringToLatLng
267
- * @static
268
- * @param str {string} The string to attempt to parse as coordinates
269
- * @return {object} LatLng literal
270
- */
271
- stringToLatLng: function(str)
272
- {
273
- var result = WPGMZA.isLatLngString(str);
274
-
275
- if(!result)
276
- throw new Error("Not a valid latLng");
277
-
278
- return result;
279
- },
280
-
281
- /**
282
- * Utility function returns a latLng literal given a valid latLng string
283
- * @method stringToLatLng
284
- * @static
285
- * @param str {string} The string to attempt to parse as coordinates
286
- * @return {object} LatLng literal
287
- */
288
- isHexColorString: function(str)
289
- {
290
- if(typeof str != "string")
291
- return false;
292
-
293
- return (str.match(/#[0-9A-F]{6}/i) ? true : false);
294
- },
295
-
296
- /**
297
- * Cache of image dimensions by URL, for internal use only
298
- * @var imageDimensionsCache
299
- * @inner
300
- * @see WPGMZA.getImageDimensions
301
- */
302
- imageDimensionsCache: {},
303
-
304
- /**
305
- * Utility function to get the dimensions of an image, caches results for best performance
306
- * @method getImageDimensions
307
- * @static
308
- * @param src {string} Image source URL
309
- * @param callback {function} Callback to recieve image dimensions
310
- * @return {void}
311
- */
312
- getImageDimensions: function(src, callback)
313
- {
314
- if(WPGMZA.imageDimensionsCache[src])
315
- {
316
- callback(WPGMZA.imageDimensionsCache[src]);
317
- return;
318
- }
319
-
320
- var img = document.createElement("img");
321
- img.onload = function(event) {
322
- var result = {
323
- width: img.width,
324
- height: img.height
325
- };
326
- WPGMZA.imageDimensionsCache[src] = result;
327
- callback(result);
328
- };
329
- img.src = src;
330
- },
331
-
332
- decodeEntities: function(input)
333
- {
334
- return input.replace(/&(nbsp|amp|quot|lt|gt);/g, function(m, e) {
335
- return m[e];
336
- }).replace(/&#(\d+);/gi, function(m, e) {
337
- return String.fromCharCode(parseInt(e, 10));
338
- });
339
- },
340
-
341
- /**
342
- * Returns true if developer mode is set or if developer mode cookie is set
343
- * @method isDeveloperMode
344
- * @static
345
- * @return {boolean} True if developer mode is on
346
- */
347
- isDeveloperMode: function()
348
- {
349
- return this.settings.developer_mode || (window.Cookies && window.Cookies.get("wpgmza-developer-mode"));
350
- },
351
-
352
- /**
353
- * Returns true if the Pro add-on is active
354
- * @method isProVersion
355
- * @static
356
- * @return {boolean} True if the Pro add-on is active
357
- */
358
- isProVersion: function()
359
- {
360
- return (this._isProVersion == "1");
361
- },
362
-
363
- /**
364
- * Opens the WP media dialog and returns the result to a callback
365
- * @method openMediaDialog
366
- * @param {function} callback Callback to recieve the attachment ID as the first parameter and URL as the second
367
- * @static
368
- * @return {void}
369
- */
370
- openMediaDialog: function(callback) {
371
- // Media upload
372
- var file_frame;
373
-
374
- // If the media frame already exists, reopen it.
375
- if ( file_frame ) {
376
- // Set the post ID to what we want
377
- file_frame.uploader.uploader.param( 'post_id', set_to_post_id );
378
- // Open frame
379
- file_frame.open();
380
- return;
381
- }
382
-
383
- // Create the media frame.
384
- file_frame = wp.media.frames.file_frame = wp.media({
385
- title: 'Select a image to upload',
386
- button: {
387
- text: 'Use this image',
388
- },
389
- multiple: false // Set to true to allow multiple files to be selected
390
- });
391
-
392
- // When an image is selected, run a callback.
393
- file_frame.on( 'select', function() {
394
- // We set multiple to false so only get one image from the uploader
395
- attachment = file_frame.state().get('selection').first().toJSON();
396
-
397
- callback(attachment.id, attachment.url);
398
- });
399
-
400
- // Finally, open the modal
401
- file_frame.open();
402
- },
403
-
404
- /**
405
- * @function getCurrentPosition
406
- * @summary This function will get the users position, it first attempts to get
407
- * high accuracy position (mobile with GPS sensors etc.), if that fails
408
- * (desktops will time out) then it tries again without high accuracy
409
- * enabled
410
- * @static
411
- * @return {object} The users position as a LatLng literal
412
- */
413
- getCurrentPosition: function(callback, error, watch)
414
- {
415
- var trigger = "userlocationfound";
416
- var nativeFunction = "getCurrentPosition";
417
-
418
- if(WPGMZA.userLocationDenied)
419
- {
420
- // NB: This code can also be reached on non https:// sites, the error code is the same
421
- if(error)
422
- error({code: 1, message: "Location unavailable"});
423
-
424
- return; // NB: The user has declined to share location. Only ask once per session.
425
- }
426
-
427
- if(watch)
428
- {
429
- trigger = "userlocationupdated";
430
- nativeFunction = "watchPosition";
431
-
432
- // Call again immediatly to get current position, watchPosition won't fire until the user moves
433
- /*setTimeout(function() {
434
- WPGMZA.getCurrentPosition(callback, false);
435
- }, 0);*/
436
- }
437
-
438
- if(!navigator.geolocation)
439
- {
440
- console.warn("No geolocation available on this device");
441
- return;
442
- }
443
-
444
- var options = {
445
- enableHighAccuracy: true
446
- };
447
-
448
- if(!navigator.geolocation[nativeFunction])
449
- {
450
- console.warn(nativeFunction + " is not available");
451
- return;
452
- }
453
-
454
- navigator.geolocation[nativeFunction](function(position) {
455
- if(callback)
456
- callback(position);
457
-
458
- WPGMZA.events.trigger("userlocationfound");
459
- },
460
- function(err) {
461
-
462
- options.enableHighAccuracy = false;
463
-
464
- navigator.geolocation[nativeFunction](function(position) {
465
- if(callback)
466
- callback(position);
467
-
468
- WPGMZA.events.trigger("userlocationfound");
469
- },
470
- function(err) {
471
- console.warn(err.code, err.message);
472
-
473
- if(err.code == 1)
474
- WPGMZA.userLocationDenied = true;
475
-
476
- if(error)
477
- error(err);
478
- },
479
- options);
480
-
481
- },
482
- options);
483
- },
484
-
485
- watchPosition: function(callback, error)
486
- {
487
- return WPGMZA.getCurrentPosition(callback, error, true);
488
- },
489
-
490
- /**
491
- * Runs a catchable task and displays a friendly error if the function throws an error
492
- * @method runCatchableTask
493
- * @static
494
- * @param {function} callback The function to run
495
- * @param {HTMLElement} friendlyErrorContainer The container element to hold the error
496
- * @return {void}
497
- * @see WPGMZA.FriendlyError
498
- */
499
- runCatchableTask: function(callback, friendlyErrorContainer) {
500
-
501
- if(WPGMZA.isDeveloperMode())
502
- callback();
503
- else
504
- try{
505
- callback();
506
- }catch(e) {
507
- var friendlyError = new WPGMZA.FriendlyError(e);
508
- $(friendlyErrorContainer).html("");
509
- $(friendlyErrorContainer).append(friendlyError.element);
510
- $(friendlyErrorContainer).show();
511
- }
512
- },
513
-
514
- capitalizeWords: function(string)
515
- {
516
- return (string + "").replace(/^(.)|\s+(.)/g, function(m) {
517
- return m.toUpperCase()
518
- });
519
- },
520
-
521
- pluralize: function(string)
522
- {
523
- return WPGMZA.singularize(string) + "s";
524
- },
525
-
526
- singularize: function(string)
527
- {
528
- return string.replace(/s$/, "");
529
- },
530
-
531
- /**
532
- * This function is for checking inheritence has been setup correctly. For objects that have engine and Pro specific classes, it will automatically add the engine and pro prefix to the supplied string and if such an object exists it will test against that name rather than the un-prefix argument supplied.
533
- *
534
- * For example, if we are running the Pro addon with Google maps as the engine, if you supply Marker as the instance name the function will check to see if instance is an instance of GoogleProMarker
535
- * @method assertInstanceOf
536
- * @static
537
- * @param {object} instance The object to check
538
- * @param {string} instanceName The class name as a string which this object should be an instance of
539
- * @return {void}
540
- */
541
- assertInstanceOf: function(instance, instanceName) {
542
- var engine, fullInstanceName, assert;
543
- var pro = WPGMZA.isProVersion() ? "Pro" : "";
544
-
545
- switch(WPGMZA.settings.engine)
546
- {
547
- case "open-layers":
548
- engine = "OL";
549
- break;
550
-
551
- default:
552
- engine = "Google";
553
- break;
554
- }
555
-
556
- if(
557
- WPGMZA[engine + pro + instanceName]
558
- &&
559
- engine + instanceName != "OLFeature" // NB: Some classes, such as OLFeature, are static utility classes and cannot be inherited from, do not check the inheritence chain for these
560
- )
561
- fullInstanceName = engine + pro + instanceName;
562
- else if(WPGMZA[pro + instanceName])
563
- fullInstanceName = pro + instanceName;
564
- else if(
565
- WPGMZA[engine + instanceName]
566
- &&
567
- WPGMZA[engine + instanceName].prototype
568
- )
569
- fullInstanceName = engine + instanceName;
570
- else
571
- fullInstanceName = instanceName;
572
-
573
- if(fullInstanceName == "OLFeature")
574
- return; // Nothing inherits from OLFeature - it's purely a "static" utility class
575
-
576
- assert = instance instanceof WPGMZA[fullInstanceName];
577
-
578
- if(!assert)
579
- throw new Error("Object must be an instance of " + fullInstanceName + " (did you call a constructor directly, rather than createInstance?)");
580
- },
581
-
582
- /**
583
- * @method getMapByID
584
- * @static
585
- * @param {mixed} id The ID of the map to retrieve
586
- * @return {object} The map object, or null if no such map exists
587
- */
588
- getMapByID: function(id) {
589
-
590
- for(var i = 0; i < WPGMZA.maps.length; i++) {
591
- if(WPGMZA.maps[i].id == id)
592
- return WPGMZA.maps[i];
593
- }
594
-
595
- return null;
596
-
597
- },
598
-
599
- /**
600
- * Shorthand function to determine if the Places Autocomplete is available
601
- * @method isGoogleAutocompleteSupported
602
- * @static
603
- * @return {boolean} True if the places autocomplete is available
604
- */
605
- isGoogleAutocompleteSupported: function() {
606
-
607
- if(!window.google)
608
- return false;
609
-
610
- if(!google.maps)
611
- return false;
612
-
613
- if(!google.maps.places)
614
- return false;
615
-
616
- if(!google.maps.places.Autocomplete)
617
- return false;
618
-
619
- if(WPGMZA.CloudAPI && WPGMZA.CloudAPI.isBeingUsed)
620
- return false;
621
-
622
- return true;
623
-
624
- },
625
-
626
- /**
627
- * The Google API status script enqueue, as reported by the server
628
- * @constant
629
- * @static
630
- */
631
- googleAPIStatus: window.wpgmza_google_api_status,
632
-
633
- /**
634
- * Makes an educated guess as to whether the browser is Safari
635
- * @method isSafari
636
- * @static
637
- * @return {boolean} True if it's likely the browser is Safari
638
- */
639
- isSafari: function() {
640
-
641
- var ua = navigator.userAgent.toLowerCase();
642
- return (ua.match(/safari/i) && !ua.match(/chrome/i));
643
-
644
- },
645
-
646
- /**
647
- * Makes an educated guess as to whether the browser is running on a touch device
648
- * @method isTouchDevice
649
- * @static
650
- * @return {boolean} True if it's likely the browser is running on a touch device
651
- */
652
- isTouchDevice: function() {
653
-
654
- return ("ontouchstart" in window);
655
-
656
- },
657
-
658
- /**
659
- * Makes an educated guess whether the browser is running on an iOS device
660
- * @method isDeviceiOS
661
- * @static
662
- * @return {boolean} True if it's likely the browser is running on an iOS device
663
- */
664
- isDeviceiOS: function() {
665
-
666
- return (
667
-
668
- (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream)
669
-
670
- ||
671
-
672
- (!!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform))
673
-
674
- );
675
-
676
- },
677
-
678
- /**
679
- * This function prevents modern style components being used with new UI styles (8.0.0)
680
- * @method isModernComponentStyleAllowed
681
- * @static
682
- * @return {boolean} True if modern or legacy style is selected, or no UI style is selected
683
- */
684
- isModernComponentStyleAllowed: function() {
685
-
686
- return (!WPGMZA.settings.user_interface_style || WPGMZA.settings.user_interface_style == "legacy" || WPGMZA.settings.user_interface_style == "modern");
687
-
688
- },
689
-
690
- isElementInView: function(element) {
691
-
692
- var pageTop = $(window).scrollTop();
693
- var pageBottom = pageTop + $(window).height();
694
- var elementTop = $(element).offset().top;
695
- var elementBottom = elementTop + $(element).height();
696
-
697
- if(elementTop < pageTop && elementBottom > pageBottom)
698
- return true;
699
-
700
- if(elementTop >= pageTop && elementTop <= pageBottom)
701
- return true;
702
-
703
- if(elementBottom >= pageTop && elementBottom <= pageBottom)
704
- return true;
705
-
706
- return false;
707
-
708
- },
709
-
710
- isFullScreen: function() {
711
-
712
- return wpgmzaisFullScreen;
713
-
714
- },
715
-
716
- getQueryParamValue: function(name) {
717
-
718
- var regex = new RegExp(name + "=([^&#]*)");
719
- var m;
720
-
721
- if(!(m = window.location.href.match(regex)))
722
- return null;
723
-
724
- return decodeURIComponent(m[1]);
725
- },
726
-
727
- notification: function(text, time) {
728
-
729
- switch(arguments.length)
730
- {
731
- case 0:
732
- text = "";
733
- time = 4000;
734
- break;
735
-
736
- case 1:
737
- time = 4000;
738
- break;
739
- }
740
-
741
- var html = '<div class="wpgmza-popup-notification">' + text + '</div>';
742
- jQuery('body').append(html);
743
- setTimeout(function(){
744
- jQuery('body').find('.wpgmza-popup-notification').remove();
745
- }, time);
746
-
747
- },
748
-
749
- initMaps: function(){
750
- $(document.body).find(".wpgmza_map:not(.wpgmza-initialized)").each(function(index, el) {
751
- if(el.wpgmzaMap) {
752
- console.warn("Element missing class wpgmza-initialized but does have wpgmzaMap property. No new instance will be created");
753
- return;
754
- }
755
-
756
- try {
757
- el.wpgmzaMap = WPGMZA.Map.createInstance(el);
758
- } catch (ex){
759
- console.warn('Map initalization: ' + ex);
760
- }
761
- });
762
-
763
- WPGMZA.Map.nextInitTimeoutID = setTimeout(WPGMZA.initMaps, 3000);
764
- },
765
-
766
- onScroll: function(){
767
- $(".wpgmza_map").each(function(index, el) {
768
- var isInView = WPGMZA.isElementInView(el);
769
- if(!el.wpgmzaScrollIntoViewTriggerFlag){
770
- if(isInView){
771
- $(el).trigger("mapscrolledintoview.wpgmza");
772
- el.wpgmzaScrollIntoViewTriggerFlag = true;
773
- }
774
- } else if(!isInView){
775
- el.wpgmzaScrollIntoViewTriggerFlag = false;
776
- }
777
-
778
- });
779
- }
780
-
781
- };
782
-
783
- var wpgmzaisFullScreen = false;
784
-
785
-
786
- // NB: Warn the user if the built in Array prototype has been extended. This will save debugging headaches where for ... in loops do bizarre things.
787
- for(var key in [])
788
- {
789
- console.warn("It appears that the built in JavaScript Array has been extended, this can create issues with for ... in loops, which may cause failure.");
790
- break;
791
- }
792
-
793
- if(window.WPGMZA)
794
- window.WPGMZA = $.extend(window.WPGMZA, core);
795
- else
796
- window.WPGMZA = core;
797
-
798
- /* Usercentrics base level integration */
799
- if(window.uc && window.uc.reloadOnOptIn){
800
- window.uc.reloadOnOptIn(
801
- 'S1pcEj_jZX'
802
- );
803
-
804
- window.uc.reloadOnOptOut(
805
- 'S1pcEj_jZX'
806
- );
807
- }
808
-
809
-
810
- for(var key in WPGMZA_localized_data){
811
- var value = WPGMZA_localized_data[key];
812
- WPGMZA[key] = value;
813
- }
814
-
815
- // delete window.WPGMZA_localized_data;
816
-
817
- WPGMZA.settings.useLegacyGlobals = true;
818
-
819
- $(document).on("fullscreenchange", function() {
820
- wpgmzaisFullScreen = document.fullscreenElement ? true : false;
821
- });
822
-
823
- $('body').on('click',"#wpgmzaCloseChat", function(e) {
824
- e.preventDefault();
825
- $.ajax(WPGMZA.ajaxurl, {
826
- method: 'POST',
827
- data: {
828
- action: 'wpgmza_hide_chat',
829
- nonce: WPGMZA_localized_data.ajaxnonce
830
- }
831
- });
832
- $('.wpgmza-chat-help').remove();
833
- });
834
-
835
-
836
- $(window).on("scroll", WPGMZA.onScroll);
837
-
838
- $(document.body).on("click", "button.wpgmza-api-consent", function(event) {
839
- Cookies.set("wpgmza-api-consent-given", true);
840
- window.location.reload();
841
- });
842
-
843
- $(document.body).on("keydown", function(event) {
844
- if(event.altKey)
845
- WPGMZA.altKeyDown = true;
846
- });
847
-
848
- $(document.body).on("keyup", function(event) {
849
- if(!event.altKey)
850
- WPGMZA.altKeyDown = false;
851
- });
852
-
853
- $(document.body).on('preinit.wpgmza', function(){
854
- $(window).trigger("ready.wpgmza");
855
-
856
- // Combined script warning
857
- if($("script[src*='wp-google-maps.combined.js'], script[src*='wp-google-maps-pro.combined.js']").length){
858
- console.warn("Minified script is out of date, using combined script instead.");
859
- }
860
-
861
- // Check for multiple jQuery versions
862
- var elements = $("script[src]").filter(function() {
863
- return this.src.match(/(^|\/)jquery\.(min\.)?js(\?|$)/i);
864
- });
865
-
866
- if(elements.length > 1){
867
- console.warn("Multiple jQuery versions detected: ", elements);
868
- }
869
-
870
- // Array incorrectly extended warning
871
- var test = [];
872
- for(var key in test) {
873
- console.warn("The Array object has been extended incorrectly by your theme or another plugin. This can cause issues with functionality.");
874
- break;
875
- }
876
-
877
- // Geolocation warnings
878
- if(window.location.protocol != 'https:'){
879
- var warning = '<div class="notice notice-warning"><p>' + WPGMZA.localized_strings.unsecure_geolocation + "</p></div>";
880
-
881
- $(".wpgmza-geolocation-setting").first().after( $(warning) );
882
- }
883
-
884
- if(WPGMZA.googleAPIStatus && WPGMZA.googleAPIStatus.code == "USER_CONSENT_NOT_GIVEN") {
885
- if(jQuery('.wpgmza-gdpr-compliance').length <= 0){
886
- /*$("#wpgmza_map, .wpgmza_map").each(function(index, el) {
887
- $(el).append($(WPGMZA.api_consent_html));
888
- $(el).css({height: "auto"});
889
- });*/
890
-
891
- $("button.wpgmza-api-consent").on("click", function(event) {
892
- Cookies.set("wpgmza-api-consent-given", true);
893
- window.location.reload();
894
- });
895
- }
896
-
897
- return;
898
- }
899
- });
900
-
901
- /**
902
- * We use to use the win-the-race approach with set timeouts
903
- *
904
- * This caused immense issues with older versions of WP
905
- *
906
- * Instead, we call an anon-func, which queues on the ready call, this controls the queue without the need for timeouts
907
- *
908
- * While also maintaining the stack order, and the ability for consent plugins to stop ready calls early
909
- */
910
- (function($){
911
- $(function(){
912
- WPGMZA.restAPI = WPGMZA.RestAPI.createInstance();
913
- if(WPGMZA.CloudAPI){
914
- WPGMZA.cloudAPI = WPGMZA.CloudAPI.createInstance();
915
- }
916
-
917
- $(document.body).trigger('preinit.wpgmza');
918
-
919
- WPGMZA.initMaps();
920
- WPGMZA.onScroll();
921
- });
922
- })($);
923
-
924
- });
1
+ /**
2
+ * @module WPGMZA
3
+ * @summary This is the core Javascript module. Some code exists in ../core.js, the functionality there will slowly be handed over to this module.
4
+ */
5
+ jQuery(function($) {
6
+
7
+ var core = {
8
+ MARKER_PULL_DATABASE: "0",
9
+ MARKER_PULL_XML: "1",
10
+
11
+ PAGE_MAP_LIST: "map-list",
12
+ PAGE_MAP_EDIT: "map-edit",
13
+ PAGE_SETTINGS: "map-settings",
14
+ PAGE_SUPPORT: "map-support",
15
+
16
+ PAGE_CATEGORIES: "categories",
17
+ PAGE_ADVANCED: "advanced",
18
+ PAGE_CUSTOM_FIELDS: "custom-fields",
19
+
20
+ /**
21
+ * Indexed array of map instances
22
+ * @constant {array} maps
23
+ * @static
24
+ */
25
+ maps: [],
26
+
27
+ /**
28
+ * Global EventDispatcher used to listen for global plugin events
29
+ * @constant {EventDispatcher} events
30
+ * @static
31
+ */
32
+ events: null,
33
+
34
+ /**
35
+ * Settings, passed from the server
36
+ * @constant {object} settings
37
+ * @static
38
+ */
39
+ settings: null,
40
+
41
+ /**
42
+ * Instance of the restAPI. Not to be confused with WPGMZA.RestAPI, which is the instances constructor
43
+ * @constant {RestAPI} restAPI
44
+ * @static
45
+ */
46
+ restAPI: null,
47
+
48
+ /**
49
+ * Key and value pairs of localized strings passed from the server
50
+ * @constant {object} localized_strings
51
+ * @static
52
+ */
53
+ localized_strings: null,
54
+
55
+ // NB: Legacy
56
+ loadingHTML: '<div class="wpgmza-preloader"><div class="wpgmza-loader">...</div></div>',
57
+
58
+ // NB: Correct
59
+ preloaderHTML: "<div class='wpgmza-preloader'><div></div><div></div><div></div><div></div></div>",
60
+
61
+ getCurrentPage: function() {
62
+
63
+ switch(WPGMZA.getQueryParamValue("page"))
64
+ {
65
+ case "wp-google-maps-menu":
66
+ if(window.location.href.match(/action=edit/) && window.location.href.match(/map_id=\d+/))
67
+ return WPGMZA.PAGE_MAP_EDIT;
68
+
69
+ return WPGMZA.PAGE_MAP_LIST;
70
+ break;
71
+
72
+ case 'wp-google-maps-menu-settings':
73
+ return WPGMZA.PAGE_SETTINGS;
74
+ break;
75
+
76
+ case 'wp-google-maps-menu-support':
77
+ return WPGMZA.PAGE_SUPPORT;
78
+ break;
79
+
80
+ case 'wp-google-maps-menu-categories':
81
+ return WPGMZA.PAGE_CATEGORIES;
82
+ break;
83
+
84
+ case 'wp-google-maps-menu-advanced':
85
+ return WPGMZA.PAGE_ADVANCED;
86
+ break;
87
+
88
+ case 'wp-google-maps-menu-custom-fields':
89
+ return WPGMZA.PAGE_CUSTOM_FIELDS;
90
+ break;
91
+
92
+ default:
93
+ return null;
94
+ break;
95
+ }
96
+
97
+ },
98
+
99
+ /**
100
+ * Override this method to add a scroll offset when using animated scroll, useful for sites with fixed headers.
101
+ * @method getScrollAnimationOffset
102
+ * @static
103
+ * @return {number} The scroll offset
104
+ */
105
+ getScrollAnimationOffset: function() {
106
+ return (WPGMZA.settings.scroll_animation_offset || 0) + ($("#wpadminbar").height() || 0);
107
+ },
108
+
109
+ getScrollAnimationDuration: function() {
110
+ if(WPGMZA.settings.scroll_animation_milliseconds)
111
+ return WPGMZA.settings.scroll_animation_milliseconds;
112
+ else
113
+ return 500;
114
+ },
115
+
116
+ /**
117
+ * Animated scroll, accounts for animation settings and fixed header height
118
+ * @method animateScroll
119
+ * @static
120
+ * @param {HTMLElement} element The element to scroll to
121
+ * @param {number} [milliseconds] The time in milliseconds to scroll over. Defaults to 500 if no value is specified.
122
+ * @return void
123
+ */
124
+ animateScroll: function(element, milliseconds) {
125
+
126
+ var offset = WPGMZA.getScrollAnimationOffset();
127
+
128
+ if(!milliseconds)
129
+ milliseconds = WPGMZA.getScrollAnimationDuration();
130
+
131
+ $("html, body").animate({
132
+ scrollTop: $(element).offset().top - offset
133
+ }, milliseconds);
134
+
135
+ },
136
+
137
+ extend: function(child, parent) {
138
+
139
+ var constructor = child;
140
+
141
+ child.prototype = Object.create(parent.prototype);
142
+ child.prototype.constructor = constructor;
143
+
144
+ },
145
+
146
+ /**
147
+ * Generates and returns a GUID
148
+ * @method guid
149
+ * @static
150
+ * @return {string} The GUID
151
+ */
152
+ guid: function() { // Public Domain/MIT
153
+ var d = new Date().getTime();
154
+ if (typeof performance !== 'undefined' && typeof performance.now === 'function'){
155
+ d += performance.now(); //use high-precision timer if available
156
+ }
157
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
158
+ var r = (d + Math.random() * 16) % 16 | 0;
159
+ d = Math.floor(d / 16);
160
+ return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
161
+ });
162
+ },
163
+
164
+ /**
165
+ * Takes a hex string and opacity value and converts it to Openlayers RGBA format
166
+ * @method hexOpacityToRGBA
167
+ * @static
168
+ * @param {string} colour The hex color string
169
+ * @param {number} opacity The opacity from 0.0 - 1.0
170
+ * @return {array} RGBA array where color components are 0 - 255 and opacity is 0.0 - 1.0
171
+ */
172
+ hexOpacityToRGBA: function(colour, opacity)
173
+ {
174
+ var hex = parseInt(colour.replace(/^#/, ""), 16);
175
+ return [
176
+ (hex & 0xFF0000) >> 16,
177
+ (hex & 0xFF00) >> 8,
178
+ hex & 0xFF,
179
+ parseFloat(opacity)
180
+ ];
181
+ },
182
+
183
+ hexOpacityToString: function(colour, opacity)
184
+ {
185
+ var arr = WPGMZA.hexOpacityToRGBA(colour, opacity);
186
+ return "rgba(" + arr[0] + ", " + arr[1] + ", " + arr[2] + ", " + arr[3] + ")";
187
+ },
188
+
189
+ /**
190
+ * Takes a hex color string and converts it to an RGBA object.
191
+ * @method hexToRgba
192
+ * @static
193
+ * @param {string} hex The hex color string
194
+ * @return {object} Object with r, g, b and a properties, or 0 if the input is invalid.
195
+ */
196
+ hexToRgba: function(hex) {
197
+ var c;
198
+ if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
199
+ c= hex.substring(1).split('');
200
+ if(c.length== 3){
201
+ c= [c[0], c[0], c[1], c[1], c[2], c[2]];
202
+ }
203
+ c= '0x'+c.join('');
204
+
205
+ return {
206
+ r: (c>>16)&255,
207
+ g: (c>>8)&255,
208
+ b: c&255,
209
+ a: 1
210
+ };
211
+ }
212
+
213
+ return 0;
214
+
215
+ //throw new Error('Bad Hex');
216
+ },
217
+
218
+ /**
219
+ * Takes an object with r, g, b and a properties and returns a CSS rgba color string
220
+ * @method rgbaToString
221
+ * @static
222
+ * @param {string} rgba The input object
223
+ * @return {string} The CSS rgba color string
224
+ */
225
+ rgbaToString: function(rgba) {
226
+ return "rgba(" + rgba.r + ", " + rgba.g + ", " + rgba.b + ", " + rgba.a + ")";
227
+ },
228
+
229
+ /**
230
+ * A regular expression that matches a latitude / longitude coordinate pair
231
+ * @constant {RegExp} latLngRegexp
232
+ * @static
233
+ */
234
+ latLngRegexp: /^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$/,
235
+
236
+ /**
237
+ * Utility function returns true is string is a latitude and longitude
238
+ * @method isLatLngString
239
+ * @deprecated Moved to WPGMZA.LatLng.isLatLngString
240
+ * @static
241
+ * @param str {string} The string to attempt to parse as coordinates
242
+ * @return {array} the matched latitude and longitude or null if no match
243
+ */
244
+ isLatLngString: function(str)
245
+ {
246
+ if(typeof str != "string")
247
+ return null;
248
+
249
+ // Remove outer brackets
250
+ if(str.match(/^\(.+\)$/))
251
+ str = str.replace(/^\(|\)$/, "");
252
+
253
+ var m = str.match(WPGMZA.latLngRegexp);
254
+
255
+ if(!m)
256
+ return null;
257
+
258
+ return new WPGMZA.LatLng({
259
+ lat: parseFloat(m[1]),
260
+ lng: parseFloat(m[3])
261
+ });
262
+ },
263
+
264
+ /**
265
+ * Utility function returns a latLng literal given a valid latLng string
266
+ * @method stringToLatLng
267
+ * @static
268
+ * @param str {string} The string to attempt to parse as coordinates
269
+ * @return {object} LatLng literal
270
+ */
271
+ stringToLatLng: function(str)
272
+ {
273
+ var result = WPGMZA.isLatLngString(str);
274
+
275
+ if(!result)
276
+ throw new Error("Not a valid latLng");
277
+
278
+ return result;
279
+ },
280
+
281
+ /**
282
+ * Utility function returns a latLng literal given a valid latLng string
283
+ * @method stringToLatLng
284
+ * @static
285
+ * @param str {string} The string to attempt to parse as coordinates
286
+ * @return {object} LatLng literal
287
+ */
288
+ isHexColorString: function(str)
289
+ {
290
+ if(typeof str != "string")
291
+ return false;
292
+
293
+ return (str.match(/#[0-9A-F]{6}/i) ? true : false);
294
+ },
295
+
296
+ /**
297
+ * Cache of image dimensions by URL, for internal use only
298
+ * @var imageDimensionsCache
299
+ * @inner
300
+ * @see WPGMZA.getImageDimensions
301
+ */
302
+ imageDimensionsCache: {},
303
+
304
+ /**
305
+ * Utility function to get the dimensions of an image, caches results for best performance
306
+ * @method getImageDimensions
307
+ * @static
308
+ * @param src {string} Image source URL
309
+ * @param callback {function} Callback to recieve image dimensions
310
+ * @return {void}
311
+ */
312
+ getImageDimensions: function(src, callback)
313
+ {
314
+ if(WPGMZA.imageDimensionsCache[src])
315
+ {
316
+ callback(WPGMZA.imageDimensionsCache[src]);
317
+ return;
318
+ }
319
+
320
+ var img = document.createElement("img");
321
+ img.onload = function(event) {
322
+ var result = {
323
+ width: img.width,
324
+ height: img.height
325
+ };
326
+ WPGMZA.imageDimensionsCache[src] = result;
327
+ callback(result);
328
+ };
329
+ img.src = src;
330
+ },
331
+
332
+ decodeEntities: function(input)
333
+ {
334
+ return input.replace(/&(nbsp|amp|quot|lt|gt);/g, function(m, e) {
335
+ return m[e];
336
+ }).replace(/&#(\d+);/gi, function(m, e) {
337
+ return String.fromCharCode(parseInt(e, 10));
338
+ });
339
+ },
340
+
341
+ /**
342
+ * Returns true if developer mode is set or if developer mode cookie is set
343
+ * @method isDeveloperMode
344
+ * @static
345
+ * @return {boolean} True if developer mode is on
346
+ */
347
+ isDeveloperMode: function()
348
+ {
349
+ return this.settings.developer_mode || (window.Cookies && window.Cookies.get("wpgmza-developer-mode"));
350
+ },
351
+
352
+ /**
353
+ * Returns true if the Pro add-on is active
354
+ * @method isProVersion
355
+ * @static
356
+ * @return {boolean} True if the Pro add-on is active
357
+ */
358
+ isProVersion: function()
359
+ {
360
+ return (this._isProVersion == "1");
361
+ },
362
+
363
+ /**
364
+ * Opens the WP media dialog and returns the result to a callback
365
+ * @method openMediaDialog
366
+ * @param {function} callback Callback to recieve the attachment ID as the first parameter and URL as the second
367
+ * @static
368
+ * @return {void}
369
+ */
370
+ openMediaDialog: function(callback) {
371
+ // Media upload
372
+ var file_frame;
373
+
374
+ // If the media frame already exists, reopen it.
375
+ if ( file_frame ) {
376
+ // Set the post ID to what we want
377
+ file_frame.uploader.uploader.param( 'post_id', set_to_post_id );
378
+ // Open frame
379
+ file_frame.open();
380
+ return;
381
+ }
382
+
383
+ // Create the media frame.
384
+ file_frame = wp.media.frames.file_frame = wp.media({
385
+ title: 'Select a image to upload',
386
+ button: {
387
+ text: 'Use this image',
388
+ },
389
+ multiple: false // Set to true to allow multiple files to be selected
390
+ });
391
+
392
+ // When an image is selected, run a callback.
393
+ file_frame.on( 'select', function() {
394
+ // We set multiple to false so only get one image from the uploader
395
+ attachment = file_frame.state().get('selection').first().toJSON();
396
+
397
+ callback(attachment.id, attachment.url);
398
+ });
399
+
400
+ // Finally, open the modal
401
+ file_frame.open();
402
+ },
403
+
404
+ /**
405
+ * @function getCurrentPosition
406
+ * @summary This function will get the users position, it first attempts to get
407
+ * high accuracy position (mobile with GPS sensors etc.), if that fails
408
+ * (desktops will time out) then it tries again without high accuracy
409
+ * enabled
410
+ * @static
411
+ * @return {object} The users position as a LatLng literal
412
+ */
413
+ getCurrentPosition: function(callback, error, watch)
414
+ {
415
+ var trigger = "userlocationfound";
416
+ var nativeFunction = "getCurrentPosition";
417
+
418
+ if(WPGMZA.userLocationDenied)
419
+ {
420
+ // NB: This code can also be reached on non https:// sites, the error code is the same
421
+ if(error)
422
+ error({code: 1, message: "Location unavailable"});
423
+
424
+ return; // NB: The user has declined to share location. Only ask once per session.
425
+ }
426
+
427
+ if(watch)
428
+ {
429
+ trigger = "userlocationupdated";
430
+ nativeFunction = "watchPosition";
431
+
432
+ // Call again immediatly to get current position, watchPosition won't fire until the user moves
433
+ /*setTimeout(function() {
434
+ WPGMZA.getCurrentPosition(callback, false);
435
+ }, 0);*/
436
+ }
437
+
438
+ if(!navigator.geolocation)
439
+ {
440
+ console.warn("No geolocation available on this device");
441
+ return;
442
+ }
443
+
444
+ var options = {
445
+ enableHighAccuracy: true
446
+ };
447
+
448
+ if(!navigator.geolocation[nativeFunction])
449
+ {
450
+ console.warn(nativeFunction + " is not available");
451
+ return;
452
+ }
453
+
454
+ navigator.geolocation[nativeFunction](function(position) {
455
+ if(callback)
456
+ callback(position);
457
+
458
+ WPGMZA.events.trigger("userlocationfound");
459
+ },
460
+ function(err) {
461
+
462
+ options.enableHighAccuracy = false;
463
+
464
+ navigator.geolocation[nativeFunction](function(position) {
465
+ if(callback)
466
+ callback(position);
467
+
468
+ WPGMZA.events.trigger("userlocationfound");
469
+ },
470
+ function(err) {
471
+ console.warn(err.code, err.message);
472
+
473
+ if(err.code == 1)
474
+ WPGMZA.userLocationDenied = true;
475
+
476
+ if(error)
477
+ error(err);
478
+ },
479
+ options);
480
+
481
+ },
482
+ options);
483
+ },
484
+
485
+ watchPosition: function(callback, error)
486
+ {
487
+ return WPGMZA.getCurrentPosition(callback, error, true);
488
+ },
489
+
490
+ /**
491
+ * Runs a catchable task and displays a friendly error if the function throws an error
492
+ * @method runCatchableTask
493
+ * @static
494
+ * @param {function} callback The function to run
495
+ * @param {HTMLElement} friendlyErrorContainer The container element to hold the error
496
+ * @return {void}
497
+ * @see WPGMZA.FriendlyError
498
+ */
499
+ runCatchableTask: function(callback, friendlyErrorContainer) {
500
+
501
+ if(WPGMZA.isDeveloperMode())
502
+ callback();
503
+ else
504
+ try{
505
+ callback();
506
+ }catch(e) {
507
+ var friendlyError = new WPGMZA.FriendlyError(e);
508
+ $(friendlyErrorContainer).html("");
509
+ $(friendlyErrorContainer).append(friendlyError.element);
510
+ $(friendlyErrorContainer).show();
511
+ }
512
+ },
513
+
514
+ capitalizeWords: function(string)
515
+ {
516
+ return (string + "").replace(/^(.)|\s+(.)/g, function(m) {
517
+ return m.toUpperCase()
518
+ });
519
+ },
520
+
521
+ pluralize: function(string)
522
+ {
523
+ return WPGMZA.singularize(string) + "s";
524
+ },
525
+
526
+ singularize: function(string)
527
+ {
528
+ return string.replace(/s$/, "");
529
+ },
530
+
531
+ /**
532
+ * This function is for checking inheritence has been setup correctly. For objects that have engine and Pro specific classes, it will automatically add the engine and pro prefix to the supplied string and if such an object exists it will test against that name rather than the un-prefix argument supplied.
533
+ *
534
+ * For example, if we are running the Pro addon with Google maps as the engine, if you supply Marker as the instance name the function will check to see if instance is an instance of GoogleProMarker
535
+ * @method assertInstanceOf
536
+ * @static
537
+ * @param {object} instance The object to check
538
+ * @param {string} instanceName The class name as a string which this object should be an instance of
539
+ * @return {void}
540
+ */
541
+ assertInstanceOf: function(instance, instanceName) {
542
+ var engine, fullInstanceName, assert;
543
+ var pro = WPGMZA.isProVersion() ? "Pro" : "";
544
+
545
+ switch(WPGMZA.settings.engine)
546
+ {
547
+ case "open-layers":
548
+ engine = "OL";
549
+ break;
550
+
551
+ default:
552
+ engine = "Google";
553
+ break;
554
+ }
555
+
556
+ if(
557
+ WPGMZA[engine + pro + instanceName]
558
+ &&
559
+ engine + instanceName != "OLFeature" // NB: Some classes, such as OLFeature, are static utility classes and cannot be inherited from, do not check the inheritence chain for these
560
+ )
561
+ fullInstanceName = engine + pro + instanceName;
562
+ else if(WPGMZA[pro + instanceName])
563
+ fullInstanceName = pro + instanceName;
564
+ else if(
565
+ WPGMZA[engine + instanceName]
566
+ &&
567
+ WPGMZA[engine + instanceName].prototype
568
+ )
569
+ fullInstanceName = engine + instanceName;
570
+ else
571
+ fullInstanceName = instanceName;
572
+
573
+ if(fullInstanceName == "OLFeature")
574
+ return; // Nothing inherits from OLFeature - it's purely a "static" utility class
575
+
576
+ assert = instance instanceof WPGMZA[fullInstanceName];
577
+
578
+ if(!assert)
579
+ throw new Error("Object must be an instance of " + fullInstanceName + " (did you call a constructor directly, rather than createInstance?)");
580
+ },
581
+
582
+ /**
583
+ * @method getMapByID
584
+ * @static
585
+ * @param {mixed} id The ID of the map to retrieve
586
+ * @return {object} The map object, or null if no such map exists
587
+ */
588
+ getMapByID: function(id) {
589
+
590
+ for(var i = 0; i < WPGMZA.maps.length; i++) {
591
+ if(WPGMZA.maps[i].id == id)
592
+ return WPGMZA.maps[i];
593
+ }
594
+
595
+ return null;
596
+
597
+ },
598
+
599
+ /**
600
+ * Shorthand function to determine if the Places Autocomplete is available
601
+ * @method isGoogleAutocompleteSupported
602
+ * @static
603
+ * @return {boolean} True if the places autocomplete is available
604
+ */
605
+ isGoogleAutocompleteSupported: function() {
606
+
607
+ if(!window.google)
608
+ return false;
609
+
610
+ if(!google.maps)
611
+ return false;
612
+
613
+ if(!google.maps.places)
614
+ return false;
615
+
616
+ if(!google.maps.places.Autocomplete)
617
+ return false;
618
+
619
+ if(WPGMZA.CloudAPI && WPGMZA.CloudAPI.isBeingUsed)
620
+ return false;
621
+
622
+ return true;
623
+
624
+ },
625
+
626
+ /**
627
+ * The Google API status script enqueue, as reported by the server
628
+ * @constant
629
+ * @static
630
+ */
631
+ googleAPIStatus: window.wpgmza_google_api_status,
632
+
633
+ /**
634
+ * Makes an educated guess as to whether the browser is Safari
635
+ * @method isSafari
636
+ * @static
637
+ * @return {boolean} True if it's likely the browser is Safari
638
+ */
639
+ isSafari: function() {
640
+
641
+ var ua = navigator.userAgent.toLowerCase();
642
+ return (ua.match(/safari/i) && !ua.match(/chrome/i));
643
+
644
+ },
645
+
646
+ /**
647
+ * Makes an educated guess as to whether the browser is running on a touch device
648
+ * @method isTouchDevice
649
+ * @static
650
+ * @return {boolean} True if it's likely the browser is running on a touch device
651
+ */
652
+ isTouchDevice: function() {
653
+
654
+ return ("ontouchstart" in window);
655
+
656
+ },
657
+
658
+ /**
659
+ * Makes an educated guess whether the browser is running on an iOS device
660
+ * @method isDeviceiOS
661
+ * @static
662
+ * @return {boolean} True if it's likely the browser is running on an iOS device
663
+ */
664
+ isDeviceiOS: function() {
665
+
666
+ return (
667
+
668
+ (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream)
669
+
670
+ ||
671
+
672
+ (!!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform))
673
+
674
+ );
675
+
676
+ },
677
+
678
+ /**
679
+ * This function prevents modern style components being used with new UI styles (8.0.0)
680
+ * @method isModernComponentStyleAllowed
681
+ * @static
682
+ * @return {boolean} True if modern or legacy style is selected, or no UI style is selected
683
+ */
684
+ isModernComponentStyleAllowed: function() {
685
+
686
+ return (!WPGMZA.settings.user_interface_style || WPGMZA.settings.user_interface_style == "legacy" || WPGMZA.settings.user_interface_style == "modern");
687
+
688
+ },
689
+
690
+ isElementInView: function(element) {
691
+
692
+ var pageTop = $(window).scrollTop();
693
+ var pageBottom = pageTop + $(window).height();
694
+ var elementTop = $(element).offset().top;
695
+ var elementBottom = elementTop + $(element).height();
696
+
697
+ if(elementTop < pageTop && elementBottom > pageBottom)
698
+ return true;
699
+
700
+ if(elementTop >= pageTop && elementTop <= pageBottom)
701
+ return true;
702
+
703
+ if(elementBottom >= pageTop && elementBottom <= pageBottom)
704
+ return true;
705
+
706
+ return false;
707
+
708
+ },
709
+
710
+ isFullScreen: function() {
711
+
712
+ return wpgmzaisFullScreen;
713
+
714
+ },
715
+
716
+ getQueryParamValue: function(name) {
717
+
718
+ var regex = new RegExp(name + "=([^&#]*)");
719
+ var m;
720
+
721
+ if(!(m = window.location.href.match(regex)))
722
+ return null;
723
+
724
+ return decodeURIComponent(m[1]);
725
+ },
726
+
727
+ notification: function(text, time) {
728
+
729
+ switch(arguments.length)
730
+ {
731
+ case 0:
732
+ text = "";
733
+ time = 4000;
734
+ break;
735
+
736
+ case 1:
737
+ time = 4000;
738
+ break;
739
+ }
740
+
741
+ var html = '<div class="wpgmza-popup-notification">' + text + '</div>';
742
+ jQuery('body').append(html);
743
+ setTimeout(function(){
744
+ jQuery('body').find('.wpgmza-popup-notification').remove();
745
+ }, time);
746
+
747
+ },
748
+
749
+ initMaps: function(){
750
+ $(document.body).find(".wpgmza_map:not(.wpgmza-initialized)").each(function(index, el) {
751
+ if(el.wpgmzaMap) {
752
+ console.warn("Element missing class wpgmza-initialized but does have wpgmzaMap property. No new instance will be created");
753
+ return;
754
+ }
755
+
756
+ try {
757
+ el.wpgmzaMap = WPGMZA.Map.createInstance(el);
758
+ } catch (ex){
759
+ console.warn('Map initalization: ' + ex);
760
+ }
761
+ });
762
+
763
+ WPGMZA.Map.nextInitTimeoutID = setTimeout(WPGMZA.initMaps, 3000);
764
+ },
765
+
766
+ onScroll: function(){
767
+ $(".wpgmza_map").each(function(index, el) {
768
+ var isInView = WPGMZA.isElementInView(el);
769
+ if(!el.wpgmzaScrollIntoViewTriggerFlag){
770
+ if(isInView){
771
+ $(el).trigger("mapscrolledintoview.wpgmza");
772
+ el.wpgmzaScrollIntoViewTriggerFlag = true;
773
+ }
774
+ } else if(!isInView){
775
+ el.wpgmzaScrollIntoViewTriggerFlag = false;
776
+ }
777
+
778
+ });
779
+ }
780
+
781
+ };
782
+
783
+ var wpgmzaisFullScreen = false;
784
+
785
+
786
+ // NB: Warn the user if the built in Array prototype has been extended. This will save debugging headaches where for ... in loops do bizarre things.
787
+ for(var key in [])
788
+ {
789
+ console.warn("It appears that the built in JavaScript Array has been extended, this can create issues with for ... in loops, which may cause failure.");
790
+ break;
791
+ }
792
+
793
+ if(window.WPGMZA)
794
+ window.WPGMZA = $.extend(window.WPGMZA, core);
795
+ else
796
+ window.WPGMZA = core;
797
+
798
+ /* Usercentrics base level integration */
799
+ if(window.uc && window.uc.reloadOnOptIn){
800
+ window.uc.reloadOnOptIn(
801
+ 'S1pcEj_jZX'
802
+ );
803
+
804
+ window.uc.reloadOnOptOut(
805
+ 'S1pcEj_jZX'
806
+ );
807
+ }
808
+
809
+
810
+ for(var key in WPGMZA_localized_data){
811
+ var value = WPGMZA_localized_data[key];
812
+ WPGMZA[key] = value;
813
+ }
814
+
815
+ // delete window.WPGMZA_localized_data;
816
+
817
+ WPGMZA.settings.useLegacyGlobals = true;
818
+
819
+ $(document).on("fullscreenchange", function() {
820
+ wpgmzaisFullScreen = document.fullscreenElement ? true : false;
821
+ });
822
+
823
+ $('body').on('click',"#wpgmzaCloseChat", function(e) {
824
+ e.preventDefault();
825
+ $.ajax(WPGMZA.ajaxurl, {
826
+ method: 'POST',
827
+ data: {
828
+ action: 'wpgmza_hide_chat',
829
+ nonce: WPGMZA_localized_data.ajaxnonce
830
+ }
831
+ });
832
+ $('.wpgmza-chat-help').remove();
833
+ });
834
+
835
+
836
+ $(window).on("scroll", WPGMZA.onScroll);
837
+
838
+ $(document.body).on("click", "button.wpgmza-api-consent", function(event) {
839
+ Cookies.set("wpgmza-api-consent-given", true);
840
+ window.location.reload();
841
+ });
842
+
843
+ $(document.body).on("keydown", function(event) {
844
+ if(event.altKey)
845
+ WPGMZA.altKeyDown = true;
846
+ });
847
+
848
+ $(document.body).on("keyup", function(event) {
849
+ if(!event.altKey)
850
+ WPGMZA.altKeyDown = false;
851
+ });
852
+
853
+ $(document.body).on('preinit.wpgmza', function(){
854
+ $(window).trigger("ready.wpgmza");
855
+
856
+ // Combined script warning
857
+ if($("script[src*='wp-google-maps.combined.js'], script[src*='wp-google-maps-pro.combined.js']").length){
858
+ console.warn("Minified script is out of date, using combined script instead.");
859
+ }
860
+
861
+ // Check for multiple jQuery versions
862
+ var elements = $("script[src]").filter(function() {
863
+ return this.src.match(/(^|\/)jquery\.(min\.)?js(\?|$)/i);
864
+ });
865
+
866
+ if(elements.length > 1){
867
+ console.warn("Multiple jQuery versions detected: ", elements);
868
+ }
869
+
870
+ // Array incorrectly extended warning
871
+ var test = [];
872
+ for(var key in test) {
873
+ console.warn("The Array object has been extended incorrectly by your theme or another plugin. This can cause issues with functionality.");
874
+ break;
875
+ }
876
+
877
+ // Geolocation warnings
878
+ if(window.location.protocol != 'https:'){
879
+ var warning = '<div class="notice notice-warning"><p>' + WPGMZA.localized_strings.unsecure_geolocation + "</p></div>";
880
+
881
+ $(".wpgmza-geolocation-setting").first().after( $(warning) );
882
+ }
883
+
884
+ if(WPGMZA.googleAPIStatus && WPGMZA.googleAPIStatus.code == "USER_CONSENT_NOT_GIVEN") {
885
+ if(jQuery('.wpgmza-gdpr-compliance').length <= 0){
886
+ /*$("#wpgmza_map, .wpgmza_map").each(function(index, el) {
887
+ $(el).append($(WPGMZA.api_consent_html));
888
+ $(el).css({height: "auto"});
889
+ });*/
890
+
891
+ $("button.wpgmza-api-consent").on("click", function(event) {
892
+ Cookies.set("wpgmza-api-consent-given", true);
893
+ window.location.reload();
894
+ });
895
+ }
896
+
897
+ return;
898
+ }
899
+ });
900
+
901
+ /**
902
+ * We use to use the win-the-race approach with set timeouts
903
+ *
904
+ * This caused immense issues with older versions of WP
905
+ *
906
+ * Instead, we call an anon-func, which queues on the ready call, this controls the queue without the need for timeouts
907
+ *
908
+ * While also maintaining the stack order, and the ability for consent plugins to stop ready calls early
909
+ */
910
+ (function($){
911
+ $(function(){
912
+ WPGMZA.restAPI = WPGMZA.RestAPI.createInstance();
913
+ if(WPGMZA.CloudAPI){
914
+ WPGMZA.cloudAPI = WPGMZA.CloudAPI.createInstance();
915
+ }
916
+
917
+ $(document.body).trigger('preinit.wpgmza');
918
+
919
+ WPGMZA.initMaps();
920
+ WPGMZA.onScroll();
921
+ });
922
+ })($);
923
+
924
+ });
js/v8/info-window.js CHANGED
@@ -1,243 +1,243 @@
1
- /**
2
- * @namespace WPGMZA
3
- * @module InfoWindow
4
- * @requires WPGMZA.EventDispatcher
5
- */
6
- jQuery(function($) {
7
-
8
- /**
9
- * Base class for infoWindows. This acts as an abstract class so that infoWindows for both Google and OpenLayers can be interacted with seamlessly by the overlying logic. <strong>Please <em>do not</em> call this constructor directly. Always use createInstance rather than instantiating this class directly.</strong> Using createInstance allows this class to be externally extensible.
10
- * @class WPGMZA.InfoWindow
11
- * @constructor WPGMZA.InfoWindow
12
- * @memberof WPGMZA
13
- * @see WPGMZA.InfoWindow.createInstance
14
- */
15
- WPGMZA.InfoWindow = function(feature) {
16
- var self = this;
17
-
18
-
19
-
20
- WPGMZA.EventDispatcher.call(this);
21
-
22
- WPGMZA.assertInstanceOf(this, "InfoWindow");
23
-
24
- this.on("infowindowopen", function(event) {
25
- self.onOpen(event);
26
- });
27
-
28
- if(!feature)
29
- return;
30
-
31
- this.feature = feature;
32
- this.state = WPGMZA.InfoWindow.STATE_CLOSED;
33
-
34
- if(feature.map)
35
- {
36
- // This has to be slightly delayed so the map initialization won't overwrite the infowindow element
37
- setTimeout(function() {
38
- self.onFeatureAdded(event);
39
- }, 100);
40
- }
41
- else
42
- feature.addEventListener("added", function(event) {
43
- self.onFeatureAdded(event);
44
- });
45
- }
46
-
47
-
48
-
49
- WPGMZA.InfoWindow.prototype = Object.create(WPGMZA.EventDispatcher.prototype);
50
- WPGMZA.InfoWindow.prototype.constructor = WPGMZA.InfoWindow;
51
-
52
- WPGMZA.InfoWindow.OPEN_BY_CLICK = 1;
53
- WPGMZA.InfoWindow.OPEN_BY_HOVER = 2;
54
-
55
- WPGMZA.InfoWindow.STATE_OPEN = "open";
56
- WPGMZA.InfoWindow.STATE_CLOSED = "closed";
57
-
58
- /**
59
- * Fetches the constructor to be used by createInstance, based on the selected maps engine
60
- * @method
61
- * @memberof WPGMZA.InfoWindow
62
- * @return {function} The appropriate constructor
63
- */
64
- WPGMZA.InfoWindow.getConstructor = function()
65
- {
66
- switch(WPGMZA.settings.engine)
67
- {
68
- case "open-layers":
69
- if(WPGMZA.isProVersion())
70
- return WPGMZA.OLProInfoWindow;
71
- return WPGMZA.OLInfoWindow;
72
- break;
73
-
74
- default:
75
- if(WPGMZA.isProVersion())
76
- return WPGMZA.GoogleProInfoWindow;
77
- return WPGMZA.GoogleInfoWindow;
78
- break;
79
- }
80
- }
81
-
82
- /**
83
- * Creates an instance of an InfoWindow, <strong>please <em>always</em> use this function rather than calling the constructor directly</strong>
84
- * @method
85
- * @memberof WPGMZA.InfoWindow
86
- * @param {object} options Options for the object (optional)
87
- */
88
- WPGMZA.InfoWindow.createInstance = function(feature)
89
- {
90
- var constructor = this.getConstructor();
91
- return new constructor(feature);
92
- }
93
-
94
- Object.defineProperty(WPGMZA.InfoWindow.prototype, "content", {
95
-
96
- "get": function()
97
- {
98
- return this.getContent();
99
- },
100
-
101
- "set": function(value)
102
- {
103
- this.contentHtml = value;
104
- }
105
- });
106
-
107
-
108
- WPGMZA.InfoWindow.prototype.addEditButton = function() {
109
- if (WPGMZA.currentPage == "map-edit") {
110
- if(this.feature instanceof WPGMZA.Marker){
111
- return ' <a title="Edit this marker" style="width:15px;" class="wpgmza_edit_btn" data-edit-marker-id="'+this.feature.id+'"><i class="fa fa-edit"></i></a>';
112
- }
113
- }
114
- return '';
115
-
116
- }
117
-
118
- WPGMZA.InfoWindow.prototype.workOutDistanceBetweenTwoMarkers = function(location1, location2) {
119
- if(!location1 || !location2)
120
- return; // No location (no search performed, user location unavailable)
121
-
122
- var distanceInKM = WPGMZA.Distance.between(location1, location2);
123
- var distanceToDisplay = distanceInKM;
124
-
125
- if(this.distanceUnits == WPGMZA.Distance.MILES)
126
- distanceToDisplay /= WPGMZA.Distance.KILOMETERS_PER_MILE;
127
-
128
- var text = Math.round(distanceToDisplay, 2);
129
-
130
- return text;
131
- }
132
-
133
-
134
- /**
135
- * Gets the content for the info window and passes it to the specified callback - this allows for delayed loading (eg AJAX) as well as instant content
136
- * @method
137
- * @memberof WPGMZA.InfoWindow
138
- * @return void
139
- */
140
- WPGMZA.InfoWindow.prototype.getContent = function(callback) {
141
- var html = "";
142
- var extra_html = "";
143
-
144
- if (this.feature instanceof WPGMZA.Marker) {
145
- // Store locator distance away
146
- // added by Nick 2020-01-12
147
- if (this.feature.map.settings.store_locator_show_distance && this.feature.map.storeLocator && (this.feature.map.storeLocator.state == WPGMZA.StoreLocator.STATE_APPLIED)) {
148
- var currentLatLng = this.feature.getPosition();
149
- var distance = this.workOutDistanceBetweenTwoMarkers(this.feature.map.storeLocator.center, currentLatLng);
150
-
151
- extra_html += "<p>"+(this.feature.map.settings.store_locator_distance == WPGMZA.Distance.KILOMETERS ? distance + WPGMZA.localized_strings.kilometers_away : distance + " " + WPGMZA.localized_strings.miles_away)+"</p>";
152
- }
153
-
154
- html = this.feature.address+extra_html;
155
- }
156
-
157
- if (this.contentHtml){
158
- html = this.contentHtml;
159
- }
160
-
161
-
162
- if(callback)
163
- callback(html);
164
-
165
- return html;
166
- }
167
-
168
- /**
169
- * Opens the info window on the specified map, with the specified map object as the subject.
170
- * @method
171
- * @memberof WPGMZA.InfoWindow
172
- * @param {WPGMZA.Map} map The map to open this InfoWindow on.
173
- * @param {WPGMZA.Feature} feature The map object (eg marker, polygon) to open this InfoWindow on.
174
- * @return boolean FALSE if the info window should not and will not open, TRUE if it will. This can be used by subclasses to establish whether or not the subclassed open should bail or open the window.
175
- */
176
- WPGMZA.InfoWindow.prototype.open = function(map, feature) {
177
- var self = this;
178
-
179
- this.feature = feature;
180
-
181
- if(WPGMZA.settings.disable_infowindows || WPGMZA.settings.wpgmza_settings_disable_infowindows == "1")
182
- return false;
183
-
184
- if(this.feature.disableInfoWindow)
185
- return false;
186
-
187
- this.state = WPGMZA.InfoWindow.STATE_OPEN;
188
-
189
- return true;
190
- }
191
-
192
- /**
193
- * Abstract function, closes this InfoWindow
194
- * @method
195
- * @memberof WPGMZA.InfoWindow
196
- */
197
- WPGMZA.InfoWindow.prototype.close = function()
198
- {
199
- if(this.state == WPGMZA.InfoWindow.STATE_CLOSED)
200
- return;
201
-
202
- this.state = WPGMZA.InfoWindow.STATE_CLOSED;
203
- this.trigger("infowindowclose");
204
- }
205
-
206
- /**
207
- * Abstract function, sets the content in this InfoWindow
208
- * @method
209
- * @memberof WPGMZA.InfoWindow
210
- */
211
- WPGMZA.InfoWindow.prototype.setContent = function(options)
212
- {
213
-
214
- }
215
-
216
- /**
217
- * Abstract function, sets options on this InfoWindow
218
- * @method
219
- * @memberof WPGMZA.InfoWindow
220
- */
221
- WPGMZA.InfoWindow.prototype.setOptions = function(options)
222
- {
223
-
224
- }
225
-
226
- /**
227
- * Event listener for when the map object is added. This will cause the info window to open if the map object has infoopen set
228
- * @method
229
- * @memberof WPGMZA.InfoWindow
230
- * @return void
231
- */
232
- WPGMZA.InfoWindow.prototype.onFeatureAdded = function()
233
- {
234
- if(this.feature.settings.infoopen == 1)
235
- this.open();
236
- }
237
-
238
- WPGMZA.InfoWindow.prototype.onOpen = function()
239
- {
240
-
241
- }
242
-
243
  });
1
+ /**
2
+ * @namespace WPGMZA
3
+ * @module InfoWindow
4
+ * @requires WPGMZA.EventDispatcher
5
+ */
6
+ jQuery(function($) {
7
+
8
+ /**
9
+ * Base class for infoWindows. This acts as an abstract class so that infoWindows for both Google and OpenLayers can be interacted with seamlessly by the overlying logic. <strong>Please <em>do not</em> call this constructor directly. Always use createInstance rather than instantiating this class directly.</strong> Using createInstance allows this class to be externally extensible.
10
+ * @class WPGMZA.InfoWindow
11
+ * @constructor WPGMZA.InfoWindow
12
+ * @memberof WPGMZA
13
+ * @see WPGMZA.InfoWindow.createInstance
14
+ */
15
+ WPGMZA.InfoWindow = function(feature) {
16
+ var self = this;
17
+
18
+
19
+
20
+ WPGMZA.EventDispatcher.call(this);
21
+
22
+ WPGMZA.assertInstanceOf(this, "InfoWindow");
23
+
24
+ this.on("infowindowopen", function(event) {
25
+ self.onOpen(event);
26
+ });
27
+
28
+ if(!feature)
29
+ return;
30
+
31
+ this.feature = feature;
32
+ this.state = WPGMZA.InfoWindow.STATE_CLOSED;
33
+
34
+ if(feature.map)
35
+ {
36
+ // This has to be slightly delayed so the map initialization won't overwrite the infowindow element
37
+ setTimeout(function() {
38
+ self.onFeatureAdded(event);
39
+ }, 100);
40
+ }
41
+ else
42
+ feature.addEventListener("added", function(event) {
43
+ self.onFeatureAdded(event);
44
+ });
45
+ }
46
+
47
+
48
+
49
+ WPGMZA.InfoWindow.prototype = Object.create(WPGMZA.EventDispatcher.prototype);
50
+ WPGMZA.InfoWindow.prototype.constructor = WPGMZA.InfoWindow;
51
+
52
+ WPGMZA.InfoWindow.OPEN_BY_CLICK = 1;
53
+ WPGMZA.InfoWindow.OPEN_BY_HOVER = 2;
54
+
55
+ WPGMZA.InfoWindow.STATE_OPEN = "open";
56
+ WPGMZA.InfoWindow.STATE_CLOSED = "closed";
57
+
58
+ /**
59
+ * Fetches the constructor to be used by createInstance, based on the selected maps engine
60
+ * @method
61
+ * @memberof WPGMZA.InfoWindow
62
+ * @return {function} The appropriate constructor
63
+ */
64
+ WPGMZA.InfoWindow.getConstructor = function()
65
+ {
66
+ switch(WPGMZA.settings.engine)
67
+ {
68
+ case "open-layers":
69
+ if(WPGMZA.isProVersion())
70
+ return WPGMZA.OLProInfoWindow;
71
+ return WPGMZA.OLInfoWindow;
72
+ break;
73
+
74
+ default:
75
+ if(WPGMZA.isProVersion())
76
+ return WPGMZA.GoogleProInfoWindow;
77
+ return WPGMZA.GoogleInfoWindow;
78
+ break;
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Creates an instance of an InfoWindow, <strong>please <em>always</em> use this function rather than calling the constructor directly</strong>
84
+ * @method
85
+ * @memberof WPGMZA.InfoWindow
86
+ * @param {object} options Options for the object (optional)
87
+ */
88
+ WPGMZA.InfoWindow.createInstance = function(feature)
89
+ {
90
+ var constructor = this.getConstructor();
91
+ return new constructor(feature);
92
+ }
93
+
94
+ Object.defineProperty(WPGMZA.InfoWindow.prototype, "content", {
95
+
96
+ "get": function()
97
+ {
98
+ return this.getContent();
99
+ },
100
+
101
+ "set": function(value)
102
+ {
103
+ this.contentHtml = value;
104
+ }
105
+ });
106
+
107
+
108
+ WPGMZA.InfoWindow.prototype.addEditButton = function() {
109
+ if (WPGMZA.currentPage == "map-edit") {
110
+ if(this.feature instanceof WPGMZA.Marker){
111
+ return ' <a title="Edit this marker" style="width:15px;" class="wpgmza_edit_btn" data-edit-marker-id="'+this.feature.id+'"><i class="fa fa-edit"></i></a>';
112
+ }
113
+ }
114
+ return '';
115
+
116
+ }
117
+
118
+ WPGMZA.InfoWindow.prototype.workOutDistanceBetweenTwoMarkers = function(location1, location2) {
119
+ if(!location1 || !location2)
120
+ return; // No location (no search performed, user location unavailable)
121
+
122
+ var distanceInKM = WPGMZA.Distance.between(location1, location2);
123
+ var distanceToDisplay = distanceInKM;
124
+
125
+ if(this.distanceUnits == WPGMZA.Distance.MILES)
126
+ distanceToDisplay /= WPGMZA.Distance.KILOMETERS_PER_MILE;
127
+
128
+ var text = Math.round(distanceToDisplay, 2);
129
+
130
+ return text;
131
+ }
132
+
133
+
134
+ /**
135
+ * Gets the content for the info window and passes it to the specified callback - this allows for delayed loading (eg AJAX) as well as instant content
136
+ * @method
137
+ * @memberof WPGMZA.InfoWindow
138
+ * @return void
139
+ */
140
+ WPGMZA.InfoWindow.prototype.getContent = function(callback) {
141
+ var html = "";
142
+ var extra_html = "";
143
+
144
+ if (this.feature instanceof WPGMZA.Marker) {
145
+ // Store locator distance away
146
+ // added by Nick 2020-01-12
147
+ if (this.feature.map.settings.store_locator_show_distance && this.feature.map.storeLocator && (this.feature.map.storeLocator.state == WPGMZA.StoreLocator.STATE_APPLIED)) {
148
+ var currentLatLng = this.feature.getPosition();
149
+ var distance = this.workOutDistanceBetweenTwoMarkers(this.feature.map.storeLocator.center, currentLatLng);
150
+
151
+ extra_html += "<p>"+(this.feature.map.settings.store_locator_distance == WPGMZA.Distance.KILOMETERS ? distance + WPGMZA.localized_strings.kilometers_away : distance + " " + WPGMZA.localized_strings.miles_away)+"</p>";
152
+ }
153
+
154
+ html = this.feature.address+extra_html;
155
+ }
156
+
157
+ if (this.contentHtml){
158
+ html = this.contentHtml;
159
+ }
160
+
161
+
162
+ if(callback)
163
+ callback(html);
164
+
165
+ return html;
166
+ }
167
+
168
+ /**
169
+ * Opens the info window on the specified map, with the specified map object as the subject.
170
+ * @method
171
+ * @memberof WPGMZA.InfoWindow
172
+ * @param {WPGMZA.Map} map The map to open this InfoWindow on.
173
+ * @param {WPGMZA.Feature} feature The map object (eg marker, polygon) to open this InfoWindow on.
174
+ * @return boolean FALSE if the info window should not and will not open, TRUE if it will. This can be used by subclasses to establish whether or not the subclassed open should bail or open the window.
175
+ */
176
+ WPGMZA.InfoWindow.prototype.open = function(map, feature) {
177
+ var self = this;
178
+
179
+ this.feature = feature;
180
+
181
+ if(WPGMZA.settings.disable_infowindows || WPGMZA.settings.wpgmza_settings_disable_infowindows == "1")
182
+ return false;
183
+
184
+ if(this.feature.disableInfoWindow)
185
+ return false;
186
+
187
+ this.state = WPGMZA.InfoWindow.STATE_OPEN;
188
+
189
+ return true;
190
+ }
191
+
192
+ /**
193
+ * Abstract function, closes this InfoWindow
194
+ * @method
195
+ * @memberof WPGMZA.InfoWindow
196
+ */
197
+ WPGMZA.InfoWindow.prototype.close = function()
198
+ {
199
+ if(this.state == WPGMZA.InfoWindow.STATE_CLOSED)
200
+ return;
201
+
202
+ this.state = WPGMZA.InfoWindow.STATE_CLOSED;
203
+ this.trigger("infowindowclose");
204
+ }
205
+
206
+ /**
207
+ * Abstract function, sets the content in this InfoWindow
208
+ * @method
209
+ * @memberof WPGMZA.InfoWindow
210
+ */
211
+ WPGMZA.InfoWindow.prototype.setContent = function(options)
212
+ {
213
+
214
+ }
215
+
216
+ /**
217
+ * Abstract function, sets options on this InfoWindow
218
+ * @method
219
+ * @memberof WPGMZA.InfoWindow
220
+ */
221
+ WPGMZA.InfoWindow.prototype.setOptions = function(options)
222
+ {
223
+
224
+ }
225
+
226
+ /**
227
+ * Event listener for when the map object is added. This will cause the info window to open if the map object has infoopen set
228
+ * @method
229
+ * @memberof WPGMZA.InfoWindow
230
+ * @return void
231
+ */
232
+ WPGMZA.InfoWindow.prototype.onFeatureAdded = function()
233
+ {
234
+ if(this.feature.settings.infoopen == 1)
235
+ this.open();
236
+ }
237
+
238
+ WPGMZA.InfoWindow.prototype.onOpen = function()
239
+ {
240
+
241
+ }
242
+
243
  });
js/v8/map-edit-page/map-edit-page.js CHANGED
@@ -1,637 +1,637 @@
1
- /**
2
- * @namespace WPGMZA
3
- * @module MapEditPage
4
- * @requires WPGMZA.EventDispatcher
5
- */
6
-
7
- var wpgmza_autoCompleteDisabled = false;
8
-
9
- jQuery(function($) {
10
-
11
- if(WPGMZA.currentPage != "map-edit")
12
- return;
13
-
14
- WPGMZA.MapEditPage = function()
15
- {
16
- var self = this;
17
- var element = document.body;
18
-
19
- WPGMZA.EventDispatcher.call(this);
20
-
21
- $("#wpgmaps_options fieldset").wrapInner("<div class='wpgmza-flex'></div>");
22
-
23
- this.themePanel = new WPGMZA.ThemePanel();
24
- this.themeEditor = new WPGMZA.ThemeEditor();
25
-
26
- this.map = WPGMZA.maps[0];
27
-
28
- // Drawing manager
29
- if(!WPGMZA.pro_version || WPGMZA.Version.compare(WPGMZA.pro_version, '8.1.0') >= WPGMZA.Version.EQUAL_TO)
30
- this.drawingManager = WPGMZA.DrawingManager.createInstance(this.map);
31
-
32
- // UI
33
- this.initDataTables();
34
- this.initFeaturePanels();
35
- this.initJQueryUIControls();
36
-
37
- if(WPGMZA.locale !== 'en'){
38
- $('#datatable_no_result_message,#datatable_search_string').parent().parent().hide();
39
- }
40
-
41
- // Address input
42
- $("input.wpgmza-address").each(function(index, el) {
43
- el.addressInput = WPGMZA.AddressInput.createInstance(el, self.map);
44
- });
45
-
46
- $('#wpgmza-map-edit-page input[type="color"]').each(function(){
47
- $("<div class='button-secondary wpgmza-paste-color-btn' title='Paste a HEX color code'><i class='fa fa-clipboard' aria-hidden='true'></i></div>").insertAfter(this);
48
- });
49
-
50
-
51
- jQuery('body').on('click','.wpgmza_ac_result', function(e) {
52
- var index = jQuery(this).data('id');
53
- var lat = jQuery(this).data('lat');
54
- var lng = jQuery(this).data('lng');
55
- var name = jQuery('#wpgmza_item_address_'+index).html();
56
-
57
-
58
- jQuery("input[name='lat']").val(lat);
59
- jQuery("input[name='lng']").val(lng);
60
- jQuery("#wpgmza_add_address_map_editor").val(name);
61
- jQuery('#wpgmza_autocomplete_search_results').hide();
62
- });
63
-
64
- jQuery('body').on('click', '.wpgmza-paste-color-btn', function(){
65
- try{
66
- var colorBtn = $(this);
67
- if(!navigator || !navigator.clipboard || !navigator.clipboard.readText){
68
- return;
69
- }
70
-
71
- navigator.clipboard.readText()
72
- .then(function(textcopy) {
73
- colorBtn.parent().find('input[type="color"]').val("#" + textcopy.replace("#","").trim());
74
- })
75
- .catch(function(err) {
76
- console.error("WP Google Maps: Could not access clipboard", err);
77
- });
78
-
79
- } catch(c_ex){
80
-
81
- }
82
- });
83
-
84
- jQuery('body').on('focusout', '#wpgmza_add_address_map_editor', function(e) {
85
- setTimeout(function() {
86
- jQuery('#wpgmza_autocomplete_search_results').fadeOut('slow');
87
- },500)
88
-
89
- });
90
-
91
- var ajaxRequest = false;
92
- var wpgmzaAjaxTimeout = false;
93
-
94
- var wpgmzaStartTyping = false;
95
- var wpgmzaKeyStrokeCount = 1;
96
- var wpgmzaAvgTimeBetweenStrokes = 300; //300 ms by default (equates to 40wpm which is the average typing speed of a person)
97
- var wpgmzaTotalTimeForKeyStrokes = 0;
98
- var wpgmzaTmp = '';
99
- var wpgmzaIdentifiedTypingSpeed = false;
100
-
101
- $('body').on('keypress', '.wpgmza-address', function(e) {
102
-
103
- if (this.id == 'wpgmza_add_address_map_editor') {
104
- if (wpgmza_autoCompleteDisabled) { return; }
105
-
106
-
107
-
108
- // if user is using their own API key then use the normal Google AutoComplete
109
- var wpgmza_apikey = false;
110
- if (WPGMZA_localized_data.settings.googleMapsApiKey && WPGMZA_localized_data.settings.googleMapsApiKey !== '') {
111
- wpgmza_apikey = WPGMZA_localized_data.settings.googleMapsApiKey;
112
- return;
113
- } else {
114
-
115
- if(e.key === "Escape" || e.key === "Alt" || e.key === "Control" || e.key === "Option" || e.key === "Shift" || e.key === "ArrowLeft" || e.key === "ArrowRight" || e.key === "ArrowUp" || e.key === "ArrowDown") {
116
- $('#wpgmza_autocomplete_search_results').hide();
117
- return;
118
- }
119
-
120
- if (!wpgmzaIdentifiedTypingSpeed) {
121
- //determine duration between key strokes to determine when we should send the request to the autocomplete server
122
- //doing this avoids sending API calls for slow typers.
123
- var d = new Date();
124
-
125
-
126
- // set a timer to reset the delay counter
127
- clearTimeout(wpgmzaTmp);
128
- wpgmzaTmp = setTimeout(function(){
129
- wpgmzaStartTyping = false;
130
- wpgmzaAvgTimeBetweenStrokes = 300;
131
- wpgmzaTotalTimeForKeyStrokes = 0;
132
- },1500
133
- ); // I'm pretty sure no one types one key stroke per 1.5 seconds. This should be safe.
134
- if (!wpgmzaStartTyping) {
135
- // first character press, set start time.
136
-
137
- wpgmzaStartTyping = d.getTime();
138
- wpgmzaKeyStrokeCount++;
139
- } else {
140
- if (wpgmzaKeyStrokeCount == 1) {
141
- // do nothing because its the first key stroke
142
- } else {
143
-
144
-
145
- wpgmzaCurrentTimeBetweenStrokes = d.getTime() - wpgmzaStartTyping;
146
- wpgmzaTotalTimeForKeyStrokes = wpgmzaTotalTimeForKeyStrokes + wpgmzaCurrentTimeBetweenStrokes;
147
-
148
- wpgmzaAvgTimeBetweenStrokes = (wpgmzaTotalTimeForKeyStrokes / (wpgmzaKeyStrokeCount-1)); // we cannot count the first key as that was the starting point
149
- wpgmzaStartTyping = d.getTime();
150
-
151
- if (wpgmzaKeyStrokeCount >= 3) {
152
- // we only need 3 keys to know how fast they type
153
- wpgmzaIdentifiedTypingSpeed = (wpgmzaAvgTimeBetweenStrokes);
154
-
155
-
156
- }
157
- }
158
- wpgmzaKeyStrokeCount++;
159
-
160
-
161
-
162
- }
163
- return;
164
- }
165
-
166
-
167
- // clear the previous timer
168
- clearTimeout(wpgmzaAjaxTimeout);
169
-
170
- $('#wpgmza_autocomplete_search_results').html('Searching...');
171
- $('#wpgmza_autocomplete_search_results').show();
172
-
173
-
174
-
175
-
176
- var currentSearch = jQuery(this).val();
177
- if (currentSearch !== '') {
178
-
179
- if(ajaxRequest !== false){
180
- ajaxRequest.abort();
181
- }
182
-
183
- var domain = window.location.hostname;
184
- if(domain === 'localhost'){
185
- try{
186
- var paths = window.location.pathname.match(/\/(.*?)\//);
187
- if(paths && paths.length >= 2 && paths[1]){
188
- var path = paths[1];
189
- domain += "-" + path
190
- }
191
- } catch (ex){
192
- /* Leave it alone */
193
- }
194
- }
195
-
196
- var wpgmza_api_url = '';
197
- if (!wpgmza_apikey) {
198
- wpgmza_api_url = "https://wpgmaps.us-3.evennode.com/api/v1/autocomplete?s="+currentSearch+"&d="+domain+"&hash="+WPGMZA_localized_data.siteHash
199
- } else {
200
- wpgmza_api_url = "https://wpgmaps.us-3.evennode.com/api/v1/autocomplete?s="+currentSearch+"&d="+domain+"&hash="+WPGMZA_localized_data.siteHash+"&k="+wpgmza_apikey
201
- }
202
-
203
- if(WPGMZA && WPGMZA.settings && WPGMZA.settings.engine){
204
- wpgmza_api_url += "&engine=" + WPGMZA.settings.engine;
205
- }
206
-
207
- // set a timer of how fast the person types in seconds to only continue with this if it runs out
208
- wpgmzaAjaxTimeout = setTimeout(function() {
209
- ajaxRequest = $.ajax({
210
- url: wpgmza_api_url,
211
- type: 'GET',
212
- dataType: 'json', // added data type
213
- success: function(results) {
214
-
215
- try {
216
-
217
- if (typeof results.error !== 'undefined') {
218
- if (results.error == 'error1') {
219
- $('#wpgmza_autoc_disabled').html(WPGMZA.localized_strings.cloud_api_key_error_1);
220
- $('#wpgmza_autoc_disabled').fadeIn('slow');
221
- $('#wpgmza_autocomplete_search_results').hide();
222
- wpgmza_autoCompleteDisabled = true;
223
- } else {
224
- console.error(results.error);
225
- }
226
-
227
- } else {
228
- $('#wpgmza_autocomplete_search_results').html('');
229
- var html = "";
230
- for(var i in results){ html += "<div class='wpgmza_ac_result " + (html === "" ? "" : "border-top") + "' data-id='" + i + "' data-lat='"+results[i]['lat']+"' data-lng='"+results[i]['lng']+"'><div class='wpgmza_ac_container'><div class='wpgmza_ac_icon'><img src='"+results[i]['icon']+"' /></div><div class='wpgmza_ac_item'><span id='wpgmza_item_name_"+i+"' class='wpgmza_item_name'>" + results[i]['place_name'] + "</span><span id='wpgmza_item_address_"+i+"' class='wpgmza_item_address'>" + results[i]['formatted_address'] + "</span></div></div></div>"; }
231
- if(html == ""){ html = "<div class='p-2 text-center'><small>No results found...</small></div>"; }
232
- $('#wpgmza_autocomplete_search_results').html(html);
233
- $('#wpgmza_autocomplete_search_results').show();
234
-
235
- }
236
- } catch (exception) {
237
- console.error("WP Google Maps Plugin: There was an error returning the list of places for your search");
238
- }
239
-
240
-
241
-
242
- }
243
- });
244
- },(wpgmzaIdentifiedTypingSpeed*2));
245
-
246
-
247
-
248
-
249
- } else {
250
- $('#wpgmza_autocomplete_search_results').hide();
251
- }
252
- }
253
- }
254
- });
255
-
256
-
257
- // Map height change (for warning)
258
- $("#wpgmza_map_height_type").on("change", function(event) {
259
- self.onMapHeightTypeChange(event);
260
- });
261
-
262
- // Don't have instructions in advanced marker panel, it's confusing for debugging and unnecessary
263
- $("#advanced-markers .wpgmza-feature-drawing-instructions").remove();
264
-
265
- // Hide the auto search area maximum zoom - not available in Basic. Pro will take care of showing it when needed
266
- $("[data-search-area='auto']").hide();
267
-
268
- // Control listeners
269
- $(document.body).on("click", "[data-wpgmza-admin-marker-datatable] input[name='mark']", function(event) {
270
- self.onShiftClick(event);
271
- });
272
-
273
- $("#wpgmza_map_type").on("change", function(event) {
274
- self.onMapTypeChanged(event);
275
- });
276
-
277
- $("body").on("click",".wpgmza_copy_shortcode", function() {
278
- var $temp = jQuery('<input>');
279
- var $tmp2 = jQuery('<span id="wpgmza_tmp" style="display:none; width:100%; text-align:center;">');
280
- jQuery("body").append($temp);
281
- $temp.val(jQuery(this).val()).select();
282
- document.execCommand("copy");
283
- $temp.remove();
284
- WPGMZA.notification("Shortcode Copied");
285
- });
286
-
287
- this.on("markerupdated", function(event) {
288
- self.onMarkerUpdated(event);
289
- });
290
-
291
- // NB: Older version of Pro (< 7.0.0 - pre-WPGMZA.Map) will have this.map as undefined. Only run this code if we have a WPGMZA.Map to work with.
292
- if(this.map)
293
- {
294
- this.map.on("zoomchanged", function(event) {
295
- self.onZoomChanged(event);
296
- });
297
-
298
- this.map.on("boundschanged", function(event) {
299
- self.onBoundsChanged(event);
300
- });
301
-
302
- this.map.on("rightclick", function(event) {
303
- self.onRightClick(event);
304
- });
305
- }
306
-
307
- $(element).on("click", ".wpgmza_poly_del_btn", function(event) {
308
- self.onDeletePolygon(event);
309
- });
310
-
311
- $(element).on("click", ".wpgmza_polyline_del_btn", function(event) {
312
- self.onDeletePolyline(event);
313
- });
314
-
315
- $(element).on("click", ".wpgmza_dataset_del_btn", function(evevnt) {
316
- self.onDeleteHeatmap(event);
317
- });
318
-
319
- $(element).on("click", ".wpgmza_circle_del_btn", function(event) {
320
- self.onDeleteCircle(event);
321
- });
322
-
323
- $(element).on("click", ".wpgmza_rectangle_del_btn", function(event) {
324
- self.onDeleteRectangle(event);
325
- });
326
-
327
- $(element).on("click", "#wpgmza-open-advanced-theme-data", function(event){
328
- event.preventDefault();
329
- $('.wpgmza_theme_data_container').toggleClass('wpgmza_hidden');
330
- });
331
- }
332
-
333
- WPGMZA.extend(WPGMZA.MapEditPage, WPGMZA.EventDispatcher);
334
-
335
- WPGMZA.MapEditPage.createInstance = function()
336
- {
337
- if(WPGMZA.isProVersion() && WPGMZA.Version.compare(WPGMZA.pro_version, "8.0.0") >= WPGMZA.Version.EQUAL_TO)
338
- return new WPGMZA.ProMapEditPage();
339
-
340
- return new WPGMZA.MapEditPage();
341
- }
342
-
343
- WPGMZA.MapEditPage.prototype.initDataTables = function()
344
- {
345
- var self = this;
346
-
347
- $("[data-wpgmza-datatable][data-wpgmza-rest-api-route]").each(function(index, el) {
348
-
349
- var featureType = $(el).attr("data-wpgmza-feature-type");
350
-
351
- self[featureType + "AdminDataTable"] = new WPGMZA.AdminFeatureDataTable(el);
352
-
353
- });
354
- }
355
-
356
- WPGMZA.MapEditPage.prototype.initFeaturePanels = function()
357
- {
358
- var self = this;
359
-
360
- $(".wpgmza-feature-accordion[data-wpgmza-feature-type]").each(function(index, el) {
361
-
362
- var featurePanelElement = $(el).find(".wpgmza-feature-panel-container > *");
363
- var featureType = $(el).attr("data-wpgmza-feature-type");
364
- var panelClassName = WPGMZA.capitalizeWords(featureType) + "Panel";
365
- var module = WPGMZA[panelClassName];
366
- var instance = module.createInstance(featurePanelElement, self);
367
-
368
- self[featureType + "Panel"] = instance;
369
-
370
- });
371
- }
372
-
373
- WPGMZA.MapEditPage.prototype.initJQueryUIControls = function()
374
- {
375
- var self = this;
376
- var mapContainer;
377
-
378
- // Now initialise tabs
379
- $("#wpgmaps_tabs").tabs();
380
-
381
- // NB: If the map container has a <ul> then this will break the tabs (this happens in OpenLayers). Temporarily detach the map to avoid this.
382
- mapContainer = $("#wpgmza-map-container").detach();
383
-
384
- $("#wpgmaps_tabs_markers").tabs();
385
-
386
- // NB: Re-add the map container (see above)
387
- $(".map_wrapper").prepend(mapContainer);
388
-
389
- // And the zoom slider
390
- $("#slider-range-max").slider({
391
- range: "max",
392
- min: 1,
393
- max: 21,
394
- value: $("input[name='map_start_zoom']").val(),
395
- slide: function( event, ui ) {
396
- $("input[name='map_start_zoom']").val(ui.value);
397
- self.map.setZoom(ui.value);
398
- }
399
- });
400
- }
401
-
402
- WPGMZA.MapEditPage.prototype.onShiftClick = function(event)
403
- {
404
- var checkbox = event.currentTarget;
405
- var row = jQuery(checkbox).closest("tr");
406
-
407
- if(this.lastSelectedRow && event.shiftKey)
408
- {
409
- var prevIndex = this.lastSelectedRow.index();
410
- var currIndex = row.index();
411
- var startIndex = Math.min(prevIndex, currIndex);
412
- var endIndex = Math.max(prevIndex, currIndex);
413
- var rows = jQuery("[data-wpgmza-admin-marker-datatable] tbody>tr");
414
-
415
- // Clear
416
- jQuery("[data-wpgmza-admin-marker-datatable] input[name='mark']").prop("checked", false);
417
-
418
- for(var i = startIndex; i <= endIndex; i++)
419
- jQuery(rows[i]).find("input[name='mark']").prop("checked", true);
420
-
421
-
422
-
423
- }
424
-
425
- this.lastSelectedRow = row;
426
- }
427
-
428
- WPGMZA.MapEditPage.prototype.onMapTypeChanged = function(event)
429
- {
430
- if(WPGMZA.settings.engine == "open-layers")
431
- return;
432
-
433
- var mapTypeId;
434
-
435
- switch(event.target.value)
436
- {
437
- case "2":
438
- mapTypeId = google.maps.MapTypeId.SATELLITE;
439
- break;
440
-
441
- case "3":
442
- mapTypeId = google.maps.MapTypeId.HYBRID;
443
- break;
444
-
445
- case "4":
446
- mapTypeId = google.maps.MapTypeId.TERRAIN;
447
- break;
448
-
449
- default:
450
- mapTypeId = google.maps.MapTypeId.ROADMAP;
451
- break;
452
- }
453
-
454
- this.map.setOptions({
455
- mapTypeId: mapTypeId
456
- });
457
- }
458
-
459
- WPGMZA.MapEditPage.prototype.onMarkerUpdated = function(event)
460
- {
461
- this.markerDataTable.reload();
462
- }
463
-
464
- WPGMZA.MapEditPage.prototype.onZoomChanged = function(event) {
465
- $(".map_start_zoom").val(this.map.getZoom());
466
- }
467
-
468
- WPGMZA.MapEditPage.prototype.onBoundsChanged = function(event)
469
- {
470
- var location = this.map.getCenter();
471
-
472
- $("#wpgmza_start_location").val(location.lat + "," + location.lng);
473
- $("input[name='map_start_lat']").val(location.lat);
474
- $("input[name='map_start_lng']").val(location.lng);
475
-
476
- $("#wpgmza_start_zoom").val(this.map.getZoom());
477
-
478
- $("#wpgmaps_save_reminder").show();
479
- }
480
-
481
- WPGMZA.MapEditPage.prototype.onMapHeightTypeChange = function(event)
482
- {
483
- if(event.target.value == "%")
484
- $("#wpgmza_height_warning").show();
485
- }
486
-
487
- WPGMZA.MapEditPage.prototype.onRightClick = function(event)
488
- {
489
- var self = this;
490
- var marker;
491
-
492
- if(this.drawingManager && this.drawingManager.mode != WPGMZA.DrawingManager.MODE_MARKER)
493
- return; // Do nothing, not in marker mode
494
-
495
- if(!this.rightClickMarker)
496
- {
497
- this.rightClickMarker = WPGMZA.Marker.createInstance({
498
- draggable: true
499
- });
500
-
501
- this.rightClickMarker.on("dragend", function(event) {
502
- $(".wpgmza-marker-panel [data-ajax-name='address']").val(event.latLng.lat + "," + event.latLng.lng);
503
- });
504
-
505
- this.map.on("click", function(event) {
506
- self.rightClickMarker.setMap(null);
507
- });
508
- }
509
-
510
- marker = this.rightClickMarker;
511
-
512
- marker.setPosition(event.latLng);
513
- marker.setMap(this.map);
514
-
515
- $(".wpgmza-marker-panel [data-ajax-name='address']").val(event.latLng.lat+', '+event.latLng.lng);
516
- }
517
-
518
- WPGMZA.MapEditPage.prototype.onDeletePolygon = function(event)
519
- {
520
- var cur_id = parseInt($(this).attr("id"));
521
- var data = {
522
- action: 'delete_poly',
523
- security: wpgmza_legacy_map_edit_page_vars.ajax_nonce,
524
- map_id: this.map.id,
525
- poly_id: cur_id
526
- };
527
-
528
- $.post(ajaxurl, data, function (response) {
529
-
530
- WPGM_Path[cur_id].setMap(null);
531
- delete WPGM_PathData[cur_id];
532
- delete WPGM_Path[cur_id];
533
- $("#wpgmza_poly_holder").html(response);
534
-
535
- });
536
- }
537
-
538
- WPGMZA.MapEditPage.prototype.onDeletePolyline = function(event)
539
- {
540
- var cur_id = $(this).attr("id");
541
- var data = {
542
- action: 'delete_polyline',
543
- security: wpgmza_legacy_map_edit_page_vars.ajax_nonce,
544
- map_id: this.map.id,
545
- poly_id: cur_id
546
- };
547
-
548
- $.post(ajaxurl, data, function (response) {
549
-
550
- WPGM_PathLine[cur_id].setMap(null);
551
- delete WPGM_PathLineData[cur_id];
552
- delete WPGM_PathLine[cur_id];
553
- $("#wpgmza_polyline_holder").html(response);
554
-
555
- });
556
- }
557
-
558
- WPGMZA.MapEditPage.prototype.onDeleteHeatmap = function(event)
559
- {
560
- var cur_id = $(this).attr("id");
561
- var data = {
562
- action: 'delete_dataset',
563
- security: wpgmza_legacy_map_edit_page_vars.ajax_nonce,
564
- map_id: this.map.id,
565
- poly_id: cur_id
566
- };
567
-
568
- $.post(ajaxurl, data, function (response) {
569
-
570
- heatmap[cur_id].setMap(null);
571
- delete heatmap[cur_id];
572
- $("#wpgmza_heatmap_holder").html(response);
573
-
574
- });
575
- }
576
-
577
- WPGMZA.MapEditPage.prototype.onDeleteCircle = function(event)
578
- {
579
- var circle_id = $(this).attr("id");
580
-
581
- var data = {
582
- action: 'delete_circle',
583
- security: wpgmza_legacy_map_edit_page_vars.ajax_nonce,
584
- map_id: this.map.id,
585
- circle_id: circle_id
586
- };
587
-
588
- $.post(ajaxurl, data, function (response) {
589
-
590
- $("#tabs-m-5 table").replaceWith(response);
591
-
592
- circle_array.forEach(function (circle) {
593
-
594
- if (circle.id == circle_id) {
595
- circle.setMap(null);
596
- return false;
597
- }
598
-
599
- });
600
-
601
- });
602
- }
603
-
604
- WPGMZA.MapEditPage.prototype.onDeleteRectangle = function(event)
605
- {
606
- var rectangle_id = $(this).attr("id");
607
-
608
- var data = {
609
- action: 'delete_rectangle',
610
- security: wpgmza_legacy_map_edit_page_vars.ajax_nonce,
611
- map_id: this.map.id,
612
- rectangle_id: rectangle_id
613
- };
614
-
615
- $.post(ajaxurl, data, function (response) {
616
-
617
- $("#tabs-m-6 table").replaceWith(response);
618
-
619
- rectangle_array.forEach(function (rectangle) {
620
-
621
- if (rectangle.id == rectangle_id) {
622
- rectangle.setMap(null);
623
- return false;
624
- }
625
-
626
- });
627
-
628
- });
629
- }
630
-
631
- $(document).ready(function(event) {
632
-
633
- WPGMZA.mapEditPage = WPGMZA.MapEditPage.createInstance();
634
-
635
- });
636
-
637
  });
1
+ /**
2
+ * @namespace WPGMZA
3
+ * @module MapEditPage
4
+ * @requires WPGMZA.EventDispatcher
5
+ */
6
+
7
+ var wpgmza_autoCompleteDisabled = false;
8
+
9
+ jQuery(function($) {
10
+
11
+ if(WPGMZA.currentPage != "map-edit")
12
+ return;
13
+
14
+ WPGMZA.MapEditPage = function()
15
+ {
16
+ var self = this;
17
+ var element = document.body;
18
+
19
+ WPGMZA.EventDispatcher.call(this);
20
+
21
+ $("#wpgmaps_options fieldset").wrapInner("<div class='wpgmza-flex'></div>");
22
+
23
+ this.themePanel = new WPGMZA.ThemePanel();
24
+ this.themeEditor = new WPGMZA.ThemeEditor();
25
+
26
+ this.map = WPGMZA.maps[0];
27
+
28
+ // Drawing manager
29
+ if(!WPGMZA.pro_version || WPGMZA.Version.compare(WPGMZA.pro_version, '8.1.0') >= WPGMZA.Version.EQUAL_TO)
30
+ this.drawingManager = WPGMZA.DrawingManager.createInstance(this.map);
31
+
32
+ // UI
33
+ this.initDataTables();
34
+ this.initFeaturePanels();
35
+ this.initJQueryUIControls();
36
+
37
+ if(WPGMZA.locale !== 'en'){
38
+ $('#datatable_no_result_message,#datatable_search_string').parent().parent().hide();
39
+ }
40
+
41
+ // Address input
42
+ $("input.wpgmza-address").each(function(index, el) {
43
+ el.addressInput = WPGMZA.AddressInput.createInstance(el, self.map);
44
+ });
45
+
46
+ $('#wpgmza-map-edit-page input[type="color"]').each(function(){
47
+ $("<div class='button-secondary wpgmza-paste-color-btn' title='Paste a HEX color code'><i class='fa fa-clipboard' aria-hidden='true'></i></div>").insertAfter(this);
48
+ });
49
+
50
+
51
+ jQuery('body').on('click','.wpgmza_ac_result', function(e) {
52
+ var index = jQuery(this).data('id');
53
+ var lat = jQuery(this).data('lat');
54
+ var lng = jQuery(this).data('lng');
55
+ var name = jQuery('#wpgmza_item_address_'+index).html();
56
+
57
+
58
+ jQuery("input[name='lat']").val(lat);
59
+ jQuery("input[name='lng']").val(lng);
60
+ jQuery("#wpgmza_add_address_map_editor").val(name);
61
+ jQuery('#wpgmza_autocomplete_search_results').hide();
62
+ });
63
+
64
+ jQuery('body').on('click', '.wpgmza-paste-color-btn', function(){
65
+ try{
66
+ var colorBtn = $(this);
67
+ if(!navigator || !navigator.clipboard || !navigator.clipboard.readText){
68
+ return;
69
+ }
70
+
71
+ navigator.clipboard.readText()
72
+ .then(function(textcopy) {
73
+ colorBtn.parent().find('input[type="color"]').val("#" + textcopy.replace("#","").trim());
74
+ })
75
+ .catch(function(err) {
76
+ console.error("WP Google Maps: Could not access clipboard", err);
77
+ });
78
+
79
+ } catch(c_ex){
80
+
81
+ }
82
+ });
83
+
84
+ jQuery('body').on('focusout', '#wpgmza_add_address_map_editor', function(e) {
85
+ setTimeout(function() {
86
+ jQuery('#wpgmza_autocomplete_search_results').fadeOut('slow');
87
+ },500)
88
+
89
+ });
90
+
91
+ var ajaxRequest = false;
92
+ var wpgmzaAjaxTimeout = false;
93
+
94
+ var wpgmzaStartTyping = false;
95
+ var wpgmzaKeyStrokeCount = 1;
96
+ var wpgmzaAvgTimeBetweenStrokes = 300; //300 ms by default (equates to 40wpm which is the average typing speed of a person)
97
+ var wpgmzaTotalTimeForKeyStrokes = 0;
98
+ var wpgmzaTmp = '';
99
+ var wpgmzaIdentifiedTypingSpeed = false;
100
+
101
+ $('body').on('keypress', '.wpgmza-address', function(e) {
102
+
103
+ if (this.id == 'wpgmza_add_address_map_editor') {
104
+ if (wpgmza_autoCompleteDisabled) { return; }
105
+
106
+
107
+
108
+ // if user is using their own API key then use the normal Google AutoComplete
109
+ var wpgmza_apikey = false;
110
+ if (WPGMZA_localized_data.settings.googleMapsApiKey && WPGMZA_localized_data.settings.googleMapsApiKey !== '') {
111
+ wpgmza_apikey = WPGMZA_localized_data.settings.googleMapsApiKey;
112
+ return;
113
+ } else {
114
+
115
+ if(e.key === "Escape" || e.key === "Alt" || e.key === "Control" || e.key === "Option" || e.key === "Shift" || e.key === "ArrowLeft" || e.key === "ArrowRight" || e.key === "ArrowUp" || e.key === "ArrowDown") {
116
+ $('#wpgmza_autocomplete_search_results').hide();
117
+ return;
118
+ }
119
+
120
+ if (!wpgmzaIdentifiedTypingSpeed) {
121
+ //determine duration between key strokes to determine when we should send the request to the autocomplete server
122
+ //doing this avoids sending API calls for slow typers.
123
+ var d = new Date();
124
+
125
+
126
+ // set a timer to reset the delay counter
127
+ clearTimeout(wpgmzaTmp);
128
+ wpgmzaTmp = setTimeout(function(){
129
+ wpgmzaStartTyping = false;
130
+ wpgmzaAvgTimeBetweenStrokes = 300;
131
+ wpgmzaTotalTimeForKeyStrokes = 0;
132
+ },1500
133
+ ); // I'm pretty sure no one types one key stroke per 1.5 seconds. This should be safe.
134
+ if (!wpgmzaStartTyping) {
135
+ // first character press, set start time.
136
+
137
+ wpgmzaStartTyping = d.getTime();
138
+ wpgmzaKeyStrokeCount++;
139
+ } else {
140
+ if (wpgmzaKeyStrokeCount == 1) {
141
+ // do nothing because its the first key stroke
142
+ } else {
143
+
144
+
145
+ wpgmzaCurrentTimeBetweenStrokes = d.getTime() - wpgmzaStartTyping;
146
+ wpgmzaTotalTimeForKeyStrokes = wpgmzaTotalTimeForKeyStrokes + wpgmzaCurrentTimeBetweenStrokes;
147
+
148
+ wpgmzaAvgTimeBetweenStrokes = (wpgmzaTotalTimeForKeyStrokes / (wpgmzaKeyStrokeCount-1)); // we cannot count the first key as that was the starting point
149
+ wpgmzaStartTyping = d.getTime();
150
+
151
+ if (wpgmzaKeyStrokeCount >= 3) {
152
+ // we only need 3 keys to know how fast they type
153
+ wpgmzaIdentifiedTypingSpeed = (wpgmzaAvgTimeBetweenStrokes);
154
+
155
+
156
+ }
157
+ }
158
+ wpgmzaKeyStrokeCount++;
159
+
160
+
161
+
162
+ }
163
+ return;
164
+ }
165
+
166
+
167
+ // clear the previous timer
168
+ clearTimeout(wpgmzaAjaxTimeout);
169
+
170
+ $('#wpgmza_autocomplete_search_results').html('Searching...');
171
+ $('#wpgmza_autocomplete_search_results').show();
172
+
173
+
174
+
175
+
176
+ var currentSearch = jQuery(this).val();
177
+ if (currentSearch !== '') {
178
+
179
+ if(ajaxRequest !== false){
180
+ ajaxRequest.abort();
181
+ }
182
+
183
+ var domain = window.location.hostname;
184
+ if(domain === 'localhost'){
185
+ try{
186
+ var paths = window.location.pathname.match(/\/(.*?)\//);
187
+ if(paths && paths.length >= 2 && paths[1]){
188
+ var path = paths[1];
189
+ domain += "-" + path
190
+ }
191
+ } catch (ex){
192
+ /* Leave it alone */
193
+ }
194
+ }
195
+
196
+ var wpgmza_api_url = '';
197
+ if (!wpgmza_apikey) {
198
+ wpgmza_api_url = "https://wpgmaps.us-3.evennode.com/api/v1/autocomplete?s="+currentSearch+"&d="+domain+"&hash="+WPGMZA_localized_data.siteHash
199
+ } else {
200
+ wpgmza_api_url = "https://wpgmaps.us-3.evennode.com/api/v1/autocomplete?s="+currentSearch+"&d="+domain+"&hash="+WPGMZA_localized_data.siteHash+"&k="+wpgmza_apikey
201
+ }
202
+
203
+ if(WPGMZA && WPGMZA.settings && WPGMZA.settings.engine){
204
+ wpgmza_api_url += "&engine=" + WPGMZA.settings.engine;
205
+ }
206
+
207
+ // set a timer of how fast the person types in seconds to only continue with this if it runs out
208
+ wpgmzaAjaxTimeout = setTimeout(function() {
209
+ ajaxRequest = $.ajax({
210
+ url: wpgmza_api_url,
211
+ type: 'GET',
212
+ dataType: 'json', // added data type
213
+ success: function(results) {
214
+
215
+ try {
216
+
217
+ if (typeof results.error !== 'undefined') {
218
+ if (results.error == 'error1') {
219
+ $('#wpgmza_autoc_disabled').html(WPGMZA.localized_strings.cloud_api_key_error_1);
220
+ $('#wpgmza_autoc_disabled').fadeIn('slow');
221
+ $('#wpgmza_autocomplete_search_results').hide();
222
+ wpgmza_autoCompleteDisabled = true;
223
+ } else {
224
+ console.error(results.error);
225
+ }
226
+
227
+ } else {
228
+ $('#wpgmza_autocomplete_search_results').html('');
229
+ var html = "";
230
+ for(var i in results){ html += "<div class='wpgmza_ac_result " + (html === "" ? "" : "border-top") + "' data-id='" + i + "' data-lat='"+results[i]['lat']+"' data-lng='"+results[i]['lng']+"'><div class='wpgmza_ac_container'><div class='wpgmza_ac_icon'><img src='"+results[i]['icon']+"' /></div><div class='wpgmza_ac_item'><span id='wpgmza_item_name_"+i+"' class='wpgmza_item_name'>" + results[i]['place_name'] + "</span><span id='wpgmza_item_address_"+i+"' class='wpgmza_item_address'>" + results[i]['formatted_address'] + "</span></div></div></div>"; }
231
+ if(html == ""){ html = "<div class='p-2 text-center'><small>No results found...</small></div>"; }
232
+ $('#wpgmza_autocomplete_search_results').html(html);
233
+ $('#wpgmza_autocomplete_search_results').show();
234
+
235
+ }
236
+ } catch (exception) {
237
+ console.error("WP Google Maps Plugin: There was an error returning the list of places for your search");
238
+ }
239
+
240
+
241
+
242
+ }
243
+ });
244
+ },(wpgmzaIdentifiedTypingSpeed*2));
245
+
246
+
247
+
248
+
249
+ } else {
250
+ $('#wpgmza_autocomplete_search_results').hide();
251
+ }
252
+ }
253
+ }
254
+ });
255
+
256
+
257
+ // Map height change (for warning)
258
+ $("#wpgmza_map_height_type").on("change", function(event) {
259
+ self.onMapHeightTypeChange(event);
260
+ });
261
+
262
+ // Don't have instructions in advanced marker panel, it's confusing for debugging and unnecessary
263
+ $("#advanced-markers .wpgmza-feature-drawing-instructions").remove();
264
+
265
+ // Hide the auto search area maximum zoom - not available in Basic. Pro will take care of showing it when needed
266
+ $("[data-search-area='auto']").hide();
267
+
268
+ // Control listeners
269
+ $(document.body).on("click", "[data-wpgmza-admin-marker-datatable] input[name='mark']", function(event) {
270
+ self.onShiftClick(event);
271
+ });
272
+
273
+ $("#wpgmza_map_type").on("change", function(event) {
274
+ self.onMapTypeChanged(event);
275
+ });
276
+
277
+ $("body").on("click",".wpgmza_copy_shortcode", function() {
278
+ var $temp = jQuery('<input>');
279
+ var $tmp2 = jQuery('<span id="wpgmza_tmp" style="display:none; width:100%; text-align:center;">');
280
+ jQuery("body").append($temp);
281
+ $temp.val(jQuery(this).val()).select();
282
+ document.execCommand("copy");
283
+ $temp.remove();
284
+ WPGMZA.notification("Shortcode Copied");
285
+ });
286
+
287
+ this.on("markerupdated", function(event) {
288
+ self.onMarkerUpdated(event);
289
+ });
290
+
291
+ // NB: Older version of Pro (< 7.0.0 - pre-WPGMZA.Map) will have this.map as undefined. Only run this code if we have a WPGMZA.Map to work with.
292
+ if(this.map)
293
+ {
294
+ this.map.on("zoomchanged", function(event) {
295
+ self.onZoomChanged(event);
296
+ });
297
+
298
+ this.map.on("boundschanged", function(event) {
299
+ self.onBoundsChanged(event);
300
+ });
301
+
302
+ this.map.on("rightclick", function(event) {
303
+ self.onRightClick(event);
304
+ });
305
+ }
306
+
307
+ $(element).on("click", ".wpgmza_poly_del_btn", function(event) {
308
+ self.onDeletePolygon(event);
309
+ });
310
+
311
+ $(element).on("click", ".wpgmza_polyline_del_btn", function(event) {
312
+ self.onDeletePolyline(event);
313
+ });
314
+
315
+ $(element).on("click", ".wpgmza_dataset_del_btn", function(evevnt) {
316
+ self.onDeleteHeatmap(event);
317
+ });
318
+
319
+ $(element).on("click", ".wpgmza_circle_del_btn", function(event) {
320
+ self.onDeleteCircle(event);
321
+ });
322
+
323
+ $(element).on("click", ".wpgmza_rectangle_del_btn", function(event) {
324
+ self.onDeleteRectangle(event);
325
+ });
326
+
327
+ $(element).on("click", "#wpgmza-open-advanced-theme-data", function(event){
328
+ event.preventDefault();
329
+ $('.wpgmza_theme_data_container').toggleClass('wpgmza_hidden');
330
+ });
331
+ }
332
+
333
+ WPGMZA.extend(WPGMZA.MapEditPage, WPGMZA.EventDispatcher);
334
+
335
+ WPGMZA.MapEditPage.createInstance = function()
336
+ {
337
+ if(WPGMZA.isProVersion() && WPGMZA.Version.compare(WPGMZA.pro_version, "8.0.0") >= WPGMZA.Version.EQUAL_TO)
338
+ return new WPGMZA.ProMapEditPage();
339
+
340
+ return new WPGMZA.MapEditPage();
341
+ }
342
+
343
+ WPGMZA.MapEditPage.prototype.initDataTables = function()
344
+ {
345
+ var self = this;
346
+
347
+ $("[data-wpgmza-datatable][data-wpgmza-rest-api-route]").each(function(index, el) {
348
+
349
+ var featureType = $(el).attr("data-wpgmza-feature-type");
350
+
351
+ self[featureType + "AdminDataTable"] = new WPGMZA.AdminFeatureDataTable(el);
352
+
353
+ });
354
+ }
355
+
356
+ WPGMZA.MapEditPage.prototype.initFeaturePanels = function()
357
+ {
358
+ var self = this;
359
+
360
+ $(".wpgmza-feature-accordion[data-wpgmza-feature-type]").each(function(index, el) {
361
+
362
+ var featurePanelElement = $(el).find(".wpgmza-feature-panel-container > *");
363
+ var featureType = $(el).attr("data-wpgmza-feature-type");
364
+ var panelClassName = WPGMZA.capitalizeWords(featureType) + "Panel";
365
+ var module = WPGMZA[panelClassName];
366
+ var instance = module.createInstance(featurePanelElement, self);
367
+
368
+ self[featureType + "Panel"] = instance;
369
+
370
+ });
371
+ }
372
+
373
+ WPGMZA.MapEditPage.prototype.initJQueryUIControls = function()
374
+ {
375
+ var self = this;
376
+ var mapContainer;
377
+
378
+ // Now initialise tabs
379
+ $("#wpgmaps_tabs").tabs();
380
+
381
+ // NB: If the map container has a <ul> then this will break the tabs (this happens in OpenLayers). Temporarily detach the map to avoid this.
382
+ mapContainer = $("#wpgmza-map-container").detach();
383
+
384
+ $("#wpgmaps_tabs_markers").tabs();
385
+
386
+ // NB: Re-add the map container (see above)
387
+ $(".map_wrapper").prepend(mapContainer);
388
+
389
+ // And the zoom slider
390
+ $("#slider-range-max").slider({
391
+ range: "max",
392
+ min: 1,
393
+ max: 21,
394
+ value: $("input[name='map_start_zoom']").val(),
395
+ slide: function( event, ui ) {
396
+ $("input[name='map_start_zoom']").val(ui.value);
397
+ self.map.setZoom(ui.value);
398
+ }
399
+ });
400
+ }
401
+
402
+ WPGMZA.MapEditPage.prototype.onShiftClick = function(event)
403
+ {
404
+ var checkbox = event.currentTarget;
405
+ var row = jQuery(checkbox).closest("tr");
406
+
407
+ if(this.lastSelectedRow && event.shiftKey)
408
+ {
409
+ var prevIndex = this.lastSelectedRow.index();
410
+ var currIndex = row.index();
411
+ var startIndex = Math.min(prevIndex, currIndex);
412
+ var endIndex = Math.max(prevIndex, currIndex);
413
+ var rows = jQuery("[data-wpgmza-admin-marker-datatable] tbody>tr");
414
+
415
+ // Clear
416
+ jQuery("[data-wpgmza-admin-marker-datatable] input[name='mark']").prop("checked", false);
417
+
418
+ for(var i = startIndex; i <= endIndex; i++)
419
+ jQuery(rows[i]).find("input[name='mark']").prop("checked", true);
420
+
421
+
422
+
423
+ }
424
+
425
+ this.lastSelectedRow = row;
426
+ }
427
+
428
+ WPGMZA.MapEditPage.prototype.onMapTypeChanged = function(event)
429
+ {
430
+ if(WPGMZA.settings.engine == "open-layers")
431
+ return;
432
+
433
+ var mapTypeId;
434
+
435
+ switch(event.target.value)
436
+ {
437
+ case "2":
438
+ mapTypeId = google.maps.MapTypeId.SATELLITE;
439
+ break;
440
+
441
+ case "3":
442
+ mapTypeId = google.maps.MapTypeId.HYBRID;
443
+ break;
444
+
445
+ case "4":
446
+ mapTypeId = google.maps.MapTypeId.TERRAIN;
447
+ break;
448
+
449
+ default:
450
+ mapTypeId = google.maps.MapTypeId.ROADMAP;
451
+ break;
452
+ }
453
+
454
+ this.map.setOptions({
455
+ mapTypeId: mapTypeId
456
+ });
457
+ }
458
+
459
+ WPGMZA.MapEditPage.prototype.onMarkerUpdated = function(event)
460
+ {
461
+ this.markerDataTable.reload();
462
+ }
463
+
464
+ WPGMZA.MapEditPage.prototype.onZoomChanged = function(event) {
465
+ $(".map_start_zoom").val(this.map.getZoom());
466
+ }
467
+
468
+ WPGMZA.MapEditPage.prototype.onBoundsChanged = function(event)
469
+ {
470
+ var location = this.map.getCenter();
471
+
472
+ $("#wpgmza_start_location").val(location.lat + "," + location.lng);
473
+ $("input[name='map_start_lat']").val(location.lat);
474
+ $("input[name='map_start_lng']").val(location.lng);
475
+
476
+ $("#wpgmza_start_zoom").val(this.map.getZoom());
477
+
478
+ $("#wpgmaps_save_reminder").show();
479
+ }
480
+
481
+ WPGMZA.MapEditPage.prototype.onMapHeightTypeChange = function(event)
482
+ {
483
+ if(event.target.value == "%")
484
+ $("#wpgmza_height_warning").show();
485
+ }
486
+
487
+ WPGMZA.MapEditPage.prototype.onRightClick = function(event)
488
+ {
489
+ var self = this;
490
+ var marker;
491
+
492
+ if(this.drawingManager && this.drawingManager.mode != WPGMZA.DrawingManager.MODE_MARKER)
493
+ return; // Do nothing, not in marker mode
494
+
495
+ if(!this.rightClickMarker)
496
+ {
497
+ this.rightClickMarker = WPGMZA.Marker.createInstance({
498
+ draggable: true
499
+ });
500
+
501
+ this.rightClickMarker.on("dragend", function(event) {
502
+ $(".wpgmza-marker-panel [data-ajax-name='address']").val(event.latLng.lat + "," + event.latLng.lng);
503
+ });
504
+
505
+ this.map.on("click", function(event) {
506
+ self.rightClickMarker.setMap(null);
507
+ });
508
+ }
509
+
510
+ marker = this.rightClickMarker;
511
+
512
+ marker.setPosition(event.latLng);
513
+ marker.setMap(this.map);
514
+
515
+ $(".wpgmza-marker-panel [data-ajax-name='address']").val(event.latLng.lat+', '+event.latLng.lng);
516
+ }
517
+
518
+ WPGMZA.MapEditPage.prototype.onDeletePolygon = function(event)
519
+ {
520
+ var cur_id = parseInt($(this).attr("id"));
521
+ var data = {
522
+ action: 'delete_poly',
523
+ security: wpgmza_legacy_map_edit_page_vars.ajax_nonce,
524
+ map_id: this.map.id,
525
+ poly_id: cur_id
526
+ };
527
+
528
+ $.post(ajaxurl, data, function (response) {
529
+
530
+ WPGM_Path[cur_id].setMap(null);
531
+ delete WPGM_PathData[cur_id];
532
+ delete WPGM_Path[cur_id];
533
+ $("#wpgmza_poly_holder").html(response);
534
+
535
+ });
536
+ }
537
+
538
+ WPGMZA.MapEditPage.prototype.onDeletePolyline = function(event)
539
+ {
540
+ var cur_id = $(this).attr("id");
541
+ var data = {
542
+ action: 'delete_polyline',
543
+ security: wpgmza_legacy_map_edit_page_vars.ajax_nonce,
544
+ map_id: this.map.id,
545
+ poly_id: cur_id
546
+ };
547
+
548
+ $.post(ajaxurl, data, function (response) {
549
+
550
+ WPGM_PathLine[cur_id].setMap(null);
551
+ delete WPGM_PathLineData[cur_id];
552
+ delete WPGM_PathLine[cur_id];
553
+ $("#wpgmza_polyline_holder").html(response);
554
+
555
+ });
556
+ }
557
+
558
+ WPGMZA.MapEditPage.prototype.onDeleteHeatmap = function(event)
559
+ {
560
+ var cur_id = $(this).attr("id");
561
+ var data = {
562
+ action: 'delete_dataset',
563
+ security: wpgmza_legacy_map_edit_page_vars.ajax_nonce,
564
+ map_id: this.map.id,
565
+ poly_id: cur_id
566
+ };
567
+
568
+ $.post(ajaxurl, data, function (response) {
569
+
570
+ heatmap[cur_id].setMap(null);
571
+ delete heatmap[cur_id];
572
+ $("#wpgmza_heatmap_holder").html(response);
573
+
574
+ });
575
+ }
576
+
577
+ WPGMZA.MapEditPage.prototype.onDeleteCircle = function(event)
578
+ {
579
+ var circle_id = $(this).attr("id");
580
+
581
+ var data = {
582
+ action: 'delete_circle',
583
+ security: wpgmza_legacy_map_edit_page_vars.ajax_nonce,
584
+ map_id: this.map.id,
585
+ circle_id: circle_id
586
+ };
587
+
588
+ $.post(ajaxurl, data, function (response) {
589
+
590
+ $("#tabs-m-5 table").replaceWith(response);
591
+
592
+ circle_array.forEach(function (circle) {
593
+
594
+ if (circle.id == circle_id) {
595
+ circle.setMap(null);
596
+ return false;
597
+ }
598
+
599
+ });
600
+
601
+ });
602
+ }
603
+
604
+ WPGMZA.MapEditPage.prototype.onDeleteRectangle = function(event)
605
+ {
606
+ var rectangle_id = $(this).attr("id");
607
+
608
+ var data = {
609
+ action: 'delete_rectangle',
610
+ security: wpgmza_legacy_map_edit_page_vars.ajax_nonce,
611
+ map_id: this.map.id,
612
+ rectangle_id: rectangle_id
613
+ };
614
+
615
+ $.post(ajaxurl, data, function (response) {
616
+
617
+ $("#tabs-m-6 table").replaceWith(response);
618
+
619
+ rectangle_array.forEach(function (rectangle) {
620
+
621
+ if (rectangle.id == rectangle_id) {
622
+ rectangle.setMap(null);
623
+ return false;
624
+ }
625
+
626
+ });
627
+
628
+ });
629
+ }
630
+
631
+ $(document).ready(function(event) {
632
+
633
+ WPGMZA.mapEditPage = WPGMZA.MapEditPage.createInstance();
634
+
635
+ });
636
+
637
  });
js/v8/map-settings.js CHANGED
@@ -1,273 +1,273 @@
1
- /**
2
- * @namespace WPGMZA
3
- * @module MapSettings
4
- * @requires WPGMZA
5
- */
6
- jQuery(function($) {
7
-
8
- /**
9
- * Handles map settings, parsing them from the data-settings attribute on the maps HTML element.
10
- * NB: This will be split into GoogleMapSettings and OLMapSettings in the future.
11
- * @class WPGMZA.MapSettings
12
- * @constructor WPGMZA.MapSettings
13
- */
14
- WPGMZA.MapSettings = function(element)
15
- {
16
- var self = this;
17
- var str = element.getAttribute("data-settings");
18
- var json;
19
-
20
- try{
21
- json = JSON.parse(str);
22
- }catch(e) {
23
-
24
- str = str.replace(/\\%/g, "%");
25
- str = str.replace(/\\\\"/g, '\\"');
26
-
27
- try{
28
- json = JSON.parse(str);
29
- }catch(e) {
30
- json = {};
31
- console.warn("Failed to parse map settings JSON");
32
- }
33
-
34
- }
35
-
36
- WPGMZA.assertInstanceOf(this, "MapSettings");
37
-
38
-
39
-
40
- function addSettings(input) {
41
- if(!input)
42
- return;
43
-
44
- for(var key in input) {
45
- if(key == "other_settings")
46
- continue; // Ignore other_settings
47
-
48
- var value = input[key];
49
-
50
- if(String(value).match(/^-?\d+$/))
51
- value = parseInt(value);
52
-
53
- self[key] = value;
54
- }
55
- }
56
-
57
- addSettings(WPGMZA.settings);
58
-
59
- addSettings(json);
60
-
61
- if(json && json.other_settings)
62
- addSettings(json.other_settings);
63
-
64
- }
65
-
66
- /**
67
- * Returns settings on this object converted to OpenLayers view options
68
- * @method
69
- * @memberof WPGMZA.MapSettings
70
- * @return {object} The map settings, in a format understood by OpenLayers
71
- */
72
- WPGMZA.MapSettings.prototype.toOLViewOptions = function()
73
- {
74
- var self = this;
75
- var options = {
76
- center: ol.proj.fromLonLat([-119.4179, 36.7783]),
77
- zoom: 4
78
- };
79
-
80
- function empty(name)
81
- {
82
- if(typeof self[name] == "object")
83
- return false;
84
-
85
- return !self[name] || !self[name].length;
86
- }
87
-
88
- // Start location
89
- if(typeof this.start_location == "string")
90
- {
91
- var coords = this.start_location.replace(/^\(|\)$/g, "").split(",");
92
- if(WPGMZA.isLatLngString(this.start_location))
93
- options.center = ol.proj.fromLonLat([
94
- parseFloat(coords[1]),
95
- parseFloat(coords[0])
96
- ]);
97
- else
98
- console.warn("Invalid start location");
99
- }
100
-
101
- if(this.center)
102
- {
103
- options.center = ol.proj.fromLonLat([
104
- parseFloat(this.center.lng),
105
- parseFloat(this.center.lat)
106
- ]);
107
- }
108
-
109
- if(!empty("map_start_lat") && !empty("map_start_lng"))
110
- {
111
- options.center = ol.proj.fromLonLat([
112
- parseFloat(this.map_start_lng),
113
- parseFloat(this.map_start_lat)
114
- ]);
115
- }
116
-
117
- // Start zoom
118
- if(this.zoom){
119
- options.zoom = parseInt(this.zoom);
120
- }
121
-
122
- if(this.start_zoom){
123
- options.zoom = parseInt(this.start_zoom);
124
- }
125
-
126
- if(this.map_start_zoom){
127
- options.zoom = parseInt(this.map_start_zoom);
128
- }
129
-
130
- // Zoom limits
131
- // TODO: This matches the Google code, so some of these could be potentially put on a parent class
132
- if(this.map_min_zoom && this.map_max_zoom)
133
- {
134
- options.minZoom = Math.min(this.map_min_zoom, this.map_max_zoom);
135
- options.maxZoom = Math.max(this.map_min_zoom, this.map_max_zoom);
136
- }
137
-
138
- return options;
139
- }
140
-
141
- /**
142
- * Returns settings on this object converted to Google's MapOptions spec.
143
- * @method
144
- * @memberof WPGMZA.MapSettings
145
- * @return {object} The map settings, in the format specified by google.maps.MapOptions
146
- */
147
- WPGMZA.MapSettings.prototype.toGoogleMapsOptions = function()
148
- {
149
- var self = this;
150
- var latLngCoords = (this.start_location && this.start_location.length ? this.start_location.split(",") : [36.7783, -119.4179]);
151
-
152
- function empty(name)
153
- {
154
- if(typeof self[name] == "object")
155
- return false;
156
-
157
- return !self[name] || !self[name].length;
158
- }
159
-
160
- function formatCoord(coord)
161
- {
162
- if($.isNumeric(coord))
163
- return coord;
164
- return parseFloat( String(coord).replace(/[\(\)\s]/, "") );
165
- }
166
-
167
- var latLng = new google.maps.LatLng(
168
- formatCoord(latLngCoords[0]),
169
- formatCoord(latLngCoords[1])
170
- );
171
-
172
- var zoom = (this.start_zoom ? parseInt(this.start_zoom) : 4);
173
-
174
- if(!this.start_zoom && this.zoom){
175
- zoom = parseInt( this.zoom );
176
- }
177
-
178
- if(this.map_start_zoom){
179
- zoom = parseInt(this.map_start_zoom);
180
- }
181
-
182
- var options = {
183
- zoom: zoom,
184
- center: latLng
185
- };
186
-
187
- if(!empty("center"))
188
- options.center = new google.maps.LatLng({
189
- lat: parseFloat(this.center.lat),
190
- lng: parseFloat(this.center.lng)
191
- });
192
-
193
- if(!empty("map_start_lat") && !empty("map_start_lng"))
194
- {
195
- // NB: map_start_lat and map_start_lng are the "real" values. Not sure where start_location comes from
196
- options.center = new google.maps.LatLng({
197
- lat: parseFloat(this.map_start_lat),
198
- lng: parseFloat(this.map_start_lng)
199
- });
200
- }
201
-
202
- if(this.map_min_zoom && this.map_max_zoom)
203
- {
204
- options.minZoom = Math.min(this.map_min_zoom, this.map_max_zoom);
205
- options.maxZoom = Math.max(this.map_min_zoom, this.map_max_zoom);
206
- }
207
-
208
- // NB: Handles legacy checkboxes as well as new, standard controls
209
- function isSettingDisabled(value)
210
- {
211
- if(value === "yes")
212
- return true;
213
-
214
- return (value ? true : false);
215
- }
216
-
217
- // These settings are all inverted because the checkbox being set means "disabled"
218
- options.zoomControl = !isSettingDisabled(this.wpgmza_settings_map_zoom);
219
- options.panControl = !isSettingDisabled(this.wpgmza_settings_map_pan);
220
- options.mapTypeControl = !isSettingDisabled(this.wpgmza_settings_map_type);
221
- options.streetViewControl = !isSettingDisabled(this.wpgmza_settings_map_streetview);
222
- options.fullscreenControl = !isSettingDisabled(this.wpgmza_settings_map_full_screen_control);
223
-
224
- options.draggable = !isSettingDisabled(this.wpgmza_settings_map_draggable);
225
- options.disableDoubleClickZoom = isSettingDisabled(this.wpgmza_settings_map_clickzoom);
226
-
227
- if(isSettingDisabled(this.wpgmza_settings_map_tilt_controls)){
228
- options.rotateControl = false;
229
- options.tilt = 0;
230
- }
231
-
232
- // NB: This setting is handled differently as setting scrollwheel to true breaks gestureHandling
233
- if(this.wpgmza_settings_map_scroll)
234
- options.scrollwheel = false;
235
-
236
- if(this.wpgmza_force_greedy_gestures == "greedy"
237
- || this.wpgmza_force_greedy_gestures == "yes"
238
- || this.wpgmza_force_greedy_gestures == true)
239
- {
240
- options.gestureHandling = "greedy";
241
-
242
- // Setting this at all will break gesture handling. Make sure we delete it when using greedy gesture handling
243
- if(!this.wpgmza_settings_map_scroll && "scrollwheel" in options)
244
- delete options.scrollwheel;
245
- }
246
- else
247
- options.gestureHandling = "cooperative";
248
-
249
- switch(parseInt(this.type))
250
- {
251
- case 2:
252
- options.mapTypeId = google.maps.MapTypeId.SATELLITE;
253
- break;
254
-
255
- case 3:
256
- options.mapTypeId = google.maps.MapTypeId.HYBRID;
257
- break;
258
-
259
- case 4:
260
- options.mapTypeId = google.maps.MapTypeId.TERRAIN;
261
- break;
262
-
263
- default:
264
- options.mapTypeId = google.maps.MapTypeId.ROADMAP;
265
- break;
266
- }
267
-
268
- if(this.wpgmza_theme_data && this.wpgmza_theme_data.length)
269
- options.styles = WPGMZA.GoogleMap.parseThemeData(this.wpgmza_theme_data);
270
-
271
- return options;
272
- }
273
  });
1
+ /**
2
+ * @namespace WPGMZA
3
+ * @module MapSettings
4
+ * @requires WPGMZA
5
+ */
6
+ jQuery(function($) {
7
+
8
+ /**
9
+ * Handles map settings, parsing them from the data-settings attribute on the maps HTML element.
10
+ * NB: This will be split into GoogleMapSettings and OLMapSettings in the future.
11
+ * @class WPGMZA.MapSettings
12
+ * @constructor WPGMZA.MapSettings
13
+ */
14
+ WPGMZA.MapSettings = function(element)
15
+ {
16
+ var self = this;
17
+ var str = element.getAttribute("data-settings");
18
+ var json;
19
+
20
+ try{
21
+ json = JSON.parse(str);
22
+ }catch(e) {
23
+
24
+ str = str.replace(/\\%/g, "%");
25
+ str = str.replace(/\\\\"/g, '\\"');
26
+
27
+ try{
28
+ json = JSON.parse(str);
29
+ }catch(e) {
30
+ json = {};
31
+ console.warn("Failed to parse map settings JSON");
32
+ }
33
+
34
+ }
35
+
36
+ WPGMZA.assertInstanceOf(this, "MapSettings");
37
+
38
+
39
+
40
+ function addSettings(input) {
41
+ if(!input)
42
+ return;
43
+
44
+ for(var key in input) {
45
+ if(key == "other_settings")
46
+ continue; // Ignore other_settings
47
+
48
+ var value = input[key];
49
+
50
+ if(String(value).match(/^-?\d+$/))
51
+ value = parseInt(value);
52
+
53
+ self[key] = value;
54
+ }
55
+ }
56
+
57
+ addSettings(WPGMZA.settings);
58
+
59
+ addSettings(json);
60
+
61
+ if(json && json.other_settings)
62
+ addSettings(json.other_settings);
63
+
64
+ }
65
+
66
+ /**
67
+ * Returns settings on this object converted to OpenLayers view options
68
+ * @method
69
+ * @memberof WPGMZA.MapSettings
70
+ * @return {object} The map settings, in a format understood by OpenLayers
71
+ */
72
+ WPGMZA.MapSettings.prototype.toOLViewOptions = function()
73
+ {
74
+ var self = this;
75
+ var options = {
76
+ center: ol.proj.fromLonLat([-119.4179, 36.7783]),
77
+ zoom: 4
78
+ };
79
+
80
+ function empty(name)
81
+ {
82
+ if(typeof self[name] == "object")
83
+ return false;
84
+
85
+ return !self[name] || !self[name].length;
86
+ }
87
+
88
+ // Start location
89
+ if(typeof this.start_location == "string")
90
+ {
91
+ var coords = this.start_location.replace(/^\(|\)$/g, "").split(",");
92
+ if(WPGMZA.isLatLngString(this.start_location))
93
+ options.center = ol.proj.fromLonLat([
94
+ parseFloat(coords[1]),
95
+ parseFloat(coords[0])
96
+ ]);
97
+ else
98
+ console.warn("Invalid start location");
99
+ }
100
+
101
+ if(this.center)
102
+ {
103
+ options.center = ol.proj.fromLonLat([
104
+ parseFloat(this.center.lng),
105
+ parseFloat(this.center.lat)
106
+ ]);
107
+ }
108
+
109
+ if(!empty("map_start_lat") && !empty("map_start_lng"))
110
+ {
111
+ options.center = ol.proj.fromLonLat([
112
+ parseFloat(this.map_start_lng),
113
+ parseFloat(this.map_start_lat)
114
+ ]);
115
+ }
116
+
117
+ // Start zoom
118
+ if(this.zoom){
119
+ options.zoom = parseInt(this.zoom);
120
+ }
121
+
122
+ if(this.start_zoom){
123
+ options.zoom = parseInt(this.start_zoom);
124
+ }
125
+
126
+ if(this.map_start_zoom){
127
+ options.zoom = parseInt(this.map_start_zoom);
128
+ }
129
+
130
+ // Zoom limits
131
+ // TODO: This matches the Google code, so some of these could be potentially put on a parent class
132
+ if(this.map_min_zoom && this.map_max_zoom)
133
+ {
134
+ options.minZoom = Math.min(this.map_min_zoom, this.map_max_zoom);
135
+ options.maxZoom = Math.max(this.map_min_zoom, this.map_max_zoom);
136
+ }
137
+
138
+ return options;
139
+ }
140
+
141
+ /**
142
+ * Returns settings on this object converted to Google's MapOptions spec.
143
+ * @method
144
+ * @memberof WPGMZA.MapSettings
145
+ * @return {object} The map settings, in the format specified by google.maps.MapOptions
146
+ */
147
+ WPGMZA.MapSettings.prototype.toGoogleMapsOptions = function()
148
+ {
149
+ var self = this;
150
+ var latLngCoords = (this.start_location && this.start_location.length ? this.start_location.split(",") : [36.7783, -119.4179]);
151
+
152
+ function empty(name)
153
+ {
154
+ if(typeof self[name] == "object")
155
+ return false;
156
+
157
+ return !self[name] || !self[name].length;
158
+ }
159
+
160
+ function formatCoord(coord)
161
+ {
162
+ if($.isNumeric(coord))
163
+ return coord;
164
+ return parseFloat( String(coord).replace(/[\(\)\s]/, "") );
165
+ }
166
+
167
+ var latLng = new google.maps.LatLng(
168
+ formatCoord(latLngCoords[0]),
169
+ formatCoord(latLngCoords[1])
170
+ );
171
+
172
+ var zoom = (this.start_zoom ? parseInt(this.start_zoom) : 4);
173
+
174
+ if(!this.start_zoom && this.zoom){
175
+ zoom = parseInt( this.zoom );
176
+ }
177
+
178
+ if(this.map_start_zoom){
179
+ zoom = parseInt(this.map_start_zoom);
180
+ }
181
+
182
+ var options = {
183
+ zoom: zoom,
184
+ center: latLng
185
+ };
186
+
187
+ if(!empty("center"))
188
+ options.center = new google.maps.LatLng({
189
+ lat: parseFloat(this.center.lat),
190
+ lng: parseFloat(this.center.lng)
191
+ });
192
+
193
+ if(!empty("map_start_lat") && !empty("map_start_lng"))
194
+ {
195
+ // NB: map_start_lat and map_start_lng are the "real" values. Not sure where start_location comes from
196
+ options.center = new google.maps.LatLng({
197
+ lat: parseFloat(this.map_start_lat),
198
+ lng: parseFloat(this.map_start_lng)
199
+ });
200
+ }
201
+
202
+ if(this.map_min_zoom && this.map_max_zoom)
203
+ {
204
+ options.minZoom = Math.min(this.map_min_zoom, this.map_max_zoom);
205
+ options.maxZoom = Math.max(this.map_min_zoom, this.map_max_zoom);
206
+ }
207
+
208
+ // NB: Handles legacy checkboxes as well as new, standard controls
209
+ function isSettingDisabled(value)
210
+ {
211
+ if(value === "yes")
212
+ return true;
213
+
214
+ return (value ? true : false);
215
+ }
216
+
217
+ // These settings are all inverted because the checkbox being set means "disabled"
218
+ options.zoomControl = !isSettingDisabled(this.wpgmza_settings_map_zoom);
219
+ options.panControl = !isSettingDisabled(this.wpgmza_settings_map_pan);
220
+ options.mapTypeControl = !isSettingDisabled(this.wpgmza_settings_map_type);
221
+ options.streetViewControl = !isSettingDisabled(this.wpgmza_settings_map_streetview);
222
+ options.fullscreenControl = !isSettingDisabled(this.wpgmza_settings_map_full_screen_control);
223
+
224
+ options.draggable = !isSettingDisabled(this.wpgmza_settings_map_draggable);
225
+ options.disableDoubleClickZoom = isSettingDisabled(this.wpgmza_settings_map_clickzoom);
226
+
227
+ if(isSettingDisabled(this.wpgmza_settings_map_tilt_controls)){
228
+ options.rotateControl = false;
229
+ options.tilt = 0;
230
+ }
231
+
232
+ // NB: This setting is handled differently as setting scrollwheel to true breaks gestureHandling
233
+ if(this.wpgmza_settings_map_scroll)
234
+ options.scrollwheel = false;
235
+
236
+ if(this.wpgmza_force_greedy_gestures == "greedy"
237
+ || this.wpgmza_force_greedy_gestures == "yes"
238
+ || this.wpgmza_force_greedy_gestures == true)
239
+ {
240
+ options.gestureHandling = "greedy";
241
+
242
+ // Setting this at all will break gesture handling. Make sure we delete it when using greedy gesture handling
243
+ if(!this.wpgmza_settings_map_scroll && "scrollwheel" in options)
244
+ delete options.scrollwheel;
245
+ }
246
+ else
247
+ options.gestureHandling = "cooperative";
248
+
249
+ switch(parseInt(this.type))
250
+ {
251
+ case 2:
252
+ options.mapTypeId = google.maps.MapTypeId.SATELLITE;
253
+ break;
254
+
255
+ case 3:
256
+ options.mapTypeId = google.maps.MapTypeId.HYBRID;
257
+ break;
258
+
259
+ case 4:
260
+ options.mapTypeId = google.maps.MapTypeId.TERRAIN;
261
+ break;
262
+
263
+ default:
264
+ options.mapTypeId = google.maps.MapTypeId.ROADMAP;
265
+ break;
266
+ }
267
+
268
+ if(this.wpgmza_theme_data && this.wpgmza_theme_data.length)
269
+ options.styles = WPGMZA.GoogleMap.parseThemeData(this.wpgmza_theme_data);
270
+
271
+ return options;
272
+ }
273
  });
js/v8/map.js CHANGED
@@ -1,1531 +1,1531 @@
1
- /**
2
- * @namespace WPGMZA
3
- * @module Map
4
- * @requires WPGMZA.EventDispatcher
5
- */
6
- jQuery(function($) {
7
-
8
- /**
9
- * Base class for maps. <strong>Please <em>do not</em> call this constructor directly. Always use createInstance rather than instantiating this class directly.</strong> Using createInstance allows this class to be externally extensible.
10
- * @class WPGMZA.Map
11
- * @constructor WPGMZA.Map
12
- * @memberof WPGMZA
13
- * @param {HTMLElement} element to contain map
14
- * @param {object} [options] Options to apply to this map
15
- * @augments WPGMZA.EventDispatcher
16
- */
17
- WPGMZA.Map = function(element, options)
18
- {
19
- var self = this;
20
-
21
- WPGMZA.assertInstanceOf(this, "Map");
22
-
23
- WPGMZA.EventDispatcher.call(this);
24
-
25
- if(!(element instanceof HTMLElement)){
26
- if(!window.elementor){
27
- /**
28
- * Temporary Solution
29
- *
30
- * If elementor is active, it won't be an HTML Element just yet, due to preview block loading
31
- *
32
- * However, our timer initializer will load it later, so we just don't throw the error
33
- */
34
- throw new Error("Argument must be a HTMLElement");
35
- }
36
- }
37
-
38
- // NB: This should be moved to a getID function or similar and offloaded to Pro. ID should be fixed to 1 in basic.
39
- if(element.hasAttribute("data-map-id"))
40
- this.id = element.getAttribute("data-map-id");
41
- else
42
- this.id = 1;
43
-
44
- if(!/\d+/.test(this.id))
45
- throw new Error("Map ID must be an integer");
46
-
47
- WPGMZA.maps.push(this);
48
-
49
- this.element = element;
50
- this.element.wpgmzaMap = this;
51
- $(this.element).addClass("wpgmza-initialized");
52
-
53
- this.engineElement = element;
54
-
55
- this.markers = [];
56
- this.polygons = [];
57
- this.polylines = [];
58
- this.circles = [];
59
- this.rectangles = [];
60
-
61
- // GDPR
62
- if(WPGMZA.googleAPIStatus && WPGMZA.googleAPIStatus.code == "USER_CONSENT_NOT_GIVEN") {
63
- $(element).append($(WPGMZA.api_consent_html));
64
- $(element).css({height: "auto"});
65
- return;
66
- }
67
-
68
- this.loadSettings(options);
69
-
70
- this.shortcodeAttributes = {};
71
- if($(this.element).attr("data-shortcode-attributes")){
72
- try{
73
- this.shortcodeAttributes = JSON.parse($(this.element).attr("data-shortcode-attributes"));
74
- if(this.shortcodeAttributes.zoom){
75
- this.settings.map_start_zoom = parseInt(this.shortcodeAttributes.zoom);
76
- }
77
- }catch(e) {
78
- console.warn("Error parsing shortcode attributes");
79
- }
80
- }
81
-
82
- if(WPGMZA.getCurrentPage() != WPGMZA.PAGE_MAP_EDIT)
83
- this.initStoreLocator();
84
- this.setDimensions();
85
- this.setAlignment();
86
-
87
- // Init marker filter
88
- this.markerFilter = WPGMZA.MarkerFilter.createInstance(this);
89
-
90
- // Initialisation
91
- this.on("init", function(event) {
92
- self.onInit(event);
93
- });
94
-
95
- this.on("click", function(event){
96
- self.onClick(event);
97
- });
98
-
99
- // Legacy support
100
- if(WPGMZA.useLegacyGlobals)
101
- {
102
- // NB: this.id stuff should be moved to Map
103
- wpgmzaLegacyGlobals.MYMAP[this.id] = {
104
- map: null,
105
- bounds: null,
106
- mc: null
107
- };
108
-
109
- wpgmzaLegacyGlobals.MYMAP.init =
110
- wpgmzaLegacyGlobals.MYMAP[this.id].init =
111
- wpgmzaLegacyGlobals.MYMAP.placeMarkers =
112
- wpgmzaLegacyGlobals.MYMAP[this.id].placeMarkers =
113
- function() {
114
- console.warn("This function is deprecated and should no longer be used");
115
- }
116
- }
117
- }
118
-
119
- WPGMZA.Map.prototype = Object.create(WPGMZA.EventDispatcher.prototype);
120
- WPGMZA.Map.prototype.constructor = WPGMZA.Map;
121
- WPGMZA.Map.nightTimeThemeData = [{"elementType":"geometry","stylers":[{"color":"#242f3e"}]},{"elementType":"labels.text.fill","stylers":[{"color":"#746855"}]},{"elementType":"labels.text.stroke","stylers":[{"color":"#242f3e"}]},{"featureType":"administrative.locality","elementType":"labels.text.fill","stylers":[{"color":"#d59563"}]},{"featureType":"landscape","elementType":"geometry.fill","stylers":[{"color":"#575663"}]},{"featureType":"poi","elementType":"labels.text.fill","stylers":[{"color":"#d59563"}]},{"featureType":"poi.park","elementType":"geometry","stylers":[{"color":"#263c3f"}]},{"featureType":"poi.park","elementType":"labels.text.fill","stylers":[{"color":"#6b9a76"}]},{"featureType":"road","elementType":"geometry","stylers":[{"color":"#38414e"}]},{"featureType":"road","elementType":"geometry.stroke","stylers":[{"color":"#212a37"}]},{"featureType":"road","elementType":"labels.text.fill","stylers":[{"color":"#9ca5b3"}]},{"featureType":"road.highway","elementType":"geometry","stylers":[{"color":"#746855"}]},{"featureType":"road.highway","elementType":"geometry.fill","stylers":[{"color":"#80823e"}]},{"featureType":"road.highway","elementType":"geometry.stroke","stylers":[{"color":"#1f2835"}]},{"featureType":"road.highway","elementType":"labels.text.fill","stylers":[{"color":"#f3d19c"}]},{"featureType":"transit","elementType":"geometry","stylers":[{"color":"#2f3948"}]},{"featureType":"transit.station","elementType":"labels.text.fill","stylers":[{"color":"#d59563"}]},{"featureType":"water","elementType":"geometry","stylers":[{"color":"#17263c"}]},{"featureType":"water","elementType":"geometry.fill","stylers":[{"color":"#1b737a"}]},{"featureType":"water","elementType":"labels.text.fill","stylers":[{"color":"#515c6d"}]},{"featureType":"water","elementType":"labels.text.stroke","stylers":[{"color":"#17263c"}]}];
122
-
123
- /**
124
- * Returns the contructor to be used by createInstance, depending on the selected maps engine.
125
- * @method
126
- * @memberof WPGMZA.Map
127
- * @return {function} The appropriate contructor
128
- */
129
- WPGMZA.Map.getConstructor = function()
130
- {
131
- switch(WPGMZA.settings.engine)
132
- {
133
- case "open-layers":
134
- if(WPGMZA.isProVersion())
135
- return WPGMZA.OLProMap;
136
-
137
- return WPGMZA.OLMap;
138
- break;
139
-
140
- default:
141
- if(WPGMZA.isProVersion())
142
- return WPGMZA.GoogleProMap;
143
-
144
- return WPGMZA.GoogleMap;
145
- break;
146
- }
147
- }
148
-
149
- /**
150
- * Creates an instance of a map, <strong>please <em>always</em> use this function rather than calling the constructor directly</strong>.
151
- * @method
152
- * @memberof WPGMZA.Map
153
- * @param {HTMLElement} element to contain map
154
- * @param {object} [options] Options to apply to this map
155
- * @return {WPGMZA.Map} An instance of WPGMZA.Map
156
- */
157
- WPGMZA.Map.createInstance = function(element, options)
158
- {
159
- var constructor = WPGMZA.Map.getConstructor();
160
- return new constructor(element, options);
161
- }
162
-
163
- /**
164
- * Whether or not the markers have been placed yet
165
- *
166
- * @name WPGMZA.ProMap#markersPlaced
167
- * @type Boolean
168
- * @readonly
169
- */
170
- Object.defineProperty(WPGMZA.Map.prototype, "markersPlaced", {
171
-
172
- get: function() {
173
- return this._markersPlaced;
174
- },
175
-
176
- set: function(value) {
177
- throw new Error("Value is read only");
178
- }
179
-
180
- });
181
-
182
- /**
183
- * The maps current latitude
184
- *
185
- * @property lat
186
- * @memberof WPGMZA.Map
187
- * @name WPGMZA.Map#lat
188
- * @type Number
189
- */
190
- Object.defineProperty(WPGMZA.Map.prototype, "lat", {
191
-
192
- get: function() {
193
- return this.getCenter().lat;
194
- },
195
-
196
- set: function(value) {
197
- var center = this.getCenter();
198
- center.lat = value;
199
- this.setCenter(center);
200
- }
201
-
202
- });
203
-
204
- /**
205
- * The maps current longitude
206
- *
207
- * @property lng
208
- * @memberof WPGMZA.Map
209
- * @name WPGMZA.Map#lng
210
- * @type Number
211
- */
212
- Object.defineProperty(WPGMZA.Map.prototype, "lng", {
213
-
214
- get: function() {
215
- return this.getCenter().lng;
216
- },
217
-
218
- set: function(value) {
219
- var center = this.getCenter();
220
- center.lng = value;
221
- this.setCenter(center);
222
- }
223
-
224
- });
225
-
226
- /**
227
- * The maps current zoom level
228
- *
229
- * @property zoom
230
- * @memberof WPGMZA.Map
231
- * @name WPGMZA.Map#zoom
232
- * @type Number
233
- */
234
- Object.defineProperty(WPGMZA.Map.prototype, "zoom", {
235
-
236
- get: function() {
237
- return this.getZoom();
238
- },
239
-
240
- set: function(value) {
241
- this.setZoom(value);
242
- }
243
-
244
- });
245
-
246
- /**
247
- * Called by the engine specific map classes when the map has fully initialised
248
- * @method
249
- * @memberof WPGMZA.Map
250
- * @param {WPGMZA.Event} The event
251
- * @listens module:WPGMZA.Map~init
252
- */
253
- WPGMZA.Map.prototype.onInit = function(event)
254
- {
255
- var self = this;
256
-
257
- this.initPreloader();
258
-
259
- if(!("autoFetchFeatures" in this.settings) || (this.settings.autoFetchFeatures !== false))
260
- this.fetchFeatures();
261
- }
262
-
263
- /**
264
- * Initialises the preloader
265
- * @method
266
- * @memberof WPGMZA.Map
267
- * @protected
268
- */
269
- WPGMZA.Map.prototype.initPreloader = function()
270
- {
271
- this.preloader = $(WPGMZA.preloaderHTML);
272
-
273
- $(this.preloader).hide();
274
-
275
- $(this.element).append(this.preloader);
276
- }
277
-
278
- /**
279
- * Shows or hides the maps preloader
280
- * @method
281
- * @memberof WPGMZA.Map
282
- */
283
- WPGMZA.Map.prototype.showPreloader = function(show)
284
- {
285
- if(show)
286
- $(this.preloader).show();
287
- else
288
- $(this.preloader).hide();
289
- }
290
-
291
- /**
292
- * Loads the maps settings and sets some defaults
293
- * @method
294
- * @mem