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 +1968 -186 1.2.3 → 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,28 +783,31 @@
541 783 // $col_name = $key;
542 784
543 785 if(strpos($key, 'skip') !== FALSE) continue;
544 786
545 - if(defined( 'WP_DEBUG' ) && WP_DEBUG)
546 - if(function_exists('pll_current_language'))
787 + if($key == 'field_booking_guest')
547 788 {
548 - $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 + }
549 797
550 - if(is_numeric($lang_term_id))
551 - {
552 - $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);
553 - $WMVC->db->where("({$WMVC->db->prefix}term_relationships.term_taxonomy_id = $lang_term_id)");
554 - }
798 + $gen_q.= $WMVC->db->prefix."wdk_booking_calendar.guests >='".intval($val)."' AND ";
799 +
555 800 }
556 -
557 - if($key == 'field_booking_date_from')
801 + elseif($key == 'field_booking_date_from')
558 802 {
559 803 if(!$wdk_bookings_joinded){
560 - $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');
561 - $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
562 - $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');
563 807 $wdk_bookings_joinded = true;
564 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');
565 810 }
566 811
567 812 if(wdk_is_date($val))
568 813 {
@@ -580,9 +825,9 @@
580 825 if(!get_option('wdk_bookings_is_hours_enabled')) {
581 826 $gen_search_from = wdk_normalize_date_db($_GET_clone['field_booking_date_from'], 'Y-m-d H:i:s', 'Y-m-d');
582 827 $gen_search_to = wdk_normalize_date_db($_GET_clone['field_booking_date_to'], 'Y-m-d H:i:s', 'Y-m-d');
583 828
584 - $gen_q.= $WMVC->listing_m->_table_name.".post_id NOT IN (
829 + $gen_q.= $WMVC->db->prefix."posts.ID NOT IN (
585 830 SELECT post_id
586 831 FROM ".$WMVC->db->prefix."wdk_booking_reservation
587 832 WHERE
588 833 ".$WMVC->db->prefix."wdk_booking_reservation.is_approved = 1
@@ -595,9 +840,9 @@
595 840 } else {
596 841 $gen_search_from = wdk_normalize_date_db($_GET_clone['field_booking_date_from']);
597 842 $gen_search_to = wdk_normalize_date_db($_GET_clone['field_booking_date_to']);
598 843
599 - $gen_q.= $WMVC->listing_m->_table_name.".post_id NOT IN (
844 + $gen_q.= $WMVC->db->prefix."posts.ID NOT IN (
600 845 SELECT post_id
601 846 FROM ".$WMVC->db->prefix."wdk_booking_reservation
602 847 WHERE
603 848 ".$WMVC->db->prefix."wdk_booking_reservation.is_approved = 1
@@ -612,12 +857,13 @@
612 857 }
613 858 elseif($key == 'field_booking_date_to')
614 859 {
615 860 if(!$wdk_bookings_joinded){
616 - $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');
617 - $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');
618 863 $wdk_bookings_joinded = true;
619 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');
620 866 }
621 867
622 868 if(wdk_is_date($val))
623 869 {
@@ -633,9 +879,33 @@
633 879 }
634 880 elseif(substr($key, -8) == '_exactly')
635 881 {
636 882 $col_name = substr($key, 0, -8);
637 - $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 + }
638 908 }
639 909 elseif(substr($key, -4) == '_max')
640 910 {
641 911 $col_name = substr($key, 0, -4);
@@ -644,10 +914,10 @@
644 914 $gen_q.=$col_name." <= ".intval($val)." AND ";
645 915 } else if(strpos($key, 'DATE') !== FALSE) {
646 916 if(wdk_is_date($val))
647 917 {
648 - $gen_search = wdk_normalize_date_db($val, 'Y-m-d H:i:s', 'Y-m-d');
649 - $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 ";
650 920 }
651 921 } else {
652 922 $gen_q.=$col_name." <= '".$val."' AND ";
653 923 }
@@ -654,16 +924,16 @@
654 924 }
655 925 else if(substr($key, -4) == '_min')
656 926 {
657 927 $col_name = substr($key, 0, -4);
658 -
928 +
659 929 if(strpos($key, 'NUMBER') !== FALSE) {
660 930 $gen_q.=$col_name." >= ".intval($val)." AND ";
661 931 } else if(strpos($key, 'DATE') !== FALSE) {
662 932 if(wdk_is_date($val))
663 933 {
664 - $gen_search = wdk_normalize_date_db($val, 'Y-m-d H:i:s', 'Y-m-d');
665 - $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 ";
666 936 }
667 937 } else {
668 938 $gen_q.=$col_name." >= '".$val."' AND ";
669 939 }
@@ -725,9 +995,9 @@
725 995 }
726 996
727 997 if(is_array($val)) {
728 998
729 - $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');
730 1000 $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
731 1001 $sql_search = '';
732 1002 foreach ($val as $v) {
733 1003 if(empty($v)) continue;
@@ -742,9 +1012,9 @@
742 1012 if(!empty($sql_search))
743 1013 $gen_q.=" ( ".$sql_search." ) AND ";
744 1014
745 1015 } elseif(is_string($val) && !empty($val)) {
746 - $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');
747 1017 $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
748 1018 $sql_search =" ".$WMVC->listing_m->_table_name.".`user_id_editor` = ".intval($val)." OR `".$WMVC->db->prefix."wdk_listings_users`.`user_id` = ".intval($val)." ";
749 1019 $gen_q.=" ( ".$sql_search." ) AND ";
750 1020 }
@@ -774,8 +1044,9 @@
774 1044 }
775 1045 }
776 1046 elseif($key == 'location_id')
777 1047 {
1048 + if(empty($val)) continue;
778 1049
779 1050 if(is_string($val) && strpos($val, ',') !== FALSE){
780 1051 $val =explode(',', $val);
781 1052 } elseif(is_string($val)){
@@ -790,10 +1061,10 @@
790 1061 }
791 1062
792 1063 $sql_search = '';
793 1064 foreach ($val as $v) {
794 - if(empty($v)) continue;
795 -
1065 + if(empty($v) || !is_intval($v)) continue;
1066 +
796 1067 if(!empty($sql_search))
797 1068 $sql_search .= " OR ";
798 1069
799 1070 $sql_search .= " ".$WMVC->listing_m->_table_name.".`location_id`=".intval($v)."";
@@ -798,8 +1069,10 @@
798 1069
799 1070 $sql_search .= " ".$WMVC->listing_m->_table_name.".`location_id`=".intval($v)."";
800 1071 $sql_search .= " OR `location_table`.`parent_id`=".intval($v)."";
801 1072
1073 + $sql_search .= " OR CONCAT(',', location_table.parent_path, ',') LIKE CONCAT('%,', ".intval($v).", ',%')";
1074 +
802 1075 /* other locations */
803 1076 /* multi select */
804 1077 if(false){
805 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).") ";
@@ -817,8 +1090,10 @@
817 1090 }
818 1091 elseif($key == 'category_id')
819 1092 {
820 1093
1094 + if(empty($val)) continue;
1095 +
821 1096 if(is_string($val) && strpos($val, ',') !== FALSE){
822 1097 $val =explode(',', $val);
823 1098 } elseif(is_string($val)){
824 1099 $val =array($val);
@@ -831,9 +1106,9 @@
831 1106 }
832 1107
833 1108 $sql_search = '';
834 1109 foreach ($val as $v) {
835 - if(empty($v)) continue;
1110 + if(empty($v) || !is_intval($v)) continue;
836 1111
837 1112 if(!empty($sql_search))
838 1113 $sql_search .= " OR ";
839 1114
@@ -838,9 +1113,10 @@
838 1113 $sql_search .= " OR ";
839 1114
840 1115 $sql_search .= " ".$WMVC->db->prefix."wdk_listings.`category_id` = ".intval($v)."";
841 1116 $sql_search .= " OR `category_table`.`parent_id`=".intval($v)."";
842 -
1117 + $sql_search .= " OR CONCAT(',', category_table.parent_path, ',') LIKE CONCAT('%,', ".intval($v).", ',%')";
1118 +
843 1119 /* other categories */
844 1120 if(false){
845 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).")";
846 1122 } elseif(false) {
@@ -895,10 +1171,15 @@
895 1171
896 1172 if(!empty($sql_search))
897 1173 $gen_q.=" ( ".$sql_search." ) AND ";
898 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 + }
899 1181 }
900 -
901 1182 }
902 1183
903 1184 $gen_q = substr($gen_q, 0, -5);
904 1185
@@ -904,14 +1185,120 @@
904 1185
905 1186 if(!empty($gen_q))
906 1187 $WMVC->db->where("($gen_q)");
907 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]
908 1215
909 1216 // order
910 - if(isset($_GET_clone['order_by']))
911 - {
912 - $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_listings.post_id', $_GET_clone['order_by']);
913 - $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 +
914 1301 }
915 1302
916 1303 }
917 1304 }
@@ -928,9 +1315,9 @@
928 1315
929 1316 if(isset($custom_parameters['order_by'])) {
930 1317
931 1318 if(isset($_GET_clone['order_by']) && !empty($_GET_clone['order_by'])) {
932 - $_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']);
933 1320 } else {
934 1321 $_GET_clone['order_by'] = $custom_parameters['order_by'];
935 1322 }
936 1323
@@ -944,9 +1331,9 @@
944 1331 $WMVC->model($model_name);
945 1332
946 1333 $smart_search = '';
947 1334 if(isset($_GET_clone['profile_search']))
948 - $smart_search = sanitize_text_field($_GET_clone['profile_search']);
1335 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['profile_search']));
949 1336
950 1337 $available_fields = array('user_login','user_nicename','user_email','user_url','display_name');
951 1338
952 1339 if(isset($_GET_clone['is_activated'])){
@@ -1113,9 +1500,9 @@
1113 1500 // order
1114 1501 if(isset($_GET_clone['order_by']))
1115 1502 {
1116 1503 $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_favorite.post_id', $_GET_clone['order_by']);
1117 - $WMVC->db->order_by($_GET_clone['order_by']);
1504 + $WMVC->db->order_by(wdk_esc_sql(sanitize_text_field($_GET_clone['order_by'])));
1118 1505 }
1119 1506
1120 1507 }
1121 1508 }
@@ -1131,9 +1518,9 @@
1131 1518 //$WMVC->model('listing_m');
1132 1519
1133 1520 $smart_search = '';
1134 1521 if(isset($_GET_clone['search']))
1135 - $smart_search = sanitize_text_field($_GET_clone['search']);
1522 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['search']));
1136 1523
1137 1524 $available_fields = $WMVC->$model_name->get_available_fields();
1138 1525
1139 1526 /* Пet column names from wdk_package and add to allow search +
@@ -1244,9 +1631,9 @@
1244 1631 $detect_date = strtotime($gen_search);
1245 1632
1246 1633 if(wdk_payments_is_date($val) && $detect_date > 1000)
1247 1634 {
1248 - $gen_search = date('Y-m-d H:i:s', $detect_date);
1635 + $gen_search = gmdate('Y-m-d H:i:s', $detect_date);
1249 1636 $gen_q.=$col_name." > '".$gen_search."' AND ";
1250 1637 }
1251 1638 else
1252 1639 {
@@ -1284,9 +1671,9 @@
1284 1671 // order
1285 1672 if(isset($_GET_clone['order_by']))
1286 1673 {
1287 1674 $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_messages.post_id', $_GET_clone['order_by']);
1288 - $WMVC->db->order_by($_GET_clone['order_by']);
1675 + $WMVC->db->order_by(wdk_esc_sql(sanitize_text_field($_GET_clone['order_by']), true));
1289 1676 }
1290 1677
1291 1678 }
1292 1679 }
@@ -1293,9 +1680,9 @@
1293 1680
1294 1681 function wdk_date() {
1295 1682 $date_format = get_option('date_format');
1296 1683 $time_format = get_option('time_format');
1297 - $date = date("{$date_format} {$time_format}", current_time('timestamp'));
1684 + $date = gmdate("{$date_format} {$time_format}", current_time('timestamp'));
1298 1685 return $date;
1299 1686 }
1300 1687
1301 1688 if(!function_exists('wdk_placeholder_image_src')) {
@@ -1319,18 +1706,20 @@
1319 1706
1320 1707 if(isset($_GET[$page_var]))
1321 1708 $current_page = intval(wmvc_xss_clean($_GET[$page_var]));
1322 1709
1323 - if(!isset($texts['previous_page']))$texts['previous_page'] = 'Previous page';
1324 - 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');
1325 1712 if(!isset($texts['first_page']))$texts['first_page'] = '';
1326 1713 if(!isset($texts['last_page']))$texts['last_page'] = '';
1327 - if(!isset($texts['items']))$texts['items'] = 'items';
1714 + if(!isset($texts['items']))$texts['items'] = esc_html__('items', 'wpdirectorykit');
1328 1715
1329 1716 if(empty($current_page))$current_page = 1;
1330 1717
1331 1718 // get url
1332 - $url = strtok($_SERVER["REQUEST_URI"], '?');
1719 + $url = strtok(wdk_server_current_url(), '?');
1720 +
1721 +
1333 1722 $qs_parameters = wmvc_xss_clean( $_GET );
1334 1723 unset($qs_parameters[$page_var]);
1335 1724 $qs_part = http_build_query($qs_parameters);
1336 1725 $url = wdk_url_suffix($url, $qs_part);
@@ -1353,16 +1742,16 @@
1353 1742
1354 1743 $output .= '<div class="nav-links">';
1355 1744
1356 1745 if($enable_latest_first && $current_page-1 > 0)
1357 - $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>';
1358 1747
1359 1748 if ($current_page-1 > 0) {
1360 1749
1361 - $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>';
1362 1751 } elseif($enable_compact)
1363 1752 {
1364 - $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>';
1365 1754 }
1366 1755
1367 1756 if (!$enable_compact) {
1368 1757 for ($i = 1 ; $i <= $total_pages; $i++) {
@@ -1370,9 +1759,9 @@
1370 1759 if(($current_page-$limit_items) <= $i && ($current_page+$limit_items) >= $i) {
1371 1760 if (($current_page == $i)) {
1372 1761 $output.= '<span aria-current="page" class="page-numbers current">'.$i.'</span>';
1373 1762 } else {
1374 - $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>';
1375 1764 }
1376 1765 }
1377 1766 }
1378 1767 } else {
@@ -1380,17 +1769,17 @@
1380 1769 }
1381 1770
1382 1771 if($current_page+1 <= $total_pages)
1383 1772 {
1384 - $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>';
1385 1774 }
1386 1775 elseif($enable_compact)
1387 1776 {
1388 - $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>';
1389 1778 }
1390 1779
1391 1780 if($enable_latest_first && $current_page+1 <= $total_pages)
1392 - $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>';
1393 1782
1394 1783
1395 1784 $output.= '</div>';
1396 1785 $output.= '</nav>';
@@ -1430,8 +1819,12 @@
1430 1819 global $wdk_text_search_button;
1431 1820 if(empty($wdk_text_search_button))
1432 1821 $wdk_text_search_button = esc_html__('Search','wpdirectorykit');
1433 1822
1823 + global $wdk_text_reset_button;
1824 + if(empty($wdk_text_reset_button))
1825 + $wdk_text_reset_button = esc_html__('Reset','wpdirectorykit');
1826 +
1434 1827 global $wdk_text_more_button;
1435 1828 if(empty($wdk_text_more_button))
1436 1829 $wdk_text_more_button = esc_html__('More','wpdirectorykit');
1437 1830
@@ -1441,18 +1834,27 @@
1441 1834 }
1442 1835
1443 1836 ?>
1444 1837 <div class="wdk-col wdk-col-btns">
1445 - <div class="wdk-field wdk-field-btn">
1838 + <div class="wdk-field wdk-field-btn">
1446 1839 <div class="wdk-field-group wdk-field-group-additional">
1447 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>
1448 - <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' />
1449 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;?>
1450 1851 <div class="wdk-field-group wdk-field-group-search">
1451 - <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 +
1452 1854 <?php if(function_exists('run_wdk_save_search') && get_option('wdk_save_search_show_on_searchform')):?>
1453 1855 <div class="section-widget-control right">
1454 - <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">
1455 1857 <i class="fas fa-save" aria-hidden="true"></i>
1456 1858 <i class="fa fa-spinner fa-spin fa-ajax-indicator"></i>
1457 1859 </a>
1458 1860 </div>
@@ -1457,8 +1859,9 @@
1457 1859 </a>
1458 1860 </div>
1459 1861 <?php endif;?>
1460 1862 </div>
1863 +
1461 1864 </div>
1462 1865 </div>
1463 1866 <div id='wdk-form-additional' class="wdk-col" style="<?php echo esc_attr($form_closed) ;?>">
1464 1867 <div class="wdk-row">
@@ -1474,9 +1877,9 @@
1474 1877 */
1475 1878 if ( ! function_exists('wdk_treefield_option'))
1476 1879 {
1477 1880 function wdk_treefield_option($name = '', $table=NULL, $selected = NULL,
1478 - $column = 'category_title', $language_id=NULL, $empty_value='', $filter_ids = '', $user_check = FALSE, $sql_where='')
1881 + $column = 'category_title', $language_id=NULL, $empty_value='', $filter_ids = '', $user_check = FALSE, $sql_where='', $hide_fields = '')
1479 1882 {
1480 1883 $WMVC = &wdk_get_instance();
1481 1884
1482 1885 if(is_array($filter_ids)) $filter_ids = implode(',', $filter_ids);
@@ -1501,9 +1904,9 @@
1501 1904
1502 1905 if(empty($selected))
1503 1906 $selected='';
1504 1907
1505 - $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/>';
1506 1909
1507 1910 $skip_id = '';
1508 1911 //load javascript library
1509 1912 if($counter==0)
@@ -1510,38 +1913,39 @@
1510 1913 {
1511 1914 wp_enqueue_script('wdk-treefield');
1512 1915 wp_enqueue_style('wdk-treefield');
1513 1916 }
1514 - ?>
1515 - <script>
1516 - jQuery(document).ready(function($) {
1517 - $('#wdktreeelem<?php echo esc_js($counter);?>:not(.init)').wdkTreefield({
1518 - 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')) . "',
1519 1922 ajax_param: {
1520 - "page": 'wdk_frontendajax',
1521 - "function": 'treefieldid',
1522 - "action": 'wdk_public_action',
1523 - "table": '<?php echo esc_js($table); ?>',
1524 - "filter_ids": '<?php echo esc_js($filter_ids); ?>',
1525 - "start_id": '<?php if(!empty($filter_ids)) esc_js($selected); else echo ""; ?>',
1526 - "empty_value": '<?php echo esc_js($empty_value); ?>',
1527 - "user_check": '<?php echo esc_js($user_check); ?>',
1528 - "sql_where": '<?php echo esc_js($sql_where); ?>'
1529 - },
1530 - attribute_id: '<?php echo esc_js($attribute_id); ?>',
1531 - language_id: '<?php echo esc_js($language_id); ?>',
1532 - attribute_value: '<?php echo esc_js($column); ?>',
1533 - 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: '',
1534 1939 empty_value: ' - ',
1535 - text_search: '<?php esc_html_e('Search term', 'wpdirectorykit');?>',
1536 - 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') . "',
1537 1942 callback_selected: function(key) {
1538 - $('#wdktreeelem<?php echo esc_js($counter);?>').trigger("change");
1943 + $('#wdktreeelem" . esc_js($counter) . "').trigger('change');
1539 1944 }
1540 1945 }).addClass('init');
1541 - });
1542 - </script>
1543 - <?php
1946 + });"
1947 + );
1544 1948 $counter++;
1545 1949 return $form;
1546 1950 }
1547 1951 }
@@ -1552,9 +1956,9 @@
1552 1956 */
1553 1957 if ( ! function_exists('wdk_treefield_option_checkboxes'))
1554 1958 {
1555 1959 function wdk_treefield_option_checkboxes($name = '', $table=NULL, $selected = NULL,
1556 - $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 = '')
1557 1961 {
1558 1962 $WMVC = &wdk_get_instance();
1559 1963
1560 1964 if(is_array($filter_ids)) $filter_ids = implode(',', $filter_ids);
@@ -1573,12 +1977,11 @@
1573 1977
1574 1978 $values = '';
1575 1979 if(!empty($selected)){
1576 1980 $ids = array();
1577 -
1578 1981 if(is_string($selected) && strpos($selected, ',') !== FALSE){
1579 1982 $val_selected = explode(',', $selected);
1580 - } elseif(is_string($selected)){
1983 + } elseif($selected){
1581 1984 $val_selected = array($selected);
1582 1985 }
1583 1986
1584 1987 foreach($val_selected as $selected_item) {
@@ -1610,9 +2013,9 @@
1610 2013 if(empty($values)) {
1611 2014 $values = $empty_value;
1612 2015 }
1613 2016
1614 - $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/>';
1615 2018
1616 2019 $skip_id = '';
1617 2020 //load javascript library
1618 2021 if($counter==0)
@@ -1623,17 +2026,19 @@
1623 2026 ?>
1624 2027 <script>
1625 2028 jQuery(document).ready(function($) {
1626 2029 $('#wdktreeelem_checkbox<?php echo esc_js($counter);?>:not(.init)').wdkTreefieldCheckboxes({
1627 - ajax_url: '<?php echo admin_url('admin-ajax.php'); ?>',
2030 + ajax_url: '<?php echo esc_url(admin_url('admin-ajax.php')); ?>',
1628 2031 ajax_param: {
1629 2032 "page": 'wdk_frontendajax',
1630 2033 "function": 'treefieldid_checkboxes',
1631 2034 "action": 'wdk_public_action',
2035 + "wdk_secure": '<?php echo esc_js(wp_create_nonce( 'wdk_secure_treefieldid_checkboxes' ));?>',
1632 2036 "table": '<?php echo esc_js($table); ?>',
1633 2037 "filter_ids": '<?php echo esc_js($filter_ids); ?>',
1634 2038 "empty_value": '<?php echo esc_js($empty_value); ?>',
1635 2039 "user_check": '<?php echo esc_js($user_check); ?>',
2040 + "hide_fields": '<?php echo esc_js($hide_fields); ?>',
1636 2041 },
1637 2042 selected: '<?php echo esc_js($selected); ?>',
1638 2043 attribute_id: '<?php echo esc_js($attribute_id); ?>',
1639 2044 language_id: '<?php echo esc_js($language_id); ?>',
@@ -1657,11 +2062,19 @@
1657 2062 if ( ! function_exists('wdk_filter_decimal'))
1658 2063 {
1659 2064 function wdk_filter_decimal($string = '')
1660 2065 {
1661 - if(substr($string, -3, 3) === ".00") {
1662 - return substr($string, 0, -3);
1663 - }
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 + }
1664 2077
1665 2078 return $string;
1666 2079 }
1667 2080 }
@@ -1739,12 +2152,8 @@
1739 2152 * @return string date in format Y-m-d H:i:s
1740 2153 */
1741 2154 function wdk_normalize_date_db($date, $format = 'Y-m-d H:i:s', $return_format = 'Y-m-d H:i:s')
1742 2155 {
1743 - /* check is date on strtotime */
1744 - if((bool)strtotime($date)){
1745 - return date($return_format, strtotime($date));
1746 - }
1747 2156
1748 2157 /* check is date from argument */
1749 2158 $d = \DateTime::createFromFormat($format, $date);
1750 2159 if($d) {
@@ -1775,24 +2184,29 @@
1775 2184 return $d->format($return_format);
1776 2185 }
1777 2186 }
1778 2187
1779 - /* issue with pm/am inside date, example bug format like "2023 01 19 pm8:06" => 'Y n j ag:i' */
1780 - $format = get_option('date_format').' '.get_option('time_format');
1781 - if(strpos($format, 'a') !== FALSE) {
1782 - $format = str_replace('a', '',$format).' a';
1783 - if(strpos($date, 'am') !== FALSE) {
1784 - $date = str_replace('am', '',$date).' am';
1785 - }
1786 - if(strpos($date, 'pm') !== FALSE) {
1787 - $date = str_replace('pm', '',$date).' pm';
1788 - }
1789 - $d = \DateTime::createFromFormat($format, $date);
1790 - if($d) {
1791 - return $d->format($return_format);
1792 - }
1793 - }
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 + }
1794 2203
2204 + /* check is date on strtotime */
2205 + if((bool)strtotime($date)){
2206 + return gmdate($return_format, strtotime($date));
2207 + }
2208 +
1795 2209 return false;
1796 2210 }
1797 2211 }
1798 2212
@@ -1810,9 +2224,100 @@
1810 2224 return $base_url.$extension_url;
1811 2225 }
1812 2226 }
1813 2227
2228 +
1814 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 +/**
1815 2320 * Insert an attachment from an URL address.
1816 2321 *
1817 2322 * @param String $url
1818 2323 * @param Int $parent_post_id
@@ -1834,14 +2339,14 @@
1834 2339 $filename = substr($filename, 0, strpos($filename, '?'));
1835 2340 }
1836 2341
1837 2342 /* if unsoported extension */
1838 - if(in_array(wdk_file_extension($filename), array('php','asp'))){
2343 + if(in_array(wdk_file_extension($filename), array('php','asp')) || strlen(wdk_file_extension($filename)) > 5){
1839 2344 $data = getimagesizefromstring($response['body']);
1840 2345 if(!$data) return false;
1841 2346 if(empty($data['mime'])) return false;
1842 2347
1843 - $filename = time().rand(0000,9999).'.'.wdk_mime2ext($data['mime']);
2348 + $filename = time().wp_rand(0000,9999).'.'.wdk_mime2ext($data['mime']);
1844 2349 }
1845 2350 $upload = wp_upload_bits( $filename, null, $response['body'] );
1846 2351
1847 2352 if( !empty( $upload['error'] ) ) {
@@ -1933,17 +2438,12 @@
1933 2438 */
1934 2439
1935 2440 function wdk_generate_profile_permalink($profile = array())
1936 2441 {
1937 -
1938 2442 $profile_slug = '';
1939 - if(wmvc_show_data('user_login', $profile, false)){
1940 - $profile_slug = wmvc_show_data('user_login', $profile);
1941 - if(wmvc_show_data('wdk_slug', $profile))
1942 - $profile_slug = wmvc_show_data('wdk_slug', $profile);
1943 - } else if(is_intval($profile)){
2443 + if(is_intval($profile)){
1944 2444 $profile_data = get_userdata($profile);
1945 - if(wmvc_show_data('wdk_slug', $profile, false)){
2445 + if(wmvc_show_data('wdk_slug', $profile_data, false)){
1946 2446 $profile_slug = wmvc_show_data('wdk_slug', $profile);
1947 2447 }elseif(wmvc_show_data('user_login', $profile_data, false)){
1948 2448 $profile_slug = wmvc_show_data('user_login', $profile_data);
1949 2449 } else {
@@ -1948,10 +2448,14 @@
1948 2448 $profile_slug = wmvc_show_data('user_login', $profile_data);
1949 2449 } else {
1950 2450 $profile_slug = $profile;
1951 2451 }
1952 - }
1953 -
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 +
1954 2458 $user_profile_page = get_option('wdk_membership_profile_preview_page');
1955 2459 if(!$user_profile_page) {
1956 2460 return '#';
1957 2461 }
@@ -2040,17 +2544,23 @@
2040 2544 * Return date in format
2041 2545 * @param string|url redirect url
2042 2546 * @param string custom_message, showed on login form like alert, visible only on wdk login form
2043 2547 */
2044 - function wdk_login_url($url_redirect = NULL, $custom_message = '')
2548 + function wdk_login_url($url_redirect = '', $custom_message = '')
2045 2549 {
2046 2550 $url = wp_login_url($url_redirect);
2047 2551
2048 2552 if(get_option('wdk_membership_login_page')){
2049 - $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 + }
2050 2560 }
2051 2561
2052 - return $url;
2562 + return trim($url, '?');
2053 2563 }
2054 2564 }
2055 2565
2056 2566 if(!function_exists('wdk_mail')) {
@@ -2069,10 +2579,10 @@
2069 2579 if(empty($subject))
2070 2580 $subject = __("New message", "wpdirectorykit");
2071 2581
2072 2582 $headers = array('Content-Type: text/html; charset=UTF-8');
2073 - $headers[] = 'From: '.$email_from;
2074 -
2583 + $headers[] = 'From: "'.get_bloginfo('name').'" <'.$email_from.'>';
2584 +
2075 2585 if(!empty($reply_to)) {
2076 2586 $headers[] = 'Reply-To: '.$reply_to;
2077 2587 } else {
2078 2588 $headers[] = 'Reply-To: '.$email_from;
@@ -2200,19 +2710,19 @@
2200 2710 <!-- Your add & remove file links -->
2201 2711 <p class="hide-if-no-js">
2202 2712 <a class="upload-custom-img <?php if ( $you_have_file ) { echo 'hidden'; } ?>"
2203 2713 href="<?php echo esc_url($upload_link) ?>">
2204 - <?php echo esc_html__('Select file','wmvc_win') ?>
2714 + <?php echo esc_html__('Select file','wpdirectorykit') ?>
2205 2715 </a>
2206 2716 <a class="delete-custom-img <?php if ( ! $you_have_file ) { echo 'hidden'; } ?>"
2207 2717 href="#">
2208 - <?php echo esc_html__('Remove file','wmvc_win') ?>
2718 + <?php echo esc_html__('Remove all files','wpdirectorykit') ?>
2209 2719 </a>
2210 2720 </p>
2211 2721 <?php //endif; ?>
2212 2722
2213 2723 <!-- A hidden input to set and post the chosen file id -->
2214 - <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); ?>" />
2215 2725 </div>
2216 2726
2217 2727 <?php
2218 2728 $custom_js ='';
@@ -2220,8 +2730,9 @@
2220 2730 if( typeof jQuery.fn.wpMediaElementFile == 'function')
2221 2731 $('#".esc_js($field_name)."meta-box-id.postbox-upload').wpMediaElementFile();
2222 2732 });";
2223 2733
2734 +// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.WP.I18n.NonSingularStringLiteralText
2224 2735 echo "<script>".$custom_js."</script>";
2225 2736
2226 2737 ?>
2227 2738
@@ -2272,19 +2783,15 @@
2272 2783 function wdk_upload_multi_files($field_name, $image_ids='', $texts = array())
2273 2784 {
2274 2785 static $media_element_counter = 0;
2275 2786
2276 - if(!isset($texts['file_select']))$texts['file_select'] = esc_html__('Select file','wmvc_win');
2277 - 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');
2278 2789
2279 2790 $media_element_counter++;
2280 2791
2281 2792 $img_field = $field_name.'_'.$media_element_counter;
2282 2793
2283 - wp_register_script( 'wpmediaelement_file', WPDIRECTORYKIT_URL . 'admin/js/jquery.wpmediaelement_file.js', array( 'jquery' ), false, false );
2284 - wp_enqueue_script( 'wpmediaelement_file' );
2285 - wp_enqueue_media();
2286 -
2287 2794 wp_enqueue_script( 'wpmediamultiple' );
2288 2795 wp_enqueue_script( 'jquery-ui-mouse' );
2289 2796 wp_enqueue_media();
2290 2797
@@ -2321,9 +2828,9 @@
2321 2828 <!-- Your image container, which can be manipulated with js -->
2322 2829 <div class="custom-img-container winter_mvc-media">
2323 2830 <?php if($you_have_img)foreach($your_img_src as $image_id => $img_src) : ?>
2324 2831 <div class="winter_mvc-media-card" data-media-id="<?php echo esc_attr($image_id);?>">
2325 - <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"/>
2326 2833 <a href="#" class="remove"></a>
2327 2834 </div>
2328 2835 <?php endforeach; ?>
2329 2836 </div>
@@ -2343,9 +2850,9 @@
2343 2850 </p>
2344 2851 <?php //endif; ?>
2345 2852
2346 2853 <!-- A hidden input to set and post the chosen image id -->
2347 - <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); ?>" />
2348 2855 </div>
2349 2856 <?php
2350 2857 $custom_js ='';
2351 2858 $custom_js .=" jQuery(function($) {
@@ -2351,11 +2858,14 @@
2351 2858 $custom_js .=" jQuery(function($) {
2352 2859 if( typeof jQuery.fn.wpMediaMultiple == 'function')
2353 2860 $('#".esc_js($field_name)."meta-box-id.postbox-upload-multiple').wpMediaMultiple({
2354 2861 frame: {
2355 - 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'))."',
2356 2863 button: '".esc_js(__('Use this media','wpdirectorykit'))."',
2357 - }
2864 + },
2865 + library: {
2866 + type: ['application', 'image', 'video']
2867 + },
2358 2868 });
2359 2869 /* order */
2360 2870 var re_order = function(media_element){
2361 2871 var list_media = '';
@@ -2382,8 +2892,9 @@
2382 2892 })
2383 2893 });
2384 2894 ";
2385 2895
2896 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.WP.I18n.NonSingularStringLiteralText
2386 2897 echo "<script>".$custom_js."</script>";
2387 2898
2388 2899 ?>
2389 2900
@@ -2434,9 +2945,9 @@
2434 2945
2435 2946 if(empty($user_id))
2436 2947 $user_id = get_current_user_id();
2437 2948
2438 - if(wmvc_user_in_role('administrator')) {
2949 + if(wmvc_user_in_role('administrator') || current_user_can('wdk_listings_manage')) {
2439 2950 return true;
2440 2951 }
2441 2952
2442 2953 if(substr($model_name,-2,2) == '_m')
@@ -2464,8 +2975,59 @@
2464 2975
2465 2976 }
2466 2977 }
2467 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 +
2468 3030 if ( ! function_exists('wdk_recaptcha_field'))
2469 3031 {
2470 3032 function wdk_recaptcha_field($is_compact=false, $style="", $load_script=true)
2471 3033 {
@@ -2475,9 +3037,16 @@
2475 3037 if(get_option('wdk_recaptcha_site_key') !== FALSE && get_option('wdk_recaptcha_secret_key') !== NULL)
2476 3038 {
2477 3039 if($load_script && $counter===0)
2478 3040 {
2479 - 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 +
2480 3049 }
2481 3050 $counter++;
2482 3051
2483 3052 $compact_tag='';
@@ -2489,15 +3058,15 @@
2489 3058 }
2490 3059
2491 3060 $recaptcha_array[$counter] = array('size'=>$size_tag);
2492 3061
2493 - 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>';
2494 3063 ?>
2495 3064
2496 3065 <script>
2497 3066 <?php if($counter===1)echo 'var ';?>CaptchaCallback = function(){
2498 3067 <?php for($j=1;$j<=$counter;$j++): ?>
2499 - 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')); ?>'});
2500 3069 <?php endfor; ?>
2501 3070 };
2502 3071 </script>
2503 3072
@@ -2599,9 +3168,9 @@
2599 3168 if(is_array($val))
2600 3169 {
2601 3170 return wdk_clean($_POST);
2602 3171 }
2603 - else
3172 + elseif(is_string($val))
2604 3173 {
2605 3174 if(strpos($val, '<iframe') === 0)
2606 3175 $val = str_replace("'",'"', $val);
2607 3176
@@ -2640,9 +3209,9 @@
2640 3209 if(is_array($val))
2641 3210 {
2642 3211 $arr_cleaned[sanitize_text_field($key)] = wdk_clean($val);
2643 3212 }
2644 - else
3213 + elseif(is_string($val))
2645 3214 {
2646 3215 $arr_cleaned[sanitize_text_field($key)] = wp_kses_post($val);
2647 3216 }
2648 3217
@@ -2652,8 +3221,34 @@
2652 3221
2653 3222 return $arr_cleaned;
2654 3223 }
2655 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 +
2656 3251 /*
2657 3252 <select class="form-control" name="<?php echo 'control_operator_'.$i_fieldnum; ?>">
2658 3253 <option value="CONTAINS">CONTAINS</option>
2659 3254 <option value="NOT_CONTAINS">NOT_CONTAINS</option>
@@ -2668,9 +3263,9 @@
2668 3263
2669 3264 if(is_array($options) && count($options) > 0)
2670 3265 foreach($options as $key=>$val)
2671 3266 {
2672 - $output.= '<option value="'.$key.'" '.($selected==$key?'selected':'').'>'.$val.'</option>';
3267 + $output.= '<option value="'.$key.'" '.($selected==$key&&$selected != ''?'selected':'').'>'.$val.'</option>';
2673 3268 }
2674 3269
2675 3270 $output.= '</select>';
2676 3271
@@ -2694,9 +3289,9 @@
2694 3289
2695 3290 if(is_array($filter_ids)) $filter_ids = implode(',', $filter_ids);
2696 3291
2697 3292 static $counter = 0;
2698 - $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="">';
2699 3294
2700 3295
2701 3296 if(false)
2702 3297 if( $column_key == 'idcategory') {
@@ -2710,9 +3305,9 @@
2710 3305
2711 3306 $ids = array();
2712 3307 foreach($selected as $selected_item) {
2713 3308 if(!empty($selected_item)) {
2714 - $ids [] = $selected_item;
3309 + $ids [] = (int) $selected_item;
2715 3310 }
2716 3311 }
2717 3312
2718 3313 /* where in */
@@ -2723,15 +3318,19 @@
2723 3318
2724 3319 $results = $WMVC->$table->get();
2725 3320 foreach ($results as $item) {
2726 3321 if($item)
2727 - $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>';
2728 3325 }
2729 3326 }
2730 3327 } elseif(is_intval($selected)) {
2731 3328 $db_item = $WMVC->$table->get($selected, TRUE);
2732 3329 if($db_item)
2733 - $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>';
2734 3333 }
2735 3334 } else {
2736 3335 //$form .= '<option value="" selected="selected">'.esc_html__('Not selected', 'wpdirectorykit').'</option>';
2737 3336 }
@@ -2739,11 +3338,11 @@
2739 3338
2740 3339 //load javascript library
2741 3340 if($counter==0)
2742 3341 {
2743 - wp_enqueue_script('select2');
3342 + wp_enqueue_script('select2-select2');
2744 3343 wp_enqueue_script('wdk-select2');
2745 - wp_enqueue_style('select2');
3344 + wp_enqueue_style('select2-select2');
2746 3345 }
2747 3346 ?>
2748 3347 <?php
2749 3348 $counter++;
@@ -2787,11 +3386,11 @@
2787 3386
2788 3387 //load javascript library
2789 3388 if($counter==0)
2790 3389 {
2791 - wp_enqueue_script('select2');
3390 + wp_enqueue_script('select2-select2');
2792 3391 wp_enqueue_script('wdk-select2');
2793 - wp_enqueue_style('select2');
3392 + wp_enqueue_style('select2-select2');
2794 3393 }
2795 3394 ?>
2796 3395 <?php
2797 3396 $counter++;
@@ -2869,11 +3468,30 @@
2869 3468 'r'=>'llll',
2870 3469 'u'=>'x',
2871 3470 );
2872 3471
2873 - $replaced_from = array_keys($replaced);
2874 - $date_format = str_replace($replaced_from, array_keys($replaced_from), $date_format);
2875 - 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);
2876 3494 }
2877 3495 }
2878 3496
2879 3497 if ( ! function_exists('wdk_convert_date_format_jquery'))
@@ -2914,11 +3532,29 @@
2914 3532 'u'=>'@',
2915 3533 ':'=>'',
2916 3534 );
2917 3535
2918 - $replaced_from = array_keys($replaced);
2919 - $date_format = str_replace($replaced_from, array_keys($replaced_from), $date_format);
2920 - 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);
2921 3557 }
2922 3558 }
2923 3559
2924 3560 if ( ! function_exists('wdk_convert_date_format_jquery'))
@@ -2959,11 +3595,31 @@
2959 3595 'u'=>'@',
2960 3596 ':'=>'',
2961 3597 );
2962 3598
2963 - $replaced_from = array_keys($replaced);
2964 - $date_format = str_replace($replaced_from, array_keys($replaced_from), $date_format);
2965 - 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 +
2966 3622 }
2967 3623 }
2968 3624
2969 3625 if ( ! function_exists('wdk_get_gps'))
@@ -2975,15 +3631,33 @@
2975 3631 * @return array An array containing Latitude/Longitude/Altitude data
2976 3632 */
2977 3633 function wdk_get_gps($address = '')
2978 3634 {
3635 +
3636 + $address_key = 'cached_address_gps';
3637 +
2979 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 +
2980 3646 $address = str_replace(' ','+',$address);
2981 3647
2982 3648 if(!isset($results[$address])) {
2983 3649 $results[$address] = NULL;
2984 3650 $url = 'https://nominatim.openstreetmap.org/search?format=json&q=' . $address;
2985 - $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);
2986 3660 $response = '';
2987 3661
2988 3662 // request failed
2989 3663 if ( is_wp_error( $request ) ) {
@@ -2989,9 +3663,8 @@
2989 3663 if ( is_wp_error( $request ) ) {
2990 3664 $response = $request;
2991 3665 }
2992 3666 $code = (int) wp_remote_retrieve_response_code( $request );
2993 -
2994 3667 // make sure the fetch was successful
2995 3668 if (empty($response) && $code == 200 ) {
2996 3669 $response = wp_remote_retrieve_body( $request );
2997 3670 // Decode the json
@@ -2998,8 +3671,9 @@
2998 3671 $resp = json_decode( $response, true );
2999 3672
3000 3673 if(!empty($resp) && isset($resp[0]) && isset($resp[0]['lat']) && isset($resp[0]['lon'])) {
3001 3674 $results[$address] = array('lat' => $resp[0]['lat'], 'lng' => $resp[0]['lon'], 'alt' => 0);
3675 +
3002 3676 return $results[$address];
3003 3677 }
3004 3678 }
3005 3679 } else {
@@ -3139,8 +3813,32 @@
3139 3813 return false;
3140 3814 }
3141 3815 }
3142 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 +
3143 3841 if ( ! function_exists('wdk_filter_phone'))
3144 3842 {
3145 3843 // Validation phone
3146 3844 /**
@@ -3276,9 +3974,22 @@
3276 3974
3277 3975 $value = filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
3278 3976 $value = (float)str_replace(array(","," ",'&nbsp;'), "", $value);
3279 3977
3280 - 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);
3281 3992 }
3282 3993 }
3283 3994
3284 3995 if ( ! function_exists('wdk_currency_symbol'))
@@ -3408,11 +4119,23 @@
3408 4119 $user_data['wdk_viber'] = wmvc_show_data('cacheduser_wdk_viber', $row);
3409 4120 $user_data['wdk_iban'] = wmvc_show_data('cacheduser_wdk_iban', $row);
3410 4121 $user_data['wdk_telegram'] = wmvc_show_data('cacheduser_wdk_telegram', $row);
3411 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);
3412 4124 $user_data['description'] = wmvc_show_data('cacheduser_description', $row);
3413 4125 $user_data['user_url'] = wmvc_show_data('cacheduser_user_url', $row);
3414 - $user_data['roles'] = explode(',', wmvc_show_data('cacheduser_roles', $value));
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 + }
3415 4138
3416 4139 return $user_data;
3417 4140 }
3418 4141 }
@@ -3656,11 +4379,11 @@
3656 4379 $page_title,
3657 4380 $post_type
3658 4381 );
3659 4382 }
3660 -
3661 - $page = $wpdb->get_var( $sql );
3662 -
4383 + $page = $wpdb->get_var( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
4384 +
4385 +
3663 4386 if ( $page ) {
3664 4387 return get_post( $page, $output );
3665 4388 }
3666 4389
@@ -3666,5 +4389,1064 @@
3666 4389
3667 4390 return null;
3668 4391 }
3669 4392 }
3670 -?>
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 +?>