PluginProbe
Maps Plugin using Google Maps for WordPress – WP Google Map / trunk
Maps Plugin using Google Maps for WordPress – WP Google Map vtrunk
1.9.7 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 All 96 releases
gmap-embed / includes / traits / MarkerCRUD.php

MarkerCRUD.php in Maps Plugin using Google Maps for WordPress – WP Google Map trunk, at includes/traits/MarkerCRUD.php

619 lines 23.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WGMSRM\Traits;
4
5 if (!defined('ABSPATH')) {
6 exit;
7 }
8
9 /**
10 * Trait MarkerCRUD: Map CRUD operation doing here
11 */
12 trait MarkerCRUD
13 {
14
15
16 /**
17 * Get Marker default values
18 *
19 * @return array
20 */
21 public function get_marker_default_values()
22 {
23 return array(
24 'map_id' => 0,
25 'marker_name' => null,
26 'marker_desc' => null,
27 'marker_image' => null,
28 'icon' => null,
29 'address' => null,
30 'lat_lng' => null,
31 'have_marker_link' => 0,
32 'marker_link' => null,
33 'marker_link_new_tab' => 0,
34 'animation' => null,
35 'category_id' => 0,
36 'show_desc_by_default' => 0,
37 'created_at' => current_time('mysql'),
38 'created_by' => get_current_user_id(),
39 'updated_at' => current_time('mysql'),
40 'updated_by' => get_current_user_id(),
41 );
42 }
43
44 /**
45 * To save new map marker
46 */
47 public function save_map_marker()
48 {
49
50 global $wpdb;
51
52
53 // Ensure POSTed marker data is present and properly unslashed; field-level sanitization is applied later.
54 $data = [];
55 if (isset($_POST['map_markers_data']) && is_array($_POST['map_markers_data'])) {
56 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- field-level sanitization is done below
57 $raw_data = $_POST['map_markers_data'];
58 $data = is_array($raw_data) ? wp_unslash($raw_data) : [];
59 }
60
61 $map_id = isset($data['wpgmap_map_id']) ? \intval(sanitize_text_field(wp_unslash($data['wpgmap_map_id']))) : 0;
62 $error = '';
63 $map_marker_data = [
64 'map_id' => $map_id,
65 'marker_name' => isset($data['wpgmap_marker_name']) && \strlen(sanitize_text_field(wp_unslash($data['wpgmap_marker_name']))) === 0 ? null : (isset($data['wpgmap_marker_name']) ? sanitize_text_field(wp_unslash($data['wpgmap_marker_name'])) : null),
66 'marker_desc' => isset($data['wpgmap_marker_desc']) ? wp_kses_post($data['wpgmap_marker_desc']) : '',
67 'marker_image' => isset($data['wpgmap_marker_image']) ? esc_url_raw(wp_unslash($data['wpgmap_marker_image'])) : '',
68 'icon' => isset($data['wpgmap_marker_icon']) ? esc_url_raw(wp_unslash($data['wpgmap_marker_icon'])) : '',
69 'address' => isset($data['wpgmap_marker_address']) ? sanitize_text_field(wp_unslash($data['wpgmap_marker_address'])) : '',
70 'lat_lng' => isset($data['wpgmap_marker_lat_lng']) ? sanitize_text_field(wp_unslash($data['wpgmap_marker_lat_lng'])) : '',
71 'have_marker_link' => isset($data['wpgmap_have_marker_link']) ? \intval($data['wpgmap_have_marker_link']) : 0,
72 'marker_link' => isset($data['wpgmap_marker_link']) ? esc_url_raw(wp_unslash($data['wpgmap_marker_link'])) : '',
73 'marker_link_new_tab' => isset($data['wpgmap_marker_link_new_tab']) ? \intval($data['wpgmap_marker_link_new_tab']) : 0,
74 'animation' => isset($data['wpgmap_marker_animation']) ? sanitize_text_field(wp_unslash($data['wpgmap_marker_animation'])) : '',
75 'category_id' => isset($data['wpgmap_marker_category']) ? (is_array($data['wpgmap_marker_category']) ? implode(',', array_map('intval', $data['wpgmap_marker_category'])) : \intval($data['wpgmap_marker_category'])) : '0',
76 'show_desc_by_default' => isset($data['wpgmap_marker_infowindow_show']) ? \intval($data['wpgmap_marker_infowindow_show']) : 0,
77 ];
78 if (empty($map_marker_data['lat_lng'])) {
79 $error = esc_html__('Please input Latitude and Longitude', 'gmap-embed');
80 }
81 if (\strlen($error) > 0) {
82 echo wp_json_encode(
83 [
84 'responseCode' => 0,
85 'message' => $error,
86 ]
87 );
88 wp_die();
89 }
90
91 if (!_wgm_is_premium()) {
92 $no_of_marker_already_have = $this->get_no_of_markers_by_map_id(\intval($map_id));
93 if ($no_of_marker_already_have > 0) {
94 echo wp_json_encode(
95 [
96 'responseCode' => 0,
97 'message' => esc_html__('Please upgrade to premium version to create unlimited markers', 'gmap-embed'),
98 ]
99 );
100 wp_die();
101 }
102 }
103
104 $defaults = $this->get_marker_default_values();
105 $wp_gmap_marker_data = wp_parse_args($map_marker_data, $defaults);
106 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
107 $wpdb->insert(
108 "{$wpdb->prefix}wgm_markers",
109 $wp_gmap_marker_data,
110 [
111 '%d', // map_id
112 '%s', // marker_name
113 '%s', // marker_desc
114 '%s', // marker_image
115 '%s', // icon
116 '%s', // address
117 '%s', // lat_lng
118 '%d', // have_marker_link
119 '%s', // marker_link
120 '%d', // marker_link_new_tab
121 '%s', // animation
122 '%s', // category_id
123 '%d', // show_desc_by_default
124 '%s', // created_at
125 '%d', // created_by
126 '%s', // updated_at
127 '%d', // updated_by
128 ]
129 ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
130
131 $return_array = [
132 'responseCode' => 1,
133 'marker_id' => \intval($wpdb->insert_id),
134 ];
135 $return_array['message'] = esc_html__('Marker Saved Successfully.', 'gmap-embed');
136 echo wp_json_encode($return_array);
137 wp_die();
138 }
139
140 /**
141 * To update existing marker information
142 */
143
144 public function update_map_marker()
145 {
146
147 global $wpdb;
148
149
150 $error = '';
151 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
152 $data = isset($_POST['map_markers_data']) && is_array($_POST['map_markers_data']) ? wp_unslash($_POST['map_markers_data']) : [];
153 $marker_id = isset($data['wpgmap_marker_id']) ? intval(sanitize_text_field(wp_unslash($data['wpgmap_marker_id']))) : 0;
154 $map_id = isset($data['wpgmap_map_id']) ? intval(sanitize_text_field(wp_unslash($data['wpgmap_map_id']))) : 0;
155 $map_marker_data = array(
156 'map_id' => $map_id,
157 'marker_name' => isset($data['wpgmap_marker_name']) && strlen(sanitize_text_field(wp_unslash($data['wpgmap_marker_name']))) === 0 ? null : (isset($data['wpgmap_marker_name']) ? sanitize_text_field(wp_unslash($data['wpgmap_marker_name'])) : null),
158 'marker_desc' => isset($data['wpgmap_marker_desc']) ? wp_kses_post($data['wpgmap_marker_desc']) : '',
159 'marker_image' => isset($data['wpgmap_marker_image']) ? esc_url_raw(wp_unslash($data['wpgmap_marker_image'])) : '',
160 'icon' => isset($data['wpgmap_marker_icon']) ? esc_url_raw(wp_unslash($data['wpgmap_marker_icon'])) : '',
161 'address' => isset($data['wpgmap_marker_address']) ? sanitize_text_field(wp_unslash($data['wpgmap_marker_address'])) : '',
162 'lat_lng' => isset($data['wpgmap_marker_lat_lng']) ? sanitize_text_field(wp_unslash($data['wpgmap_marker_lat_lng'])) : '',
163 'have_marker_link' => isset($data['wpgmap_have_marker_link']) ? intval($data['wpgmap_have_marker_link']) : 0,
164 'marker_link' => isset($data['wpgmap_marker_link']) ? esc_url_raw(wp_unslash($data['wpgmap_marker_link'])) : '',
165 'marker_link_new_tab' => isset($data['wpgmap_marker_link_new_tab']) ? intval($data['wpgmap_marker_link_new_tab']) : 0,
166 'animation' => isset($data['wpgmap_marker_animation']) ? sanitize_text_field(wp_unslash($data['wpgmap_marker_animation'])) : '',
167 'category_id' => isset($data['wpgmap_marker_category']) ? (is_array($data['wpgmap_marker_category']) ? implode(',', array_map('intval', $data['wpgmap_marker_category'])) : intval($data['wpgmap_marker_category'])) : '0',
168 'show_desc_by_default' => isset($data['wpgmap_marker_infowindow_show']) ? intval($data['wpgmap_marker_infowindow_show']) : 0,
169 );
170 if (empty($map_marker_data['lat_lng'])) {
171 $error = esc_html__('Please input Latitude and Longitude', 'gmap-embed');
172 }
173 if (strlen($error) > 0) {
174 echo wp_json_encode(
175 array(
176 'responseCode' => 0,
177 'message' => $error,
178 )
179 );
180 wp_die();
181 }
182
183 $defaults = $this->get_marker_default_values();
184 $wp_gmap_marker_data = wp_parse_args($map_marker_data, $defaults);
185
186 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
187 $wpdb->update(
188 $wpdb->prefix . 'wgm_markers',
189 $wp_gmap_marker_data,
190 array('id' => intval($marker_id)),
191 array(
192 '%d', // map_id
193 '%s', // marker_name
194 '%s', // marker_desc
195 '%s', // marker_image
196 '%s', // icon
197 '%s', // address
198 '%s', // lat_lng
199 '%d', // have_marker_link
200 '%s', // marker_link
201 '%d', // marker_link_new_tab
202 '%s', // animation
203 '%s', // category_id
204 '%d', // show_desc_by_default
205 '%s', // created_at
206 '%d', // created_by
207 '%s', // updated_at
208 '%d', // updated_by
209 ),
210 array('%d')
211 ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
212
213 $return_array = array(
214 'responseCode' => 1,
215 'marker_id' => intval($marker_id),
216 );
217 $return_array['message'] = esc_html__('Updated Successfully.', 'gmap-embed');
218 echo wp_json_encode($return_array);
219 wp_die();
220 }
221
222 /**
223 * Get all marker icons/pins
224 */
225 public function get_marker_icons()
226 {
227 // Nonce verification
228
229
230 ob_start();
231 require_once WGM_PLUGIN_PATH . 'admin/includes/markers-icons.php';
232 $output = ob_get_clean();
233 // Allow necessary HTML for the icon selector with search functionality
234 $allowed_html = array(
235 'style' => array(),
236 'ul' => array(
237 'class' => array(),
238 'id' => array(),
239 ),
240 'li' => array(
241 'class' => array(),
242 'id' => array(),
243 'style' => array(),
244 'data-*' => array(),
245 'data-icon-name' => array(),
246 ),
247 'img' => array(
248 'src' => array(),
249 'alt' => array(),
250 'class' => array(),
251 'style' => array(),
252 'onclick' => array(),
253 'width' => array(),
254 'height' => array(),
255 'id' => array(),
256 'title' => array(),
257 'data-*' => array(),
258 ),
259 'div' => array(
260 'class' => array(),
261 'id' => array(),
262 'style' => array(),
263 ),
264 'input' => array(
265 'type' => array(),
266 'id' => array(),
267 'class' => array(),
268 'placeholder' => array(),
269 'autocomplete' => array(),
270 'aria-label' => array(),
271 'value' => array(),
272 ),
273 'button' => array(
274 'type' => array(),
275 'class' => array(),
276 'id' => array(),
277 'aria-label' => array(),
278 ),
279 'span' => array(
280 'class' => array(),
281 'id' => array(),
282 'style' => array(),
283 ),
284 'a' => array(
285 'href' => array(),
286 'class' => array(),
287 'id' => array(),
288 'style' => array(),
289 'target' => array(),
290 'rel' => array(),
291 ),
292 );
293 echo wp_kses($output, $allowed_html);
294 wp_die();
295 }
296
297 /**
298 * Save Marker Icon
299 */
300 public function save_marker_icon()
301 {
302
303 global $wpdb;
304
305
306 $error = '';
307 $icon_url = isset($_POST['data']['icon_url']) ? esc_url_raw(wp_unslash($_POST['data']['icon_url'])) : '';
308 $map_icon_data = array(
309 'type' => 'uploaded_marker_icon',
310 'title' => '',
311 'desc' => '',
312 'file_name' => $icon_url,
313 );
314
315 $is_marker_icon_already_exist = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->prefix}wgm_icons WHERE file_name=%s", $icon_url)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
316 if ($is_marker_icon_already_exist == 0) {
317 $defaults = array(
318 'file_name' => '',
319 );
320 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
321 $wp_gmap_marker_icon = wp_parse_args($map_icon_data, $defaults);
322 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
323 $wpdb->insert(
324 $wpdb->prefix . 'wgm_icons',
325 $wp_gmap_marker_icon,
326 array(
327 '%s',
328 '%s',
329 '%s',
330 '%s',
331 )
332 ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
333 }
334
335 $return_array = array(
336 'responseCode' => 1,
337 'icon_url' => esc_url($icon_url),
338 );
339 $return_array['message'] = esc_html__('Updated Successfully.', 'gmap-embed');
340 echo wp_json_encode($return_array);
341 wp_die();
342 }
343
344 /**
345 * Get no of markers by map id
346 *
347 * @param $map_id int
348 *
349 * @retun int
350 */
351 public function get_no_of_markers_by_map_id($map_id = 0)
352 {
353 global $wpdb;
354 $map_id = intval($map_id);
355 return $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->prefix}wgm_markers WHERE map_id=%d", $map_id)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
356 }
357
358 /**
359 * Get all markers by map id
360 */
361 public function get_markers_by_map_id()
362 {
363
364 global $wpdb;
365
366
367 $map_id = isset($_POST['data']['map_id']) ? intval(sanitize_text_field(wp_unslash($_POST['data']['map_id']))) : 0;
368 $filtered_map_markers = array();
369
370 $orderby_field = get_post_meta($map_id, 'marker_orderby_field', true);
371 $orderby_dir = get_post_meta($map_id, 'marker_orderby_dir', true);
372
373 // Sanitize field name - only allow specific fields
374 $allowed_fields = ['id', 'marker_name', 'address', 'marker_desc', 'created_at', 'updated_at', 'lat_lng'];
375 if (!in_array($orderby_field, $allowed_fields)) {
376 $orderby_field = 'id';
377 }
378 // Sanitize direction
379 $orderby_dir = (strtoupper($orderby_dir) === 'DESC') ? 'DESC' : 'ASC';
380
381 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- ORDER BY is whitelisted above.
382 $map_markers = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wgm_markers WHERE map_id=%d ORDER BY {$orderby_field} {$orderby_dir}", $map_id));
383 if (count($map_markers) > 0) {
384 foreach ($map_markers as $key => $map_marker) {
385 $filtered_map_markers[$key] = $map_marker;
386 }
387 }
388 $return_array = array(
389 'responseCode' => 1,
390 'markers' => $filtered_map_markers,
391 );
392 $return_array['message'] = esc_html__('Markers fetched successfully.', 'gmap-embed');
393 echo wp_json_encode($return_array);
394 wp_die();
395 }
396
397 /**
398 * Public Get all markers by map id
399 */
400 public function p_get_markers_by_map_id()
401 {
402 global $wpdb;
403
404 $map_id = isset($_POST['data']['map_id']) ? intval(sanitize_text_field(wp_unslash($_POST['data']['map_id']))) : 0;
405 $nonce = isset($_POST['_wgm_p_nonce']) ? sanitize_text_field(wp_unslash($_POST['_wgm_p_nonce'])) : '';
406
407 /**
408 * Technical Solution for Cache Plugins (e.g. LiteSpeed):
409 *
410 * Nonces are incompatible with heavy caching because they expire while the page remains cached.
411 * For "Read" actions like fetching markers, we allow the request if:
412 * 1. A valid nonce is provided.
413 * 2. OR the Map ID corresponds to a valid 'wpgmapembed' post.
414 */
415 $is_valid_nonce = !empty($nonce) && wp_verify_nonce($nonce, 'wgm_marker_render');
416 $is_valid_map = ($map_id > 0 && get_post_type($map_id) === 'wpgmapembed');
417
418 if (!$is_valid_nonce && !$is_valid_map) {
419 $return_array = array(
420 'responseCode' => 0,
421 'message' => esc_html__('Invalid request or Map ID.', 'gmap-embed'),
422 );
423 echo wp_json_encode($return_array);
424 wp_die();
425 }
426
427 $filtered_map_markers = array();
428
429 $orderby_field = get_post_meta($map_id, 'marker_orderby_field', true);
430 $orderby_dir = get_post_meta($map_id, 'marker_orderby_dir', true);
431
432 // Sanitize field name - only allow specific fields
433 $allowed_fields = ['id', 'marker_name', 'address', 'marker_desc', 'created_at', 'updated_at', 'lat_lng'];
434 if (!in_array($orderby_field, $allowed_fields)) {
435 $orderby_field = 'id';
436 }
437 // Sanitize direction
438 $orderby_dir = (strtoupper($orderby_dir) === 'DESC') ? 'DESC' : 'ASC';
439
440 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- ORDER BY is whitelisted above.
441 $map_markers = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wgm_markers WHERE map_id=%d ORDER BY {$orderby_field} {$orderby_dir}", $map_id));
442 if (count($map_markers) > 0) {
443 foreach ($map_markers as $key => $map_marker) {
444 $filtered_map_markers[$key] = $map_marker;
445 }
446 }
447 $return_array = array(
448 'responseCode' => 1,
449 'markers' => $filtered_map_markers,
450 );
451 $return_array['message'] = esc_html__('Markers fetched successfully.', 'gmap-embed');
452 echo wp_json_encode($return_array);
453 wp_die();
454 }
455
456 /**
457 * Get markers by map id for datatable
458 */
459 public function wgm_get_markers_by_map_id_for_dt()
460 {
461
462
463 $map_id = isset($_GET['map_id']) ? intval(sanitize_text_field(wp_unslash($_GET['map_id']))) : 0;
464
465 $return_json = array();
466 global $wpdb;
467 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Direct query is required for custom table.
468 $wpgmap_markers = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wgm_markers WHERE map_id=%d", $map_id)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
469 if (count($wpgmap_markers) > 0) {
470 foreach ($wpgmap_markers as $marker_key => $wpgmap_marker) {
471 $clone_btn = _wgm_is_premium()
472 ? '<a href="" class="wpgmap_marker_clone button button-small" map_marker_id="' . esc_attr($wpgmap_marker->id) . '" title="' . esc_attr__('Clone Marker', 'gmap-embed') . '"><i class="fas fa-copy"></i></a>'
473 : '<a href="" class="wgm_enable_premium button button-small" style="opacity: 0.5;" title="' . esc_attr__('Clone Marker (Premium)', 'gmap-embed') . '" data-notice="' . esc_attr(sprintf(__('You need to upgrade to the <a target="_blank" href="%s">Premium</a> Version to <b>Clone Markers</b>.', 'gmap-embed'), esc_url('https://wpgooglemap.com/pricing?utm_source=gmap-embed&utm_medium=wordpress-plugin&utm_campaign=upgrade-to-pro&utm_content=marker-list-clone-lock'))) . '"><i class="fas fa-copy"></i></a>';
474 $action = '<a href="" class="wpgmap_marker_edit button button-small"
475 map_marker_id="' . esc_attr($wpgmap_marker->id) . '" title="' . esc_attr__('Edit Marker', 'gmap-embed') . '"><i class="fas fa-edit"></i></a>
476 <a href="" class="wpgmap_marker_view button button-small"
477 map_marker_id="' . esc_attr($wpgmap_marker->id) . '" title="' . esc_attr__('View on Map', 'gmap-embed') . '"><i class="fas fa-eye"></i></a>
478 ' . $clone_btn . '
479 <a href="" class="wpgmap_marker_trash button button-small"
480 map_marker_id="' . esc_attr($wpgmap_marker->id) . '" title="' . esc_attr__('Delete Marker', 'gmap-embed') . '"><i class="fas fa-trash"></i></a>';
481 $row = array(
482 'id' => intval($wpgmap_marker->id),
483 'marker_name' => esc_html($wpgmap_marker->marker_name),
484 //phpscs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage
485 'icon' => '<img src="' . esc_url($wpgmap_marker->icon) . '" width="20">',
486 'action' => $action,
487 );
488 $return_json[] = $row;
489 }
490 }
491 echo wp_json_encode(array('data' => $return_json));
492 wp_die();
493 }
494
495 /**
496 * Delete single marker
497 */
498 public function delete_marker()
499 {
500
501 global $wpdb;
502
503
504 $marker_id = isset($_POST['data']['marker_id']) ? intval(sanitize_text_field(wp_unslash($_POST['data']['marker_id']))) : 0;
505 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
506 $wpdb->delete(
507 $wpdb->prefix . 'wgm_markers',
508 array(
509 'id' => $marker_id,
510 ),
511 array(
512 '%d',
513 )
514 ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
515 }
516
517 /**
518 * Get marker single data by marker ID
519 */
520 public function get_marker_data_by_marker_id()
521 {
522
523 global $wpdb;
524
525
526 $marker_id = 0;
527 if (isset($_POST['data']['marker_id'])) {
528 $marker_id = intval(sanitize_text_field(wp_unslash($_POST['data']['marker_id'])));
529 }
530 $result = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wgm_markers WHERE id=%d", intval($marker_id)), OBJECT); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
531 if ($result) {
532 }
533 echo wp_json_encode($result);
534 wp_die();
535 }
536
537 function get_marker_data_by_map_id($map_id)
538 {
539 global $wpdb;
540 $map_id = intval($map_id);
541 $map_id = intval($map_id);
542 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
543 $markers = $wpdb->get_results(
544 $wpdb->prepare(
545 "SELECT id, map_id, marker_name, marker_desc, icon, address, lat_lng,
546 have_marker_link, marker_link, marker_link_new_tab, animation, category_id, show_desc_by_default
547 FROM {$wpdb->prefix}wgm_markers WHERE map_id = %d",
548 $map_id
549 ),
550 ARRAY_A
551 );
552 return $markers;
553 }
554
555 /**
556 * Clone a single marker. Pro feature — availability is also enforced
557 * server-side here in addition to the client-side lock, since this is
558 * invoked directly over AJAX.
559 *
560 * @since 1.9.7
561 */
562 public function clone_map_marker()
563 {
564 if (!_wgm_is_premium()) {
565 wp_send_json_error(array('message' => esc_html__('Cloning markers is a Premium feature. Please upgrade to unlock it.', 'gmap-embed')), 403);
566 }
567
568 $marker_id = isset($_POST['marker_id']) ? intval(sanitize_text_field(wp_unslash($_POST['marker_id']))) : 0;
569 if ($marker_id <= 0) {
570 wp_send_json_error(array('message' => esc_html__('Invalid marker ID.', 'gmap-embed')));
571 }
572
573 global $wpdb;
574 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
575 $marker = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wgm_markers WHERE id = %d", $marker_id), ARRAY_A);
576 if (!$marker) {
577 wp_send_json_error(array('message' => esc_html__('Marker not found.', 'gmap-embed')));
578 }
579
580 unset($marker['id']);
581 // A NULL text field (e.g. from a legacy/imported row) would otherwise be
582 // carried into the clone and break the marker-edit form (which expects
583 // strings, not null, for these inputs).
584 foreach (array('marker_desc', 'marker_image', 'address', 'marker_link', 'animation') as $text_field) {
585 if (!isset($marker[$text_field]) || is_null($marker[$text_field])) {
586 $marker[$text_field] = '';
587 }
588 }
589 $marker['marker_name'] = !empty($marker['marker_name'])
590 // translators: %s: original marker name.
591 ? sprintf(__('%s (Copy)', 'gmap-embed'), $marker['marker_name'])
592 : esc_html__('Marker (Copy)', 'gmap-embed');
593 $marker['created_at'] = current_time('mysql');
594 $marker['updated_at'] = current_time('mysql');
595 $marker['created_by'] = get_current_user_id();
596 $marker['updated_by'] = get_current_user_id();
597
598 $new_marker_data = wp_parse_args($marker, $this->get_marker_default_values());
599 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
600 $inserted = $wpdb->insert("{$wpdb->prefix}wgm_markers", $new_marker_data);
601
602 if (!$inserted) {
603 wp_send_json_error(array('message' => esc_html__('Failed to clone marker.', 'gmap-embed')));
604 }
605
606 $new_marker_id = intval($wpdb->insert_id);
607 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
608 $new_marker = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wgm_markers WHERE id = %d", $new_marker_id));
609
610 wp_send_json_success(
611 array(
612 'marker_id' => $new_marker_id,
613 'marker' => $new_marker,
614 'message' => esc_html__('Marker cloned successfully.', 'gmap-embed'),
615 )
616 );
617 }
618 }
619