← All changes
|
includes/admin/settings/class-ph-settings-custom-fields.php
+677
-472
2.2.2
→
2.3.1
View file →
| @@ -1,5 +1,8 @@ | ||
| 1 | 1 | <?php |
| 2 | +// phpcs:set WordPress.Security.ValidatedSanitizedInput customSanitizingFunctions[] ph_clean | |
| 3 | +// ph_clean() recursively sanitizes text; presence, shape and unslashing checks remain separate. | |
| 4 | + | |
| 2 | 5 | /** |
| 3 | 6 | * PropertyHive Custom Fields Settings |
| 4 | 7 | * |
| 5 | 8 | * @author PropertyHive |
| @@ -16,8 +19,9 @@ | ||
| 16 | 19 | |
| 17 | 20 | /** |
| 18 | 21 | * PH_Settings_General |
| 19 | 22 | */ |
| 23 | +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- Legacy public global class PH_Settings_Custom_Fields; preserving the existing PH_* class name is required for plugin and extension compatibility. | |
| 20 | 24 | class PH_Settings_Custom_Fields extends PH_Settings_Page { |
| 21 | 25 | |
| 22 | 26 | const LINKED_POSTS_COLUMN_HEADING = 'Assigned Properties'; |
| 23 | 27 | |
| @@ -46,59 +50,145 @@ | ||
| 46 | 50 | } |
| 47 | 51 | |
| 48 | 52 | public function check_for_delete_additional_field() |
| 49 | 53 | { |
| 50 | - if ( isset($_GET['action']) && $_GET['action'] == 'deleteadditionalfield' && isset($_GET['id']) && $_GET['id'] != '' ) | |
| 51 | - { | |
| 52 | - $current_settings = get_option( 'propertyhive_template_assistant', array() ); | |
| 54 | + if ( | |
| 55 | + ! isset( $_GET['action'] ) || | |
| 56 | + 'deleteadditionalfield' !== $_GET['action'] | |
| 57 | + ) { | |
| 58 | + return; | |
| 59 | + } | |
| 53 | 60 | |
| 54 | - $current_id = ( !isset( $_GET['id'] ) ) ? '' : sanitize_title( $_GET['id'] ); | |
| 61 | + if ( ! current_user_can( 'manage_options' ) ) { | |
| 62 | + wp_die( | |
| 63 | + esc_html__( 'You do not have permission to manage Property Hive fields.', 'propertyhive' ), | |
| 64 | + '', | |
| 65 | + array( 'response' => 403 ) | |
| 66 | + ); | |
| 67 | + } | |
| 55 | 68 | |
| 56 | - $existing_custom_fields = ( (isset($current_settings['custom_fields'])) ? $current_settings['custom_fields'] : array() ); | |
| 69 | + check_admin_referer( 'propertyhive_delete_additional_field' ); | |
| 57 | 70 | |
| 58 | - if ( !isset($existing_custom_fields[$current_id]) ) | |
| 59 | - { | |
| 60 | - die("Trying to delete a non-existant additional field. Please go back and try again"); | |
| 61 | - } | |
| 71 | + $current_id = isset( $_GET['id'] ) && is_string( $_GET['id'] ) | |
| 72 | + ? sanitize_title( wp_unslash( $_GET['id'] ) ) | |
| 73 | + : ''; | |
| 62 | 74 | |
| 63 | - if ( isset($existing_custom_fields[$current_id]) ) | |
| 64 | - { | |
| 65 | - unset($existing_custom_fields[$current_id]); | |
| 66 | - } | |
| 75 | + if ( '' === $current_id ) { | |
| 76 | + wp_die( | |
| 77 | + esc_html__( 'Invalid additional field.', 'propertyhive' ), | |
| 78 | + '', | |
| 79 | + array( 'response' => 400 ) | |
| 80 | + ); | |
| 81 | + } | |
| 67 | 82 | |
| 68 | - $current_settings['custom_fields'] = $existing_custom_fields; | |
| 83 | + $current_settings = get_option( | |
| 84 | + 'propertyhive_template_assistant', | |
| 85 | + array() | |
| 86 | + ); | |
| 69 | 87 | |
| 70 | - update_option( 'propertyhive_template_assistant', $current_settings ); | |
| 88 | + $existing_custom_fields = | |
| 89 | + isset( $current_settings['custom_fields'] ) | |
| 90 | + && is_array( $current_settings['custom_fields'] ) | |
| 91 | + ? $current_settings['custom_fields'] | |
| 92 | + : array(); | |
| 93 | + | |
| 94 | + if ( ! isset( $existing_custom_fields[ $current_id ] ) ) { | |
| 95 | + wp_die( | |
| 96 | + esc_html__( 'The additional field does not exist.', 'propertyhive' ), | |
| 97 | + '', | |
| 98 | + array( 'response' => 404 ) | |
| 99 | + ); | |
| 71 | 100 | } |
| 101 | + | |
| 102 | + unset( $existing_custom_fields[ $current_id ] ); | |
| 103 | + | |
| 104 | + $current_settings['custom_fields'] = $existing_custom_fields; | |
| 105 | + | |
| 106 | + update_option( | |
| 107 | + 'propertyhive_template_assistant', | |
| 108 | + $current_settings | |
| 109 | + ); | |
| 110 | + | |
| 111 | + wp_safe_redirect( | |
| 112 | + admin_url( | |
| 113 | + 'admin.php?page=ph-settings&tab=customfields§ion=additional&ph_message=' . __( 'Additional field deleted successfully', 'propertyhive' ) | |
| 114 | + ) | |
| 115 | + ); | |
| 116 | + exit; | |
| 72 | 117 | } |
| 73 | 118 | |
| 74 | 119 | public function check_for_reorder_additional_fields() |
| 75 | 120 | { |
| 76 | - if ( isset($_GET['neworder']) && $_GET['neworder'] != '' ) | |
| 77 | - { | |
| 78 | - $current_settings = get_option( 'propertyhive_template_assistant', array() ); | |
| 121 | + if ( ! isset( $_GET['neworder'] ) ) { | |
| 122 | + return; | |
| 123 | + } | |
| 79 | 124 | |
| 80 | - $current_id = ( !isset( $_GET['id'] ) ) ? '' : sanitize_title( $_GET['id'] ); | |
| 125 | + if ( ! current_user_can( 'manage_options' ) ) { | |
| 126 | + wp_die( | |
| 127 | + esc_html__( 'You do not have permission to manage Property Hive fields.', 'propertyhive' ), | |
| 128 | + '', | |
| 129 | + array( 'response' => 403 ) | |
| 130 | + ); | |
| 131 | + } | |
| 81 | 132 | |
| 82 | - $existing_custom_fields = ( (isset($current_settings['custom_fields'])) ? $current_settings['custom_fields'] : array() ); | |
| 133 | + check_admin_referer( 'propertyhive_reorder_additional_fields' ); | |
| 83 | 134 | |
| 84 | - $new_order = explode(",", sanitize_text_field($_GET['neworder'])); | |
| 85 | - $new_order = ph_clean($new_order); | |
| 135 | + if ( ! is_string( $_GET['neworder'] ) ) { | |
| 136 | + wp_die( esc_html__( 'Invalid additional field order.', 'propertyhive' ), '', array( 'response' => 400 ) ); | |
| 137 | + } | |
| 86 | 138 | |
| 87 | - $new_custom_fields = array(); | |
| 139 | + $new_order = array_map( | |
| 140 | + 'sanitize_title', | |
| 141 | + explode( | |
| 142 | + ',', | |
| 143 | + sanitize_text_field( | |
| 144 | + wp_unslash( $_GET['neworder'] ) | |
| 145 | + ) | |
| 146 | + ) | |
| 147 | + ); | |
| 88 | 148 | |
| 89 | - foreach ( $new_order as $id ) | |
| 90 | - { | |
| 91 | - $new_custom_fields[] = $existing_custom_fields[$id]; | |
| 92 | - } | |
| 149 | + $current_settings = get_option( | |
| 150 | + 'propertyhive_template_assistant', | |
| 151 | + array() | |
| 152 | + ); | |
| 93 | 153 | |
| 94 | - $current_settings['custom_fields'] = $new_custom_fields; | |
| 154 | + $existing_custom_fields = | |
| 155 | + isset( $current_settings['custom_fields'] ) | |
| 156 | + && is_array( $current_settings['custom_fields'] ) | |
| 157 | + ? $current_settings['custom_fields'] | |
| 158 | + : array(); | |
| 95 | 159 | |
| 96 | - update_option( 'propertyhive_template_assistant', $current_settings ); | |
| 160 | + if ( | |
| 161 | + count( $new_order ) !== count( $existing_custom_fields ) || | |
| 162 | + array_diff( $new_order, array_keys( $existing_custom_fields ) ) || | |
| 163 | + array_diff( array_keys( $existing_custom_fields ), $new_order ) | |
| 164 | + ) { | |
| 165 | + wp_die( | |
| 166 | + esc_html__( 'Invalid additional field order.', 'propertyhive' ), | |
| 167 | + '', | |
| 168 | + array( 'response' => 400 ) | |
| 169 | + ); | |
| 170 | + } | |
| 97 | 171 | |
| 98 | - header("Location: " . admin_url('admin.php?page=ph-settings&tab=customfields§ion=additional')); | |
| 99 | - exit(); | |
| 172 | + $new_custom_fields = array(); | |
| 173 | + | |
| 174 | + foreach ( $new_order as $id ) { | |
| 175 | + $new_custom_fields[ $id ] = $existing_custom_fields[ $id ]; | |
| 100 | 176 | } |
| 177 | + | |
| 178 | + $current_settings['custom_fields'] = $new_custom_fields; | |
| 179 | + | |
| 180 | + update_option( | |
| 181 | + 'propertyhive_template_assistant', | |
| 182 | + $current_settings | |
| 183 | + ); | |
| 184 | + | |
| 185 | + wp_safe_redirect( | |
| 186 | + admin_url( | |
| 187 | + 'admin.php?page=ph-settings&tab=customfields§ion=additional&ph_message=' . __( 'Additional fields reordered successfully', 'propertyhive' ) | |
| 188 | + ) | |
| 189 | + ); | |
| 190 | + exit; | |
| 101 | 191 | } |
| 102 | 192 | |
| 103 | 193 | /** |
| 104 | 194 | * Get sections |
| @@ -246,36 +336,13 @@ | ||
| 246 | 336 | public function get_settings() { |
| 247 | 337 | |
| 248 | 338 | global $hide_save_button; |
| 249 | 339 | |
| 340 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Shared admin settings-view state; this global is intentionally used to control the common settings template and is not an arbitrary application global. | |
| 250 | 341 | $hide_save_button = true; |
| 251 | 342 | |
| 252 | 343 | $i = 0; |
| 253 | - $html = '<style> | |
| 254 | - | |
| 255 | - .ph-custom-fields-grid { display:grid; grid-template-columns:repeat(4, 1fr); gap:22px; } | |
| 256 | - .ph-custom-fields-grid > div { display:flex; gap:20px; background:#FFF; padding:25px; border:1px solid #AAA } | |
| 257 | - .ph-custom-fields-grid > div .ph-grid-image { flex:0 0 50px; } | |
| 258 | - .ph-custom-fields-grid > div .ph-grid-image-bg { background:#fbfcd4; border:1px solid #ffcd00; padding:10px; border-radius:7px; } | |
| 259 | - .ph-custom-fields-grid > div .ph-grid-image img { max-width:40px; height:40px; display:block } | |
| 260 | - .ph-custom-fields-grid > div .feature-card-content { flex:1; min-width:0; } | |
| 261 | - .ph-custom-fields-grid > div h3 { margin-top:0; margin-bottom:0.6em } | |
| 262 | - | |
| 263 | - @media (max-width:1750px) { | |
| 264 | - | |
| 265 | - .ph-custom-fields-grid { grid-template-columns:repeat(3, 1fr); } | |
| 266 | - | |
| 267 | - } | |
| 268 | - | |
| 269 | - @media (max-width:1370px) { | |
| 270 | - | |
| 271 | - .ph-custom-fields-grid { grid-template-columns:repeat(2, 1fr); } | |
| 272 | - | |
| 273 | - } | |
| 274 | - | |
| 275 | - </style> | |
| 276 | - | |
| 277 | - <div class="ph-custom-fields-grid">'; | |
| 344 | + $html = '<div class="ph-custom-fields-grid">'; | |
| 278 | 345 | foreach ( $this->custom_field_sections as $key => $value ) |
| 279 | 346 | { |
| 280 | 347 | $image = 'default.png'; |
| 281 | 348 | if ( file_exists(PH()->plugin_path() . '/assets/images/admin/settings/custom-fields/' . $key . '.png') ) |
| @@ -323,8 +390,9 @@ | ||
| 323 | 390 | case "additional": |
| 324 | 391 | { |
| 325 | 392 | global $hide_save_button; |
| 326 | 393 | |
| 394 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Shared admin settings-view state; this global is intentionally used to control the common settings template and is not an arbitrary application global. | |
| 327 | 395 | $hide_save_button = true; |
| 328 | 396 | |
| 329 | 397 | // The main custom field screen listing them in a table |
| 330 | 398 | $settings = $this->get_custom_fields_additional_fields_setting(); |
| @@ -344,11 +412,13 @@ | ||
| 344 | 412 | break; |
| 345 | 413 | } |
| 346 | 414 | default: |
| 347 | 415 | { |
| 348 | - if (isset($_REQUEST['id'])) // we're either adding or editing | |
| 416 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This branch only renders a settings form from an optional id; it does not mutate state. The corresponding save path verifies the settings nonce and capability. | |
| 417 | + if ( isset( $_REQUEST['id'] ) ) // we're either adding or editing | |
| 349 | 418 | { |
| 350 | - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_text_field($_REQUEST['id']); | |
| 419 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This id is used only to render a settings form; the corresponding save path verifies the settings nonce and capability. | |
| 420 | + $current_id = ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['id'] ) ) : ''; | |
| 351 | 421 | |
| 352 | 422 | switch ($current_section) |
| 353 | 423 | { |
| 354 | 424 | case "availability": { $settings = $this->get_custom_fields_availability_setting(); break; } |
| @@ -405,8 +475,9 @@ | ||
| 405 | 475 | else |
| 406 | 476 | { |
| 407 | 477 | global $hide_save_button; |
| 408 | 478 | |
| 479 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Shared admin settings-view state; this global is intentionally used to control the common settings template and is not an arbitrary application global. | |
| 409 | 480 | $hide_save_button = true; |
| 410 | 481 | |
| 411 | 482 | // The main custom field screen listing them in a table |
| 412 | 483 | $settings = $this->get_custom_fields_setting($current_section); |
| @@ -434,9 +505,10 @@ | ||
| 434 | 505 | { |
| 435 | 506 | $current_settings['custom_fields'] = array(); |
| 436 | 507 | } |
| 437 | 508 | |
| 438 | - $current_id = ( !isset( $_REQUEST['id'] ) ) ? '' : sanitize_title( $_REQUEST['id'] ); | |
| 509 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This settings getter only loads stored configuration for rendering; it does not mutate state. | |
| 510 | + $current_id = ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_title( wp_unslash( $_REQUEST['id'] ) ) : ''; | |
| 439 | 511 | |
| 440 | 512 | $custom_field_details = array(); |
| 441 | 513 | |
| 442 | 514 | if ($current_id != '') |
| @@ -454,9 +526,9 @@ | ||
| 454 | 526 | } |
| 455 | 527 | |
| 456 | 528 | $settings = array( |
| 457 | 529 | |
| 458 | - array( 'title' => __( ( $current_section == 'addadditionalfield' ? 'Add Additional Field' : 'Edit Additional Field' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'customfield' ), | |
| 530 | + array( 'title' => ( $current_section == 'addadditionalfield' ? __( 'Add Additional Field', 'propertyhive' ) : __( 'Edit Additional Field', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'customfield' ), | |
| 459 | 531 | |
| 460 | 532 | ); |
| 461 | 533 | |
| 462 | 534 | $settings[] = array( |
| @@ -699,9 +771,10 @@ | ||
| 699 | 771 | { |
| 700 | 772 | $current_settings['custom_fields'] = array(); |
| 701 | 773 | } |
| 702 | 774 | |
| 703 | - $current_id = ( !isset( $_REQUEST['id'] ) ) ? '' : sanitize_title( $_REQUEST['id'] ); | |
| 775 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This settings getter only loads stored configuration for rendering; it does not mutate state. | |
| 776 | + $current_id = ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_title( wp_unslash( $_REQUEST['id'] ) ) : ''; | |
| 704 | 777 | |
| 705 | 778 | $custom_field_details = array(); |
| 706 | 779 | |
| 707 | 780 | if ($current_id != '') |
| @@ -722,15 +795,15 @@ | ||
| 722 | 795 | <tr valign="top" id="row_dropdown_options"> |
| 723 | 796 | <th scope="row" class="titledesc"> |
| 724 | 797 | <label for="field_type">Dropdown Options</label> |
| 725 | 798 | </th> |
| 726 | - <td class="forminp forminp-dropdown-options"><div id="sortable_options_' . $current_id . '">'; | |
| 799 | + <td class="forminp forminp-dropdown-options"><div id="sortable_options_' . esc_attr( $current_id ) . '">'; | |
| 727 | 800 | if ( isset($custom_field_details['dropdown_options']) && !empty($custom_field_details['dropdown_options']) ) |
| 728 | 801 | { |
| 729 | 802 | foreach ( $custom_field_details['dropdown_options'] as $dropdown_option ) |
| 730 | 803 | { |
| 731 | 804 | echo ' |
| 732 | - <div><i class="fa fa-reorder" style="cursor:pointer; opacity:0.3"></i> <input type="text" name="dropdown_options[]" value="' . $dropdown_option . '"> <a href="" class="delete-dropdown-option">Delete Option</a></div> | |
| 805 | + <div><i class="fa fa-reorder" style="cursor:pointer; opacity:0.3"></i> <input type="text" name="dropdown_options[]" value="' . esc_attr( $dropdown_option ) . '"> <a href="" class="delete-dropdown-option">Delete Option</a></div> | |
| 733 | 806 | '; |
| 734 | 807 | } |
| 735 | 808 | } |
| 736 | 809 | else |
| @@ -774,9 +847,9 @@ | ||
| 774 | 847 | jQuery(this).parent().remove(); |
| 775 | 848 | } |
| 776 | 849 | }); |
| 777 | 850 | |
| 778 | - jQuery( \'#sortable_options_' . $current_id . '\' ) | |
| 851 | + jQuery( \'#sortable_options_' . esc_js( $current_id ) . '\' ) | |
| 779 | 852 | .sortable({ |
| 780 | 853 | axis: "y", |
| 781 | 854 | handle: "i", |
| 782 | 855 | stop: function( event, ui ) |
| @@ -899,11 +972,19 @@ | ||
| 899 | 972 | { |
| 900 | 973 | echo '-'; |
| 901 | 974 | } |
| 902 | 975 | echo '</td>'; |
| 976 | + | |
| 977 | + $delete_url = wp_nonce_url( | |
| 978 | + admin_url( | |
| 979 | + 'admin.php?page=ph-settings&tab=customfields§ion=additional&action=deleteadditionalfield&id=' . rawurlencode( $id ) | |
| 980 | + ), | |
| 981 | + 'propertyhive_delete_additional_field' | |
| 982 | + ); | |
| 983 | + | |
| 903 | 984 | echo '<td class="settings"> |
| 904 | 985 | <a class="button" href="' . esc_url(admin_url( 'admin.php?page=ph-settings&tab=customfields§ion=editadditionalfield&id=' . $id )) . '">' . esc_html(__( 'Edit Field', 'propertyhive' )) . '</a> |
| 905 | - <a class="button" href="' . esc_url(admin_url( 'admin.php?page=ph-settings&tab=customfields§ion=additional&action=deleteadditionalfield&id=' . $id )) . '" onclick="var confirmBox = confirm(\'Are you sure you wish to delete this custom field?\'); return confirmBox;">' . esc_html(__( 'Delete', 'propertyhive' )) . '</a> | |
| 986 | + <a class="button" href="' . esc_url( $delete_url ) . '" onclick="var confirmBox = confirm(\'Are you sure you wish to delete this custom field?\'); return confirmBox;">' . esc_html(__( 'Delete', 'propertyhive' )) . '</a> | |
| 906 | 987 | </td>'; |
| 907 | 988 | echo '</tr>'; |
| 908 | 989 | } |
| 909 | 990 | } |
| @@ -938,9 +1019,9 @@ | ||
| 938 | 1019 | new_order = new_order + jQuery(this).attr('id').replace('custom_field_', ''); |
| 939 | 1020 | }); |
| 940 | 1021 | |
| 941 | 1022 | // reload page |
| 942 | - window.location.href = '<?php echo admin_url('admin.php?page=ph-settings&tab=customfields§ion=additional'); ?>&neworder=' + new_order; | |
| 1023 | + window.location.href = <?php echo wp_json_encode( add_query_arg( '_wpnonce', wp_create_nonce( 'propertyhive_reorder_additional_fields' ), admin_url( 'admin.php?page=ph-settings&tab=customfields§ion=additional' ) ), JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT ); ?> + '&neworder=' + encodeURIComponent( new_order ); | |
| 943 | 1024 | } |
| 944 | 1025 | }); |
| 945 | 1026 | |
| 946 | 1027 | }); |
| @@ -1012,9 +1093,9 @@ | ||
| 1012 | 1093 | <th class="id" style="width:45px;"><?php echo esc_html(__( 'ID', 'propertyhive' )); ?></th> |
| 1013 | 1094 | <?php do_action( 'propertyhive_custom_field_availability_table_before_header_column' ); ?> |
| 1014 | 1095 | <th class="type"><?php echo esc_html(__( 'Availability', 'propertyhive' )); ?></th> |
| 1015 | 1096 | <th class="department"><?php echo esc_html(__( 'Applies To', 'propertyhive' )); ?></th> |
| 1016 | - <th class="assigned_count"><?php echo esc_html(__( $this::LINKED_POSTS_COLUMN_HEADING, 'propertyhive' )); ?></th> | |
| 1097 | + <th class="assigned_count"><?php echo esc_html(__( 'Assigned Properties', 'propertyhive' )); ?></th> | |
| 1017 | 1098 | <th class="settings"> </th> |
| 1018 | 1099 | </tr> |
| 1019 | 1100 | </thead> |
| 1020 | 1101 | <tbody> |
| @@ -1022,9 +1103,9 @@ | ||
| 1022 | 1103 | $args = array( |
| 1023 | 1104 | 'hide_empty' => false, |
| 1024 | 1105 | 'parent' => 0 |
| 1025 | 1106 | ); |
| 1026 | - $terms = get_terms( 'availability', $args ); | |
| 1107 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'availability' ) ) ); | |
| 1027 | 1108 | |
| 1028 | 1109 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 1029 | 1110 | { |
| 1030 | 1111 | foreach ( $terms as $term ) |
| @@ -1121,9 +1202,9 @@ | ||
| 1121 | 1202 | <th class="cb" style="width:1px;"><input class="select_all" type="checkbox" style="margin: 2px 0 0 0;"></th> |
| 1122 | 1203 | <th class="id" style="width:45px;"><?php echo esc_html(__( 'ID', 'propertyhive' )); ?></th> |
| 1123 | 1204 | <?php do_action( 'propertyhive_custom_field_property_type_table_before_header_column' ); ?> |
| 1124 | 1205 | <th class="type"><?php echo esc_html(__( 'Property Type', 'propertyhive' )); ?></th> |
| 1125 | - <th class="assigned_count"><?php echo esc_html(__( $this::LINKED_POSTS_COLUMN_HEADING, 'propertyhive' )); ?></th> | |
| 1206 | + <th class="assigned_count"><?php echo esc_html(__( 'Assigned Properties', 'propertyhive' )); ?></th> | |
| 1126 | 1207 | <th class="settings"> </th> |
| 1127 | 1208 | </tr> |
| 1128 | 1209 | </thead> |
| 1129 | 1210 | <tbody> |
| @@ -1131,9 +1212,9 @@ | ||
| 1131 | 1212 | $args = array( |
| 1132 | 1213 | 'hide_empty' => false, |
| 1133 | 1214 | 'parent' => 0 |
| 1134 | 1215 | ); |
| 1135 | - $terms = get_terms( 'property_type', $args ); | |
| 1216 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'property_type' ) ) ); | |
| 1136 | 1217 | |
| 1137 | 1218 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 1138 | 1219 | { |
| 1139 | 1220 | foreach ($terms as $term) |
| @@ -1143,9 +1224,9 @@ | ||
| 1143 | 1224 | $args = array( |
| 1144 | 1225 | 'hide_empty' => false, |
| 1145 | 1226 | 'parent' => $parent_term_id |
| 1146 | 1227 | ); |
| 1147 | - $subterms = get_terms( 'property_type', $args ); | |
| 1228 | + $subterms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'property_type' ) ) ); | |
| 1148 | 1229 | ?> |
| 1149 | 1230 | <tr> |
| 1150 | 1231 | <td class="cb"><?php if ( empty( $subterms ) ) { ?><input type="checkbox" name="term_id[]" value="<?php echo esc_attr($term->term_id); ?>"><?php }else{ echo ' '; } ?></td> |
| 1151 | 1232 | <td class="id"><?php echo esc_html($term->term_id); ?></td> |
| @@ -1235,9 +1316,9 @@ | ||
| 1235 | 1316 | <th class="cb" style="width:1px;"><input class="select_all" type="checkbox" style="margin: 2px 0 0 0;"></th> |
| 1236 | 1317 | <th class="id" style="width:45px;"><?php echo esc_html(__( 'ID', 'propertyhive' )); ?></th> |
| 1237 | 1318 | <?php do_action( 'propertyhive_custom_field_commercial_property_type_table_before_header_column' ); ?> |
| 1238 | 1319 | <th class="type"><?php echo esc_html(__( 'Property Type', 'propertyhive' )); ?></th> |
| 1239 | - <th class="assigned_count"><?php echo esc_html(__( $this::LINKED_POSTS_COLUMN_HEADING, 'propertyhive' )); ?></th> | |
| 1320 | + <th class="assigned_count"><?php echo esc_html(__( 'Assigned Properties', 'propertyhive' )); ?></th> | |
| 1240 | 1321 | <th class="settings"> </th> |
| 1241 | 1322 | </tr> |
| 1242 | 1323 | </thead> |
| 1243 | 1324 | <tbody> |
| @@ -1245,9 +1326,9 @@ | ||
| 1245 | 1326 | $args = array( |
| 1246 | 1327 | 'hide_empty' => false, |
| 1247 | 1328 | 'parent' => 0 |
| 1248 | 1329 | ); |
| 1249 | - $terms = get_terms( 'commercial_property_type', $args ); | |
| 1330 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'commercial_property_type' ) ) ); | |
| 1250 | 1331 | |
| 1251 | 1332 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 1252 | 1333 | { |
| 1253 | 1334 | foreach ($terms as $term) |
| @@ -1257,9 +1338,9 @@ | ||
| 1257 | 1338 | $args = array( |
| 1258 | 1339 | 'hide_empty' => false, |
| 1259 | 1340 | 'parent' => $parent_term_id |
| 1260 | 1341 | ); |
| 1261 | - $subterms = get_terms( 'commercial_property_type', $args ); | |
| 1342 | + $subterms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'commercial_property_type' ) ) ); | |
| 1262 | 1343 | ?> |
| 1263 | 1344 | <tr> |
| 1264 | 1345 | <td class="cb"><?php if ( empty( $subterms ) ) { ?><input type="checkbox" name="term_id[]" value="<?php echo esc_attr($term->term_id); ?>"><?php }else{ echo ' '; } ?></td> |
| 1265 | 1346 | <td class="id"><?php echo esc_html($term->term_id); ?></td> |
| @@ -1348,9 +1429,9 @@ | ||
| 1348 | 1429 | <tr> |
| 1349 | 1430 | <th class="cb" style="width:1px;"><input class="select_all" type="checkbox" style="margin: 2px 0 0 0;"></th> |
| 1350 | 1431 | <th class="id" style="width:45px;"><?php echo esc_html(__( 'ID', 'propertyhive' )); ?></th> |
| 1351 | 1432 | <th class="type"><?php echo esc_html(__( 'Location', 'propertyhive' )); ?></th> |
| 1352 | - <th class="assigned_count"><?php echo esc_html(__( $this::LINKED_POSTS_COLUMN_HEADING, 'propertyhive' )); ?></th> | |
| 1433 | + <th class="assigned_count"><?php echo esc_html(__( 'Assigned Properties', 'propertyhive' )); ?></th> | |
| 1353 | 1434 | <th class="settings"> </th> |
| 1354 | 1435 | </tr> |
| 1355 | 1436 | </thead> |
| 1356 | 1437 | <tbody> |
| @@ -1358,9 +1439,9 @@ | ||
| 1358 | 1439 | $args = array( |
| 1359 | 1440 | 'hide_empty' => false, |
| 1360 | 1441 | 'parent' => 0 |
| 1361 | 1442 | ); |
| 1362 | - $terms = get_terms( 'location', $args ); | |
| 1443 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'location' ) ) ); | |
| 1363 | 1444 | |
| 1364 | 1445 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 1365 | 1446 | { |
| 1366 | 1447 | foreach ($terms as $term) |
| @@ -1368,9 +1449,9 @@ | ||
| 1368 | 1449 | $args = array( |
| 1369 | 1450 | 'hide_empty' => false, |
| 1370 | 1451 | 'parent' => $term->term_id |
| 1371 | 1452 | ); |
| 1372 | - $subterms = get_terms( 'location', $args ); | |
| 1453 | + $subterms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'location' ) ) ); | |
| 1373 | 1454 | ?> |
| 1374 | 1455 | <tr> |
| 1375 | 1456 | <td class="cb"><?php if ( empty( $subterms ) ) { ?><input type="checkbox" name="term_id[]" value="<?php echo esc_attr($term->term_id); ?>"><?php }else{ echo ' '; } ?></td> |
| 1376 | 1457 | <td class="id"><?php echo esc_html($term->term_id); ?></td> |
| @@ -1391,9 +1472,9 @@ | ||
| 1391 | 1472 | $args = array( |
| 1392 | 1473 | 'hide_empty' => false, |
| 1393 | 1474 | 'parent' => $term->term_id |
| 1394 | 1475 | ); |
| 1395 | - $subsubterms = get_terms( 'location', $args ); | |
| 1476 | + $subsubterms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'location' ) ) ); | |
| 1396 | 1477 | ?> |
| 1397 | 1478 | <tr> |
| 1398 | 1479 | <td class="cb"><?php if ( empty( $subsubterms ) ) { ?><input type="checkbox" name="term_id[]" value="<?php echo esc_attr($term->term_id); ?>"><?php }else{ echo ' '; } ?></td> |
| 1399 | 1480 | <td class="id"><?php echo esc_html($term->term_id); ?></td> |
| @@ -1482,9 +1563,9 @@ | ||
| 1482 | 1563 | <tr> |
| 1483 | 1564 | <th class="cb" style="width:1px;"><input class="select_all" type="checkbox" style="margin: 2px 0 0 0;"></th> |
| 1484 | 1565 | <th class="id" style="width:45px;"><?php echo esc_html(__( 'ID', 'propertyhive' )); ?></th> |
| 1485 | 1566 | <th class="type"><?php echo esc_html(__( 'Parking', 'propertyhive' )); ?></th> |
| 1486 | - <th class="assigned_count"><?php echo esc_html(__( $this::LINKED_POSTS_COLUMN_HEADING, 'propertyhive' )); ?></th> | |
| 1567 | + <th class="assigned_count"><?php echo esc_html(__( 'Assigned Properties', 'propertyhive' )); ?></th> | |
| 1487 | 1568 | <th class="settings"> </th> |
| 1488 | 1569 | </tr> |
| 1489 | 1570 | </thead> |
| 1490 | 1571 | <tbody> |
| @@ -1492,9 +1573,9 @@ | ||
| 1492 | 1573 | $args = array( |
| 1493 | 1574 | 'hide_empty' => false, |
| 1494 | 1575 | 'parent' => 0 |
| 1495 | 1576 | ); |
| 1496 | - $terms = get_terms( 'parking', $args ); | |
| 1577 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'parking' ) ) ); | |
| 1497 | 1578 | |
| 1498 | 1579 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 1499 | 1580 | { |
| 1500 | 1581 | foreach ($terms as $term) |
| @@ -1564,9 +1645,9 @@ | ||
| 1564 | 1645 | <tr> |
| 1565 | 1646 | <th class="cb" style="width:1px;"><input class="select_all" type="checkbox" style="margin: 2px 0 0 0;"></th> |
| 1566 | 1647 | <th class="id" style="width:45px;"><?php echo esc_html(__( 'ID', 'propertyhive' )); ?></th> |
| 1567 | 1648 | <th class="type"><?php echo esc_html(__( 'Outside Space', 'propertyhive' )); ?></th> |
| 1568 | - <th class="assigned_count"><?php echo esc_html(__( $this::LINKED_POSTS_COLUMN_HEADING, 'propertyhive' )); ?></th> | |
| 1649 | + <th class="assigned_count"><?php echo esc_html(__( 'Assigned Properties', 'propertyhive' )); ?></th> | |
| 1569 | 1650 | <th class="settings"> </th> |
| 1570 | 1651 | </tr> |
| 1571 | 1652 | </thead> |
| 1572 | 1653 | <tbody> |
| @@ -1574,9 +1655,9 @@ | ||
| 1574 | 1655 | $args = array( |
| 1575 | 1656 | 'hide_empty' => false, |
| 1576 | 1657 | 'parent' => 0 |
| 1577 | 1658 | ); |
| 1578 | - $terms = get_terms( 'outside_space', $args ); | |
| 1659 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'outside_space' ) ) ); | |
| 1579 | 1660 | |
| 1580 | 1661 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 1581 | 1662 | { |
| 1582 | 1663 | foreach ($terms as $term) |
| @@ -1646,9 +1727,9 @@ | ||
| 1646 | 1727 | <tr> |
| 1647 | 1728 | <th class="cb" style="width:1px;"><input class="select_all" type="checkbox" style="margin: 2px 0 0 0;"></th> |
| 1648 | 1729 | <th class="id" style="width:45px;"><?php echo esc_html(__( 'ID', 'propertyhive' )); ?></th> |
| 1649 | 1730 | <th class="type"><?php echo esc_html(__( 'Price Qualifier', 'propertyhive' )); ?></th> |
| 1650 | - <th class="assigned_count"><?php echo esc_html(__( $this::LINKED_POSTS_COLUMN_HEADING, 'propertyhive' )); ?></th> | |
| 1731 | + <th class="assigned_count"><?php echo esc_html(__( 'Assigned Properties', 'propertyhive' )); ?></th> | |
| 1651 | 1732 | <th class="settings"> </th> |
| 1652 | 1733 | </tr> |
| 1653 | 1734 | </thead> |
| 1654 | 1735 | <tbody> |
| @@ -1656,9 +1737,9 @@ | ||
| 1656 | 1737 | $args = array( |
| 1657 | 1738 | 'hide_empty' => false, |
| 1658 | 1739 | 'parent' => 0 |
| 1659 | 1740 | ); |
| 1660 | - $terms = get_terms( 'price_qualifier', $args ); | |
| 1741 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'price_qualifier' ) ) ); | |
| 1661 | 1742 | |
| 1662 | 1743 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 1663 | 1744 | { |
| 1664 | 1745 | foreach ($terms as $term) |
| @@ -1728,9 +1809,9 @@ | ||
| 1728 | 1809 | <tr> |
| 1729 | 1810 | <th class="cb" style="width:1px;"><input class="select_all" type="checkbox" style="margin: 2px 0 0 0;"></th> |
| 1730 | 1811 | <th class="id" style="width:45px;"><?php echo esc_html(__( 'ID', 'propertyhive' )); ?></th> |
| 1731 | 1812 | <th class="type"><?php echo esc_html(__( 'Sale By', 'propertyhive' )); ?></th> |
| 1732 | - <th class="assigned_count"><?php echo esc_html(__( $this::LINKED_POSTS_COLUMN_HEADING, 'propertyhive' )); ?></th> | |
| 1813 | + <th class="assigned_count"><?php echo esc_html(__( 'Assigned Properties', 'propertyhive' )); ?></th> | |
| 1733 | 1814 | <th class="settings"> </th> |
| 1734 | 1815 | </tr> |
| 1735 | 1816 | </thead> |
| 1736 | 1817 | <tbody> |
| @@ -1738,9 +1819,9 @@ | ||
| 1738 | 1819 | $args = array( |
| 1739 | 1820 | 'hide_empty' => false, |
| 1740 | 1821 | 'parent' => 0 |
| 1741 | 1822 | ); |
| 1742 | - $terms = get_terms( 'sale_by', $args ); | |
| 1823 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'sale_by' ) ) ); | |
| 1743 | 1824 | |
| 1744 | 1825 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 1745 | 1826 | { |
| 1746 | 1827 | foreach ($terms as $term) |
| @@ -1810,9 +1891,9 @@ | ||
| 1810 | 1891 | <tr> |
| 1811 | 1892 | <th class="cb" style="width:1px;"><input class="select_all" type="checkbox" style="margin: 2px 0 0 0;"></th> |
| 1812 | 1893 | <th class="id" style="width:45px;"><?php echo esc_html(__( 'ID', 'propertyhive' )); ?></th> |
| 1813 | 1894 | <th class="type"><?php echo esc_html(__( 'Tenure', 'propertyhive' )); ?></th> |
| 1814 | - <th class="assigned_count"><?php echo esc_html(__( $this::LINKED_POSTS_COLUMN_HEADING, 'propertyhive' )); ?></th> | |
| 1895 | + <th class="assigned_count"><?php echo esc_html(__( 'Assigned Properties', 'propertyhive' )); ?></th> | |
| 1815 | 1896 | <th class="settings"> </th> |
| 1816 | 1897 | </tr> |
| 1817 | 1898 | </thead> |
| 1818 | 1899 | <tbody> |
| @@ -1820,9 +1901,9 @@ | ||
| 1820 | 1901 | $args = array( |
| 1821 | 1902 | 'hide_empty' => false, |
| 1822 | 1903 | 'parent' => 0 |
| 1823 | 1904 | ); |
| 1824 | - $terms = get_terms( 'tenure', $args ); | |
| 1905 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'tenure' ) ) ); | |
| 1825 | 1906 | |
| 1826 | 1907 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 1827 | 1908 | { |
| 1828 | 1909 | foreach ($terms as $term) |
| @@ -1892,9 +1973,9 @@ | ||
| 1892 | 1973 | <tr> |
| 1893 | 1974 | <th class="cb" style="width:1px;"><input class="select_all" type="checkbox" style="margin: 2px 0 0 0;"></th> |
| 1894 | 1975 | <th class="id" style="width:45px;"><?php echo esc_html(__( 'ID', 'propertyhive' )); ?></th> |
| 1895 | 1976 | <th class="type"><?php echo esc_html(__( 'Tenure', 'propertyhive' )); ?></th> |
| 1896 | - <th class="assigned_count"><?php echo esc_html(__( $this::LINKED_POSTS_COLUMN_HEADING, 'propertyhive' )); ?></th> | |
| 1977 | + <th class="assigned_count"><?php echo esc_html(__( 'Assigned Properties', 'propertyhive' )); ?></th> | |
| 1897 | 1978 | <th class="settings"> </th> |
| 1898 | 1979 | </tr> |
| 1899 | 1980 | </thead> |
| 1900 | 1981 | <tbody> |
| @@ -1902,9 +1983,9 @@ | ||
| 1902 | 1983 | $args = array( |
| 1903 | 1984 | 'hide_empty' => false, |
| 1904 | 1985 | 'parent' => 0 |
| 1905 | 1986 | ); |
| 1906 | - $terms = get_terms( 'commercial_tenure', $args ); | |
| 1987 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'commercial_tenure' ) ) ); | |
| 1907 | 1988 | |
| 1908 | 1989 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 1909 | 1990 | { |
| 1910 | 1991 | foreach ($terms as $term) |
| @@ -1974,9 +2055,9 @@ | ||
| 1974 | 2055 | <tr> |
| 1975 | 2056 | <th class="cb" style="width:1px;"><input class="select_all" type="checkbox" style="margin: 2px 0 0 0;"></th> |
| 1976 | 2057 | <th class="id" style="width:45px;"><?php echo esc_html(__( 'ID', 'propertyhive' )); ?></th> |
| 1977 | 2058 | <th class="type"><?php echo esc_html(__( 'Furnished', 'propertyhive' )); ?></th> |
| 1978 | - <th class="assigned_count"><?php echo esc_html(__( $this::LINKED_POSTS_COLUMN_HEADING, 'propertyhive' )); ?></th> | |
| 2059 | + <th class="assigned_count"><?php echo esc_html(__( 'Assigned Properties', 'propertyhive' )); ?></th> | |
| 1979 | 2060 | <th class="settings"> </th> |
| 1980 | 2061 | </tr> |
| 1981 | 2062 | </thead> |
| 1982 | 2063 | <tbody> |
| @@ -1984,9 +2065,9 @@ | ||
| 1984 | 2065 | $args = array( |
| 1985 | 2066 | 'hide_empty' => false, |
| 1986 | 2067 | 'parent' => 0 |
| 1987 | 2068 | ); |
| 1988 | - $terms = get_terms( 'furnished', $args ); | |
| 2069 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'furnished' ) ) ); | |
| 1989 | 2070 | |
| 1990 | 2071 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 1991 | 2072 | { |
| 1992 | 2073 | foreach ($terms as $term) |
| @@ -2042,9 +2123,9 @@ | ||
| 2042 | 2123 | </td> |
| 2043 | 2124 | </tr> |
| 2044 | 2125 | <?php foreach( array ('property_management' => __( 'Property Management', 'propertyhive' ), 'tenancy_management' => __( 'Tenancy Management', 'propertyhive' ) ) as $type => $title): ?> |
| 2045 | 2126 | <tr valign="top"> |
| 2046 | - <th scope="row" class="titledesc no-auto"><?php echo esc_html(__( $title, 'propertyhive' )); ?></th> | |
| 2127 | + <th scope="row" class="titledesc no-auto"><?php echo esc_html( $title ); ?></th> | |
| 2047 | 2128 | <td class="forminp no-auto"> |
| 2048 | 2129 | <table class="ph_customfields widefat" cellspacing="0"> |
| 2049 | 2130 | <thead> |
| 2050 | 2131 | <tr> |
| @@ -2059,9 +2140,9 @@ | ||
| 2059 | 2140 | $args = array( |
| 2060 | 2141 | 'hide_empty' => false, |
| 2061 | 2142 | 'parent' => 0 |
| 2062 | 2143 | ); |
| 2063 | - $terms = get_terms( 'management_key_date_type', $args ); | |
| 2144 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'management_key_date_type' ) ) ); | |
| 2064 | 2145 | |
| 2065 | 2146 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 2066 | 2147 | { |
| 2067 | 2148 | $recurrence_rules = get_option( 'propertyhive_key_date_type', array() ); |
| @@ -2182,9 +2263,9 @@ | ||
| 2182 | 2263 | <tr> |
| 2183 | 2264 | <th class="cb" style="width:1px;"><input class="select_all" type="checkbox" style="margin: 2px 0 0 0;"></th> |
| 2184 | 2265 | <th class="id" style="width:45px;"><?php echo esc_html(__( 'ID', 'propertyhive' )); ?></th> |
| 2185 | 2266 | <th class="type"><?php echo esc_html(__( 'Marketing Flag', 'propertyhive' )); ?></th> |
| 2186 | - <th class="assigned_count"><?php echo esc_html(__( $this::LINKED_POSTS_COLUMN_HEADING, 'propertyhive' )); ?></th> | |
| 2267 | + <th class="assigned_count"><?php echo esc_html(__( 'Assigned Properties', 'propertyhive' )); ?></th> | |
| 2187 | 2268 | <th class="settings"> </th> |
| 2188 | 2269 | </tr> |
| 2189 | 2270 | </thead> |
| 2190 | 2271 | <tbody> |
| @@ -2192,9 +2273,9 @@ | ||
| 2192 | 2273 | $args = array( |
| 2193 | 2274 | 'hide_empty' => false, |
| 2194 | 2275 | 'parent' => 0 |
| 2195 | 2276 | ); |
| 2196 | - $terms = get_terms( 'marketing_flag', $args ); | |
| 2277 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'marketing_flag' ) ) ); | |
| 2197 | 2278 | |
| 2198 | 2279 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 2199 | 2280 | { |
| 2200 | 2281 | foreach ($terms as $term) |
| @@ -2264,9 +2345,9 @@ | ||
| 2264 | 2345 | <tr> |
| 2265 | 2346 | <th class="cb" style="width:1px;"><input class="select_all" type="checkbox" style="margin: 2px 0 0 0;"></th> |
| 2266 | 2347 | <th class="id" style="width:45px;"><?php echo esc_html(__( 'ID', 'propertyhive' )); ?></th> |
| 2267 | 2348 | <th class="type"><?php echo esc_html(__( 'Property Feature', 'propertyhive' )); ?></th> |
| 2268 | - <th class="assigned_count"><?php echo esc_html(__( $this::LINKED_POSTS_COLUMN_HEADING, 'propertyhive' )); ?></th> | |
| 2349 | + <th class="assigned_count"><?php echo esc_html(__( 'Assigned Properties', 'propertyhive' )); ?></th> | |
| 2269 | 2350 | <th class="settings"> </th> |
| 2270 | 2351 | </tr> |
| 2271 | 2352 | </thead> |
| 2272 | 2353 | <tbody> |
| @@ -2274,9 +2355,9 @@ | ||
| 2274 | 2355 | $args = array( |
| 2275 | 2356 | 'hide_empty' => false, |
| 2276 | 2357 | 'parent' => 0 |
| 2277 | 2358 | ); |
| 2278 | - $terms = get_terms( 'property_feature', $args ); | |
| 2359 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'property_feature' ) ) ); | |
| 2279 | 2360 | |
| 2280 | 2361 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 2281 | 2362 | { |
| 2282 | 2363 | foreach ($terms as $term) |
| @@ -2327,9 +2408,10 @@ | ||
| 2327 | 2408 | * @return string |
| 2328 | 2409 | */ |
| 2329 | 2410 | public function get_custom_fields_availability_setting() |
| 2330 | 2411 | { |
| 2331 | - $current_id = empty( $_REQUEST['id'] ) ? '' : (int)$_REQUEST['id']; | |
| 2412 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This getter only renders stored taxonomy settings and does not mutate state. | |
| 2413 | + $current_id = $this->normalize_custom_fields_render_term_id( ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['id'] ) ) : '' ); | |
| 2332 | 2414 | |
| 2333 | 2415 | $taxonomy = 'availability'; |
| 2334 | 2416 | $term_name = ''; |
| 2335 | 2417 | if ($current_id != '') |
| @@ -2341,9 +2423,9 @@ | ||
| 2341 | 2423 | $departments = ph_get_departments(); |
| 2342 | 2424 | |
| 2343 | 2425 | $args = array( |
| 2344 | 2426 | |
| 2345 | - array( 'title' => __( ( $current_id == '' ? 'Add New Availability Option' : 'Edit Availability' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_availability_settings' ), | |
| 2427 | + array( 'title' => ( $current_id == '' ? __( 'Add New Availability Option', 'propertyhive' ) : __( 'Edit Availability', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_availability_settings' ), | |
| 2346 | 2428 | |
| 2347 | 2429 | array( |
| 2348 | 2430 | 'title' => __( 'Availability', 'propertyhive' ), |
| 2349 | 2431 | 'id' => 'availability_name', |
| @@ -2395,9 +2477,10 @@ | ||
| 2395 | 2477 | * @return string |
| 2396 | 2478 | */ |
| 2397 | 2479 | public function get_custom_fields_property_type_setting() |
| 2398 | 2480 | { |
| 2399 | - $current_id = empty( $_REQUEST['id'] ) ? '' : (int)$_REQUEST['id']; | |
| 2481 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This getter only renders stored taxonomy settings and does not mutate state. | |
| 2482 | + $current_id = $this->normalize_custom_fields_render_term_id( ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['id'] ) ) : '' ); | |
| 2400 | 2483 | |
| 2401 | 2484 | $taxonomy = 'property_type'; |
| 2402 | 2485 | $term_name = ''; |
| 2403 | 2486 | $term_parent = ''; |
| @@ -2412,11 +2495,12 @@ | ||
| 2412 | 2495 | |
| 2413 | 2496 | $args = array( |
| 2414 | 2497 | 'hide_empty' => false, |
| 2415 | 2498 | 'parent' => 0, |
| 2499 | + // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- Edit screens exclude only the currently edited term from its own parent choices. Each line is exclude=>array($current_id), where current_id is cast to int from the request; one term ID prevents self-parenting. | |
| 2416 | 2500 | 'exclude' => array($current_id) |
| 2417 | 2501 | ); |
| 2418 | - $terms = get_terms( 'property_type', $args ); | |
| 2502 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'property_type' ) ) ); | |
| 2419 | 2503 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 2420 | 2504 | { |
| 2421 | 2505 | foreach ($terms as $term) |
| 2422 | 2506 | { |
| @@ -2425,9 +2509,9 @@ | ||
| 2425 | 2509 | } |
| 2426 | 2510 | |
| 2427 | 2511 | $args = array( |
| 2428 | 2512 | |
| 2429 | - array( 'title' => __( ( $current_id == '' ? 'Add New Property Type' : 'Edit Property Type' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_property_type_settings' ), | |
| 2513 | + array( 'title' => ( $current_id == '' ? __( 'Add New Property Type', 'propertyhive' ) : __( 'Edit Property Type', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_property_type_settings' ), | |
| 2430 | 2514 | |
| 2431 | 2515 | array( |
| 2432 | 2516 | 'title' => __( 'Property Type', 'propertyhive' ), |
| 2433 | 2517 | 'id' => 'property_type_name', |
| @@ -2466,9 +2550,10 @@ | ||
| 2466 | 2550 | * @return string |
| 2467 | 2551 | */ |
| 2468 | 2552 | public function get_custom_fields_commercial_property_type_setting() |
| 2469 | 2553 | { |
| 2470 | - $current_id = empty( $_REQUEST['id'] ) ? '' : (int)$_REQUEST['id']; | |
| 2554 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This getter only renders stored taxonomy settings and does not mutate state. | |
| 2555 | + $current_id = $this->normalize_custom_fields_render_term_id( ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['id'] ) ) : '' ); | |
| 2471 | 2556 | |
| 2472 | 2557 | $taxonomy = 'commercial_property_type'; |
| 2473 | 2558 | $term_name = ''; |
| 2474 | 2559 | $term_parent = ''; |
| @@ -2483,11 +2568,12 @@ | ||
| 2483 | 2568 | |
| 2484 | 2569 | $args = array( |
| 2485 | 2570 | 'hide_empty' => false, |
| 2486 | 2571 | 'parent' => 0, |
| 2572 | + // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- Edit screens exclude only the currently edited term from its own parent choices. Each line is exclude=>array($current_id), where current_id is cast to int from the request; one term ID prevents self-parenting. | |
| 2487 | 2573 | 'exclude' => array($current_id) |
| 2488 | 2574 | ); |
| 2489 | - $terms = get_terms( 'commercial_property_type', $args ); | |
| 2575 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => 'commercial_property_type' ) ) ); | |
| 2490 | 2576 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 2491 | 2577 | { |
| 2492 | 2578 | foreach ($terms as $term) |
| 2493 | 2579 | { |
| @@ -2496,9 +2582,9 @@ | ||
| 2496 | 2582 | } |
| 2497 | 2583 | |
| 2498 | 2584 | $args = array( |
| 2499 | 2585 | |
| 2500 | - array( 'title' => __( ( $current_id == '' ? 'Add New Property Type' : 'Edit Property Type' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_commercial_property_type_settings' ), | |
| 2586 | + array( 'title' => ( $current_id == '' ? __( 'Add New Property Type', 'propertyhive' ) : __( 'Edit Property Type', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_commercial_property_type_settings' ), | |
| 2501 | 2587 | |
| 2502 | 2588 | array( |
| 2503 | 2589 | 'title' => __( 'Property Type', 'propertyhive' ), |
| 2504 | 2590 | 'id' => 'commercial_property_type_name', |
| @@ -2537,9 +2623,10 @@ | ||
| 2537 | 2623 | * @return string |
| 2538 | 2624 | */ |
| 2539 | 2625 | public function get_custom_fields_location_setting() |
| 2540 | 2626 | { |
| 2541 | - $current_id = empty( $_REQUEST['id'] ) ? '' : (int)$_REQUEST['id']; | |
| 2627 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This getter only renders stored taxonomy settings and does not mutate state. | |
| 2628 | + $current_id = $this->normalize_custom_fields_render_term_id( ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['id'] ) ) : '' ); | |
| 2542 | 2629 | |
| 2543 | 2630 | $taxonomy = 'location'; |
| 2544 | 2631 | $term_name = ''; |
| 2545 | 2632 | $term_parent = ''; |
| @@ -2554,11 +2641,12 @@ | ||
| 2554 | 2641 | |
| 2555 | 2642 | $args = array( |
| 2556 | 2643 | 'hide_empty' => false, |
| 2557 | 2644 | 'parent' => 0, |
| 2645 | + // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- Edit screens exclude only the currently edited term from its own parent choices. Each line is exclude=>array($current_id), where current_id is cast to int from the request; one term ID prevents self-parenting. | |
| 2558 | 2646 | 'exclude' => array($current_id) |
| 2559 | 2647 | ); |
| 2560 | - $terms = get_terms( $taxonomy, $args ); | |
| 2648 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => $taxonomy ) ) ); | |
| 2561 | 2649 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 2562 | 2650 | { |
| 2563 | 2651 | foreach ($terms as $term) |
| 2564 | 2652 | { |
| @@ -2566,11 +2654,12 @@ | ||
| 2566 | 2654 | |
| 2567 | 2655 | $args = array( |
| 2568 | 2656 | 'hide_empty' => false, |
| 2569 | 2657 | 'parent' => $term->term_id, |
| 2658 | + // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- Edit screens exclude only the currently edited term from its own parent choices. Each line is exclude=>array($current_id), where current_id is cast to int from the request; one term ID prevents self-parenting. | |
| 2570 | 2659 | 'exclude' => array($current_id) |
| 2571 | 2660 | ); |
| 2572 | - $terms = get_terms( $taxonomy, $args ); | |
| 2661 | + $terms = get_terms( array_merge( wp_parse_args( $args ), array( 'taxonomy' => $taxonomy ) ) ); | |
| 2573 | 2662 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 2574 | 2663 | { |
| 2575 | 2664 | foreach ($terms as $term) |
| 2576 | 2665 | { |
| @@ -2581,9 +2670,9 @@ | ||
| 2581 | 2670 | } |
| 2582 | 2671 | |
| 2583 | 2672 | $args = array( |
| 2584 | 2673 | |
| 2585 | - array( 'title' => __( ( $current_id == '' ? 'Add New Location' : 'Edit Location' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_location_settings' ), | |
| 2674 | + array( 'title' => ( $current_id == '' ? __( 'Add New Location', 'propertyhive' ) : __( 'Edit Location', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_location_settings' ), | |
| 2586 | 2675 | |
| 2587 | 2676 | array( |
| 2588 | 2677 | 'title' => __( 'Location', 'propertyhive' ), |
| 2589 | 2678 | 'id' => 'location_name', |
| @@ -2622,9 +2711,10 @@ | ||
| 2622 | 2711 | * @return string |
| 2623 | 2712 | */ |
| 2624 | 2713 | public function get_custom_fields_parking_setting() |
| 2625 | 2714 | { |
| 2626 | - $current_id = empty( $_REQUEST['id'] ) ? '' : (int)$_REQUEST['id']; | |
| 2715 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This getter only renders stored taxonomy settings and does not mutate state. | |
| 2716 | + $current_id = $this->normalize_custom_fields_render_term_id( ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['id'] ) ) : '' ); | |
| 2627 | 2717 | |
| 2628 | 2718 | $taxonomy = 'parking'; |
| 2629 | 2719 | $term_name = ''; |
| 2630 | 2720 | if ($current_id != '') |
| @@ -2634,9 +2724,9 @@ | ||
| 2634 | 2724 | } |
| 2635 | 2725 | |
| 2636 | 2726 | $args = array( |
| 2637 | 2727 | |
| 2638 | - array( 'title' => __( ( $current_id == '' ? 'Add New Parking Option' : 'Edit Parking' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_parking_settings' ), | |
| 2728 | + array( 'title' => ( $current_id == '' ? __( 'Add New Parking Option', 'propertyhive' ) : __( 'Edit Parking', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_parking_settings' ), | |
| 2639 | 2729 | |
| 2640 | 2730 | array( |
| 2641 | 2731 | 'title' => __( 'Parking', 'propertyhive' ), |
| 2642 | 2732 | 'id' => 'parking_name', |
| @@ -2665,9 +2755,10 @@ | ||
| 2665 | 2755 | * @return string |
| 2666 | 2756 | */ |
| 2667 | 2757 | public function get_custom_fields_outside_space_setting() |
| 2668 | 2758 | { |
| 2669 | - $current_id = empty( $_REQUEST['id'] ) ? '' : (int)$_REQUEST['id']; | |
| 2759 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This getter only renders stored taxonomy settings and does not mutate state. | |
| 2760 | + $current_id = $this->normalize_custom_fields_render_term_id( ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_text_field( wp_unslash( $_REQUEST['id'] ) ) : '' ); | |
| 2670 | 2761 | |
| 2671 | 2762 | $taxonomy = 'outside_space'; |
| 2672 | 2763 | $term_name = ''; |
| 2673 | 2764 | if ($current_id != '') |
| @@ -2677,9 +2768,9 @@ | ||
| 2677 | 2768 | } |
| 2678 | 2769 | |
| 2679 | 2770 | $args = array( |
| 2680 | 2771 | |
| 2681 | - array( 'title' => __( ( $current_id == '' ? 'Add New Outside Space' : 'Edit Outside Space' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_outside_space_settings' ), | |
| 2772 | + array( 'title' => ( $current_id == '' ? __( 'Add New Outside Space', 'propertyhive' ) : __( 'Edit Outside Space', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_outside_space_settings' ), | |
| 2682 | 2773 | |
| 2683 | 2774 | array( |
| 2684 | 2775 | 'title' => __( 'Outside Space', 'propertyhive' ), |
| 2685 | 2776 | 'id' => 'outside_space_name', |
| @@ -2710,20 +2801,26 @@ | ||
| 2710 | 2801 | public function get_custom_fields_delete($current_id, $taxonomy, $taxonomy_name) |
| 2711 | 2802 | { |
| 2712 | 2803 | global $save_button_text; |
| 2713 | 2804 | |
| 2805 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Shared admin settings-view state; this global is intentionally used to control the common settings template and is not an arbitrary application global. | |
| 2714 | 2806 | $save_button_text = __( 'Delete', 'propertyhive' ); |
| 2715 | 2807 | |
| 2716 | 2808 | //$taxonomy = 'outside_space'; |
| 2717 | 2809 | //$taxonomy_name = __( 'Outside Space', 'propertyhive' ); |
| 2718 | 2810 | |
| 2719 | - if ( isset($_POST['confirm_removal']) && $_POST['confirm_removal'] == 1 ) | |
| 2811 | + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- This branch only selects a read-only success view; the deletion mutation occurs in save() after the settings nonce and capability checks. | |
| 2812 | + $confirm_removal = ( isset( $_POST['confirm_removal'] ) && is_string( $_POST['confirm_removal'] ) ) ? sanitize_text_field( wp_unslash( $_POST['confirm_removal'] ) ) : ''; | |
| 2813 | + if ( '1' === $confirm_removal ) | |
| 2720 | 2814 | { |
| 2721 | 2815 | // A term has just been deleted |
| 2722 | 2816 | global $hide_save_button, $show_cancel_button, $cancel_button_href; |
| 2723 | 2817 | |
| 2818 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Shared admin settings-view state; this global is intentionally used to control the common settings template and is not an arbitrary application global. | |
| 2724 | 2819 | $hide_save_button = TRUE; |
| 2820 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Shared admin settings-view state; this global is intentionally used to control the common settings template and is not an arbitrary application global. | |
| 2725 | 2821 | $show_cancel_button = TRUE; |
| 2822 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Shared admin settings-view state; this global is intentionally used to control the common settings template and is not an arbitrary application global. | |
| 2726 | 2823 | $cancel_button_href = admin_url( 'admin.php?page=ph-settings&tab=customfields§ion=' . str_replace("_", "-", $taxonomy) ); |
| 2727 | 2824 | |
| 2728 | 2825 | $args = array(); |
| 2729 | 2826 | |
| @@ -2770,8 +2867,9 @@ | ||
| 2770 | 2867 | $query_args = array( |
| 2771 | 2868 | 'post_type' => 'property', |
| 2772 | 2869 | 'nopaging' => true, |
| 2773 | 2870 | 'post_status' => array( 'pending', 'auto-draft', 'draft', 'private', 'publish', 'future', 'trash' ), |
| 2871 | + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- Term deletion/reassignment must locate all properties or key dates attached to this selected term before removing it. | |
| 2774 | 2872 | 'tax_query' => array( |
| 2775 | 2873 | array( |
| 2776 | 2874 | 'taxonomy' => $taxonomy, |
| 2777 | 2875 | 'field' => 'id', |
| @@ -2792,8 +2890,9 @@ | ||
| 2792 | 2890 | $query_args = array( |
| 2793 | 2891 | 'post_type' => 'contact', |
| 2794 | 2892 | 'nopaging' => true, |
| 2795 | 2893 | 'post_status' => array( 'pending', 'auto-draft', 'draft', 'private', 'publish', 'future', 'trash' ), |
| 2894 | + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Applicant preferences are serialized profile metadata; deletion/reassignment must inspect every applicant profile to preserve its other selections. | |
| 2796 | 2895 | 'meta_query' => array( |
| 2797 | 2896 | array( |
| 2798 | 2897 | 'key' => '_contact_types', |
| 2799 | 2898 | 'value' => 'applicant', |
| @@ -2850,8 +2949,9 @@ | ||
| 2850 | 2949 | $query_args = array( |
| 2851 | 2950 | 'post_type' => 'key_date', |
| 2852 | 2951 | 'nopaging' => true, |
| 2853 | 2952 | 'post_status' => array( 'pending', 'auto-draft', 'draft', 'private', 'publish', 'future', 'trash' ), |
| 2953 | + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- Term deletion/reassignment must locate all properties or key dates attached to this selected term before removing it. | |
| 2854 | 2954 | 'tax_query' => array( |
| 2855 | 2955 | array( |
| 2856 | 2956 | 'taxonomy' => $taxonomy, |
| 2857 | 2957 | 'field' => 'id', |
| @@ -2873,12 +2973,13 @@ | ||
| 2873 | 2973 | $alternative_terms['none'] = '-- ' . __( 'Don\'t Reassign', 'propertyhive' ) . ' --'; |
| 2874 | 2974 | |
| 2875 | 2975 | $term_args = array( |
| 2876 | 2976 | 'hide_empty' => false, |
| 2977 | + // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- This is a get_terms argument excluding the terms being deleted from reassignment choices, not a posts exclusion query. | |
| 2877 | 2978 | 'exclude' => $term_ids, |
| 2878 | 2979 | 'parent' => 0 |
| 2879 | 2980 | ); |
| 2880 | - $terms = get_terms( $taxonomy, $term_args ); | |
| 2981 | + $terms = get_terms( array_merge( wp_parse_args( $term_args ), array( 'taxonomy' => $taxonomy ) ) ); | |
| 2881 | 2982 | |
| 2882 | 2983 | if ( !empty( $terms ) && !is_wp_error( $terms ) ) |
| 2883 | 2984 | { |
| 2884 | 2985 | foreach ($terms as $term) |
| @@ -2886,12 +2987,13 @@ | ||
| 2886 | 2987 | $alternative_terms[$term->term_id] = $term->name; |
| 2887 | 2988 | |
| 2888 | 2989 | $term_args = array( |
| 2889 | 2990 | 'hide_empty' => false, |
| 2991 | + // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- This is a get_terms argument excluding the terms being deleted from reassignment choices, not a posts exclusion query. | |
| 2890 | 2992 | 'exclude' => $term_ids, |
| 2891 | 2993 | 'parent' => $term->term_id |
| 2892 | 2994 | ); |
| 2893 | - $subterms = get_terms( $taxonomy, $term_args ); | |
| 2995 | + $subterms = get_terms( array_merge( wp_parse_args( $term_args ), array( 'taxonomy' => $taxonomy ) ) ); | |
| 2894 | 2996 | |
| 2895 | 2997 | if ( !empty( $subterms ) && !is_wp_error( $subterms ) ) |
| 2896 | 2998 | { |
| 2897 | 2999 | foreach ($subterms as $term) |
| @@ -2899,12 +3001,13 @@ | ||
| 2899 | 3001 | $alternative_terms[$term->term_id] = '- ' . $term->name; |
| 2900 | 3002 | |
| 2901 | 3003 | $term_args = array( |
| 2902 | 3004 | 'hide_empty' => false, |
| 3005 | + // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- This is a get_terms argument excluding the terms being deleted from reassignment choices, not a posts exclusion query. | |
| 2903 | 3006 | 'exclude' => $term_ids, |
| 2904 | 3007 | 'parent' => $term->term_id |
| 2905 | 3008 | ); |
| 2906 | - $subsubterms = get_terms( $taxonomy, $term_args ); | |
| 3009 | + $subsubterms = get_terms( array_merge( wp_parse_args( $term_args ), array( 'taxonomy' => $taxonomy ) ) ); | |
| 2907 | 3010 | |
| 2908 | 3011 | if ( !empty( $subsubterms ) && !is_wp_error( $subsubterms ) ) |
| 2909 | 3012 | { |
| 2910 | 3013 | foreach ($subsubterms as $term) |
| @@ -2962,9 +3065,10 @@ | ||
| 2962 | 3065 | * @return string |
| 2963 | 3066 | */ |
| 2964 | 3067 | public function get_custom_fields_price_qualifier_setting() |
| 2965 | 3068 | { |
| 2966 | - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] ); | |
| 3069 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This settings getter only loads stored configuration for rendering; it does not mutate state. | |
| 3070 | + $current_id = ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_title( wp_unslash( $_REQUEST['id'] ) ) : ''; | |
| 2967 | 3071 | |
| 2968 | 3072 | $taxonomy = 'price_qualifier'; |
| 2969 | 3073 | $term_name = ''; |
| 2970 | 3074 | if ($current_id != '') |
| @@ -2974,9 +3078,9 @@ | ||
| 2974 | 3078 | } |
| 2975 | 3079 | |
| 2976 | 3080 | $args = array( |
| 2977 | 3081 | |
| 2978 | - array( 'title' => __( ( $current_id == '' ? 'Add New Price Qualifier' : 'Edit Price Qualifier' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_price_qualifier_settings' ), | |
| 3082 | + array( 'title' => ( $current_id == '' ? __( 'Add New Price Qualifier', 'propertyhive' ) : __( 'Edit Price Qualifier', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_price_qualifier_settings' ), | |
| 2979 | 3083 | |
| 2980 | 3084 | array( |
| 2981 | 3085 | 'title' => __( 'Price Qualifier', 'propertyhive' ), |
| 2982 | 3086 | 'id' => 'price_qualifier_name', |
| @@ -3005,9 +3109,10 @@ | ||
| 3005 | 3109 | * @return string |
| 3006 | 3110 | */ |
| 3007 | 3111 | public function get_custom_fields_sale_by_setting() |
| 3008 | 3112 | { |
| 3009 | - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] ); | |
| 3113 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This settings getter only loads stored configuration for rendering; it does not mutate state. | |
| 3114 | + $current_id = ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_title( wp_unslash( $_REQUEST['id'] ) ) : ''; | |
| 3010 | 3115 | |
| 3011 | 3116 | $taxonomy = 'sale_by'; |
| 3012 | 3117 | $term_name = ''; |
| 3013 | 3118 | if ($current_id != '') |
| @@ -3017,9 +3122,9 @@ | ||
| 3017 | 3122 | } |
| 3018 | 3123 | |
| 3019 | 3124 | $args = array( |
| 3020 | 3125 | |
| 3021 | - array( 'title' => __( ( $current_id == '' ? 'Add New Sale By' : 'Edit Sale By' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_sale_by_settings' ), | |
| 3126 | + array( 'title' => ( $current_id == '' ? __( 'Add New Sale By', 'propertyhive' ) : __( 'Edit Sale By', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_sale_by_settings' ), | |
| 3022 | 3127 | |
| 3023 | 3128 | array( |
| 3024 | 3129 | 'title' => __( 'Sale By', 'propertyhive' ), |
| 3025 | 3130 | 'id' => 'sale_by_name', |
| @@ -3048,9 +3153,10 @@ | ||
| 3048 | 3153 | * @return string |
| 3049 | 3154 | */ |
| 3050 | 3155 | public function get_custom_fields_tenure_setting() |
| 3051 | 3156 | { |
| 3052 | - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] ); | |
| 3157 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This settings getter only loads stored configuration for rendering; it does not mutate state. | |
| 3158 | + $current_id = ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_title( wp_unslash( $_REQUEST['id'] ) ) : ''; | |
| 3053 | 3159 | |
| 3054 | 3160 | $taxonomy = 'tenure'; |
| 3055 | 3161 | $term_name = ''; |
| 3056 | 3162 | if ($current_id != '') |
| @@ -3060,9 +3166,9 @@ | ||
| 3060 | 3166 | } |
| 3061 | 3167 | |
| 3062 | 3168 | $args = array( |
| 3063 | 3169 | |
| 3064 | - array( 'title' => __( ( $current_id == '' ? 'Add New Tenure' : 'Edit Tenure' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_tenure_settings' ), | |
| 3170 | + array( 'title' => ( $current_id == '' ? __( 'Add New Tenure', 'propertyhive' ) : __( 'Edit Tenure', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_tenure_settings' ), | |
| 3065 | 3171 | |
| 3066 | 3172 | array( |
| 3067 | 3173 | 'title' => __( 'Tenure', 'propertyhive' ), |
| 3068 | 3174 | 'id' => 'tenure_name', |
| @@ -3091,9 +3197,10 @@ | ||
| 3091 | 3197 | * @return string |
| 3092 | 3198 | */ |
| 3093 | 3199 | public function get_custom_fields_commercial_tenure_setting() |
| 3094 | 3200 | { |
| 3095 | - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] ); | |
| 3201 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This settings getter only loads stored configuration for rendering; it does not mutate state. | |
| 3202 | + $current_id = ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_title( wp_unslash( $_REQUEST['id'] ) ) : ''; | |
| 3096 | 3203 | |
| 3097 | 3204 | $taxonomy = 'commercial_tenure'; |
| 3098 | 3205 | $term_name = ''; |
| 3099 | 3206 | if ($current_id != '') |
| @@ -3103,9 +3210,9 @@ | ||
| 3103 | 3210 | } |
| 3104 | 3211 | |
| 3105 | 3212 | $args = array( |
| 3106 | 3213 | |
| 3107 | - array( 'title' => __( ( $current_id == '' ? 'Add New Tenure' : 'Edit Tenure' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_commercial_tenure_settings' ), | |
| 3214 | + array( 'title' => ( $current_id == '' ? __( 'Add New Tenure', 'propertyhive' ) : __( 'Edit Tenure', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_commercial_tenure_settings' ), | |
| 3108 | 3215 | |
| 3109 | 3216 | array( |
| 3110 | 3217 | 'title' => __( 'Tenure', 'propertyhive' ), |
| 3111 | 3218 | 'id' => 'commercial_tenure_name', |
| @@ -3134,9 +3241,10 @@ | ||
| 3134 | 3241 | * @return string |
| 3135 | 3242 | */ |
| 3136 | 3243 | public function get_custom_fields_furnished_setting() |
| 3137 | 3244 | { |
| 3138 | - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] ); | |
| 3245 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This settings getter only loads stored configuration for rendering; it does not mutate state. | |
| 3246 | + $current_id = ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_title( wp_unslash( $_REQUEST['id'] ) ) : ''; | |
| 3139 | 3247 | |
| 3140 | 3248 | $taxonomy = 'furnished'; |
| 3141 | 3249 | $term_name = ''; |
| 3142 | 3250 | if ($current_id != '') |
| @@ -3146,9 +3254,9 @@ | ||
| 3146 | 3254 | } |
| 3147 | 3255 | |
| 3148 | 3256 | $args = array( |
| 3149 | 3257 | |
| 3150 | - array( 'title' => __( ( $current_id == '' ? 'Add New Furnished' : 'Edit Furnished' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_furnished_settings' ), | |
| 3258 | + array( 'title' => ( $current_id == '' ? __( 'Add New Furnished', 'propertyhive' ) : __( 'Edit Furnished', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_furnished_settings' ), | |
| 3151 | 3259 | |
| 3152 | 3260 | array( |
| 3153 | 3261 | 'title' => __( 'Furnished', 'propertyhive' ), |
| 3154 | 3262 | 'id' => 'furnished_name', |
| @@ -3176,9 +3284,10 @@ | ||
| 3176 | 3284 | * @return string |
| 3177 | 3285 | */ |
| 3178 | 3286 | public function get_custom_fields_management_key_date_type_setting() |
| 3179 | 3287 | { |
| 3180 | - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] ); | |
| 3288 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This settings getter only loads stored configuration for rendering; it does not mutate state. | |
| 3289 | + $current_id = ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_title( wp_unslash( $_REQUEST['id'] ) ) : ''; | |
| 3181 | 3290 | |
| 3182 | 3291 | $taxonomy = 'management_key_date_type'; |
| 3183 | 3292 | $term_name = ''; |
| 3184 | 3293 | if ($current_id != '') |
| @@ -3211,9 +3320,9 @@ | ||
| 3211 | 3320 | $interval_disabled = $recurrence['FREQ'] == 'ONCE' ? array('disabled' => 'disabled') : array(); |
| 3212 | 3321 | |
| 3213 | 3322 | $args = array( |
| 3214 | 3323 | |
| 3215 | - array( 'title' => __( ( $current_id == '' ? 'Add New Management Date Type' : 'Edit Management Date Type' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_management_key_date_type_settings' ), | |
| 3324 | + array( 'title' => ( $current_id == '' ? __( 'Add New Management Date Type', 'propertyhive' ) : __( 'Edit Management Date Type', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_management_key_date_type_settings' ), | |
| 3216 | 3325 | |
| 3217 | 3326 | array( |
| 3218 | 3327 | 'title' => __( 'Description', 'propertyhive' ), |
| 3219 | 3328 | 'id' => 'management_key_date_type_name', |
| @@ -3281,9 +3390,10 @@ | ||
| 3281 | 3390 | * @return string |
| 3282 | 3391 | */ |
| 3283 | 3392 | public function get_custom_fields_marketing_flag_setting() |
| 3284 | 3393 | { |
| 3285 | - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] ); | |
| 3394 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This settings getter only loads stored configuration for rendering; it does not mutate state. | |
| 3395 | + $current_id = ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_title( wp_unslash( $_REQUEST['id'] ) ) : ''; | |
| 3286 | 3396 | |
| 3287 | 3397 | $taxonomy = 'marketing_flag'; |
| 3288 | 3398 | $term_name = ''; |
| 3289 | 3399 | if ($current_id != '') |
| @@ -3293,9 +3403,9 @@ | ||
| 3293 | 3403 | } |
| 3294 | 3404 | |
| 3295 | 3405 | $args = array( |
| 3296 | 3406 | |
| 3297 | - array( 'title' => __( ( $current_id == '' ? 'Add New Marketing Flag' : 'Edit Marketing Flag' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_marketing_flag_settings' ), | |
| 3407 | + array( 'title' => ( $current_id == '' ? __( 'Add New Marketing Flag', 'propertyhive' ) : __( 'Edit Marketing Flag', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_marketing_flag_settings' ), | |
| 3298 | 3408 | |
| 3299 | 3409 | array( |
| 3300 | 3410 | 'title' => __( 'Marketing Flag', 'propertyhive' ), |
| 3301 | 3411 | 'id' => 'marketing_flag_name', |
| @@ -3324,9 +3434,10 @@ | ||
| 3324 | 3434 | * @return string |
| 3325 | 3435 | */ |
| 3326 | 3436 | public function get_custom_fields_property_feature_setting() |
| 3327 | 3437 | { |
| 3328 | - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] ); | |
| 3438 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This settings getter only loads stored configuration for rendering; it does not mutate state. | |
| 3439 | + $current_id = ( isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ) ) ? sanitize_title( wp_unslash( $_REQUEST['id'] ) ) : ''; | |
| 3329 | 3440 | |
| 3330 | 3441 | $taxonomy = 'property_feature'; |
| 3331 | 3442 | $term_name = ''; |
| 3332 | 3443 | if ($current_id != '') |
| @@ -3336,9 +3447,9 @@ | ||
| 3336 | 3447 | } |
| 3337 | 3448 | |
| 3338 | 3449 | $args = array( |
| 3339 | 3450 | |
| 3340 | - array( 'title' => __( ( $current_id == '' ? 'Add New Property Feature' : 'Edit Property Feature' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_property_feature_settings' ), | |
| 3451 | + array( 'title' => ( $current_id == '' ? __( 'Add New Property Feature', 'propertyhive' ) : __( 'Edit Property Feature', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'custom_field_property_feature_settings' ), | |
| 3341 | 3452 | |
| 3342 | 3453 | array( |
| 3343 | 3454 | 'title' => __( 'Property Feature', 'propertyhive' ), |
| 3344 | 3455 | 'id' => 'property_feature_name', |
| @@ -3359,402 +3470,496 @@ | ||
| 3359 | 3470 | |
| 3360 | 3471 | return apply_filters( 'propertyhive_custom_field_property_feature_settings', $args ); |
| 3361 | 3472 | } |
| 3362 | 3473 | |
| 3474 | + private function normalize_custom_fields_field_type( $value ) { | |
| 3475 | + if ( ! is_string( $value ) ) { | |
| 3476 | + return 'text'; | |
| 3477 | + } | |
| 3478 | + | |
| 3479 | + $field_type = sanitize_key( $value ); | |
| 3480 | + $allowed_types = array( 'text', 'textarea', 'select', 'multiselect', 'checkbox', 'date', 'image', 'file' ); | |
| 3481 | + | |
| 3482 | + return in_array( $field_type, $allowed_types, true ) ? $field_type : 'text'; | |
| 3483 | + } | |
| 3484 | + | |
| 3485 | + private function normalize_custom_fields_dropdown_options( $value ) { | |
| 3486 | + if ( ! is_array( $value ) ) { | |
| 3487 | + return ''; | |
| 3488 | + } | |
| 3489 | + | |
| 3490 | + $options = array(); | |
| 3491 | + foreach ( $value as $option ) { | |
| 3492 | + if ( ! is_string( $option ) ) { | |
| 3493 | + return ''; | |
| 3494 | + } | |
| 3495 | + $options[] = sanitize_text_field( $option ); | |
| 3496 | + } | |
| 3497 | + | |
| 3498 | + return $options; | |
| 3499 | + } | |
| 3500 | + | |
| 3501 | + private function normalize_custom_fields_checkbox( $value ) { | |
| 3502 | + return ( is_string( $value ) && '1' === $value ) ? '1' : ''; | |
| 3503 | + } | |
| 3504 | + | |
| 3505 | + private function normalize_custom_fields_meta_box( $value ) { | |
| 3506 | + return is_string( $value ) ? sanitize_key( $value ) : ''; | |
| 3507 | + } | |
| 3508 | + | |
| 3509 | + private function normalize_custom_fields_term_id( $value, $allow_empty = true ) { | |
| 3510 | + if ( ! is_string( $value ) ) { | |
| 3511 | + return null; | |
| 3512 | + } | |
| 3513 | + | |
| 3514 | + $value = trim( $value ); | |
| 3515 | + if ( '' === $value ) { | |
| 3516 | + return $allow_empty ? '' : null; | |
| 3517 | + } | |
| 3518 | + | |
| 3519 | + if ( ! preg_match( '/^[0-9]+$/D', $value ) ) { | |
| 3520 | + return null; | |
| 3521 | + } | |
| 3522 | + | |
| 3523 | + $term_id = absint( $value ); | |
| 3524 | + return $term_id > 0 ? (string) $term_id : null; | |
| 3525 | + } | |
| 3526 | + | |
| 3527 | + private function normalize_custom_fields_render_term_id( $value ) { | |
| 3528 | + $term_id = $this->normalize_custom_fields_term_id( $value ); | |
| 3529 | + return ( null === $term_id || '' === $term_id ) ? '' : absint( $term_id ); | |
| 3530 | + } | |
| 3531 | + | |
| 3532 | + private function normalize_custom_fields_parent_id( $value ) { | |
| 3533 | + if ( ! is_string( $value ) ) { | |
| 3534 | + return null; | |
| 3535 | + } | |
| 3536 | + | |
| 3537 | + $value = trim( $value ); | |
| 3538 | + if ( '' === $value ) { | |
| 3539 | + return 0; | |
| 3540 | + } | |
| 3541 | + | |
| 3542 | + if ( ! preg_match( '/^[0-9]+$/D', $value ) ) { | |
| 3543 | + return null; | |
| 3544 | + } | |
| 3545 | + | |
| 3546 | + return absint( $value ); | |
| 3547 | + } | |
| 3548 | + | |
| 3549 | + private function normalize_custom_fields_term_id_list( $value ) { | |
| 3550 | + if ( ! is_string( $value ) || '' === trim( $value ) ) { | |
| 3551 | + return array(); | |
| 3552 | + } | |
| 3553 | + | |
| 3554 | + $term_ids = array(); | |
| 3555 | + foreach ( explode( '-', trim( $value ) ) as $term_id ) { | |
| 3556 | + if ( ! preg_match( '/^[0-9]+$/D', $term_id ) ) { | |
| 3557 | + return array(); | |
| 3558 | + } | |
| 3559 | + | |
| 3560 | + $term_id = absint( $term_id ); | |
| 3561 | + if ( $term_id < 1 || in_array( (string) $term_id, $term_ids, true ) ) { | |
| 3562 | + return array(); | |
| 3563 | + } | |
| 3564 | + | |
| 3565 | + $term_ids[] = (string) $term_id; | |
| 3566 | + } | |
| 3567 | + | |
| 3568 | + return $term_ids; | |
| 3569 | + } | |
| 3570 | + | |
| 3571 | + private function normalize_custom_fields_reassignment( $value, $deleted_ids ) { | |
| 3572 | + if ( ! is_string( $value ) ) { | |
| 3573 | + return null; | |
| 3574 | + } | |
| 3575 | + | |
| 3576 | + $value = trim( $value ); | |
| 3577 | + if ( '' === $value || 'none' === $value || ! preg_match( '/^[0-9]+$/D', $value ) ) { | |
| 3578 | + return null; | |
| 3579 | + } | |
| 3580 | + | |
| 3581 | + $term_id = (string) absint( $value ); | |
| 3582 | + if ( '0' === $term_id || in_array( $term_id, $deleted_ids, true ) ) { | |
| 3583 | + return null; | |
| 3584 | + } | |
| 3585 | + | |
| 3586 | + return $term_id; | |
| 3587 | + } | |
| 3588 | + | |
| 3589 | + private function get_custom_fields_taxonomy_for_section( $section ) { | |
| 3590 | + $taxonomies = array( | |
| 3591 | + 'availability' => 'availability', | |
| 3592 | + 'property-type' => 'property_type', | |
| 3593 | + 'commercial-property-type' => 'commercial_property_type', | |
| 3594 | + 'location' => 'location', | |
| 3595 | + 'parking' => 'parking', | |
| 3596 | + 'outside-space' => 'outside_space', | |
| 3597 | + 'price-qualifier' => 'price_qualifier', | |
| 3598 | + 'sale-by' => 'sale_by', | |
| 3599 | + 'tenure' => 'tenure', | |
| 3600 | + 'commercial-tenure' => 'commercial_tenure', | |
| 3601 | + 'furnished' => 'furnished', | |
| 3602 | + 'management-key-date-type' => 'management_key_date_type', | |
| 3603 | + 'marketing-flag' => 'marketing_flag', | |
| 3604 | + 'property-feature' => 'property_feature', | |
| 3605 | + ); | |
| 3606 | + | |
| 3607 | + if ( isset( $taxonomies[ $section ] ) ) { | |
| 3608 | + return $taxonomies[ $section ]; | |
| 3609 | + } | |
| 3610 | + | |
| 3611 | + if ( is_string( $section ) && '-delete' === substr( $section, -7 ) ) { | |
| 3612 | + $base_section = substr( $section, 0, -7 ); | |
| 3613 | + return isset( $taxonomies[ $base_section ] ) ? $taxonomies[ $base_section ] : ''; | |
| 3614 | + } | |
| 3615 | + | |
| 3616 | + return ''; | |
| 3617 | + } | |
| 3618 | + | |
| 3363 | 3619 | /** |
| 3364 | - * Save settings | |
| 3620 | + * Save settings. | |
| 3365 | 3621 | */ |
| 3366 | 3622 | public function save() { |
| 3623 | + if ( ! current_user_can( 'manage_options' ) || ! isset( $_REQUEST['_wpnonce'] ) || ! is_string( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'propertyhive-settings' ) ) { | |
| 3624 | + return; | |
| 3625 | + } | |
| 3626 | + | |
| 3367 | 3627 | global $current_section, $post; |
| 3368 | 3628 | |
| 3369 | - if ( $current_section != '' ) | |
| 3370 | - { | |
| 3371 | - switch ($current_section) | |
| 3372 | - { | |
| 3373 | - case "addadditionalfield": | |
| 3374 | - case "editadditionalfield": | |
| 3375 | - { | |
| 3376 | - $current_settings = get_option( 'propertyhive_template_assistant', array() ); | |
| 3629 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Existing shared settings-router global; normalization preserves the public settings page contract. | |
| 3630 | + $current_section = is_string( $current_section ) ? $current_section : ''; | |
| 3631 | + $request_id_present = isset( $_REQUEST['id'] ) && is_string( $_REQUEST['id'] ); | |
| 3632 | + $request_id = $request_id_present ? sanitize_text_field( wp_unslash( $_REQUEST['id'] ) ) : ''; | |
| 3633 | + $post_data = is_array( $_POST ) ? wp_unslash( $_POST ) : array(); | |
| 3377 | 3634 | |
| 3378 | - $current_id = ( !isset( $_REQUEST['id'] ) ) ? '' : sanitize_title( $_REQUEST['id'] ); | |
| 3635 | + if ( '' === $current_section ) { | |
| 3636 | + return; | |
| 3637 | + } | |
| 3379 | 3638 | |
| 3380 | - $existing_custom_fields = ( (isset($current_settings['custom_fields'])) ? $current_settings['custom_fields'] : array() ); | |
| 3639 | + switch ( $current_section ) { | |
| 3640 | + case 'addadditionalfield': | |
| 3641 | + case 'editadditionalfield': | |
| 3642 | + $current_settings = get_option( 'propertyhive_template_assistant', array() ); | |
| 3643 | + if ( ! is_array( $current_settings ) ) { | |
| 3644 | + $current_settings = array(); | |
| 3645 | + } | |
| 3381 | 3646 | |
| 3382 | - if ( $current_section == 'editadditionalfield' && $current_id != 'default' && !isset($existing_custom_fields[$current_id]) ) | |
| 3383 | - { | |
| 3384 | - die("Trying to edit a non-existant custom field. Please go back and try again"); | |
| 3385 | - } | |
| 3647 | + $current_id = $request_id_present ? sanitize_title( $request_id ) : ''; | |
| 3648 | + $existing_custom_fields = ( isset( $current_settings['custom_fields'] ) && is_array( $current_settings['custom_fields'] ) ) ? $current_settings['custom_fields'] : array(); | |
| 3386 | 3649 | |
| 3387 | - $field_name = trim( ( ( isset($_POST['field_name']) ) ? sanitize_title( $_POST['field_name'] ) : '' ) ); | |
| 3650 | + if ( 'editadditionalfield' === $current_section && 'default' !== $current_id && ! isset( $existing_custom_fields[ $current_id ] ) ) { | |
| 3651 | + die( 'Trying to edit a non-existant custom field. Please go back and try again' ); | |
| 3652 | + } | |
| 3388 | 3653 | |
| 3389 | - if ( $field_name == '' ) | |
| 3390 | - { | |
| 3391 | - $field_name = str_replace("-", "_", sanitize_title( $_POST['field_label'] ) ); | |
| 3392 | - } | |
| 3654 | + $field_label = ( isset( $post_data['field_label'] ) && is_string( $post_data['field_label'] ) ) ? sanitize_text_field( $post_data['field_label'] ) : ''; | |
| 3655 | + $field_name = ( isset( $post_data['field_name'] ) && is_string( $post_data['field_name'] ) ) ? sanitize_title( $post_data['field_name'] ) : ''; | |
| 3656 | + if ( '' === trim( $field_name ) ) { | |
| 3657 | + $field_name = str_replace( '-', '_', sanitize_title( $field_label ) ); | |
| 3658 | + } | |
| 3659 | + $field_name = '_' . ltrim( $field_name, '_' ); | |
| 3393 | 3660 | |
| 3394 | - $field_name = '_' . ltrim( $field_name, '_' ); | |
| 3661 | + $field_type = $this->normalize_custom_fields_field_type( isset( $post_data['field_type'] ) ? $post_data['field_type'] : '' ); | |
| 3662 | + $dropdown_options = ( in_array( $field_type, array( 'select', 'multiselect' ), true ) && isset( $post_data['dropdown_options'] ) ) ? $this->normalize_custom_fields_dropdown_options( $post_data['dropdown_options'] ) : ''; | |
| 3663 | + $field_settings = array( | |
| 3664 | + 'field_label' => $field_label, | |
| 3665 | + 'field_name' => $field_name, | |
| 3666 | + 'field_type' => $field_type, | |
| 3667 | + 'dropdown_options' => $dropdown_options, | |
| 3668 | + 'meta_box' => $this->normalize_custom_fields_meta_box( isset( $post_data['meta_box'] ) ? $post_data['meta_box'] : '' ), | |
| 3669 | + 'display_on_website' => $this->normalize_custom_fields_checkbox( isset( $post_data['display_on_website'] ) ? $post_data['display_on_website'] : '' ), | |
| 3670 | + 'display_on_applicant_requirements' => $this->normalize_custom_fields_checkbox( isset( $post_data['display_on_applicant_requirements'] ) ? $post_data['display_on_applicant_requirements'] : '' ), | |
| 3671 | + 'exact_match' => $this->normalize_custom_fields_checkbox( isset( $post_data['exact_match'] ) ? $post_data['exact_match'] : '' ), | |
| 3672 | + 'display_on_user_details' => $this->normalize_custom_fields_checkbox( isset( $post_data['display_on_user_details'] ) ? $post_data['display_on_user_details'] : '' ), | |
| 3673 | + 'admin_list' => $this->normalize_custom_fields_checkbox( isset( $post_data['admin_list'] ) ? $post_data['admin_list'] : '' ), | |
| 3674 | + 'admin_list_sortable' => $this->normalize_custom_fields_checkbox( isset( $post_data['admin_list_sortable'] ) ? $post_data['admin_list_sortable'] : '' ), | |
| 3675 | + ); | |
| 3395 | 3676 | |
| 3396 | - if ( $current_section == 'addadditionalfield' ) | |
| 3397 | - { | |
| 3398 | - $existing_custom_fields[] = array( | |
| 3399 | - 'field_label' => sanitize_text_field(wp_unslash($_POST['field_label'])), | |
| 3400 | - 'field_name' => $field_name, | |
| 3401 | - 'field_type' => ( ( isset($_POST['field_type']) && $_POST['field_type'] != '' ) ? sanitize_text_field($_POST['field_type']) : 'text' ), | |
| 3402 | - 'dropdown_options' => ( ( isset($_POST['field_type']) && ( $_POST['field_type'] == 'select' || $_POST['field_type'] == 'multiselect' ) && isset($_POST['dropdown_options']) ) ? $_POST['dropdown_options'] : '' ), | |
| 3403 | - 'meta_box' => sanitize_text_field($_POST['meta_box']), | |
| 3404 | - 'display_on_website' => ( ( isset($_POST['display_on_website']) ) ? sanitize_text_field($_POST['display_on_website']) : '' ), | |
| 3405 | - 'display_on_applicant_requirements' => ( ( isset($_POST['display_on_applicant_requirements']) ) ? sanitize_text_field($_POST['display_on_applicant_requirements']) : '' ), | |
| 3406 | - 'exact_match' => ( ( isset($_POST['exact_match']) ) ? sanitize_text_field($_POST['exact_match']) : '' ), | |
| 3407 | - 'display_on_user_details' => ( ( isset($_POST['display_on_user_details']) ) ? sanitize_text_field($_POST['display_on_user_details']) : '' ), | |
| 3408 | - 'admin_list' => ( ( isset($_POST['admin_list']) ) ? sanitize_text_field($_POST['admin_list']) : '' ), | |
| 3409 | - 'admin_list_sortable' => ( ( isset($_POST['admin_list_sortable']) ) ? sanitize_text_field($_POST['admin_list_sortable']) : '' ), | |
| 3410 | - ); | |
| 3411 | - } | |
| 3412 | - else | |
| 3413 | - { | |
| 3414 | - $existing_custom_fields[$current_id] = array( | |
| 3415 | - 'field_label' => sanitize_text_field(wp_unslash($_POST['field_label'])), | |
| 3416 | - 'field_name' => $field_name, | |
| 3417 | - 'field_type' => ( ( isset($_POST['field_type']) && $_POST['field_type'] != '' ) ? sanitize_text_field($_POST['field_type']) : 'text' ), | |
| 3418 | - 'dropdown_options' => ( ( isset($_POST['field_type']) && ( $_POST['field_type'] == 'select' || $_POST['field_type'] == 'multiselect' ) && isset($_POST['dropdown_options']) ) ? $_POST['dropdown_options'] : '' ), | |
| 3419 | - 'meta_box' => sanitize_text_field($_POST['meta_box']), | |
| 3420 | - 'display_on_website' => ( ( isset($_POST['display_on_website']) ) ? sanitize_text_field($_POST['display_on_website']) : '' ), | |
| 3421 | - 'display_on_applicant_requirements' => ( ( isset($_POST['display_on_applicant_requirements']) ) ? sanitize_text_field($_POST['display_on_applicant_requirements']) : '' ), | |
| 3422 | - 'exact_match' => ( ( isset($_POST['exact_match']) ) ? sanitize_text_field($_POST['exact_match']) : '' ), | |
| 3423 | - 'display_on_user_details' => ( ( isset($_POST['display_on_user_details']) ) ? sanitize_text_field($_POST['display_on_user_details']) : '' ), | |
| 3424 | - 'admin_list' => ( ( isset($_POST['admin_list']) ) ? sanitize_text_field($_POST['admin_list']) : '' ), | |
| 3425 | - 'admin_list_sortable' => ( ( isset($_POST['admin_list_sortable']) ) ? sanitize_text_field($_POST['admin_list_sortable']) : '' ), | |
| 3426 | - ); | |
| 3427 | - } | |
| 3677 | + if ( 'addadditionalfield' === $current_section ) { | |
| 3678 | + $existing_custom_fields[] = $field_settings; | |
| 3679 | + } else { | |
| 3680 | + $existing_custom_fields[ $current_id ] = $field_settings; | |
| 3681 | + } | |
| 3428 | 3682 | |
| 3429 | - $current_settings['custom_fields'] = $existing_custom_fields; | |
| 3683 | + $current_settings['custom_fields'] = $existing_custom_fields; | |
| 3430 | 3684 | |
| 3431 | - // see if this custom field in used in search forms and amend the type accordingly | |
| 3432 | - if ( $current_section != 'addadditionalfield' ) | |
| 3433 | - { | |
| 3434 | - if ( isset($current_settings['search_forms']) && !empty($current_settings['search_forms']) ) | |
| 3435 | - { | |
| 3436 | - foreach ( $current_settings['search_forms'] as $search_form_id => $search_form ) | |
| 3437 | - { | |
| 3438 | - // Active fields | |
| 3439 | - if ( isset($search_form['active_fields']) && !empty($search_form['active_fields']) ) | |
| 3440 | - { | |
| 3441 | - foreach ( $search_form['active_fields'] as $field_id => $field_data ) | |
| 3442 | - { | |
| 3443 | - if ( $field_name == $field_id ) | |
| 3444 | - { | |
| 3445 | - // we found this field. Set type | |
| 3446 | - $current_settings['search_forms'][$search_form_id]['active_fields'][$field_id]['type'] = ( ( isset($_POST['field_type']) && $_POST['field_type'] != '' ) ? sanitize_text_field($_POST['field_type']) : 'text' ); | |
| 3447 | - } | |
| 3448 | - } | |
| 3685 | + if ( 'addadditionalfield' !== $current_section && ! empty( $current_settings['search_forms'] ) && is_array( $current_settings['search_forms'] ) ) { | |
| 3686 | + foreach ( $current_settings['search_forms'] as $search_form_id => $search_form ) { | |
| 3687 | + if ( isset( $search_form['active_fields'] ) && is_array( $search_form['active_fields'] ) ) { | |
| 3688 | + foreach ( $search_form['active_fields'] as $field_id => $field_data ) { | |
| 3689 | + if ( $field_name === $field_id ) { | |
| 3690 | + $current_settings['search_forms'][ $search_form_id ]['active_fields'][ $field_id ]['type'] = $field_type; | |
| 3449 | 3691 | } |
| 3692 | + } | |
| 3693 | + } | |
| 3450 | 3694 | |
| 3451 | - // Inactive fields | |
| 3452 | - if ( isset($search_form['inactive_fields']) && !empty($search_form['inactive_fields']) ) | |
| 3453 | - { | |
| 3454 | - foreach ( $search_form['inactive_fields'] as $field_id => $field_data ) | |
| 3455 | - { | |
| 3456 | - if ( $field_name == $field_id ) | |
| 3457 | - { | |
| 3458 | - // we found this field. Set type | |
| 3459 | - $current_settings['search_forms'][$search_form_id]['inactive_fields'][$field_id]['type'] = ( ( isset($_POST['field_type']) && $_POST['field_type'] != '' ) ? sanitize_text_field($_POST['field_type']) : 'text' ); | |
| 3460 | - } | |
| 3461 | - } | |
| 3695 | + if ( isset( $search_form['inactive_fields'] ) && is_array( $search_form['inactive_fields'] ) ) { | |
| 3696 | + foreach ( $search_form['inactive_fields'] as $field_id => $field_data ) { | |
| 3697 | + if ( $field_name === $field_id ) { | |
| 3698 | + $current_settings['search_forms'][ $search_form_id ]['inactive_fields'][ $field_id ]['type'] = $field_type; | |
| 3462 | 3699 | } |
| 3463 | 3700 | } |
| 3464 | 3701 | } |
| 3465 | 3702 | } |
| 3703 | + } | |
| 3466 | 3704 | |
| 3467 | - update_option( 'propertyhive_template_assistant', $current_settings ); | |
| 3705 | + update_option( 'propertyhive_template_assistant', $current_settings ); | |
| 3706 | + break; | |
| 3468 | 3707 | |
| 3469 | - break; | |
| 3708 | + default: | |
| 3709 | + if ( ! $request_id_present ) { | |
| 3710 | + break; | |
| 3470 | 3711 | } |
| 3471 | - default: | |
| 3472 | - { | |
| 3473 | - if (isset($_REQUEST['id'])) // we're either adding or editing | |
| 3474 | - { | |
| 3475 | - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_text_field($_REQUEST['id']); | |
| 3476 | - | |
| 3477 | - switch ($current_section) | |
| 3478 | - { | |
| 3479 | - // With heirarchy | |
| 3480 | - case "property-type": | |
| 3481 | - case "commercial-property-type": | |
| 3482 | - case "location": | |
| 3483 | - { | |
| 3484 | - // TODO: Validate (check for blank fields) | |
| 3485 | - | |
| 3486 | - if ($current_id == '') | |
| 3487 | - { | |
| 3488 | - // Adding new term | |
| 3489 | - | |
| 3490 | - // TODO: Check term doesn't exist already | |
| 3491 | - | |
| 3492 | - wp_insert_term( | |
| 3493 | - ph_clean($_POST[ph_clean($_POST['taxonomy']) . '_name']), // the term | |
| 3494 | - ph_clean($_POST['taxonomy']), // the taxonomy | |
| 3495 | - array( | |
| 3496 | - 'parent' => $_POST['parent_' . ph_clean($_POST['taxonomy']) . '_id'] | |
| 3497 | - ) | |
| 3498 | - ); | |
| 3499 | - | |
| 3500 | - // TODO: Check for errors returned from wp_insert_term() | |
| 3501 | - } | |
| 3502 | - else | |
| 3503 | - { | |
| 3504 | - // Editing term | |
| 3505 | - wp_update_term($current_id, ph_clean($_POST['taxonomy']), array( | |
| 3506 | - 'name' => ph_clean($_POST[ph_clean($_POST['taxonomy']).'_name']), | |
| 3507 | - 'parent' => ph_clean($_POST['parent_' . $_POST['taxonomy'] . '_id']) | |
| 3508 | - )); | |
| 3509 | - | |
| 3510 | - // TODO: Check for errors returned from wp_update_term() | |
| 3511 | - } | |
| 3512 | - break; | |
| 3513 | - } | |
| 3514 | - // Without heirarchy | |
| 3515 | - case "availability": | |
| 3516 | - case "outside-space": | |
| 3517 | - case "parking": | |
| 3518 | - case "price-qualifier": | |
| 3519 | - case "sale-by": | |
| 3520 | - case "tenure": | |
| 3521 | - case "commercial-tenure": | |
| 3522 | - case "furnished": | |
| 3523 | - case "management-key-date-type": | |
| 3524 | - case "marketing-flag": | |
| 3525 | - case "property-feature": | |
| 3526 | - { | |
| 3527 | - // TODO: Validate (check for blank fields) | |
| 3528 | - | |
| 3529 | - if ($current_id == '') | |
| 3530 | - { | |
| 3531 | - // Adding new term | |
| 3532 | - | |
| 3533 | - // TODO: Check term doesn't exist already | |
| 3534 | - | |
| 3535 | - $term = wp_insert_term( | |
| 3536 | - ph_clean($_POST[ph_clean($_POST['taxonomy']) . '_name']), // the term | |
| 3537 | - $_POST['taxonomy'] // the taxonomy | |
| 3538 | - ); | |
| 3539 | - | |
| 3540 | - // TODO: Check for errors returned from wp_insert_term() | |
| 3541 | 3712 | |
| 3542 | - if ( ! is_wp_error( $term ) ) | |
| 3543 | - { | |
| 3544 | - $current_id = isset( $term['term_id'] ) ? $term['term_id'] : 0; | |
| 3545 | - } | |
| 3546 | - } | |
| 3547 | - else | |
| 3548 | - { | |
| 3549 | - // Editing term | |
| 3550 | - wp_update_term($current_id, ph_clean($_POST['taxonomy']), array( | |
| 3551 | - 'name' => ph_clean($_POST[ph_clean($_POST['taxonomy']) . '_name']) | |
| 3552 | - )); | |
| 3553 | - | |
| 3554 | - // TODO: Check for errors returned from wp_update_term() | |
| 3555 | - } | |
| 3713 | + $taxonomy = $this->get_custom_fields_taxonomy_for_section( $current_section ); | |
| 3714 | + $is_delete_section = '-delete' === substr( $current_section, -7 ); | |
| 3556 | 3715 | |
| 3557 | - if ( $current_section == 'availability' ) | |
| 3558 | - { | |
| 3559 | - $availability_departments = get_option( 'propertyhive_availability_departments', array() ); | |
| 3560 | - if ( !is_array($availability_departments) ) { $availability_departments = array(); } | |
| 3716 | + if ( '' !== $taxonomy ) { | |
| 3717 | + if ( $is_delete_section ) { | |
| 3718 | + $term_ids = $this->normalize_custom_fields_term_id_list( $request_id ); | |
| 3719 | + if ( empty( $term_ids ) ) { | |
| 3720 | + return; | |
| 3721 | + } | |
| 3722 | + $current_id = implode( '-', $term_ids ); | |
| 3723 | + } else { | |
| 3724 | + $current_id = $this->normalize_custom_fields_term_id( $request_id ); | |
| 3725 | + if ( null === $current_id ) { | |
| 3726 | + return; | |
| 3727 | + } | |
| 3728 | + } | |
| 3729 | + } else { | |
| 3730 | + $current_id = sanitize_text_field( $request_id ); | |
| 3731 | + } | |
| 3561 | 3732 | |
| 3562 | - $departments = ph_get_departments(); | |
| 3733 | + switch ( $current_section ) { | |
| 3734 | + case 'property-type': | |
| 3735 | + case 'commercial-property-type': | |
| 3736 | + case 'location': | |
| 3737 | + $term_name_key = $taxonomy . '_name'; | |
| 3738 | + $parent_key = 'parent_' . $taxonomy . '_id'; | |
| 3739 | + $term_name = ( isset( $post_data[ $term_name_key ] ) && is_string( $post_data[ $term_name_key ] ) ) ? sanitize_text_field( $post_data[ $term_name_key ] ) : ''; | |
| 3740 | + $parent_id = $this->normalize_custom_fields_parent_id( isset( $post_data[ $parent_key ] ) ? $post_data[ $parent_key ] : '' ); | |
| 3741 | + if ( '' === $term_name || null === $parent_id ) { | |
| 3742 | + return; | |
| 3743 | + } | |
| 3563 | 3744 | |
| 3564 | - $availability_departments[$current_id] = array(); | |
| 3565 | - foreach ( $departments as $key => $value ) | |
| 3566 | - { | |
| 3567 | - if ( isset($_POST['department'][$key]) && $_POST['department'][$key] == '1' ) | |
| 3568 | - { | |
| 3569 | - $availability_departments[$current_id][] = $key; | |
| 3570 | - } | |
| 3571 | - } | |
| 3745 | + if ( '' === $current_id ) { | |
| 3746 | + wp_insert_term( | |
| 3747 | + $term_name, | |
| 3748 | + $taxonomy, | |
| 3749 | + array( 'parent' => $parent_id ) | |
| 3750 | + ); | |
| 3751 | + } else { | |
| 3752 | + wp_update_term( | |
| 3753 | + absint( $current_id ), | |
| 3754 | + $taxonomy, | |
| 3755 | + array( | |
| 3756 | + 'name' => $term_name, | |
| 3757 | + 'parent' => $parent_id, | |
| 3758 | + ) | |
| 3759 | + ); | |
| 3760 | + } | |
| 3761 | + break; | |
| 3572 | 3762 | |
| 3573 | - update_option( 'propertyhive_availability_departments', $availability_departments ); | |
| 3763 | + case 'availability': | |
| 3764 | + case 'outside-space': | |
| 3765 | + case 'parking': | |
| 3766 | + case 'price-qualifier': | |
| 3767 | + case 'sale-by': | |
| 3768 | + case 'tenure': | |
| 3769 | + case 'commercial-tenure': | |
| 3770 | + case 'furnished': | |
| 3771 | + case 'management-key-date-type': | |
| 3772 | + case 'marketing-flag': | |
| 3773 | + case 'property-feature': | |
| 3774 | + $term_name_key = $taxonomy . '_name'; | |
| 3775 | + $term_name = ( isset( $post_data[ $term_name_key ] ) && is_string( $post_data[ $term_name_key ] ) ) ? sanitize_text_field( $post_data[ $term_name_key ] ) : ''; | |
| 3776 | + if ( '' === $term_name ) { | |
| 3777 | + return; | |
| 3778 | + } | |
| 3779 | + | |
| 3780 | + if ( '' === $current_id ) { | |
| 3781 | + $term = wp_insert_term( $term_name, $taxonomy ); | |
| 3782 | + if ( ! is_wp_error( $term ) ) { | |
| 3783 | + $current_id = isset( $term['term_id'] ) ? (string) absint( $term['term_id'] ) : '0'; | |
| 3784 | + } | |
| 3785 | + } else { | |
| 3786 | + wp_update_term( absint( $current_id ), $taxonomy, array( 'name' => $term_name ) ); | |
| 3787 | + } | |
| 3788 | + | |
| 3789 | + if ( 'availability' === $current_section ) { | |
| 3790 | + $availability_departments = get_option( 'propertyhive_availability_departments', array() ); | |
| 3791 | + if ( ! is_array( $availability_departments ) ) { | |
| 3792 | + $availability_departments = array(); | |
| 3793 | + } | |
| 3794 | + | |
| 3795 | + $departments = ph_get_departments(); | |
| 3796 | + $posted_departments = ( isset( $post_data['department'] ) && is_array( $post_data['department'] ) ) ? $post_data['department'] : array(); | |
| 3797 | + $availability_departments[ $current_id ] = array(); | |
| 3798 | + foreach ( $departments as $key => $value ) { | |
| 3799 | + if ( isset( $posted_departments[ $key ] ) && is_string( $posted_departments[ $key ] ) && '1' === $posted_departments[ $key ] ) { | |
| 3800 | + $availability_departments[ $current_id ][] = $key; | |
| 3574 | 3801 | } |
| 3802 | + } | |
| 3803 | + update_option( 'propertyhive_availability_departments', $availability_departments ); | |
| 3804 | + } | |
| 3575 | 3805 | |
| 3576 | - if ( $current_section == 'management-key-date-type' ) | |
| 3577 | - { | |
| 3578 | - $options = get_option( 'propertyhive_key_date_type', array() ); | |
| 3579 | - if ( !is_array($options) ) { $options = array(); } | |
| 3806 | + if ( 'management-key-date-type' === $current_section ) { | |
| 3807 | + $options = get_option( 'propertyhive_key_date_type', array() ); | |
| 3808 | + if ( ! is_array( $options ) ) { | |
| 3809 | + $options = array(); | |
| 3810 | + } | |
| 3580 | 3811 | |
| 3581 | - $recurrence = array(); | |
| 3582 | - if (isset($_POST['management_key_date_type_recurrence_freq'])) { | |
| 3583 | - $recurrence[] = 'FREQ=' . $_POST['management_key_date_type_recurrence_freq']; | |
| 3584 | - } | |
| 3585 | - if (isset($_POST['management_key_date_type_recurrence_interval'])) { | |
| 3586 | - $recurrence[] = 'INTERVAL=' . $_POST['management_key_date_type_recurrence_interval']; | |
| 3587 | - } | |
| 3812 | + $recurrence = array(); | |
| 3813 | + $frequency = ( isset( $post_data['management_key_date_type_recurrence_freq'] ) && is_string( $post_data['management_key_date_type_recurrence_freq'] ) ) ? strtoupper( sanitize_text_field( $post_data['management_key_date_type_recurrence_freq'] ) ) : ''; | |
| 3814 | + if ( in_array( $frequency, array( 'ONCE', 'DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY' ), true ) ) { | |
| 3815 | + $recurrence[] = 'FREQ=' . $frequency; | |
| 3816 | + } | |
| 3588 | 3817 | |
| 3589 | - $options[$current_id]['recurrence_rule'] = join(';', $recurrence); | |
| 3590 | - $options[$current_id]['recurrence_type'] = $_POST['management_key_date_type_recurrence_type']; | |
| 3591 | - update_option( 'propertyhive_key_date_type', $options ); | |
| 3592 | - } | |
| 3818 | + $interval = ( isset( $post_data['management_key_date_type_recurrence_interval'] ) && is_string( $post_data['management_key_date_type_recurrence_interval'] ) ) ? trim( $post_data['management_key_date_type_recurrence_interval'] ) : ''; | |
| 3819 | + if ( '' !== $interval && preg_match( '/^[1-9][0-9]*$/D', $interval ) ) { | |
| 3820 | + $recurrence[] = 'INTERVAL=' . absint( $interval ); | |
| 3821 | + } | |
| 3593 | 3822 | |
| 3594 | - break; | |
| 3823 | + $recurrence_type = ( isset( $post_data['management_key_date_type_recurrence_type'] ) && is_string( $post_data['management_key_date_type_recurrence_type'] ) ) ? sanitize_key( $post_data['management_key_date_type_recurrence_type'] ) : ''; | |
| 3824 | + if ( ! in_array( $recurrence_type, array( 'tenancy_management', 'property_management' ), true ) ) { | |
| 3825 | + $recurrence_type = ''; | |
| 3595 | 3826 | } |
| 3596 | - case "availability-delete": | |
| 3597 | - case "property-type-delete": | |
| 3598 | - case "commercial-property-type-delete": | |
| 3599 | - case "location-delete": | |
| 3600 | - case "parking-delete": | |
| 3601 | - case "outside-space-delete": | |
| 3602 | - case "price-qualifier-delete": | |
| 3603 | - case "sale-by-delete": | |
| 3604 | - case "tenure-delete": | |
| 3605 | - case "commercial-tenure-delete": | |
| 3606 | - case "furnished-delete": | |
| 3607 | - case "management-key-date-type-delete": | |
| 3608 | - case "marketing-flag-delete": | |
| 3609 | - case "property-feature-delete": | |
| 3610 | - { | |
| 3611 | - if ( isset($_POST['confirm_removal']) && $_POST['confirm_removal'] == '1' ) | |
| 3612 | - { | |
| 3613 | - $term_ids = explode("-", $current_id); | |
| 3614 | 3827 | |
| 3615 | - foreach ( $term_ids as $current_id ) | |
| 3616 | - { | |
| 3617 | - // Update properties that have this taxonomy term set | |
| 3618 | - $query_args = array( | |
| 3619 | - 'post_type' => 'property', | |
| 3620 | - 'nopaging' => true, | |
| 3621 | - 'post_status' => array( 'pending', 'auto-draft', 'draft', 'private', 'publish', 'future', 'trash' ), | |
| 3622 | - 'tax_query' => array( | |
| 3623 | - array( | |
| 3624 | - 'taxonomy' => $_POST['taxonomy'], | |
| 3625 | - 'field' => 'id', | |
| 3626 | - 'terms' => $current_id, | |
| 3627 | - ), | |
| 3628 | - ), | |
| 3629 | - ); | |
| 3630 | - $property_query = new WP_Query( $query_args ); | |
| 3631 | - | |
| 3632 | - if ( $property_query->have_posts() ) | |
| 3633 | - { | |
| 3634 | - while ( $property_query->have_posts() ) | |
| 3635 | - { | |
| 3636 | - $property_query->the_post(); | |
| 3637 | - | |
| 3638 | - wp_remove_object_terms( $post->ID, $current_id, ph_clean($_POST['taxonomy']) ); | |
| 3639 | - | |
| 3640 | - // Re-assign to another term | |
| 3641 | - if ( isset($_POST['reassign_to_' . $current_id]) && ! empty( $_POST['reassign_to_' . $current_id] ) && $_POST['reassign_to_' . $current_id] != 'none' ) | |
| 3642 | - { | |
| 3643 | - $new_id = $_POST['reassign_to_' . $current_id]; | |
| 3644 | - | |
| 3645 | - wp_set_post_terms( $post->ID, $new_id, ph_clean($_POST['taxonomy']), TRUE ); | |
| 3646 | - | |
| 3647 | - // TODO: Check for WP_ERROR | |
| 3648 | - } | |
| 3649 | - } | |
| 3650 | - } | |
| 3651 | - | |
| 3652 | - wp_reset_postdata(); | |
| 3828 | + $options[ $current_id ]['recurrence_rule'] = join( ';', $recurrence ); | |
| 3829 | + $options[ $current_id ]['recurrence_type'] = $recurrence_type; | |
| 3830 | + update_option( 'propertyhive_key_date_type', $options ); | |
| 3831 | + } | |
| 3832 | + break; | |
| 3653 | 3833 | |
| 3654 | - if ( $current_section == 'availability-delete' ) | |
| 3655 | - { | |
| 3656 | - // Remove from propertyhive_availability_departments option | |
| 3657 | - $availability_departments = get_option( 'propertyhive_availability_departments', array() ); | |
| 3834 | + case 'availability-delete': | |
| 3835 | + case 'property-type-delete': | |
| 3836 | + case 'commercial-property-type-delete': | |
| 3837 | + case 'location-delete': | |
| 3838 | + case 'parking-delete': | |
| 3839 | + case 'outside-space-delete': | |
| 3840 | + case 'price-qualifier-delete': | |
| 3841 | + case 'sale-by-delete': | |
| 3842 | + case 'tenure-delete': | |
| 3843 | + case 'commercial-tenure-delete': | |
| 3844 | + case 'furnished-delete': | |
| 3845 | + case 'management-key-date-type-delete': | |
| 3846 | + case 'marketing-flag-delete': | |
| 3847 | + case 'property-feature-delete': | |
| 3848 | + if ( ! isset( $post_data['confirm_removal'] ) || ! is_string( $post_data['confirm_removal'] ) || '1' !== $post_data['confirm_removal'] ) { | |
| 3849 | + break; | |
| 3850 | + } | |
| 3658 | 3851 | |
| 3659 | - if ( isset($availability_departments[$current_id]) ) | |
| 3660 | - { | |
| 3661 | - unset($availability_departments[$current_id]); | |
| 3662 | - update_option( 'propertyhive_availability_departments', $availability_departments ); | |
| 3663 | - } | |
| 3664 | - } | |
| 3852 | + foreach ( $term_ids as $current_id ) { | |
| 3853 | + $query_args = array( | |
| 3854 | + 'post_type' => 'property', | |
| 3855 | + 'nopaging' => true, | |
| 3856 | + 'post_status' => array( 'pending', 'auto-draft', 'draft', 'private', 'publish', 'future', 'trash' ), | |
| 3857 | + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- Term deletion/reassignment must locate all properties or key dates attached to this selected term before removing it. | |
| 3858 | + 'tax_query' => array( | |
| 3859 | + array( | |
| 3860 | + 'taxonomy' => $taxonomy, | |
| 3861 | + 'field' => 'id', | |
| 3862 | + 'terms' => $current_id, | |
| 3863 | + ), | |
| 3864 | + ), | |
| 3865 | + ); | |
| 3866 | + $property_query = new WP_Query( $query_args ); | |
| 3665 | 3867 | |
| 3666 | - if ( $_POST['taxonomy'] == 'property_type' || $_POST['taxonomy'] == 'commercial_property_type' || $_POST['taxonomy'] == 'location' ) | |
| 3667 | - { | |
| 3668 | - $query_args = array( | |
| 3669 | - 'post_type' => 'contact', | |
| 3670 | - 'nopaging' => true, | |
| 3671 | - 'post_status' => array( 'pending', 'auto-draft', 'draft', 'private', 'publish', 'future', 'trash' ), | |
| 3672 | - 'meta_query' => array( | |
| 3673 | - array( | |
| 3674 | - 'key' => '_contact_types', | |
| 3675 | - 'value' => 'applicant', | |
| 3676 | - 'compare' => 'LIKE' | |
| 3677 | - ), | |
| 3678 | - ), | |
| 3679 | - ); | |
| 3680 | - $applicant_query = new WP_Query( $query_args ); | |
| 3868 | + if ( $property_query->have_posts() ) { | |
| 3869 | + while ( $property_query->have_posts() ) { | |
| 3870 | + $property_query->the_post(); | |
| 3871 | + wp_remove_object_terms( $post->ID, $current_id, $taxonomy ); | |
| 3681 | 3872 | |
| 3682 | - if ( $applicant_query->have_posts() ) | |
| 3683 | - { | |
| 3684 | - while ( $applicant_query->have_posts() ) | |
| 3685 | - { | |
| 3686 | - $applicant_query->the_post(); | |
| 3687 | - | |
| 3688 | - $num_applicant_profiles = get_post_meta( get_the_ID(), '_applicant_profiles', TRUE ); | |
| 3689 | - if ( $num_applicant_profiles == '' ) | |
| 3690 | - { | |
| 3691 | - $num_applicant_profiles = 0; | |
| 3692 | - } | |
| 3873 | + $new_id = $this->normalize_custom_fields_reassignment( isset( $post_data[ 'reassign_to_' . $current_id ] ) ? $post_data[ 'reassign_to_' . $current_id ] : '', $term_ids ); | |
| 3874 | + if ( null !== $new_id ) { | |
| 3875 | + wp_set_post_terms( $post->ID, $new_id, $taxonomy, true ); | |
| 3876 | + } | |
| 3877 | + } | |
| 3878 | + } | |
| 3879 | + wp_reset_postdata(); | |
| 3693 | 3880 | |
| 3694 | - if ( $num_applicant_profiles > 0 ) | |
| 3695 | - { | |
| 3696 | - for ( $i = 0; $i < $num_applicant_profiles; ++$i ) | |
| 3697 | - { | |
| 3698 | - $applicant_profile = get_post_meta( get_the_ID(), '_applicant_profile_' . $i, TRUE ); | |
| 3881 | + if ( 'availability-delete' === $current_section ) { | |
| 3882 | + $availability_departments = get_option( 'propertyhive_availability_departments', array() ); | |
| 3883 | + if ( is_array( $availability_departments ) && isset( $availability_departments[ $current_id ] ) ) { | |
| 3884 | + unset( $availability_departments[ $current_id ] ); | |
| 3885 | + update_option( 'propertyhive_availability_departments', $availability_departments ); | |
| 3886 | + } | |
| 3887 | + } | |
| 3699 | 3888 | |
| 3700 | - if ( isset($applicant_profile[ph_clean($_POST['taxonomy']).'s']) && is_array($applicant_profile[ph_clean($_POST['taxonomy']).'s']) && !empty($applicant_profile[ph_clean($_POST['taxonomy']).'s']) ) | |
| 3701 | - { | |
| 3702 | - if (in_array($current_id, $applicant_profile[ph_clean($_POST['taxonomy']).'s'])) | |
| 3703 | - { | |
| 3704 | - // This profile has this term set | |
| 3705 | - unset($applicant_profile[ph_clean($_POST['taxonomy']).'s'][$current_id]); | |
| 3889 | + if ( in_array( $taxonomy, array( 'property_type', 'commercial_property_type', 'location' ), true ) ) { | |
| 3890 | + $query_args = array( | |
| 3891 | + 'post_type' => 'contact', | |
| 3892 | + 'nopaging' => true, | |
| 3893 | + 'post_status' => array( 'pending', 'auto-draft', 'draft', 'private', 'publish', 'future', 'trash' ), | |
| 3894 | + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Applicant preferences are serialized profile metadata; deletion/reassignment must inspect every applicant profile to preserve its other selections. | |
| 3895 | + 'meta_query' => array( | |
| 3896 | + array( | |
| 3897 | + 'key' => '_contact_types', | |
| 3898 | + 'value' => 'applicant', | |
| 3899 | + 'compare' => 'LIKE', | |
| 3900 | + ), | |
| 3901 | + ), | |
| 3902 | + ); | |
| 3903 | + $applicant_query = new WP_Query( $query_args ); | |
| 3706 | 3904 | |
| 3707 | - if ( isset($_POST['reassign_to_' . $current_id]) && ! empty( $_POST['reassign_to_' . $current_id] ) && ph_clean($_POST['reassign_to_' . $current_id]) != 'none' ) | |
| 3708 | - { | |
| 3709 | - $applicant_profile[ph_clean($_POST['taxonomy']).'s'][] = $_POST['reassign_to_' . $current_id]; | |
| 3710 | - $applicant_profile[ph_clean($_POST['taxonomy']).'s'] = array_unique($applicant_profile[ph_clean($_POST['taxonomy']).'s']); | |
| 3711 | - } | |
| 3905 | + if ( $applicant_query->have_posts() ) { | |
| 3906 | + while ( $applicant_query->have_posts() ) { | |
| 3907 | + $applicant_query->the_post(); | |
| 3908 | + $num_applicant_profiles = get_post_meta( get_the_ID(), '_applicant_profiles', true ); | |
| 3909 | + if ( '' === $num_applicant_profiles ) { | |
| 3910 | + $num_applicant_profiles = 0; | |
| 3911 | + } | |
| 3712 | 3912 | |
| 3713 | - $applicant_profile[ph_clean($_POST['taxonomy']).'s'] = array_values($applicant_profile[ph_clean($_POST['taxonomy']).'s']); | |
| 3913 | + if ( $num_applicant_profiles > 0 ) { | |
| 3914 | + for ( $i = 0; $i < $num_applicant_profiles; ++$i ) { | |
| 3915 | + $applicant_profile = get_post_meta( get_the_ID(), '_applicant_profile_' . $i, true ); | |
| 3916 | + $profile_key = $taxonomy . 's'; | |
| 3917 | + if ( ! is_array( $applicant_profile ) || ! isset( $applicant_profile[ $profile_key ] ) || ! is_array( $applicant_profile[ $profile_key ] ) ) { | |
| 3918 | + continue; | |
| 3919 | + } | |
| 3714 | 3920 | |
| 3715 | - update_post_meta( get_the_ID(), '_applicant_profile_' . $i, $applicant_profile ); | |
| 3716 | - } | |
| 3717 | - } | |
| 3718 | - } | |
| 3921 | + $profile_terms = array(); | |
| 3922 | + foreach ( $applicant_profile[ $profile_key ] as $profile_term_id ) { | |
| 3923 | + if ( is_scalar( $profile_term_id ) ) { | |
| 3924 | + $profile_terms[] = (string) absint( $profile_term_id ); | |
| 3719 | 3925 | } |
| 3720 | 3926 | } |
| 3927 | + if ( ! in_array( (string) $current_id, $profile_terms, true ) ) { | |
| 3928 | + continue; | |
| 3929 | + } | |
| 3930 | + | |
| 3931 | + $profile_terms = array_values( array_filter( $profile_terms, static function ( $profile_term_id ) use ( $current_id ) { | |
| 3932 | + return (string) $profile_term_id !== (string) $current_id; | |
| 3933 | + } ) ); | |
| 3934 | + $new_id = $this->normalize_custom_fields_reassignment( isset( $post_data[ 'reassign_to_' . $current_id ] ) ? $post_data[ 'reassign_to_' . $current_id ] : '', $term_ids ); | |
| 3935 | + if ( null !== $new_id ) { | |
| 3936 | + $profile_terms[] = $new_id; | |
| 3937 | + } | |
| 3938 | + $applicant_profile[ $profile_key ] = array_values( array_unique( $profile_terms ) ); | |
| 3939 | + update_post_meta( get_the_ID(), '_applicant_profile_' . $i, wp_slash( $applicant_profile ) ); | |
| 3721 | 3940 | } |
| 3722 | 3941 | } |
| 3723 | - | |
| 3724 | - wp_reset_postdata(); | |
| 3725 | - | |
| 3726 | - wp_delete_term( $current_id, ph_clean($_POST['taxonomy']) ); | |
| 3727 | 3942 | } |
| 3728 | 3943 | } |
| 3944 | + wp_reset_postdata(); | |
| 3945 | + } | |
| 3729 | 3946 | |
| 3730 | - break; | |
| 3731 | - } | |
| 3732 | - default: | |
| 3733 | - { | |
| 3734 | - $section_found = apply_filters( 'propertyhive_custom_fields_save_section', false, $current_section, $current_id ); | |
| 3947 | + wp_delete_term( absint( $current_id ), $taxonomy ); | |
| 3948 | + } | |
| 3949 | + break; | |
| 3735 | 3950 | |
| 3736 | - if ( !($section_found) ) | |
| 3737 | - { | |
| 3738 | - echo 'UNKNOWN CUSTOM FIELD'; | |
| 3739 | - } | |
| 3740 | - } | |
| 3951 | + default: | |
| 3952 | + $section_found = apply_filters( 'propertyhive_custom_fields_save_section', false, $current_section, $current_id ); | |
| 3953 | + if ( ! $section_found ) { | |
| 3954 | + echo 'UNKNOWN CUSTOM FIELD'; | |
| 3741 | 3955 | } |
| 3742 | - } | |
| 3743 | - else | |
| 3744 | - { | |
| 3745 | - // Nothing to save. Should always be an id set when editing custom fields. | |
| 3746 | - // Even blank ids dictate something is being added | |
| 3747 | - } | |
| 3956 | + break; | |
| 3748 | 3957 | } |
| 3749 | - } | |
| 3958 | + break; | |
| 3750 | 3959 | } |
| 3751 | - else | |
| 3752 | - { | |
| 3753 | - // Nothing to save. Should always be a section when editing custom fields | |
| 3754 | - } | |
| 3755 | 3960 | } |
| 3756 | 3961 | } |
| 3757 | 3962 | |
| 3758 | 3963 | endif; |
| 3759 | 3964 | |
| 3760 | -return new PH_Settings_Custom_Fields(); | |
| 3965 | +return new PH_Settings_Custom_Fields(); | |