PluginProbe
WP Directory Kit / 1.5.9
WP Directory Kit v1.5.9
1.5.9 1.5.7 1.5.6 1.5.5 1.5.4 1.5.3 trunk 1.1.0 1.1.6 1.1.8 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.8 All 37 releases
← All changes | application/helpers/Basic.php +2317 -227 1.1.8 → 1.5.9 View file →
@@ -3,9 +3,9 @@
3 3 if ( ! defined( 'ABSPATH' ) ) {
4 4 exit; // Exit if accessed directly.
5 5 }
6 6
7 -function wdk_generate_fields($fields, $db_data)
7 +function wdk_generate_fields($fields, $db_data, $form = NULL)
8 8 {
9 9 if(is_array($fields))
10 10 foreach($fields as $field)
11 11 {
@@ -20,9 +20,9 @@
20 20 include $field_view_path;
21 21 }
22 22 else
23 23 {
24 - echo __('Missing VIEW file: ', 'wpdirectorykit').esc_html($field_type).'.php';
24 + echo esc_html__('Missing VIEW file:', 'wpdirectorykit').' '.esc_html($field_type).'.php';
25 25 }
26 26 }
27 27 }
28 28
@@ -107,8 +107,18 @@
107 107 "suffix" => '',
108 108 "values_list" => '',
109 109 "placeholder" => '',
110 110 );
111 + }else if(function_exists('run_wdk_bookings') && $used_field->field_id == 'booking_guest') {
112 + $field = array(
113 + "idfield" => 'booking_guest',
114 + "field_type" => 'NUMBER',
115 + "field_label" => __('Booking Max Guests', 'wpdirectorykit'),
116 + "prefix" => '',
117 + "suffix" => '',
118 + "values_list" => '',
119 + "placeholder" => '',
120 + );
111 121 }else if($used_field->field_id == 'more') {
112 122 $field = array(
113 123 "idfield" => 'MORE',
114 124 "field_type" => 'MORE',
@@ -140,9 +150,10 @@
140 150 "field_label" =>wmvc_show_data('field_label', $field_data),
141 151 "prefix" => wmvc_show_data('prefix', $field_data),
142 152 "suffix" => wmvc_show_data('suffix', $field_data),
143 153 "values_list" => wmvc_show_data('values_list', $field_data),
144 - "placeholder" => wmvc_show_data('placeholder', $field_data)
154 + "placeholder" => wmvc_show_data('placeholder', $field_data),
155 + "is_select_2_ajax_field_db_suggestion" => wmvc_show_data('is_select_2_ajax_field_db_suggestion', $used_field),
145 156 );
146 157 }
147 158 }
148 159 }
@@ -173,14 +184,15 @@
173 184 else
174 185 {
175 186 /* show missing view file of field, only if print enable */
176 187 if($print)
177 - $output .= __('Missing VIEW file: ', 'wpdirectorykit').esc_html($subfolder).(wmvc_show_data('field_type', $field)).'.php';
188 + $output .= __('Missing VIEW file:', 'wpdirectorykit').' '.esc_html($subfolder).(wmvc_show_data('field_type', $field)).'.php';
178 189 }
179 190
180 191 }
181 192
182 193 if($print){
194 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.WP.I18n.NonSingularStringLiteralText
183 195 echo $output;
184 196 return FALSE;
185 197 }
186 198
@@ -187,8 +199,179 @@
187 199 return $output;
188 200 }
189 201 }
190 202
203 +if ( ! function_exists('wdk_generate_search_form_fields_elementor'))
204 +{
205 + function wdk_generate_search_form_fields_elementor($fields_array = array(), $subfolder='', $print = TRUE, $predefinedfields_query = array())
206 + {
207 + /* load WMVC data */
208 + $WMVC = &wdk_get_instance();
209 + $WMVC->model('searchform_m');
210 + $WMVC->model('field_m');
211 + $output = '';
212 +
213 + foreach ($fields_array as $key => $el_field_data) {
214 + $field_id = wmvc_show_data('field_id', $el_field_data, '');
215 + if(empty($field_id)) continue;
216 +
217 + if(strpos($field_id,'__') !== FALSE){
218 + $field_id = substr($field_id, strpos($field_id,'__')+2);
219 + }
220 +
221 + $field = NULL;
222 + if($field_id == 'category_id') {
223 + $field = array(
224 + "idfield" => 'category',
225 + "field_type" => 'CATEGORY',
226 + "field_label" => __('Category', 'wpdirectorykit'),
227 + "prefix" => '',
228 + "suffix" => '',
229 + "values_list" => '',
230 + "placeholder" => '',
231 + );
232 + }else if($field_id == 'location_id') {
233 + $field = array(
234 + "idfield" => 'location',
235 + "field_type" => 'LOCATION',
236 + "field_label" => __('Location', 'wpdirectorykit'),
237 + "prefix" => '',
238 + "suffix" => '',
239 + "values_list" => '',
240 + "placeholder" => '',
241 + );
242 + }else if($field_id == 'address') {
243 + $field = array(
244 + "idfield" => 'address',
245 + "field_type" => 'INPUTBOX',
246 + "field_label" => __('Address', 'wpdirectorykit'),
247 + "prefix" => '',
248 + "suffix" => '',
249 + "values_list" => '',
250 + "placeholder" => '',
251 + );
252 + }else if($field_id == 'post_title') {
253 + $field = array(
254 + "idfield" => 'post_title',
255 + "field_type" => 'INPUTBOX',
256 + "field_label" => __('Title', 'wpdirectorykit'),
257 + "prefix" => '',
258 + "suffix" => '',
259 + "values_list" => '',
260 + "placeholder" => '',
261 + );
262 + }else if($field_id == 'search') {
263 + $field = array(
264 + "idfield" => 'search',
265 + "field_type" => 'INPUTBOX',
266 + "field_label" => __('Search', 'wpdirectorykit'),
267 + "prefix" => '',
268 + "suffix" => '',
269 + "values_list" => '',
270 + "placeholder" => '',
271 + );
272 + }else if(function_exists('run_wdk_bookings') && $field_id == 'booking_date') {
273 + $field = array(
274 + "idfield" => 'booking_date',
275 + "field_type" => 'BOOKINGS_DATE',
276 + "field_label" => __('Booking Date', 'wpdirectorykit'),
277 + "prefix" => '',
278 + "suffix" => '',
279 + "values_list" => '',
280 + "placeholder" => '',
281 + );
282 + }else if($field_id == 'more') {
283 + $field = array(
284 + "idfield" => 'MORE',
285 + "field_type" => 'MORE',
286 + "field_label" => __('MORE', 'wpdirectorykit'),
287 + "prefix" => '',
288 + "suffix" => '',
289 + "values_list" => '',
290 + "placeholder" => '',
291 + );
292 + } else {
293 + $field_data = $WMVC->field_m->get_fields_data($field_id);
294 +
295 + if($field_data) {
296 + if(wmvc_show_data('search_type', $el_field_data, '') == 'slider_range') {
297 + $field = array(
298 + "idfield" => wmvc_show_data('idfield', $field_data),
299 + "field_type" => 'SLIDER_RANGE',
300 + "field_label" =>wmvc_show_data('field_label', $field_data),
301 + "prefix" => wmvc_show_data('prefix', $field_data),
302 + "suffix" => wmvc_show_data('suffix', $field_data),
303 + "value_min" => wmvc_show_data('value_min', $el_field_data),
304 + "value_max" => wmvc_show_data('value_max', $el_field_data),
305 + "values_list" => wmvc_show_data('values_list', $field_data),
306 + "placeholder" => wmvc_show_data('placeholder', $field_data)
307 + );
308 + } else {
309 + $field = array(
310 + "idfield" => wmvc_show_data('idfield', $field_data),
311 + "field_type" => wmvc_show_data('field_type', $field_data),
312 + "field_label" =>wmvc_show_data('field_label', $field_data),
313 + "prefix" => wmvc_show_data('prefix', $field_data),
314 + "suffix" => wmvc_show_data('suffix', $field_data),
315 + "values_list" => wmvc_show_data('values_list', $field_data),
316 + "placeholder" => wmvc_show_data('placeholder', $field_data)
317 + );
318 + }
319 + }
320 + }
321 +
322 + if(wmvc_show_data('field_placeholder', $el_field_data, false)) {
323 + $field['placeholder'] = wmvc_show_data('field_placeholder', $el_field_data, false);
324 + }
325 +
326 + if(wmvc_show_data('search_type_tree_hide', $el_field_data, false)) {
327 + $field['search_type_tree_hide'] = wmvc_show_data('search_type_tree_hide', $el_field_data, false);
328 + }
329 +
330 + /* if field not detected or remove from fields list, skip field in search */
331 + if(empty($field)) continue;
332 +
333 + /* add from user fields data */
334 + $field['field_id'] = wmvc_show_data('idfield', $field);
335 + $field['class'] = wmvc_show_data('field_css_class', $el_field_data);
336 + $field['query_type'] = wmvc_show_data('search_type', $el_field_data);
337 + $field['columns'] = wmvc_show_data('field_columns_number', $el_field_data);
338 +
339 +
340 + $field_data = array();
341 + $field_data ['field_data'] = $field;
342 + $field_data ['predefinedfields_query'] = $predefinedfields_query;
343 +
344 + if(in_array(wmvc_show_data('field_type', $field),array('SECTION'))) {
345 + continue;
346 + }
347 +
348 + $field_suffix = strtoupper(wmvc_show_data('search_type_tree', $el_field_data,''));
349 +
350 + $field_view_path = WPDIRECTORYKIT_PATH.'application/views/search_fields/'.$subfolder.(wmvc_show_data('field_type', $field)).$field_suffix.'.php';
351 + if(file_exists($field_view_path))
352 + {
353 + $output .= $WMVC->view('search_fields/'.$subfolder.(wmvc_show_data('field_type', $field)).$field_suffix, $field_data, FALSE);
354 + }
355 + else
356 + {
357 + /* show missing view file of field, only if print enable */
358 + if($print)
359 + $output .= __('Missing VIEW file:', 'wpdirectorykit').' '.esc_html($subfolder).(wmvc_show_data('field_type', $field)).$field_suffix.'.php';
360 + }
361 + }
362 +
363 + if($print){
364 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.WP.I18n.NonSingularStringLiteralText
365 + echo $output;
366 + return FALSE;
367 + }
368 +
369 + return $output;
370 + }
371 +}
372 +
373 +
191 374 function &wdk_get_instance()
192 375 {
193 376 global $Winter_MVC_WDK;
194 377
@@ -210,9 +393,10 @@
210 393 $wdk_bookings_joinded = false;
211 394 static $available_fields_listings = NULL;
212 395 static $available_fields_static = array();
213 396 static $list_fields_static = NULL;
214 -
397 + $fields_type = array();
398 +
215 399 /* add if missing columns */
216 400 if(!in_array('post_id', $columns)) {
217 401 $columns[] = $Winter_MVC_WDK->db->prefix.'wdk_listings.post_id';
218 402 }
@@ -224,14 +408,14 @@
224 408
225 409 if(isset($_GET_clone['order_by']) && $_GET_clone['order_by'] =='undefined') {
226 410 unset($_GET_clone['order_by']);
227 411 }
228 -
412 +
229 413 if(isset($custom_parameters['order_by'])) {
230 414
231 415 if(isset($_GET_clone['order_by']) && !empty($_GET_clone['order_by'])) {
232 - $_GET_clone['order_by'] = $custom_parameters['order_by'].', '.$_GET_clone['order_by'];
233 - } else {
416 + $_GET_clone['order_by'] = ((!empty($custom_parameters['order_by'])) ? $custom_parameters['order_by'].', ':'').sanitize_text_field($_GET_clone['order_by']);
417 + } elseif(!empty( $custom_parameters['order_by'])) {
234 418 $_GET_clone['order_by'] = $custom_parameters['order_by'];
235 419 }
236 420
237 421 unset($custom_parameters['order_by']);
@@ -246,12 +430,12 @@
246 430 $WMVC->model('listingfield_m');
247 431
248 432 $smart_search = '';
249 433 if(isset($_GET_clone['search']))
250 - $smart_search = sanitize_text_field($_GET_clone['search']);
434 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['search']));
251 435
252 436 if(isset($_GET_clone['field_search']))
253 - $smart_search = sanitize_text_field($_GET_clone['field_search']);
437 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['field_search']));
254 438
255 439 if(!isset($available_fields_static[$model_name]))
256 440 {
257 441 $available_fields = $WMVC->$model_name->get_available_fields();
@@ -284,8 +468,10 @@
284 468 foreach($list_fields as $field_data) {
285 469
286 470 $field_id = wmvc_show_data('idfield',$field_data);
287 471 $field_type = wmvc_show_data('field_type',$field_data);
472 +
473 + $fields_type[$field_id] = $field_type;
288 474 $column_name ='field_'.$field_id.'_'.$field_type;
289 475 if(!isset($available_fields_listings[$column_name])) continue;
290 476
291 477 if(isset($_GET_clone['field_'.$field_id])) {
@@ -303,9 +489,9 @@
303 489 if(isset($_GET_clone['field_'.$field_id.'_min'])) {
304 490 $_GET_clone['field_'.$field_id.'_'.$field_type.'_min'] = apply_filters( 'wdk-currency-conversion/convert/default_value',sanitize_text_field($_GET_clone['field_'.$field_id.'_min']), $field_id);
305 491 }
306 492 if(isset($_GET_clone['field_'.$field_id.'_exactly'])) {
307 - $_GET_clone['field_'.$field_id.'_'.$field_type.'_exactly'] = sanitize_text_field($_GET_clone['field_'.$field_id.'_exactly']);
493 + $_GET_clone['field_'.$field_id.'_'.$field_type.'_exactly'] = wdk_clean_mixed($_GET_clone['field_'.$field_id.'_exactly']);
308 494 }
309 495
310 496 $columns[] = $column_name;
311 497 $columns[] = $column_name.'_max';
@@ -360,13 +546,34 @@
360 546 }
361 547
362 548 if(isset($_GET_clone['field_post_id'])) {
363 549 $column_name ='ID_exactly';
364 - $_GET_clone[$column_name] = intval($_GET_clone['field_post_id']);
550 + $_GET_clone[$column_name] = sanitize_text_field($_GET_clone['field_post_id']);
365 551 $columns[] = $column_name;
366 552 $external_columns[] = $column_name;
367 553 }
368 554
555 + if(isset($_GET_clone['field_post_date'])) {
556 + $column_name ='post_DATE';
557 + $_GET_clone[$column_name] = ($_GET_clone['field_post_date']);
558 + $columns[] = $column_name;
559 + $external_columns[] = $column_name;
560 + }
561 +
562 + if(isset($_GET_clone['field_post_date_min'])) {
563 + $column_name ='post_DATE_min';
564 + $_GET_clone[$column_name] = ($_GET_clone['field_post_date_min']);
565 + $columns[] = $column_name;
566 + $external_columns[] = $column_name;
567 + }
568 +
569 + if(isset($_GET_clone['field_post_date_max'])) {
570 + $column_name ='post_DATE_max';
571 + $_GET_clone[$column_name] = ($_GET_clone['field_post_date_max']);
572 + $columns[] = $column_name;
573 + $external_columns[] = $column_name;
574 + }
575 +
369 576 if (function_exists('run_wdk_bookings') && isset($_GET_clone['field_booking_date_from'])) {
370 577 $column_name ='field_booking_date_from';
371 578 $_GET_clone[$column_name] = $_GET_clone['field_booking_date_from'];
372 579 $columns[] = $column_name;
@@ -379,8 +586,36 @@
379 586 $columns[] = $column_name;
380 587 $external_columns[] = $column_name;
381 588 }
382 589
590 + if (function_exists('run_wdk_bookings') && isset($_GET_clone['field_booking_guest'])) {
591 + $column_name ='field_booking_guest';
592 + $_GET_clone[$column_name] = $_GET_clone['field_booking_guest'];
593 + $columns[] = $column_name;
594 + $external_columns[] = $column_name;
595 + }
596 +
597 + if (isset($_GET_clone['search_rank'])) {
598 + $column_name ='`rank`';
599 + $_GET_clone[$column_name] = $_GET_clone['search_rank'];
600 + $columns[] = $column_name;
601 + $external_columns[] = $column_name;
602 + }
603 +
604 + if (isset($_GET_clone['search_rank_min'])) {
605 + $column_name ='`rank`_min';
606 + $_GET_clone[$column_name] = $_GET_clone['search_rank_min'];
607 + $columns[] = $column_name;
608 + $external_columns[] = $column_name;
609 + }
610 +
611 + if (isset($_GET_clone['search_rank_max'])) {
612 + $column_name ='`rank`_max';
613 + $_GET_clone[$column_name] = $_GET_clone['search_rank_max'];
614 + $columns[] = $column_name;
615 + $external_columns[] = $column_name;
616 + }
617 +
383 618 //$table_name = substr($model_name, 0, -2);
384 619 $columns_original = array();
385 620 foreach($columns as $key=>$val)
386 621 {
@@ -408,8 +643,10 @@
408 643 {
409 644 unset($_GET_clone['search']);
410 645 unset($_GET_clone['field_search']);
411 646
647 + $WMVC->db->join($WMVC->listing_m->_table_name.' ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'posts'.'.ID', NULL, 'LEFT');
648 +
412 649 // For quick/smart search
413 650 if(wmvc_count($columns) > 0 && !empty($smart_search))
414 651 {
415 652 $gen_q = '';
@@ -415,9 +652,9 @@
415 652 $gen_q = '';
416 653 foreach($columns as $key=>$value)
417 654 {
418 655
419 - if($value == 'field_booking_date_from' || $value == 'field_booking_date_to' || $value == 'agents_ids' || $value == 'gps' || $value == 'is_featured') continue;
656 + if($value == 'field_booking_date_from' || $value == 'field_booking_date_to' || $value == 'agents_ids' || $value == 'gps' || $value == 'is_featured' || $value == 'field_booking_guest') continue;
420 657
421 658 if(strpos($value, '_CHECKBOX') !== FALSE) continue;
422 659
423 660 // if smart is number, search only im number fields
@@ -467,8 +704,13 @@
467 704 /* location / categories */
468 705 if(!is_intval($smart_search)) {
469 706 $gen_q.="location_title LIKE '%$smart_search%' OR ";
470 707 $gen_q.="category_title LIKE '%$smart_search%' OR ";
708 +
709 +
710 + $gen_q.="`category_table`.`titles_for_search` LIKE '%$smart_search%' OR ";
711 + $gen_q.="`location_table`.`titles_for_search` LIKE '%$smart_search%' OR ";
712 +
471 713 }
472 714 /* get address and gps */
473 715 if(strlen($smart_search) > 5) {
474 716 $coordinates_center = wdk_get_gps($smart_search);
@@ -524,9 +766,9 @@
524 766
525 767 if(!empty($gen_q))
526 768 $WMVC->db->where("($gen_q)");
527 769 }
528 -
770 +
529 771 // For column search
530 772 if(isset($_GET_clone))
531 773 {
532 774 $gen_q = '';
@@ -534,9 +776,9 @@
534 776 {
535 777 if(!empty($val) && in_array($key, $columns))
536 778 {
537 779 $col_name = $key;
538 -
780 +
539 781 $val = esc_sql($val);
540 782 //if(isset($key))
541 783 // $col_name = $key;
542 784
@@ -541,27 +783,31 @@
541 783 // $col_name = $key;
542 784
543 785 if(strpos($key, 'skip') !== FALSE) continue;
544 786
545 - if(function_exists('pll_current_language'))
787 + if($key == 'field_booking_guest')
546 788 {
547 - $lang_term_id = pll_current_language('term_id');
789 + if(!$wdk_bookings_joinded){
790 + $WMVC->db->join($WMVC->db->prefix.'wdk_booking_price ON '.$WMVC->db->prefix.'posts.ID = '.$WMVC->db->prefix.'wdk_booking_price.post_id', NULL, 'LEFT');
791 + $WMVC->db->distinct($WMVC->db->prefix.'posts.ID');
792 + $WMVC->db->join($WMVC->db->prefix.'wdk_booking_reservation ON '.$WMVC->db->prefix.'posts.ID = '.$WMVC->db->prefix.'wdk_booking_reservation.post_id', NULL, 'LEFT');
793 + $wdk_bookings_joinded = true;
794 + $gen_q.= $WMVC->db->prefix.'wdk_booking_price.is_activated = 1 AND ';
795 + $WMVC->db->join($WMVC->db->prefix.'wdk_booking_calendar ON '.$WMVC->db->prefix.'posts.ID = '.$WMVC->db->prefix.'wdk_booking_calendar.post_id', NULL, 'LEFT');
796 + }
548 797
549 - if(is_numeric($lang_term_id))
550 - {
551 - $WMVC->db->join($WMVC->db->prefix.'term_relationships ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'term_relationships.object_id', NULL, NULL);
552 - $WMVC->db->where("({$WMVC->db->prefix}term_relationships.term_taxonomy_id = $lang_term_id)");
553 - }
798 + $gen_q.= $WMVC->db->prefix."wdk_booking_calendar.guests >='".intval($val)."' AND ";
799 +
554 800 }
555 -
556 - if($key == 'field_booking_date_from')
801 + elseif($key == 'field_booking_date_from')
557 802 {
558 803 if(!$wdk_bookings_joinded){
559 - $WMVC->db->join($WMVC->db->prefix.'wdk_booking_price ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'wdk_booking_price.post_id', NULL, 'LEFT');
560 - $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
561 - $WMVC->db->join($WMVC->db->prefix.'wdk_booking_reservation ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'wdk_booking_price.post_id', NULL, 'LEFT');
804 + $WMVC->db->join($WMVC->db->prefix.'wdk_booking_price ON '.$WMVC->db->prefix.'posts.ID = '.$WMVC->db->prefix.'wdk_booking_price.post_id', NULL, 'LEFT');
805 + $WMVC->db->distinct($WMVC->db->prefix.'posts.ID');
806 + $WMVC->db->join($WMVC->db->prefix.'wdk_booking_reservation ON '.$WMVC->db->prefix.'posts.ID = '.$WMVC->db->prefix.'wdk_booking_reservation.post_id', NULL, 'LEFT');
562 807 $wdk_bookings_joinded = true;
563 808 $gen_q.= $WMVC->db->prefix.'wdk_booking_price.is_activated = 1 AND ';
809 + $WMVC->db->join($WMVC->db->prefix.'wdk_booking_calendar ON '.$WMVC->db->prefix.'posts.ID = '.$WMVC->db->prefix.'wdk_booking_calendar.post_id', NULL, 'LEFT');
564 810 }
565 811
566 812 if(wdk_is_date($val))
567 813 {
@@ -579,9 +825,9 @@
579 825 if(!get_option('wdk_bookings_is_hours_enabled')) {
580 826 $gen_search_from = wdk_normalize_date_db($_GET_clone['field_booking_date_from'], 'Y-m-d H:i:s', 'Y-m-d');
581 827 $gen_search_to = wdk_normalize_date_db($_GET_clone['field_booking_date_to'], 'Y-m-d H:i:s', 'Y-m-d');
582 828
583 - $gen_q.= $WMVC->listing_m->_table_name.".post_id NOT IN (
829 + $gen_q.= $WMVC->db->prefix."posts.ID NOT IN (
584 830 SELECT post_id
585 831 FROM ".$WMVC->db->prefix."wdk_booking_reservation
586 832 WHERE
587 833 ".$WMVC->db->prefix."wdk_booking_reservation.is_approved = 1
@@ -594,9 +840,9 @@
594 840 } else {
595 841 $gen_search_from = wdk_normalize_date_db($_GET_clone['field_booking_date_from']);
596 842 $gen_search_to = wdk_normalize_date_db($_GET_clone['field_booking_date_to']);
597 843
598 - $gen_q.= $WMVC->listing_m->_table_name.".post_id NOT IN (
844 + $gen_q.= $WMVC->db->prefix."posts.ID NOT IN (
599 845 SELECT post_id
600 846 FROM ".$WMVC->db->prefix."wdk_booking_reservation
601 847 WHERE
602 848 ".$WMVC->db->prefix."wdk_booking_reservation.is_approved = 1
@@ -611,12 +857,13 @@
611 857 }
612 858 elseif($key == 'field_booking_date_to')
613 859 {
614 860 if(!$wdk_bookings_joinded){
615 - $WMVC->db->join($WMVC->db->prefix.'wdk_booking_price ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'wdk_booking_price.post_id',NULL, 'LEFT');
616 - $WMVC->db->join($WMVC->db->prefix.'wdk_booking_reservation ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'wdk_booking_price.post_id',NULL, 'LEFT');
861 + $WMVC->db->join($WMVC->db->prefix.'wdk_booking_price ON '.$WMVC->db->prefix.'posts.ID = '.$WMVC->db->prefix.'wdk_booking_price.post_id',NULL, 'LEFT');
862 + $WMVC->db->join($WMVC->db->prefix.'wdk_booking_reservation ON '.$WMVC->db->prefix.'posts.ID = '.$WMVC->db->prefix.'wdk_booking_reservation.post_id',NULL, 'LEFT');
617 863 $wdk_bookings_joinded = true;
618 864 $gen_q.= $WMVC->db->prefix.'wdk_booking_price.is_activated = 1 AND ';
865 + $WMVC->db->join($WMVC->db->prefix.'wdk_booking_calendar ON '.$WMVC->db->prefix.'posts.ID = '.$WMVC->db->prefix.'wdk_booking_calendar.post_id', NULL, 'LEFT');
619 866 }
620 867
621 868 if(wdk_is_date($val))
622 869 {
@@ -632,9 +879,33 @@
632 879 }
633 880 elseif(substr($key, -8) == '_exactly')
634 881 {
635 882 $col_name = substr($key, 0, -8);
636 - $gen_q.=$col_name." = '".$val."' AND ";
883 +
884 + if(is_string($val) && strpos($val, ',') !== FALSE){
885 + $val =explode(',', $val);
886 + } elseif(is_string($val)){
887 + $val =array($val);
888 + }
889 +
890 + if(is_array($val))
891 + {
892 + $sql_search = '';
893 + foreach ($val as $v) {
894 + if(empty($v)) continue;
895 +
896 + if(!empty($sql_search))
897 + $sql_search .= " OR ";
898 +
899 + $sql_search .= " ".$col_name." = '".$v."' ";
900 + }
901 +
902 + if(!empty($sql_search))
903 + $gen_q.=" ( ".$sql_search." ) AND ";
904 + } else {
905 +
906 + $gen_q.=$col_name." = '".$val."' AND ";
907 + }
637 908 }
638 909 elseif(substr($key, -4) == '_max')
639 910 {
640 911 $col_name = substr($key, 0, -4);
@@ -643,10 +914,10 @@
643 914 $gen_q.=$col_name." <= ".intval($val)." AND ";
644 915 } else if(strpos($key, 'DATE') !== FALSE) {
645 916 if(wdk_is_date($val))
646 917 {
647 - $gen_search = wdk_normalize_date_db($val, 'Y-m-d H:i:s', 'Y-m-d');
648 - $gen_q.=$col_name." >= ".$gen_search." AND ";
918 + $gen_search = wdk_normalize_date_db($val, 'Y-m-d H:i:s', 'Y-m-d H:i:s');
919 + $gen_q.=$col_name." <= '".$gen_search."' AND ";
649 920 }
650 921 } else {
651 922 $gen_q.=$col_name." <= '".$val."' AND ";
652 923 }
@@ -653,16 +924,16 @@
653 924 }
654 925 else if(substr($key, -4) == '_min')
655 926 {
656 927 $col_name = substr($key, 0, -4);
657 -
928 +
658 929 if(strpos($key, 'NUMBER') !== FALSE) {
659 930 $gen_q.=$col_name." >= ".intval($val)." AND ";
660 931 } else if(strpos($key, 'DATE') !== FALSE) {
661 932 if(wdk_is_date($val))
662 933 {
663 - $gen_search = wdk_normalize_date_db($val, 'Y-m-d H:i:s', 'Y-m-d');
664 - $gen_q.=$col_name." >= ".$gen_search." AND ";
934 + $gen_search = wdk_normalize_date_db($val, 'Y-m-d H:i:s', 'Y-m-d H:i:s');
935 + $gen_q.=$col_name." >= '".$gen_search."' AND ";
665 936 }
666 937 } else {
667 938 $gen_q.=$col_name." >= '".$val."' AND ";
668 939 }
@@ -724,9 +995,9 @@
724 995 }
725 996
726 997 if(is_array($val)) {
727 998
728 - $WMVC->db->join($WMVC->db->prefix.'wdk_listings_users ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'wdk_listings_users.post_id', NULL, 'LEFT');
999 + $WMVC->db->join($WMVC->db->prefix.'wdk_listings_users ON '.$WMVC->db->prefix.'posts.ID = '.$WMVC->db->prefix.'wdk_listings_users.post_id', NULL, 'LEFT');
729 1000 $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
730 1001 $sql_search = '';
731 1002 foreach ($val as $v) {
732 1003 if(empty($v)) continue;
@@ -741,9 +1012,9 @@
741 1012 if(!empty($sql_search))
742 1013 $gen_q.=" ( ".$sql_search." ) AND ";
743 1014
744 1015 } elseif(is_string($val) && !empty($val)) {
745 - $WMVC->db->join($WMVC->db->prefix.'wdk_listings_users ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'wdk_listings_users.post_id', NULL, 'LEFT');
1016 + $WMVC->db->join($WMVC->db->prefix.'wdk_listings_users ON '.$WMVC->db->prefix.'posts.post_id = '.$WMVC->db->prefix.'wdk_listings_users.post_id', NULL, 'LEFT');
746 1017 $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
747 1018 $sql_search =" ".$WMVC->listing_m->_table_name.".`user_id_editor` = ".intval($val)." OR `".$WMVC->db->prefix."wdk_listings_users`.`user_id` = ".intval($val)." ";
748 1019 $gen_q.=" ( ".$sql_search." ) AND ";
749 1020 }
@@ -773,8 +1044,9 @@
773 1044 }
774 1045 }
775 1046 elseif($key == 'location_id')
776 1047 {
1048 + if(empty($val)) continue;
777 1049
778 1050 if(is_string($val) && strpos($val, ',') !== FALSE){
779 1051 $val =explode(',', $val);
780 1052 } elseif(is_string($val)){
@@ -789,10 +1061,10 @@
789 1061 }
790 1062
791 1063 $sql_search = '';
792 1064 foreach ($val as $v) {
793 - if(empty($v)) continue;
794 -
1065 + if(empty($v) || !is_intval($v)) continue;
1066 +
795 1067 if(!empty($sql_search))
796 1068 $sql_search .= " OR ";
797 1069
798 1070 $sql_search .= " ".$WMVC->listing_m->_table_name.".`location_id`=".intval($v)."";
@@ -797,8 +1069,10 @@
797 1069
798 1070 $sql_search .= " ".$WMVC->listing_m->_table_name.".`location_id`=".intval($v)."";
799 1071 $sql_search .= " OR `location_table`.`parent_id`=".intval($v)."";
800 1072
1073 + $sql_search .= " OR CONCAT(',', location_table.parent_path, ',') LIKE CONCAT('%,', ".intval($v).", ',%')";
1074 +
801 1075 /* other locations */
802 1076 /* multi select */
803 1077 if(false){
804 1078 $sql_search .= " OR `".$WMVC->db->prefix."wdk_listings`.`post_id` IN (SELECT `post_id` FROM `".$WMVC->db->prefix."wdk_listings_locations` WHERE `location_id` = ".intval($v).") ";
@@ -816,8 +1090,10 @@
816 1090 }
817 1091 elseif($key == 'category_id')
818 1092 {
819 1093
1094 + if(empty($val)) continue;
1095 +
820 1096 if(is_string($val) && strpos($val, ',') !== FALSE){
821 1097 $val =explode(',', $val);
822 1098 } elseif(is_string($val)){
823 1099 $val =array($val);
@@ -830,9 +1106,9 @@
830 1106 }
831 1107
832 1108 $sql_search = '';
833 1109 foreach ($val as $v) {
834 - if(empty($v)) continue;
1110 + if(empty($v) || !is_intval($v)) continue;
835 1111
836 1112 if(!empty($sql_search))
837 1113 $sql_search .= " OR ";
838 1114
@@ -837,9 +1113,10 @@
837 1113 $sql_search .= " OR ";
838 1114
839 1115 $sql_search .= " ".$WMVC->db->prefix."wdk_listings.`category_id` = ".intval($v)."";
840 1116 $sql_search .= " OR `category_table`.`parent_id`=".intval($v)."";
841 -
1117 + $sql_search .= " OR CONCAT(',', category_table.parent_path, ',') LIKE CONCAT('%,', ".intval($v).", ',%')";
1118 +
842 1119 /* other categories */
843 1120 if(false){
844 1121 $sql_search .= " OR `".$WMVC->db->prefix."wdk_listings`.`post_id` IN (SELECT `post_id` FROM `".$WMVC->db->prefix."wdk_listings_categories` WHERE `category_id` = ".intval($v).")";
845 1122 } elseif(false) {
@@ -894,10 +1171,15 @@
894 1171
895 1172 if(!empty($sql_search))
896 1173 $gen_q.=" ( ".$sql_search." ) AND ";
897 1174 }
1175 + } elseif ($val == 0) {
1176 + $col_name = $key;
1177 + $val = esc_sql($val);
1178 + if(in_array($col_name, ['`rank`'])) {
1179 + $gen_q.=" ( ".$col_name." = 0 OR ".$col_name." IS NULL ) AND ";
1180 + }
898 1181 }
899 -
900 1182 }
901 1183
902 1184 $gen_q = substr($gen_q, 0, -5);
903 1185
@@ -903,14 +1185,120 @@
903 1185
904 1186 if(!empty($gen_q))
905 1187 $WMVC->db->where("($gen_q)");
906 1188 }
1189 +
1190 + //if(defined( 'WP_DEBUG' ) && WP_DEBUG)
1191 + if(function_exists('pll_current_language'))
1192 + {
1193 + $lang_term_id = pll_current_language('term_id');
1194 +
1195 + if(is_numeric($lang_term_id))
1196 + {
1197 + $WMVC->db->join($WMVC->db->prefix.'term_relationships ON '.$WMVC->db->prefix.'posts.ID = '.$WMVC->db->prefix.'term_relationships.object_id', NULL, NULL);
1198 + $WMVC->db->where("({$WMVC->db->prefix}term_relationships.term_taxonomy_id = $lang_term_id)");
1199 + }
1200 + }
1201 +
1202 + // [RECTANGLE SEARCH]
1203 + if(isset($_GET_clone['rectangle_ne']) && isset($_GET_clone['rectangle_sw']))
1204 + {
1205 + if(wdk_is_gps($_GET_clone['rectangle_ne']) && wdk_is_gps($_GET_clone['rectangle_sw'])) {
1206 +
1207 + $gps_ne = explode(',', $_GET_clone['rectangle_ne']);
1208 + $gps_sw = explode(',', $_GET_clone['rectangle_sw']);
1209 +
1210 + $WMVC->db->where("(".$WMVC->db->prefix."wdk_listings.lat < '$gps_ne[0]' AND ".$WMVC->db->prefix."wdk_listings.lat > '$gps_sw[0]' AND
1211 + ".$WMVC->db->prefix."wdk_listings.lng > '$gps_ne[1]' AND ".$WMVC->db->prefix."wdk_listings.lng < '$gps_sw[1]')");
1212 + }
1213 + }
1214 + // [/RECTANGLE SEARCH]
907 1215
908 1216 // order
909 - if(isset($_GET_clone['order_by']))
910 - {
911 - $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_listings.post_id', $_GET_clone['order_by']);
912 - $WMVC->db->order_by($_GET_clone['order_by']);
1217 + if (isset($_GET_clone['order_by'])) {
1218 + // Merge available fields + system columns
1219 + $order_columns = [
1220 + 'post_id' => $WMVC->db->prefix . 'wdk_listings.post_id',
1221 + 'counter_views' => $WMVC->db->prefix . 'wdk_listings.counter_views',
1222 + 'date_modified' => $WMVC->db->prefix . 'wdk_listings.date_modified',
1223 + 'post_title' => $WMVC->db->prefix . 'posts.post_title',
1224 + 'address' => $WMVC->db->prefix . 'wdk_listings.address',
1225 + 'category_id' => $WMVC->db->prefix . 'wdk_listings.category_id',
1226 + 'location_id' => $WMVC->db->prefix . 'wdk_listings.location_id',
1227 + 'rank' => $WMVC->db->prefix . 'wdk_listings.rank'
1228 + ];
1229 +
1230 + $order_columns = apply_filters('wdk/listings/order_columns', $order_columns);
1231 +
1232 + $_GET_clone['order_by'] = str_replace(
1233 + 'post_id',
1234 + $WMVC->db->prefix . 'wdk_listings.post_id',
1235 + sanitize_text_field($_GET_clone['order_by'])
1236 + );
1237 +
1238 + // Fix common typos: ask → asc, desk → desc
1239 + $_GET_clone['order_by'] = str_ireplace([' ask', ' desk'], [' asc', ' desc'], $_GET_clone['order_by']);
1240 +
1241 + /* we no need field type in get link now */
1242 + $_GET_clone['order_by'] = str_ireplace(['_NUMBER', '_SECTION', '_TEXTAREA', '_DATE', '_DROPDOWN', '_DROPDOWNMULTIPLE', '_CHECKBOX'], '', $_GET_clone['order_by']);
1243 +
1244 + // Parse order_by string into parts
1245 + $order_by_array = explode(',', $_GET_clone['order_by']);
1246 + $final_order_by = [];
1247 +
1248 + foreach ($order_by_array as $order_part) {
1249 + $order_part = trim($order_part);
1250 +
1251 + // detect direction asc/desc
1252 + $direction = 'DESC';
1253 + if (stripos($order_part, ' asc') !== false) {
1254 + $direction = 'ASC';
1255 + } elseif (stripos($order_part, ' desc') !== false) {
1256 + $direction = 'DESC';
1257 + }
1258 +
1259 + $order_part = str_ireplace(['desc', 'asc'], '', $order_part);
1260 + $order_part = esc_sql(sanitize_textarea_field(str_replace(' ', '', $order_part)));
1261 +
1262 + // Try to detect field_(id)
1263 + if (preg_match('/field_(\d+)\b/', $order_part, $matches)) {
1264 +
1265 + $search_field_id = $matches[1];
1266 + if (!empty($fields_type[$search_field_id])) {
1267 + $field_name = "field_{$search_field_id}_{$fields_type[$search_field_id]}";
1268 +
1269 + // Check if field exists in order_columns
1270 + if (isset($available_fields_listings[$field_name])) {
1271 + $final_order_by[] = $field_name . ' ' . $direction;
1272 + }
1273 + }
1274 +
1275 + // else → skip invalid field automatically
1276 +
1277 + } else {
1278 + // Extract only the part after the last '.' if exists, else use entire string
1279 + $col_field = $order_part;
1280 + if (strpos($col_field, '.') !== false) {
1281 + $parts = explode('.', $col_field);
1282 + $col_field = end($parts);
1283 + }
1284 +
1285 + // Check if field exists in order_columns
1286 + if (isset($order_columns[$col_field])) {
1287 + $safe_column = $order_columns[$col_field];
1288 + $final_order_by[] = "$safe_column $direction";
1289 + }
1290 + }
1291 + }
1292 +
1293 + // Apply final order if any valid fields left
1294 + if (!empty($final_order_by)) {
1295 + $_GET_clone['order_by'] = implode(', ', $final_order_by);
1296 + $WMVC->db->order_by($_GET_clone['order_by']);
1297 + } else {
1298 + $WMVC->db->order_by('');
1299 + }
1300 +
913 1301 }
914 1302
915 1303 }
916 1304 }
@@ -927,9 +1315,9 @@
927 1315
928 1316 if(isset($custom_parameters['order_by'])) {
929 1317
930 1318 if(isset($_GET_clone['order_by']) && !empty($_GET_clone['order_by'])) {
931 - $_GET_clone['order_by'] = $custom_parameters['order_by'].', '.$_GET_clone['order_by'];
1319 + $_GET_clone['order_by'] = $custom_parameters['order_by'].', '.sanitize_text_field($_GET_clone['order_by']);
932 1320 } else {
933 1321 $_GET_clone['order_by'] = $custom_parameters['order_by'];
934 1322 }
935 1323
@@ -943,9 +1331,9 @@
943 1331 $WMVC->model($model_name);
944 1332
945 1333 $smart_search = '';
946 1334 if(isset($_GET_clone['profile_search']))
947 - $smart_search = sanitize_text_field($_GET_clone['profile_search']);
1335 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['profile_search']));
948 1336
949 1337 $available_fields = array('user_login','user_nicename','user_email','user_url','display_name');
950 1338
951 1339 if(isset($_GET_clone['is_activated'])){
@@ -1112,58 +1500,35 @@
1112 1500 // order
1113 1501 if(isset($_GET_clone['order_by']))
1114 1502 {
1115 1503 $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_favorite.post_id', $_GET_clone['order_by']);
1116 - $WMVC->db->order_by($_GET_clone['order_by']);
1504 + $WMVC->db->order_by(wdk_esc_sql(sanitize_text_field($_GET_clone['order_by'])));
1117 1505 }
1118 1506
1119 1507 }
1120 1508 }
1121 1509
1122 -function wdk_messages_prepare_search_query_GET($columns = array(), $model_name = NULL, $external_columns = array(), $custom_parameters = array(), $skip_postget = FALSE)
1510 +function wdk_messages_prepare_search_query_GET($columns = array(), $model_name = NULL, $external_columns = array())
1123 1511 {
1124 1512 global $Winter_MVC_WDK;
1125 1513 $WMVC = &$Winter_MVC_WDK;
1514 + $_GET_clone = array_merge($_GET, $_POST);
1515 +
1516 + $_GET_clone = ($_GET_clone);
1126 1517
1127 - $_GET_clone = array();
1128 -
1129 - if(!$skip_postget)
1130 - $_GET_clone = array_merge($_GET, $_POST);
1131 -
1132 - if(isset($custom_parameters['order_by'])) {
1133 -
1134 - if(isset($_GET_clone['order_by']) && !empty($_GET_clone['order_by'])) {
1135 - $_GET_clone['order_by'] = $custom_parameters['order_by'].', '.$_GET_clone['order_by'];
1136 - } else {
1137 - $_GET_clone['order_by'] = $custom_parameters['order_by'];
1138 - }
1139 -
1140 - unset($custom_parameters['order_by']);
1141 - }
1142 -
1143 -
1144 - if(!empty($custom_parameters))
1145 - $_GET_clone = array_merge($_GET_clone, $custom_parameters);
1146 -
1147 - $WMVC->model($model_name);
1518 + //$WMVC->model('listing_m');
1148 1519
1149 1520 $smart_search = '';
1150 - if(isset($_GET_clone['profile_search']))
1151 - $smart_search = sanitize_text_field($_GET_clone['profile_search']);
1521 + if(isset($_GET_clone['search']))
1522 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['search']));
1152 1523
1153 - $available_fields = array('user_login','user_nicename','user_email','user_url','display_name');
1524 + $available_fields = $WMVC->$model_name->get_available_fields();
1154 1525
1155 - if(isset($_GET_clone['is_activated'])){
1156 - $_GET_clone[$WMVC->$model_name->_table_name.'.is_activated'] = sanitize_text_field($_GET_clone['is_activated']);
1157 - unset($_GET_clone['is_activated']);
1158 - }
1526 + /* Пet column names from wdk_package and add to allow search +
1527 + in _GET_clone replace field_#id to field_id_TYPE*/
1528 + $list_fields = $WMVC->db->list_fields( $WMVC->db->prefix.'wdk_messages');
1159 1529
1160 - if(isset($_GET_clone['is_approved'])){
1161 - $_GET_clone[$WMVC->$model_name->_table_name.'.is_approved'] = sanitize_text_field($_GET_clone['is_approved']);
1162 - unset($_GET_clone['is_approved']);
1163 - }
1164 1530
1165 -
1166 1531 //$table_name = substr($model_name, 0, -2);
1167 1532 $columns_original = array();
1168 1533 foreach($columns as $key=>$val)
1169 1534 {
@@ -1196,14 +1561,8 @@
1196 1561 {
1197 1562 $gen_q = '';
1198 1563 foreach($columns as $key=>$value)
1199 1564 {
1200 -
1201 - if($value == 'post_type')
1202 - {
1203 - $value = $WMVC->$model_name->_table_name.'.'.$value;
1204 - }
1205 -
1206 1565 if(substr_count($value, 'id') > 0 && is_numeric($smart_search))
1207 1566 {
1208 1567 $gen_q.="$value = $smart_search OR ";
1209 1568 }
@@ -1235,14 +1594,8 @@
1235 1594 {
1236 1595 if(!empty($val) && in_array($key, $columns))
1237 1596 {
1238 1597 $col_name = $key;
1239 -
1240 - if($col_name == 'post_type')
1241 - {
1242 - $col_name = $WMVC->$model_name->_table_name.'.'.$col_name;
1243 - }
1244 -
1245 1598 //if(isset($key))
1246 1599 // $col_name = $key;
1247 1600
1248 1601 if(strpos($key, 'skip') !== FALSE) continue;
@@ -1274,12 +1627,13 @@
1274 1627 // DATE VALUES
1275 1628
1276 1629 $gen_search = $val;
1277 1630
1631 + $detect_date = strtotime($gen_search);
1278 1632
1279 - if(wdk_is_date($val))
1633 + if(wdk_payments_is_date($val) && $detect_date > 1000)
1280 1634 {
1281 - $gen_search = wdk_normalize_date_db($gen_search);
1635 + $gen_search = gmdate('Y-m-d H:i:s', $detect_date);
1282 1636 $gen_q.=$col_name." > '".$gen_search."' AND ";
1283 1637 }
1284 1638 else
1285 1639 {
@@ -1316,10 +1670,10 @@
1316 1670
1317 1671 // order
1318 1672 if(isset($_GET_clone['order_by']))
1319 1673 {
1320 - $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_favorite.post_id', $_GET_clone['order_by']);
1321 - $WMVC->db->order_by($_GET_clone['order_by']);
1674 + $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_messages.post_id', $_GET_clone['order_by']);
1675 + $WMVC->db->order_by(wdk_esc_sql(sanitize_text_field($_GET_clone['order_by']), true));
1322 1676 }
1323 1677
1324 1678 }
1325 1679 }
@@ -1326,9 +1680,9 @@
1326 1680
1327 1681 function wdk_date() {
1328 1682 $date_format = get_option('date_format');
1329 1683 $time_format = get_option('time_format');
1330 - $date = date("{$date_format} {$time_format}", current_time('timestamp'));
1684 + $date = gmdate("{$date_format} {$time_format}", current_time('timestamp'));
1331 1685 return $date;
1332 1686 }
1333 1687
1334 1688 if(!function_exists('wdk_placeholder_image_src')) {
@@ -1352,18 +1706,20 @@
1352 1706
1353 1707 if(isset($_GET[$page_var]))
1354 1708 $current_page = intval(wmvc_xss_clean($_GET[$page_var]));
1355 1709
1356 - if(!isset($texts['previous_page']))$texts['previous_page'] = 'Previous page';
1357 - if(!isset($texts['next_page']))$texts['next_page'] = 'Next page';
1710 + if(!isset($texts['previous_page']))$texts['previous_page'] = esc_html__('Previous page', 'wpdirectorykit');
1711 + if(!isset($texts['next_page']))$texts['next_page'] = esc_html__('Next page', 'wpdirectorykit');
1358 1712 if(!isset($texts['first_page']))$texts['first_page'] = '';
1359 1713 if(!isset($texts['last_page']))$texts['last_page'] = '';
1360 - if(!isset($texts['items']))$texts['items'] = 'items';
1714 + if(!isset($texts['items']))$texts['items'] = esc_html__('items', 'wpdirectorykit');
1361 1715
1362 1716 if(empty($current_page))$current_page = 1;
1363 1717
1364 1718 // get url
1365 - $url = strtok($_SERVER["REQUEST_URI"], '?');
1719 + $url = strtok(wdk_server_current_url(), '?');
1720 +
1721 +
1366 1722 $qs_parameters = wmvc_xss_clean( $_GET );
1367 1723 unset($qs_parameters[$page_var]);
1368 1724 $qs_part = http_build_query($qs_parameters);
1369 1725 $url = wdk_url_suffix($url, $qs_part);
@@ -1386,16 +1742,16 @@
1386 1742
1387 1743 $output .= '<div class="nav-links">';
1388 1744
1389 1745 if($enable_latest_first && $current_page-1 > 0)
1390 - $output.= '<a class="next page-numbers" href="'.esc_url($url).'#results"><span class="screen-reader-text">'.esc_html($texts['first_page']).'</span><span aria-hidden="true">«</span></a>';
1746 + $output.= '<a class="next page-numbers scroll-ignore" href="'.esc_url($url).'#results"><span class="screen-reader-text">'.esc_html($texts['first_page']).'</span><span aria-hidden="true">«</span></a>';
1391 1747
1392 1748 if ($current_page-1 > 0) {
1393 1749
1394 - $output.= '<a class="next page-numbers" href="'.esc_url(wdk_url_suffix($url,esc_attr($page_var).'='.esc_attr($current_page-1))).'#results"><span class="screen-reader-text">'.esc_html($texts['previous_page']).'</span><span aria-hidden="true">‹</span></a>';
1750 + $output.= '<a class="next page-numbers scroll-ignore" href="'.esc_url(wdk_url_suffix($url,esc_attr($page_var).'='.esc_attr($current_page-1))).'#results"><span class="screen-reader-text">'.esc_html($texts['previous_page']).'</span><span aria-hidden="true">‹</span></a>';
1395 1751 } elseif($enable_compact)
1396 1752 {
1397 - $output.= '<span class="next page-numbers disabled" href=""><span class="screen-reader-text">'.esc_html($texts['previous_page']).'</span><span aria-hidden="true">‹</span></span>';
1753 + $output.= '<span class="next page-numbers disabled " href=""><span class="screen-reader-text">'.esc_html($texts['previous_page']).'</span><span aria-hidden="true">‹</span></span>';
1398 1754 }
1399 1755
1400 1756 if (!$enable_compact) {
1401 1757 for ($i = 1 ; $i <= $total_pages; $i++) {
@@ -1403,9 +1759,9 @@
1403 1759 if(($current_page-$limit_items) <= $i && ($current_page+$limit_items) >= $i) {
1404 1760 if (($current_page == $i)) {
1405 1761 $output.= '<span aria-current="page" class="page-numbers current">'.$i.'</span>';
1406 1762 } else {
1407 - $output.= '<a class="page-numbers" href="'.esc_url(wdk_url_suffix($url, esc_attr($page_var).'='.esc_attr($i))).'#results">'.esc_attr($i).'</a>';
1763 + $output.= '<a class="page-numbers scroll-ignore" href="'.esc_url(wdk_url_suffix($url, esc_attr($page_var).'='.esc_attr($i))).'#results">'.esc_attr($i).'</a>';
1408 1764 }
1409 1765 }
1410 1766 }
1411 1767 } else {
@@ -1413,17 +1769,17 @@
1413 1769 }
1414 1770
1415 1771 if($current_page+1 <= $total_pages)
1416 1772 {
1417 - $output.= '<a class="next page-numbers" href="'.esc_url(wdk_url_suffix($url, esc_attr($page_var).'='.esc_attr($current_page+1))).'#results"><span class="screen-reader-text">'.esc_html($texts['next_page']).'</span><span aria-hidden="true">›</span></a>';
1773 + $output.= '<a class="next page-numbers scroll-ignore" href="'.esc_url(wdk_url_suffix($url, esc_attr($page_var).'='.esc_attr($current_page+1))).'#results"><span class="screen-reader-text">'.esc_html($texts['next_page']).'</span><span aria-hidden="true">›</span></a>';
1418 1774 }
1419 1775 elseif($enable_compact)
1420 1776 {
1421 - $output.= '<a class="next page-numbers disabled" href=""><span class="screen-reader-text">'.esc_html($texts['next_page']).'</span><span aria-hidden="true">›</span></a>';
1777 + $output.= '<a class="next page-numbers disabled scroll-ignore" href=""><span class="screen-reader-text">'.esc_html($texts['next_page']).'</span><span aria-hidden="true">›</span></a>';
1422 1778 }
1423 1779
1424 1780 if($enable_latest_first && $current_page+1 <= $total_pages)
1425 - $output.= '<a class="next page-numbers" href="'.esc_url(wdk_url_suffix($url, esc_attr($page_var).'='.esc_attr($total_pages))).'#results"><span class="screen-reader-text">'.esc_html($texts['last_page']).'</span><span aria-hidden="true">»</span></a>';
1781 + $output.= '<a class="next page-numbers scroll-ignore" href="'.esc_url(wdk_url_suffix($url, esc_attr($page_var).'='.esc_attr($total_pages))).'#results"><span class="screen-reader-text">'.esc_html($texts['last_page']).'</span><span aria-hidden="true">»</span></a>';
1426 1782
1427 1783
1428 1784 $output.= '</div>';
1429 1785 $output.= '</nav>';
@@ -1463,8 +1819,12 @@
1463 1819 global $wdk_text_search_button;
1464 1820 if(empty($wdk_text_search_button))
1465 1821 $wdk_text_search_button = esc_html__('Search','wpdirectorykit');
1466 1822
1823 + global $wdk_text_reset_button;
1824 + if(empty($wdk_text_reset_button))
1825 + $wdk_text_reset_button = esc_html__('Reset','wpdirectorykit');
1826 +
1467 1827 global $wdk_text_more_button;
1468 1828 if(empty($wdk_text_more_button))
1469 1829 $wdk_text_more_button = esc_html__('More','wpdirectorykit');
1470 1830
@@ -1474,18 +1834,27 @@
1474 1834 }
1475 1835
1476 1836 ?>
1477 1837 <div class="wdk-col wdk-col-btns">
1478 - <div class="wdk-field wdk-field-btn">
1838 + <div class="wdk-field wdk-field-btn">
1479 1839 <div class="wdk-field-group wdk-field-group-additional">
1480 1840 <button id="wdk-search-additional" type="button" class="wdk-search-additional-btn"><?php echo esc_html($wdk_text_more_button); ?><i class="wdk-toggle-icon"></i></button>
1481 - <input type='checkbox' style="display: none !important" value='1' name='wdk_search_additional_opened' />
1841 + <input type='checkbox' style="display: none !important" value='1' <?php if(isset($_GET['wdk_search_additional_opened']) && wmvc_xss_clean($_GET['wdk_search_additional_opened']) == 1):?> checked <?php endif;?> name='wdk_search_additional_opened' />
1482 1842 </div>
1843 + <div class="wdk-field-group wdk-field-group-reset">
1844 + <button title="<?php echo esc_attr__('Reset','wpdirectorykit');?>" id="wdk-reset-primary" type="reset" class="wdk-search-start wdk-search-reset wdk-click-load-animation"><?php echo esc_html($wdk_text_reset_button);?></button>
1845 + </div>
1846 + <?php if (function_exists('fpai_register_settings')):?>
1847 + <div class="wdk-field-group wdk-field-group-ai-search">
1848 + <button title="<?php echo esc_attr__('Ai Search','wpdirectorykit');?>" type="button" class="wdk-ai-search"><?php echo esc_html__('Ai Search','wpdirectorykit');?></button>
1849 + </div>
1850 + <?php endif;?>
1483 1851 <div class="wdk-field-group wdk-field-group-search">
1484 - <button id="wdk-start-primary" type="submit" class="wdk-search-start wdk-click-load-animation">&nbsp;&nbsp;<?php echo esc_html($wdk_text_search_button);?>&nbsp;<i class="fa fa-spinner fa-spin fa-ajax-indicator" style="display: none;"></i>&nbsp;</button>
1852 + <button title="<?php echo esc_attr__('Search','wpdirectorykit');?>" id="wdk-start-primary" type="submit" class="wdk-search-start wdk-click-load-animation">&nbsp;&nbsp;<?php echo esc_html($wdk_text_search_button);?>&nbsp;<i class="fa fa-spinner fa-spin fa-ajax-indicator" style="display: none;"></i>&nbsp;</button>
1853 +
1485 1854 <?php if(function_exists('run_wdk_save_search') && get_option('wdk_save_search_show_on_searchform')):?>
1486 1855 <div class="section-widget-control right">
1487 - <a class="wdk-c-btn wdk-c-edit wdk-save-search-button" href="#" data-url="<?php echo esc_url(admin_url('admin-ajax.php')); ?>" title="<?php echo esc_attr_e('Save Search', 'selio'); ?>" target="_blank">
1856 + <a class="wdk-c-btn wdk-c-edit wdk-save-search-button" href="#" data-url="<?php echo esc_url(admin_url('admin-ajax.php')); ?>" title="<?php echo esc_attr__('Save Search', 'wpdirectorykit'); ?>" target="_blank">
1488 1857 <i class="fas fa-save" aria-hidden="true"></i>
1489 1858 <i class="fa fa-spinner fa-spin fa-ajax-indicator"></i>
1490 1859 </a>
1491 1860 </div>
@@ -1490,8 +1859,9 @@
1490 1859 </a>
1491 1860 </div>
1492 1861 <?php endif;?>
1493 1862 </div>
1863 +
1494 1864 </div>
1495 1865 </div>
1496 1866 <div id='wdk-form-additional' class="wdk-col" style="<?php echo esc_attr($form_closed) ;?>">
1497 1867 <div class="wdk-row">
@@ -1507,9 +1877,9 @@
1507 1877 */
1508 1878 if ( ! function_exists('wdk_treefield_option'))
1509 1879 {
1510 1880 function wdk_treefield_option($name = '', $table=NULL, $selected = NULL,
1511 - $column = 'category_title', $language_id=NULL, $empty_value='', $filter_ids = '', $user_check = FALSE)
1881 + $column = 'category_title', $language_id=NULL, $empty_value='', $filter_ids = '', $user_check = FALSE, $sql_where='', $hide_fields = '')
1512 1882 {
1513 1883 $WMVC = &wdk_get_instance();
1514 1884
1515 1885 if(is_array($filter_ids)) $filter_ids = implode(',', $filter_ids);
@@ -1534,9 +1904,9 @@
1534 1904
1535 1905 if(empty($selected))
1536 1906 $selected='';
1537 1907
1538 - $form = '<input name="'.$name.'" value="'.$selected.'" class="wdk-hidden" type="text" id="wdktreeelem'.$counter.'" readonly/>';
1908 + $form = '<input name="'.esc_attr($name).'" value="'.esc_attr($selected).'" class="wdk-hidden" type="text" id="wdktreeelem'.esc_attr($counter).'" readonly/>';
1539 1909
1540 1910 $skip_id = '';
1541 1911 //load javascript library
1542 1912 if($counter==0)
@@ -1543,37 +1913,39 @@
1543 1913 {
1544 1914 wp_enqueue_script('wdk-treefield');
1545 1915 wp_enqueue_style('wdk-treefield');
1546 1916 }
1547 - ?>
1548 - <script>
1549 - jQuery(document).ready(function($) {
1550 - $('#wdktreeelem<?php echo esc_js($counter);?>:not(.init)').wdkTreefield({
1551 - ajax_url: '<?php echo admin_url('admin-ajax.php'); ?>',
1917 + wp_add_inline_script(
1918 + 'wdk-treefield',
1919 + "jQuery(document).ready(function($) {
1920 + $('#wdktreeelem" . esc_js($counter) . ":not(.init)').wdkTreefield({
1921 + ajax_url: '" . esc_js(admin_url('admin-ajax.php')) . "',
1552 1922 ajax_param: {
1553 - "page": 'wdk_frontendajax',
1554 - "function": 'treefieldid',
1555 - "action": 'wdk_public_action',
1556 - "table": '<?php echo esc_js($table); ?>',
1557 - "filter_ids": '<?php echo esc_js($filter_ids); ?>',
1558 - "start_id": '<?php if(!empty($filter_ids)) esc_js($selected); else echo ""; ?>',
1559 - "empty_value": '<?php echo esc_js($empty_value); ?>',
1560 - "user_check": '<?php echo esc_js($user_check); ?>'
1561 - },
1562 - attribute_id: '<?php echo esc_js($attribute_id); ?>',
1563 - language_id: '<?php echo esc_js($language_id); ?>',
1564 - attribute_value: '<?php echo esc_js($column); ?>',
1565 - skip_id: '<?php echo esc_js($skip_id); ?>',
1923 + page: 'wdk_frontendajax',
1924 + function: 'treefieldid',
1925 + action: 'wdk_public_action',
1926 + wdk_secure: '" . esc_js(wp_create_nonce('wdk_secure_treefieldid')) . "',
1927 + table: '" . esc_js($table) . "',
1928 + filter_ids: '" . esc_js($filter_ids) . "',
1929 + start_id: '" . (!empty($filter_ids) ? esc_js($selected) : "") . "',
1930 + empty_value: '" . esc_js($empty_value) . "',
1931 + user_check: '" . esc_js($user_check) . "',
1932 + sql_where: '" . esc_js($sql_where) . "',
1933 + hide_fields: '" . esc_js($hide_fields) . "'
1934 + },
1935 + attribute_id: '" . esc_js($attribute_id) . "',
1936 + language_id: '" . esc_js($language_id) . "',
1937 + attribute_value: '" . esc_js($column) . "',
1938 + skip_id: '',
1566 1939 empty_value: ' - ',
1567 - text_search: '<?php esc_html_e('Search term', 'wpdirectorykit');?>',
1568 - text_no_results: '<?php esc_html_e('No results found', 'wpdirectorykit');?>',
1940 + text_search: '" . esc_html__('Search term', 'wpdirectorykit') . "',
1941 + text_no_results: '" . esc_html__('No results found', 'wpdirectorykit') . "',
1569 1942 callback_selected: function(key) {
1570 - $('#wdktreeelem<?php echo esc_js($counter);?>').trigger("change");
1943 + $('#wdktreeelem" . esc_js($counter) . "').trigger('change');
1571 1944 }
1572 1945 }).addClass('init');
1573 - });
1574 - </script>
1575 - <?php
1946 + });"
1947 + );
1576 1948 $counter++;
1577 1949 return $form;
1578 1950 }
1579 1951 }
@@ -1584,9 +1956,9 @@
1584 1956 */
1585 1957 if ( ! function_exists('wdk_treefield_option_checkboxes'))
1586 1958 {
1587 1959 function wdk_treefield_option_checkboxes($name = '', $table=NULL, $selected = NULL,
1588 - $column = 'category_title', $language_id=NULL, $empty_value='', $filter_ids = '', $user_check = FALSE)
1960 + $column = 'category_title', $language_id=NULL, $empty_value='', $filter_ids = '', $user_check = FALSE, $sql_where='', $hide_fields = '')
1589 1961 {
1590 1962 $WMVC = &wdk_get_instance();
1591 1963
1592 1964 if(is_array($filter_ids)) $filter_ids = implode(',', $filter_ids);
@@ -1605,12 +1977,11 @@
1605 1977
1606 1978 $values = '';
1607 1979 if(!empty($selected)){
1608 1980 $ids = array();
1609 -
1610 1981 if(is_string($selected) && strpos($selected, ',') !== FALSE){
1611 1982 $val_selected = explode(',', $selected);
1612 - } elseif(is_string($selected)){
1983 + } elseif($selected){
1613 1984 $val_selected = array($selected);
1614 1985 }
1615 1986
1616 1987 foreach($val_selected as $selected_item) {
@@ -1642,9 +2013,9 @@
1642 2013 if(empty($values)) {
1643 2014 $values = $empty_value;
1644 2015 }
1645 2016
1646 - $form = '<input name="'.$name.'" value="'.esc_html($selected).'" data-placehoder="'.esc_html($values).'" class="wdk-hidden" type="text" id="wdktreeelem_checkbox'.$counter.'" readonly/>';
2017 + $form = '<input name="'.esc_attr($name).'" value="'.esc_html($selected).'" data-placehoder="'.esc_html($values).'" class="wdk-hidden" type="text" id="wdktreeelem_checkbox'.esc_attr($counter).'" readonly/>';
1647 2018
1648 2019 $skip_id = '';
1649 2020 //load javascript library
1650 2021 if($counter==0)
@@ -1655,17 +2026,19 @@
1655 2026 ?>
1656 2027 <script>
1657 2028 jQuery(document).ready(function($) {
1658 2029 $('#wdktreeelem_checkbox<?php echo esc_js($counter);?>:not(.init)').wdkTreefieldCheckboxes({
1659 - ajax_url: '<?php echo admin_url('admin-ajax.php'); ?>',
2030 + ajax_url: '<?php echo esc_url(admin_url('admin-ajax.php')); ?>',
1660 2031 ajax_param: {
1661 2032 "page": 'wdk_frontendajax',
1662 2033 "function": 'treefieldid_checkboxes',
1663 2034 "action": 'wdk_public_action',
2035 + "wdk_secure": '<?php echo esc_js(wp_create_nonce( 'wdk_secure_treefieldid_checkboxes' ));?>',
1664 2036 "table": '<?php echo esc_js($table); ?>',
1665 2037 "filter_ids": '<?php echo esc_js($filter_ids); ?>',
1666 2038 "empty_value": '<?php echo esc_js($empty_value); ?>',
1667 2039 "user_check": '<?php echo esc_js($user_check); ?>',
2040 + "hide_fields": '<?php echo esc_js($hide_fields); ?>',
1668 2041 },
1669 2042 selected: '<?php echo esc_js($selected); ?>',
1670 2043 attribute_id: '<?php echo esc_js($attribute_id); ?>',
1671 2044 language_id: '<?php echo esc_js($language_id); ?>',
@@ -1689,11 +2062,19 @@
1689 2062 if ( ! function_exists('wdk_filter_decimal'))
1690 2063 {
1691 2064 function wdk_filter_decimal($string = '')
1692 2065 {
1693 - if(substr($string, -3, 3) === ".00") {
1694 - return substr($string, 0, -3);
1695 - }
2066 + if(wdk_get_option('wdk_enable_filter_zero_decimal')) {
2067 + if(substr($string, -3, 3) === ",00") {
2068 + return substr($string, 0, -3);
2069 + }
2070 + if(substr($string, -3, 3) === ".00") {
2071 + return substr($string, 0, -3);
2072 + }
2073 + if(substr($string, -3, 1) === "." && substr($string, -1, 1) === "0") {
2074 + return substr($string, 0, -1);
2075 + }
2076 + }
1696 2077
1697 2078 return $string;
1698 2079 }
1699 2080 }
@@ -1771,12 +2152,8 @@
1771 2152 * @return string date in format Y-m-d H:i:s
1772 2153 */
1773 2154 function wdk_normalize_date_db($date, $format = 'Y-m-d H:i:s', $return_format = 'Y-m-d H:i:s')
1774 2155 {
1775 - /* check is date on strtotime */
1776 - if((bool)strtotime($date)){
1777 - return date($return_format, strtotime($date));
1778 - }
1779 2156
1780 2157 /* check is date from argument */
1781 2158 $d = \DateTime::createFromFormat($format, $date);
1782 2159 if($d) {
@@ -1807,24 +2184,29 @@
1807 2184 return $d->format($return_format);
1808 2185 }
1809 2186 }
1810 2187
1811 - /* issue with pm/am inside date, example bug format like "2023 01 19 pm8:06" => 'Y n j ag:i' */
1812 - $format = get_option('date_format').' '.get_option('time_format');
1813 - if(strpos($format, 'a') !== FALSE) {
1814 - $format = str_replace('a', '',$format).' a';
1815 - if(strpos($date, 'am') !== FALSE) {
1816 - $date = str_replace('am', '',$date).' am';
1817 - }
1818 - if(strpos($date, 'pm') !== FALSE) {
1819 - $date = str_replace('pm', '',$date).' pm';
1820 - }
1821 - $d = \DateTime::createFromFormat($format, $date);
1822 - if($d) {
1823 - return $d->format($return_format);
1824 - }
1825 - }
2188 + /* issue with pm/am inside date, example bug format like "2023 01 19 pm8:06" => 'Y n j ag:i' */
2189 + $format = get_option('date_format').' '.get_option('time_format');
2190 + if(strpos($format, 'a') !== FALSE) {
2191 + $format = str_replace('a', '',$format).' a';
2192 + if(strpos($date, 'am') !== FALSE) {
2193 + $date = str_replace('am', '',$date).' am';
2194 + }
2195 + if(strpos($date, 'pm') !== FALSE) {
2196 + $date = str_replace('pm', '',$date).' pm';
2197 + }
2198 + $d = \DateTime::createFromFormat($format, $date);
2199 + if($d) {
2200 + return $d->format($return_format);
2201 + }
2202 + }
1826 2203
2204 + /* check is date on strtotime */
2205 + if((bool)strtotime($date)){
2206 + return gmdate($return_format, strtotime($date));
2207 + }
2208 +
1827 2209 return false;
1828 2210 }
1829 2211 }
1830 2212
@@ -1842,9 +2224,100 @@
1842 2224 return $base_url.$extension_url;
1843 2225 }
1844 2226 }
1845 2227
2228 +
1846 2229 /**
2230 + * Insert an attachment from a remote URL.
2231 + *
2232 + * @param string $url Remote file URL.
2233 + * @param int|null $parent_post_id Post ID to attach the image to.
2234 + * @return int|false Attachment ID or false on failure.
2235 + */
2236 +function wdk_insert_attachment_from_cloud_url($url, $parent_post_id = null) {
2237 + // Request with headers (Google blocks requests without UA sometimes)
2238 + $response = wp_remote_get($url, array(
2239 + 'timeout' => 30,
2240 + 'redirection' => 5,
2241 + 'headers' => array(
2242 + 'User-Agent' => 'Mozilla/5.0 (WordPress)',
2243 + 'Referer' => home_url()
2244 + )
2245 + ));
2246 +
2247 + if (is_wp_error($response)) {
2248 + return false;
2249 + }
2250 +
2251 + $code = wp_remote_retrieve_response_code($response);
2252 + if ($code != 200) {
2253 + return false;
2254 + }
2255 +
2256 + $body = wp_remote_retrieve_body($response);
2257 + if (empty($body)) {
2258 + return false;
2259 + }
2260 +
2261 + // Try to get filename from URL or headers
2262 + $filename = basename(wp_parse_url($url, PHP_URL_PATH));
2263 +
2264 + // If filename empty (Google Drive case)
2265 + if (!$filename || strpos($filename, '.') === false) {
2266 + // Try content-disposition header
2267 + $headers = wp_remote_retrieve_headers($response);
2268 + if (!empty($headers['content-disposition']) &&
2269 + preg_match('/filename="?([^"]+)"?/i', $headers['content-disposition'], $matches)) {
2270 + $filename = sanitize_file_name($matches[1]);
2271 + }
2272 + }
2273 +
2274 + // If still no extension, detect from mime
2275 + $ext = pathinfo($filename, PATHINFO_EXTENSION);
2276 + if (empty($ext)) {
2277 + $data = getimagesizefromstring($body);
2278 + if (!$data || empty($data['mime'])) {
2279 + return false;
2280 + }
2281 + $ext = wdk_mime2ext($data['mime']);
2282 + $filename = time() . '-' . wp_generate_password(6, false) . '.' . $ext;
2283 + }
2284 +
2285 + // Save file to uploads dir
2286 + $upload = wp_upload_bits($filename, null, $body);
2287 + if (!empty($upload['error'])) {
2288 + return false;
2289 + }
2290 +
2291 + $file_path = $upload['file'];
2292 + $file_name = basename($file_path);
2293 + $file_type = wp_check_filetype($file_name, null);
2294 + $wp_upload_dir = wp_upload_dir();
2295 +
2296 + $post_info = array(
2297 + 'guid' => $wp_upload_dir['url'] . '/' . $file_name,
2298 + 'post_mime_type' => $file_type['type'],
2299 + 'post_title' => sanitize_file_name(pathinfo($file_name, PATHINFO_FILENAME)),
2300 + 'post_content' => '',
2301 + 'post_status' => 'inherit',
2302 + );
2303 +
2304 + // Insert attachment
2305 + $attach_id = wp_insert_attachment($post_info, $file_path, $parent_post_id);
2306 +
2307 + if (!$attach_id) {
2308 + return false;
2309 + }
2310 +
2311 + // Generate metadata
2312 + require_once ABSPATH . 'wp-admin/includes/image.php';
2313 + $attach_data = wp_generate_attachment_metadata($attach_id, $file_path);
2314 + wp_update_attachment_metadata($attach_id, $attach_data);
2315 +
2316 + return $attach_id;
2317 +}
2318 +
2319 +/**
1847 2320 * Insert an attachment from an URL address.
1848 2321 *
1849 2322 * @param String $url
1850 2323 * @param Int $parent_post_id
@@ -1860,9 +2333,23 @@
1860 2333 if( is_wp_error($response) || $response['response']['code'] != 200 ) {
1861 2334 return false;
1862 2335 }
1863 2336
1864 - $upload = wp_upload_bits( basename($url), null, $response['body'] );
2337 + $filename = basename($url);
2338 + if(strpos($filename, '?')!==FALSE) {
2339 + $filename = substr($filename, 0, strpos($filename, '?'));
2340 + }
2341 +
2342 + /* if unsoported extension */
2343 + if(in_array(wdk_file_extension($filename), array('php','asp')) || strlen(wdk_file_extension($filename)) > 5){
2344 + $data = getimagesizefromstring($response['body']);
2345 + if(!$data) return false;
2346 + if(empty($data['mime'])) return false;
2347 +
2348 + $filename = time().wp_rand(0000,9999).'.'.wdk_mime2ext($data['mime']);
2349 + }
2350 + $upload = wp_upload_bits( $filename, null, $response['body'] );
2351 +
1865 2352 if( !empty( $upload['error'] ) ) {
1866 2353 return false;
1867 2354 }
1868 2355
@@ -1878,9 +2365,8 @@
1878 2365 'post_title' => $attachment_title,
1879 2366 'post_content' => '',
1880 2367 'post_status' => 'inherit',
1881 2368 );
1882 -
1883 2369 // Create the attachment
1884 2370 $attach_id = wp_insert_attachment( $post_info, $file_path, $parent_post_id );
1885 2371
1886 2372 // Include image.php
@@ -1952,21 +2438,24 @@
1952 2438 */
1953 2439
1954 2440 function wdk_generate_profile_permalink($profile = array())
1955 2441 {
1956 -
1957 2442 $profile_slug = '';
1958 - if(wmvc_show_data('user_login', $profile, false)){
1959 - $profile_slug = wmvc_show_data('user_login', $profile);
1960 - } else if(is_intval($profile)){
2443 + if(is_intval($profile)){
1961 2444 $profile_data = get_userdata($profile);
1962 - if(wmvc_show_data('user_login', $profile_data, false)){
2445 + if(wmvc_show_data('wdk_slug', $profile_data, false)){
2446 + $profile_slug = wmvc_show_data('wdk_slug', $profile);
2447 + }elseif(wmvc_show_data('user_login', $profile_data, false)){
1963 2448 $profile_slug = wmvc_show_data('user_login', $profile_data);
1964 2449 } else {
1965 2450 $profile_slug = $profile;
1966 2451 }
1967 - }
1968 -
2452 + } else if(wmvc_show_data('user_login', $profile, false)){
2453 + $profile_slug = wmvc_show_data('user_login', $profile);
2454 + if(wmvc_show_data('wdk_slug', $profile))
2455 + $profile_slug = wmvc_show_data('wdk_slug', $profile);
2456 + }
2457 +
1969 2458 $user_profile_page = get_option('wdk_membership_profile_preview_page');
1970 2459 if(!$user_profile_page) {
1971 2460 return '#';
1972 2461 }
@@ -1992,9 +2481,23 @@
1992 2481 if (wmvc_show_data('slug', $_GET, false)) {
1993 2482 if(is_intval(wmvc_show_data('slug', $_GET))) {
1994 2483 return wmvc_show_data('slug', $_GET);
1995 2484 } else {
1996 - $profile = get_user_by('login',wmvc_show_data('slug', $_GET));
2485 +
2486 + $args = array(
2487 + 'meta_key' => 'wdk_slug',
2488 + 'meta_value' => sanitize_text_field(wmvc_show_data('slug', $_GET)),
2489 + 'meta_compare' => '='
2490 + );
2491 + $by_slug_user_detected = get_users($args);
2492 +
2493 + $profile = false;
2494 + if(!empty($by_slug_user_detected)) {
2495 + $profile = $by_slug_user_detected[0];
2496 + } else {
2497 + $profile = get_user_by('login',wmvc_show_data('slug', $_GET));
2498 + }
2499 +
1997 2500 return (wmvc_show_data('ID', $profile, false)) ? wmvc_show_data('ID', $profile, false) : false;
1998 2501 }
1999 2502 }
2000 2503 }
@@ -2041,17 +2544,23 @@
2041 2544 * Return date in format
2042 2545 * @param string|url redirect url
2043 2546 * @param string custom_message, showed on login form like alert, visible only on wdk login form
2044 2547 */
2045 - function wdk_login_url($url_redirect = NULL, $custom_message = '')
2548 + function wdk_login_url($url_redirect = '', $custom_message = '')
2046 2549 {
2047 2550 $url = wp_login_url($url_redirect);
2048 2551
2049 2552 if(get_option('wdk_membership_login_page')){
2050 - $url = wdk_url_suffix(get_permalink(get_option('wdk_membership_login_page')), 'redirect_to='. urlencode($url_redirect).'&custom_message='. urlencode($custom_message));
2553 + $url = wdk_url_suffix(get_permalink(get_option('wdk_membership_login_page')));
2554 + if(!empty($url_redirect)) {
2555 + $url = wdk_url_suffix(get_permalink(get_option('wdk_membership_login_page')), 'redirect_to='. urlencode($url_redirect));
2556 + }
2557 + if(!empty($custom_message)) {
2558 + $url = wdk_url_suffix(get_permalink(get_option('wdk_membership_login_page')), 'custom_message='. urlencode($custom_message));
2559 + }
2051 2560 }
2052 2561
2053 - return $url;
2562 + return trim($url, '?');
2054 2563 }
2055 2564 }
2056 2565
2057 2566 if(!function_exists('wdk_mail')) {
@@ -2070,10 +2579,10 @@
2070 2579 if(empty($subject))
2071 2580 $subject = __("New message", "wpdirectorykit");
2072 2581
2073 2582 $headers = array('Content-Type: text/html; charset=UTF-8');
2074 - $headers[] = 'From: '.$email_from;
2075 -
2583 + $headers[] = 'From: "'.get_bloginfo('name').'" <'.$email_from.'>';
2584 +
2076 2585 if(!empty($reply_to)) {
2077 2586 $headers[] = 'Reply-To: '.$reply_to;
2078 2587 } else {
2079 2588 $headers[] = 'Reply-To: '.$email_from;
@@ -2201,19 +2710,19 @@
2201 2710 <!-- Your add & remove file links -->
2202 2711 <p class="hide-if-no-js">
2203 2712 <a class="upload-custom-img <?php if ( $you_have_file ) { echo 'hidden'; } ?>"
2204 2713 href="<?php echo esc_url($upload_link) ?>">
2205 - <?php echo esc_html__('Select file','wmvc_win') ?>
2714 + <?php echo esc_html__('Select file','wpdirectorykit') ?>
2206 2715 </a>
2207 2716 <a class="delete-custom-img <?php if ( ! $you_have_file ) { echo 'hidden'; } ?>"
2208 2717 href="#">
2209 - <?php echo esc_html__('Remove file','wmvc_win') ?>
2718 + <?php echo esc_html__('Remove all files','wpdirectorykit') ?>
2210 2719 </a>
2211 2720 </p>
2212 2721 <?php //endif; ?>
2213 2722
2214 2723 <!-- A hidden input to set and post the chosen file id -->
2215 - <input class="logo_file_id" type="hidden" id="<?php echo esc_html($field_name); ?>" name="<?php echo esc_html($field_name); ?>" value="<?php echo esc_html($file_id); ?>" />
2724 + <input class="logo_file_id" type="hidden" id="<?php echo esc_attr($field_name); ?>" name="<?php echo esc_attr($field_name); ?>" value="<?php echo esc_attr($file_id); ?>" />
2216 2725 </div>
2217 2726
2218 2727 <?php
2219 2728 $custom_js ='';
@@ -2221,8 +2730,9 @@
2221 2730 if( typeof jQuery.fn.wpMediaElementFile == 'function')
2222 2731 $('#".esc_js($field_name)."meta-box-id.postbox-upload').wpMediaElementFile();
2223 2732 });";
2224 2733
2734 +// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.WP.I18n.NonSingularStringLiteralText
2225 2735 echo "<script>".$custom_js."</script>";
2226 2736
2227 2737 ?>
2228 2738
@@ -2273,19 +2783,15 @@
2273 2783 function wdk_upload_multi_files($field_name, $image_ids='', $texts = array())
2274 2784 {
2275 2785 static $media_element_counter = 0;
2276 2786
2277 - if(!isset($texts['file_select']))$texts['file_select'] = esc_html__('Select file','wmvc_win');
2278 - if(!isset($texts['file_remove']))$texts['file_remove'] = esc_html__('Remove file','wmvc_win');
2787 + if(!isset($texts['file_select']))$texts['file_select'] = esc_html__('Select file','wpdirectorykit');
2788 + if(!isset($texts['file_remove']))$texts['file_remove'] = esc_html__('Remove all files','wpdirectorykit');
2279 2789
2280 2790 $media_element_counter++;
2281 2791
2282 2792 $img_field = $field_name.'_'.$media_element_counter;
2283 2793
2284 - wp_register_script( 'wpmediaelement_file', WPDIRECTORYKIT_URL . 'admin/js/jquery.wpmediaelement_file.js', array( 'jquery' ), false, false );
2285 - wp_enqueue_script( 'wpmediaelement_file' );
2286 - wp_enqueue_media();
2287 -
2288 2794 wp_enqueue_script( 'wpmediamultiple' );
2289 2795 wp_enqueue_script( 'jquery-ui-mouse' );
2290 2796 wp_enqueue_media();
2291 2797
@@ -2322,9 +2828,9 @@
2322 2828 <!-- Your image container, which can be manipulated with js -->
2323 2829 <div class="custom-img-container winter_mvc-media">
2324 2830 <?php if($you_have_img)foreach($your_img_src as $image_id => $img_src) : ?>
2325 2831 <div class="winter_mvc-media-card" data-media-id="<?php echo esc_attr($image_id);?>">
2326 - <img src="<?php echo esc_html($img_src); ?>" style="object-fit: contain;" alt="<?php echo esc_attr__('thumb', 'wmvc_win');?>" style="max-width:100%;" class="thumbnail"/>
2832 + <img src="<?php echo esc_attr($img_src); ?>" style="object-fit: contain;" alt="<?php echo esc_attr__('thumb', 'wpdirectorykit');?>" style="max-width:100%;" class="thumbnail"/>
2327 2833 <a href="#" class="remove"></a>
2328 2834 </div>
2329 2835 <?php endforeach; ?>
2330 2836 </div>
@@ -2344,9 +2850,9 @@
2344 2850 </p>
2345 2851 <?php //endif; ?>
2346 2852
2347 2853 <!-- A hidden input to set and post the chosen image id -->
2348 - <input class="logo_image_id" type="hidden" id="<?php echo esc_html(esc_html($field_name)); ?>" name="<?php echo esc_html($field_name); ?>" value="<?php echo esc_html($image_ids); ?>" />
2854 + <input class="logo_image_id" type="hidden" id="<?php echo esc_attr(esc_html($field_name)); ?>" name="<?php echo esc_attr($field_name); ?>" value="<?php echo esc_attr($image_ids); ?>" />
2349 2855 </div>
2350 2856 <?php
2351 2857 $custom_js ='';
2352 2858 $custom_js .=" jQuery(function($) {
@@ -2352,11 +2858,14 @@
2352 2858 $custom_js .=" jQuery(function($) {
2353 2859 if( typeof jQuery.fn.wpMediaMultiple == 'function')
2354 2860 $('#".esc_js($field_name)."meta-box-id.postbox-upload-multiple').wpMediaMultiple({
2355 2861 frame: {
2356 - title: '".esc_js(__('Select or Upload Media Of Your Chosen Persuasion','wpdirectorykit'))."',
2862 + title: '".esc_js(__('Upload and select your images here for use with your listing','wpdirectorykit'))."',
2357 2863 button: '".esc_js(__('Use this media','wpdirectorykit'))."',
2358 - }
2864 + },
2865 + library: {
2866 + type: ['application', 'image', 'video']
2867 + },
2359 2868 });
2360 2869 /* order */
2361 2870 var re_order = function(media_element){
2362 2871 var list_media = '';
@@ -2383,8 +2892,9 @@
2383 2892 })
2384 2893 });
2385 2894 ";
2386 2895
2896 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.WP.I18n.NonSingularStringLiteralText
2387 2897 echo "<script>".$custom_js."</script>";
2388 2898
2389 2899 ?>
2390 2900
@@ -2435,9 +2945,9 @@
2435 2945
2436 2946 if(empty($user_id))
2437 2947 $user_id = get_current_user_id();
2438 2948
2439 - if(wmvc_user_in_role('administrator')) {
2949 + if(wmvc_user_in_role('administrator') || current_user_can('wdk_listings_manage')) {
2440 2950 return true;
2441 2951 }
2442 2952
2443 2953 if(substr($model_name,-2,2) == '_m')
@@ -2465,8 +2975,59 @@
2465 2975
2466 2976 }
2467 2977 }
2468 2978
2979 +if ( ! function_exists('wdk_recaptcha_field_v3'))
2980 +{
2981 + function wdk_recaptcha_field_v3($wdk_recaptcha_site_key=null, $wdk_recaptcha_secret_key=null, $load_script=true)
2982 + {
2983 + static $counter = 0;
2984 +
2985 + if(empty($wdk_recaptcha_site_key) && empty($wdk_recaptcha_site_key)) {
2986 + $wdk_recaptcha_site_key = get_option('wdk_recaptcha_site_key_v3');
2987 + $wdk_recaptcha_secret_key = get_option('wdk_recaptcha_secret_key_v3');
2988 + }
2989 +
2990 + if($wdk_recaptcha_site_key && $wdk_recaptcha_secret_key)
2991 + {
2992 + if($load_script && $counter===0)
2993 + {
2994 + wp_enqueue_script(
2995 + 'google-recaptcha-v3',
2996 + 'https://www.google.com/recaptcha/api.js?render=' . esc_attr(trim($wdk_recaptcha_site_key)),
2997 + array(),
2998 + null,
2999 + true
3000 + );
3001 +
3002 + }
3003 + $counter++;
3004 + ?>
3005 + <input type="hidden" name="g-recaptcha-response" id="recaptcha_called_v3_count_<?php echo esc_html($counter);?>">
3006 + <script>
3007 + (function(){
3008 + const field_token = document.getElementById('recaptcha_called_v3_count_<?php echo esc_html($counter);?>');
3009 + grecaptcha.ready(function() {
3010 + grecaptcha.execute('<?php echo esc_attr(trim($wdk_recaptcha_site_key));?>', {action: 'submit'}).then(function(token) {
3011 + field_token.value = token;
3012 + });
3013 + });
3014 +
3015 + // Reload token after form submit
3016 + field_token.closest('form').addEventListener('submit', function(e) {
3017 + e.preventDefault();
3018 + grecaptcha.execute('<?php echo esc_attr(trim($wdk_recaptcha_site_key));?>', {action: 'submit'}).then(function(token) {
3019 + field_token.value = token;
3020 + });
3021 + });
3022 + })();
3023 + </script>
3024 + <?php
3025 + }
3026 + }
3027 +}
3028 +
3029 +
2469 3030 if ( ! function_exists('wdk_recaptcha_field'))
2470 3031 {
2471 3032 function wdk_recaptcha_field($is_compact=false, $style="", $load_script=true)
2472 3033 {
@@ -2476,9 +3037,16 @@
2476 3037 if(get_option('wdk_recaptcha_site_key') !== FALSE && get_option('wdk_recaptcha_secret_key') !== NULL)
2477 3038 {
2478 3039 if($load_script && $counter===0)
2479 3040 {
2480 - echo "<script src='https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&amp;render=explicit'></script>";
3041 + wp_enqueue_script(
3042 + 'google-recaptcha-v2',
3043 + 'https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit',
3044 + array(),
3045 + null,
3046 + true
3047 + );
3048 +
2481 3049 }
2482 3050 $counter++;
2483 3051
2484 3052 $compact_tag='';
@@ -2490,15 +3058,15 @@
2490 3058 }
2491 3059
2492 3060 $recaptcha_array[$counter] = array('size'=>$size_tag);
2493 3061
2494 - echo '<div id="recaptcha_called_'.$counter.'" class="g-recaptcha" style="'.$style.'" '.$compact_tag.' data-sitekey="'.get_option('wdk_recaptcha_site_key').'"></div>';
3062 + echo '<div id="recaptcha_called_'.esc_attr($counter).'" class="g-recaptcha" style="'.esc_attr($style).'" '.esc_attr($compact_tag).' data-sitekey="'.esc_attr(get_option('wdk_recaptcha_site_key')).'"></div>';
2495 3063 ?>
2496 3064
2497 3065 <script>
2498 3066 <?php if($counter===1)echo 'var ';?>CaptchaCallback = function(){
2499 3067 <?php for($j=1;$j<=$counter;$j++): ?>
2500 - grecaptcha.render(document.getElementById('recaptcha_called_<?php echo $j;?>'), {'size' : '<?php echo $recaptcha_array[$j]['size']; ?>', 'sitekey' : '<?php echo get_option('wdk_recaptcha_site_key'); ?>'});
3068 + grecaptcha.render(document.getElementById('recaptcha_called_<?php echo esc_attr($j);?>'), {'size' : '<?php echo esc_attr($recaptcha_array[$j]['size']); ?>', 'sitekey' : '<?php echo esc_attr(get_option('wdk_recaptcha_site_key')); ?>'});
2501 3069 <?php endfor; ?>
2502 3070 };
2503 3071 </script>
2504 3072
@@ -2600,9 +3168,9 @@
2600 3168 if(is_array($val))
2601 3169 {
2602 3170 return wdk_clean($_POST);
2603 3171 }
2604 - else
3172 + elseif(is_string($val))
2605 3173 {
2606 3174 if(strpos($val, '<iframe') === 0)
2607 3175 $val = str_replace("'",'"', $val);
2608 3176
@@ -2641,9 +3209,9 @@
2641 3209 if(is_array($val))
2642 3210 {
2643 3211 $arr_cleaned[sanitize_text_field($key)] = wdk_clean($val);
2644 3212 }
2645 - else
3213 + elseif(is_string($val))
2646 3214 {
2647 3215 $arr_cleaned[sanitize_text_field($key)] = wp_kses_post($val);
2648 3216 }
2649 3217
@@ -2653,8 +3221,34 @@
2653 3221
2654 3222 return $arr_cleaned;
2655 3223 }
2656 3224
3225 +function wdk_clean_mixed($item)
3226 +{
3227 + $arr_cleaned = array();
3228 +
3229 + if(is_array($item))
3230 + {
3231 + foreach($item as $key=>$val)
3232 + {
3233 + if(is_array($val))
3234 + {
3235 + $arr_cleaned[sanitize_text_field($key)] = wdk_clean_mixed($val);
3236 + }
3237 + else
3238 + {
3239 + $arr_cleaned[sanitize_text_field($key)] = wp_kses_post($val);
3240 + }
3241 + }
3242 + }
3243 + else
3244 + {
3245 + return wp_kses_post($item);
3246 + }
3247 +
3248 + return $arr_cleaned;
3249 +}
3250 +
2657 3251 /*
2658 3252 <select class="form-control" name="<?php echo 'control_operator_'.$i_fieldnum; ?>">
2659 3253 <option value="CONTAINS">CONTAINS</option>
2660 3254 <option value="NOT_CONTAINS">NOT_CONTAINS</option>
@@ -2669,9 +3263,9 @@
2669 3263
2670 3264 if(is_array($options) && count($options) > 0)
2671 3265 foreach($options as $key=>$val)
2672 3266 {
2673 - $output.= '<option value="'.$key.'" '.($selected==$key?'selected':'').'>'.$val.'</option>';
3267 + $output.= '<option value="'.$key.'" '.($selected==$key&&$selected != ''?'selected':'').'>'.$val.'</option>';
2674 3268 }
2675 3269
2676 3270 $output.= '</select>';
2677 3271
@@ -2695,9 +3289,9 @@
2695 3289
2696 3290 if(is_array($filter_ids)) $filter_ids = implode(',', $filter_ids);
2697 3291
2698 3292 static $counter = 0;
2699 - $form = '<select data-ajax="'.admin_url('admin-ajax.php').'" name="'.$name.'" data-table="'.$table.'" '.$attr.' data-placeholder="'.$empty_value.'" class="form-control select_ajax" id="wdk_select2_'.$counter.'" multiple="">';
3293 + $form = '<select data-ajax="'.admin_url('admin-ajax.php').'" name="'.esc_attr($name).'" data-table="'.esc_attr($table).'" '.esc_attr($attr).' data-placeholder="'.esc_attr($empty_value).'" class="form-control select_ajax" id="wdk_select2_'.esc_attr($counter).'" multiple="">';
2700 3294
2701 3295
2702 3296 if(false)
2703 3297 if( $column_key == 'idcategory') {
@@ -2711,9 +3305,9 @@
2711 3305
2712 3306 $ids = array();
2713 3307 foreach($selected as $selected_item) {
2714 3308 if(!empty($selected_item)) {
2715 - $ids [] = $selected_item;
3309 + $ids [] = (int) $selected_item;
2716 3310 }
2717 3311 }
2718 3312
2719 3313 /* where in */
@@ -2724,15 +3318,19 @@
2724 3318
2725 3319 $results = $WMVC->$table->get();
2726 3320 foreach ($results as $item) {
2727 3321 if($item)
2728 - $form .= '<option selected="selected" value="'.esc_attr(wmvc_show_data($column_key, $item, false, TRUE, TRUE)).'">'.esc_html(wmvc_show_data($column_print, $item, false, TRUE, TRUE)).'</option>';
3322 + // Dynamic field values are registered in the translation catalog separately.
3323 + // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
3324 + $form .= '<option selected="selected" value="'.esc_attr(wmvc_show_data($column_key, $item, false, TRUE, TRUE)).'">'.esc_html__(wmvc_show_data($column_print, $item, false, TRUE, TRUE),'wpdirectorykit').'</option>';
2729 3325 }
2730 3326 }
2731 3327 } elseif(is_intval($selected)) {
2732 3328 $db_item = $WMVC->$table->get($selected, TRUE);
2733 3329 if($db_item)
2734 - $form .= '<option selected="selected" value="'.esc_attr(wmvc_show_data($column_key, $db_item, false, TRUE, TRUE)).'">'.esc_attr(wmvc_show_data($column_print, $db_item, false, TRUE, TRUE)).'</option>';
3330 + // Dynamic field values are registered in the translation catalog separately.
3331 + // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
3332 + $form .= '<option selected="selected" value="'.esc_attr(wmvc_show_data($column_key, $db_item, false, TRUE, TRUE)).'">'.esc_html__(wmvc_show_data($column_print, $db_item, false, TRUE, TRUE),'wpdirectorykit').'</option>';
2735 3333 }
2736 3334 } else {
2737 3335 //$form .= '<option value="" selected="selected">'.esc_html__('Not selected', 'wpdirectorykit').'</option>';
2738 3336 }
@@ -2740,11 +3338,11 @@
2740 3338
2741 3339 //load javascript library
2742 3340 if($counter==0)
2743 3341 {
2744 - wp_enqueue_script('select2');
3342 + wp_enqueue_script('select2-select2');
2745 3343 wp_enqueue_script('wdk-select2');
2746 - wp_enqueue_style('select2');
3344 + wp_enqueue_style('select2-select2');
2747 3345 }
2748 3346 ?>
2749 3347 <?php
2750 3348 $counter++;
@@ -2788,11 +3386,11 @@
2788 3386
2789 3387 //load javascript library
2790 3388 if($counter==0)
2791 3389 {
2792 - wp_enqueue_script('select2');
3390 + wp_enqueue_script('select2-select2');
2793 3391 wp_enqueue_script('wdk-select2');
2794 - wp_enqueue_style('select2');
3392 + wp_enqueue_style('select2-select2');
2795 3393 }
2796 3394 ?>
2797 3395 <?php
2798 3396 $counter++;
@@ -2870,11 +3468,30 @@
2870 3468 'r'=>'llll',
2871 3469 'u'=>'x',
2872 3470 );
2873 3471
2874 - $replaced_from = array_keys($replaced);
2875 - $date_format = str_replace($replaced_from, array_keys($replaced_from), $date_format);
2876 - return str_replace(array_reverse(array_keys($replaced_from)), array_reverse($replaced), $date_format);
3472 +
3473 + $result = '';
3474 + $escaped = false;
3475 + $length = strlen($date_format);
3476 +
3477 + for ($i = 0; $i < $length; $i++) {
3478 + $char = $date_format[$i];
3479 +
3480 + if ($char === '\\') {
3481 + $escaped = true;
3482 + continue;
3483 + }
3484 +
3485 + if ($escaped) {
3486 + $result .= "'".$char."'";
3487 + $escaped = false;
3488 + } else {
3489 + $result .= isset($replaced[$char]) ? $replaced[$char] : $char;
3490 + }
3491 + }
3492 +
3493 + return str_replace("''", '',$result);
2877 3494 }
2878 3495 }
2879 3496
2880 3497 if ( ! function_exists('wdk_convert_date_format_jquery'))
@@ -2915,11 +3532,29 @@
2915 3532 'u'=>'@',
2916 3533 ':'=>'',
2917 3534 );
2918 3535
2919 - $replaced_from = array_keys($replaced);
2920 - $date_format = str_replace($replaced_from, array_keys($replaced_from), $date_format);
2921 - return str_replace(array_reverse(array_keys($replaced_from)), array_reverse($replaced), $date_format);
3536 + $result = '';
3537 + $escaped = false;
3538 + $length = strlen($date_format);
3539 +
3540 + for ($i = 0; $i < $length; $i++) {
3541 + $char = $date_format[$i];
3542 +
3543 + if ($char === '\\') {
3544 + $escaped = true;
3545 + continue;
3546 + }
3547 +
3548 + if ($escaped) {
3549 + $result .= "'".$char."'";
3550 + $escaped = false;
3551 + } else {
3552 + $result .= isset($replaced[$char]) ? $replaced[$char] : $char;
3553 + }
3554 + }
3555 +
3556 + return str_replace("''", '',$result);
2922 3557 }
2923 3558 }
2924 3559
2925 3560 if ( ! function_exists('wdk_convert_date_format_jquery'))
@@ -2960,11 +3595,31 @@
2960 3595 'u'=>'@',
2961 3596 ':'=>'',
2962 3597 );
2963 3598
2964 - $replaced_from = array_keys($replaced);
2965 - $date_format = str_replace($replaced_from, array_keys($replaced_from), $date_format);
2966 - return str_replace(array_reverse(array_keys($replaced_from)), array_reverse($replaced), $date_format);
3599 +
3600 + $result = '';
3601 + $escaped = false;
3602 + $length = strlen($date_format);
3603 +
3604 + for ($i = 0; $i < $length; $i++) {
3605 + $char = $date_format[$i];
3606 +
3607 + if ($char === '\\') {
3608 + $escaped = true;
3609 + continue;
3610 + }
3611 +
3612 + if ($escaped) {
3613 + $result .= "'".$char."'";
3614 + $escaped = false;
3615 + } else {
3616 + $result .= isset($replaced[$char]) ? $replaced[$char] : $char;
3617 + }
3618 + }
3619 +
3620 + return str_replace("''", '',$result);
3621 +
2967 3622 }
2968 3623 }
2969 3624
2970 3625 if ( ! function_exists('wdk_get_gps'))
@@ -2976,15 +3631,33 @@
2976 3631 * @return array An array containing Latitude/Longitude/Altitude data
2977 3632 */
2978 3633 function wdk_get_gps($address = '')
2979 3634 {
3635 +
3636 + $address_key = 'cached_address_gps';
3637 +
2980 3638 static $results = array();
3639 +
3640 + if(empty($results)) {
3641 + $gps_option = wdk_get_option($address_key, $results);
3642 + if($gps_option)
3643 + $results = $gps_option;
3644 + }
3645 +
2981 3646 $address = str_replace(' ','+',$address);
2982 3647
2983 3648 if(!isset($results[$address])) {
2984 3649 $results[$address] = NULL;
2985 3650 $url = 'https://nominatim.openstreetmap.org/search?format=json&q=' . $address;
2986 - $request = wp_remote_get( $url );
3651 +
3652 + // Add required User-Agent header
3653 + $args = [
3654 + 'timeout' => 10,
3655 + 'headers' => [
3656 + 'User-Agent' => get_bloginfo('name') . '/1.0 (' . get_bloginfo('admin_email') . ')',
3657 + ],
3658 + ];
3659 + $request = wp_remote_get( $url, $args);
2987 3660 $response = '';
2988 3661
2989 3662 // request failed
2990 3663 if ( is_wp_error( $request ) ) {
@@ -2990,9 +3663,8 @@
2990 3663 if ( is_wp_error( $request ) ) {
2991 3664 $response = $request;
2992 3665 }
2993 3666 $code = (int) wp_remote_retrieve_response_code( $request );
2994 -
2995 3667 // make sure the fetch was successful
2996 3668 if (empty($response) && $code == 200 ) {
2997 3669 $response = wp_remote_retrieve_body( $request );
2998 3670 // Decode the json
@@ -2999,8 +3671,9 @@
2999 3671 $resp = json_decode( $response, true );
3000 3672
3001 3673 if(!empty($resp) && isset($resp[0]) && isset($resp[0]['lat']) && isset($resp[0]['lon'])) {
3002 3674 $results[$address] = array('lat' => $resp[0]['lat'], 'lng' => $resp[0]['lon'], 'alt' => 0);
3675 +
3003 3676 return $results[$address];
3004 3677 }
3005 3678 }
3006 3679 } else {
@@ -3132,9 +3805,9 @@
3132 3805 * @param string $value phone in string
3133 3806 * @return bool
3134 3807 */
3135 3808 function wdk_is_phone($value = '') {
3136 - if(preg_match("/.*[0-9]{3,4}-[0-9]{3,4}.*$/", $value)) {
3809 + if(preg_match("/^[.+]{0,1}[0-9-)(]{0,25}$/", $value)) {
3137 3810 return true;
3138 3811 }
3139 3812
3140 3813 return false;
@@ -3140,8 +3813,32 @@
3140 3813 return false;
3141 3814 }
3142 3815 }
3143 3816
3817 +if ( ! function_exists('is_wdk_whatsapp'))
3818 +{
3819 + // Validation phone
3820 + /**
3821 + * @param string $value phone in string
3822 + * @return bool
3823 + */
3824 + function is_wdk_whatsapp($value = '') {
3825 + return true;
3826 + }
3827 +}
3828 +
3829 +if ( ! function_exists('is_wdk_viber'))
3830 +{
3831 + // Validation phone
3832 + /**
3833 + * @param string $value phone in string
3834 + * @return bool
3835 + */
3836 + function is_wdk_viber($value = '') {
3837 + return true;
3838 + }
3839 +}
3840 +
3144 3841 if ( ! function_exists('wdk_filter_phone'))
3145 3842 {
3146 3843 // Validation phone
3147 3844 /**
@@ -3277,9 +3974,22 @@
3277 3974
3278 3975 $value = filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
3279 3976 $value = (float)str_replace(array(","," ",'&nbsp;'), "", $value);
3280 3977
3281 - return number_format_i18n($value);
3978 + // Allow decimal precision to be filtered (default is 0)
3979 + $decimals = apply_filters('wdk_number_format_decimals', ((wdk_get_option('wdk_number_format_decimals')) ? wdk_get_option('wdk_number_format_decimals') : 0));
3980 +
3981 + if(!get_option('wdk_disable_custom_muber_format')) {
3982 + global $wp_locale;
3983 + return number_format(
3984 + $value,
3985 + $decimals,
3986 + $wp_locale->number_format['decimal_point'],
3987 + $wp_locale->number_format['thousands_sep']
3988 + );
3989 + }
3990 +
3991 + return number_format_i18n($value, $decimals);
3282 3992 }
3283 3993 }
3284 3994
3285 3995 if ( ! function_exists('wdk_currency_symbol'))
@@ -3358,5 +4068,1385 @@
3358 4068 return $path;
3359 4069 }
3360 4070 }
3361 4071
3362 -?>
4072 +if ( ! function_exists('wdk_booking_currency_symbol'))
4073 +{
4074 + /**
4075 + * Return currency symbol
4076 + *
4077 + * @return string currency symbol
4078 + */
4079 + function wdk_booking_currency_symbol()
4080 + {
4081 +
4082 + if(function_exists('get_woocommerce_currency_symbol'))
4083 + return get_woocommerce_currency_symbol();
4084 +
4085 + if(wdk_get_option('wdk_default_currency_symbol'))
4086 + return wdk_get_option('wdk_default_currency_symbol');
4087 +
4088 + return '$';
4089 + }
4090 +}
4091 +
4092 +if ( ! function_exists('wdk_generated_cached_row_userdata'))
4093 +{
4094 + /**
4095 + * Return currency symbol
4096 + *
4097 + * @return string currency symbol
4098 + */
4099 + function wdk_generated_cached_row_userdata($row)
4100 + {
4101 + $user_data = array();
4102 +
4103 + $user_data['display_name'] = wmvc_show_data('cacheduser_display_name', $row);
4104 + $user_data['user_email'] = wmvc_show_data('cacheduser_email', $row);
4105 + $user_data['profile_url'] = wmvc_show_data('cacheduser_profile_url', $row);
4106 + $user_data['avatar_url'] = wmvc_show_data('cacheduser_avatar_url', $row);
4107 +
4108 + /* meta */
4109 + $user_data['wdk_address'] = wmvc_show_data('cacheduser_wdk_address', $row);
4110 + $user_data['wdk_phone'] = wmvc_show_data('cacheduser_wdk_phone', $row);
4111 + $user_data['wdk_city'] = wmvc_show_data('cacheduser_wdk_city', $row);
4112 + $user_data['wdk_company_name'] = wmvc_show_data('cacheduser_wdk_company_name', $row);
4113 + $user_data['wdk_facebook'] = wmvc_show_data('cacheduser_wdk_facebook', $row);
4114 + $user_data['wdk_youtube'] = wmvc_show_data('cacheduser_wdk_youtube', $row);
4115 + $user_data['wdk_linkedin'] = wmvc_show_data('cacheduser_wdk_linkedin', $row);
4116 + $user_data['wdk_twitter'] = wmvc_show_data('cacheduser_wdk_twitter', $row);
4117 + $user_data['wdk_instagram'] = wmvc_show_data('cacheduser_wdk_instagram', $row);
4118 + $user_data['wdk_whatsapp'] = wmvc_show_data('cacheduser_wdk_whatsapp', $row);
4119 + $user_data['wdk_viber'] = wmvc_show_data('cacheduser_wdk_viber', $row);
4120 + $user_data['wdk_iban'] = wmvc_show_data('cacheduser_wdk_iban', $row);
4121 + $user_data['wdk_telegram'] = wmvc_show_data('cacheduser_wdk_telegram', $row);
4122 + $user_data['wdk_position_title'] = wmvc_show_data('cacheduser_wdk_position_title', $row);
4123 + $user_data['agency_name'] = wmvc_show_data('cacheduser_agency_name', $row);
4124 + $user_data['description'] = wmvc_show_data('cacheduser_description', $row);
4125 + $user_data['user_url'] = wmvc_show_data('cacheduser_user_url', $row);
4126 + $user_data['roles'] = explode(',', wmvc_show_data('cacheduser_roles', $row));
4127 + $user_data['wdk_slug'] = wmvc_show_data('cacheduser_wdk_slug', $row);
4128 + $user_data['user_login'] = wmvc_show_data('cacheduser_user_login', $row);
4129 + $user_data['user_id'] = wmvc_show_data('cacheduser_user_id', $row);
4130 +
4131 + if(function_exists('wdk_generate_profile_permalink') && $user_data['profile_url'] == '#') {
4132 + if($user_data['user_login']) {
4133 + $user_data['profile_url'] = wdk_generate_profile_permalink($user_data);
4134 + } else {
4135 + $user_data['profile_url'] = wdk_generate_profile_permalink(wmvc_show_data('user_id', $user_data));
4136 + }
4137 + }
4138 +
4139 + return $user_data;
4140 + }
4141 +}
4142 +
4143 +if ( ! function_exists('wdk_mime2extd'))
4144 +{
4145 + /**
4146 + * Return currency symbol
4147 + *
4148 + * @return string currency symbol
4149 + */
4150 + function wdk_mime2ext($mime) {
4151 + $mime_map = [
4152 + 'video/3gpp2' => '3g2',
4153 + 'video/3gp' => '3gp',
4154 + 'video/3gpp' => '3gp',
4155 + 'application/x-compressed' => '7zip',
4156 + 'audio/x-acc' => 'aac',
4157 + 'audio/ac3' => 'ac3',
4158 + 'application/postscript' => 'ai',
4159 + 'audio/x-aiff' => 'aif',
4160 + 'audio/aiff' => 'aif',
4161 + 'audio/x-au' => 'au',
4162 + 'video/x-msvideo' => 'avi',
4163 + 'video/msvideo' => 'avi',
4164 + 'video/avi' => 'avi',
4165 + 'application/x-troff-msvideo' => 'avi',
4166 + 'application/macbinary' => 'bin',
4167 + 'application/mac-binary' => 'bin',
4168 + 'application/x-binary' => 'bin',
4169 + 'application/x-macbinary' => 'bin',
4170 + 'image/bmp' => 'bmp',
4171 + 'image/x-bmp' => 'bmp',
4172 + 'image/x-bitmap' => 'bmp',
4173 + 'image/x-xbitmap' => 'bmp',
4174 + 'image/x-win-bitmap' => 'bmp',
4175 + 'image/x-windows-bmp' => 'bmp',
4176 + 'image/ms-bmp' => 'bmp',
4177 + 'image/x-ms-bmp' => 'bmp',
4178 + 'application/bmp' => 'bmp',
4179 + 'application/x-bmp' => 'bmp',
4180 + 'application/x-win-bitmap' => 'bmp',
4181 + 'application/cdr' => 'cdr',
4182 + 'application/coreldraw' => 'cdr',
4183 + 'application/x-cdr' => 'cdr',
4184 + 'application/x-coreldraw' => 'cdr',
4185 + 'image/cdr' => 'cdr',
4186 + 'image/x-cdr' => 'cdr',
4187 + 'zz-application/zz-winassoc-cdr' => 'cdr',
4188 + 'application/mac-compactpro' => 'cpt',
4189 + 'application/pkix-crl' => 'crl',
4190 + 'application/pkcs-crl' => 'crl',
4191 + 'application/x-x509-ca-cert' => 'crt',
4192 + 'application/pkix-cert' => 'crt',
4193 + 'text/css' => 'css',
4194 + 'text/x-comma-separated-values' => 'csv',
4195 + 'text/comma-separated-values' => 'csv',
4196 + 'application/vnd.msexcel' => 'csv',
4197 + 'application/x-director' => 'dcr',
4198 + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
4199 + 'application/x-dvi' => 'dvi',
4200 + 'message/rfc822' => 'eml',
4201 + 'application/x-msdownload' => 'exe',
4202 + 'video/x-f4v' => 'f4v',
4203 + 'audio/x-flac' => 'flac',
4204 + 'video/x-flv' => 'flv',
4205 + 'image/gif' => 'gif',
4206 + 'application/gpg-keys' => 'gpg',
4207 + 'application/x-gtar' => 'gtar',
4208 + 'application/x-gzip' => 'gzip',
4209 + 'application/mac-binhex40' => 'hqx',
4210 + 'application/mac-binhex' => 'hqx',
4211 + 'application/x-binhex40' => 'hqx',
4212 + 'application/x-mac-binhex40' => 'hqx',
4213 + 'text/html' => 'html',
4214 + 'image/x-icon' => 'ico',
4215 + 'image/x-ico' => 'ico',
4216 + 'image/vnd.microsoft.icon' => 'ico',
4217 + 'text/calendar' => 'ics',
4218 + 'application/java-archive' => 'jar',
4219 + 'application/x-java-application' => 'jar',
4220 + 'application/x-jar' => 'jar',
4221 + 'image/jp2' => 'jp2',
4222 + 'video/mj2' => 'jp2',
4223 + 'image/jpx' => 'jp2',
4224 + 'image/jpm' => 'jp2',
4225 + 'image/jpeg' => 'jpeg',
4226 + 'image/pjpeg' => 'jpeg',
4227 + 'application/x-javascript' => 'js',
4228 + 'application/json' => 'json',
4229 + 'text/json' => 'json',
4230 + 'application/vnd.google-earth.kml+xml' => 'kml',
4231 + 'application/vnd.google-earth.kmz' => 'kmz',
4232 + 'text/x-log' => 'log',
4233 + 'audio/x-m4a' => 'm4a',
4234 + 'application/vnd.mpegurl' => 'm4u',
4235 + 'audio/midi' => 'mid',
4236 + 'application/vnd.mif' => 'mif',
4237 + 'video/quicktime' => 'mov',
4238 + 'video/x-sgi-movie' => 'movie',
4239 + 'audio/mpeg' => 'mp3',
4240 + 'audio/mpg' => 'mp3',
4241 + 'audio/mpeg3' => 'mp3',
4242 + 'audio/mp3' => 'mp3',
4243 + 'video/mp4' => 'mp4',
4244 + 'video/mpeg' => 'mpeg',
4245 + 'application/oda' => 'oda',
4246 + 'application/vnd.oasis.opendocument.text' => 'odt',
4247 + 'application/vnd.oasis.opendocument.spreadsheet' => 'ods',
4248 + 'application/vnd.oasis.opendocument.presentation' => 'odp',
4249 + 'audio/ogg' => 'ogg',
4250 + 'video/ogg' => 'ogg',
4251 + 'application/ogg' => 'ogg',
4252 + 'application/x-pkcs10' => 'p10',
4253 + 'application/pkcs10' => 'p10',
4254 + 'application/x-pkcs12' => 'p12',
4255 + 'application/x-pkcs7-signature' => 'p7a',
4256 + 'application/pkcs7-mime' => 'p7c',
4257 + 'application/x-pkcs7-mime' => 'p7c',
4258 + 'application/x-pkcs7-certreqresp' => 'p7r',
4259 + 'application/pkcs7-signature' => 'p7s',
4260 + 'application/pdf' => 'pdf',
4261 + 'application/octet-stream' => 'pdf',
4262 + 'application/x-x509-user-cert' => 'pem',
4263 + 'application/x-pem-file' => 'pem',
4264 + 'application/pgp' => 'pgp',
4265 + 'application/x-httpd-php' => 'php',
4266 + 'application/php' => 'php',
4267 + 'application/x-php' => 'php',
4268 + 'text/php' => 'php',
4269 + 'text/x-php' => 'php',
4270 + 'application/x-httpd-php-source' => 'php',
4271 + 'image/png' => 'png',
4272 + 'image/x-png' => 'png',
4273 + 'application/powerpoint' => 'ppt',
4274 + 'application/vnd.ms-powerpoint' => 'ppt',
4275 + 'application/vnd.ms-office' => 'ppt',
4276 + 'application/msword' => 'doc',
4277 + 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
4278 + 'application/x-photoshop' => 'psd',
4279 + 'image/vnd.adobe.photoshop' => 'psd',
4280 + 'audio/x-realaudio' => 'ra',
4281 + 'audio/x-pn-realaudio' => 'ram',
4282 + 'application/x-rar' => 'rar',
4283 + 'application/rar' => 'rar',
4284 + 'application/x-rar-compressed' => 'rar',
4285 + 'audio/x-pn-realaudio-plugin' => 'rpm',
4286 + 'application/x-pkcs7' => 'rsa',
4287 + 'text/rtf' => 'rtf',
4288 + 'text/richtext' => 'rtx',
4289 + 'video/vnd.rn-realvideo' => 'rv',
4290 + 'application/x-stuffit' => 'sit',
4291 + 'application/smil' => 'smil',
4292 + 'text/srt' => 'srt',
4293 + 'image/svg+xml' => 'svg',
4294 + 'application/x-shockwave-flash' => 'swf',
4295 + 'application/x-tar' => 'tar',
4296 + 'application/x-gzip-compressed' => 'tgz',
4297 + 'image/tiff' => 'tiff',
4298 + 'text/plain' => 'txt',
4299 + 'text/x-vcard' => 'vcf',
4300 + 'application/videolan' => 'vlc',
4301 + 'text/vtt' => 'vtt',
4302 + 'audio/x-wav' => 'wav',
4303 + 'audio/wave' => 'wav',
4304 + 'audio/wav' => 'wav',
4305 + 'application/wbxml' => 'wbxml',
4306 + 'video/webm' => 'webm',
4307 + 'audio/x-ms-wma' => 'wma',
4308 + 'application/wmlc' => 'wmlc',
4309 + 'video/x-ms-wmv' => 'wmv',
4310 + 'video/x-ms-asf' => 'wmv',
4311 + 'application/xhtml+xml' => 'xhtml',
4312 + 'application/excel' => 'xl',
4313 + 'application/msexcel' => 'xls',
4314 + 'application/x-msexcel' => 'xls',
4315 + 'application/x-ms-excel' => 'xls',
4316 + 'application/x-excel' => 'xls',
4317 + 'application/x-dos_ms_excel' => 'xls',
4318 + 'application/xls' => 'xls',
4319 + 'application/x-xls' => 'xls',
4320 + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
4321 + 'application/vnd.ms-excel' => 'xlsx',
4322 + 'application/xml' => 'xml',
4323 + 'text/xml' => 'xml',
4324 + 'text/xsl' => 'xsl',
4325 + 'application/xspf+xml' => 'xspf',
4326 + 'application/x-compress' => 'z',
4327 + 'application/x-zip' => 'zip',
4328 + 'application/zip' => 'zip',
4329 + 'application/x-zip-compressed' => 'zip',
4330 + 'application/s-compressed' => 'zip',
4331 + 'multipart/x-zip' => 'zip',
4332 + 'text/x-scriptzsh' => 'zsh',
4333 + ];
4334 +
4335 + return isset($mime_map[$mime]) === true ? $mime_map[$mime] : false;
4336 + }
4337 +}
4338 +
4339 +if ( ! function_exists('wdk_is_dash_enabled'))
4340 +{
4341 + /**
4342 + * IS Dash pages exists
4343 + *
4344 + * @return bool true if exists dash
4345 + */
4346 + function wdk_is_dash_enabled() {
4347 + if(function_exists('run_wdk_membership') && wdk_get_option('wdk_membership_dash_page') && get_post_status(wdk_get_option('wdk_membership_dash_page')) =='publish'){
4348 + return true;
4349 + }
4350 +
4351 + return false;
4352 + }
4353 +}
4354 +
4355 +if(!function_exists('wdk_page_by_title')) {
4356 + function wdk_page_by_title ( $page_title, $output = OBJECT, $post_type = 'page' ) {
4357 + global $wpdb;
4358 +
4359 + if ( is_array( $post_type ) ) {
4360 + $post_type = esc_sql( $post_type );
4361 + $post_type_in_string = "'" . implode( "','", $post_type ) . "'";
4362 + $sql = $wpdb->prepare(
4363 + "
4364 + SELECT ID
4365 + FROM $wpdb->posts
4366 + WHERE post_title = %s
4367 + AND post_type IN ($post_type_in_string)
4368 + ",
4369 + $page_title
4370 + );
4371 + } else {
4372 + $sql = $wpdb->prepare(
4373 + "
4374 + SELECT ID
4375 + FROM $wpdb->posts
4376 + WHERE post_title = %s
4377 + AND post_type = %s
4378 + ",
4379 + $page_title,
4380 + $post_type
4381 + );
4382 + }
4383 + $page = $wpdb->get_var( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
4384 +
4385 +
4386 + if ( $page ) {
4387 + return get_post( $page, $output );
4388 + }
4389 +
4390 + return null;
4391 + }
4392 +}
4393 +
4394 +
4395 +if ( ! function_exists('is_wdk_gps_single'))
4396 +{
4397 + function is_wdk_gps_single($param)
4398 + {
4399 +
4400 + if (is_numeric($param) && $param > -180 && $param < 180) {
4401 + return true;
4402 + }
4403 +
4404 + return false;
4405 + }
4406 +}
4407 +
4408 +if ( ! function_exists('wdk_get_tgmpa_link'))
4409 +{
4410 + function wdk_get_tgmpa_link()
4411 + {
4412 + if(file_exists(get_template_directory().'/includes/tgm_pa/class-tgm-plugin-activation.php') || file_exists(get_template_directory().'/tgm_pa/class-tgm-plugin-activation.php')) {
4413 + return get_admin_url() . "themes.php?page=tgmpa-install-plugins";
4414 + } else {
4415 + return get_admin_url() . "plugins.php?page=tgmpa-install-plugins";
4416 + }
4417 +
4418 + return false;
4419 + }
4420 +}
4421 +
4422 +if ( ! function_exists('wdk_sprintf'))
4423 +{
4424 + function wdk_sprintf($string = '')
4425 + {
4426 + $arg_list = func_get_args();
4427 +
4428 + if(count($arg_list)<2) {
4429 + return $string;
4430 + }
4431 +
4432 + if(stripos($string, '%1$s') === FALSE) {
4433 + return $string;
4434 + }
4435 +
4436 + return call_user_func_array("sprintf", $arg_list);
4437 + }
4438 +}
4439 +
4440 +if ( ! function_exists('wdk_db_table'))
4441 +{
4442 + function wdk_db_table($data, $columns = array()) {
4443 + $output = '<table>';
4444 + foreach($data as $key => $var) {
4445 + if($key === 0)
4446 + {
4447 + $output .= '<tr>';
4448 + foreach($var as $k => $v) {
4449 + if(count($columns) > 0 && !in_array($k, $columns))continue;
4450 +
4451 + $output .= '<td><strong>' . esc_html($k) . '</strong></td>';
4452 + }
4453 + $output .= '</tr>';
4454 + }
4455 +
4456 + $output .= '<tr>';
4457 + foreach($var as $k => $v) {
4458 + if(count($columns) > 0 && !in_array($k, $columns))continue;
4459 +
4460 + $output .= '<td>' . esc_html($v) . '</td>';
4461 + }
4462 + $output .= '</tr>';
4463 + }
4464 + $output .= '</table>';
4465 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.WP.I18n.NonSingularStringLiteralText
4466 + echo $output;
4467 + }
4468 +}
4469 +
4470 +if ( ! function_exists('wdk_move_gps'))
4471 +{
4472 + function wdk_move_gps($value) {
4473 + return $value+0.001 * wp_rand(1, 9);
4474 + }
4475 +}
4476 +
4477 +if ( ! function_exists('wdk_get_near_location'))
4478 +{
4479 + function wdk_get_near_location($latitude, $longitude, $radius = 10000) {
4480 + // Convert radius from meters to degrees
4481 + $radiusInDegrees = $radius / 111000;
4482 +
4483 + $u = wp_rand() / mt_getrandmax();
4484 + $v = wp_rand() / mt_getrandmax();
4485 + $w = $radiusInDegrees * sqrt($u);
4486 + $t = 2 * M_PI * $v;
4487 + $x = $w * cos($t);
4488 + $y = $w * sin($t);
4489 +
4490 + // Adjust the x-coordinate for the shrinking of the east-west distances
4491 + $newX = $x / cos(deg2rad($latitude));
4492 +
4493 + $newLongitude = $longitude + $newX;
4494 + $newLatitude = $latitude + $y;
4495 +
4496 + return array('lat' => $newLatitude, 'lng' => $newLongitude);
4497 + }
4498 +}
4499 +
4500 +if ( ! function_exists('wdk_is_listing_preview_page'))
4501 +{
4502 + function wdk_is_listing_preview_page() {
4503 + global $wdk_listing_id;
4504 +
4505 + if(!empty($wdk_listing_id))
4506 + return TRUE;
4507 +
4508 + return FALSE;
4509 + }
4510 +}
4511 +
4512 +if ( ! function_exists('wdk_is_listing_field_exists'))
4513 +{
4514 + function wdk_is_listing_field_exists($field_name = '', $udpate_cache = FALSE) {
4515 + static $available_fields_listings = array();
4516 + $custom_fields = array();
4517 +
4518 + $WMVC = &wdk_get_instance();
4519 + $WMVC->model('listingfield_m');
4520 +
4521 + if(empty($available_fields_listings) || $udpate_cache) {
4522 + $available_fields_listings = $WMVC->listingfield_m->get_available_fields();
4523 + }
4524 +
4525 + if(isset($available_fields_listings[$field_name]) || isset($custom_fields[$field_name])) {
4526 + return TRUE;
4527 + }
4528 +
4529 + return FALSE;
4530 + }
4531 +}
4532 +
4533 +if ( ! function_exists('wdk_cached_field_get'))
4534 +{
4535 + function wdk_cached_field_get($udpate_cache = FALSE) {
4536 + static $fields = NULL;
4537 +
4538 + $WMVC = &wdk_get_instance();
4539 + $WMVC->model('field_m');
4540 +
4541 + if(is_null($fields) || $udpate_cache) {
4542 + $fields = $WMVC->field_m->get();
4543 + }
4544 +
4545 + return $fields;
4546 + }
4547 +}
4548 +
4549 +if (! function_exists('wdk_generate_slug'))
4550 +{
4551 + function wdk_generate_slug($str, $separator = 'dash', $lowercase = TRUE)
4552 + {
4553 + if ($separator == 'dash')
4554 + {
4555 + $search = '_';
4556 + $replace = '-';
4557 + }
4558 + else
4559 + {
4560 + $search = '-';
4561 + $replace = '_';
4562 + }
4563 +
4564 + $dot='';
4565 + if($separator == 'dot'){
4566 + $str = str_replace(' ', '.', $str);
4567 + $dot='.';
4568 + }
4569 +
4570 + $trans = array(
4571 + $search => $replace,
4572 + "\s+" => $replace,
4573 + "[^a-z0-9".$replace.$dot."]" => '',
4574 + $replace."+" => $replace,
4575 + $replace."$" => '',
4576 + "^".$replace => ''
4577 + );
4578 +
4579 + // For Croatia
4580 + $str = str_replace(array('č','ć','ž','š','đ', 'Č','Ć','Ž','Š','Đ'),
4581 + array('c','c','z','s','d', 'c','c','z','s','d'), $str);
4582 +
4583 + // For Turkish
4584 + $str = str_replace(array('ş','Ş','ı','İ','ğ','Ğ','Ü','ü','Ö','ö','ç','Ç'),
4585 + array('s','s','i','i','g','g','u','u','o','o','c','c'), $str);
4586 +
4587 + // Russian alphabet
4588 + $str = str_replace(array('А','Б','В','Г','Д','Е','Ё','Ж','З','И','Й','К','Л','М','Н','О','П','Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я'),
4589 + array('a','b','v','g','d','e','e','zh','z','i','y','k','l','m','n','o','p','r','s','t','u','f','kh','c','ch','sh','sh','','y','','e','yu','ya'), $str);
4590 + $str = str_replace(array('а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п','р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я'),
4591 + array('a','b','v','g','d','e','e','zh','z','i','y','k','l','m','n','o','p','r','s','t','u','f','kh','c','ch','sh','sh','','y','','e','yu','ya'), $str);
4592 +
4593 + // Ukrainian alphabet
4594 + $str = str_replace(array('Ґ','Є','І','Ї'),
4595 + array('G','E','I','I'), $str);
4596 + $str = str_replace(array('ґ','є','і','ї'),
4597 + array('g','e','i','i'), $str);
4598 + // Symbols
4599 + $str = str_replace(array("  ","’","–",'«','»','№','„','”'),
4600 + array("","","-",'','','no','',''), $str);
4601 +
4602 + // Alphabets Czech Croatian Turkish and other
4603 + $str = str_replace(array('Á','Ä','Ď','É','Ě','Ë','Í','Ň','Ń','Ó','Ŕ','Ř','Ť','Ú','Ů','Ý','Ź','Č','Ć','Ž','Š','Đ','Ş','İ','Ğ','Ü','Ö','Ç'),
4604 + array('a','a','d','e','e','e','i','n','n','o','r','r','t','u','u','y','z','c','c','z','s','d','s','i','g','u','o','c'), $str);
4605 + $str = str_replace(array('á','ä','ď','é','ě','ë','í','ň','ń','ó','ŕ','ř','ť','ú','ů','ý','ź','č','ć','ž','š','đ','ş','ı','ğ','ü','ö','ç'),
4606 + array('a','a','d','e','e','e','i','n','n','o','r','r','t','u','u','y','z','c','c','z','s','d','s','i','g','u','o','c'), $str);
4607 +
4608 + // For french
4609 + $str = str_replace(array('â','é','è','û','ê', 'à','Â','ç','ï','î','ä','î'),
4610 + array('a','e','e','u','e', 'a','c','c','i','î','a','î'), $str);
4611 +
4612 + $str = wp_strip_all_tags(strtolower($str));
4613 +
4614 +
4615 + foreach ($trans as $key => $val)
4616 + {
4617 + $str = preg_replace("#".$key."#", $val, $str);
4618 + }
4619 +
4620 + return trim(stripslashes($str));
4621 + }
4622 +}
4623 +
4624 +
4625 +if (! function_exists('wdk_is_gps'))
4626 +{
4627 + function wdk_is_gps($gps = '')
4628 + {
4629 +
4630 + if(stripos($gps,',') === FALSE) {
4631 + return FALSE;
4632 + }
4633 +
4634 + $gps_coor = explode(',', $gps);
4635 +
4636 + if(count($gps_coor) != 2)
4637 + {
4638 + return FALSE;
4639 + }
4640 +
4641 + if(!is_numeric($gps_coor[0]) || !is_numeric($gps_coor[1]))
4642 + {
4643 + return FALSE;
4644 + }
4645 +
4646 + if($gps_coor[0] < -90 || $gps_coor[0] > 90 || $gps_coor[1] < -180 || $gps_coor[1] > 180)
4647 + {
4648 + return FALSE;
4649 + }
4650 +
4651 + return TRUE;
4652 + }
4653 +}
4654 +
4655 +if ( ! function_exists('is_wdk_is_useremail_exists'))
4656 +{
4657 + function is_wdk_is_useremail_exists($param)
4658 + {
4659 +
4660 + if(null == username_exists( $param ) && !email_exists($param)) {
4661 + return true;
4662 + }
4663 +
4664 + return false;
4665 + }
4666 +}
4667 +
4668 +
4669 +/*
4670 + Validation is natural integer
4671 +*/
4672 +if ( ! function_exists('is_wdk_is_natural'))
4673 +{
4674 + function is_wdk_is_natural($param)
4675 + {
4676 +
4677 + if (is_intval($param) && stripos($param, '.') === FALSE && stripos($param, ',') === FALSE) {
4678 + return true;
4679 + }
4680 +
4681 + return false;
4682 + }
4683 +}
4684 +
4685 +
4686 +/**
4687 + * Check is listing preview page exits
4688 + *
4689 + * @return bool
4690 +*/
4691 +if ( ! function_exists('wdk_is_listing_page_enabled'))
4692 +{
4693 + function wdk_is_listing_page_enabled ()
4694 + {
4695 +
4696 + if(get_option('wdk_listing_page') && get_post_status(get_option('wdk_listing_page')) =='publish') {
4697 + return true;
4698 + }
4699 +
4700 + return false;
4701 + }
4702 +}
4703 +
4704 +
4705 +/**
4706 + * Check is listing preview page exits
4707 + *
4708 + * @return bool
4709 +*/
4710 +if ( ! function_exists('replace_smart_data'))
4711 +{
4712 + function replace_smart_data($output = '', $replace_data = array()) {
4713 + // Match all occurrences of the pattern
4714 + if (preg_match_all('/\{([^}]+)\}/', $output, $matches)) {
4715 + foreach ($matches[1] as $key => $value) {
4716 + foreach ($replace_data as $replace_key => $replace_value) {
4717 + $output = str_replace('{'.$replace_key.'}', $replace_value, $output);
4718 + }
4719 + }
4720 + }
4721 + return $output;
4722 + }
4723 +}
4724 +
4725 +if ( ! function_exists('wdk_generate_missing_image_sizes'))
4726 +{
4727 + /**
4728 + * Wdk_generate_missing_image_sizes and update meta
4729 + * @param int $attachment_id of iamge
4730 + * @param string $size_name size of image based on wp intermediate_size
4731 + *
4732 + * @return bool
4733 + */
4734 + function wdk_generate_missing_image_sizes($attachment_id, $size_name = '') {
4735 + if(empty($size_name) || $size_name == 'full' || !get_option( "{$size_name}_size_w" )) {
4736 + return true;
4737 + }
4738 +
4739 + // Check if the attachment is an image
4740 + if (!wp_attachment_is_image($attachment_id)) {
4741 + return false;
4742 + }
4743 +
4744 + $file = get_attached_file( $attachment_id );
4745 + require_once(ABSPATH . "wp-admin" . '/includes/image.php');
4746 + $metadata = wp_generate_attachment_metadata($attachment_id, $file);
4747 + if ( ! isset( $metadata['sizes'][ $size_name ] ) ) {
4748 + // Generate the missing image size
4749 + $resized = image_make_intermediate_size( $file, get_option( "{$size_name}_size_w" ), get_option( "{$size_name}_size_h" ), get_option( "{$size_name}_crop" ) );
4750 +
4751 + // If the resizing was successful, add it to the metadata
4752 + if ( $resized ) {
4753 + $metadata['sizes'][ $size_name ] = $resized;
4754 + wp_update_attachment_metadata( $attachment_id, $metadata );
4755 + }
4756 + }
4757 + return true;
4758 + }
4759 +}
4760 +
4761 +if (!function_exists('wdk_get_languages')) {
4762 +
4763 + function wdk_get_languages($lang_code_id = null)
4764 + {
4765 + $lang_pattern = ['title' => '', 'lang_code' => '', 'id' => '', 'icon' => '', 'url' => ''];
4766 + $languages = [];
4767 +
4768 + // [qTranslate X]
4769 + if (function_exists('qtranxf_getSortedLanguages')) {
4770 + global $q_config;
4771 +
4772 + if (empty($q_config)) {
4773 + // Initialize qTranslate X language settings if needed
4774 + // qtranxf_init_language();
4775 + }
4776 +
4777 + $all_langs = qtranxf_getSortedLanguages();
4778 + if (count($all_langs) > 0) {
4779 + foreach ($all_langs as $key => $lang_code) {
4780 + $languages[$key + 1] = array_merge(
4781 + $lang_pattern,
4782 + [
4783 + 'title' => $q_config['language_name'][$lang_code],
4784 + 'lang_code' => $lang_code,
4785 + 'id' => $key + 1,
4786 + 'icon' => '',
4787 + 'url' => wdk_get_language_url($lang_code),
4788 + ]
4789 + );
4790 + }
4791 + }
4792 + }
4793 + // [/qTranslate X]
4794 +
4795 + // [WPML]
4796 + if (function_exists('icl_get_languages')) {
4797 + $wpml_langs = icl_get_languages('orderby=KEY&order=DIR&link_empty_to=str');
4798 + $k = 1;
4799 + foreach ($wpml_langs as $key => $lang_data) {
4800 + $languages[$k] = array_merge(
4801 + $lang_pattern,
4802 + [
4803 + 'title' => (!empty($lang_data['translated_name'])) ? $lang_data['translated_name'] : $lang_data['native_name'],
4804 + 'lang_code' => $lang_data['language_code'],
4805 + 'id' => $k,
4806 + 'icon' => (!empty($lang_data['country_flag_url'])) ? $lang_data['country_flag_url'] : WPDIRECTORYKIT_URL.'public/img/flags/'.$lang_data['language_code'].'.png',
4807 + 'url' => wdk_get_language_url($lang_data['language_code']),
4808 + ]
4809 + );
4810 + $k++;
4811 + }
4812 + } elseif (has_filter('wpml_active_languages')) {
4813 + $wpml_langs = apply_filters('wpml_active_languages', null) ?: get_query_var('lang', 'all');
4814 + if (is_array($wpml_langs)) {
4815 + foreach ($wpml_langs as $lang_data) {
4816 + if (!isset($lang_data['code']) && isset($lang_data['language_code'])) {
4817 + $lang_data['code'] = $lang_data['language_code'];
4818 + }
4819 + if (empty($lang_data['translated_name']) && !empty($lang_data['native_name'])) {
4820 + $lang_data['translated_name'] = $lang_data['native_name'];
4821 + }
4822 + $languages[$lang_data['id']] = array_merge(
4823 + $lang_pattern,
4824 + [
4825 + 'title' => (!empty($lang_data['translated_name'])) ? $lang_data['translated_name'] : $lang_data['native_name'],
4826 + 'lang_code' => $lang_data['code'],
4827 + 'id' => $lang_data['id'],
4828 + 'icon' => (!empty($lang_data['country_flag_url'])) ? $lang_data['country_flag_url'] : WPDIRECTORYKIT_URL.'public/img/flags/'.$lang_data['language_code'].'.png',
4829 + 'url' => wdk_get_language_url($lang_data['code']),
4830 + ]
4831 + );
4832 + }
4833 + }
4834 + }
4835 + // [/WPML]
4836 +
4837 + // [TranslatePress]
4838 + if (function_exists('trp_custom_language_switcher')) {
4839 + $k = 1;
4840 + foreach (trp_custom_language_switcher() as $lang_data) {
4841 + $languages[$k++] = array_merge(
4842 + $lang_pattern,
4843 + [
4844 + 'title' => $lang_data['language_name'],
4845 + 'lang_code' => $lang_data['language_code'],
4846 + 'id' => $k,
4847 + 'icon' => $lang_data['flag_link'],
4848 + 'url' => $lang_data['current_page_url'],
4849 + ]
4850 + );
4851 + }
4852 + }
4853 + // [/TranslatePress]
4854 +
4855 + if (!empty($lang_code_id)) {
4856 + foreach ($languages as $lang) {
4857 + if (($lang['id'] == $lang_code_id) || ($lang['lang_code'] == $lang_code_id)) {
4858 + return $lang['id'] == $lang_code_id ? $lang['lang_code'] : $lang['id'];
4859 + }
4860 + }
4861 + return false;
4862 + }
4863 +
4864 + return $languages;
4865 + }
4866 +}
4867 +
4868 +if (!function_exists('wdk_default_language')) {
4869 + function wdk_default_language()
4870 + {
4871 + // [qTranslate X]
4872 + if (function_exists('qtranxf_getLanguageDefault')) {
4873 + return qtranxf_getLanguageDefault();
4874 + }
4875 + // [/qTranslate X]
4876 +
4877 + // [WPML]
4878 + if (function_exists('icl_get_languages')) {
4879 + $wpml_langs = icl_get_languages('orderby=KEY&order=DIR&link_empty_to=str');
4880 + foreach ($wpml_langs as $lang_data) {
4881 + if ($lang_data['major'] == 1) {
4882 + return $lang_data['code'];
4883 + }
4884 + }
4885 + } elseif (has_filter('wpml_default_language')) {
4886 + return apply_filters('wpml_default_language', null);
4887 + }
4888 + // [/WPML]
4889 +
4890 + return 'en';
4891 + }
4892 +}
4893 +
4894 +if (!function_exists('wdk_current_language')) {
4895 + function wdk_current_language()
4896 + {
4897 + if (function_exists('trp_get_languages')) {
4898 + global $TRP_LANGUAGE;
4899 + $trp = TRP_Translate_Press::get_trp_instance();
4900 + $settings = $trp->get_component('settings')->get_settings();
4901 + $translation_languages = $trp->get_component('languages')->get_language_names($settings['publish-languages']);
4902 + if (isset($translation_languages[$TRP_LANGUAGE])) {
4903 + return $translation_languages[$TRP_LANGUAGE];
4904 + }
4905 + }
4906 +
4907 + // [qTranslate X]
4908 + if (function_exists('qtranxf_getLanguage')) {
4909 + return qtranxf_getLanguage();
4910 + }
4911 + // [/qTranslate X]
4912 +
4913 + // [WPML]
4914 + if (function_exists('icl_get_languages')) {
4915 + $wpml_langs = icl_get_languages('orderby=KEY&order=DIR&link_empty_to=str');
4916 + foreach ($wpml_langs as $lang_data) {
4917 + if ($lang_data['active'] == 1) {
4918 + return (!empty($lang_data['native_name'])) ? $lang_data['native_name'] : $lang_data['language_code'];
4919 + }
4920 + }
4921 + } elseif (has_filter('wpml_current_language')) {
4922 + return apply_filters('wpml_current_language', null);
4923 + }
4924 + // [/WPML]
4925 +
4926 + return 'en';
4927 + }
4928 +}
4929 +
4930 +if (!function_exists('wdk_current_language_id')) {
4931 + function wdk_current_language_id()
4932 + {
4933 + $lang_id = wdk_get_languages(wdk_current_language());
4934 + return is_numeric($lang_id) ? $lang_id : wdk_default_language_id();
4935 + }
4936 +}
4937 +
4938 +if (!function_exists('wdk_default_language_id')) {
4939 + function wdk_default_language_id()
4940 + {
4941 + $lang_id = wdk_get_languages(wdk_default_language());
4942 + return is_numeric($lang_id) ? $lang_id : '1';
4943 + }
4944 +}
4945 +
4946 +if (!function_exists('wdk_get_language_name')) {
4947 + function wdk_get_language_name($id_or_code)
4948 + {
4949 + $langs = wdk_get_languages();
4950 + foreach ($langs as $lang) {
4951 + if ($lang['lang_code'] == $id_or_code || $lang['id'] == $id_or_code) {
4952 + return $lang['title'];
4953 + }
4954 + }
4955 + return '';
4956 + }
4957 +}
4958 +
4959 +if (!function_exists('wdk_get_language_url')) {
4960 + function wdk_get_language_url($lang_code)
4961 + {
4962 + // [qTranslate X]
4963 + if (function_exists('qtranxf_convertURL')) {
4964 + return qtranxf_convertURL('', $lang_code, false, true);
4965 + }
4966 + // [/qTranslate X]
4967 +
4968 + // [WPML]
4969 + if (function_exists('icl_get_languages')) {
4970 + $wpml_langs = icl_get_languages('orderby=KEY&order=DIR&link_empty_to=str');
4971 + foreach ($wpml_langs as $lang_data) {
4972 + if ($lang_data['language_code'] == $lang_code) {
4973 + return $lang_data['url'];
4974 + }
4975 + }
4976 + } elseif (has_filter('wpml_active_languages')) {
4977 + $wpml_langs = apply_filters('wpml_active_languages', null);
4978 + foreach ($wpml_langs as $lang_data) {
4979 + if (!isset($lang_data['language_code']) && isset($lang_data['language_code'])) {
4980 + $lang_data['language_code'] = $lang_data['language_code'];
4981 + }
4982 + if (empty($lang_data['translated_name']) && !empty($lang_data['native_name'])) {
4983 + $lang_data['translated_name'] = $lang_data['native_name'];
4984 + }
4985 + $url = wdk_wpml_ls_language_url($lang_data['url'], $lang_data);
4986 + if ($lang_data['language_code'] == $lang_code) {
4987 + return $url;
4988 + }
4989 + }
4990 + }
4991 + // [/WPML]
4992 +
4993 + return '';
4994 + }
4995 +}
4996 +
4997 +function wdk_set_user_default_language($user_id = null)
4998 +{
4999 + if (is_null($user_id)) {
5000 + $user_id = get_current_user_id();
5001 + }
5002 +
5003 + $get_language = get_user_meta($user_id, 'user_language', true);
5004 +
5005 + if (!$get_language && (function_exists('icl_get_languages') || has_filter('wpml_active_languages'))) {
5006 + do_action('wpml_switch_language', $get_language);
5007 + }
5008 +}
5009 +
5010 +function wdk_set_language($lang_code = null)
5011 +{
5012 + if (!is_null($lang_code) && (function_exists('icl_get_languages') || has_filter('wpml_active_languages'))) {
5013 + do_action('wpml_switch_language', $lang_code);
5014 + }
5015 +}
5016 +
5017 +function wdk_wpml_ls_language_url($url, $data)
5018 +{
5019 + global $sitepress;
5020 +
5021 + if (is_object($sitepress)) {
5022 + $sitepress_settings = $sitepress->get_settings();
5023 + }
5024 +
5025 + return $url;
5026 +}
5027 +
5028 +add_filter('wpml_ls_language_url', 'wdk_wpml_ls_language_url', 10, 3);
5029 +
5030 +if (!function_exists('wdk_calculate_nights')) {
5031 + /**
5032 + * Calculate the number of nights between two dates
5033 + *
5034 + * This function takes two date strings as input and calculates the number of nights
5035 + * (i.e., the difference in days) between them. It returns the total number of nights
5036 + * between the provided start and end dates. The date format must be valid for PHP's
5037 + * DateTime class.
5038 + *
5039 + * @param string $start_date The start date in 'Y-m-d' format.
5040 + * @param string $end_date The end date in 'Y-m-d' format.
5041 + * @return int The number of nights (days between the two dates).
5042 + */
5043 + function wdk_calculate_nights($start_date, $end_date) {
5044 +
5045 + /* normalize date */
5046 + $start_date = wdk_normalize_date_db($start_date, 'Y-m-d H:i:s', 'Y-m-d');
5047 + $end_date = wdk_normalize_date_db($end_date, 'Y-m-d H:i:s', 'Y-m-d');
5048 +
5049 + // Create DateTime objects for start and end dates
5050 + $start = new DateTime($start_date);
5051 + $end = new DateTime($end_date);
5052 +
5053 + // Calculate the difference between the two dates
5054 + $difference = $start->diff($end);
5055 +
5056 + // Return the number of nights (difference in days)
5057 + return $difference->days;
5058 + }
5059 +}
5060 +
5061 +if ( ! function_exists('wdk_select_db_field_ajax'))
5062 +{
5063 + /**
5064 + * Return select2 ajax
5065 + *
5066 + * @param string option Option key
5067 + * @return string alt or title
5068 + */
5069 + function wdk_select_db_field_ajax($name = '', $selected = NULL, $empty_value='', $filter_id = '')
5070 + {
5071 + $WMVC = &wdk_get_instance();
5072 +
5073 + static $counter = 0;
5074 + $form = '<select data-ajax="'.esc_url(admin_url('admin-ajax.php')).'" name="'.$name.'" data-id="'.$filter_id.'" data-placeholder="'.$empty_value.'" class="form-control wdk_select2_field_suggestion" id="wdk_select2_field_'.$filter_id.'_'.$counter.'" multiple="">';
5075 + if($selected) {
5076 + if(is_array($selected)) {
5077 + /* where in */
5078 + foreach ($selected as $item) {
5079 + $form .= '<option selected="selected" value="'.esc_attr($item).'">'.esc_html($item).'</option>';
5080 + }
5081 + } elseif(is_string($selected)) {
5082 + $form .= '<option selected="selected" value="'.esc_attr($selected).'">'.esc_html($selected).'</option>';
5083 + }
5084 + } else {
5085 + //$form .= '<option value="" selected="selected">'.esc_html__('Not selected', 'wpdirectorykit').'</option>';
5086 + }
5087 + $form .= '</select>';
5088 +
5089 + //load javascript library
5090 + if($counter==0)
5091 + {
5092 + wp_enqueue_script('select2-select2');
5093 + wp_enqueue_script('wdk-select2');
5094 + wp_enqueue_style('select2-select2');
5095 + }
5096 + ?>
5097 + <?php
5098 + $counter++;
5099 + return $form;
5100 +
5101 + }
5102 +}
5103 +
5104 +if ( ! function_exists('wdk_next_month_payment_day'))
5105 +{
5106 + /**
5107 + * Gets the next payment date one month later, considering the number of days in the next month.
5108 + *
5109 + * @param string $currentDate The current payment date in 'Y-m-d H:i:s' format.
5110 + * @return string|false The next payment date in 'Y-m-d H:i:s' format or false on error.
5111 + */
5112 + function wdk_next_month_payment_day($currentDate, $time = false, $wanted_day = NULL) {
5113 + $nextDate = null;
5114 + $timestamp = strtotime($currentDate);
5115 + $daysInNextMonth = gmdate('t', strtotime('+1 month', strtotime(gmdate('Y-m', $timestamp))));
5116 + $currentDay = (int)gmdate('d', $timestamp);
5117 +
5118 + $timeFormat = $time ? "H:i:s" : "00:00:00";
5119 +
5120 +
5121 + // Determine the wanted day
5122 + if ($wanted_day !== NULL) {
5123 + $wanted_day = (int)gmdate('d', strtotime($wanted_day));
5124 + } else {
5125 + $wanted_day = (int)gmdate('d', $timestamp);
5126 + }
5127 +
5128 + $nextMonth = strtotime('first day of next month', $timestamp);
5129 + $daysInNextMonth = gmdate('t', $nextMonth);
5130 +
5131 + // Adjust for the wanted day
5132 + if ($wanted_day > $daysInNextMonth ||
5133 + (
5134 + get_option('wdk_membership_next_month_calculation_with_last_day')
5135 +
5136 + && (
5137 + $currentDay >= 30 || $currentDay == gmdate('t', $timestamp)
5138 + )
5139 + )
5140 + ) {
5141 + // If the wanted day exceeds the max days of the next month, use the last day of the month
5142 + $nextDate = gmdate("Y-m-{$daysInNextMonth} {$timeFormat}", $nextMonth);
5143 + } else {
5144 + // Otherwise, set the exact wanted day
5145 + $nextDate = gmdate("Y-m-{$wanted_day} {$timeFormat}", $nextMonth);
5146 + }
5147 +
5148 + return ($nextDate) ? $nextDate : false;
5149 + }
5150 +}
5151 +
5152 +if ( ! function_exists('wdk_next_year_payment_day'))
5153 +{
5154 + /**
5155 + * Gets the next payment date one year later, considering the number of days in the next month.
5156 + *
5157 + * @param string $currentDate The current payment date in 'Y-m-d H:i:s' format.
5158 + * @return string|false The next payment date in 'Y-m-d H:i:s' format or false on error.
5159 + */
5160 +
5161 + function wdk_next_year_payment_day($currentDate, $time = false) {
5162 + $nextDate = null;
5163 + $timestamp = strtotime($currentDate);
5164 + $nextYearTimestamp = strtotime('+1 year', strtotime(gmdate('Y-m', $timestamp)));
5165 + $daysInNextMonth = gmdate('t', $nextYearTimestamp);
5166 + $currentDay = gmdate('j', $timestamp);
5167 + $timeFormat = "00:00:00";
5168 + if($time) {
5169 + $timeFormat = "H:i:s";
5170 + }
5171 + if ($currentDay > $daysInNextMonth) {
5172 + $nextDate = gmdate('Y-m-d '.$timeFormat, strtotime('last day of this month', $nextYearTimestamp));
5173 + } else {
5174 + $nextDate = gmdate('Y-m-d '.$timeFormat, strtotime('+1 year', $timestamp));
5175 + }
5176 +
5177 + return ($nextDate) ? $nextDate : false;
5178 + }
5179 +}
5180 +
5181 +if ( ! function_exists('wdk_generate_auto_login_link'))
5182 +{
5183 + function wdk_generate_auto_login_link( $user_id = null ) {
5184 + $token = substr(md5($user_id.NONCE_KEY.'wpdirectorykit'),0,10);
5185 +
5186 + $login_url = site_url( "/?auto-login=1&user_id={$user_id}&token={$token}" );
5187 + return $login_url;
5188 + }
5189 +}
5190 +
5191 +if ( ! function_exists('wdk_get_user_subscription_id'))
5192 +{
5193 + function wdk_get_user_subscription_id($user_id = null) {
5194 + global $Winter_MVC_wdk_membership;
5195 + if(!isset($Winter_MVC_wdk_membership)) {
5196 + return false;
5197 + }
5198 + $Winter_MVC_wdk_membership->model('subscription_user_m');
5199 + $user_subscription = $Winter_MVC_wdk_membership->subscription_user_m->get_by(array('user_id'=>$user_id), TRUE);
5200 + return wmvc_show_data('subscription_id', $user_subscription, '', TRUE, TRUE);
5201 + }
5202 +}
5203 +
5204 +if ( ! function_exists('is_wdk_related_validation'))
5205 + /**
5206 + * IS WDK related validation
5207 + *
5208 + * @return bool true if exists dash
5209 + */
5210 + {
5211 + function is_wdk_related_validation($param)
5212 + {
5213 +
5214 + if(empty($param)) {
5215 + return TRUE;
5216 + }
5217 +
5218 + $listing_id = (!empty($_GET['id'])) ? intval(sanitize_text_field($_GET['id'])) : null;
5219 +
5220 +
5221 + global $Winter_MVC_WDK;
5222 + $Winter_MVC_WDK->model('listing_m');
5223 +
5224 + $Winter_MVC_WDK->db->select('post_id');
5225 + $Winter_MVC_WDK->db->where(array(
5226 + '(post_id IN ('.esc_sql(sanitize_text_field($param)).'))' => NULL,
5227 + '((`listing_related_ids` IS NOT NULL AND `listing_related_ids` !="") OR (`listing_parent_post_id` IS NOT NULL AND `listing_parent_post_id` !=0))' => NULL,
5228 + ));
5229 +
5230 + if($listing_id) {
5231 + $Winter_MVC_WDK->db->where(array(
5232 + '`listing_parent_post_id` !='.esc_sql($listing_id).'' => NULL,
5233 + ));
5234 + }
5235 +
5236 + $Winter_MVC_WDK->db->from($Winter_MVC_WDK->listing_m->_table_name);
5237 + $Winter_MVC_WDK->db->limit(5);
5238 +
5239 + $Winter_MVC_WDK->db->get();
5240 + if ($Winter_MVC_WDK->db->num_rows() > 0) {
5241 + $db_results = $Winter_MVC_WDK->db->results();
5242 + } else {
5243 + $db_results = null;
5244 + }
5245 +
5246 + if (!empty($db_results)) {
5247 + return false;
5248 + }
5249 +
5250 + return TRUE;
5251 + }
5252 + }
5253 +
5254 + /**
5255 + * Renders an Elementor template by its title or post ID.
5256 + *
5257 + * Attempts to find and render an Elementor layout/template using the post title or post ID.
5258 + * If the post is found and public, its rendered Elementor content is returned, otherwise post content fallback or error.
5259 + *
5260 + * @since 1.0.0
5261 + * @param string|int $title The title (or ID if $id=true) of the Elementor template to render.
5262 + * @param bool $id Optional. If true, $title is treated as a post ID. If false (default), searches by title.
5263 + * @return string|false Rendered template HTML on success, public/content fallback, or error message/false on failure.
5264 + */
5265 + function wdk_render_elementor_template( $title, $id = false ) {
5266 + // Initialize variables.
5267 + $layout_id = null;
5268 + $template_content = '';
5269 +
5270 + // Determine the layout/post ID.
5271 + if ( ! $id ) {
5272 + // Search by post title. Returns WP_Post/object or null.
5273 + $found_post = wdk_page_by_title( $title, OBJECT, ['elementor_library','page'] );
5274 + $layout_id = $found_post ? $found_post->ID : null;
5275 +
5276 + // Support WPML translation if present.
5277 + // The filter may change $layout_id to a translated post's ID if needed.
5278 + $layout_id = apply_filters( 'wpml_object_id', $layout_id, 'elementor_library', true );
5279 + } else {
5280 + // ID provided directly.
5281 + $layout_id = intval($title);
5282 + }
5283 +
5284 + // Early return if no valid layout found.
5285 + if ( empty( $layout_id ) ) {
5286 + return false;
5287 + }
5288 +
5289 + // Get post object (Elementor template or WP Page).
5290 + $post_data = get_post( $layout_id );
5291 +
5292 +
5293 + // Validate post: should exist, be published, and not password protected.
5294 + if ( ! $post_data || $post_data->post_status !== 'publish' || post_password_required( $post_data ) ) {
5295 + return esc_html__( 'Layout is not public', 'wpdirectorykit' );
5296 + }
5297 +
5298 + // Render content depending on post type.
5299 + if (
5300 + ( isset($post_data->post_type) && $post_data->post_type === 'elementor_library' ) ||
5301 + ( isset($post_data->post_type) && $post_data->post_type === 'page' )
5302 + ) {
5303 + // Try to render using Elementor's frontend builder.
5304 + if ( class_exists('\Elementor\Plugin') && method_exists('\Elementor\Plugin', 'instance') ) {
5305 + $elementor_instance = \Elementor\Plugin::instance();
5306 + $content = $elementor_instance->frontend->get_builder_content_for_display( $layout_id );
5307 + $template_content = ! empty( $content ) ? $content : $post_data->post_content;
5308 + } else {
5309 + // Elementor not present; fallback to post content.
5310 + $template_content = $post_data->post_content;
5311 + }
5312 + } else {
5313 + // Non-Elementor post types, fallback to post content.
5314 + $template_content = $post_data->post_content;
5315 + }
5316 +
5317 + /**
5318 + * Filter: Allows modification of the rendered Elementor template content before returning.
5319 + *
5320 + * @param string $template_content The rendered template content.
5321 + * @param int $layout_id The ID of the layout/template.
5322 + * @param WP_Post $post_data The WP_Post object of the layout/template.
5323 + */
5324 + return apply_filters( 'wdk_render_elementor_template_output', $template_content, $layout_id, $post_data );
5325 + }
5326 +
5327 + if(!function_exists('wdk_esc_sql')) {
5328 + function wdk_esc_sql($value = '', $strict = false) {
5329 + $patterns = [
5330 + '/\bselect\b/i',
5331 + '/\binsert\b/i',
5332 + '/\bupdate\b/i',
5333 + '/\bdelete\b/i',
5334 + '/\bunion\b/i',
5335 + '/\bextractvalue\b/i',
5336 + '/\bversion\s*\(\)/i',
5337 + '/\bdatabase\s*\(\)/i',
5338 + '/\bconcat\s*\(/i',
5339 + '/\bdrop\b/i',
5340 + '/\bsleep\s*\(/i',
5341 + '/\bbenchmark\s*\(/i',
5342 + '/--/',
5343 + '/#/i',
5344 + '/\/\*/',
5345 +
5346 + // EXTRA BLOCK YOU REQUESTED
5347 + '/\\\\/', // remove backslash \
5348 + '/\|/', // remove |
5349 + '/%/', // remove %
5350 + ];
5351 +
5352 + // If strict mode is enabled, block additional patterns
5353 + if ($strict === true) {
5354 + $strict_patterns = [
5355 + '/\bif\b\s*\(/i',
5356 + '/\bord\b/i',
5357 + '/\bsubstr\s*\(/i',
5358 + '/\bschema\s*\(\)/i',
5359 + '/@@version/i',
5360 + ];
5361 + $patterns = array_merge($patterns, $strict_patterns);
5362 + }
5363 +
5364 + return esc_sql(trim(preg_replace($patterns, '', sanitize_text_field($value))));
5365 + }
5366 + }
5367 +
5368 + if(!function_exists('wdk_esc_sql_order_by')) {
5369 + function wdk_esc_sql_order_by($value = '', array $allowed_fields = [])
5370 + {
5371 + if (empty($value) || empty($allowed_fields)) {
5372 + return '';
5373 + }
5374 + $result = [];
5375 + foreach (explode(',', $value) as $part) {
5376 + $part = trim(sanitize_text_field($part));
5377 +
5378 + $direction = 'ASC';
5379 + if (preg_match('/\s+(ASC|DESC)$/i', $part, $match)) {
5380 + $direction = strtoupper($match[1]);
5381 + $part = trim(substr($part, 0, -strlen($match[0])));
5382 + }
5383 +
5384 + $part = sanitize_key($part);
5385 +
5386 + if (in_array($part, $allowed_fields, true)) {
5387 + $result[] = $part . ' ' . $direction;
5388 + }
5389 + }
5390 +
5391 + return implode(', ', $result);
5392 + }
5393 + }
5394 +
5395 + if(!function_exists('wdk_listing_seo_title')) {
5396 + function wdk_listing_seo_title () {
5397 + static $cached_seo_title = null;
5398 + if ($cached_seo_title !== null) {
5399 + return $cached_seo_title;
5400 + }
5401 +
5402 + $seo_title ='';
5403 + global $wp_query;
5404 + $wdk_listing_id = $wp_query->post->ID;
5405 + if(wdk_get_option('wdk_seo_listing_title')) {
5406 + global $Winter_MVC_WDK;
5407 + $Winter_MVC_WDK->model('field_m');
5408 + $Winter_MVC_WDK->load_helper('listing');
5409 +
5410 + $seo_template = wdk_get_option('wdk_seo_listing_title');
5411 +
5412 + $matches = [];
5413 + preg_match_all('/{(?:field_)?([^}]+)}/', $seo_template, $matches);
5414 + $fields_in_template = isset($matches[1]) ? $matches[1] : [];
5415 +
5416 + $fields_values = [];
5417 +
5418 + foreach ($fields_in_template as $field_id) {
5419 + $key_id = '{field_' . $field_id . '}';
5420 + if($field_id == 'category') {
5421 + $field_id = 'category_title';
5422 + }
5423 + if($field_id == 'location') {
5424 + $field_id = 'location_title';
5425 + }
5426 + // Try to get value for field_id for this listing
5427 + $fields_values[$key_id] = wdk_field_value($field_id, $wdk_listing_id);
5428 + }
5429 + // Replace the fields in template with real values
5430 + $seo_title = strtr($seo_template, $fields_values);
5431 + }
5432 +
5433 + $cached_seo_title = $seo_title;
5434 + return $seo_title;
5435 + }
5436 + }
5437 +
5438 +
5439 + if ( ! function_exists('wdk_filter_viber_phone'))
5440 + {
5441 + // Validation phone for viber
5442 + /**
5443 + * @param string $value phone in string
5444 + * @return strings +xxx
5445 + */
5446 + function wdk_filter_viber_phone($value = '') {
5447 + $value = str_replace(array(' ','-','(',')'),'',$value);
5448 + return (strpos($value, '+') !== 0) ? '+' . $value : $value;
5449 + }
5450 + }
5451 +
5452 +?>