PluginProbe
WP Directory Kit / 1.4.8
WP Directory Kit v1.4.8
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 1.4.0 1.4.1 All 35 releases
← All changes | application/helpers/Basic.php +1158 -110 1.3.21.4.8 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 {
@@ -150,9 +150,10 @@
150 150 "field_label" =>wmvc_show_data('field_label', $field_data),
151 151 "prefix" => wmvc_show_data('prefix', $field_data),
152 152 "suffix" => wmvc_show_data('suffix', $field_data),
153 153 "values_list" => wmvc_show_data('values_list', $field_data),
154 - "placeholder" => wmvc_show_data('placeholder', $field_data)
154 + "placeholder" => wmvc_show_data('placeholder', $field_data),
155 + "is_select_2_ajax_field_db_suggestion" => wmvc_show_data('is_select_2_ajax_field_db_suggestion', $used_field),
155 156 );
156 157 }
157 158 }
158 159 }
@@ -390,9 +391,10 @@
390 391 $wdk_bookings_joinded = false;
391 392 static $available_fields_listings = NULL;
392 393 static $available_fields_static = array();
393 394 static $list_fields_static = NULL;
394 -
395 + $fields_type = array();
396 +
395 397 /* add if missing columns */
396 398 if(!in_array('post_id', $columns)) {
397 399 $columns[] = $Winter_MVC_WDK->db->prefix.'wdk_listings.post_id';
398 400 }
@@ -408,10 +410,10 @@
408 410
409 411 if(isset($custom_parameters['order_by'])) {
410 412
411 413 if(isset($_GET_clone['order_by']) && !empty($_GET_clone['order_by'])) {
412 - $_GET_clone['order_by'] = $custom_parameters['order_by'].', '.$_GET_clone['order_by'];
413 - } else {
414 + $_GET_clone['order_by'] = ((!empty($custom_parameters['order_by'])) ? $custom_parameters['order_by'].', ':'').sanitize_text_field($_GET_clone['order_by']);
415 + } elseif(!empty( $custom_parameters['order_by'])) {
414 416 $_GET_clone['order_by'] = $custom_parameters['order_by'];
415 417 }
416 418
417 419 unset($custom_parameters['order_by']);
@@ -426,12 +428,12 @@
426 428 $WMVC->model('listingfield_m');
427 429
428 430 $smart_search = '';
429 431 if(isset($_GET_clone['search']))
430 - $smart_search = sanitize_text_field($_GET_clone['search']);
432 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['search']));
431 433
432 434 if(isset($_GET_clone['field_search']))
433 - $smart_search = sanitize_text_field($_GET_clone['field_search']);
435 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['field_search']));
434 436
435 437 if(!isset($available_fields_static[$model_name]))
436 438 {
437 439 $available_fields = $WMVC->$model_name->get_available_fields();
@@ -464,8 +466,10 @@
464 466 foreach($list_fields as $field_data) {
465 467
466 468 $field_id = wmvc_show_data('idfield',$field_data);
467 469 $field_type = wmvc_show_data('field_type',$field_data);
470 +
471 + $fields_type[$field_id] = $field_type;
468 472 $column_name ='field_'.$field_id.'_'.$field_type;
469 473 if(!isset($available_fields_listings[$column_name])) continue;
470 474
471 475 if(isset($_GET_clone['field_'.$field_id])) {
@@ -483,9 +487,9 @@
483 487 if(isset($_GET_clone['field_'.$field_id.'_min'])) {
484 488 $_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);
485 489 }
486 490 if(isset($_GET_clone['field_'.$field_id.'_exactly'])) {
487 - $_GET_clone['field_'.$field_id.'_'.$field_type.'_exactly'] = sanitize_text_field($_GET_clone['field_'.$field_id.'_exactly']);
491 + $_GET_clone['field_'.$field_id.'_'.$field_type.'_exactly'] = wdk_clean_mixed($_GET_clone['field_'.$field_id.'_exactly']);
488 492 }
489 493
490 494 $columns[] = $column_name;
491 495 $columns[] = $column_name.'_max';
@@ -540,9 +544,9 @@
540 544 }
541 545
542 546 if(isset($_GET_clone['field_post_id'])) {
543 547 $column_name ='ID_exactly';
544 - $_GET_clone[$column_name] = intval($_GET_clone['field_post_id']);
548 + $_GET_clone[$column_name] = sanitize_text_field($_GET_clone['field_post_id']);
545 549 $columns[] = $column_name;
546 550 $external_columns[] = $column_name;
547 551 }
548 552
@@ -587,15 +591,29 @@
587 591 $columns[] = $column_name;
588 592 $external_columns[] = $column_name;
589 593 }
590 594
591 - if (isset($_GET_clone['search_rank_'.NONCE_KEY])) {
595 + if (isset($_GET_clone['search_rank'])) {
592 596 $column_name ='`rank`';
593 - $_GET_clone[$column_name] = $_GET_clone['search_rank_'.NONCE_KEY];
597 + $_GET_clone[$column_name] = $_GET_clone['search_rank'];
594 598 $columns[] = $column_name;
595 599 $external_columns[] = $column_name;
596 600 }
597 601
602 + if (isset($_GET_clone['search_rank_min'])) {
603 + $column_name ='`rank`_min';
604 + $_GET_clone[$column_name] = $_GET_clone['search_rank_min'];
605 + $columns[] = $column_name;
606 + $external_columns[] = $column_name;
607 + }
608 +
609 + if (isset($_GET_clone['search_rank_max'])) {
610 + $column_name ='`rank`_max';
611 + $_GET_clone[$column_name] = $_GET_clone['search_rank_max'];
612 + $columns[] = $column_name;
613 + $external_columns[] = $column_name;
614 + }
615 +
598 616 //$table_name = substr($model_name, 0, -2);
599 617 $columns_original = array();
600 618 foreach($columns as $key=>$val)
601 619 {
@@ -623,8 +641,10 @@
623 641 {
624 642 unset($_GET_clone['search']);
625 643 unset($_GET_clone['field_search']);
626 644
645 + $WMVC->db->join($WMVC->listing_m->_table_name.' ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'posts'.'.ID', NULL, 'LEFT');
646 +
627 647 // For quick/smart search
628 648 if(wmvc_count($columns) > 0 && !empty($smart_search))
629 649 {
630 650 $gen_q = '';
@@ -739,9 +759,9 @@
739 759
740 760 if(!empty($gen_q))
741 761 $WMVC->db->where("($gen_q)");
742 762 }
743 -
763 +
744 764 // For column search
745 765 if(isset($_GET_clone))
746 766 {
747 767 $gen_q = '';
@@ -756,43 +776,31 @@
756 776 // $col_name = $key;
757 777
758 778 if(strpos($key, 'skip') !== FALSE) continue;
759 779
760 - if(defined( 'WP_DEBUG' ) && WP_DEBUG)
761 - if(function_exists('pll_current_language'))
762 - {
763 - $lang_term_id = pll_current_language('term_id');
764 -
765 - if(is_numeric($lang_term_id))
766 - {
767 - $WMVC->db->join($WMVC->db->prefix.'term_relationships ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'term_relationships.object_id', NULL, NULL);
768 - $WMVC->db->where("({$WMVC->db->prefix}term_relationships.term_taxonomy_id = $lang_term_id)");
769 - }
770 - }
771 -
772 780 if($key == 'field_booking_guest')
773 781 {
774 782 if(!$wdk_bookings_joinded){
775 - $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');
776 - $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
777 - $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');
783 + $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');
784 + $WMVC->db->distinct($WMVC->db->prefix.'posts.ID');
785 + $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');
778 786 $wdk_bookings_joinded = true;
779 787 $gen_q.= $WMVC->db->prefix.'wdk_booking_price.is_activated = 1 AND ';
780 - $WMVC->db->join($WMVC->db->prefix.'wdk_booking_calendar ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'wdk_booking_calendar.post_id', NULL, 'LEFT');
788 + $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');
781 789 }
782 790
783 - $gen_q.= $WMVC->db->prefix."wdk_booking_calendar.guests <='".intval($val)."' AND ";
791 + $gen_q.= $WMVC->db->prefix."wdk_booking_calendar.guests >='".intval($val)."' AND ";
784 792
785 793 }
786 794 elseif($key == 'field_booking_date_from')
787 795 {
788 796 if(!$wdk_bookings_joinded){
789 - $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');
790 - $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
791 - $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');
797 + $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');
798 + $WMVC->db->distinct($WMVC->db->prefix.'posts.ID');
799 + $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');
792 800 $wdk_bookings_joinded = true;
793 801 $gen_q.= $WMVC->db->prefix.'wdk_booking_price.is_activated = 1 AND ';
794 - $WMVC->db->join($WMVC->db->prefix.'wdk_booking_calendar ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'wdk_booking_calendar.post_id', NULL, 'LEFT');
802 + $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');
795 803 }
796 804
797 805 if(wdk_is_date($val))
798 806 {
@@ -810,9 +818,9 @@
810 818 if(!get_option('wdk_bookings_is_hours_enabled')) {
811 819 $gen_search_from = wdk_normalize_date_db($_GET_clone['field_booking_date_from'], 'Y-m-d H:i:s', 'Y-m-d');
812 820 $gen_search_to = wdk_normalize_date_db($_GET_clone['field_booking_date_to'], 'Y-m-d H:i:s', 'Y-m-d');
813 821
814 - $gen_q.= $WMVC->listing_m->_table_name.".post_id NOT IN (
822 + $gen_q.= $WMVC->db->prefix."posts.ID NOT IN (
815 823 SELECT post_id
816 824 FROM ".$WMVC->db->prefix."wdk_booking_reservation
817 825 WHERE
818 826 ".$WMVC->db->prefix."wdk_booking_reservation.is_approved = 1
@@ -825,9 +833,9 @@
825 833 } else {
826 834 $gen_search_from = wdk_normalize_date_db($_GET_clone['field_booking_date_from']);
827 835 $gen_search_to = wdk_normalize_date_db($_GET_clone['field_booking_date_to']);
828 836
829 - $gen_q.= $WMVC->listing_m->_table_name.".post_id NOT IN (
837 + $gen_q.= $WMVC->db->prefix."posts.ID NOT IN (
830 838 SELECT post_id
831 839 FROM ".$WMVC->db->prefix."wdk_booking_reservation
832 840 WHERE
833 841 ".$WMVC->db->prefix."wdk_booking_reservation.is_approved = 1
@@ -842,13 +850,13 @@
842 850 }
843 851 elseif($key == 'field_booking_date_to')
844 852 {
845 853 if(!$wdk_bookings_joinded){
846 - $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');
847 - $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');
854 + $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');
855 + $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');
848 856 $wdk_bookings_joinded = true;
849 857 $gen_q.= $WMVC->db->prefix.'wdk_booking_price.is_activated = 1 AND ';
850 - $WMVC->db->join($WMVC->db->prefix.'wdk_booking_calendar ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'wdk_booking_calendar.post_id', NULL, 'LEFT');
858 + $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');
851 859 }
852 860
853 861 if(wdk_is_date($val))
854 862 {
@@ -864,9 +872,33 @@
864 872 }
865 873 elseif(substr($key, -8) == '_exactly')
866 874 {
867 875 $col_name = substr($key, 0, -8);
868 - $gen_q.=$col_name." = '".$val."' AND ";
876 +
877 + if(is_string($val) && strpos($val, ',') !== FALSE){
878 + $val =explode(',', $val);
879 + } elseif(is_string($val)){
880 + $val =array($val);
881 + }
882 +
883 + if(is_array($val))
884 + {
885 + $sql_search = '';
886 + foreach ($val as $v) {
887 + if(empty($v)) continue;
888 +
889 + if(!empty($sql_search))
890 + $sql_search .= " OR ";
891 +
892 + $sql_search .= " ".$col_name." = '".$v."' ";
893 + }
894 +
895 + if(!empty($sql_search))
896 + $gen_q.=" ( ".$sql_search." ) AND ";
897 + } else {
898 +
899 + $gen_q.=$col_name." = '".$val."' AND ";
900 + }
869 901 }
870 902 elseif(substr($key, -4) == '_max')
871 903 {
872 904 $col_name = substr($key, 0, -4);
@@ -956,9 +988,9 @@
956 988 }
957 989
958 990 if(is_array($val)) {
959 991
960 - $WMVC->db->join($WMVC->db->prefix.'wdk_listings_users ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'wdk_listings_users.post_id', NULL, 'LEFT');
992 + $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');
961 993 $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
962 994 $sql_search = '';
963 995 foreach ($val as $v) {
964 996 if(empty($v)) continue;
@@ -973,9 +1005,9 @@
973 1005 if(!empty($sql_search))
974 1006 $gen_q.=" ( ".$sql_search." ) AND ";
975 1007
976 1008 } elseif(is_string($val) && !empty($val)) {
977 - $WMVC->db->join($WMVC->db->prefix.'wdk_listings_users ON '.$WMVC->listing_m->_table_name.'.post_id = '.$WMVC->db->prefix.'wdk_listings_users.post_id', NULL, 'LEFT');
1009 + $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');
978 1010 $WMVC->db->distinct($WMVC->listing_m->_table_name.'.post_id');
979 1011 $sql_search =" ".$WMVC->listing_m->_table_name.".`user_id_editor` = ".intval($val)." OR `".$WMVC->db->prefix."wdk_listings_users`.`user_id` = ".intval($val)." ";
980 1012 $gen_q.=" ( ".$sql_search." ) AND ";
981 1013 }
@@ -1132,10 +1164,15 @@
1132 1164
1133 1165 if(!empty($sql_search))
1134 1166 $gen_q.=" ( ".$sql_search." ) AND ";
1135 1167 }
1168 + } elseif ($val == 0) {
1169 + $col_name = $key;
1170 + $val = esc_sql($val);
1171 + if(in_array($col_name, ['`rank`'])) {
1172 + $gen_q.=" ( ".$col_name." = 0 OR ".$col_name." IS NULL ) AND ";
1173 + }
1136 1174 }
1137 -
1138 1175 }
1139 1176
1140 1177 $gen_q = substr($gen_q, 0, -5);
1141 1178
@@ -1142,8 +1179,21 @@
1142 1179 if(!empty($gen_q))
1143 1180 $WMVC->db->where("($gen_q)");
1144 1181 }
1145 1182
1183 + //if(defined( 'WP_DEBUG' ) && WP_DEBUG)
1184 + if(function_exists('pll_current_language'))
1185 + {
1186 + $lang_term_id = pll_current_language('term_id');
1187 +
1188 + if(is_numeric($lang_term_id))
1189 + {
1190 + //echo $lang_term_id.'<br />';
1191 + $WMVC->db->join($WMVC->db->prefix.'term_relationships ON '.$WMVC->db->prefix.'posts.ID = '.$WMVC->db->prefix.'term_relationships.object_id', NULL, NULL);
1192 + $WMVC->db->where("({$WMVC->db->prefix}term_relationships.term_taxonomy_id = $lang_term_id)");
1193 + }
1194 + }
1195 +
1146 1196 // [RECTANGLE SEARCH]
1147 1197 if(isset($_GET_clone['rectangle_ne']) && isset($_GET_clone['rectangle_sw']))
1148 1198 {
1149 1199 if(wdk_is_gps($_GET_clone['rectangle_ne']) && wdk_is_gps($_GET_clone['rectangle_sw'])) {
@@ -1157,12 +1207,90 @@
1157 1207 }
1158 1208 // [/RECTANGLE SEARCH]
1159 1209
1160 1210 // order
1161 - if(isset($_GET_clone['order_by']))
1162 - {
1163 - $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_listings.post_id', $_GET_clone['order_by']);
1164 - $WMVC->db->order_by($_GET_clone['order_by']);
1211 + if (isset($_GET_clone['order_by'])) {
1212 + // Merge available fields + system columns
1213 + $order_columns = array_fill_keys([
1214 + 'post_id',
1215 + 'counter_views',
1216 + 'date_modified',
1217 + 'post_title',
1218 + 'address',
1219 + 'category_id',
1220 + 'location_id',
1221 + 'rank'
1222 + ], true);
1223 +
1224 + $order_columns = apply_filters('wdk/listings/order_columns', $order_columns);
1225 +
1226 + $_GET_clone['order_by'] = str_replace(
1227 + 'post_id',
1228 + $WMVC->db->prefix . 'wdk_listings.post_id',
1229 + sanitize_text_field($_GET_clone['order_by'])
1230 + );
1231 +
1232 + // Fix common typos: ask → asc, desk → desc
1233 + $_GET_clone['order_by'] = str_ireplace([' ask', ' desk'], [' asc', ' desc'], $_GET_clone['order_by']);
1234 +
1235 + /* we no need field type in get link now */
1236 + $_GET_clone['order_by'] = str_ireplace(['_NUMBER', '_SECTION', '_TEXTAREA', '_DATE', '_DROPDOWN', '_DROPDOWNMULTIPLE', '_CHECKBOX'], '', $_GET_clone['order_by']);
1237 +
1238 + // Parse order_by string into parts
1239 + $order_by_array = explode(',', $_GET_clone['order_by']);
1240 + $final_order_by = [];
1241 + foreach ($order_by_array as $order_part) {
1242 + $order_part = trim($order_part);
1243 +
1244 + // detect direction asc/desc
1245 + $direction = 'DESC';
1246 + if (stripos($order_part, ' asc') !== false) {
1247 + $direction = 'ASC';
1248 + } elseif (stripos($order_part, ' desc') !== false) {
1249 + $direction = 'DESC';
1250 + }
1251 +
1252 + $order_part = str_ireplace(['desc', 'asc'], '', $order_part);
1253 + $order_part = str_replace(' ', '', $order_part);
1254 +
1255 + // Try to detect field_(id)
1256 + if (preg_match('/field_(\d+)\b/', $order_part, $matches)) {
1257 +
1258 + $search_field_id = $matches[1];
1259 + if (!empty($fields_type[$search_field_id])) {
1260 + $field_name = "field_{$search_field_id}_{$fields_type[$search_field_id]}";
1261 +
1262 + // Check if field exists in order_columns
1263 + if (isset($available_fields_listings[$field_name])) {
1264 + $final_order_by[] = $field_name . ' ' . $direction;
1265 + }
1266 + }
1267 +
1268 + // else → skip invalid field automatically
1269 +
1270 + } else {
1271 + // Extract only the part after the last '.' if exists, else use entire string
1272 + $col_field = $order_part;
1273 + if (strpos($col_field, '.') !== false) {
1274 + $parts = explode('.', $col_field);
1275 + $col_field = end($parts);
1276 + }
1277 +
1278 + // Check if field exists in order_columns
1279 + if (isset($order_columns[$col_field]) || isset($available_fields_listings[$col_field])) {
1280 + $final_order_by[] = $order_part . ' ' . $direction;
1281 + }
1282 + }
1283 + }
1284 +
1285 + // Apply final order if any valid fields left
1286 + if (!empty($final_order_by)) {
1287 + $_GET_clone['order_by'] = implode(', ', $final_order_by);
1288 + $WMVC->db->order_by($_GET_clone['order_by']);
1289 + } else {
1290 + $WMVC->db->order_by('');
1291 + }
1292 +
1165 1293 }
1166 1294
1167 1295 }
1168 1296 }
@@ -1179,9 +1307,9 @@
1179 1307
1180 1308 if(isset($custom_parameters['order_by'])) {
1181 1309
1182 1310 if(isset($_GET_clone['order_by']) && !empty($_GET_clone['order_by'])) {
1183 - $_GET_clone['order_by'] = $custom_parameters['order_by'].', '.$_GET_clone['order_by'];
1311 + $_GET_clone['order_by'] = $custom_parameters['order_by'].', '.sanitize_text_field($_GET_clone['order_by']);
1184 1312 } else {
1185 1313 $_GET_clone['order_by'] = $custom_parameters['order_by'];
1186 1314 }
1187 1315
@@ -1195,9 +1323,9 @@
1195 1323 $WMVC->model($model_name);
1196 1324
1197 1325 $smart_search = '';
1198 1326 if(isset($_GET_clone['profile_search']))
1199 - $smart_search = sanitize_text_field($_GET_clone['profile_search']);
1327 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['profile_search']));
1200 1328
1201 1329 $available_fields = array('user_login','user_nicename','user_email','user_url','display_name');
1202 1330
1203 1331 if(isset($_GET_clone['is_activated'])){
@@ -1364,9 +1492,9 @@
1364 1492 // order
1365 1493 if(isset($_GET_clone['order_by']))
1366 1494 {
1367 1495 $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_favorite.post_id', $_GET_clone['order_by']);
1368 - $WMVC->db->order_by($_GET_clone['order_by']);
1496 + $WMVC->db->order_by(wdk_esc_sql(sanitize_text_field($_GET_clone['order_by'])));
1369 1497 }
1370 1498
1371 1499 }
1372 1500 }
@@ -1382,9 +1510,9 @@
1382 1510 //$WMVC->model('listing_m');
1383 1511
1384 1512 $smart_search = '';
1385 1513 if(isset($_GET_clone['search']))
1386 - $smart_search = sanitize_text_field($_GET_clone['search']);
1514 + $smart_search = wdk_esc_sql(sanitize_text_field($_GET_clone['search']));
1387 1515
1388 1516 $available_fields = $WMVC->$model_name->get_available_fields();
1389 1517
1390 1518 /* Пet column names from wdk_package and add to allow search +
@@ -1535,9 +1663,9 @@
1535 1663 // order
1536 1664 if(isset($_GET_clone['order_by']))
1537 1665 {
1538 1666 $_GET_clone['order_by'] = str_replace('post_id', $WMVC->db->prefix.'wdk_messages.post_id', $_GET_clone['order_by']);
1539 - $WMVC->db->order_by($_GET_clone['order_by']);
1667 + $WMVC->db->order_by(wdk_esc_sql(sanitize_text_field($_GET_clone['order_by'])));
1540 1668 }
1541 1669
1542 1670 }
1543 1671 }
@@ -1570,18 +1698,20 @@
1570 1698
1571 1699 if(isset($_GET[$page_var]))
1572 1700 $current_page = intval(wmvc_xss_clean($_GET[$page_var]));
1573 1701
1574 - if(!isset($texts['previous_page']))$texts['previous_page'] = 'Previous page';
1575 - if(!isset($texts['next_page']))$texts['next_page'] = 'Next page';
1702 + if(!isset($texts['previous_page']))$texts['previous_page'] = esc_html__('Previous page', 'wpdirectorykit');
1703 + if(!isset($texts['next_page']))$texts['next_page'] = esc_html__('Next page', 'wpdirectorykit');
1576 1704 if(!isset($texts['first_page']))$texts['first_page'] = '';
1577 1705 if(!isset($texts['last_page']))$texts['last_page'] = '';
1578 - if(!isset($texts['items']))$texts['items'] = 'items';
1706 + if(!isset($texts['items']))$texts['items'] = esc_html__('items', 'wpdirectorykit');
1579 1707
1580 1708 if(empty($current_page))$current_page = 1;
1581 1709
1582 1710 // get url
1583 - $url = strtok($_SERVER["REQUEST_URI"], '?');
1711 + $url = strtok(wdk_server_current_url(), '?');
1712 +
1713 +
1584 1714 $qs_parameters = wmvc_xss_clean( $_GET );
1585 1715 unset($qs_parameters[$page_var]);
1586 1716 $qs_part = http_build_query($qs_parameters);
1587 1717 $url = wdk_url_suffix($url, $qs_part);
@@ -1604,16 +1734,16 @@
1604 1734
1605 1735 $output .= '<div class="nav-links">';
1606 1736
1607 1737 if($enable_latest_first && $current_page-1 > 0)
1608 - $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>';
1738 + $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>';
1609 1739
1610 1740 if ($current_page-1 > 0) {
1611 1741
1612 - $output.= '<a class="next page-numbers" href="'.esc_url(wdk_url_suffix($url,esc_attr($page_var).'='.esc_attr($current_page-1))).'#results"><span class="screen-reader-text">'.esc_html($texts['previous_page']).'</span><span aria-hidden="true">‹</span></a>';
1742 + $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>';
1613 1743 } elseif($enable_compact)
1614 1744 {
1615 - $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>';
1745 + $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>';
1616 1746 }
1617 1747
1618 1748 if (!$enable_compact) {
1619 1749 for ($i = 1 ; $i <= $total_pages; $i++) {
@@ -1621,9 +1751,9 @@
1621 1751 if(($current_page-$limit_items) <= $i && ($current_page+$limit_items) >= $i) {
1622 1752 if (($current_page == $i)) {
1623 1753 $output.= '<span aria-current="page" class="page-numbers current">'.$i.'</span>';
1624 1754 } else {
1625 - $output.= '<a class="page-numbers" href="'.esc_url(wdk_url_suffix($url, esc_attr($page_var).'='.esc_attr($i))).'#results">'.esc_attr($i).'</a>';
1755 + $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>';
1626 1756 }
1627 1757 }
1628 1758 }
1629 1759 } else {
@@ -1631,17 +1761,17 @@
1631 1761 }
1632 1762
1633 1763 if($current_page+1 <= $total_pages)
1634 1764 {
1635 - $output.= '<a class="next page-numbers" href="'.esc_url(wdk_url_suffix($url, esc_attr($page_var).'='.esc_attr($current_page+1))).'#results"><span class="screen-reader-text">'.esc_html($texts['next_page']).'</span><span aria-hidden="true">›</span></a>';
1765 + $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>';
1636 1766 }
1637 1767 elseif($enable_compact)
1638 1768 {
1639 - $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>';
1769 + $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>';
1640 1770 }
1641 1771
1642 1772 if($enable_latest_first && $current_page+1 <= $total_pages)
1643 - $output.= '<a class="next page-numbers" href="'.esc_url(wdk_url_suffix($url, esc_attr($page_var).'='.esc_attr($total_pages))).'#results"><span class="screen-reader-text">'.esc_html($texts['last_page']).'</span><span aria-hidden="true">»</span></a>';
1773 + $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>';
1644 1774
1645 1775
1646 1776 $output.= '</div>';
1647 1777 $output.= '</nav>';
@@ -1699,15 +1829,15 @@
1699 1829 <div class="wdk-col wdk-col-btns">
1700 1830 <div class="wdk-field wdk-field-btn">
1701 1831 <div class="wdk-field-group wdk-field-group-additional">
1702 1832 <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>
1703 - <input type='checkbox' style="display: none !important" value='1' name='wdk_search_additional_opened' />
1833 + <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' />
1704 1834 </div>
1705 1835 <div class="wdk-field-group wdk-field-group-reset">
1706 - <button 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>
1836 + <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>
1707 1837 </div>
1708 1838 <div class="wdk-field-group wdk-field-group-search">
1709 - <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>
1839 + <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>
1710 1840
1711 1841 <?php if(function_exists('run_wdk_save_search') && get_option('wdk_save_search_show_on_searchform')):?>
1712 1842 <div class="section-widget-control right">
1713 1843 <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">
@@ -1778,8 +1908,9 @@
1778 1908 ajax_param: {
1779 1909 "page": 'wdk_frontendajax',
1780 1910 "function": 'treefieldid',
1781 1911 "action": 'wdk_public_action',
1912 + "wdk_secure": '<?php echo wp_create_nonce( 'wdk_secure_treefieldid' );?>',
1782 1913 "table": '<?php echo esc_js($table); ?>',
1783 1914 "filter_ids": '<?php echo esc_js($filter_ids); ?>',
1784 1915 "start_id": '<?php if(!empty($filter_ids)) esc_js($selected); else echo ""; ?>',
1785 1916 "empty_value": '<?php echo esc_js($empty_value); ?>',
@@ -1887,8 +2018,9 @@
1887 2018 ajax_param: {
1888 2019 "page": 'wdk_frontendajax',
1889 2020 "function": 'treefieldid_checkboxes',
1890 2021 "action": 'wdk_public_action',
2022 + "wdk_secure": '<?php echo wp_create_nonce( 'wdk_secure_treefieldid_checkboxes' );?>',
1891 2023 "table": '<?php echo esc_js($table); ?>',
1892 2024 "filter_ids": '<?php echo esc_js($filter_ids); ?>',
1893 2025 "empty_value": '<?php echo esc_js($empty_value); ?>',
1894 2026 "user_check": '<?php echo esc_js($user_check); ?>',
@@ -1917,14 +2049,19 @@
1917 2049 if ( ! function_exists('wdk_filter_decimal'))
1918 2050 {
1919 2051 function wdk_filter_decimal($string = '')
1920 2052 {
1921 - if(substr($string, -3, 3) === ".00") {
1922 - return substr($string, 0, -3);
1923 - }
1924 - if(substr($string, -3, 1) === "." && substr($string, -1, 1) === "0") {
1925 - return substr($string, 0, -1);
1926 - }
2053 + if(wdk_get_option('wdk_enable_filter_zero_decimal')) {
2054 + if(substr($string, -3, 3) === ",00") {
2055 + return substr($string, 0, -3);
2056 + }
2057 + if(substr($string, -3, 3) === ".00") {
2058 + return substr($string, 0, -3);
2059 + }
2060 + if(substr($string, -3, 1) === "." && substr($string, -1, 1) === "0") {
2061 + return substr($string, 0, -1);
2062 + }
2063 + }
1927 2064
1928 2065 return $string;
1929 2066 }
1930 2067 }
@@ -2074,9 +2211,100 @@
2074 2211 return $base_url.$extension_url;
2075 2212 }
2076 2213 }
2077 2214
2215 +
2078 2216 /**
2217 + * Insert an attachment from a remote URL.
2218 + *
2219 + * @param string $url Remote file URL.
2220 + * @param int|null $parent_post_id Post ID to attach the image to.
2221 + * @return int|false Attachment ID or false on failure.
2222 + */
2223 +function wdk_insert_attachment_from_cloud_url($url, $parent_post_id = null) {
2224 + // Request with headers (Google blocks requests without UA sometimes)
2225 + $response = wp_remote_get($url, array(
2226 + 'timeout' => 30,
2227 + 'redirection' => 5,
2228 + 'headers' => array(
2229 + 'User-Agent' => 'Mozilla/5.0 (WordPress)',
2230 + 'Referer' => home_url()
2231 + )
2232 + ));
2233 +
2234 + if (is_wp_error($response)) {
2235 + return false;
2236 + }
2237 +
2238 + $code = wp_remote_retrieve_response_code($response);
2239 + if ($code != 200) {
2240 + return false;
2241 + }
2242 +
2243 + $body = wp_remote_retrieve_body($response);
2244 + if (empty($body)) {
2245 + return false;
2246 + }
2247 +
2248 + // Try to get filename from URL or headers
2249 + $filename = basename(parse_url($url, PHP_URL_PATH));
2250 +
2251 + // If filename empty (Google Drive case)
2252 + if (!$filename || strpos($filename, '.') === false) {
2253 + // Try content-disposition header
2254 + $headers = wp_remote_retrieve_headers($response);
2255 + if (!empty($headers['content-disposition']) &&
2256 + preg_match('/filename="?([^"]+)"?/i', $headers['content-disposition'], $matches)) {
2257 + $filename = sanitize_file_name($matches[1]);
2258 + }
2259 + }
2260 +
2261 + // If still no extension, detect from mime
2262 + $ext = pathinfo($filename, PATHINFO_EXTENSION);
2263 + if (empty($ext)) {
2264 + $data = getimagesizefromstring($body);
2265 + if (!$data || empty($data['mime'])) {
2266 + return false;
2267 + }
2268 + $ext = wdk_mime2ext($data['mime']);
2269 + $filename = time() . '-' . wp_generate_password(6, false) . '.' . $ext;
2270 + }
2271 +
2272 + // Save file to uploads dir
2273 + $upload = wp_upload_bits($filename, null, $body);
2274 + if (!empty($upload['error'])) {
2275 + return false;
2276 + }
2277 +
2278 + $file_path = $upload['file'];
2279 + $file_name = basename($file_path);
2280 + $file_type = wp_check_filetype($file_name, null);
2281 + $wp_upload_dir = wp_upload_dir();
2282 +
2283 + $post_info = array(
2284 + 'guid' => $wp_upload_dir['url'] . '/' . $file_name,
2285 + 'post_mime_type' => $file_type['type'],
2286 + 'post_title' => sanitize_file_name(pathinfo($file_name, PATHINFO_FILENAME)),
2287 + 'post_content' => '',
2288 + 'post_status' => 'inherit',
2289 + );
2290 +
2291 + // Insert attachment
2292 + $attach_id = wp_insert_attachment($post_info, $file_path, $parent_post_id);
2293 +
2294 + if (!$attach_id) {
2295 + return false;
2296 + }
2297 +
2298 + // Generate metadata
2299 + require_once ABSPATH . 'wp-admin/includes/image.php';
2300 + $attach_data = wp_generate_attachment_metadata($attach_id, $file_path);
2301 + wp_update_attachment_metadata($attach_id, $attach_data);
2302 +
2303 + return $attach_id;
2304 +}
2305 +
2306 +/**
2079 2307 * Insert an attachment from an URL address.
2080 2308 *
2081 2309 * @param String $url
2082 2310 * @param Int $parent_post_id
@@ -2098,9 +2326,9 @@
2098 2326 $filename = substr($filename, 0, strpos($filename, '?'));
2099 2327 }
2100 2328
2101 2329 /* if unsoported extension */
2102 - if(in_array(wdk_file_extension($filename), array('php','asp'))){
2330 + if(in_array(wdk_file_extension($filename), array('php','asp')) || strlen(wdk_file_extension($filename)) > 5){
2103 2331 $data = getimagesizefromstring($response['body']);
2104 2332 if(!$data) return false;
2105 2333 if(empty($data['mime'])) return false;
2106 2334
@@ -2197,17 +2425,12 @@
2197 2425 */
2198 2426
2199 2427 function wdk_generate_profile_permalink($profile = array())
2200 2428 {
2201 -
2202 2429 $profile_slug = '';
2203 - if(wmvc_show_data('user_login', $profile, false)){
2204 - $profile_slug = wmvc_show_data('user_login', $profile);
2205 - if(wmvc_show_data('wdk_slug', $profile))
2206 - $profile_slug = wmvc_show_data('wdk_slug', $profile);
2207 - } else if(is_intval($profile)){
2430 + if(is_intval($profile)){
2208 2431 $profile_data = get_userdata($profile);
2209 - if(wmvc_show_data('wdk_slug', $profile, false)){
2432 + if(wmvc_show_data('wdk_slug', $profile_data, false)){
2210 2433 $profile_slug = wmvc_show_data('wdk_slug', $profile);
2211 2434 }elseif(wmvc_show_data('user_login', $profile_data, false)){
2212 2435 $profile_slug = wmvc_show_data('user_login', $profile_data);
2213 2436 } else {
@@ -2212,10 +2435,14 @@
2212 2435 $profile_slug = wmvc_show_data('user_login', $profile_data);
2213 2436 } else {
2214 2437 $profile_slug = $profile;
2215 2438 }
2216 - }
2217 -
2439 + } else if(wmvc_show_data('user_login', $profile, false)){
2440 + $profile_slug = wmvc_show_data('user_login', $profile);
2441 + if(wmvc_show_data('wdk_slug', $profile))
2442 + $profile_slug = wmvc_show_data('wdk_slug', $profile);
2443 + }
2444 +
2218 2445 $user_profile_page = get_option('wdk_membership_profile_preview_page');
2219 2446 if(!$user_profile_page) {
2220 2447 return '#';
2221 2448 }
@@ -2474,9 +2701,9 @@
2474 2701 <?php echo esc_html__('Select file','wmvc_win') ?>
2475 2702 </a>
2476 2703 <a class="delete-custom-img <?php if ( ! $you_have_file ) { echo 'hidden'; } ?>"
2477 2704 href="#">
2478 - <?php echo esc_html__('Remove file','wmvc_win') ?>
2705 + <?php echo esc_html__('Remove all files','wmvc_win') ?>
2479 2706 </a>
2480 2707 </p>
2481 2708 <?php //endif; ?>
2482 2709
@@ -2543,18 +2770,14 @@
2543 2770 {
2544 2771 static $media_element_counter = 0;
2545 2772
2546 2773 if(!isset($texts['file_select']))$texts['file_select'] = esc_html__('Select file','wmvc_win');
2547 - if(!isset($texts['file_remove']))$texts['file_remove'] = esc_html__('Remove file','wmvc_win');
2774 + if(!isset($texts['file_remove']))$texts['file_remove'] = esc_html__('Remove all files','wmvc_win');
2548 2775
2549 2776 $media_element_counter++;
2550 2777
2551 2778 $img_field = $field_name.'_'.$media_element_counter;
2552 2779
2553 - wp_register_script( 'wpmediaelement_file', WPDIRECTORYKIT_URL . 'admin/js/jquery.wpmediaelement_file.js', array( 'jquery' ), false, false );
2554 - wp_enqueue_script( 'wpmediaelement_file' );
2555 - wp_enqueue_media();
2556 -
2557 2780 wp_enqueue_script( 'wpmediamultiple' );
2558 2781 wp_enqueue_script( 'jquery-ui-mouse' );
2559 2782 wp_enqueue_media();
2560 2783
@@ -2623,9 +2846,12 @@
2623 2846 $('#".esc_js($field_name)."meta-box-id.postbox-upload-multiple').wpMediaMultiple({
2624 2847 frame: {
2625 2848 title: '".esc_js(__('Select or Upload Media Of Your Chosen Persuasion','wpdirectorykit'))."',
2626 2849 button: '".esc_js(__('Use this media','wpdirectorykit'))."',
2627 - }
2850 + },
2851 + library: {
2852 + type: ['application', 'image', 'video']
2853 + },
2628 2854 });
2629 2855 /* order */
2630 2856 var re_order = function(media_element){
2631 2857 var list_media = '';
@@ -2734,8 +2960,52 @@
2734 2960
2735 2961 }
2736 2962 }
2737 2963
2964 +if ( ! function_exists('wdk_recaptcha_field_v3'))
2965 +{
2966 + function wdk_recaptcha_field_v3($wdk_recaptcha_site_key=null, $wdk_recaptcha_secret_key=null, $load_script=true)
2967 + {
2968 + static $counter = 0;
2969 +
2970 + if(empty($wdk_recaptcha_site_key) && empty($wdk_recaptcha_site_key)) {
2971 + $wdk_recaptcha_site_key = get_option('wdk_recaptcha_site_key_v3');
2972 + $wdk_recaptcha_secret_key = get_option('wdk_recaptcha_secret_key_v3');
2973 + }
2974 +
2975 + if($wdk_recaptcha_site_key && $wdk_recaptcha_secret_key)
2976 + {
2977 + if($load_script && $counter===0)
2978 + {
2979 + echo "<script src='https://www.google.com/recaptcha/api.js?render=".esc_attr(trim($wdk_recaptcha_site_key))."'></script>";
2980 + }
2981 + $counter++;
2982 + ?>
2983 + <input type="hidden" name="g-recaptcha-response" id="recaptcha_called_v3_count_<?php echo esc_html($counter);?>">
2984 + <script>
2985 + (function(){
2986 + const field_token = document.getElementById('recaptcha_called_v3_count_<?php echo esc_html($counter);?>');
2987 + grecaptcha.ready(function() {
2988 + grecaptcha.execute('<?php echo esc_attr(trim($wdk_recaptcha_site_key));?>', {action: 'submit'}).then(function(token) {
2989 + field_token.value = token;
2990 + });
2991 + });
2992 +
2993 + // Reload token after form submit
2994 + field_token.closest('form').addEventListener('submit', function(e) {
2995 + e.preventDefault();
2996 + grecaptcha.execute('<?php echo esc_attr(trim($wdk_recaptcha_site_key));?>', {action: 'submit'}).then(function(token) {
2997 + field_token.value = token;
2998 + });
2999 + });
3000 + })();
3001 + </script>
3002 + <?php
3003 + }
3004 + }
3005 +}
3006 +
3007 +
2738 3008 if ( ! function_exists('wdk_recaptcha_field'))
2739 3009 {
2740 3010 function wdk_recaptcha_field($is_compact=false, $style="", $load_script=true)
2741 3011 {
@@ -2759,15 +3029,15 @@
2759 3029 }
2760 3030
2761 3031 $recaptcha_array[$counter] = array('size'=>$size_tag);
2762 3032
2763 - echo '<div id="recaptcha_called_'.$counter.'" class="g-recaptcha" style="'.$style.'" '.$compact_tag.' data-sitekey="'.get_option('wdk_recaptcha_site_key').'"></div>';
3033 + echo '<div id="recaptcha_called_'.$counter.'" class="g-recaptcha" style="'.$style.'" '.$compact_tag.' data-sitekey="'.esc_attr(get_option('wdk_recaptcha_site_key')).'"></div>';
2764 3034 ?>
2765 3035
2766 3036 <script>
2767 3037 <?php if($counter===1)echo 'var ';?>CaptchaCallback = function(){
2768 3038 <?php for($j=1;$j<=$counter;$j++): ?>
2769 - 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'); ?>'});
3039 + grecaptcha.render(document.getElementById('recaptcha_called_<?php echo $j;?>'), {'size' : '<?php echo esc_attr($recaptcha_array[$j]['size']); ?>', 'sitekey' : '<?php echo esc_attr(get_option('wdk_recaptcha_site_key')); ?>'});
2770 3040 <?php endfor; ?>
2771 3041 };
2772 3042 </script>
2773 3043
@@ -2869,9 +3139,9 @@
2869 3139 if(is_array($val))
2870 3140 {
2871 3141 return wdk_clean($_POST);
2872 3142 }
2873 - else
3143 + elseif(is_string($val))
2874 3144 {
2875 3145 if(strpos($val, '<iframe') === 0)
2876 3146 $val = str_replace("'",'"', $val);
2877 3147
@@ -2910,9 +3180,9 @@
2910 3180 if(is_array($val))
2911 3181 {
2912 3182 $arr_cleaned[sanitize_text_field($key)] = wdk_clean($val);
2913 3183 }
2914 - else
3184 + elseif(is_string($val))
2915 3185 {
2916 3186 $arr_cleaned[sanitize_text_field($key)] = wp_kses_post($val);
2917 3187 }
2918 3188
@@ -2922,8 +3192,34 @@
2922 3192
2923 3193 return $arr_cleaned;
2924 3194 }
2925 3195
3196 +function wdk_clean_mixed($item)
3197 +{
3198 + $arr_cleaned = array();
3199 +
3200 + if(is_array($item))
3201 + {
3202 + foreach($item as $key=>$val)
3203 + {
3204 + if(is_array($val))
3205 + {
3206 + $arr_cleaned[sanitize_text_field($key)] = wdk_clean_mixed($val);
3207 + }
3208 + else
3209 + {
3210 + $arr_cleaned[sanitize_text_field($key)] = wp_kses_post($val);
3211 + }
3212 + }
3213 + }
3214 + else
3215 + {
3216 + return wp_kses_post($item);
3217 + }
3218 +
3219 + return $arr_cleaned;
3220 +}
3221 +
2926 3222 /*
2927 3223 <select class="form-control" name="<?php echo 'control_operator_'.$i_fieldnum; ?>">
2928 3224 <option value="CONTAINS">CONTAINS</option>
2929 3225 <option value="NOT_CONTAINS">NOT_CONTAINS</option>
@@ -2993,15 +3289,15 @@
2993 3289
2994 3290 $results = $WMVC->$table->get();
2995 3291 foreach ($results as $item) {
2996 3292 if($item)
2997 - $form .= '<option selected="selected" value="'.esc_attr(wmvc_show_data($column_key, $item, false, TRUE, TRUE)).'">'.esc_html(wmvc_show_data($column_print, $item, false, TRUE, TRUE)).'</option>';
3293 + $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>';
2998 3294 }
2999 3295 }
3000 3296 } elseif(is_intval($selected)) {
3001 3297 $db_item = $WMVC->$table->get($selected, TRUE);
3002 3298 if($db_item)
3003 - $form .= '<option selected="selected" value="'.esc_attr(wmvc_show_data($column_key, $db_item, false, TRUE, TRUE)).'">'.esc_attr(wmvc_show_data($column_print, $db_item, false, TRUE, TRUE)).'</option>';
3299 + $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>';
3004 3300 }
3005 3301 } else {
3006 3302 //$form .= '<option value="" selected="selected">'.esc_html__('Not selected', 'wpdirectorykit').'</option>';
3007 3303 }
@@ -3009,11 +3305,11 @@
3009 3305
3010 3306 //load javascript library
3011 3307 if($counter==0)
3012 3308 {
3013 - wp_enqueue_script('select2');
3309 + wp_enqueue_script('select2-select2');
3014 3310 wp_enqueue_script('wdk-select2');
3015 - wp_enqueue_style('select2');
3311 + wp_enqueue_style('select2-select2');
3016 3312 }
3017 3313 ?>
3018 3314 <?php
3019 3315 $counter++;
@@ -3057,11 +3353,11 @@
3057 3353
3058 3354 //load javascript library
3059 3355 if($counter==0)
3060 3356 {
3061 - wp_enqueue_script('select2');
3357 + wp_enqueue_script('select2-select2');
3062 3358 wp_enqueue_script('wdk-select2');
3063 - wp_enqueue_style('select2');
3359 + wp_enqueue_style('select2-select2');
3064 3360 }
3065 3361 ?>
3066 3362 <?php
3067 3363 $counter++;
@@ -3139,11 +3435,30 @@
3139 3435 'r'=>'llll',
3140 3436 'u'=>'x',
3141 3437 );
3142 3438
3143 - $replaced_from = array_keys($replaced);
3144 - $date_format = str_replace($replaced_from, array_keys($replaced_from), $date_format);
3145 - return str_replace(array_reverse(array_keys($replaced_from)), array_reverse($replaced), $date_format);
3439 +
3440 + $result = '';
3441 + $escaped = false;
3442 + $length = strlen($date_format);
3443 +
3444 + for ($i = 0; $i < $length; $i++) {
3445 + $char = $date_format[$i];
3446 +
3447 + if ($char === '\\') {
3448 + $escaped = true;
3449 + continue;
3450 + }
3451 +
3452 + if ($escaped) {
3453 + $result .= "'".$char."'";
3454 + $escaped = false;
3455 + } else {
3456 + $result .= isset($replaced[$char]) ? $replaced[$char] : $char;
3457 + }
3458 + }
3459 +
3460 + return str_replace("''", '',$result);
3146 3461 }
3147 3462 }
3148 3463
3149 3464 if ( ! function_exists('wdk_convert_date_format_jquery'))
@@ -3184,11 +3499,29 @@
3184 3499 'u'=>'@',
3185 3500 ':'=>'',
3186 3501 );
3187 3502
3188 - $replaced_from = array_keys($replaced);
3189 - $date_format = str_replace($replaced_from, array_keys($replaced_from), $date_format);
3190 - return str_replace(array_reverse(array_keys($replaced_from)), array_reverse($replaced), $date_format);
3503 + $result = '';
3504 + $escaped = false;
3505 + $length = strlen($date_format);
3506 +
3507 + for ($i = 0; $i < $length; $i++) {
3508 + $char = $date_format[$i];
3509 +
3510 + if ($char === '\\') {
3511 + $escaped = true;
3512 + continue;
3513 + }
3514 +
3515 + if ($escaped) {
3516 + $result .= "'".$char."'";
3517 + $escaped = false;
3518 + } else {
3519 + $result .= isset($replaced[$char]) ? $replaced[$char] : $char;
3520 + }
3521 + }
3522 +
3523 + return str_replace("''", '',$result);
3191 3524 }
3192 3525 }
3193 3526
3194 3527 if ( ! function_exists('wdk_convert_date_format_jquery'))
@@ -3229,11 +3562,31 @@
3229 3562 'u'=>'@',
3230 3563 ':'=>'',
3231 3564 );
3232 3565
3233 - $replaced_from = array_keys($replaced);
3234 - $date_format = str_replace($replaced_from, array_keys($replaced_from), $date_format);
3235 - return str_replace(array_reverse(array_keys($replaced_from)), array_reverse($replaced), $date_format);
3566 +
3567 + $result = '';
3568 + $escaped = false;
3569 + $length = strlen($date_format);
3570 +
3571 + for ($i = 0; $i < $length; $i++) {
3572 + $char = $date_format[$i];
3573 +
3574 + if ($char === '\\') {
3575 + $escaped = true;
3576 + continue;
3577 + }
3578 +
3579 + if ($escaped) {
3580 + $result .= "'".$char."'";
3581 + $escaped = false;
3582 + } else {
3583 + $result .= isset($replaced[$char]) ? $replaced[$char] : $char;
3584 + }
3585 + }
3586 +
3587 + return str_replace("''", '',$result);
3588 +
3236 3589 }
3237 3590 }
3238 3591
3239 3592 if ( ! function_exists('wdk_get_gps'))
@@ -3261,9 +3614,17 @@
3261 3614
3262 3615 if(!isset($results[$address])) {
3263 3616 $results[$address] = NULL;
3264 3617 $url = 'https://nominatim.openstreetmap.org/search?format=json&q=' . $address;
3265 - $request = wp_remote_get( $url );
3618 +
3619 + // Add required User-Agent header
3620 + $args = [
3621 + 'timeout' => 10,
3622 + 'headers' => [
3623 + 'User-Agent' => get_bloginfo('name') . '/1.0 (' . get_bloginfo('admin_email') . ')',
3624 + ],
3625 + ];
3626 + $request = wp_remote_get( $url, $args);
3266 3627 $response = '';
3267 3628
3268 3629 // request failed
3269 3630 if ( is_wp_error( $request ) ) {
@@ -3419,8 +3780,32 @@
3419 3780 return false;
3420 3781 }
3421 3782 }
3422 3783
3784 +if ( ! function_exists('is_wdk_whatsapp'))
3785 +{
3786 + // Validation phone
3787 + /**
3788 + * @param string $value phone in string
3789 + * @return bool
3790 + */
3791 + function is_wdk_whatsapp($value = '') {
3792 + return true;
3793 + }
3794 +}
3795 +
3796 +if ( ! function_exists('is_wdk_viber'))
3797 +{
3798 + // Validation phone
3799 + /**
3800 + * @param string $value phone in string
3801 + * @return bool
3802 + */
3803 + function is_wdk_viber($value = '') {
3804 + return true;
3805 + }
3806 +}
3807 +
3423 3808 if ( ! function_exists('wdk_filter_phone'))
3424 3809 {
3425 3810 // Validation phone
3426 3811 /**
@@ -3556,9 +3941,12 @@
3556 3941
3557 3942 $value = filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
3558 3943 $value = (float)str_replace(array(","," ",'&nbsp;'), "", $value);
3559 3944
3560 - return number_format_i18n($value);
3945 + // Allow decimal precision to be filtered (default is 0)
3946 + $decimals = apply_filters('wdk_number_format_decimals', ((wdk_get_option('wdk_number_format_decimals')) ? wdk_get_option('wdk_number_format_decimals') : 0));
3947 +
3948 + return number_format_i18n($value, $decimals);
3561 3949 }
3562 3950 }
3563 3951
3564 3952 if ( ! function_exists('wdk_currency_symbol'))
@@ -3691,9 +4079,20 @@
3691 4079 $user_data['wdk_position_title'] = wmvc_show_data('cacheduser_wdk_position_title', $row);
3692 4080 $user_data['agency_name'] = wmvc_show_data('cacheduser_agency_name', $row);
3693 4081 $user_data['description'] = wmvc_show_data('cacheduser_description', $row);
3694 4082 $user_data['user_url'] = wmvc_show_data('cacheduser_user_url', $row);
3695 - $user_data['roles'] = explode(',', wmvc_show_data('cacheduser_roles', $value));
4083 + $user_data['roles'] = explode(',', wmvc_show_data('cacheduser_roles', $row));
4084 + $user_data['wdk_slug'] = wmvc_show_data('cacheduser_wdk_slug', $row);
4085 + $user_data['user_login'] = wmvc_show_data('cacheduser_user_login', $row);
4086 + $user_data['user_id'] = wmvc_show_data('cacheduser_user_id', $row);
4087 +
4088 + if(function_exists('wdk_generate_profile_permalink') && $user_data['profile_url'] == '#') {
4089 + if($user_data['user_login']) {
4090 + $user_data['profile_url'] = wdk_generate_profile_permalink($user_data);
4091 + } else {
4092 + $user_data['profile_url'] = wdk_generate_profile_permalink(wmvc_show_data('user_id', $user_data));
4093 + }
4094 + }
3696 4095
3697 4096 return $user_data;
3698 4097 }
3699 4098 }
@@ -4257,5 +4656,654 @@
4257 4656 return false;
4258 4657 }
4259 4658 }
4260 4659
4660 +
4661 +/**
4662 + * Check is listing preview page exits
4663 + *
4664 + * @return bool
4665 +*/
4666 +if ( ! function_exists('replace_smart_data'))
4667 +{
4668 + function replace_smart_data($output = '', $replace_data = array()) {
4669 + // Match all occurrences of the pattern
4670 + if (preg_match_all('/\{([^}]+)\}/', $output, $matches)) {
4671 + foreach ($matches[1] as $key => $value) {
4672 + foreach ($replace_data as $replace_key => $replace_value) {
4673 + $output = str_replace('{'.$replace_key.'}', $replace_value, $output);
4674 + }
4675 + }
4676 + }
4677 + return $output;
4678 + }
4679 +}
4680 +
4681 +if ( ! function_exists('wdk_generate_missing_image_sizes'))
4682 +{
4683 + /**
4684 + * Wdk_generate_missing_image_sizes and update meta
4685 + * @param int $attachment_id of iamge
4686 + * @param string $size_name size of image based on wp intermediate_size
4687 + *
4688 + * @return bool
4689 + */
4690 + function wdk_generate_missing_image_sizes($attachment_id, $size_name = '') {
4691 + if(empty($size_name) || $size_name == 'full' || !get_option( "{$size_name}_size_w" )) {
4692 + return true;
4693 + }
4694 +
4695 + // Check if the attachment is an image
4696 + if (!wp_attachment_is_image($attachment_id)) {
4697 + return false;
4698 + }
4699 +
4700 + $file = get_attached_file( $attachment_id );
4701 + require_once(ABSPATH . "wp-admin" . '/includes/image.php');
4702 + $metadata = wp_generate_attachment_metadata($attachment_id, $file);
4703 + if ( ! isset( $metadata['sizes'][ $size_name ] ) ) {
4704 + // Generate the missing image size
4705 + $resized = image_make_intermediate_size( $file, get_option( "{$size_name}_size_w" ), get_option( "{$size_name}_size_h" ), get_option( "{$size_name}_crop" ) );
4706 +
4707 + // If the resizing was successful, add it to the metadata
4708 + if ( $resized ) {
4709 + $metadata['sizes'][ $size_name ] = $resized;
4710 + wp_update_attachment_metadata( $attachment_id, $metadata );
4711 + }
4712 + }
4713 + return true;
4714 + }
4715 +}
4716 +
4717 +if (!function_exists('wdk_get_languages')) {
4718 +
4719 + function wdk_get_languages($lang_code_id = null)
4720 + {
4721 + $lang_pattern = ['title' => '', 'lang_code' => '', 'id' => '', 'icon' => '', 'url' => ''];
4722 + $languages = [];
4723 +
4724 + // [qTranslate X]
4725 + if (function_exists('qtranxf_getSortedLanguages')) {
4726 + global $q_config;
4727 +
4728 + if (empty($q_config)) {
4729 + // Initialize qTranslate X language settings if needed
4730 + // qtranxf_init_language();
4731 + }
4732 +
4733 + $all_langs = qtranxf_getSortedLanguages();
4734 + if (count($all_langs) > 0) {
4735 + foreach ($all_langs as $key => $lang_code) {
4736 + $languages[$key + 1] = array_merge(
4737 + $lang_pattern,
4738 + [
4739 + 'title' => $q_config['language_name'][$lang_code],
4740 + 'lang_code' => $lang_code,
4741 + 'id' => $key + 1,
4742 + 'icon' => '',
4743 + 'url' => wdk_get_language_url($lang_code),
4744 + ]
4745 + );
4746 + }
4747 + }
4748 + }
4749 + // [/qTranslate X]
4750 +
4751 + // [WPML]
4752 + if (function_exists('icl_get_languages')) {
4753 + $wpml_langs = icl_get_languages('orderby=KEY&order=DIR&link_empty_to=str');
4754 + $k = 1;
4755 + foreach ($wpml_langs as $key => $lang_data) {
4756 + $languages[$k] = array_merge(
4757 + $lang_pattern,
4758 + [
4759 + 'title' => (!empty($lang_data['translated_name'])) ? $lang_data['translated_name'] : $lang_data['native_name'],
4760 + 'lang_code' => $lang_data['language_code'],
4761 + 'id' => $k,
4762 + 'icon' => (!empty($lang_data['country_flag_url'])) ? $lang_data['country_flag_url'] : WPDIRECTORYKIT_URL.'public/img/flags/'.$lang_data['language_code'].'.png',
4763 + 'url' => wdk_get_language_url($lang_data['language_code']),
4764 + ]
4765 + );
4766 + $k++;
4767 + }
4768 + } elseif (has_filter('wpml_active_languages')) {
4769 + $wpml_langs = apply_filters('wpml_active_languages', null) ?: get_query_var('lang', 'all');
4770 + if (is_array($wpml_langs)) {
4771 + foreach ($wpml_langs as $lang_data) {
4772 + if (!isset($lang_data['code']) && isset($lang_data['language_code'])) {
4773 + $lang_data['code'] = $lang_data['language_code'];
4774 + }
4775 + if (empty($lang_data['translated_name']) && !empty($lang_data['native_name'])) {
4776 + $lang_data['translated_name'] = $lang_data['native_name'];
4777 + }
4778 + $languages[$lang_data['id']] = array_merge(
4779 + $lang_pattern,
4780 + [
4781 + 'title' => (!empty($lang_data['translated_name'])) ? $lang_data['translated_name'] : $lang_data['native_name'],
4782 + 'lang_code' => $lang_data['code'],
4783 + 'id' => $lang_data['id'],
4784 + 'icon' => (!empty($lang_data['country_flag_url'])) ? $lang_data['country_flag_url'] : WPDIRECTORYKIT_URL.'public/img/flags/'.$lang_data['language_code'].'.png',
4785 + 'url' => wdk_get_language_url($lang_data['code']),
4786 + ]
4787 + );
4788 + }
4789 + }
4790 + }
4791 + // [/WPML]
4792 +
4793 + // [TranslatePress]
4794 + if (function_exists('trp_custom_language_switcher')) {
4795 + $k = 1;
4796 + foreach (trp_custom_language_switcher() as $lang_data) {
4797 + $languages[$k++] = array_merge(
4798 + $lang_pattern,
4799 + [
4800 + 'title' => $lang_data['language_name'],
4801 + 'lang_code' => $lang_data['language_code'],
4802 + 'id' => $k,
4803 + 'icon' => $lang_data['flag_link'],
4804 + 'url' => $lang_data['current_page_url'],
4805 + ]
4806 + );
4807 + }
4808 + }
4809 + // [/TranslatePress]
4810 +
4811 + if (!empty($lang_code_id)) {
4812 + foreach ($languages as $lang) {
4813 + if (($lang['id'] == $lang_code_id) || ($lang['lang_code'] == $lang_code_id)) {
4814 + return $lang['id'] == $lang_code_id ? $lang['lang_code'] : $lang['id'];
4815 + }
4816 + }
4817 + return false;
4818 + }
4819 +
4820 + return $languages;
4821 + }
4822 +}
4823 +
4824 +if (!function_exists('wdk_default_language')) {
4825 + function wdk_default_language()
4826 + {
4827 + // [qTranslate X]
4828 + if (function_exists('qtranxf_getLanguageDefault')) {
4829 + return qtranxf_getLanguageDefault();
4830 + }
4831 + // [/qTranslate X]
4832 +
4833 + // [WPML]
4834 + if (function_exists('icl_get_languages')) {
4835 + $wpml_langs = icl_get_languages('orderby=KEY&order=DIR&link_empty_to=str');
4836 + foreach ($wpml_langs as $lang_data) {
4837 + if ($lang_data['major'] == 1) {
4838 + return $lang_data['code'];
4839 + }
4840 + }
4841 + } elseif (has_filter('wpml_default_language')) {
4842 + return apply_filters('wpml_default_language', null);
4843 + }
4844 + // [/WPML]
4845 +
4846 + return 'en';
4847 + }
4848 +}
4849 +
4850 +if (!function_exists('wdk_current_language')) {
4851 + function wdk_current_language()
4852 + {
4853 + if (function_exists('trp_get_languages')) {
4854 + global $TRP_LANGUAGE;
4855 + $trp = TRP_Translate_Press::get_trp_instance();
4856 + $settings = $trp->get_component('settings')->get_settings();
4857 + $translation_languages = $trp->get_component('languages')->get_language_names($settings['publish-languages']);
4858 + if (isset($translation_languages[$TRP_LANGUAGE])) {
4859 + return $translation_languages[$TRP_LANGUAGE];
4860 + }
4861 + }
4862 +
4863 + // [qTranslate X]
4864 + if (function_exists('qtranxf_getLanguage')) {
4865 + return qtranxf_getLanguage();
4866 + }
4867 + // [/qTranslate X]
4868 +
4869 + // [WPML]
4870 + if (function_exists('icl_get_languages')) {
4871 + $wpml_langs = icl_get_languages('orderby=KEY&order=DIR&link_empty_to=str');
4872 + foreach ($wpml_langs as $lang_data) {
4873 + if ($lang_data['active'] == 1) {
4874 + return (!empty($lang_data['native_name'])) ? $lang_data['native_name'] : $lang_data['language_code'];
4875 + }
4876 + }
4877 + } elseif (has_filter('wpml_current_language')) {
4878 + return apply_filters('wpml_current_language', null);
4879 + }
4880 + // [/WPML]
4881 +
4882 + return 'en';
4883 + }
4884 +}
4885 +
4886 +if (!function_exists('wdk_current_language_id')) {
4887 + function wdk_current_language_id()
4888 + {
4889 + $lang_id = wdk_get_languages(wdk_current_language());
4890 + return is_numeric($lang_id) ? $lang_id : wdk_default_language_id();
4891 + }
4892 +}
4893 +
4894 +if (!function_exists('wdk_default_language_id')) {
4895 + function wdk_default_language_id()
4896 + {
4897 + $lang_id = wdk_get_languages(wdk_default_language());
4898 + return is_numeric($lang_id) ? $lang_id : '1';
4899 + }
4900 +}
4901 +
4902 +if (!function_exists('wdk_get_language_name')) {
4903 + function wdk_get_language_name($id_or_code)
4904 + {
4905 + $langs = wdk_get_languages();
4906 + foreach ($langs as $lang) {
4907 + if ($lang['lang_code'] == $id_or_code || $lang['id'] == $id_or_code) {
4908 + return $lang['title'];
4909 + }
4910 + }
4911 + return '';
4912 + }
4913 +}
4914 +
4915 +if (!function_exists('wdk_get_language_url')) {
4916 + function wdk_get_language_url($lang_code)
4917 + {
4918 + // [qTranslate X]
4919 + if (function_exists('qtranxf_convertURL')) {
4920 + return qtranxf_convertURL('', $lang_code, false, true);
4921 + }
4922 + // [/qTranslate X]
4923 +
4924 + // [WPML]
4925 + if (function_exists('icl_get_languages')) {
4926 + $wpml_langs = icl_get_languages('orderby=KEY&order=DIR&link_empty_to=str');
4927 + foreach ($wpml_langs as $lang_data) {
4928 + if ($lang_data['language_code'] == $lang_code) {
4929 + return $lang_data['url'];
4930 + }
4931 + }
4932 + } elseif (has_filter('wpml_active_languages')) {
4933 + $wpml_langs = apply_filters('wpml_active_languages', null);
4934 + foreach ($wpml_langs as $lang_data) {
4935 + if (!isset($lang_data['language_code']) && isset($lang_data['language_code'])) {
4936 + $lang_data['language_code'] = $lang_data['language_code'];
4937 + }
4938 + if (empty($lang_data['translated_name']) && !empty($lang_data['native_name'])) {
4939 + $lang_data['translated_name'] = $lang_data['native_name'];
4940 + }
4941 + $url = wdk_wpml_ls_language_url($lang_data['url'], $lang_data);
4942 + if ($lang_data['language_code'] == $lang_code) {
4943 + return $url;
4944 + }
4945 + }
4946 + }
4947 + // [/WPML]
4948 +
4949 + return '';
4950 + }
4951 +}
4952 +
4953 +function wdk_set_user_default_language($user_id = null)
4954 +{
4955 + if (is_null($user_id)) {
4956 + $user_id = get_current_user_id();
4957 + }
4958 +
4959 + $get_language = get_user_meta($user_id, 'user_language', true);
4960 +
4961 + if (!$get_language && (function_exists('icl_get_languages') || has_filter('wpml_active_languages'))) {
4962 + do_action('wpml_switch_language', $get_language);
4963 + }
4964 +}
4965 +
4966 +function wdk_set_language($lang_code = null)
4967 +{
4968 + if (!is_null($lang_code) && (function_exists('icl_get_languages') || has_filter('wpml_active_languages'))) {
4969 + do_action('wpml_switch_language', $lang_code);
4970 + }
4971 +}
4972 +
4973 +function wdk_wpml_ls_language_url($url, $data)
4974 +{
4975 + global $sitepress;
4976 +
4977 + if (is_object($sitepress)) {
4978 + $sitepress_settings = $sitepress->get_settings();
4979 + }
4980 +
4981 + return $url;
4982 +}
4983 +
4984 +add_filter('wpml_ls_language_url', 'wdk_wpml_ls_language_url', 10, 3);
4985 +
4986 +if (!function_exists('wdk_calculate_nights')) {
4987 + /**
4988 + * Calculate the number of nights between two dates
4989 + *
4990 + * This function takes two date strings as input and calculates the number of nights
4991 + * (i.e., the difference in days) between them. It returns the total number of nights
4992 + * between the provided start and end dates. The date format must be valid for PHP's
4993 + * DateTime class.
4994 + *
4995 + * @param string $start_date The start date in 'Y-m-d' format.
4996 + * @param string $end_date The end date in 'Y-m-d' format.
4997 + * @return int The number of nights (days between the two dates).
4998 + */
4999 + function wdk_calculate_nights($start_date, $end_date) {
5000 +
5001 + /* normalize date */
5002 + $start_date = wdk_normalize_date_db($start_date, 'Y-m-d H:i:s', 'Y-m-d');
5003 + $end_date = wdk_normalize_date_db($end_date, 'Y-m-d H:i:s', 'Y-m-d');
5004 +
5005 + // Create DateTime objects for start and end dates
5006 + $start = new DateTime($start_date);
5007 + $end = new DateTime($end_date);
5008 +
5009 + // Calculate the difference between the two dates
5010 + $difference = $start->diff($end);
5011 +
5012 + // Return the number of nights (difference in days)
5013 + return $difference->days;
5014 + }
5015 +}
5016 +
5017 +if ( ! function_exists('wdk_select_db_field_ajax'))
5018 +{
5019 + /**
5020 + * Return select2 ajax
5021 + *
5022 + * @param string option Option key
5023 + * @return string alt or title
5024 + */
5025 + function wdk_select_db_field_ajax($name = '', $selected = NULL, $empty_value='', $filter_id = '')
5026 + {
5027 + $WMVC = &wdk_get_instance();
5028 +
5029 + static $counter = 0;
5030 + $form = '<select data-ajax="'.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="">';
5031 + if($selected) {
5032 + if(is_array($selected)) {
5033 + /* where in */
5034 + foreach ($selected as $item) {
5035 + $form .= '<option selected="selected" value="'.esc_attr($item).'">'.esc_html($item).'</option>';
5036 + }
5037 + } elseif(is_string($selected)) {
5038 + $form .= '<option selected="selected" value="'.esc_attr($selected).'">'.esc_html($selected).'</option>';
5039 + }
5040 + } else {
5041 + //$form .= '<option value="" selected="selected">'.esc_html__('Not selected', 'wpdirectorykit').'</option>';
5042 + }
5043 + $form .= '</select>';
5044 +
5045 + //load javascript library
5046 + if($counter==0)
5047 + {
5048 + wp_enqueue_script('select2-select2');
5049 + wp_enqueue_script('wdk-select2');
5050 + wp_enqueue_style('select2-select2');
5051 + }
5052 + ?>
5053 + <?php
5054 + $counter++;
5055 + return $form;
5056 +
5057 + }
5058 +}
5059 +
5060 +if ( ! function_exists('wdk_next_month_payment_day'))
5061 +{
5062 + /**
5063 + * Gets the next payment date one month later, considering the number of days in the next month.
5064 + *
5065 + * @param string $currentDate The current payment date in 'Y-m-d H:i:s' format.
5066 + * @return string|false The next payment date in 'Y-m-d H:i:s' format or false on error.
5067 + */
5068 + function wdk_next_month_payment_day($currentDate, $time = false, $wanted_day = NULL) {
5069 + $nextDate = null;
5070 + $timestamp = strtotime($currentDate);
5071 + $daysInNextMonth = date('t', strtotime('+1 month', strtotime(date('Y-m', $timestamp))));
5072 + $currentDay = (int)date('d', $timestamp);
5073 +
5074 + $timeFormat = $time ? "H:i:s" : "00:00:00";
5075 +
5076 +
5077 + // Determine the wanted day
5078 + if ($wanted_day !== NULL) {
5079 + $wanted_day = (int)date('d', strtotime($wanted_day));
5080 + } else {
5081 + $wanted_day = (int)date('d', $timestamp);
5082 + }
5083 +
5084 + $nextMonth = strtotime('first day of next month', $timestamp);
5085 + $daysInNextMonth = date('t', $nextMonth);
5086 +
5087 + // Adjust for the wanted day
5088 + if ($wanted_day > $daysInNextMonth ||
5089 + (
5090 + get_option('wdk_membership_next_month_calculation_with_last_day')
5091 +
5092 + && (
5093 + $currentDay >= 30 || $currentDay == date('t', $timestamp)
5094 + )
5095 + )
5096 + ) {
5097 + // If the wanted day exceeds the max days of the next month, use the last day of the month
5098 + $nextDate = date("Y-m-{$daysInNextMonth} {$timeFormat}", $nextMonth);
5099 + } else {
5100 + // Otherwise, set the exact wanted day
5101 + $nextDate = date("Y-m-{$wanted_day} {$timeFormat}", $nextMonth);
5102 + }
5103 +
5104 + return ($nextDate) ? $nextDate : false;
5105 + }
5106 +}
5107 +
5108 +if ( ! function_exists('wdk_next_year_payment_day'))
5109 +{
5110 + /**
5111 + * Gets the next payment date one year later, considering the number of days in the next month.
5112 + *
5113 + * @param string $currentDate The current payment date in 'Y-m-d H:i:s' format.
5114 + * @return string|false The next payment date in 'Y-m-d H:i:s' format or false on error.
5115 + */
5116 +
5117 + function wdk_next_year_payment_day($currentDate, $time = false) {
5118 + $nextDate = null;
5119 + $timestamp = strtotime($currentDate);
5120 + $nextYearTimestamp = strtotime('+1 year', strtotime(date('Y-m', $timestamp)));
5121 + $daysInNextMonth = date('t', $nextYearTimestamp);
5122 + $currentDay = date('j', $timestamp);
5123 + $timeFormat = "00:00:00";
5124 + if($time) {
5125 + $timeFormat = "H:i:s";
5126 + }
5127 + if ($currentDay > $daysInNextMonth) {
5128 + $nextDate = date('Y-m-d '.$timeFormat, strtotime('last day of this month', $nextYearTimestamp));
5129 + } else {
5130 + $nextDate = date('Y-m-d '.$timeFormat, strtotime('+1 year', $timestamp));
5131 + }
5132 +
5133 + return ($nextDate) ? $nextDate : false;
5134 + }
5135 +}
5136 +
5137 +if ( ! function_exists('wdk_generate_auto_login_link'))
5138 +{
5139 + function wdk_generate_auto_login_link( $user_id = null ) {
5140 + $token = substr(md5($user_id.NONCE_KEY.'wpdirectorykit'),0,10);
5141 +
5142 + $login_url = site_url( "/?auto-login=1&user_id={$user_id}&token={$token}" );
5143 + return $login_url;
5144 + }
5145 +}
5146 +
5147 +if ( ! function_exists('wdk_get_user_subscription_id'))
5148 +{
5149 + function wdk_get_user_subscription_id($user_id = null) {
5150 + global $Winter_MVC_wdk_membership;
5151 + if(!isset($Winter_MVC_wdk_membership)) {
5152 + return false;
5153 + }
5154 + $Winter_MVC_wdk_membership->model('subscription_user_m');
5155 + $user_subscription = $Winter_MVC_wdk_membership->subscription_user_m->get_by(array('user_id'=>$user_id), TRUE);
5156 + return wmvc_show_data('subscription_id', $user_subscription, '', TRUE, TRUE);
5157 + }
5158 +}
5159 +
5160 +if ( ! function_exists('is_wdk_related_validation'))
5161 + /**
5162 + * IS WDK related validation
5163 + *
5164 + * @return bool true if exists dash
5165 + */
5166 + {
5167 + function is_wdk_related_validation($param)
5168 + {
5169 +
5170 + if(empty($param)) {
5171 + return TRUE;
5172 + }
5173 +
5174 + $listing_id = (!empty($_GET['id'])) ? intval(sanitize_text_field($_GET['id'])) : null;
5175 +
5176 +
5177 + global $Winter_MVC_WDK;
5178 + $Winter_MVC_WDK->model('listing_m');
5179 +
5180 + $Winter_MVC_WDK->db->select('post_id');
5181 + $Winter_MVC_WDK->db->where(array(
5182 + '(post_id IN ('.esc_sql(sanitize_text_field($param)).'))' => NULL,
5183 + '((`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,
5184 + ));
5185 +
5186 + if($listing_id) {
5187 + $Winter_MVC_WDK->db->where(array(
5188 + '`listing_parent_post_id` !='.esc_sql($listing_id).'' => NULL,
5189 + ));
5190 + }
5191 +
5192 + $Winter_MVC_WDK->db->from($Winter_MVC_WDK->listing_m->_table_name);
5193 + $Winter_MVC_WDK->db->limit(5);
5194 +
5195 + $Winter_MVC_WDK->db->get();
5196 + if ($Winter_MVC_WDK->db->num_rows() > 0) {
5197 + $db_results = $Winter_MVC_WDK->db->results();
5198 + } else {
5199 + $db_results = null;
5200 + }
5201 +
5202 + if (!empty($db_results)) {
5203 + return false;
5204 + }
5205 +
5206 + return TRUE;
5207 + }
5208 + }
5209 +
5210 + /**
5211 + * Renders an Elementor template by its title or post ID.
5212 + *
5213 + * Attempts to find and render an Elementor layout/template using the post title or post ID.
5214 + * If the post is found and public, its rendered Elementor content is returned, otherwise post content fallback or error.
5215 + *
5216 + * @since 1.0.0
5217 + * @param string|int $title The title (or ID if $id=true) of the Elementor template to render.
5218 + * @param bool $id Optional. If true, $title is treated as a post ID. If false (default), searches by title.
5219 + * @return string|false Rendered template HTML on success, public/content fallback, or error message/false on failure.
5220 + */
5221 + function wdk_render_elementor_template( $title, $id = false ) {
5222 + // Initialize variables.
5223 + $layout_id = null;
5224 + $template_content = '';
5225 +
5226 + // Determine the layout/post ID.
5227 + if ( ! $id ) {
5228 + // Search by post title. Returns WP_Post/object or null.
5229 + $found_post = wdk_page_by_title( $title, OBJECT, ['elementor_library','page'] );
5230 + $layout_id = $found_post ? $found_post->ID : null;
5231 +
5232 + // Support WPML translation if present.
5233 + // The filter may change $layout_id to a translated post's ID if needed.
5234 + $layout_id = apply_filters( 'wpml_object_id', $layout_id, 'elementor_library', true );
5235 + } else {
5236 + // ID provided directly.
5237 + $layout_id = intval($title);
5238 + }
5239 +
5240 + // Early return if no valid layout found.
5241 + if ( empty( $layout_id ) ) {
5242 + return false;
5243 + }
5244 +
5245 + // Get post object (Elementor template or WP Page).
5246 + $post_data = get_post( $layout_id );
5247 +
5248 +
5249 + // Validate post: should exist, be published, and not password protected.
5250 + if ( ! $post_data || $post_data->post_status !== 'publish' || post_password_required( $post_data ) ) {
5251 + return esc_html__( 'Layout is not public', 'wpdirectorykit' );
5252 + }
5253 +
5254 + // Render content depending on post type.
5255 + if (
5256 + ( isset($post_data->post_type) && $post_data->post_type === 'elementor_library' ) ||
5257 + ( isset($post_data->post_type) && $post_data->post_type === 'page' )
5258 + ) {
5259 + // Try to render using Elementor's frontend builder.
5260 + if ( class_exists('\Elementor\Plugin') && method_exists('\Elementor\Plugin', 'instance') ) {
5261 + $elementor_instance = \Elementor\Plugin::instance();
5262 + $content = $elementor_instance->frontend->get_builder_content_for_display( $layout_id );
5263 + $template_content = ! empty( $content ) ? $content : $post_data->post_content;
5264 + } else {
5265 + // Elementor not present; fallback to post content.
5266 + $template_content = $post_data->post_content;
5267 + }
5268 + } else {
5269 + // Non-Elementor post types, fallback to post content.
5270 + $template_content = $post_data->post_content;
5271 + }
5272 +
5273 + /**
5274 + * Filter: Allows modification of the rendered Elementor template content before returning.
5275 + *
5276 + * @param string $template_content The rendered template content.
5277 + * @param int $layout_id The ID of the layout/template.
5278 + * @param WP_Post $post_data The WP_Post object of the layout/template.
5279 + */
5280 + return apply_filters( 'wdk_render_elementor_template_output', $template_content, $layout_id, $post_data );
5281 + }
5282 +
5283 + if(!function_exists('wdk_esc_sql')) {
5284 + function wdk_esc_sql ($value = '') {
5285 + return esc_sql(trim(preg_replace([
5286 + '/\bselect\b/i',
5287 + '/\binsert\b/i',
5288 + '/\bupdate\b/i',
5289 + '/\bdelete\b/i',
5290 + '/\bunion\b/i',
5291 + '/\bextractvalue\b/i',
5292 + '/\bversion\s*\(\)/i',
5293 + '/\bdatabase\s*\(\)/i',
5294 + '/\bconcat\s*\(/i',
5295 + '/\bdrop\b/i',
5296 + '/\bsleep\s*\(/i',
5297 + '/\bbenchmark\s*\(/i',
5298 + '/--/',
5299 + '/#/i',
5300 + '/\/\*/',
5301 +
5302 + // EXTRA BLOCK YOU REQUESTED
5303 + '/\\\\/', // remove backslash \
5304 + '/\|/', // remove |
5305 + '/%/', // remove %
5306 + ], '', sanitize_text_field($value))));
5307 + }
5308 + }
4261 5309 ?>