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 +3884 -137 1.1.0 → 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
@@ -42,13 +42,13 @@
42 42
43 43 /* get WMVC form fields */
44 44 if(is_object($fields))
45 45 $user_fields = json_decode($fields->searchform_json);
46 -
47 46 /* generate WMVC form fields html */
48 47 if(is_array($user_fields))
49 48 foreach($user_fields as $used_field)
50 49 {
50 +
51 51 if($used_field->field_id == 'cat') {
52 52 $field = array(
53 53 "idfield" => 'category',
54 54 "field_type" => 'CATEGORY',
@@ -55,8 +55,9 @@
55 55 "field_label" => __('Category', 'wpdirectorykit'),
56 56 "prefix" => '',
57 57 "suffix" => '',
58 58 "values_list" => '',
59 + "placeholder" => '',
59 60 );
60 61 }else if($used_field->field_id == 'loc') {
61 62 $field = array(
62 63 "idfield" => 'location',
@@ -64,8 +65,9 @@
64 65 "field_label" => __('Location', 'wpdirectorykit'),
65 66 "prefix" => '',
66 67 "suffix" => '',
67 68 "values_list" => '',
69 + "placeholder" => '',
68 70 );
69 71 }else if($used_field->field_id == 'address') {
70 72 $field = array(
71 73 "idfield" => 'address',
@@ -73,8 +75,9 @@
73 75 "field_label" => __('Address', 'wpdirectorykit'),
74 76 "prefix" => '',
75 77 "suffix" => '',
76 78 "values_list" => '',
79 + "placeholder" => '',
77 80 );
78 81 }else if($used_field->field_id == 'post_title') {
79 82 $field = array(
80 83 "idfield" => 'post_title',
@@ -82,8 +85,9 @@
82 85 "field_label" => __('Title', 'wpdirectorykit'),
83 86 "prefix" => '',
84 87 "suffix" => '',
85 88 "values_list" => '',
89 + "placeholder" => '',
86 90 );
87 91 }else if($used_field->field_id == 'search') {
88 92 $field = array(
89 93 "idfield" => 'search',
@@ -91,8 +95,9 @@
91 95 "field_label" => __('Search', 'wpdirectorykit'),
92 96 "prefix" => '',
93 97 "suffix" => '',
94 98 "values_list" => '',
99 + "placeholder" => '',
95 100 );
96 101 }else if(function_exists('run_wdk_bookings') && $used_field->field_id == 'booking_date') {
97 102 $field = array(
98 103 "idfield" => 'booking_date',
@@ -100,9 +105,20 @@
100 105 "field_label" => __('Booking Date', 'wpdirectorykit'),
101 106 "prefix" => '',
102 107 "suffix" => '',
103 108 "values_list" => '',
109 + "placeholder" => '',
104 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 + );
105 121 }else if($used_field->field_id == 'more') {
106 122 $field = array(
107 123 "idfield" => 'MORE',
108 124 "field_type" => 'MORE',
@@ -109,20 +125,38 @@
109 125 "field_label" => __('MORE', 'wpdirectorykit'),
110 126 "prefix" => '',
111 127 "suffix" => '',
112 128 "values_list" => '',
129 + "placeholder" => '',
113 130 );
114 131 } else {
115 132 $field_data = $WMVC->field_m->get_fields_data($used_field->field_id);
116 - if($field_data)
117 - $field = array(
118 - "idfield" => wmvc_show_data('idfield', $field_data),
119 - "field_type" => wmvc_show_data('field_type', $field_data),
120 - "field_label" =>wmvc_show_data('field_label', $field_data),
121 - "prefix" => wmvc_show_data('prefix', $field_data),
122 - "suffix" => wmvc_show_data('suffix', $field_data),
123 - "values_list" => wmvc_show_data('values_list', $field_data)
124 - );
133 + if($field_data) {
134 + if($used_field->query_type == 'slider_range') {
135 + $field = array(
136 + "idfield" => wmvc_show_data('idfield', $field_data),
137 + "field_type" => 'SLIDER_RANGE',
138 + "field_label" =>wmvc_show_data('field_label', $field_data),
139 + "prefix" => wmvc_show_data('prefix', $field_data),
140 + "suffix" => wmvc_show_data('suffix', $field_data),
141 + "value_min" => wmvc_show_data('value_min', $used_field),
142 + "value_max" => wmvc_show_data('value_max', $used_field),
143 + "values_list" => wmvc_show_data('values_list', $field_data),
144 + "placeholder" => wmvc_show_data('placeholder', $field_data)
145 + );
146 + } else {
147 + $field = array(
148 + "idfield" => wmvc_show_data('idfield', $field_data),
149 + "field_type" => wmvc_show_data('field_type', $field_data),
150 + "field_label" =>wmvc_show_data('field_label', $field_data),
151 + "prefix" => wmvc_show_data('prefix', $field_data),
152 + "suffix" => wmvc_show_data('suffix', $field_data),
153 + "values_list" => wmvc_show_data('values_list', $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),
156 + );
157 + }
158 + }
125 159 }
126 160
127 161 /* if field not detected or remove from fields list, skip field in search */
128 162 if(empty($field)) continue;
@@ -137,8 +171,12 @@
137 171 $field_data = array();
138 172 $field_data ['field_data'] = $field;
139 173 $field_data ['predefinedfields_query'] = $predefinedfields_query;
140 174
175 + if(in_array(wmvc_show_data('field_type', $field),array('SECTION'))) {
176 + continue;
177 + }
178 +
141 179 $field_view_path = WPDIRECTORYKIT_PATH.'application/views/search_fields/'.$subfolder.(wmvc_show_data('field_type', $field)).'.php';
142 180 if(file_exists($field_view_path))
143 181 {
144 182 $output .= $WMVC->view('search_fields/'.$subfolder.(wmvc_show_data('field_type', $field)), $field_data, FALSE);
@@ -146,14 +184,15 @@
146 184 else
147 185 {
148 186 /* show missing view file of field, only if print enable */
149 187 if($print)
150 - $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';
151 189 }
152 190
153 191 }
154 192
155 193 if($print){
194 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.WP.I18n.NonSingularStringLiteralText
156 195 echo $output;
157 196 return FALSE;
158 197 }
159 198
@@ -160,8 +199,179 @@
160 199 return $output;
161 200 }
162 201 }
163 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 +
164 374 function &wdk_get_instance()
165 375 {
166 376 global $Winter_MVC_WDK;
167 377
@@ -176,8 +386,9 @@
176 386 }
177 387
178 388 function wdk_prepare_search_query_GET($columns = array(), $model_name = NULL, $external_columns = array(), $custom_parameters = array(), $skip_postget = FALSE)
179 389 {
390 +
180 391 global $Winter_MVC_WDK;
181 392 $WMVC = &$Winter_MVC_WDK;
182 393 $wdk_bookings_joinded = false;
183 394 static $available_fields_listings = NULL;
@@ -182,9 +393,15 @@
182 393 $wdk_bookings_joinded = false;
183 394 static $available_fields_listings = NULL;
184 395 static $available_fields_static = array();
185 396 static $list_fields_static = NULL;
397 + $fields_type = array();
186 398
399 + /* add if missing columns */
400 + if(!in_array('post_id', $columns)) {
401 + $columns[] = $Winter_MVC_WDK->db->prefix.'wdk_listings.post_id';
402 + }
403 +
187 404 $_GET_clone = array();
188 405
189 406 if(!$skip_postget)
190 407 $_GET_clone = array_merge($_GET, $_POST);
@@ -191,14 +408,14 @@
191 408
192 409 if(isset($_GET_clone['order_by']) && $_GET_clone['order_by'] =='undefined') {
193 410 unset($_GET_clone['order_by']);
194 411 }
195 -
412 +
196 413 if(isset($custom_parameters['order_by'])) {
197 414
198 415 if(isset($_GET_clone['order_by']) && !empty($_GET_clone['order_by'])) {
199 - $_GET_clone['order_by'] = $custom_parameters['order_by'].', '.$_GET_clone['order_by'];
200 - } 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'])) {
201 418 $_GET_clone['order_by'] = $custom_parameters['order_by'];
202 419 }
203 420
204 421 unset($custom_parameters['order_by']);
@@ -211,15 +428,14 @@
211 428 $WMVC->model('listing_m');
212 429 $WMVC->model('field_m');
213 430 $WMVC->model('listingfield_m');
214 431
215 -
216 432 $smart_search = '';
217 433 if(isset($_GET_clone['search']))
218 - $smart_search = sanitize_text_field($_GET_clone['search']);
434 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['search']));
219 435
220 436 if(isset($_GET_clone['field_search']))
221 - $smart_search = sanitize_text_field($_GET_clone['field_search']);
437 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['field_search']));
222 438
223 439 if(!isset($available_fields_static[$model_name]))
224 440 {
225 441 $available_fields = $WMVC->$model_name->get_available_fields();
@@ -252,13 +468,20 @@
252 468 foreach($list_fields as $field_data) {
253 469
254 470 $field_id = wmvc_show_data('idfield',$field_data);
255 471 $field_type = wmvc_show_data('field_type',$field_data);
472 +
473 + $fields_type[$field_id] = $field_type;
256 474 $column_name ='field_'.$field_id.'_'.$field_type;
257 475 if(!isset($available_fields_listings[$column_name])) continue;
258 476
259 477 if(isset($_GET_clone['field_'.$field_id])) {
260 - $_GET_clone['field_'.$field_id.'_'.$field_type] = apply_filters( 'wdk-currency-conversion/convert/default_value',sanitize_text_field($_GET_clone['field_'.$field_id]), $field_id);
478 +
479 + if($field_type == 'DROPDOWNMULTIPLE') {
480 + $_GET_clone['field_'.$field_id.'_'.$field_type] = $_GET_clone['field_'.$field_id];
481 + } else {
482 + $_GET_clone['field_'.$field_id.'_'.$field_type] = apply_filters( 'wdk-currency-conversion/convert/default_value',sanitize_text_field($_GET_clone['field_'.$field_id]), $field_id);
483 + }
261 484 }
262 485
263 486 if(isset($_GET_clone['field_'.$field_id.'_max'])) {
264 487 $_GET_clone['field_'.$field_id.'_'.$field_type.'_max'] = apply_filters( 'wdk-currency-conversion/convert/default_value',sanitize_text_field($_GET_clone['field_'.$field_id.'_max']), $field_id);
@@ -266,9 +489,9 @@
266 489 if(isset($_GET_clone['field_'.$field_id.'_min'])) {
267 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);
268 491 }
269 492 if(isset($_GET_clone['field_'.$field_id.'_exactly'])) {
270 - $_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']);
271 494 }
272 495
273 496 $columns[] = $column_name;
274 497 $columns[] = $column_name.'_max';
@@ -278,9 +501,23 @@
278 501 $external_columns[] = $column_name.'_max';
279 502 $external_columns[] = $column_name.'_min';
280 503 $external_columns[] = $column_name.'_exactly';
281 504 }
505 +
506 + if(isset($_GET_clone['search_agents_ids'])) {
507 + $column_name ='agents_ids';
508 + $_GET_clone[$column_name] = $_GET_clone['search_agents_ids'];
509 + $columns[] = $column_name;
510 + $external_columns[] = $column_name;
511 + }
282 512
513 + if(isset($_GET_clone['search_user_editor_ids'])) {
514 + $column_name ='user_editor_ids';
515 + $_GET_clone[$column_name] = $_GET_clone['search_user_editor_ids'];
516 + $columns[] = $column_name;
517 + $external_columns[] = $column_name;
518 + }
519 +
283 520 if(isset($_GET_clone['search_location'])) {
284 521 $column_name ='location_id';
285 522 $_GET_clone[$column_name] = $_GET_clone['search_location'];
286 523 $columns[] = $column_name;
@@ -292,8 +529,15 @@
292 529 $_GET_clone[$column_name] = $_GET_clone['search_category'];
293 530 $columns[] = $column_name;
294 531 $external_columns[] = $column_name;
295 532 }
533 +
534 + if(isset($_GET_clone['search_gps'])) {
535 + $column_name ='gps';
536 + $_GET_clone[$column_name] = $_GET_clone['search_gps'];
537 + $columns[] = $column_name;
538 + $external_columns[] = $column_name;
539 + }
296 540
297 541 if(isset($_GET_clone['field_address'])) {
298 542 $column_name ='address';
299 543 $_GET_clone[$column_name] = $_GET_clone['field_address'];
@@ -300,8 +544,36 @@
300 544 $columns[] = $column_name;
301 545 $external_columns[] = $column_name;
302 546 }
303 547
548 + if(isset($_GET_clone['field_post_id'])) {
549 + $column_name ='ID_exactly';
550 + $_GET_clone[$column_name] = sanitize_text_field($_GET_clone['field_post_id']);
551 + $columns[] = $column_name;
552 + $external_columns[] = $column_name;
553 + }
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 +
304 576 if (function_exists('run_wdk_bookings') && isset($_GET_clone['field_booking_date_from'])) {
305 577 $column_name ='field_booking_date_from';
306 578 $_GET_clone[$column_name] = $_GET_clone['field_booking_date_from'];
307 579 $columns[] = $column_name;
@@ -314,8 +586,36 @@
314 586 $columns[] = $column_name;
315 587 $external_columns[] = $column_name;
316 588 }
317 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 +
318 618 //$table_name = substr($model_name, 0, -2);
319 619 $columns_original = array();
320 620 foreach($columns as $key=>$val)
321 621 {
@@ -343,8 +643,10 @@
343 643 {
344 644 unset($_GET_clone['search']);
345 645 unset($_GET_clone['field_search']);
346 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 +
347 649 // For quick/smart search
348 650 if(wmvc_count($columns) > 0 && !empty($smart_search))
349 651 {
350 652 $gen_q = '';
@@ -349,8 +651,22 @@
349 651 {
350 652 $gen_q = '';
351 653 foreach($columns as $key=>$value)
352 654 {
655 +
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;
657 +
658 + if(strpos($value, '_CHECKBOX') !== FALSE) continue;
659 +
660 + // if smart is number, search only im number fields
661 +
662 +
663 + if(is_intval($smart_search)) {
664 + if(strpos($value, '_NUMBER') === FALSE /*&& $value != 'category_id' && $value != 'location_id'*/ && strpos($value, 'post_id') === FALSE ) continue;
665 + } else {
666 + if($value == 'category_id' || $value == 'location_id' || strpos($value, 'post_id') !== FALSE) continue;
667 + }
668 +
353 669 if(substr_count($value, 'id') > 0 && is_numeric($smart_search))
354 670 {
355 671 $gen_q.="$value = $smart_search OR ";
356 672 }
@@ -371,8 +687,15 @@
371 687 else if(substr($value, -4) == '_min')
372 688 {
373 689
374 690 }
691 + else if(strpos($value, '_NUMBER') !== FALSE)
692 + {
693 + if(is_intval($smart_search)){
694 + $gen_search = $smart_search;
695 + $gen_q.="$value = $gen_search OR ";
696 + }
697 + }
375 698 else
376 699 {
377 700 $gen_q.="$value LIKE '%$smart_search%' OR ";
378 701 }
@@ -377,52 +700,123 @@
377 700 $gen_q.="$value LIKE '%$smart_search%' OR ";
378 701 }
379 702 }
380 703
381 - for($i = 1 ; $i <= 2; $i++){
382 - $gen_q.="location_".$i.".location_title LIKE '%$smart_search%' OR ";
704 + /* location / categories */
705 + if(!is_intval($smart_search)) {
706 + $gen_q.="location_title LIKE '%$smart_search%' OR ";
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 +
383 713 }
714 + /* get address and gps */
715 + if(strlen($smart_search) > 5) {
716 + $coordinates_center = wdk_get_gps($smart_search);
717 + $search_radius = 5;
718 + if($coordinates_center && $coordinates_center['lat'] != 0 && is_numeric($search_radius))
719 + {
720 + $distance_unit = 'km';
721 + if(__('km', 'wpdirectorykit') == 'm')
722 + {
723 + $distance_unit = 'm';
724 + }
725 +
726 + // calculate rectangle
727 + $rectangle_ne = wdk_getDueCoords($coordinates_center['lat'], $coordinates_center['lng'], 45, $search_radius, $distance_unit);
728 + $rectangle_sw = wdk_getDueCoords($coordinates_center['lat'], $coordinates_center['lng'], 225, $search_radius, $distance_unit);
729 +
730 + $gps_ne = explode(', ', $rectangle_ne);
731 + $gps_sw = explode(', ', $rectangle_sw);
732 +
733 + $gen_q .="(".$WMVC->db->prefix."wdk_listings.lat < '$gps_ne[0]' AND ".$WMVC->db->prefix."wdk_listings.lat > '$gps_sw[0]' AND
734 + ".$WMVC->db->prefix."wdk_listings.lng < '$gps_ne[1]' AND ".$WMVC->db->prefix."wdk_listings.lng > '$gps_sw[1]') OR ";
735 +
736 + }
737 + }
384 738
739 + /* detect is gps */
740 + if(wdk_is_gps($smart_search)) {
741 + $gps = explode(',',$smart_search);
742 + $coordinates_center = array('lat'=>trim($gps[0]),'lng'=>trim($gps[1]));
743 + $search_radius = 5;
744 + if($coordinates_center && $coordinates_center['lat'] != 0 && is_numeric($search_radius))
745 + {
746 + $distance_unit = 'km';
747 + if(__('km', 'wpdirectorykit') == 'm')
748 + {
749 + $distance_unit = 'm';
750 + }
751 +
752 + // calculate rectangle
753 + $rectangle_ne = wdk_getDueCoords($coordinates_center['lat'], $coordinates_center['lng'], 45, $search_radius, $distance_unit);
754 + $rectangle_sw = wdk_getDueCoords($coordinates_center['lat'], $coordinates_center['lng'], 225, $search_radius, $distance_unit);
755 +
756 + $gps_ne = explode(', ', $rectangle_ne);
757 + $gps_sw = explode(', ', $rectangle_sw);
758 +
759 + $gen_q .="(".$WMVC->db->prefix."wdk_listings.lat < '$gps_ne[0]' AND ".$WMVC->db->prefix."wdk_listings.lat > '$gps_sw[0]' AND
760 + ".$WMVC->db->prefix."wdk_listings.lng < '$gps_ne[1]' AND ".$WMVC->db->prefix."wdk_listings.lng > '$gps_sw[1]') OR ";
761 +
762 + }
763 + }
764 +
385 765 $gen_q = substr($gen_q, 0, -4);
386 766
387 767 if(!empty($gen_q))
388 768 $WMVC->db->where("($gen_q)");
389 769 }
390 -
770 +
391 771 // For column search
392 772 if(isset($_GET_clone))
393 773 {
394 774 $gen_q = '';
395 -
396 775 foreach($_GET_clone as $key=>$val)
397 776 {
398 777 if(!empty($val) && in_array($key, $columns))
399 778 {
400 779 $col_name = $key;
401 -
780 +
402 781 $val = esc_sql($val);
403 782 //if(isset($key))
404 783 // $col_name = $key;
405 784
406 785 if(strpos($key, 'skip') !== FALSE) continue;
407 -
408 - if($key == 'field_booking_date_from')
786 +
787 + if($key == 'field_booking_guest')
409 788 {
410 789 if(!$wdk_bookings_joinded){
411 - $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');
412 - $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
413 - $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');
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');
414 793 $wdk_bookings_joinded = true;
415 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');
416 796 }
417 797
418 - if((bool)strtotime($val) && strtotime($val) > 1000)
798 + $gen_q.= $WMVC->db->prefix."wdk_booking_calendar.guests >='".intval($val)."' AND ";
799 +
800 + }
801 + elseif($key == 'field_booking_date_from')
802 + {
803 + if(!$wdk_bookings_joinded){
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');
807 + $wdk_bookings_joinded = true;
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');
810 + }
811 +
812 + if(wdk_is_date($val))
419 813 {
420 814 if(!get_option('wdk_bookings_is_hours_enabled')) {
421 - $gen_search = date('Y-m-d', strtotime($val));
815 + $gen_search = wdk_normalize_date_db($val, 'Y-m-d H:i:s', 'Y-m-d');
422 816 $gen_q.= "DATE_FORMAT(".$WMVC->db->prefix."wdk_booking_price.date_from, '%Y-%m-%d') <= '".$gen_search."' AND ";
423 817 } else {
424 - $gen_search = date('Y-m-d H:i:s', strtotime($val));
818 + $gen_search = wdk_normalize_date_db($val);
425 819 $gen_q.= $WMVC->db->prefix."wdk_booking_price.date_from >'".$gen_search."' AND ";
426 820 }
427 821 }
428 822
@@ -428,12 +822,12 @@
428 822
429 823 if( isset($_GET_clone['field_booking_date_from']) && isset($_GET_clone['field_booking_date_to'])) {
430 824
431 825 if(!get_option('wdk_bookings_is_hours_enabled')) {
432 - $gen_search_from = date('Y-m-d', strtotime($_GET_clone['field_booking_date_from']));
433 - $gen_search_to = date('Y-m-d', strtotime($_GET_clone['field_booking_date_to']));
826 + $gen_search_from = wdk_normalize_date_db($_GET_clone['field_booking_date_from'], 'Y-m-d H:i:s', 'Y-m-d');
827 + $gen_search_to = wdk_normalize_date_db($_GET_clone['field_booking_date_to'], 'Y-m-d H:i:s', 'Y-m-d');
434 828
435 - $gen_q.= $WMVC->listing_m->_table_name.".post_id NOT IN (
829 + $gen_q.= $WMVC->db->prefix."posts.ID NOT IN (
436 830 SELECT post_id
437 831 FROM ".$WMVC->db->prefix."wdk_booking_reservation
438 832 WHERE
439 833 ".$WMVC->db->prefix."wdk_booking_reservation.is_approved = 1
@@ -443,12 +837,12 @@
443 837 DATE_FORMAT(".$WMVC->db->prefix."wdk_booking_reservation.date_to, '%Y-%m-%d') > '".$gen_search_from."'
444 838 ) AND ";
445 839
446 840 } else {
447 - $gen_search_from = date('Y-m-d H:i:s', strtotime($_GET_clone['field_booking_date_from']));
448 - $gen_search_to = date('Y-m-d H:i:s', strtotime($_GET_clone['field_booking_date_to']));
841 + $gen_search_from = wdk_normalize_date_db($_GET_clone['field_booking_date_from']);
842 + $gen_search_to = wdk_normalize_date_db($_GET_clone['field_booking_date_to']);
449 843
450 - $gen_q.= $WMVC->listing_m->_table_name.".post_id NOT IN (
844 + $gen_q.= $WMVC->db->prefix."posts.ID NOT IN (
451 845 SELECT post_id
452 846 FROM ".$WMVC->db->prefix."wdk_booking_reservation
453 847 WHERE
454 848 ".$WMVC->db->prefix."wdk_booking_reservation.is_approved = 1
@@ -463,22 +857,22 @@
463 857 }
464 858 elseif($key == 'field_booking_date_to')
465 859 {
466 860 if(!$wdk_bookings_joinded){
467 - $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');
468 - $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');
469 863 $wdk_bookings_joinded = true;
470 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');
471 866 }
472 867
473 - if((bool)strtotime($val) && strtotime($val) > 1000)
868 + if(wdk_is_date($val))
474 869 {
475 -
476 870 if(!get_option('wdk_bookings_is_hours_enabled')) {
477 - $gen_search = date('Y-m-d', strtotime($val));
871 + $gen_search = wdk_normalize_date_db($val, 'Y-m-d H:i:s', 'Y-m-d');
478 872 $gen_q.= "DATE_FORMAT(".$WMVC->db->prefix."wdk_booking_price.date_to, '%Y-%m-%d') >= '".$gen_search."' AND ";
479 873 } else {
480 - $gen_search = date('Y-m-d H:i:s', strtotime($val));
874 + $gen_search = wdk_normalize_date_db($val);
481 875 $gen_q.= $WMVC->db->prefix."wdk_booking_price.date_to >'".$gen_search."' AND ";
482 876 }
483 877 }
484 878
@@ -485,9 +879,33 @@
485 879 }
486 880 elseif(substr($key, -8) == '_exactly')
487 881 {
488 882 $col_name = substr($key, 0, -8);
489 - $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 + }
490 908 }
491 909 elseif(substr($key, -4) == '_max')
492 910 {
493 911 $col_name = substr($key, 0, -4);
@@ -493,8 +911,14 @@
493 911 $col_name = substr($key, 0, -4);
494 912
495 913 if(strpos($key, 'NUMBER') !== FALSE) {
496 914 $gen_q.=$col_name." <= ".intval($val)." AND ";
915 + } else if(strpos($key, 'DATE') !== FALSE) {
916 + if(wdk_is_date($val))
917 + {
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 ";
920 + }
497 921 } else {
498 922 $gen_q.=$col_name." <= '".$val."' AND ";
499 923 }
500 924 }
@@ -500,22 +924,31 @@
500 924 }
501 925 else if(substr($key, -4) == '_min')
502 926 {
503 927 $col_name = substr($key, 0, -4);
504 -
928 +
505 929 if(strpos($key, 'NUMBER') !== FALSE) {
506 930 $gen_q.=$col_name." >= ".intval($val)." AND ";
931 + } else if(strpos($key, 'DATE') !== FALSE) {
932 + if(wdk_is_date($val))
933 + {
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 ";
936 + }
507 937 } else {
508 938 $gen_q.=$col_name." >= '".$val."' AND ";
509 939 }
510 940 }
511 - elseif(substr_count($key, 'id') > 0 && is_numeric($val))
941 + elseif(substr_count($key, 'id') > 0 && is_numeric($val) && $key != 'agents_ids' && $key !='user_editor_ids' && $key !='location_id' && $key !='category_id')
512 942 {
513 943 // ID is always numeric
514 944
515 945 if($key == 'location_id') {
516 - $gen_q .= "(`location_1`.`parent_path` = ".$val." OR ";
517 - $gen_q .= "`location_2`.`parent_path` = ".$val." OR ";
946 + /* $gen_q .= "(`location_table`.`parent_path` = ".$val." OR ";
947 + $gen_q .= "`location_2`.`parent_path` = ".$val." OR ";*/
948 + $gen_q .= "(`location_table`.`parent_id` = ".$val." OR ";
949 + //$gen_q .= "`".$WMVC->db->prefix."wdk_locations `.`level_0_id` = ".$val." OR ";
950 +
518 951 $gen_q .= $col_name." = ".$val.") AND ";
519 952 } elseif($key == 'category_id') {
520 953 $gen_q .= "('parent_path' = ".$val." OR ";
521 954 $gen_q .= $col_name." = ".$val.") AND ";
@@ -522,20 +955,17 @@
522 955 } else {
523 956 $gen_q.=$col_name." = ".$val." AND ";
524 957 }
525 958 }
526 - else if(substr_count($key, 'date') > 0)
959 + else if(substr_count($key, '_DATE') > 0)
527 960 {
528 961 // DATE VALUES
529 962
530 963 $gen_search = $val;
531 -
532 - $detect_date = strtotime($gen_search);
533 -
534 - if(wdk_is_date($val) && $detect_date > 1000)
964 + if(wdk_is_date($val))
535 965 {
536 - $gen_search = date('Y-m-d H:i:s', $detect_date);
537 - $gen_q.=$col_name." > '".$gen_search."' AND ";
966 + $gen_search = wdk_normalize_date_db($gen_search, 'Y-m-d H:i:s', 'Y-m-d');
967 + $gen_q.=$col_name." LIKE '%".$gen_search."%' AND ";
538 968 }
539 969 else
540 970 {
541 971 $gen_q.=$col_name." LIKE '%".$gen_search."%' AND ";
@@ -555,14 +985,201 @@
555 985 {
556 986 $gen_q.=$col_name." IS NULL AND ";
557 987 }
558 988 }
559 - else
989 + elseif($key == 'agents_ids')
560 990 {
561 - $gen_q.=$col_name." LIKE '%".$val."%' AND ";
991 + if(is_string($val) && strpos($val, ',') !== FALSE){
992 + $val =explode(',', $val);
993 + } elseif(is_string($val)){
994 + $val =array($val);
995 + }
996 +
997 + if(is_array($val)) {
998 +
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');
1000 + $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
1001 + $sql_search = '';
1002 + foreach ($val as $v) {
1003 + if(empty($v)) continue;
1004 +
1005 + if(!empty($sql_search))
1006 + $sql_search .= " OR ";
1007 +
1008 +
1009 + $sql_search .=" ".$WMVC->listing_m->_table_name.".`user_id_editor` = ".intval($v)." OR `".$WMVC->db->prefix."wdk_listings_users`.`user_id` = ".intval($v)." ";
1010 + }
1011 +
1012 + if(!empty($sql_search))
1013 + $gen_q.=" ( ".$sql_search." ) AND ";
1014 +
1015 + } elseif(is_string($val) && !empty($val)) {
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');
1017 + $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
1018 + $sql_search =" ".$WMVC->listing_m->_table_name.".`user_id_editor` = ".intval($val)." OR `".$WMVC->db->prefix."wdk_listings_users`.`user_id` = ".intval($val)." ";
1019 + $gen_q.=" ( ".$sql_search." ) AND ";
1020 + }
562 1021 }
1022 + elseif($key == 'user_editor_ids')
1023 + {
1024 +
1025 + if(is_array($val)) {
1026 +
1027 + $sql_search = '';
1028 + foreach ($val as $v) {
1029 + if(empty($v)) continue;
1030 +
1031 + if(!empty($sql_search))
1032 + $sql_search .= " OR ";
1033 +
1034 +
1035 + $sql_search .=" ".$WMVC->listing_m->_table_name.".`user_id_editor` = ".intval($v)." ";
1036 + }
1037 +
1038 + if(!empty($sql_search))
1039 + $gen_q.=" ( ".$sql_search." ) AND ";
1040 +
1041 + } elseif(is_string($val) && !empty($val)) {
1042 + $sql_search =" ".$WMVC->listing_m->_table_name.".`user_id_editor` = ".intval($val)." ";
1043 + $gen_q.=" ( ".$sql_search." ) AND ";
1044 + }
1045 + }
1046 + elseif($key == 'location_id')
1047 + {
1048 + if(empty($val)) continue;
1049 +
1050 + if(is_string($val) && strpos($val, ',') !== FALSE){
1051 + $val =explode(',', $val);
1052 + } elseif(is_string($val)){
1053 + $val =array($val);
1054 + }
1055 +
1056 + if(is_array($val)) {
1057 +
1058 + if(false){
1059 + $WMVC->db->join($WMVC->db->prefix.'wdk_listings_locations ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'wdk_listings_locations.post_id', NULL, 'LEFT');
1060 + $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
1061 + }
1062 +
1063 + $sql_search = '';
1064 + foreach ($val as $v) {
1065 + if(empty($v) || !is_intval($v)) continue;
1066 +
1067 + if(!empty($sql_search))
1068 + $sql_search .= " OR ";
1069 +
1070 + $sql_search .= " ".$WMVC->listing_m->_table_name.".`location_id`=".intval($v)."";
1071 + $sql_search .= " OR `location_table`.`parent_id`=".intval($v)."";
1072 +
1073 + $sql_search .= " OR CONCAT(',', location_table.parent_path, ',') LIKE CONCAT('%,', ".intval($v).", ',%')";
1074 +
1075 + /* other locations */
1076 + /* multi select */
1077 + if(false){
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).") ";
1079 + } elseif(false) {
1080 + $sql_search .= " OR ".$WMVC->db->prefix."wdk_listings_locations.location_id=".intval($v)."";
1081 + } else {
1082 + $sql_search .= " OR ".$WMVC->listing_m->_table_name.".locations_list LIKE '%,".intval($v).",%'";
1083 + }
1084 +
1085 + }
1086 +
1087 + if(!empty($sql_search))
1088 + $gen_q.=" ( ".$sql_search." ) AND ";
1089 + }
1090 + }
1091 + elseif($key == 'category_id')
1092 + {
1093 +
1094 + if(empty($val)) continue;
1095 +
1096 + if(is_string($val) && strpos($val, ',') !== FALSE){
1097 + $val =explode(',', $val);
1098 + } elseif(is_string($val)){
1099 + $val =array($val);
1100 + }
1101 +
1102 +
1103 + if(is_array($val)) {
1104 + if(false){
1105 + $WMVC->db->join($WMVC->db->prefix.'wdk_listings_categories ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'wdk_listings_categories.post_id', NULL, 'LEFT');
1106 + }
1107 +
1108 + $sql_search = '';
1109 + foreach ($val as $v) {
1110 + if(empty($v) || !is_intval($v)) continue;
1111 +
1112 + if(!empty($sql_search))
1113 + $sql_search .= " OR ";
1114 +
1115 + $sql_search .= " ".$WMVC->db->prefix."wdk_listings.`category_id` = ".intval($v)."";
1116 + $sql_search .= " OR `category_table`.`parent_id`=".intval($v)."";
1117 + $sql_search .= " OR CONCAT(',', category_table.parent_path, ',') LIKE CONCAT('%,', ".intval($v).", ',%')";
1118 +
1119 + /* other categories */
1120 + if(false){
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).")";
1122 + } elseif(false) {
1123 + $sql_search .= " OR ".$WMVC->db->prefix."wdk_listings_categories.category_id=".intval($v)."";
1124 + } else {
1125 + $sql_search .= " OR ".$WMVC->listing_m->_table_name.".categories_list LIKE '%,".intval($v).",%'";
1126 + }
1127 +
1128 + }
1129 +
1130 + if(!empty($sql_search))
1131 + $gen_q.=" ( ".$sql_search." ) AND ";
1132 + }
1133 + }
1134 + elseif(is_string($val))
1135 + {
1136 +
1137 + if(strpos($val, ',') !== FALSE){
1138 + $val = explode(',', $val);
1139 + }
1140 +
1141 + if(is_array($val)) {
1142 + $sql_search = '';
1143 + foreach ($val as $v) {
1144 + if(empty($v)) continue;
1145 +
1146 + if(!empty($sql_search))
1147 + $sql_search .= " OR ";
1148 +
1149 + $sql_search .= $col_name." LIKE '%".$v."%'";
1150 +
1151 + }
1152 +
1153 + if(!empty($sql_search))
1154 + $gen_q.=" ( ".$sql_search." ) AND ";
1155 + } else {
1156 + $gen_q.=$col_name." LIKE '%".$val."%' AND ";
1157 + }
1158 +
1159 + }
1160 + elseif(is_array($val))
1161 + {
1162 + $sql_search = '';
1163 + foreach ($val as $v) {
1164 + if(empty($v)) continue;
1165 +
1166 + if(!empty($sql_search))
1167 + $sql_search .= " OR ";
1168 +
1169 + $sql_search .= " ".$col_name." LIKE '%".esc_sql($v)."%' ";
1170 + }
1171 +
1172 + if(!empty($sql_search))
1173 + $gen_q.=" ( ".$sql_search." ) AND ";
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 + }
563 1181 }
564 -
565 1182 }
566 1183
567 1184 $gen_q = substr($gen_q, 0, -5);
568 1185
@@ -568,14 +1185,120 @@
568 1185
569 1186 if(!empty($gen_q))
570 1187 $WMVC->db->where("($gen_q)");
571 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]
572 1215
573 1216 // order
574 - if(isset($_GET_clone['order_by']))
575 - {
576 - $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_listings.post_id', $_GET_clone['order_by']);
577 - $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 +
578 1301 }
579 1302
580 1303 }
581 1304 }
@@ -592,9 +1315,9 @@
592 1315
593 1316 if(isset($custom_parameters['order_by'])) {
594 1317
595 1318 if(isset($_GET_clone['order_by']) && !empty($_GET_clone['order_by'])) {
596 - $_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']);
597 1320 } else {
598 1321 $_GET_clone['order_by'] = $custom_parameters['order_by'];
599 1322 }
600 1323
@@ -608,9 +1331,9 @@
608 1331 $WMVC->model($model_name);
609 1332
610 1333 $smart_search = '';
611 1334 if(isset($_GET_clone['profile_search']))
612 - $smart_search = sanitize_text_field($_GET_clone['profile_search']);
1335 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['profile_search']));
613 1336
614 1337 $available_fields = array('user_login','user_nicename','user_email','user_url','display_name');
615 1338
616 1339 if(isset($_GET_clone['is_activated'])){
@@ -735,13 +1458,182 @@
735 1458 // DATE VALUES
736 1459
737 1460 $gen_search = $val;
738 1461
1462 + if(wdk_is_date($val))
1463 + {
1464 + $gen_search = wdk_normalize_date_db($gen_search);
1465 + $gen_q.=$col_name." > '".$gen_search."' AND ";
1466 + }
1467 + else
1468 + {
1469 + $gen_q.=$col_name." LIKE '%".$gen_search."%' AND ";
1470 + }
1471 + }
1472 + else if(substr_count($key, 'is_') > 0)
1473 + {
1474 + // CHECKBOXES
1475 +
1476 + if($val=='on')
1477 + {
1478 + $gen_search = 1;
1479 + $gen_q.=$col_name." LIKE '%".$gen_search."%' AND ";
1480 + }
1481 + else if($val=='off')
1482 + {
1483 + $gen_q.=$col_name." IS NULL AND ";
1484 + }
1485 + }
1486 + else
1487 + {
1488 + $gen_q.=$col_name." LIKE '%".$val."%' AND ";
1489 + }
1490 + }
1491 +
1492 + }
1493 +
1494 + $gen_q = substr($gen_q, 0, -5);
1495 +
1496 + if(!empty($gen_q))
1497 + $WMVC->db->where("($gen_q)");
1498 + }
1499 +
1500 + // order
1501 + if(isset($_GET_clone['order_by']))
1502 + {
1503 + $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_favorite.post_id', $_GET_clone['order_by']);
1504 + $WMVC->db->order_by(wdk_esc_sql(sanitize_text_field($_GET_clone['order_by'])));
1505 + }
1506 +
1507 + }
1508 +}
1509 +
1510 +function wdk_messages_prepare_search_query_GET($columns = array(), $model_name = NULL, $external_columns = array())
1511 +{
1512 + global $Winter_MVC_WDK;
1513 + $WMVC = &$Winter_MVC_WDK;
1514 + $_GET_clone = array_merge($_GET, $_POST);
1515 +
1516 + $_GET_clone = ($_GET_clone);
1517 +
1518 + //$WMVC->model('listing_m');
1519 +
1520 + $smart_search = '';
1521 + if(isset($_GET_clone['search']))
1522 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['search']));
1523 +
1524 + $available_fields = $WMVC->$model_name->get_available_fields();
1525 +
1526 + /* Пet column names from wdk_package and add to allow search +
1527 + in _GET_clone replace field_#id to field_id_TYPE*/
1528 + $list_fields = $WMVC->db->list_fields( $WMVC->db->prefix.'wdk_messages');
1529 +
1530 +
1531 + //$table_name = substr($model_name, 0, -2);
1532 + $columns_original = array();
1533 + foreach($columns as $key=>$val)
1534 + {
1535 + $columns_original[$val] = $val;
1536 +
1537 + // if column contain also "table_name.*"
1538 + $splited = explode('.', $val);
1539 + if(wmvc_count($splited) == 2)
1540 + $val = $splited[1];
1541 +
1542 + if(isset($available_fields[$val]))
1543 + {
1544 +
1545 + }
1546 + else
1547 + {
1548 + if(!in_array($columns[$key], $external_columns))
1549 + {
1550 + unset($columns[$key]);
1551 + }
1552 + }
1553 + }
1554 +
1555 + if(wmvc_count($_GET_clone) > 0)
1556 + {
1557 + unset($_GET_clone['search']);
1558 +
1559 + // For quick/smart search
1560 + if(wmvc_count($columns) > 0 && !empty($smart_search))
1561 + {
1562 + $gen_q = '';
1563 + foreach($columns as $key=>$value)
1564 + {
1565 + if(substr_count($value, 'id') > 0 && is_numeric($smart_search))
1566 + {
1567 + $gen_q.="$value = $smart_search OR ";
1568 + }
1569 + else if(substr_count($value, 'date') > 0)
1570 + {
1571 + //$gen_search = wmvc_generate_slug($smart_search, ' ');
1572 +
1573 + $gen_search = $smart_search;
1574 +
1575 + $gen_q.="$value LIKE '%$gen_search%' OR ";
1576 + }
1577 + else
1578 + {
1579 + $gen_q.="$value LIKE '%$smart_search%' OR ";
1580 + }
1581 + }
1582 + $gen_q = substr($gen_q, 0, -4);
1583 +
1584 + if(!empty($gen_q))
1585 + $WMVC->db->where("($gen_q)");
1586 + }
1587 +
1588 + // For column search
1589 + if(isset($_GET_clone))
1590 + {
1591 + $gen_q = '';
1592 +
1593 + foreach($_GET_clone as $key=>$val)
1594 + {
1595 + if(!empty($val) && in_array($key, $columns))
1596 + {
1597 + $col_name = $key;
1598 + //if(isset($key))
1599 + // $col_name = $key;
1600 +
1601 + if(strpos($key, 'skip') !== FALSE) continue;
1602 +
1603 + if(substr($key, -8) == '_exactly')
1604 + {
1605 + $col_name = substr($key, 0, -8);
1606 + $gen_q.=$col_name." = '".$val."' AND ";
1607 + }
1608 + elseif(substr($key, -4) == '_max')
1609 + {
1610 + $col_name = substr($key, 0, -4);
1611 + $gen_q.=$col_name." <= '".$val."' AND ";
1612 + }
1613 + else if(substr($key, -4) == '_min')
1614 + {
1615 + $col_name = substr($key, 0, -4);
1616 +
1617 + $gen_q.=$col_name." >= '".$val."' AND ";
1618 + }
1619 + elseif(substr_count($key, 'id') > 0 && is_numeric($val))
1620 + {
1621 + // ID is always numeric
1622 +
1623 + $gen_q.=$col_name." = ".$val." AND ";
1624 + }
1625 + else if(substr_count($key, 'date') > 0)
1626 + {
1627 + // DATE VALUES
1628 +
1629 + $gen_search = $val;
1630 +
739 1631 $detect_date = strtotime($gen_search);
740 1632
741 - if(wdk_is_date($val) && $detect_date > 1000)
1633 + if(wdk_payments_is_date($val) && $detect_date > 1000)
742 1634 {
743 - $gen_search = date('Y-m-d H:i:s', $detect_date);
1635 + $gen_search = gmdate('Y-m-d H:i:s', $detect_date);
744 1636 $gen_q.=$col_name." > '".$gen_search."' AND ";
745 1637 }
746 1638 else
747 1639 {
@@ -778,10 +1670,10 @@
778 1670
779 1671 // order
780 1672 if(isset($_GET_clone['order_by']))
781 1673 {
782 - $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_favorite.post_id', $_GET_clone['order_by']);
783 - $WMVC->db->order_by($_GET_clone['order_by']);
1674 + $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_messages.post_id', $_GET_clone['order_by']);
1675 + $WMVC->db->order_by(wdk_esc_sql(sanitize_text_field($_GET_clone['order_by']), true));
784 1676 }
785 1677
786 1678 }
787 1679 }
@@ -788,16 +1680,22 @@
788 1680
789 1681 function wdk_date() {
790 1682 $date_format = get_option('date_format');
791 1683 $time_format = get_option('time_format');
792 - $date = date("{$date_format} {$time_format}", current_time('timestamp'));
1684 + $date = gmdate("{$date_format} {$time_format}", current_time('timestamp'));
793 1685 return $date;
794 1686 }
795 1687
796 1688 if(!function_exists('wdk_placeholder_image_src')) {
797 1689 function wdk_placeholder_image_src () {
798 - $i = WPDIRECTORYKIT_URL.'/public/img/placeholder.jpg';
1690 + $i = WPDIRECTORYKIT_URL.'public/img/placeholder.jpg';
799 1691
1692 + if(wdk_get_option('wdk_placeholder')) {
1693 + $image = wp_get_attachment_image_src(wdk_get_option('wdk_placeholder'), 'full' );
1694 + if(!empty($image) && file_exists(str_replace(WP_CONTENT_URL, WP_CONTENT_DIR, $image[0])))
1695 + $i = $image[0];
1696 + }
1697 +
800 1698 return $i;
801 1699 }
802 1700 }
803 1701
@@ -808,23 +1706,24 @@
808 1706
809 1707 if(isset($_GET[$page_var]))
810 1708 $current_page = intval(wmvc_xss_clean($_GET[$page_var]));
811 1709
812 - if(!isset($texts['previous_page']))$texts['previous_page'] = 'Previous page';
813 - 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');
814 1712 if(!isset($texts['first_page']))$texts['first_page'] = '';
815 1713 if(!isset($texts['last_page']))$texts['last_page'] = '';
816 - if(!isset($texts['items']))$texts['items'] = 'items';
1714 + if(!isset($texts['items']))$texts['items'] = esc_html__('items', 'wpdirectorykit');
817 1715
818 1716 if(empty($current_page))$current_page = 1;
819 1717
820 1718 // get url
821 - $url = strtok($_SERVER["REQUEST_URI"], '?');
1719 + $url = strtok(wdk_server_current_url(), '?');
1720 +
1721 +
822 1722 $qs_parameters = wmvc_xss_clean( $_GET );
823 1723 unset($qs_parameters[$page_var]);
824 -
825 1724 $qs_part = http_build_query($qs_parameters);
826 - $url.='?'.$qs_part;
1725 + $url = wdk_url_suffix($url, $qs_part);
827 1726
828 1727 // total pages
829 1728 $total_pages = intval($total_items/$per_page+0.99);
830 1729
@@ -839,19 +1738,20 @@
839 1738 $output = '<nav class="wdk-pagination navigation pagination" role="navigation">';
840 1739 if($enable_count){
841 1740 $output.= '<span class="displaying-num">'.$total_items.' '.$texts['items'].'</span>';
842 1741 }
843 -
1742 +
844 1743 $output .= '<div class="nav-links">';
845 1744
846 1745 if($enable_latest_first && $current_page-1 > 0)
847 - $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>';
848 1747
849 1748 if ($current_page-1 > 0) {
850 - $output.= '<a class="next page-numbers" href="'.esc_url($url).'&amp;'.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>';
1749 +
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>';
851 1751 } elseif($enable_compact)
852 1752 {
853 - $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>';
854 1754 }
855 1755
856 1756 if (!$enable_compact) {
857 1757 for ($i = 1 ; $i <= $total_pages; $i++) {
@@ -859,9 +1759,9 @@
859 1759 if(($current_page-$limit_items) <= $i && ($current_page+$limit_items) >= $i) {
860 1760 if (($current_page == $i)) {
861 1761 $output.= '<span aria-current="page" class="page-numbers current">'.$i.'</span>';
862 1762 } else {
863 - $output.= '<a class="page-numbers" href="'.esc_url($url).'&amp;'.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>';
864 1764 }
865 1765 }
866 1766 }
867 1767 } else {
@@ -869,17 +1769,17 @@
869 1769 }
870 1770
871 1771 if($current_page+1 <= $total_pages)
872 1772 {
873 - $output.= '<a class="next page-numbers" href="'.esc_url($url).'&amp;'.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>';
874 1774 }
875 1775 elseif($enable_compact)
876 1776 {
877 - $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>';
878 1778 }
879 1779
880 1780 if($enable_latest_first && $current_page+1 <= $total_pages)
881 - $output.= '<a class="next page-numbers" href="'.esc_url($url).'&amp;'.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>';
882 1782
883 1783
884 1784 $output.= '</div>';
885 1785 $output.= '</nav>';
@@ -903,11 +1803,17 @@
903 1803 global $wdk_activate_more;
904 1804
905 1805 if(!$wdk_enable_search_fields_toggle) return false;
906 1806
1807 + global $wdk_search_fields_toggle_reset;
1808 + if($wdk_search_fields_toggle_reset) {
1809 + $wdk_visible_filters = 0;
1810 + $wdk_search_fields_toggle_reset = false;
1811 + }
1812 +
907 1813 $wdk_visible_filters++;
908 1814
909 - if($wdk_activate_more || (!$wdk_button_search_defined && $wdk_visible_filters == $wdk_visible_filters_limit)){
1815 + if($wdk_activate_more || (!empty($wdk_visible_filters_limit) && !$wdk_button_search_defined && $wdk_visible_filters == $wdk_visible_filters_limit)){
910 1816 $wdk_button_search_defined=true;
911 1817 $wdk_activate_more = false;
912 1818
913 1819 global $wdk_text_search_button;
@@ -913,8 +1819,12 @@
913 1819 global $wdk_text_search_button;
914 1820 if(empty($wdk_text_search_button))
915 1821 $wdk_text_search_button = esc_html__('Search','wpdirectorykit');
916 1822
1823 + global $wdk_text_reset_button;
1824 + if(empty($wdk_text_reset_button))
1825 + $wdk_text_reset_button = esc_html__('Reset','wpdirectorykit');
1826 +
917 1827 global $wdk_text_more_button;
918 1828 if(empty($wdk_text_more_button))
919 1829 $wdk_text_more_button = esc_html__('More','wpdirectorykit');
920 1830
@@ -924,18 +1834,27 @@
924 1834 }
925 1835
926 1836 ?>
927 1837 <div class="wdk-col wdk-col-btns">
928 - <div class="wdk-field wdk-field-btn">
929 - <div class="wdk-field-group">
1838 + <div class="wdk-field wdk-field-btn">
1839 + <div class="wdk-field-group wdk-field-group-additional">
930 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>
931 - <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' />
932 1842 </div>
933 - <div class="wdk-field-group">
934 - <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>
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;?>
1851 + <div class="wdk-field-group wdk-field-group-search">
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 +
935 1854 <?php if(function_exists('run_wdk_save_search') && get_option('wdk_save_search_show_on_searchform')):?>
936 1855 <div class="section-widget-control right">
937 - <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">
938 1857 <i class="fas fa-save" aria-hidden="true"></i>
939 1858 <i class="fa fa-spinner fa-spin fa-ajax-indicator"></i>
940 1859 </a>
941 1860 </div>
@@ -940,8 +1859,9 @@
940 1859 </a>
941 1860 </div>
942 1861 <?php endif;?>
943 1862 </div>
1863 +
944 1864 </div>
945 1865 </div>
946 1866 <div id='wdk-form-additional' class="wdk-col" style="<?php echo esc_attr($form_closed) ;?>">
947 1867 <div class="wdk-row">
@@ -957,9 +1877,9 @@
957 1877 */
958 1878 if ( ! function_exists('wdk_treefield_option'))
959 1879 {
960 1880 function wdk_treefield_option($name = '', $table=NULL, $selected = NULL,
961 - $column = 'category_title', $language_id=NULL, $empty_value='', $filter_ids = '', $user_check = FALSE)
1881 + $column = 'category_title', $language_id=NULL, $empty_value='', $filter_ids = '', $user_check = FALSE, $sql_where='', $hide_fields = '')
962 1882 {
963 1883 $WMVC = &wdk_get_instance();
964 1884
965 1885 if(is_array($filter_ids)) $filter_ids = implode(',', $filter_ids);
@@ -984,9 +1904,9 @@
984 1904
985 1905 if(empty($selected))
986 1906 $selected='';
987 1907
988 - $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/>';
989 1909
990 1910 $skip_id = '';
991 1911 //load javascript library
992 1912 if($counter==0)
@@ -993,23 +1913,134 @@
993 1913 {
994 1914 wp_enqueue_script('wdk-treefield');
995 1915 wp_enqueue_style('wdk-treefield');
996 1916 }
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')) . "',
1922 + ajax_param: {
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: '',
1939 + empty_value: ' - ',
1940 + text_search: '" . esc_html__('Search term', 'wpdirectorykit') . "',
1941 + text_no_results: '" . esc_html__('No results found', 'wpdirectorykit') . "',
1942 + callback_selected: function(key) {
1943 + $('#wdktreeelem" . esc_js($counter) . "').trigger('change');
1944 + }
1945 + }).addClass('init');
1946 + });"
1947 + );
1948 + $counter++;
1949 + return $form;
1950 + }
1951 +}
1952 +
1953 +/*
1954 + * @param $filter_ids string|array, included ids, what will be visible, other skiped, if set 1_fetch_child, where 1 is category_id, will be detected all childs and filtered, for visible
1955 + *
1956 + */
1957 +if ( ! function_exists('wdk_treefield_option_checkboxes'))
1958 +{
1959 + function wdk_treefield_option_checkboxes($name = '', $table=NULL, $selected = NULL,
1960 + $column = 'category_title', $language_id=NULL, $empty_value='', $filter_ids = '', $user_check = FALSE, $sql_where='', $hide_fields = '')
1961 + {
1962 + $WMVC = &wdk_get_instance();
1963 +
1964 + if(is_array($filter_ids)) $filter_ids = implode(',', $filter_ids);
1965 +
1966 + static $counter = 0;
1967 +
1968 + $model_name = $table;
1969 +
1970 + $table_name = str_replace('_m', '', $table);
1971 +
1972 + $attribute_id = 'id'.$table_name;
1973 +
1974 +
1975 + $WMVC->model($model_name);
1976 + $attribute_id = $WMVC ->$model_name->_primary_key;
1977 +
1978 + $values = '';
1979 + if(!empty($selected)){
1980 + $ids = array();
1981 + if(is_string($selected) && strpos($selected, ',') !== FALSE){
1982 + $val_selected = explode(',', $selected);
1983 + } elseif($selected){
1984 + $val_selected = array($selected);
1985 + }
1986 +
1987 + foreach($val_selected as $selected_item) {
1988 + if(!empty($selected_item) && is_intval($selected_item)) {
1989 + $ids [] = $selected_item;
1990 + }
1991 + }
1992 +
1993 + /* where in */
1994 + if(!empty($ids)){
1995 + $WMVC->db->select($WMVC->$table->_table_name.'.*');
1996 + $WMVC->db->where($WMVC->$table->_table_name.'.'.$WMVC->$table->_primary_key.' IN(' . implode(',', $ids) . ')', null, false);
1997 + $WMVC->db->order_by('FIELD('.$WMVC->$table->_table_name.'.'.$WMVC->$table->_primary_key.', '. implode(',', $ids) . ')');
1998 +
1999 + $results = $WMVC->$table->get();
2000 + foreach ($results as $item) {
2001 + if($item) {
2002 + $values .= wmvc_show_data($column, $item, false, TRUE, TRUE).',';
2003 + }
2004 + }
2005 + $values = substr($values,0,-1);
2006 +
2007 + if(strlen($values)>23) {
2008 + $values = substr($values,0,20).'...';
2009 + }
2010 + }
2011 + }
2012 +
2013 + if(empty($values)) {
2014 + $values = $empty_value;
2015 + }
2016 +
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/>';
2018 +
2019 + $skip_id = '';
2020 + //load javascript library
2021 + if($counter==0)
2022 + {
2023 + wp_enqueue_script('wdk-treefield');
2024 + wp_enqueue_style('wdk-treefield');
2025 + }
997 2026 ?>
998 2027 <script>
999 2028 jQuery(document).ready(function($) {
1000 - $('#wdktreeelem<?php echo esc_js($counter);?>:not(.init)').wdkTreefield({
1001 - ajax_url: '<?php echo admin_url('admin-ajax.php'); ?>',
2029 + $('#wdktreeelem_checkbox<?php echo esc_js($counter);?>:not(.init)').wdkTreefieldCheckboxes({
2030 + ajax_url: '<?php echo esc_url(admin_url('admin-ajax.php')); ?>',
1002 2031 ajax_param: {
1003 2032 "page": 'wdk_frontendajax',
1004 - "function": 'treefieldid',
2033 + "function": 'treefieldid_checkboxes',
1005 2034 "action": 'wdk_public_action',
2035 + "wdk_secure": '<?php echo esc_js(wp_create_nonce( 'wdk_secure_treefieldid_checkboxes' ));?>',
1006 2036 "table": '<?php echo esc_js($table); ?>',
1007 2037 "filter_ids": '<?php echo esc_js($filter_ids); ?>',
1008 - "start_id": '<?php if(!empty($filter_ids)) esc_js($selected); else echo ""; ?>',
1009 2038 "empty_value": '<?php echo esc_js($empty_value); ?>',
1010 - "user_check": '<?php echo esc_js($user_check); ?>'
1011 - },
2039 + "user_check": '<?php echo esc_js($user_check); ?>',
2040 + "hide_fields": '<?php echo esc_js($hide_fields); ?>',
2041 + },
2042 + selected: '<?php echo esc_js($selected); ?>',
1012 2043 attribute_id: '<?php echo esc_js($attribute_id); ?>',
1013 2044 language_id: '<?php echo esc_js($language_id); ?>',
1014 2045 attribute_value: '<?php echo esc_js($column); ?>',
1015 2046 skip_id: '<?php echo esc_js($skip_id); ?>',
@@ -1016,9 +2047,9 @@
1016 2047 empty_value: ' - ',
1017 2048 text_search: '<?php esc_html_e('Search term', 'wpdirectorykit');?>',
1018 2049 text_no_results: '<?php esc_html_e('No results found', 'wpdirectorykit');?>',
1019 2050 callback_selected: function(key) {
1020 - $('#wdktreeelem<?php echo esc_js($counter);?>').trigger("change");
2051 + $('#wdktreeelem_checkbox<?php echo esc_js($counter);?>').trigger("change");
1021 2052 }
1022 2053 }).addClass('init');
1023 2054 });
1024 2055 </script>
@@ -1031,11 +2062,19 @@
1031 2062 if ( ! function_exists('wdk_filter_decimal'))
1032 2063 {
1033 2064 function wdk_filter_decimal($string = '')
1034 2065 {
1035 - if(substr($string, -3, 3) === ".00") {
1036 - return substr($string, 0, -3);
1037 - }
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 + }
1038 2077
1039 2078 return $string;
1040 2079 }
1041 2080 }
@@ -1043,18 +2082,142 @@
1043 2082 if ( ! function_exists('wdk_is_date'))
1044 2083 {
1045 2084 function wdk_is_date($date, $format = 'Y-m-d H:i:s')
1046 2085 {
1047 - $d = DateTime::createFromFormat($format, $date);
1048 - return $d && $d->format($format) == $date;
2086 +
2087 + /* check is date on strtotime */
2088 + if((bool)strtotime($date)){
2089 + return true;
2090 + }
2091 +
2092 + /* check is date from argument */
2093 + $d = \DateTime::createFromFormat($format, $date);
2094 + if($d) {
2095 + return true;
2096 + }
2097 +
2098 + /* check is date from wp date and time */
2099 + $d = \DateTime::createFromFormat(get_option('date_format').' '.get_option('time_format'), $date);
2100 + if($d) {
2101 + return true;
2102 + }
2103 +
2104 + /* check is date from wp date */
2105 + $d = \DateTime::createFromFormat(get_option('date_format'), $date);
2106 + if($d) {
2107 + return true;
2108 + }
2109 +
2110 + /* try with default */
2111 + if('Y-m-d H:i:s' != $format) {
2112 + $d = \DateTime::createFromFormat('Y-m-d H:i:s', $date);
2113 + if($d) {
2114 + return true;
2115 + }
2116 +
2117 + $d = \DateTime::createFromFormat('Y-m-d', $date);
2118 + if($d) {
2119 + return true;
2120 + }
2121 + }
2122 +
2123 + /* issue with pm/am inside date, example bug format like "2023 01 19 pm8:06" => 'Y n j ag:i' */
2124 + $format = get_option('date_format').' '.get_option('time_format');
2125 + if(strpos($format, 'a') !== FALSE) {
2126 + $format = str_replace('a', '',$format).' a';
2127 + if(strpos($date, 'am') !== FALSE) {
2128 + $date = str_replace('am', '',$date).' am';
2129 + }
2130 + if(strpos($date, 'pm') !== FALSE) {
2131 + $date = str_replace('pm', '',$date).' pm';
2132 + }
2133 + $d = \DateTime::createFromFormat($format, $date);
2134 + if($d) {
2135 + return true;
2136 + }
2137 + }
2138 +
2139 + return false;
1049 2140 }
1050 2141 }
1051 2142
2143 +
2144 +if ( ! function_exists('wdk_normalize_date_db'))
2145 +{
2146 + /**
2147 + * Convert date to db format, from wp format
2148 + * @param string $date Date in string
2149 + * @param string $format Special format
2150 + * @param string $format Special format
2151 + * @param string $return_format return date format
2152 + * @return string date in format Y-m-d H:i:s
2153 + */
2154 + function wdk_normalize_date_db($date, $format = 'Y-m-d H:i:s', $return_format = 'Y-m-d H:i:s')
2155 + {
2156 +
2157 + /* check is date from argument */
2158 + $d = \DateTime::createFromFormat($format, $date);
2159 + if($d) {
2160 + return $d->format($return_format);
2161 + }
2162 +
2163 + /* check is date from wp date and time */
2164 + $d = \DateTime::createFromFormat(get_option('date_format').' '.get_option('time_format'), $date);
2165 + if($d) {
2166 + return $d->format($return_format);
2167 + }
2168 +
2169 + /* check is date from wp date */
2170 + $d = \DateTime::createFromFormat(get_option('date_format'), $date);
2171 + if($d) {
2172 + return $d->format($return_format);
2173 + }
2174 +
2175 + /* try with default */
2176 + if('Y-m-d H:i:s' != $format) {
2177 + $d = \DateTime::createFromFormat('Y-m-d H:i:s', $date);
2178 + if($d) {
2179 + return $d->format($return_format);
2180 + }
2181 +
2182 + $d = \DateTime::createFromFormat('Y-m-d', $date);
2183 + if($d) {
2184 + return $d->format($return_format);
2185 + }
2186 + }
2187 +
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 + }
2203 +
2204 + /* check is date on strtotime */
2205 + if((bool)strtotime($date)){
2206 + return gmdate($return_format, strtotime($date));
2207 + }
2208 +
2209 + return false;
2210 + }
2211 +}
2212 +
1052 2213 if ( ! function_exists('wdk_url_suffix'))
1053 2214 {
1054 2215 function wdk_url_suffix($base_url, $extension_url="")
1055 - {
1056 - if(strpos($base_url,'?') !== FALSE){
2216 + {
2217 + if(substr($base_url, -1) == '?'){
2218 + $base_url .='';
2219 + } elseif(strpos($base_url,'?') !== FALSE){
1057 2220 $base_url .='&';
1058 2221 } else {
1059 2222 $base_url .='?';
1060 2223 }
@@ -1061,9 +2224,100 @@
1061 2224 return $base_url.$extension_url;
1062 2225 }
1063 2226 }
1064 2227
2228 +
1065 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 +/**
1066 2320 * Insert an attachment from an URL address.
1067 2321 *
1068 2322 * @param String $url
1069 2323 * @param Int $parent_post_id
@@ -1079,9 +2333,23 @@
1079 2333 if( is_wp_error($response) || $response['response']['code'] != 200 ) {
1080 2334 return false;
1081 2335 }
1082 2336
1083 - $upload = wp_upload_bits( basename($url), null, $response['body'] );
2337 + $filename = basename($url);
2338 + if(strpos($filename, '?')!==FALSE) {
2339 + $filename = substr($filename, 0, strpos($filename, '?'));
2340 + }
2341 +
2342 + /* if unsoported extension */
2343 + if(in_array(wdk_file_extension($filename), array('php','asp')) || strlen(wdk_file_extension($filename)) > 5){
2344 + $data = getimagesizefromstring($response['body']);
2345 + if(!$data) return false;
2346 + if(empty($data['mime'])) return false;
2347 +
2348 + $filename = time().wp_rand(0000,9999).'.'.wdk_mime2ext($data['mime']);
2349 + }
2350 + $upload = wp_upload_bits( $filename, null, $response['body'] );
2351 +
1084 2352 if( !empty( $upload['error'] ) ) {
1085 2353 return false;
1086 2354 }
1087 2355
@@ -1097,9 +2365,8 @@
1097 2365 'post_title' => $attachment_title,
1098 2366 'post_content' => '',
1099 2367 'post_status' => 'inherit',
1100 2368 );
1101 -
1102 2369 // Create the attachment
1103 2370 $attach_id = wp_insert_attachment( $post_info, $file_path, $parent_post_id );
1104 2371
1105 2372 // Include image.php
@@ -1171,21 +2438,24 @@
1171 2438 */
1172 2439
1173 2440 function wdk_generate_profile_permalink($profile = array())
1174 2441 {
1175 -
1176 2442 $profile_slug = '';
1177 - if(wmvc_show_data('user_login', $profile, false)){
1178 - $profile_slug = wmvc_show_data('user_login', $profile);
1179 - } else if(is_intval($profile)){
2443 + if(is_intval($profile)){
1180 2444 $profile_data = get_userdata($profile);
1181 - if(wmvc_show_data('user_login', $profile_data, false)){
2445 + if(wmvc_show_data('wdk_slug', $profile_data, false)){
2446 + $profile_slug = wmvc_show_data('wdk_slug', $profile);
2447 + }elseif(wmvc_show_data('user_login', $profile_data, false)){
1182 2448 $profile_slug = wmvc_show_data('user_login', $profile_data);
1183 2449 } else {
1184 2450 $profile_slug = $profile;
1185 2451 }
1186 - }
1187 -
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 +
1188 2458 $user_profile_page = get_option('wdk_membership_profile_preview_page');
1189 2459 if(!$user_profile_page) {
1190 2460 return '#';
1191 2461 }
@@ -1211,9 +2481,23 @@
1211 2481 if (wmvc_show_data('slug', $_GET, false)) {
1212 2482 if(is_intval(wmvc_show_data('slug', $_GET))) {
1213 2483 return wmvc_show_data('slug', $_GET);
1214 2484 } else {
1215 - $profile = get_user_by('login',wmvc_show_data('slug', $_GET));
2485 +
2486 + $args = array(
2487 + 'meta_key' => 'wdk_slug',
2488 + 'meta_value' => sanitize_text_field(wmvc_show_data('slug', $_GET)),
2489 + 'meta_compare' => '='
2490 + );
2491 + $by_slug_user_detected = get_users($args);
2492 +
2493 + $profile = false;
2494 + if(!empty($by_slug_user_detected)) {
2495 + $profile = $by_slug_user_detected[0];
2496 + } else {
2497 + $profile = get_user_by('login',wmvc_show_data('slug', $_GET));
2498 + }
2499 +
1216 2500 return (wmvc_show_data('ID', $profile, false)) ? wmvc_show_data('ID', $profile, false) : false;
1217 2501 }
1218 2502 }
1219 2503 }
@@ -1228,8 +2512,9 @@
1228 2512 *
1229 2513 */
1230 2514 function wdk_get_date($datetime = NULL, $time = TRUE, $default='timestamp')
1231 2515 {
2516 + $init_datetime = $datetime;
1232 2517 if(is_null($datetime))
1233 2518 {
1234 2519 if($default == 'timestamp')
1235 2520 {
@@ -1245,9 +2530,11 @@
1245 2530 $datetime = strtotime($datetime);
1246 2531 }
1247 2532
1248 2533 $date_format = get_option('date_format');
1249 - $time_format = ($time) ? get_option('time_format') : '';
2534 +
2535 + $time_format = ($time && strpos($init_datetime, '00:00:00')===FALSE) ? get_option('time_format') : '';
2536 +
1250 2537 $date = date_i18n("{$date_format} {$time_format}", $datetime);
1251 2538 return $date;
1252 2539 }
1253 2540 }
@@ -1257,17 +2544,23 @@
1257 2544 * Return date in format
1258 2545 * @param string|url redirect url
1259 2546 * @param string custom_message, showed on login form like alert, visible only on wdk login form
1260 2547 */
1261 - function wdk_login_url($url_redirect = NULL, $custom_message = '')
2548 + function wdk_login_url($url_redirect = '', $custom_message = '')
1262 2549 {
1263 2550 $url = wp_login_url($url_redirect);
1264 2551
1265 2552 if(get_option('wdk_membership_login_page')){
1266 - $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 + }
1267 2560 }
1268 2561
1269 - return $url;
2562 + return trim($url, '?');
1270 2563 }
1271 2564 }
1272 2565
1273 2566 if(!function_exists('wdk_mail')) {
@@ -1286,10 +2579,10 @@
1286 2579 if(empty($subject))
1287 2580 $subject = __("New message", "wpdirectorykit");
1288 2581
1289 2582 $headers = array('Content-Type: text/html; charset=UTF-8');
1290 - $headers[] = 'From: '.$email_from;
1291 -
2583 + $headers[] = 'From: "'.get_bloginfo('name').'" <'.$email_from.'>';
2584 +
1292 2585 if(!empty($reply_to)) {
1293 2586 $headers[] = 'Reply-To: '.$reply_to;
1294 2587 } else {
1295 2588 $headers[] = 'Reply-To: '.$email_from;
@@ -1417,19 +2710,19 @@
1417 2710 <!-- Your add & remove file links -->
1418 2711 <p class="hide-if-no-js">
1419 2712 <a class="upload-custom-img <?php if ( $you_have_file ) { echo 'hidden'; } ?>"
1420 2713 href="<?php echo esc_url($upload_link) ?>">
1421 - <?php echo esc_html__('Select file','wmvc_win') ?>
2714 + <?php echo esc_html__('Select file','wpdirectorykit') ?>
1422 2715 </a>
1423 2716 <a class="delete-custom-img <?php if ( ! $you_have_file ) { echo 'hidden'; } ?>"
1424 2717 href="#">
1425 - <?php echo esc_html__('Remove file','wmvc_win') ?>
2718 + <?php echo esc_html__('Remove all files','wpdirectorykit') ?>
1426 2719 </a>
1427 2720 </p>
1428 2721 <?php //endif; ?>
1429 2722
1430 2723 <!-- A hidden input to set and post the chosen file id -->
1431 - <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); ?>" />
1432 2725 </div>
1433 2726
1434 2727 <?php
1435 2728 $custom_js ='';
@@ -1437,8 +2730,9 @@
1437 2730 if( typeof jQuery.fn.wpMediaElementFile == 'function')
1438 2731 $('#".esc_js($field_name)."meta-box-id.postbox-upload').wpMediaElementFile();
1439 2732 });";
1440 2733
2734 +// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.WP.I18n.NonSingularStringLiteralText
1441 2735 echo "<script>".$custom_js."</script>";
1442 2736
1443 2737 ?>
1444 2738
@@ -1444,9 +2738,171 @@
1444 2738
1445 2739 <?php
1446 2740 }
1447 2741
2742 +if ( ! function_exists('wdk_file_extension'))
2743 +{
2744 + function wdk_file_extension($filepath)
2745 + {
2746 +
2747 + /* filters */
2748 + if(strpos($filepath, '?') !== FALSE) {
2749 + $filepath = $filepath;
2750 + $filepath = substr($filepath, 0,strpos($filepath, '?'));
2751 + }
2752 + if(strpos($filepath, '#') !== FALSE) {
2753 + $filepath = $filepath;
2754 + $filepath = substr($filepath, 0,strpos($filepath, '#'));
2755 + }
1448 2756
2757 + return substr($filepath, strrpos($filepath, '.')+1);
2758 + }
2759 +}
2760 +
2761 +if ( ! function_exists('wdk_file_extension_type'))
2762 +{
2763 + /**
2764 + * Get image type based on extension
2765 + *
2766 + * @param string $filepath string path(url) to file with extension
2767 + * @return string type of file (image,video,docs)
2768 + */
2769 + function wdk_file_extension_type($filepath = NULL)
2770 + {
2771 +
2772 + if(in_array(wdk_file_extension($filepath),array('jpg','jpeg','bmp','png','webp'))) {
2773 + return 'image';
2774 + }
2775 + if(in_array(wdk_file_extension($filepath),array('mp4','mov','flv','mkv','avi','webm'))) {
2776 + return 'video';
2777 + }
2778 +
2779 + return 'docs';
2780 + }
2781 +}
2782 +
2783 +function wdk_upload_multi_files($field_name, $image_ids='', $texts = array())
2784 +{
2785 + static $media_element_counter = 0;
2786 +
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');
2789 +
2790 + $media_element_counter++;
2791 +
2792 + $img_field = $field_name.'_'.$media_element_counter;
2793 +
2794 + wp_enqueue_script( 'wpmediamultiple' );
2795 + wp_enqueue_script( 'jquery-ui-mouse' );
2796 + wp_enqueue_media();
2797 +
2798 + ?>
2799 + <div id="<?php echo esc_attr($field_name); ?>meta-box-id" class="postbox-upload-multiple">
2800 + <?php
2801 + // Get WordPress' media upload URL
2802 + $upload_link = '#';
2803 +
2804 +
2805 + // Get the image src
2806 +
2807 + $your_img_src = array();
2808 +
2809 + foreach(explode(',', $image_ids) as $image_id)
2810 + {
2811 + if(is_numeric($image_id)){
2812 + $src = wp_get_attachment_url( $image_id, 'full' );
2813 + if(!in_array(wdk_file_extension($src),array('jpg','jpeg','bmp','png','webp'))) {
2814 + if(file_exists(WPDIRECTORYKIT_PATH.'/public/img/filetype/'.wdk_file_extension($src).'.png')) {
2815 + $src = WPDIRECTORYKIT_URL.'public/img/filetype/'.wdk_file_extension($src).'.png';
2816 + } else {
2817 + $src = WPDIRECTORYKIT_URL.'public/img/filetype/_blank.png';
2818 + }
2819 + }
2820 + $your_img_src[$image_id] = $src;
2821 + }
2822 + }
2823 +
2824 + // For convenience, see if the array is valid
2825 + $you_have_img = count($your_img_src) > 0;
2826 + ?>
2827 +
2828 + <!-- Your image container, which can be manipulated with js -->
2829 + <div class="custom-img-container winter_mvc-media">
2830 + <?php if($you_have_img)foreach($your_img_src as $image_id => $img_src) : ?>
2831 + <div class="winter_mvc-media-card" data-media-id="<?php echo esc_attr($image_id);?>">
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"/>
2833 + <a href="#" class="remove"></a>
2834 + </div>
2835 + <?php endforeach; ?>
2836 + </div>
2837 + <br style="clear:both;" />
2838 +
2839 + <?php //if(sw_user_in_role('administrator')): ?>
2840 + <!-- Your add & remove image links -->
2841 + <p class="hide-if-no-js">
2842 + <a class="button button-primary upload-custom-img <?php if ( $you_have_img ) { echo ''; } ?>"
2843 + href="<?php echo esc_url($upload_link) ?>">
2844 + <?php echo esc_html($texts['file_select']) ?>
2845 + </a>
2846 + <a class="button button-secondary delete-custom-img <?php if ( ! $you_have_img ) { echo 'hidden'; } ?>"
2847 + href="#">
2848 + <?php echo esc_html($texts['file_remove']) ?>
2849 + </a>
2850 + </p>
2851 + <?php //endif; ?>
2852 +
2853 + <!-- A hidden input to set and post the chosen image id -->
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); ?>" />
2855 + </div>
2856 + <?php
2857 + $custom_js ='';
2858 + $custom_js .=" jQuery(function($) {
2859 + if( typeof jQuery.fn.wpMediaMultiple == 'function')
2860 + $('#".esc_js($field_name)."meta-box-id.postbox-upload-multiple').wpMediaMultiple({
2861 + frame: {
2862 + title: '".esc_js(__('Upload and select your images here for use with your listing','wpdirectorykit'))."',
2863 + button: '".esc_js(__('Use this media','wpdirectorykit'))."',
2864 + },
2865 + library: {
2866 + type: ['application', 'image', 'video']
2867 + },
2868 + });
2869 + /* order */
2870 + var re_order = function(media_element){
2871 + var list_media = '';
2872 + media_element.find('.winter_mvc-media-card').each(function(){
2873 + if(list_media !='')
2874 + list_media +=',';
2875 +
2876 + list_media += $(this).attr('data-media-id');
2877 + })
2878 + media_element.closest('.postbox-upload-multiple').find('.logo_image_id').val(list_media);
2879 + }
2880 + /* Sort table */
2881 + $( '.winter_mvc-media' ).sortable({
2882 + update: function(event, ui) {
2883 + re_order($(this));
2884 + }
2885 + });
2886 + /* remove media */
2887 + $( '.winter_mvc-media' ).find('.winter_mvc-media-card .remove').on('click', function(e){
2888 + e.preventDefault();
2889 + var media = $(this).closest('.winter_mvc-media')
2890 + $(this).closest('.winter_mvc-media-card').remove();
2891 + re_order(media)
2892 + })
2893 + });
2894 + ";
2895 +
2896 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.WP.I18n.NonSingularStringLiteralText
2897 + echo "<script>".$custom_js."</script>";
2898 +
2899 + ?>
2900 +
2901 + <?php
2902 +}
2903 +
2904 +
1449 2905 if(!function_exists('wdk_access_check')) {
1450 2906 /**
1451 2907 * Generate listing card html
1452 2908 *
@@ -1460,9 +2916,9 @@
1460 2916 function wdk_access_check($model_name, $item_id, $user_id=NULL, $method='edit') {
1461 2917
1462 2918 if(!empty($item_id) && !is_numeric($item_id))
1463 2919 exit('Issue with ID');
1464 -
2920 +
1465 2921 if (in_array($model_name, array('reviews_m','reviews_type_m','reviews_option_m','reviews_data_m'))) {
1466 2922 global $Winter_MVC_wdk_reviews;
1467 2923 $WMVC = $Winter_MVC_wdk_reviews;
1468 2924 }elseif(in_array($model_name,array('package_m','payment_m'))) {
@@ -1479,8 +2935,11 @@
1479 2935 $WMVC = $Winter_MVC_wdk_bookings;
1480 2936 }elseif(in_array($model_name,array('save_search_m'))) {
1481 2937 global $Winter_MVC_wdk_save_search;
1482 2938 $WMVC = $Winter_MVC_wdk_save_search;
2939 + }elseif(in_array($model_name,array('messageschat_m'))) {
2940 + global $Winter_MVC_wdk_messages_chat;
2941 + $WMVC = $Winter_MVC_wdk_messages_chat;
1483 2942 } else {
1484 2943 $WMVC = &wdk_get_instance();
1485 2944 }
1486 2945
@@ -1486,9 +2945,9 @@
1486 2945
1487 2946 if(empty($user_id))
1488 2947 $user_id = get_current_user_id();
1489 2948
1490 - if(wmvc_user_in_role('administrator')) {
2949 + if(wmvc_user_in_role('administrator') || current_user_can('wdk_listings_manage')) {
1491 2950 return true;
1492 2951 }
1493 2952
1494 2953 if(substr($model_name,-2,2) == '_m')
@@ -1516,8 +2975,59 @@
1516 2975
1517 2976 }
1518 2977 }
1519 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 +
1520 3030 if ( ! function_exists('wdk_recaptcha_field'))
1521 3031 {
1522 3032 function wdk_recaptcha_field($is_compact=false, $style="", $load_script=true)
1523 3033 {
@@ -1527,9 +3037,16 @@
1527 3037 if(get_option('wdk_recaptcha_site_key') !== FALSE && get_option('wdk_recaptcha_secret_key') !== NULL)
1528 3038 {
1529 3039 if($load_script && $counter===0)
1530 3040 {
1531 - 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 +
1532 3049 }
1533 3050 $counter++;
1534 3051
1535 3052 $compact_tag='';
@@ -1541,15 +3058,15 @@
1541 3058 }
1542 3059
1543 3060 $recaptcha_array[$counter] = array('size'=>$size_tag);
1544 3061
1545 - 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>';
1546 3063 ?>
1547 3064
1548 3065 <script>
1549 3066 <?php if($counter===1)echo 'var ';?>CaptchaCallback = function(){
1550 3067 <?php for($j=1;$j<=$counter;$j++): ?>
1551 - 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')); ?>'});
1552 3069 <?php endfor; ?>
1553 3070 };
1554 3071 </script>
1555 3072
@@ -1651,10 +3168,13 @@
1651 3168 if(is_array($val))
1652 3169 {
1653 3170 return wdk_clean($_POST);
1654 3171 }
1655 - else
3172 + elseif(is_string($val))
1656 3173 {
3174 + if(strpos($val, '<iframe') === 0)
3175 + $val = str_replace("'",'"', $val);
3176 +
1657 3177 $post[sanitize_text_field($key)] = wp_kses_post($val);
1658 3178 }
1659 3179 }
1660 3180
@@ -1689,9 +3209,9 @@
1689 3209 if(is_array($val))
1690 3210 {
1691 3211 $arr_cleaned[sanitize_text_field($key)] = wdk_clean($val);
1692 3212 }
1693 - else
3213 + elseif(is_string($val))
1694 3214 {
1695 3215 $arr_cleaned[sanitize_text_field($key)] = wp_kses_post($val);
1696 3216 }
1697 3217
@@ -1701,5 +3221,2232 @@
1701 3221
1702 3222 return $arr_cleaned;
1703 3223 }
1704 3224
1705 -?>
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 +
3251 +/*
3252 +<select class="form-control" name="<?php echo 'control_operator_'.$i_fieldnum; ?>">
3253 + <option value="CONTAINS">CONTAINS</option>
3254 + <option value="NOT_CONTAINS">NOT_CONTAINS</option>
3255 +</select>
3256 +*/
3257 +function wdk_select_multi_option($field_name, $options = array(), $selected = NULL, $extra=NULL, $empty_text = NULL, $empty_val = '')
3258 +{
3259 + $output = '<select name="'.$field_name.'" '.$extra.' multiple="multiple">';
3260 +
3261 + if(!is_null($empty_text))
3262 + $output.= '<option value="'.esc_attr($empty_val).'">'.esc_html($empty_text).'</option>';
3263 +
3264 + if(is_array($options) && count($options) > 0)
3265 + foreach($options as $key=>$val)
3266 + {
3267 + $output.= '<option value="'.$key.'" '.($selected==$key&&$selected != ''?'selected':'').'>'.$val.'</option>';
3268 + }
3269 +
3270 + $output.= '</select>';
3271 +
3272 + return $output;
3273 +}
3274 +
3275 +
3276 +if ( ! function_exists('wdk_treefield_select_ajax'))
3277 +{
3278 + /**
3279 + * Return select2 ajax
3280 + *
3281 + * @param string option Option key
3282 + * @return string alt or title
3283 + */
3284 + function wdk_treefield_select_ajax($name = '', $table=NULL, $selected = NULL,
3285 + $column_print = 'category_title', $column_key = 'idcategory', $language_id=NULL, $empty_value='', $filter_ids = '', $attr = '')
3286 + {
3287 + $WMVC = &wdk_get_instance();
3288 + $WMVC->model($table);
3289 +
3290 + if(is_array($filter_ids)) $filter_ids = implode(',', $filter_ids);
3291 +
3292 + static $counter = 0;
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="">';
3294 +
3295 +
3296 + if(false)
3297 + if( $column_key == 'idcategory') {
3298 + $form .= '<option selected="selected" value="">'.esc_html__('Select Category', 'wpdirectorykit').'</option>';
3299 + } else {
3300 + $form .= '<option selected="selected" value="">'.esc_html__('Select Location', 'wpdirectorykit').'</option>';
3301 + }
3302 +
3303 + if($selected) {
3304 + if(is_array($selected)) {
3305 +
3306 + $ids = array();
3307 + foreach($selected as $selected_item) {
3308 + if(!empty($selected_item)) {
3309 + $ids [] = (int) $selected_item;
3310 + }
3311 + }
3312 +
3313 + /* where in */
3314 + if(!empty($ids)){
3315 + $WMVC->db->select($WMVC->$table->_table_name.'.*');
3316 + $WMVC->db->where($WMVC->$table->_table_name.'.'.$column_key.' IN(' . implode(',', $ids) . ')', null, false);
3317 + $WMVC->db->order_by('FIELD('.$WMVC->$table->_table_name.'.'.$column_key.', '. implode(',', $ids) . ')');
3318 +
3319 + $results = $WMVC->$table->get();
3320 + foreach ($results as $item) {
3321 + if($item)
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>';
3325 + }
3326 + }
3327 + } elseif(is_intval($selected)) {
3328 + $db_item = $WMVC->$table->get($selected, TRUE);
3329 + if($db_item)
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>';
3333 + }
3334 + } else {
3335 + //$form .= '<option value="" selected="selected">'.esc_html__('Not selected', 'wpdirectorykit').'</option>';
3336 + }
3337 + $form .= '</select>';
3338 +
3339 + //load javascript library
3340 + if($counter==0)
3341 + {
3342 + wp_enqueue_script('select2-select2');
3343 + wp_enqueue_script('wdk-select2');
3344 + wp_enqueue_style('select2-select2');
3345 + }
3346 + ?>
3347 + <?php
3348 + $counter++;
3349 + return $form;
3350 + }
3351 +}
3352 +
3353 +if ( ! function_exists('wdk_user_select_ajax'))
3354 +{
3355 + /**
3356 + * Return select2 ajax
3357 + *
3358 + * @param string option Option key
3359 + * @return string alt or title
3360 + */
3361 + function wdk_user_select_ajax($name = '', $selected = NULL, $empty_value='', $filter_ids = '')
3362 + {
3363 + $WMVC = &wdk_get_instance();
3364 +
3365 + if(is_array($filter_ids)) $filter_ids = implode(',', $filter_ids);
3366 +
3367 + static $counter = 0;
3368 + $form = '<select data-ajax="'.admin_url('admin-ajax.php').'" name="'.$name.'" data-placeholder="'.$empty_value.'" class="form-control select_ajax_user" id="wdk_select2_user_'.$counter.'" multiple="">';
3369 + if($selected) {
3370 + if(is_array($selected)) {
3371 + /* where in */
3372 + foreach ($selected as $item) {
3373 + $user_data = get_userdata($item);
3374 + if($user_data)
3375 + $form .= '<option selected="selected" value="'.esc_attr(wmvc_show_data('ID', $user_data, false, TRUE, TRUE)).'">'.esc_html(wmvc_show_data('display_name', $user_data, false, TRUE, TRUE)).'</option>';
3376 + }
3377 + } elseif(is_intval($selected)) {
3378 + $user_data = get_userdata($selected);
3379 + if($user_data)
3380 + $form .= '<option selected="selected" value="'.esc_attr(wmvc_show_data('ID', $user_data, false, TRUE, TRUE)).'">'.esc_html(wmvc_show_data('display_name', $user_data, false, TRUE, TRUE)).'</option>';
3381 + }
3382 + } else {
3383 + //$form .= '<option value="" selected="selected">'.esc_html__('Not selected', 'wpdirectorykit').'</option>';
3384 + }
3385 + $form .= '</select>';
3386 +
3387 + //load javascript library
3388 + if($counter==0)
3389 + {
3390 + wp_enqueue_script('select2-select2');
3391 + wp_enqueue_script('wdk-select2');
3392 + wp_enqueue_style('select2-select2');
3393 + }
3394 + ?>
3395 + <?php
3396 + $counter++;
3397 + return $form;
3398 + }
3399 +}
3400 +
3401 +
3402 +/*
3403 +<select class="form-control" name="<?php echo 'control_operator_'.$i_fieldnum; ?>">
3404 + <option value="CONTAINS">CONTAINS</option>
3405 + <option value="NOT_CONTAINS">NOT_CONTAINS</option>
3406 +</select>
3407 +*/
3408 +function wdk_select_option_multiple($field_name, $options = array(), $selected = array(), $extra=NULL, $empty_text = NULL, $empty_val = '')
3409 +{
3410 + $output = '<select name="'.$field_name.'" '.$extra.' multiple >';
3411 +
3412 + if(!is_null($empty_text))
3413 + $output.= '<option value="'.esc_attr($empty_val).'">'.esc_html($empty_text).'</option>';
3414 +
3415 + if(is_array($options) && count($options) > 0)
3416 + foreach($options as $key=>$val)
3417 + {
3418 + if(is_string($selected)) {
3419 + $output.= '<option value="'.$key.'" '.(($selected == $key)?'selected="selected"':'').'>'.$val.'</option>';
3420 + } else if(is_array($selected)){
3421 + $output.= '<option value="'.$key.'" '.((in_array($key, $selected) === TRUE)?'selected="selected"':'').'>'.$val.'</option>';
3422 + }
3423 + }
3424 +
3425 + $output.= '</select>';
3426 +
3427 + return $output;
3428 +}
3429 +
3430 +
3431 +
3432 +if ( ! function_exists('wdk_convert_date_format_js'))
3433 +{
3434 + /**
3435 + * Convert date format for support in js
3436 + * From: https://wordpress.org/support/article/formatting-date-and-time/
3437 + * To: https://momentjscom.readthedocs.io/en/latest/moment/04-displaying/01-format/
3438 + *
3439 + * @param string php date format Option key
3440 + * @return string js date format
3441 + */
3442 + function wdk_convert_date_format_js($date_format)
3443 + {
3444 + $replaced = array(
3445 + 'D'=>'ddd',
3446 + 'j'=>'D',
3447 + 'd'=>'DD',
3448 + 'l'=>'dddd',
3449 + 'F'=>'MMMM',
3450 + 'Y'=>'YYYY',
3451 + 'S'=>'Do',
3452 + 'm'=>'MM',
3453 + 'n'=>'MM',
3454 + 'F'=>'MMMM',
3455 + 'M'=>'MMM',
3456 + 'Y'=>'YYYY',
3457 + 'y'=>'YY',
3458 + 'a'=>'a',
3459 + 'A'=>'A',
3460 + 'h'=>'hh',
3461 + 'G'=>'H',
3462 + 'H'=>'HH',
3463 + 'g'=>'h',
3464 + 'i'=>'mm',
3465 + 's'=>'ss',
3466 + 'T'=>'zz',
3467 + 'c'=>'',
3468 + 'r'=>'llll',
3469 + 'u'=>'x',
3470 + );
3471 +
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);
3494 + }
3495 +}
3496 +
3497 +if ( ! function_exists('wdk_convert_date_format_jquery'))
3498 +{
3499 + /**
3500 + * Convert date format for support in js
3501 + * From: https://wordpress.org/support/article/formatting-date-and-time/
3502 + * To: https://api.jqueryui.com/datepicker/
3503 + *
3504 + * @param string php date format Option key
3505 + * @return string js date format
3506 + */
3507 + function wdk_convert_date_format_jquery($date_format)
3508 + {
3509 + $replaced = array(
3510 + 'D'=>'D',
3511 + 'd'=>'dd',
3512 + 'j'=>'d',
3513 + 'l'=>'DD',
3514 + 'Y'=>'yy',
3515 + 'S'=>'d',
3516 + 'm'=>'mm',
3517 + 'n'=>'m',
3518 + 'M'=>'m',
3519 + 'F'=>'MM',
3520 + 'y'=>'y',
3521 + 'a'=>'',
3522 + 'A'=>'',
3523 + 'h'=>'',
3524 + 'G'=>'',
3525 + 'H'=>'',
3526 + 'g'=>'',
3527 + 'i'=>'',
3528 + 's'=>'',
3529 + 'T'=>'',
3530 + 'c'=>'ISO_8601',
3531 + 'r'=>'RFC_2822',
3532 + 'u'=>'@',
3533 + ':'=>'',
3534 + );
3535 +
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);
3557 + }
3558 +}
3559 +
3560 +if ( ! function_exists('wdk_convert_date_format_jquery'))
3561 +{
3562 + /**
3563 + * Convert date format for support in js
3564 + * From: https://wordpress.org/support/article/formatting-date-and-time/
3565 + * To: https://api.jqueryui.com/datepicker/
3566 + *
3567 + * @param string php date format Option key
3568 + * @return string js date format
3569 + */
3570 + function wdk_convert_date_format_jquery($date_format)
3571 + {
3572 + $replaced = array(
3573 + 'D'=>'D',
3574 + 'd'=>'dd',
3575 + 'j'=>'d',
3576 + 'l'=>'DD',
3577 + 'Y'=>'yy',
3578 + 'S'=>'d',
3579 + 'm'=>'mm',
3580 + 'n'=>'m',
3581 + 'M'=>'m',
3582 + 'F'=>'MM',
3583 + 'y'=>'y',
3584 + 'a'=>'',
3585 + 'A'=>'',
3586 + 'h'=>'',
3587 + 'G'=>'',
3588 + 'H'=>'',
3589 + 'g'=>'',
3590 + 'i'=>'',
3591 + 's'=>'',
3592 + 'T'=>'',
3593 + 'c'=>'ISO_8601',
3594 + 'r'=>'RFC_2822',
3595 + 'u'=>'@',
3596 + ':'=>'',
3597 + );
3598 +
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 +
3622 + }
3623 +}
3624 +
3625 +if ( ! function_exists('wdk_get_gps'))
3626 +{
3627 +
3628 + /**
3629 + * Get Latitude/Longitude/Altitude based on an address
3630 + * @param string $address The address for converting into coordinates
3631 + * @return array An array containing Latitude/Longitude/Altitude data
3632 + */
3633 + function wdk_get_gps($address = '')
3634 + {
3635 +
3636 + $address_key = 'cached_address_gps';
3637 +
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 +
3646 + $address = str_replace(' ','+',$address);
3647 +
3648 + if(!isset($results[$address])) {
3649 + $results[$address] = NULL;
3650 + $url = 'https://nominatim.openstreetmap.org/search?format=json&q=' . $address;
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);
3660 + $response = '';
3661 +
3662 + // request failed
3663 + if ( is_wp_error( $request ) ) {
3664 + $response = $request;
3665 + }
3666 + $code = (int) wp_remote_retrieve_response_code( $request );
3667 + // make sure the fetch was successful
3668 + if (empty($response) && $code == 200 ) {
3669 + $response = wp_remote_retrieve_body( $request );
3670 + // Decode the json
3671 + $resp = json_decode( $response, true );
3672 +
3673 + if(!empty($resp) && isset($resp[0]) && isset($resp[0]['lat']) && isset($resp[0]['lon'])) {
3674 + $results[$address] = array('lat' => $resp[0]['lat'], 'lng' => $resp[0]['lon'], 'alt' => 0);
3675 +
3676 + return $results[$address];
3677 + }
3678 + }
3679 + } else {
3680 + return $results[$address];
3681 + }
3682 + return false;
3683 + }
3684 +}
3685 +
3686 +if ( ! function_exists('wdk_get_gps_google'))
3687 +{
3688 +
3689 + /**
3690 + * Get Latitude/Longitude/Altitude based on an address from Google Api
3691 + * @param string $address The address for converting into coordinates
3692 + * @param string $api_key Custom google API Key
3693 + *
3694 + * @return array An array containing Latitude/Longitude/Altitude data
3695 + */
3696 + function wdk_get_gps_google($address = '', $api_key = NULL)
3697 + {
3698 + static $results = array();
3699 +
3700 + if ( empty( $api_key ) ) {
3701 + $api_key = wdk_get_option('wdk_geo_google_api_key');
3702 + }
3703 +
3704 + $address = str_replace(' ','+',$address);
3705 +
3706 + if(!isset($results[$address])) {
3707 + $results[$address] = NULL;
3708 + $url = 'https://maps.googleapis.com/maps/api/geocode/json?address='.trim($address).'&key='.$api_key;
3709 + $request = wp_remote_get( $url );
3710 + $response = '';
3711 +
3712 + // request failed
3713 + if ( is_wp_error( $request ) ) {
3714 + $response = $request;
3715 + }
3716 + $code = (int) wp_remote_retrieve_response_code( $request );
3717 +
3718 + // make sure the fetch was successful
3719 + if (empty($response) && $code == 200 ) {
3720 + $response = wp_remote_retrieve_body( $request );
3721 + // Decode the json
3722 + $resp = json_decode( $response, true );
3723 + $status = $resp['status'];
3724 +
3725 + //if request status is successful
3726 + if($status == "OK"){
3727 + //get address from json data
3728 + $lat = $resp['results'][0]['geometry']['location']['lat'];
3729 + $lng = $resp['results'][0]['geometry']['location']['lng'];
3730 +
3731 + $results[$address] = array('lat' => $lat , 'lng' => $lng, 'alt' => 0);
3732 + return $results[$address];
3733 + }
3734 + }
3735 + } else {
3736 + return $results[$address];
3737 + }
3738 +
3739 + return false;
3740 + }
3741 +}
3742 +
3743 +
3744 +if ( ! function_exists('wdk_getDueCoords'))
3745 +{
3746 + // Modified from:
3747 + // http://www.sitepoint.com/forums/showthread.php?656315-adding-distance-gps-coordinates-get-bounding-box
3748 + /**
3749 + * bearing is 0 = north, 180 = south, 90 = east, 270 = west
3750 + *
3751 + */
3752 + function wdk_getDueCoords($latitude, $longitude, $bearing, $distance, $distance_unit = "km", $return_as_array = FALSE) {
3753 +
3754 + if ($distance_unit == "m") {
3755 + // Distance is in miles.
3756 + $radius = 3963.1676;
3757 + }
3758 + else {
3759 + // distance is in km.
3760 + $radius = 6378.1;
3761 + }
3762 +
3763 + // New latitude in degrees.
3764 + $new_latitude = rad2deg(asin(sin(deg2rad($latitude)) * cos($distance / $radius) + cos(deg2rad($latitude)) * sin($distance / $radius) * cos(deg2rad($bearing))));
3765 +
3766 + // New longitude in degrees.
3767 + $new_longitude = rad2deg(deg2rad($longitude) + atan2(sin(deg2rad($bearing)) * sin($distance / $radius) * cos(deg2rad($latitude)), cos($distance / $radius) - sin(deg2rad($latitude)) * sin(deg2rad($new_latitude))));
3768 +
3769 + if ($return_as_array) {
3770 + // Assign new latitude and longitude to an array to be returned to the caller.
3771 + $coord = array();
3772 + $coord['lat'] = $new_latitude;
3773 + $coord['lng'] = $new_longitude;
3774 + }
3775 + else {
3776 + $coord = $new_latitude . ", " . $new_longitude;
3777 + }
3778 +
3779 + return $coord;
3780 +
3781 + }
3782 +}
3783 +
3784 +if ( ! function_exists('wdk_is_gps'))
3785 +{
3786 + // Validation gps
3787 + /**
3788 + * @param string $string_gps gps in string like xx.xxxx,xx.xxxxx
3789 + * @return bool
3790 + */
3791 + function wdk_is_gps($string_gps = '') {
3792 + if(preg_match('/^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$/', $string_gps)) {
3793 + return true;
3794 + }
3795 +
3796 + return false;
3797 + }
3798 +}
3799 +
3800 +
3801 +if ( ! function_exists('wdk_is_phone'))
3802 +{
3803 + // Validation phone
3804 + /**
3805 + * @param string $value phone in string
3806 + * @return bool
3807 + */
3808 + function wdk_is_phone($value = '') {
3809 + if(preg_match("/^[.+]{0,1}[0-9-)(]{0,25}$/", $value)) {
3810 + return true;
3811 + }
3812 +
3813 + return false;
3814 + }
3815 +}
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 +
3841 +if ( ! function_exists('wdk_filter_phone'))
3842 +{
3843 + // Validation phone
3844 + /**
3845 + * @param string $value phone in string
3846 + * @return bool
3847 + */
3848 + function wdk_filter_phone($value = '') {
3849 + return str_replace(array(' ','-','(',')'),'',$value);
3850 + }
3851 +}
3852 +
3853 +
3854 +if ( ! function_exists('wdk_generate_media_field'))
3855 +{
3856 + // Based on value return video embed, youtube, source video tag
3857 + /**
3858 + * @param string $value value
3859 + * @param string $class help css class
3860 + * @return string html or NULL
3861 + */
3862 + function wdk_generate_media_field($value = '', $class="wdk-image") {
3863 + $output = NULL;
3864 +
3865 + if(strpos($value, 'vimeo.com') !== FALSE)
3866 + {
3867 + $output = wp_oembed_get($value, array("width"=>"800", "height"=>"450"));
3868 + $output = str_replace( '<iframe', '<iframe class="'.$class.'" ', $output);
3869 + }
3870 + elseif(strpos($value, 'watch?v=') !== FALSE)
3871 + {
3872 + $embed_code = substr($value, strpos($value, 'watch?v=')+8);
3873 + $output = wp_oembed_get('https://www.youtube.com/watch?v='.$embed_code, array("width"=>"800", "height"=>"455"));
3874 + $output = str_replace( '<iframe', '<iframe class="'.$class.'" ', $output );
3875 + }
3876 + elseif(strpos($value, 'youtu.be/') !== FALSE)
3877 + {
3878 + $embed_code = substr($value, strpos($value, 'youtu.be/')+9);
3879 + $output = wp_oembed_get('https://www.youtube.com/watch?v='.$embed_code, array("width"=>"800", "height"=>"455"));
3880 + $output = str_replace( '<iframe', '<iframe class="'.$class.'" ', $output );
3881 + }
3882 + elseif(strpos($value, 'youtube.com/embed/') !== FALSE)
3883 + {
3884 + $embed_code = substr($value, strpos($value, 'youtube.com/embed/')+18);
3885 + $output = wp_oembed_get('https://www.youtube.com/watch?v='.$embed_code, array("width"=>"800", "height"=>"455"));
3886 + $output = str_replace( '<iframe', '<iframe class="'.$class.'" ', $output );
3887 + }
3888 + elseif(filter_var($value, FILTER_VALIDATE_URL) !== FALSE && preg_match('/\.(mp4|flv|wmw|ogv|webm|ogg)$/i', $value))
3889 + {
3890 + $output = '<video src="'.$value.'" controls class="'.$class.'"></video> ';
3891 + }
3892 +
3893 + return $output;
3894 + }
3895 +}
3896 +
3897 +
3898 +if ( ! function_exists('wdk_depend_get_hidden_fields'))
3899 +{
3900 + // Based on value return video embed, youtube, source video tag
3901 + /**
3902 + * @param int $tree_id tree_id of category
3903 + * @param string $type type, default 'categories'
3904 + * @return string string with hidden fields like ,1,2,3,4, or NULL
3905 + */
3906 + function wdk_depend_get_hidden_fields($tree_id = NULL, $type="categories") {
3907 + static $output = array();
3908 +
3909 + if(isset($output[$tree_id])) {
3910 + return $output[$tree_id];
3911 + }
3912 + if(empty($tree_id)) {
3913 + return NULL;
3914 + } else {
3915 + $output[$tree_id] = false;
3916 +
3917 + global $Winter_MVC_WDK;
3918 + $Winter_MVC_WDK->model('dependfields_m');
3919 +
3920 + $depend_fields = $Winter_MVC_WDK->dependfields_m->get_by(array('field_id' => $tree_id,'main_field' => $type), TRUE);
3921 +
3922 + if($depend_fields && !empty($depend_fields->hidden_fields_list)) {
3923 + $output[$tree_id] = ','.$depend_fields->hidden_fields_list. ',';
3924 + }
3925 + return $output[$tree_id];
3926 + }
3927 +
3928 + return false;
3929 + }
3930 +}
3931 +
3932 +if ( ! function_exists('wdk_depend_is_hidden_field'))
3933 +{
3934 + // Based on value return video embed, youtube, source video tag
3935 + /**
3936 + * @param int $field_id field_id
3937 + * @param int $tree_id id for category
3938 + * @param string $type type, default 'categories'
3939 + * @return string string with hidden fields like ,1,2,3,4, or NULL
3940 + */
3941 + function wdk_depend_is_hidden_field($field_id = NULL, $tree_id = NULL, $type="categories") {
3942 + $hidden_fields = wdk_depend_get_hidden_fields($tree_id, $type);
3943 + if($hidden_fields && strpos($hidden_fields, ','.trim($field_id).',') !== FALSE) {
3944 + return true;
3945 + }
3946 +
3947 + return false;
3948 + }
3949 +}
3950 +
3951 +
3952 +if ( ! function_exists('is_wdk_slug_format'))
3953 +{
3954 + function is_wdk_slug_format($string)
3955 + {
3956 + if(empty($string))return FALSE;
3957 +
3958 +
3959 + if (preg_match("/^[a-z0-9-_]+\$/", $string)) {
3960 +
3961 + return TRUE;
3962 + }
3963 +
3964 + return FALSE;
3965 + }
3966 +}
3967 +
3968 +if ( ! function_exists('wdk_number_format_i18n'))
3969 +{
3970 + function wdk_number_format_i18n($value)
3971 + {
3972 + if(empty($value))return NULL;
3973 +
3974 +
3975 + $value = filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
3976 + $value = (float)str_replace(array(","," ",'&nbsp;'), "", $value);
3977 +
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);
3992 + }
3993 +}
3994 +
3995 +if ( ! function_exists('wdk_currency_symbol'))
3996 +{
3997 + /**
3998 + * Return currency symbol
3999 + *
4000 + * @return string currency symbol
4001 + */
4002 + function wdk_currency_symbol()
4003 + {
4004 +
4005 + if(function_exists('get_woocommerce_currency_symbol'))
4006 + return get_woocommerce_currency_symbol();
4007 +
4008 + if(wdk_get_option('wdk_default_currency_symbol'))
4009 + return wdk_get_option('wdk_default_currency_symbol');
4010 +
4011 + return '$';
4012 + }
4013 +}
4014 +
4015 +if ( ! function_exists('wdk_generate_path_image'))
4016 +{
4017 + /**
4018 + * Generate path of images
4019 + *
4020 + * @param string $id or ids of images, separeted by comma
4021 + * @param bool $multi multi images, separeted by comma
4022 + * @param int $limit limit characters for path
4023 + * @param int $limit limit images for path
4024 + *
4025 + * @return string with path of image or multi images
4026 + */
4027 + function wdk_generate_path_image($ids = NULL, $multi = FALSE, $limit = 95, $limit_images = 10)
4028 + {
4029 + $path = '';
4030 + if(empty($ids))
4031 + return $path;
4032 +
4033 + $image_ids = explode(',', $ids);
4034 + $count_images = 0;
4035 + if(is_array($image_ids)) {
4036 + foreach ($image_ids as $image_id) {
4037 + if(is_numeric($image_id))
4038 + {
4039 +
4040 + if($count_images>=$limit_images)
4041 + break;
4042 +
4043 + $image_path = wp_get_original_image_path($image_id);
4044 + if($image_path) {
4045 + /* path of image */
4046 + $next_path = str_replace(WP_CONTENT_DIR . '/uploads/','', $image_path);
4047 +
4048 + /* check length listing_images_path + next image + comma, should be less then $limit */
4049 + if(strlen($path.$next_path)<$limit) {
4050 +
4051 + if($multi) {
4052 + if(!empty($path))
4053 + $path .= ',';
4054 + }
4055 +
4056 + $path .= $next_path;
4057 + }
4058 +
4059 + if(!$multi)
4060 + break;
4061 +
4062 + $count_images++;
4063 + }
4064 + }
4065 + }
4066 + }
4067 +
4068 + return $path;
4069 + }
4070 +}
4071 +
4072 +if ( ! function_exists('wdk_booking_currency_symbol'))
4073 +{
4074 + /**
4075 + * Return currency symbol
4076 + *
4077 + * @return string currency symbol
4078 + */
4079 + function wdk_booking_currency_symbol()
4080 + {
4081 +
4082 + if(function_exists('get_woocommerce_currency_symbol'))
4083 + return get_woocommerce_currency_symbol();
4084 +
4085 + if(wdk_get_option('wdk_default_currency_symbol'))
4086 + return wdk_get_option('wdk_default_currency_symbol');
4087 +
4088 + return '$';
4089 + }
4090 +}
4091 +
4092 +if ( ! function_exists('wdk_generated_cached_row_userdata'))
4093 +{
4094 + /**
4095 + * Return currency symbol
4096 + *
4097 + * @return string currency symbol
4098 + */
4099 + function wdk_generated_cached_row_userdata($row)
4100 + {
4101 + $user_data = array();
4102 +
4103 + $user_data['display_name'] = wmvc_show_data('cacheduser_display_name', $row);
4104 + $user_data['user_email'] = wmvc_show_data('cacheduser_email', $row);
4105 + $user_data['profile_url'] = wmvc_show_data('cacheduser_profile_url', $row);
4106 + $user_data['avatar_url'] = wmvc_show_data('cacheduser_avatar_url', $row);
4107 +
4108 + /* meta */
4109 + $user_data['wdk_address'] = wmvc_show_data('cacheduser_wdk_address', $row);
4110 + $user_data['wdk_phone'] = wmvc_show_data('cacheduser_wdk_phone', $row);
4111 + $user_data['wdk_city'] = wmvc_show_data('cacheduser_wdk_city', $row);
4112 + $user_data['wdk_company_name'] = wmvc_show_data('cacheduser_wdk_company_name', $row);
4113 + $user_data['wdk_facebook'] = wmvc_show_data('cacheduser_wdk_facebook', $row);
4114 + $user_data['wdk_youtube'] = wmvc_show_data('cacheduser_wdk_youtube', $row);
4115 + $user_data['wdk_linkedin'] = wmvc_show_data('cacheduser_wdk_linkedin', $row);
4116 + $user_data['wdk_twitter'] = wmvc_show_data('cacheduser_wdk_twitter', $row);
4117 + $user_data['wdk_instagram'] = wmvc_show_data('cacheduser_wdk_instagram', $row);
4118 + $user_data['wdk_whatsapp'] = wmvc_show_data('cacheduser_wdk_whatsapp', $row);
4119 + $user_data['wdk_viber'] = wmvc_show_data('cacheduser_wdk_viber', $row);
4120 + $user_data['wdk_iban'] = wmvc_show_data('cacheduser_wdk_iban', $row);
4121 + $user_data['wdk_telegram'] = wmvc_show_data('cacheduser_wdk_telegram', $row);
4122 + $user_data['wdk_position_title'] = wmvc_show_data('cacheduser_wdk_position_title', $row);
4123 + $user_data['agency_name'] = wmvc_show_data('cacheduser_agency_name', $row);
4124 + $user_data['description'] = wmvc_show_data('cacheduser_description', $row);
4125 + $user_data['user_url'] = wmvc_show_data('cacheduser_user_url', $row);
4126 + $user_data['roles'] = explode(',', wmvc_show_data('cacheduser_roles', $row));
4127 + $user_data['wdk_slug'] = wmvc_show_data('cacheduser_wdk_slug', $row);
4128 + $user_data['user_login'] = wmvc_show_data('cacheduser_user_login', $row);
4129 + $user_data['user_id'] = wmvc_show_data('cacheduser_user_id', $row);
4130 +
4131 + if(function_exists('wdk_generate_profile_permalink') && $user_data['profile_url'] == '#') {
4132 + if($user_data['user_login']) {
4133 + $user_data['profile_url'] = wdk_generate_profile_permalink($user_data);
4134 + } else {
4135 + $user_data['profile_url'] = wdk_generate_profile_permalink(wmvc_show_data('user_id', $user_data));
4136 + }
4137 + }
4138 +
4139 + return $user_data;
4140 + }
4141 +}
4142 +
4143 +if ( ! function_exists('wdk_mime2extd'))
4144 +{
4145 + /**
4146 + * Return currency symbol
4147 + *
4148 + * @return string currency symbol
4149 + */
4150 + function wdk_mime2ext($mime) {
4151 + $mime_map = [
4152 + 'video/3gpp2' => '3g2',
4153 + 'video/3gp' => '3gp',
4154 + 'video/3gpp' => '3gp',
4155 + 'application/x-compressed' => '7zip',
4156 + 'audio/x-acc' => 'aac',
4157 + 'audio/ac3' => 'ac3',
4158 + 'application/postscript' => 'ai',
4159 + 'audio/x-aiff' => 'aif',
4160 + 'audio/aiff' => 'aif',
4161 + 'audio/x-au' => 'au',
4162 + 'video/x-msvideo' => 'avi',
4163 + 'video/msvideo' => 'avi',
4164 + 'video/avi' => 'avi',
4165 + 'application/x-troff-msvideo' => 'avi',
4166 + 'application/macbinary' => 'bin',
4167 + 'application/mac-binary' => 'bin',
4168 + 'application/x-binary' => 'bin',
4169 + 'application/x-macbinary' => 'bin',
4170 + 'image/bmp' => 'bmp',
4171 + 'image/x-bmp' => 'bmp',
4172 + 'image/x-bitmap' => 'bmp',
4173 + 'image/x-xbitmap' => 'bmp',
4174 + 'image/x-win-bitmap' => 'bmp',
4175 + 'image/x-windows-bmp' => 'bmp',
4176 + 'image/ms-bmp' => 'bmp',
4177 + 'image/x-ms-bmp' => 'bmp',
4178 + 'application/bmp' => 'bmp',
4179 + 'application/x-bmp' => 'bmp',
4180 + 'application/x-win-bitmap' => 'bmp',
4181 + 'application/cdr' => 'cdr',
4182 + 'application/coreldraw' => 'cdr',
4183 + 'application/x-cdr' => 'cdr',
4184 + 'application/x-coreldraw' => 'cdr',
4185 + 'image/cdr' => 'cdr',
4186 + 'image/x-cdr' => 'cdr',
4187 + 'zz-application/zz-winassoc-cdr' => 'cdr',
4188 + 'application/mac-compactpro' => 'cpt',
4189 + 'application/pkix-crl' => 'crl',
4190 + 'application/pkcs-crl' => 'crl',
4191 + 'application/x-x509-ca-cert' => 'crt',
4192 + 'application/pkix-cert' => 'crt',
4193 + 'text/css' => 'css',
4194 + 'text/x-comma-separated-values' => 'csv',
4195 + 'text/comma-separated-values' => 'csv',
4196 + 'application/vnd.msexcel' => 'csv',
4197 + 'application/x-director' => 'dcr',
4198 + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
4199 + 'application/x-dvi' => 'dvi',
4200 + 'message/rfc822' => 'eml',
4201 + 'application/x-msdownload' => 'exe',
4202 + 'video/x-f4v' => 'f4v',
4203 + 'audio/x-flac' => 'flac',
4204 + 'video/x-flv' => 'flv',
4205 + 'image/gif' => 'gif',
4206 + 'application/gpg-keys' => 'gpg',
4207 + 'application/x-gtar' => 'gtar',
4208 + 'application/x-gzip' => 'gzip',
4209 + 'application/mac-binhex40' => 'hqx',
4210 + 'application/mac-binhex' => 'hqx',
4211 + 'application/x-binhex40' => 'hqx',
4212 + 'application/x-mac-binhex40' => 'hqx',
4213 + 'text/html' => 'html',
4214 + 'image/x-icon' => 'ico',
4215 + 'image/x-ico' => 'ico',
4216 + 'image/vnd.microsoft.icon' => 'ico',
4217 + 'text/calendar' => 'ics',
4218 + 'application/java-archive' => 'jar',
4219 + 'application/x-java-application' => 'jar',
4220 + 'application/x-jar' => 'jar',
4221 + 'image/jp2' => 'jp2',
4222 + 'video/mj2' => 'jp2',
4223 + 'image/jpx' => 'jp2',
4224 + 'image/jpm' => 'jp2',
4225 + 'image/jpeg' => 'jpeg',
4226 + 'image/pjpeg' => 'jpeg',
4227 + 'application/x-javascript' => 'js',
4228 + 'application/json' => 'json',
4229 + 'text/json' => 'json',
4230 + 'application/vnd.google-earth.kml+xml' => 'kml',
4231 + 'application/vnd.google-earth.kmz' => 'kmz',
4232 + 'text/x-log' => 'log',
4233 + 'audio/x-m4a' => 'm4a',
4234 + 'application/vnd.mpegurl' => 'm4u',
4235 + 'audio/midi' => 'mid',
4236 + 'application/vnd.mif' => 'mif',
4237 + 'video/quicktime' => 'mov',
4238 + 'video/x-sgi-movie' => 'movie',
4239 + 'audio/mpeg' => 'mp3',
4240 + 'audio/mpg' => 'mp3',
4241 + 'audio/mpeg3' => 'mp3',
4242 + 'audio/mp3' => 'mp3',
4243 + 'video/mp4' => 'mp4',
4244 + 'video/mpeg' => 'mpeg',
4245 + 'application/oda' => 'oda',
4246 + 'application/vnd.oasis.opendocument.text' => 'odt',
4247 + 'application/vnd.oasis.opendocument.spreadsheet' => 'ods',
4248 + 'application/vnd.oasis.opendocument.presentation' => 'odp',
4249 + 'audio/ogg' => 'ogg',
4250 + 'video/ogg' => 'ogg',
4251 + 'application/ogg' => 'ogg',
4252 + 'application/x-pkcs10' => 'p10',
4253 + 'application/pkcs10' => 'p10',
4254 + 'application/x-pkcs12' => 'p12',
4255 + 'application/x-pkcs7-signature' => 'p7a',
4256 + 'application/pkcs7-mime' => 'p7c',
4257 + 'application/x-pkcs7-mime' => 'p7c',
4258 + 'application/x-pkcs7-certreqresp' => 'p7r',
4259 + 'application/pkcs7-signature' => 'p7s',
4260 + 'application/pdf' => 'pdf',
4261 + 'application/octet-stream' => 'pdf',
4262 + 'application/x-x509-user-cert' => 'pem',
4263 + 'application/x-pem-file' => 'pem',
4264 + 'application/pgp' => 'pgp',
4265 + 'application/x-httpd-php' => 'php',
4266 + 'application/php' => 'php',
4267 + 'application/x-php' => 'php',
4268 + 'text/php' => 'php',
4269 + 'text/x-php' => 'php',
4270 + 'application/x-httpd-php-source' => 'php',
4271 + 'image/png' => 'png',
4272 + 'image/x-png' => 'png',
4273 + 'application/powerpoint' => 'ppt',
4274 + 'application/vnd.ms-powerpoint' => 'ppt',
4275 + 'application/vnd.ms-office' => 'ppt',
4276 + 'application/msword' => 'doc',
4277 + 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
4278 + 'application/x-photoshop' => 'psd',
4279 + 'image/vnd.adobe.photoshop' => 'psd',
4280 + 'audio/x-realaudio' => 'ra',
4281 + 'audio/x-pn-realaudio' => 'ram',
4282 + 'application/x-rar' => 'rar',
4283 + 'application/rar' => 'rar',
4284 + 'application/x-rar-compressed' => 'rar',
4285 + 'audio/x-pn-realaudio-plugin' => 'rpm',
4286 + 'application/x-pkcs7' => 'rsa',
4287 + 'text/rtf' => 'rtf',
4288 + 'text/richtext' => 'rtx',
4289 + 'video/vnd.rn-realvideo' => 'rv',
4290 + 'application/x-stuffit' => 'sit',
4291 + 'application/smil' => 'smil',
4292 + 'text/srt' => 'srt',
4293 + 'image/svg+xml' => 'svg',
4294 + 'application/x-shockwave-flash' => 'swf',
4295 + 'application/x-tar' => 'tar',
4296 + 'application/x-gzip-compressed' => 'tgz',
4297 + 'image/tiff' => 'tiff',
4298 + 'text/plain' => 'txt',
4299 + 'text/x-vcard' => 'vcf',
4300 + 'application/videolan' => 'vlc',
4301 + 'text/vtt' => 'vtt',
4302 + 'audio/x-wav' => 'wav',
4303 + 'audio/wave' => 'wav',
4304 + 'audio/wav' => 'wav',
4305 + 'application/wbxml' => 'wbxml',
4306 + 'video/webm' => 'webm',
4307 + 'audio/x-ms-wma' => 'wma',
4308 + 'application/wmlc' => 'wmlc',
4309 + 'video/x-ms-wmv' => 'wmv',
4310 + 'video/x-ms-asf' => 'wmv',
4311 + 'application/xhtml+xml' => 'xhtml',
4312 + 'application/excel' => 'xl',
4313 + 'application/msexcel' => 'xls',
4314 + 'application/x-msexcel' => 'xls',
4315 + 'application/x-ms-excel' => 'xls',
4316 + 'application/x-excel' => 'xls',
4317 + 'application/x-dos_ms_excel' => 'xls',
4318 + 'application/xls' => 'xls',
4319 + 'application/x-xls' => 'xls',
4320 + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
4321 + 'application/vnd.ms-excel' => 'xlsx',
4322 + 'application/xml' => 'xml',
4323 + 'text/xml' => 'xml',
4324 + 'text/xsl' => 'xsl',
4325 + 'application/xspf+xml' => 'xspf',
4326 + 'application/x-compress' => 'z',
4327 + 'application/x-zip' => 'zip',
4328 + 'application/zip' => 'zip',
4329 + 'application/x-zip-compressed' => 'zip',
4330 + 'application/s-compressed' => 'zip',
4331 + 'multipart/x-zip' => 'zip',
4332 + 'text/x-scriptzsh' => 'zsh',
4333 + ];
4334 +
4335 + return isset($mime_map[$mime]) === true ? $mime_map[$mime] : false;
4336 + }
4337 +}
4338 +
4339 +if ( ! function_exists('wdk_is_dash_enabled'))
4340 +{
4341 + /**
4342 + * IS Dash pages exists
4343 + *
4344 + * @return bool true if exists dash
4345 + */
4346 + function wdk_is_dash_enabled() {
4347 + if(function_exists('run_wdk_membership') && wdk_get_option('wdk_membership_dash_page') && get_post_status(wdk_get_option('wdk_membership_dash_page')) =='publish'){
4348 + return true;
4349 + }
4350 +
4351 + return false;
4352 + }
4353 +}
4354 +
4355 +if(!function_exists('wdk_page_by_title')) {
4356 + function wdk_page_by_title ( $page_title, $output = OBJECT, $post_type = 'page' ) {
4357 + global $wpdb;
4358 +
4359 + if ( is_array( $post_type ) ) {
4360 + $post_type = esc_sql( $post_type );
4361 + $post_type_in_string = "'" . implode( "','", $post_type ) . "'";
4362 + $sql = $wpdb->prepare(
4363 + "
4364 + SELECT ID
4365 + FROM $wpdb->posts
4366 + WHERE post_title = %s
4367 + AND post_type IN ($post_type_in_string)
4368 + ",
4369 + $page_title
4370 + );
4371 + } else {
4372 + $sql = $wpdb->prepare(
4373 + "
4374 + SELECT ID
4375 + FROM $wpdb->posts
4376 + WHERE post_title = %s
4377 + AND post_type = %s
4378 + ",
4379 + $page_title,
4380 + $post_type
4381 + );
4382 + }
4383 + $page = $wpdb->get_var( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
4384 +
4385 +
4386 + if ( $page ) {
4387 + return get_post( $page, $output );
4388 + }
4389 +
4390 + return null;
4391 + }
4392 +}
4393 +
4394 +
4395 +if ( ! function_exists('is_wdk_gps_single'))
4396 +{
4397 + function is_wdk_gps_single($param)
4398 + {
4399 +
4400 + if (is_numeric($param) && $param > -180 && $param < 180) {
4401 + return true;
4402 + }
4403 +
4404 + return false;
4405 + }
4406 +}
4407 +
4408 +if ( ! function_exists('wdk_get_tgmpa_link'))
4409 +{
4410 + function wdk_get_tgmpa_link()
4411 + {
4412 + if(file_exists(get_template_directory().'/includes/tgm_pa/class-tgm-plugin-activation.php') || file_exists(get_template_directory().'/tgm_pa/class-tgm-plugin-activation.php')) {
4413 + return get_admin_url() . "themes.php?page=tgmpa-install-plugins";
4414 + } else {
4415 + return get_admin_url() . "plugins.php?page=tgmpa-install-plugins";
4416 + }
4417 +
4418 + return false;
4419 + }
4420 +}
4421 +
4422 +if ( ! function_exists('wdk_sprintf'))
4423 +{
4424 + function wdk_sprintf($string = '')
4425 + {
4426 + $arg_list = func_get_args();
4427 +
4428 + if(count($arg_list)<2) {
4429 + return $string;
4430 + }
4431 +
4432 + if(stripos($string, '%1$s') === FALSE) {
4433 + return $string;
4434 + }
4435 +
4436 + return call_user_func_array("sprintf", $arg_list);
4437 + }
4438 +}
4439 +
4440 +if ( ! function_exists('wdk_db_table'))
4441 +{
4442 + function wdk_db_table($data, $columns = array()) {
4443 + $output = '<table>';
4444 + foreach($data as $key => $var) {
4445 + if($key === 0)
4446 + {
4447 + $output .= '<tr>';
4448 + foreach($var as $k => $v) {
4449 + if(count($columns) > 0 && !in_array($k, $columns))continue;
4450 +
4451 + $output .= '<td><strong>' . esc_html($k) . '</strong></td>';
4452 + }
4453 + $output .= '</tr>';
4454 + }
4455 +
4456 + $output .= '<tr>';
4457 + foreach($var as $k => $v) {
4458 + if(count($columns) > 0 && !in_array($k, $columns))continue;
4459 +
4460 + $output .= '<td>' . esc_html($v) . '</td>';
4461 + }
4462 + $output .= '</tr>';
4463 + }
4464 + $output .= '</table>';
4465 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPress.WP.I18n.NonSingularStringLiteralText
4466 + echo $output;
4467 + }
4468 +}
4469 +
4470 +if ( ! function_exists('wdk_move_gps'))
4471 +{
4472 + function wdk_move_gps($value) {
4473 + return $value+0.001 * wp_rand(1, 9);
4474 + }
4475 +}
4476 +
4477 +if ( ! function_exists('wdk_get_near_location'))
4478 +{
4479 + function wdk_get_near_location($latitude, $longitude, $radius = 10000) {
4480 + // Convert radius from meters to degrees
4481 + $radiusInDegrees = $radius / 111000;
4482 +
4483 + $u = wp_rand() / mt_getrandmax();
4484 + $v = wp_rand() / mt_getrandmax();
4485 + $w = $radiusInDegrees * sqrt($u);
4486 + $t = 2 * M_PI * $v;
4487 + $x = $w * cos($t);
4488 + $y = $w * sin($t);
4489 +
4490 + // Adjust the x-coordinate for the shrinking of the east-west distances
4491 + $newX = $x / cos(deg2rad($latitude));
4492 +
4493 + $newLongitude = $longitude + $newX;
4494 + $newLatitude = $latitude + $y;
4495 +
4496 + return array('lat' => $newLatitude, 'lng' => $newLongitude);
4497 + }
4498 +}
4499 +
4500 +if ( ! function_exists('wdk_is_listing_preview_page'))
4501 +{
4502 + function wdk_is_listing_preview_page() {
4503 + global $wdk_listing_id;
4504 +
4505 + if(!empty($wdk_listing_id))
4506 + return TRUE;
4507 +
4508 + return FALSE;
4509 + }
4510 +}
4511 +
4512 +if ( ! function_exists('wdk_is_listing_field_exists'))
4513 +{
4514 + function wdk_is_listing_field_exists($field_name = '', $udpate_cache = FALSE) {
4515 + static $available_fields_listings = array();
4516 + $custom_fields = array();
4517 +
4518 + $WMVC = &wdk_get_instance();
4519 + $WMVC->model('listingfield_m');
4520 +
4521 + if(empty($available_fields_listings) || $udpate_cache) {
4522 + $available_fields_listings = $WMVC->listingfield_m->get_available_fields();
4523 + }
4524 +
4525 + if(isset($available_fields_listings[$field_name]) || isset($custom_fields[$field_name])) {
4526 + return TRUE;
4527 + }
4528 +
4529 + return FALSE;
4530 + }
4531 +}
4532 +
4533 +if ( ! function_exists('wdk_cached_field_get'))
4534 +{
4535 + function wdk_cached_field_get($udpate_cache = FALSE) {
4536 + static $fields = NULL;
4537 +
4538 + $WMVC = &wdk_get_instance();
4539 + $WMVC->model('field_m');
4540 +
4541 + if(is_null($fields) || $udpate_cache) {
4542 + $fields = $WMVC->field_m->get();
4543 + }
4544 +
4545 + return $fields;
4546 + }
4547 +}
4548 +
4549 +if (! function_exists('wdk_generate_slug'))
4550 +{
4551 + function wdk_generate_slug($str, $separator = 'dash', $lowercase = TRUE)
4552 + {
4553 + if ($separator == 'dash')
4554 + {
4555 + $search = '_';
4556 + $replace = '-';
4557 + }
4558 + else
4559 + {
4560 + $search = '-';
4561 + $replace = '_';
4562 + }
4563 +
4564 + $dot='';
4565 + if($separator == 'dot'){
4566 + $str = str_replace(' ', '.', $str);
4567 + $dot='.';
4568 + }
4569 +
4570 + $trans = array(
4571 + $search => $replace,
4572 + "\s+" => $replace,
4573 + "[^a-z0-9".$replace.$dot."]" => '',
4574 + $replace."+" => $replace,
4575 + $replace."$" => '',
4576 + "^".$replace => ''
4577 + );
4578 +
4579 + // For Croatia
4580 + $str = str_replace(array('č','ć','ž','š','đ', 'Č','Ć','Ž','Š','Đ'),
4581 + array('c','c','z','s','d', 'c','c','z','s','d'), $str);
4582 +
4583 + // For Turkish
4584 + $str = str_replace(array('ş','Ş','ı','İ','ğ','Ğ','Ü','ü','Ö','ö','ç','Ç'),
4585 + array('s','s','i','i','g','g','u','u','o','o','c','c'), $str);
4586 +
4587 + // Russian alphabet
4588 + $str = str_replace(array('А','Б','В','Г','Д','Е','Ё','Ж','З','И','Й','К','Л','М','Н','О','П','Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я'),
4589 + array('a','b','v','g','d','e','e','zh','z','i','y','k','l','m','n','o','p','r','s','t','u','f','kh','c','ch','sh','sh','','y','','e','yu','ya'), $str);
4590 + $str = str_replace(array('а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п','р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я'),
4591 + array('a','b','v','g','d','e','e','zh','z','i','y','k','l','m','n','o','p','r','s','t','u','f','kh','c','ch','sh','sh','','y','','e','yu','ya'), $str);
4592 +
4593 + // Ukrainian alphabet
4594 + $str = str_replace(array('Ґ','Є','І','Ї'),
4595 + array('G','E','I','I'), $str);
4596 + $str = str_replace(array('ґ','є','і','ї'),
4597 + array('g','e','i','i'), $str);
4598 + // Symbols
4599 + $str = str_replace(array("  ","’","–",'«','»','№','„','”'),
4600 + array("","","-",'','','no','',''), $str);
4601 +
4602 + // Alphabets Czech Croatian Turkish and other
4603 + $str = str_replace(array('Á','Ä','Ď','É','Ě','Ë','Í','Ň','Ń','Ó','Ŕ','Ř','Ť','Ú','Ů','Ý','Ź','Č','Ć','Ž','Š','Đ','Ş','İ','Ğ','Ü','Ö','Ç'),
4604 + array('a','a','d','e','e','e','i','n','n','o','r','r','t','u','u','y','z','c','c','z','s','d','s','i','g','u','o','c'), $str);
4605 + $str = str_replace(array('á','ä','ď','é','ě','ë','í','ň','ń','ó','ŕ','ř','ť','ú','ů','ý','ź','č','ć','ž','š','đ','ş','ı','ğ','ü','ö','ç'),
4606 + array('a','a','d','e','e','e','i','n','n','o','r','r','t','u','u','y','z','c','c','z','s','d','s','i','g','u','o','c'), $str);
4607 +
4608 + // For french
4609 + $str = str_replace(array('â','é','è','û','ê', 'à','Â','ç','ï','î','ä','î'),
4610 + array('a','e','e','u','e', 'a','c','c','i','î','a','î'), $str);
4611 +
4612 + $str = wp_strip_all_tags(strtolower($str));
4613 +
4614 +
4615 + foreach ($trans as $key => $val)
4616 + {
4617 + $str = preg_replace("#".$key."#", $val, $str);
4618 + }
4619 +
4620 + return trim(stripslashes($str));
4621 + }
4622 +}
4623 +
4624 +
4625 +if (! function_exists('wdk_is_gps'))
4626 +{
4627 + function wdk_is_gps($gps = '')
4628 + {
4629 +
4630 + if(stripos($gps,',') === FALSE) {
4631 + return FALSE;
4632 + }
4633 +
4634 + $gps_coor = explode(',', $gps);
4635 +
4636 + if(count($gps_coor) != 2)
4637 + {
4638 + return FALSE;
4639 + }
4640 +
4641 + if(!is_numeric($gps_coor[0]) || !is_numeric($gps_coor[1]))
4642 + {
4643 + return FALSE;
4644 + }
4645 +
4646 + if($gps_coor[0] < -90 || $gps_coor[0] > 90 || $gps_coor[1] < -180 || $gps_coor[1] > 180)
4647 + {
4648 + return FALSE;
4649 + }
4650 +
4651 + return TRUE;
4652 + }
4653 +}
4654 +
4655 +if ( ! function_exists('is_wdk_is_useremail_exists'))
4656 +{
4657 + function is_wdk_is_useremail_exists($param)
4658 + {
4659 +
4660 + if(null == username_exists( $param ) && !email_exists($param)) {
4661 + return true;
4662 + }
4663 +
4664 + return false;
4665 + }
4666 +}
4667 +
4668 +
4669 +/*
4670 + Validation is natural integer
4671 +*/
4672 +if ( ! function_exists('is_wdk_is_natural'))
4673 +{
4674 + function is_wdk_is_natural($param)
4675 + {
4676 +
4677 + if (is_intval($param) && stripos($param, '.') === FALSE && stripos($param, ',') === FALSE) {
4678 + return true;
4679 + }
4680 +
4681 + return false;
4682 + }
4683 +}
4684 +
4685 +
4686 +/**
4687 + * Check is listing preview page exits
4688 + *
4689 + * @return bool
4690 +*/
4691 +if ( ! function_exists('wdk_is_listing_page_enabled'))
4692 +{
4693 + function wdk_is_listing_page_enabled ()
4694 + {
4695 +
4696 + if(get_option('wdk_listing_page') && get_post_status(get_option('wdk_listing_page')) =='publish') {
4697 + return true;
4698 + }
4699 +
4700 + return false;
4701 + }
4702 +}
4703 +
4704 +
4705 +/**
4706 + * Check is listing preview page exits
4707 + *
4708 + * @return bool
4709 +*/
4710 +if ( ! function_exists('replace_smart_data'))
4711 +{
4712 + function replace_smart_data($output = '', $replace_data = array()) {
4713 + // Match all occurrences of the pattern
4714 + if (preg_match_all('/\{([^}]+)\}/', $output, $matches)) {
4715 + foreach ($matches[1] as $key => $value) {
4716 + foreach ($replace_data as $replace_key => $replace_value) {
4717 + $output = str_replace('{'.$replace_key.'}', $replace_value, $output);
4718 + }
4719 + }
4720 + }
4721 + return $output;
4722 + }
4723 +}
4724 +
4725 +if ( ! function_exists('wdk_generate_missing_image_sizes'))
4726 +{
4727 + /**
4728 + * Wdk_generate_missing_image_sizes and update meta
4729 + * @param int $attachment_id of iamge
4730 + * @param string $size_name size of image based on wp intermediate_size
4731 + *
4732 + * @return bool
4733 + */
4734 + function wdk_generate_missing_image_sizes($attachment_id, $size_name = '') {
4735 + if(empty($size_name) || $size_name == 'full' || !get_option( "{$size_name}_size_w" )) {
4736 + return true;
4737 + }
4738 +
4739 + // Check if the attachment is an image
4740 + if (!wp_attachment_is_image($attachment_id)) {
4741 + return false;
4742 + }
4743 +
4744 + $file = get_attached_file( $attachment_id );
4745 + require_once(ABSPATH . "wp-admin" . '/includes/image.php');
4746 + $metadata = wp_generate_attachment_metadata($attachment_id, $file);
4747 + if ( ! isset( $metadata['sizes'][ $size_name ] ) ) {
4748 + // Generate the missing image size
4749 + $resized = image_make_intermediate_size( $file, get_option( "{$size_name}_size_w" ), get_option( "{$size_name}_size_h" ), get_option( "{$size_name}_crop" ) );
4750 +
4751 + // If the resizing was successful, add it to the metadata
4752 + if ( $resized ) {
4753 + $metadata['sizes'][ $size_name ] = $resized;
4754 + wp_update_attachment_metadata( $attachment_id, $metadata );
4755 + }
4756 + }
4757 + return true;
4758 + }
4759 +}
4760 +
4761 +if (!function_exists('wdk_get_languages')) {
4762 +
4763 + function wdk_get_languages($lang_code_id = null)
4764 + {
4765 + $lang_pattern = ['title' => '', 'lang_code' => '', 'id' => '', 'icon' => '', 'url' => ''];
4766 + $languages = [];
4767 +
4768 + // [qTranslate X]
4769 + if (function_exists('qtranxf_getSortedLanguages')) {
4770 + global $q_config;
4771 +
4772 + if (empty($q_config)) {
4773 + // Initialize qTranslate X language settings if needed
4774 + // qtranxf_init_language();
4775 + }
4776 +
4777 + $all_langs = qtranxf_getSortedLanguages();
4778 + if (count($all_langs) > 0) {
4779 + foreach ($all_langs as $key => $lang_code) {
4780 + $languages[$key + 1] = array_merge(
4781 + $lang_pattern,
4782 + [
4783 + 'title' => $q_config['language_name'][$lang_code],
4784 + 'lang_code' => $lang_code,
4785 + 'id' => $key + 1,
4786 + 'icon' => '',
4787 + 'url' => wdk_get_language_url($lang_code),
4788 + ]
4789 + );
4790 + }
4791 + }
4792 + }
4793 + // [/qTranslate X]
4794 +
4795 + // [WPML]
4796 + if (function_exists('icl_get_languages')) {
4797 + $wpml_langs = icl_get_languages('orderby=KEY&order=DIR&link_empty_to=str');
4798 + $k = 1;
4799 + foreach ($wpml_langs as $key => $lang_data) {
4800 + $languages[$k] = array_merge(
4801 + $lang_pattern,
4802 + [
4803 + 'title' => (!empty($lang_data['translated_name'])) ? $lang_data['translated_name'] : $lang_data['native_name'],
4804 + 'lang_code' => $lang_data['language_code'],
4805 + 'id' => $k,
4806 + 'icon' => (!empty($lang_data['country_flag_url'])) ? $lang_data['country_flag_url'] : WPDIRECTORYKIT_URL.'public/img/flags/'.$lang_data['language_code'].'.png',
4807 + 'url' => wdk_get_language_url($lang_data['language_code']),
4808 + ]
4809 + );
4810 + $k++;
4811 + }
4812 + } elseif (has_filter('wpml_active_languages')) {
4813 + $wpml_langs = apply_filters('wpml_active_languages', null) ?: get_query_var('lang', 'all');
4814 + if (is_array($wpml_langs)) {
4815 + foreach ($wpml_langs as $lang_data) {
4816 + if (!isset($lang_data['code']) && isset($lang_data['language_code'])) {
4817 + $lang_data['code'] = $lang_data['language_code'];
4818 + }
4819 + if (empty($lang_data['translated_name']) && !empty($lang_data['native_name'])) {
4820 + $lang_data['translated_name'] = $lang_data['native_name'];
4821 + }
4822 + $languages[$lang_data['id']] = array_merge(
4823 + $lang_pattern,
4824 + [
4825 + 'title' => (!empty($lang_data['translated_name'])) ? $lang_data['translated_name'] : $lang_data['native_name'],
4826 + 'lang_code' => $lang_data['code'],
4827 + 'id' => $lang_data['id'],
4828 + 'icon' => (!empty($lang_data['country_flag_url'])) ? $lang_data['country_flag_url'] : WPDIRECTORYKIT_URL.'public/img/flags/'.$lang_data['language_code'].'.png',
4829 + 'url' => wdk_get_language_url($lang_data['code']),
4830 + ]
4831 + );
4832 + }
4833 + }
4834 + }
4835 + // [/WPML]
4836 +
4837 + // [TranslatePress]
4838 + if (function_exists('trp_custom_language_switcher')) {
4839 + $k = 1;
4840 + foreach (trp_custom_language_switcher() as $lang_data) {
4841 + $languages[$k++] = array_merge(
4842 + $lang_pattern,
4843 + [
4844 + 'title' => $lang_data['language_name'],
4845 + 'lang_code' => $lang_data['language_code'],
4846 + 'id' => $k,
4847 + 'icon' => $lang_data['flag_link'],
4848 + 'url' => $lang_data['current_page_url'],
4849 + ]
4850 + );
4851 + }
4852 + }
4853 + // [/TranslatePress]
4854 +
4855 + if (!empty($lang_code_id)) {
4856 + foreach ($languages as $lang) {
4857 + if (($lang['id'] == $lang_code_id) || ($lang['lang_code'] == $lang_code_id)) {
4858 + return $lang['id'] == $lang_code_id ? $lang['lang_code'] : $lang['id'];
4859 + }
4860 + }
4861 + return false;
4862 + }
4863 +
4864 + return $languages;
4865 + }
4866 +}
4867 +
4868 +if (!function_exists('wdk_default_language')) {
4869 + function wdk_default_language()
4870 + {
4871 + // [qTranslate X]
4872 + if (function_exists('qtranxf_getLanguageDefault')) {
4873 + return qtranxf_getLanguageDefault();
4874 + }
4875 + // [/qTranslate X]
4876 +
4877 + // [WPML]
4878 + if (function_exists('icl_get_languages')) {
4879 + $wpml_langs = icl_get_languages('orderby=KEY&order=DIR&link_empty_to=str');
4880 + foreach ($wpml_langs as $lang_data) {
4881 + if ($lang_data['major'] == 1) {
4882 + return $lang_data['code'];
4883 + }
4884 + }
4885 + } elseif (has_filter('wpml_default_language')) {
4886 + return apply_filters('wpml_default_language', null);
4887 + }
4888 + // [/WPML]
4889 +
4890 + return 'en';
4891 + }
4892 +}
4893 +
4894 +if (!function_exists('wdk_current_language')) {
4895 + function wdk_current_language()
4896 + {
4897 + if (function_exists('trp_get_languages')) {
4898 + global $TRP_LANGUAGE;
4899 + $trp = TRP_Translate_Press::get_trp_instance();
4900 + $settings = $trp->get_component('settings')->get_settings();
4901 + $translation_languages = $trp->get_component('languages')->get_language_names($settings['publish-languages']);
4902 + if (isset($translation_languages[$TRP_LANGUAGE])) {
4903 + return $translation_languages[$TRP_LANGUAGE];
4904 + }
4905 + }
4906 +
4907 + // [qTranslate X]
4908 + if (function_exists('qtranxf_getLanguage')) {
4909 + return qtranxf_getLanguage();
4910 + }
4911 + // [/qTranslate X]
4912 +
4913 + // [WPML]
4914 + if (function_exists('icl_get_languages')) {
4915 + $wpml_langs = icl_get_languages('orderby=KEY&order=DIR&link_empty_to=str');
4916 + foreach ($wpml_langs as $lang_data) {
4917 + if ($lang_data['active'] == 1) {
4918 + return (!empty($lang_data['native_name'])) ? $lang_data['native_name'] : $lang_data['language_code'];
4919 + }
4920 + }
4921 + } elseif (has_filter('wpml_current_language')) {
4922 + return apply_filters('wpml_current_language', null);
4923 + }
4924 + // [/WPML]
4925 +
4926 + return 'en';
4927 + }
4928 +}
4929 +
4930 +if (!function_exists('wdk_current_language_id')) {
4931 + function wdk_current_language_id()
4932 + {
4933 + $lang_id = wdk_get_languages(wdk_current_language());
4934 + return is_numeric($lang_id) ? $lang_id : wdk_default_language_id();
4935 + }
4936 +}
4937 +
4938 +if (!function_exists('wdk_default_language_id')) {
4939 + function wdk_default_language_id()
4940 + {
4941 + $lang_id = wdk_get_languages(wdk_default_language());
4942 + return is_numeric($lang_id) ? $lang_id : '1';
4943 + }
4944 +}
4945 +
4946 +if (!function_exists('wdk_get_language_name')) {
4947 + function wdk_get_language_name($id_or_code)
4948 + {
4949 + $langs = wdk_get_languages();
4950 + foreach ($langs as $lang) {
4951 + if ($lang['lang_code'] == $id_or_code || $lang['id'] == $id_or_code) {
4952 + return $lang['title'];
4953 + }
4954 + }
4955 + return '';
4956 + }
4957 +}
4958 +
4959 +if (!function_exists('wdk_get_language_url')) {
4960 + function wdk_get_language_url($lang_code)
4961 + {
4962 + // [qTranslate X]
4963 + if (function_exists('qtranxf_convertURL')) {
4964 + return qtranxf_convertURL('', $lang_code, false, true);
4965 + }
4966 + // [/qTranslate X]
4967 +
4968 + // [WPML]
4969 + if (function_exists('icl_get_languages')) {
4970 + $wpml_langs = icl_get_languages('orderby=KEY&order=DIR&link_empty_to=str');
4971 + foreach ($wpml_langs as $lang_data) {
4972 + if ($lang_data['language_code'] == $lang_code) {
4973 + return $lang_data['url'];
4974 + }
4975 + }
4976 + } elseif (has_filter('wpml_active_languages')) {
4977 + $wpml_langs = apply_filters('wpml_active_languages', null);
4978 + foreach ($wpml_langs as $lang_data) {
4979 + if (!isset($lang_data['language_code']) && isset($lang_data['language_code'])) {
4980 + $lang_data['language_code'] = $lang_data['language_code'];
4981 + }
4982 + if (empty($lang_data['translated_name']) && !empty($lang_data['native_name'])) {
4983 + $lang_data['translated_name'] = $lang_data['native_name'];
4984 + }
4985 + $url = wdk_wpml_ls_language_url($lang_data['url'], $lang_data);
4986 + if ($lang_data['language_code'] == $lang_code) {
4987 + return $url;
4988 + }
4989 + }
4990 + }
4991 + // [/WPML]
4992 +
4993 + return '';
4994 + }
4995 +}
4996 +
4997 +function wdk_set_user_default_language($user_id = null)
4998 +{
4999 + if (is_null($user_id)) {
5000 + $user_id = get_current_user_id();
5001 + }
5002 +
5003 + $get_language = get_user_meta($user_id, 'user_language', true);
5004 +
5005 + if (!$get_language && (function_exists('icl_get_languages') || has_filter('wpml_active_languages'))) {
5006 + do_action('wpml_switch_language', $get_language);
5007 + }
5008 +}
5009 +
5010 +function wdk_set_language($lang_code = null)
5011 +{
5012 + if (!is_null($lang_code) && (function_exists('icl_get_languages') || has_filter('wpml_active_languages'))) {
5013 + do_action('wpml_switch_language', $lang_code);
5014 + }
5015 +}
5016 +
5017 +function wdk_wpml_ls_language_url($url, $data)
5018 +{
5019 + global $sitepress;
5020 +
5021 + if (is_object($sitepress)) {
5022 + $sitepress_settings = $sitepress->get_settings();
5023 + }
5024 +
5025 + return $url;
5026 +}
5027 +
5028 +add_filter('wpml_ls_language_url', 'wdk_wpml_ls_language_url', 10, 3);
5029 +
5030 +if (!function_exists('wdk_calculate_nights')) {
5031 + /**
5032 + * Calculate the number of nights between two dates
5033 + *
5034 + * This function takes two date strings as input and calculates the number of nights
5035 + * (i.e., the difference in days) between them. It returns the total number of nights
5036 + * between the provided start and end dates. The date format must be valid for PHP's
5037 + * DateTime class.
5038 + *
5039 + * @param string $start_date The start date in 'Y-m-d' format.
5040 + * @param string $end_date The end date in 'Y-m-d' format.
5041 + * @return int The number of nights (days between the two dates).
5042 + */
5043 + function wdk_calculate_nights($start_date, $end_date) {
5044 +
5045 + /* normalize date */
5046 + $start_date = wdk_normalize_date_db($start_date, 'Y-m-d H:i:s', 'Y-m-d');
5047 + $end_date = wdk_normalize_date_db($end_date, 'Y-m-d H:i:s', 'Y-m-d');
5048 +
5049 + // Create DateTime objects for start and end dates
5050 + $start = new DateTime($start_date);
5051 + $end = new DateTime($end_date);
5052 +
5053 + // Calculate the difference between the two dates
5054 + $difference = $start->diff($end);
5055 +
5056 + // Return the number of nights (difference in days)
5057 + return $difference->days;
5058 + }
5059 +}
5060 +
5061 +if ( ! function_exists('wdk_select_db_field_ajax'))
5062 +{
5063 + /**
5064 + * Return select2 ajax
5065 + *
5066 + * @param string option Option key
5067 + * @return string alt or title
5068 + */
5069 + function wdk_select_db_field_ajax($name = '', $selected = NULL, $empty_value='', $filter_id = '')
5070 + {
5071 + $WMVC = &wdk_get_instance();
5072 +
5073 + static $counter = 0;
5074 + $form = '<select data-ajax="'.esc_url(admin_url('admin-ajax.php')).'" name="'.$name.'" data-id="'.$filter_id.'" data-placeholder="'.$empty_value.'" class="form-control wdk_select2_field_suggestion" id="wdk_select2_field_'.$filter_id.'_'.$counter.'" multiple="">';
5075 + if($selected) {
5076 + if(is_array($selected)) {
5077 + /* where in */
5078 + foreach ($selected as $item) {
5079 + $form .= '<option selected="selected" value="'.esc_attr($item).'">'.esc_html($item).'</option>';
5080 + }
5081 + } elseif(is_string($selected)) {
5082 + $form .= '<option selected="selected" value="'.esc_attr($selected).'">'.esc_html($selected).'</option>';
5083 + }
5084 + } else {
5085 + //$form .= '<option value="" selected="selected">'.esc_html__('Not selected', 'wpdirectorykit').'</option>';
5086 + }
5087 + $form .= '</select>';
5088 +
5089 + //load javascript library
5090 + if($counter==0)
5091 + {
5092 + wp_enqueue_script('select2-select2');
5093 + wp_enqueue_script('wdk-select2');
5094 + wp_enqueue_style('select2-select2');
5095 + }
5096 + ?>
5097 + <?php
5098 + $counter++;
5099 + return $form;
5100 +
5101 + }
5102 +}
5103 +
5104 +if ( ! function_exists('wdk_next_month_payment_day'))
5105 +{
5106 + /**
5107 + * Gets the next payment date one month later, considering the number of days in the next month.
5108 + *
5109 + * @param string $currentDate The current payment date in 'Y-m-d H:i:s' format.
5110 + * @return string|false The next payment date in 'Y-m-d H:i:s' format or false on error.
5111 + */
5112 + function wdk_next_month_payment_day($currentDate, $time = false, $wanted_day = NULL) {
5113 + $nextDate = null;
5114 + $timestamp = strtotime($currentDate);
5115 + $daysInNextMonth = gmdate('t', strtotime('+1 month', strtotime(gmdate('Y-m', $timestamp))));
5116 + $currentDay = (int)gmdate('d', $timestamp);
5117 +
5118 + $timeFormat = $time ? "H:i:s" : "00:00:00";
5119 +
5120 +
5121 + // Determine the wanted day
5122 + if ($wanted_day !== NULL) {
5123 + $wanted_day = (int)gmdate('d', strtotime($wanted_day));
5124 + } else {
5125 + $wanted_day = (int)gmdate('d', $timestamp);
5126 + }
5127 +
5128 + $nextMonth = strtotime('first day of next month', $timestamp);
5129 + $daysInNextMonth = gmdate('t', $nextMonth);
5130 +
5131 + // Adjust for the wanted day
5132 + if ($wanted_day > $daysInNextMonth ||
5133 + (
5134 + get_option('wdk_membership_next_month_calculation_with_last_day')
5135 +
5136 + && (
5137 + $currentDay >= 30 || $currentDay == gmdate('t', $timestamp)
5138 + )
5139 + )
5140 + ) {
5141 + // If the wanted day exceeds the max days of the next month, use the last day of the month
5142 + $nextDate = gmdate("Y-m-{$daysInNextMonth} {$timeFormat}", $nextMonth);
5143 + } else {
5144 + // Otherwise, set the exact wanted day
5145 + $nextDate = gmdate("Y-m-{$wanted_day} {$timeFormat}", $nextMonth);
5146 + }
5147 +
5148 + return ($nextDate) ? $nextDate : false;
5149 + }
5150 +}
5151 +
5152 +if ( ! function_exists('wdk_next_year_payment_day'))
5153 +{
5154 + /**
5155 + * Gets the next payment date one year later, considering the number of days in the next month.
5156 + *
5157 + * @param string $currentDate The current payment date in 'Y-m-d H:i:s' format.
5158 + * @return string|false The next payment date in 'Y-m-d H:i:s' format or false on error.
5159 + */
5160 +
5161 + function wdk_next_year_payment_day($currentDate, $time = false) {
5162 + $nextDate = null;
5163 + $timestamp = strtotime($currentDate);
5164 + $nextYearTimestamp = strtotime('+1 year', strtotime(gmdate('Y-m', $timestamp)));
5165 + $daysInNextMonth = gmdate('t', $nextYearTimestamp);
5166 + $currentDay = gmdate('j', $timestamp);
5167 + $timeFormat = "00:00:00";
5168 + if($time) {
5169 + $timeFormat = "H:i:s";
5170 + }
5171 + if ($currentDay > $daysInNextMonth) {
5172 + $nextDate = gmdate('Y-m-d '.$timeFormat, strtotime('last day of this month', $nextYearTimestamp));
5173 + } else {
5174 + $nextDate = gmdate('Y-m-d '.$timeFormat, strtotime('+1 year', $timestamp));
5175 + }
5176 +
5177 + return ($nextDate) ? $nextDate : false;
5178 + }
5179 +}
5180 +
5181 +if ( ! function_exists('wdk_generate_auto_login_link'))
5182 +{
5183 + function wdk_generate_auto_login_link( $user_id = null ) {
5184 + $token = substr(md5($user_id.NONCE_KEY.'wpdirectorykit'),0,10);
5185 +
5186 + $login_url = site_url( "/?auto-login=1&user_id={$user_id}&token={$token}" );
5187 + return $login_url;
5188 + }
5189 +}
5190 +
5191 +if ( ! function_exists('wdk_get_user_subscription_id'))
5192 +{
5193 + function wdk_get_user_subscription_id($user_id = null) {
5194 + global $Winter_MVC_wdk_membership;
5195 + if(!isset($Winter_MVC_wdk_membership)) {
5196 + return false;
5197 + }
5198 + $Winter_MVC_wdk_membership->model('subscription_user_m');
5199 + $user_subscription = $Winter_MVC_wdk_membership->subscription_user_m->get_by(array('user_id'=>$user_id), TRUE);
5200 + return wmvc_show_data('subscription_id', $user_subscription, '', TRUE, TRUE);
5201 + }
5202 +}
5203 +
5204 +if ( ! function_exists('is_wdk_related_validation'))
5205 + /**
5206 + * IS WDK related validation
5207 + *
5208 + * @return bool true if exists dash
5209 + */
5210 + {
5211 + function is_wdk_related_validation($param)
5212 + {
5213 +
5214 + if(empty($param)) {
5215 + return TRUE;
5216 + }
5217 +
5218 + $listing_id = (!empty($_GET['id'])) ? intval(sanitize_text_field($_GET['id'])) : null;
5219 +
5220 +
5221 + global $Winter_MVC_WDK;
5222 + $Winter_MVC_WDK->model('listing_m');
5223 +
5224 + $Winter_MVC_WDK->db->select('post_id');
5225 + $Winter_MVC_WDK->db->where(array(
5226 + '(post_id IN ('.esc_sql(sanitize_text_field($param)).'))' => NULL,
5227 + '((`listing_related_ids` IS NOT NULL AND `listing_related_ids` !="") OR (`listing_parent_post_id` IS NOT NULL AND `listing_parent_post_id` !=0))' => NULL,
5228 + ));
5229 +
5230 + if($listing_id) {
5231 + $Winter_MVC_WDK->db->where(array(
5232 + '`listing_parent_post_id` !='.esc_sql($listing_id).'' => NULL,
5233 + ));
5234 + }
5235 +
5236 + $Winter_MVC_WDK->db->from($Winter_MVC_WDK->listing_m->_table_name);
5237 + $Winter_MVC_WDK->db->limit(5);
5238 +
5239 + $Winter_MVC_WDK->db->get();
5240 + if ($Winter_MVC_WDK->db->num_rows() > 0) {
5241 + $db_results = $Winter_MVC_WDK->db->results();
5242 + } else {
5243 + $db_results = null;
5244 + }
5245 +
5246 + if (!empty($db_results)) {
5247 + return false;
5248 + }
5249 +
5250 + return TRUE;
5251 + }
5252 + }
5253 +
5254 + /**
5255 + * Renders an Elementor template by its title or post ID.
5256 + *
5257 + * Attempts to find and render an Elementor layout/template using the post title or post ID.
5258 + * If the post is found and public, its rendered Elementor content is returned, otherwise post content fallback or error.
5259 + *
5260 + * @since 1.0.0
5261 + * @param string|int $title The title (or ID if $id=true) of the Elementor template to render.
5262 + * @param bool $id Optional. If true, $title is treated as a post ID. If false (default), searches by title.
5263 + * @return string|false Rendered template HTML on success, public/content fallback, or error message/false on failure.
5264 + */
5265 + function wdk_render_elementor_template( $title, $id = false ) {
5266 + // Initialize variables.
5267 + $layout_id = null;
5268 + $template_content = '';
5269 +
5270 + // Determine the layout/post ID.
5271 + if ( ! $id ) {
5272 + // Search by post title. Returns WP_Post/object or null.
5273 + $found_post = wdk_page_by_title( $title, OBJECT, ['elementor_library','page'] );
5274 + $layout_id = $found_post ? $found_post->ID : null;
5275 +
5276 + // Support WPML translation if present.
5277 + // The filter may change $layout_id to a translated post's ID if needed.
5278 + $layout_id = apply_filters( 'wpml_object_id', $layout_id, 'elementor_library', true );
5279 + } else {
5280 + // ID provided directly.
5281 + $layout_id = intval($title);
5282 + }
5283 +
5284 + // Early return if no valid layout found.
5285 + if ( empty( $layout_id ) ) {
5286 + return false;
5287 + }
5288 +
5289 + // Get post object (Elementor template or WP Page).
5290 + $post_data = get_post( $layout_id );
5291 +
5292 +
5293 + // Validate post: should exist, be published, and not password protected.
5294 + if ( ! $post_data || $post_data->post_status !== 'publish' || post_password_required( $post_data ) ) {
5295 + return esc_html__( 'Layout is not public', 'wpdirectorykit' );
5296 + }
5297 +
5298 + // Render content depending on post type.
5299 + if (
5300 + ( isset($post_data->post_type) && $post_data->post_type === 'elementor_library' ) ||
5301 + ( isset($post_data->post_type) && $post_data->post_type === 'page' )
5302 + ) {
5303 + // Try to render using Elementor's frontend builder.
5304 + if ( class_exists('\Elementor\Plugin') && method_exists('\Elementor\Plugin', 'instance') ) {
5305 + $elementor_instance = \Elementor\Plugin::instance();
5306 + $content = $elementor_instance->frontend->get_builder_content_for_display( $layout_id );
5307 + $template_content = ! empty( $content ) ? $content : $post_data->post_content;
5308 + } else {
5309 + // Elementor not present; fallback to post content.
5310 + $template_content = $post_data->post_content;
5311 + }
5312 + } else {
5313 + // Non-Elementor post types, fallback to post content.
5314 + $template_content = $post_data->post_content;
5315 + }
5316 +
5317 + /**
5318 + * Filter: Allows modification of the rendered Elementor template content before returning.
5319 + *
5320 + * @param string $template_content The rendered template content.
5321 + * @param int $layout_id The ID of the layout/template.
5322 + * @param WP_Post $post_data The WP_Post object of the layout/template.
5323 + */
5324 + return apply_filters( 'wdk_render_elementor_template_output', $template_content, $layout_id, $post_data );
5325 + }
5326 +
5327 + if(!function_exists('wdk_esc_sql')) {
5328 + function wdk_esc_sql($value = '', $strict = false) {
5329 + $patterns = [
5330 + '/\bselect\b/i',
5331 + '/\binsert\b/i',
5332 + '/\bupdate\b/i',
5333 + '/\bdelete\b/i',
5334 + '/\bunion\b/i',
5335 + '/\bextractvalue\b/i',
5336 + '/\bversion\s*\(\)/i',
5337 + '/\bdatabase\s*\(\)/i',
5338 + '/\bconcat\s*\(/i',
5339 + '/\bdrop\b/i',
5340 + '/\bsleep\s*\(/i',
5341 + '/\bbenchmark\s*\(/i',
5342 + '/--/',
5343 + '/#/i',
5344 + '/\/\*/',
5345 +
5346 + // EXTRA BLOCK YOU REQUESTED
5347 + '/\\\\/', // remove backslash \
5348 + '/\|/', // remove |
5349 + '/%/', // remove %
5350 + ];
5351 +
5352 + // If strict mode is enabled, block additional patterns
5353 + if ($strict === true) {
5354 + $strict_patterns = [
5355 + '/\bif\b\s*\(/i',
5356 + '/\bord\b/i',
5357 + '/\bsubstr\s*\(/i',
5358 + '/\bschema\s*\(\)/i',
5359 + '/@@version/i',
5360 + ];
5361 + $patterns = array_merge($patterns, $strict_patterns);
5362 + }
5363 +
5364 + return esc_sql(trim(preg_replace($patterns, '', sanitize_text_field($value))));
5365 + }
5366 + }
5367 +
5368 + if(!function_exists('wdk_esc_sql_order_by')) {
5369 + function wdk_esc_sql_order_by($value = '', array $allowed_fields = [])
5370 + {
5371 + if (empty($value) || empty($allowed_fields)) {
5372 + return '';
5373 + }
5374 + $result = [];
5375 + foreach (explode(',', $value) as $part) {
5376 + $part = trim(sanitize_text_field($part));
5377 +
5378 + $direction = 'ASC';
5379 + if (preg_match('/\s+(ASC|DESC)$/i', $part, $match)) {
5380 + $direction = strtoupper($match[1]);
5381 + $part = trim(substr($part, 0, -strlen($match[0])));
5382 + }
5383 +
5384 + $part = sanitize_key($part);
5385 +
5386 + if (in_array($part, $allowed_fields, true)) {
5387 + $result[] = $part . ' ' . $direction;
5388 + }
5389 + }
5390 +
5391 + return implode(', ', $result);
5392 + }
5393 + }
5394 +
5395 + if(!function_exists('wdk_listing_seo_title')) {
5396 + function wdk_listing_seo_title () {
5397 + static $cached_seo_title = null;
5398 + if ($cached_seo_title !== null) {
5399 + return $cached_seo_title;
5400 + }
5401 +
5402 + $seo_title ='';
5403 + global $wp_query;
5404 + $wdk_listing_id = $wp_query->post->ID;
5405 + if(wdk_get_option('wdk_seo_listing_title')) {
5406 + global $Winter_MVC_WDK;
5407 + $Winter_MVC_WDK->model('field_m');
5408 + $Winter_MVC_WDK->load_helper('listing');
5409 +
5410 + $seo_template = wdk_get_option('wdk_seo_listing_title');
5411 +
5412 + $matches = [];
5413 + preg_match_all('/{(?:field_)?([^}]+)}/', $seo_template, $matches);
5414 + $fields_in_template = isset($matches[1]) ? $matches[1] : [];
5415 +
5416 + $fields_values = [];
5417 +
5418 + foreach ($fields_in_template as $field_id) {
5419 + $key_id = '{field_' . $field_id . '}';
5420 + if($field_id == 'category') {
5421 + $field_id = 'category_title';
5422 + }
5423 + if($field_id == 'location') {
5424 + $field_id = 'location_title';
5425 + }
5426 + // Try to get value for field_id for this listing
5427 + $fields_values[$key_id] = wdk_field_value($field_id, $wdk_listing_id);
5428 + }
5429 + // Replace the fields in template with real values
5430 + $seo_title = strtr($seo_template, $fields_values);
5431 + }
5432 +
5433 + $cached_seo_title = $seo_title;
5434 + return $seo_title;
5435 + }
5436 + }
5437 +
5438 +
5439 + if ( ! function_exists('wdk_filter_viber_phone'))
5440 + {
5441 + // Validation phone for viber
5442 + /**
5443 + * @param string $value phone in string
5444 + * @return strings +xxx
5445 + */
5446 + function wdk_filter_viber_phone($value = '') {
5447 + $value = str_replace(array(' ','-','(',')'),'',$value);
5448 + return (strpos($value, '+') !== 0) ? '+' . $value : $value;
5449 + }
5450 + }
5451 +
5452 +?>