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 +1097 -99 1.3.31.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 }
@@ -1704,12 +1832,12 @@
1704 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>
1705 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' />
1706 1834 </div>
1707 1835 <div class="wdk-field-group wdk-field-group-reset">
1708 - <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>
1709 1837 </div>
1710 1838 <div class="wdk-field-group wdk-field-group-search">
1711 - <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>
1712 1840
1713 1841 <?php if(function_exists('run_wdk_save_search') && get_option('wdk_save_search_show_on_searchform')):?>
1714 1842 <div class="section-widget-control right">
1715 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">
@@ -1780,8 +1908,9 @@
1780 1908 ajax_param: {
1781 1909 "page": 'wdk_frontendajax',
1782 1910 "function": 'treefieldid',
1783 1911 "action": 'wdk_public_action',
1912 + "wdk_secure": '<?php echo wp_create_nonce( 'wdk_secure_treefieldid' );?>',
1784 1913 "table": '<?php echo esc_js($table); ?>',
1785 1914 "filter_ids": '<?php echo esc_js($filter_ids); ?>',
1786 1915 "start_id": '<?php if(!empty($filter_ids)) esc_js($selected); else echo ""; ?>',
1787 1916 "empty_value": '<?php echo esc_js($empty_value); ?>',
@@ -1889,8 +2018,9 @@
1889 2018 ajax_param: {
1890 2019 "page": 'wdk_frontendajax',
1891 2020 "function": 'treefieldid_checkboxes',
1892 2021 "action": 'wdk_public_action',
2022 + "wdk_secure": '<?php echo wp_create_nonce( 'wdk_secure_treefieldid_checkboxes' );?>',
1893 2023 "table": '<?php echo esc_js($table); ?>',
1894 2024 "filter_ids": '<?php echo esc_js($filter_ids); ?>',
1895 2025 "empty_value": '<?php echo esc_js($empty_value); ?>',
1896 2026 "user_check": '<?php echo esc_js($user_check); ?>',
@@ -1919,14 +2049,19 @@
1919 2049 if ( ! function_exists('wdk_filter_decimal'))
1920 2050 {
1921 2051 function wdk_filter_decimal($string = '')
1922 2052 {
1923 - if(substr($string, -3, 3) === ".00") {
1924 - return substr($string, 0, -3);
1925 - }
1926 - if(substr($string, -3, 1) === "." && substr($string, -1, 1) === "0") {
1927 - return substr($string, 0, -1);
1928 - }
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 + }
1929 2064
1930 2065 return $string;
1931 2066 }
1932 2067 }
@@ -2076,9 +2211,100 @@
2076 2211 return $base_url.$extension_url;
2077 2212 }
2078 2213 }
2079 2214
2215 +
2080 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 +/**
2081 2307 * Insert an attachment from an URL address.
2082 2308 *
2083 2309 * @param String $url
2084 2310 * @param Int $parent_post_id
@@ -2100,9 +2326,9 @@
2100 2326 $filename = substr($filename, 0, strpos($filename, '?'));
2101 2327 }
2102 2328
2103 2329 /* if unsoported extension */
2104 - 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){
2105 2331 $data = getimagesizefromstring($response['body']);
2106 2332 if(!$data) return false;
2107 2333 if(empty($data['mime'])) return false;
2108 2334
@@ -2199,17 +2425,12 @@
2199 2425 */
2200 2426
2201 2427 function wdk_generate_profile_permalink($profile = array())
2202 2428 {
2203 -
2204 2429 $profile_slug = '';
2205 - if(wmvc_show_data('user_login', $profile, false)){
2206 - $profile_slug = wmvc_show_data('user_login', $profile);
2207 - if(wmvc_show_data('wdk_slug', $profile))
2208 - $profile_slug = wmvc_show_data('wdk_slug', $profile);
2209 - } else if(is_intval($profile)){
2430 + if(is_intval($profile)){
2210 2431 $profile_data = get_userdata($profile);
2211 - if(wmvc_show_data('wdk_slug', $profile, false)){
2432 + if(wmvc_show_data('wdk_slug', $profile_data, false)){
2212 2433 $profile_slug = wmvc_show_data('wdk_slug', $profile);
2213 2434 }elseif(wmvc_show_data('user_login', $profile_data, false)){
2214 2435 $profile_slug = wmvc_show_data('user_login', $profile_data);
2215 2436 } else {
@@ -2214,10 +2435,14 @@
2214 2435 $profile_slug = wmvc_show_data('user_login', $profile_data);
2215 2436 } else {
2216 2437 $profile_slug = $profile;
2217 2438 }
2218 - }
2219 -
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 +
2220 2445 $user_profile_page = get_option('wdk_membership_profile_preview_page');
2221 2446 if(!$user_profile_page) {
2222 2447 return '#';
2223 2448 }
@@ -2476,9 +2701,9 @@
2476 2701 <?php echo esc_html__('Select file','wmvc_win') ?>
2477 2702 </a>
2478 2703 <a class="delete-custom-img <?php if ( ! $you_have_file ) { echo 'hidden'; } ?>"
2479 2704 href="#">
2480 - <?php echo esc_html__('Remove file','wmvc_win') ?>
2705 + <?php echo esc_html__('Remove all files','wmvc_win') ?>
2481 2706 </a>
2482 2707 </p>
2483 2708 <?php //endif; ?>
2484 2709
@@ -2545,18 +2770,14 @@
2545 2770 {
2546 2771 static $media_element_counter = 0;
2547 2772
2548 2773 if(!isset($texts['file_select']))$texts['file_select'] = esc_html__('Select file','wmvc_win');
2549 - 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');
2550 2775
2551 2776 $media_element_counter++;
2552 2777
2553 2778 $img_field = $field_name.'_'.$media_element_counter;
2554 2779
2555 - wp_register_script( 'wpmediaelement_file', WPDIRECTORYKIT_URL . 'admin/js/jquery.wpmediaelement_file.js', array( 'jquery' ), false, false );
2556 - wp_enqueue_script( 'wpmediaelement_file' );
2557 - wp_enqueue_media();
2558 -
2559 2780 wp_enqueue_script( 'wpmediamultiple' );
2560 2781 wp_enqueue_script( 'jquery-ui-mouse' );
2561 2782 wp_enqueue_media();
2562 2783
@@ -2625,9 +2846,12 @@
2625 2846 $('#".esc_js($field_name)."meta-box-id.postbox-upload-multiple').wpMediaMultiple({
2626 2847 frame: {
2627 2848 title: '".esc_js(__('Select or Upload Media Of Your Chosen Persuasion','wpdirectorykit'))."',
2628 2849 button: '".esc_js(__('Use this media','wpdirectorykit'))."',
2629 - }
2850 + },
2851 + library: {
2852 + type: ['application', 'image', 'video']
2853 + },
2630 2854 });
2631 2855 /* order */
2632 2856 var re_order = function(media_element){
2633 2857 var list_media = '';
@@ -2736,8 +2960,52 @@
2736 2960
2737 2961 }
2738 2962 }
2739 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 +
2740 3008 if ( ! function_exists('wdk_recaptcha_field'))
2741 3009 {
2742 3010 function wdk_recaptcha_field($is_compact=false, $style="", $load_script=true)
2743 3011 {
@@ -2761,15 +3029,15 @@
2761 3029 }
2762 3030
2763 3031 $recaptcha_array[$counter] = array('size'=>$size_tag);
2764 3032
2765 - 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>';
2766 3034 ?>
2767 3035
2768 3036 <script>
2769 3037 <?php if($counter===1)echo 'var ';?>CaptchaCallback = function(){
2770 3038 <?php for($j=1;$j<=$counter;$j++): ?>
2771 - 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')); ?>'});
2772 3040 <?php endfor; ?>
2773 3041 };
2774 3042 </script>
2775 3043
@@ -2871,9 +3139,9 @@
2871 3139 if(is_array($val))
2872 3140 {
2873 3141 return wdk_clean($_POST);
2874 3142 }
2875 - else
3143 + elseif(is_string($val))
2876 3144 {
2877 3145 if(strpos($val, '<iframe') === 0)
2878 3146 $val = str_replace("'",'"', $val);
2879 3147
@@ -2912,9 +3180,9 @@
2912 3180 if(is_array($val))
2913 3181 {
2914 3182 $arr_cleaned[sanitize_text_field($key)] = wdk_clean($val);
2915 3183 }
2916 - else
3184 + elseif(is_string($val))
2917 3185 {
2918 3186 $arr_cleaned[sanitize_text_field($key)] = wp_kses_post($val);
2919 3187 }
2920 3188
@@ -2924,8 +3192,34 @@
2924 3192
2925 3193 return $arr_cleaned;
2926 3194 }
2927 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 +
2928 3222 /*
2929 3223 <select class="form-control" name="<?php echo 'control_operator_'.$i_fieldnum; ?>">
2930 3224 <option value="CONTAINS">CONTAINS</option>
2931 3225 <option value="NOT_CONTAINS">NOT_CONTAINS</option>
@@ -2995,15 +3289,15 @@
2995 3289
2996 3290 $results = $WMVC->$table->get();
2997 3291 foreach ($results as $item) {
2998 3292 if($item)
2999 - $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>';
3000 3294 }
3001 3295 }
3002 3296 } elseif(is_intval($selected)) {
3003 3297 $db_item = $WMVC->$table->get($selected, TRUE);
3004 3298 if($db_item)
3005 - $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>';
3006 3300 }
3007 3301 } else {
3008 3302 //$form .= '<option value="" selected="selected">'.esc_html__('Not selected', 'wpdirectorykit').'</option>';
3009 3303 }
@@ -3011,11 +3305,11 @@
3011 3305
3012 3306 //load javascript library
3013 3307 if($counter==0)
3014 3308 {
3015 - wp_enqueue_script('select2');
3309 + wp_enqueue_script('select2-select2');
3016 3310 wp_enqueue_script('wdk-select2');
3017 - wp_enqueue_style('select2');
3311 + wp_enqueue_style('select2-select2');
3018 3312 }
3019 3313 ?>
3020 3314 <?php
3021 3315 $counter++;
@@ -3059,11 +3353,11 @@
3059 3353
3060 3354 //load javascript library
3061 3355 if($counter==0)
3062 3356 {
3063 - wp_enqueue_script('select2');
3357 + wp_enqueue_script('select2-select2');
3064 3358 wp_enqueue_script('wdk-select2');
3065 - wp_enqueue_style('select2');
3359 + wp_enqueue_style('select2-select2');
3066 3360 }
3067 3361 ?>
3068 3362 <?php
3069 3363 $counter++;
@@ -3141,11 +3435,30 @@
3141 3435 'r'=>'llll',
3142 3436 'u'=>'x',
3143 3437 );
3144 3438
3145 - $replaced_from = array_keys($replaced);
3146 - $date_format = str_replace($replaced_from, array_keys($replaced_from), $date_format);
3147 - 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);
3148 3461 }
3149 3462 }
3150 3463
3151 3464 if ( ! function_exists('wdk_convert_date_format_jquery'))
@@ -3186,11 +3499,29 @@
3186 3499 'u'=>'@',
3187 3500 ':'=>'',
3188 3501 );
3189 3502
3190 - $replaced_from = array_keys($replaced);
3191 - $date_format = str_replace($replaced_from, array_keys($replaced_from), $date_format);
3192 - 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);
3193 3524 }
3194 3525 }
3195 3526
3196 3527 if ( ! function_exists('wdk_convert_date_format_jquery'))
@@ -3231,11 +3562,31 @@
3231 3562 'u'=>'@',
3232 3563 ':'=>'',
3233 3564 );
3234 3565
3235 - $replaced_from = array_keys($replaced);
3236 - $date_format = str_replace($replaced_from, array_keys($replaced_from), $date_format);
3237 - 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 +
3238 3589 }
3239 3590 }
3240 3591
3241 3592 if ( ! function_exists('wdk_get_gps'))
@@ -3263,9 +3614,17 @@
3263 3614
3264 3615 if(!isset($results[$address])) {
3265 3616 $results[$address] = NULL;
3266 3617 $url = 'https://nominatim.openstreetmap.org/search?format=json&q=' . $address;
3267 - $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);
3268 3627 $response = '';
3269 3628
3270 3629 // request failed
3271 3630 if ( is_wp_error( $request ) ) {
@@ -3421,8 +3780,32 @@
3421 3780 return false;
3422 3781 }
3423 3782 }
3424 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 +
3425 3808 if ( ! function_exists('wdk_filter_phone'))
3426 3809 {
3427 3810 // Validation phone
3428 3811 /**
@@ -3558,9 +3941,12 @@
3558 3941
3559 3942 $value = filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
3560 3943 $value = (float)str_replace(array(","," ",'&nbsp;'), "", $value);
3561 3944
3562 - 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);
3563 3949 }
3564 3950 }
3565 3951
3566 3952 if ( ! function_exists('wdk_currency_symbol'))
@@ -3693,9 +4079,20 @@
3693 4079 $user_data['wdk_position_title'] = wmvc_show_data('cacheduser_wdk_position_title', $row);
3694 4080 $user_data['agency_name'] = wmvc_show_data('cacheduser_agency_name', $row);
3695 4081 $user_data['description'] = wmvc_show_data('cacheduser_description', $row);
3696 4082 $user_data['user_url'] = wmvc_show_data('cacheduser_user_url', $row);
3697 - $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 + }
3698 4095
3699 4096 return $user_data;
3700 4097 }
3701 4098 }
@@ -4289,9 +4686,18 @@
4289 4686 * @param string $size_name size of image based on wp intermediate_size
4290 4687 *
4291 4688 * @return bool
4292 4689 */
4293 - function wdk_generate_missing_image_sizes($attachment_id, $size_name) {
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 +
4294 4700 $file = get_attached_file( $attachment_id );
4295 4701 require_once(ABSPATH . "wp-admin" . '/includes/image.php');
4296 4702 $metadata = wp_generate_attachment_metadata($attachment_id, $file);
4297 4703 if ( ! isset( $metadata['sizes'][ $size_name ] ) ) {
@@ -4307,5 +4713,597 @@
4307 4713 return true;
4308 4714 }
4309 4715 }
4310 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 + }
4311 5309 ?>