PluginProbe
Property Hive / 2.4.0
Property Hive v2.4.0
2.4.0 2.3.1 2.3.0 2.2.6 2.2.5 2.2.4 2.2.3 2.2.2 1.4.46 1.4.47 1.4.48 1.4.49 1.4.5 1.4.50 1.4.51 1.4.52 1.4.53 1.4.54 1.4.55 1.4.56 1.4.57 1.4.58 1.4.59 1.4.6 1.4.60 All 262 releases
← All changes | includes/admin/settings/class-ph-settings-offices.php +147 -124 1.4.6 → 2.4.0 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 Office Settings
4 7 *
5 8 * @author PropertyHive
@@ -14,8 +17,9 @@
14 17
15 18 /**
16 19 * PH_Settings_Offices
17 20 */
21 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- Legacy public global class PH_Settings_Offices; preserving the existing PH_* class name is required for plugin and extension compatibility.
18 22 class PH_Settings_Offices extends PH_Settings_Page {
19 23
20 24 /**
21 25 * Constructor.
@@ -29,8 +33,27 @@
29 33 add_action( 'propertyhive_settings_save_' . $this->id, array( $this, 'save' ) );
30 34 add_action( 'propertyhive_sections_' . $this->id, array( $this, 'output_sections' ) );
31 35 add_action( 'propertyhive_admin_field_offices', array( $this, 'offices_setting' ) );
32 36 }
37 +
38 + /**
39 + * Read one scalar value from the verified office settings form.
40 + *
41 + * @param string $key Posted field name.
42 + * @return string
43 + */
44 + private function get_posted_text( $key ) {
45 + // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended -- save() verifies the settings nonce and manage_options before calling this helper; arrays are rejected before the scalar is copied.
46 + if ( ! isset( $_POST[ $key ] ) || ! is_scalar( $_POST[ $key ] ) ) {
47 + return '';
48 + }
49 +
50 + // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- save() verifies the settings nonce before this helper is called; the copied scalar is unslashed immediately below and sanitized before use.
51 + $raw_value = $_POST[ $key ];
52 + $raw_value = wp_unslash( (string) $raw_value );
53 +
54 + return ph_clean( $raw_value );
55 + }
33 56
34 57 /**
35 58 * Get settings array
36 59 *
@@ -59,13 +82,14 @@
59 82 public function get_office_settings() {
60 83
61 84 global $current_section;
62 85
63 - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] );
86 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only settings selection; no state change occurs while building the form.
87 + $current_id = isset( $_REQUEST['id'] ) && is_scalar( $_REQUEST['id'] ) ? absint( $_REQUEST['id'] ) : 0;
64 88
65 89 $args = array(
66 90
67 - array( 'title' => __( ( $current_section == 'add' ? 'Add New Office' : 'Edit Office Details' ), 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'office_options' ),
91 + array( 'title' => ( $current_section == 'add' ? __( 'Add New Office', 'propertyhive' ) : __( 'Edit Office Details', 'propertyhive' ) ), 'type' => 'title', 'desc' => '', 'id' => 'office_options' ),
68 92
69 93 array(
70 94 'title' => __( 'Office Name', 'propertyhive' ),
71 95 'id' => 'office_name',
@@ -125,69 +149,40 @@
125 149 array( 'title' => __( 'Contact Details', 'propertyhive' ), 'type' => 'title', 'desc' => '', 'id' => 'office_contact_options' ),
126 150
127 151 );
128 152
129 - if ( get_option( 'propertyhive_active_departments_sales' ) == 'yes' )
130 - {
131 - $args[] = array(
132 - 'title' => __( 'Telephone Number (Residential Sales)', 'propertyhive' ),
133 - 'id' => '_office_telephone_number_sales',
134 - //'css' => 'width:50px;',
135 - 'default' => get_post_meta($current_id, '_office_telephone_number_sales', TRUE),
136 - 'type' => 'text',
137 - 'desc_tip' => false,
138 - );
139 -
140 - $args[] = array(
141 - 'title' => __( 'Email Address (Residential Sales)', 'propertyhive' ),
142 - 'id' => '_office_email_address_sales',
143 - //'css' => 'width:50px;',
144 - 'default' => get_post_meta($current_id, '_office_email_address_sales', TRUE),
145 - 'type' => 'text',
146 - 'desc_tip' => false,
147 - );
148 - }
149 -
150 - if ( get_option( 'propertyhive_active_departments_lettings' ) == 'yes' )
151 - {
152 - $args[] = array(
153 - 'title' => __( 'Telephone Number (Residential Lettings)', 'propertyhive' ),
154 - 'id' => '_office_telephone_number_lettings',
155 - //'css' => 'width:50px;',
156 - 'default' => get_post_meta($current_id, '_office_telephone_number_lettings', TRUE),
157 - 'type' => 'text',
158 - 'desc_tip' => false,
159 - );
160 -
161 - $args[] = array(
162 - 'title' => __( 'Email Address (Residential Lettings)', 'propertyhive' ),
163 - 'id' => '_office_email_address_lettings',
164 - //'css' => 'width:50px;',
165 - 'default' => get_post_meta($current_id, '_office_email_address_lettings', TRUE),
166 - 'type' => 'text',
167 - 'desc_tip' => false,
168 - );
169 - }
153 + $departments = ph_get_departments();
170 154
171 - if ( get_option( 'propertyhive_active_departments_commercial' ) == 'yes' )
155 + foreach ( $departments as $key => $value )
172 156 {
173 - $args[] = array(
174 - 'title' => __( 'Telephone Number (Commercial)', 'propertyhive' ),
175 - 'id' => '_office_telephone_number_commercial',
176 - //'css' => 'width:50px;',
177 - 'default' => get_post_meta($current_id, '_office_telephone_number_commercial', TRUE),
178 - 'type' => 'text',
179 - 'desc_tip' => false,
180 - );
181 -
182 - $args[] = array(
183 - 'title' => __( 'Email Address (Commercial)', 'propertyhive' ),
184 - 'id' => '_office_email_address_commercial',
185 - //'css' => 'width:50px;',
186 - 'default' => get_post_meta($current_id, '_office_email_address_commercial', TRUE),
187 - 'type' => 'text',
188 - 'desc_tip' => false,
189 - );
157 + if ( get_option( 'propertyhive_active_departments_' . str_replace("residential-", "", $key) ) == 'yes' )
158 + {
159 + $args[] = array(
160 + 'title' => sprintf(
161 + /* translators: %s: department (e.g. Sales, Lettings, Commercial) */
162 + __( 'Telephone Number (%s)', 'propertyhive' ),
163 + $value
164 + ),
165 + 'id' => '_office_telephone_number_' . str_replace("residential-", "", $key),
166 + //'css' => 'width:50px;',
167 + 'default' => get_post_meta($current_id, '_office_telephone_number_' . str_replace("residential-", "", $key), TRUE),
168 + 'type' => 'text',
169 + 'desc_tip' => false,
170 + );
171 +
172 + $args[] = array(
173 + 'title' => sprintf(
174 + /* translators: %s: department (e.g. Sales, Lettings, Commercial) */
175 + __( 'Email Address (%s)', 'propertyhive' ),
176 + $value
177 + ),
178 + 'id' => '_office_email_address_' . str_replace("residential-", "", $key),
179 + //'css' => 'width:50px;',
180 + 'default' => get_post_meta($current_id, '_office_email_address_' . str_replace("residential-", "", $key), TRUE),
181 + 'type' => 'text',
182 + 'desc_tip' => false,
183 + );
184 + }
190 185 }
191 186
192 187 $args[] = array( 'type' => 'sectionend', 'id' => 'office_contact_options' );
193 188
@@ -225,17 +220,22 @@
225 220 public function get_office_delete() {
226 221
227 222 global $save_button_text, $post;
228 223
224 + // 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.
229 225 $save_button_text = __( 'Delete', 'propertyhive' );
230 226
227 + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- This POST field only selects the delete confirmation display; save() performs the mutation after nonce and capability checks.
231 228 if ( isset($_POST['confirm_removal']) && $_POST['confirm_removal'] == 1 )
232 229 {
233 230 // A term has just been deleted
234 231 global $hide_save_button, $show_cancel_button, $cancel_button_href;
235 232
233 + // 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.
236 234 $hide_save_button = TRUE;
235 + // 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.
237 236 $show_cancel_button = TRUE;
237 + // 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.
238 238 $cancel_button_href = admin_url( 'admin.php?page=ph-settings&tab=offices' );
239 239
240 240 $args = array();
241 241
@@ -252,9 +252,10 @@
252 252 $args[] = array( 'type' => 'sectionend', 'id' => 'office_delete' );
253 253 }
254 254 else
255 255 {
256 - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] );
256 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only settings selection; no state change occurs while building the form.
257 + $current_id = isset( $_REQUEST['id'] ) && is_scalar( $_REQUEST['id'] ) ? absint( $_REQUEST['id'] ) : 0;
257 258
258 259 if ($current_id == '')
259 260 {
260 261 die("ID not passed");
@@ -273,8 +274,9 @@
273 274 $query_args = array(
274 275 'post_type' => 'property',
275 276 'nopaging' => true,
276 277 'post_status' => array( 'pending', 'auto-draft', 'draft', 'private', 'publish', 'future', 'trash' ),
278 + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Count all properties assigned through _office_id across the existing statuses before offering office deletion/reassignment choices.
277 279 'meta_query' => array(
278 280 array(
279 281 'key' => '_office_id',
280 282 'value' => $current_id,
@@ -289,13 +291,14 @@
289 291 // Get number of applicants assigned to this term (future)
290 292
291 293 if ($num_properties > 0)
292 294 {
293 - $alternative_offices = array();
295 + $alternative_terms = array();
294 296
295 297 $query_args = array(
296 298 'post_type' => 'office',
297 299 'nopaging' => true,
300 + // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in -- The delete form must offer every other office as a reassignment target and must exclude the office currently being deleted.
298 301 'post__not_in' => array( $current_id ),
299 302 'orderby' => 'title',
300 303 'order' => 'ASC'
301 304 );
@@ -346,9 +349,9 @@
346 349 /**
347 350 * Output the settings
348 351 */
349 352 public function output() {
350 - global $current_section;
353 + global $current_section, $redirect_after_save;
351 354
352 355 if ( $current_section == 'add' ) {
353 356
354 357 remove_action('propertyhive_admin_field_offices', array( $this, 'offices_setting' ));
@@ -354,24 +357,25 @@
354 357 remove_action('propertyhive_admin_field_offices', array( $this, 'offices_setting' ));
355 358
356 359 $settings = $this->get_office_settings();
357 360
361 + // 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.
362 + $redirect_after_save = admin_url('admin.php?page=ph-settings&tab=offices');
363 +
358 364 PH_Admin_Settings::output_fields( $settings );
359 -
360 - /*foreach ( $shipping_methods as $method ) {
361 - if ( strtolower( get_class( $method ) ) == strtolower( $current_section ) && $method->has_settings() ) {
362 - $method->admin_options();
363 - break;
364 - }
365 - }*/
365 +
366 366 } elseif ( $current_section == 'edit' ) {
367 367
368 368 remove_action('propertyhive_admin_field_offices', array( $this, 'offices_setting' ));
369 369
370 - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] );
370 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only settings selection; no state change occurs while building the form.
371 + $current_id = isset( $_REQUEST['id'] ) && is_scalar( $_REQUEST['id'] ) ? absint( $_REQUEST['id'] ) : 0;
371 372
372 373 $settings = $this->get_office_settings();
373 374
375 + // 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.
376 + $redirect_after_save = admin_url('admin.php?page=ph-settings&tab=offices');
377 +
374 378 PH_Admin_Settings::output_fields( $settings );
375 379
376 380 } elseif ( $current_section == 'delete' ) {
377 381
@@ -376,9 +380,10 @@
376 380 } elseif ( $current_section == 'delete' ) {
377 381
378 382 remove_action('propertyhive_admin_field_offices', array( $this, 'offices_setting' ));
379 383
380 - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] );
384 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only settings selection; no state change occurs while building the form.
385 + $current_id = isset( $_REQUEST['id'] ) && is_scalar( $_REQUEST['id'] ) ? absint( $_REQUEST['id'] ) : 0;
381 386
382 387 $settings = $this->get_office_delete();
383 388
384 389 PH_Admin_Settings::output_fields( $settings );
@@ -404,21 +409,22 @@
404 409 <th scope="row" class="titledesc">
405 410 &nbsp;
406 411 </th>
407 412 <td class="forminp forminp-button">
408 - <a href="<?php echo admin_url( 'admin.php?page=ph-settings&tab=offices&section=add' ); ?>" class="button alignright"><?php echo __( 'Add New Office', 'propertyhive' ); ?></a>
413 + <a href="<?php echo esc_url(admin_url( 'admin.php?page=ph-settings&tab=offices&section=add' )); ?>" class="button alignright"><?php echo esc_html(__( 'Add New Office', 'propertyhive' )); ?></a>
409 414 </td>
410 415 </tr>
411 416 <tr valign="top">
412 - <th scope="row" class="titledesc"><?php _e( 'Offices', 'propertyhive' ) ?></th>
417 + <th scope="row" class="titledesc"><?php echo esc_html(__( 'Offices', 'propertyhive' )); ?></th>
413 418 <td class="forminp">
414 419 <table class="ph_offices widefat" cellspacing="0">
415 420 <thead>
416 421 <tr>
417 - <th class="primary"><?php _e( 'Primary', 'propertyhive' ); ?></th>
418 - <th class="name"><?php _e( 'Name', 'propertyhive' ); ?></th>
419 - <th class="address"><?php _e( 'Address', 'propertyhive' ); ?></th>
420 - <th class="contact"><?php _e( 'Contact Details', 'propertyhive' ); ?></th>
422 + <th class="primary"><?php echo esc_html(__( 'Primary', 'propertyhive' )); ?></th>
423 + <th class="name"><?php echo esc_html(__( 'Name', 'propertyhive' )); ?></th>
424 + <th class="address"><?php echo esc_html(__( 'Address', 'propertyhive' )); ?></th>
425 + <th class="contact"><?php echo esc_html(__( 'Contact Details', 'propertyhive' )); ?></th>
426 + <?php do_action( 'propertyhive_office_table_header_columns' ); ?>
421 427 <th class="settings">&nbsp;</th>
422 428 </tr>
423 429 </thead>
424 430 <tbody>
@@ -451,23 +457,19 @@
451 457 $address_part = get_post_meta($post->ID, '_office_address_postcode', TRUE);
452 458 $address .= $address_part;
453 459
454 460 $contact_details = '';
455 - if ( get_option( 'propertyhive_active_departments_sales' ) == 'yes' )
461 +
462 + $departments = ph_get_departments();
463 +
464 + foreach ( $departments as $key => $value )
456 465 {
457 - $contact_details .= 'T: ' . get_post_meta($post->ID, '_office_telephone_number_sales', TRUE) . '<br>';
458 - $contact_details .= 'E: ' . get_post_meta($post->ID, '_office_email_address_sales', TRUE) . '<br>';
466 + if ( get_option( 'propertyhive_active_departments_' . str_replace("residential-", "", $key) ) == 'yes' )
467 + {
468 + $contact_details .= 'T: ' . esc_html(get_post_meta($post->ID, '_office_telephone_number_' . str_replace("residential-", "", $key), TRUE)) . '<br>';
469 + $contact_details .= 'E: ' . esc_html(get_post_meta($post->ID, '_office_email_address_' . str_replace("residential-", "", $key), TRUE)) . '<br>';
470 + }
459 471 }
460 - if ( get_option( 'propertyhive_active_departments_lettings' ) == 'yes' )
461 - {
462 - $contact_details .= 'T: ' . get_post_meta($post->ID, '_office_telephone_number_lettings', TRUE) . '<br>';
463 - $contact_details .= 'E: ' . get_post_meta($post->ID, '_office_email_address_lettings', TRUE) . '<br>';
464 - }
465 - if ( get_option( 'propertyhive_active_departments_commercial' ) == 'yes' )
466 - {
467 - $contact_details .= 'T: ' . get_post_meta($post->ID, '_office_telephone_number_commercial', TRUE) . '<br>';
468 - $contact_details .= 'E: ' . get_post_meta($post->ID, '_office_email_address_commercial', TRUE) . '<br>';
469 - }
470 472
471 473 echo '<tr>
472 474 <td width="1%" class="primary">
473 475 <input type="radio" name="primary" value="' . esc_attr( $post->ID ) . '" ' . checked( get_post_meta($post->ID, 'primary', TRUE), '1', false ) . ' />
@@ -472,22 +474,24 @@
472 474 <td width="1%" class="primary">
473 475 <input type="radio" name="primary" value="' . esc_attr( $post->ID ) . '" ' . checked( get_post_meta($post->ID, 'primary', TRUE), '1', false ) . ' />
474 476 </td>
475 477 <td class="name">
476 - ' . get_the_title() . '
478 + ' . esc_html(get_the_title()) . '
477 479 </td>
478 480 <td class="address">
479 - ' . $address . '
481 + ' . esc_html($address) . '
480 482 </td>
481 483 <td class="contact">
482 - ' . $contact_details . '
483 - </td>
484 + ' . wp_kses_post( $contact_details ) . '
485 + </td>';
486 + do_action( 'propertyhive_office_table_row_columns', get_the_ID() );
487 + echo '
484 488 <td class="settings">
485 - <a class="button" href="' . admin_url( 'admin.php?page=ph-settings&tab=offices&section=edit&id=' . $post->ID ) . '">' . __( 'Edit', 'propertyhive' ) . '</a>
489 + <a class="button" href="' . esc_url(admin_url( 'admin.php?page=ph-settings&tab=offices&section=edit&id=' . $post->ID )) . '">' . esc_html(__( 'Edit', 'propertyhive' )) . '</a>
486 490 ';
487 - if ( $num_offices > 1 )
491 + if ( $num_offices > 1 && get_post_meta($post->ID, 'primary', TRUE) != '1' )
488 492 {
489 - echo '<a class="button" href="' . admin_url( 'admin.php?page=ph-settings&tab=offices&section=delete&id=' . $post->ID ) . '">' . __( 'Delete', 'propertyhive' ) . '</a>';
493 + echo '<a class="button" href="' . esc_url(admin_url( 'admin.php?page=ph-settings&tab=offices&section=delete&id=' . $post->ID )) . '">' . esc_html(__( 'Delete', 'propertyhive' )) . '</a>';
490 494 }
491 495 echo '
492 496 </td>
493 497 </tr>';
@@ -503,9 +507,9 @@
503 507 <th scope="row" class="titledesc">
504 508 &nbsp;
505 509 </th>
506 510 <td class="forminp forminp-button">
507 - <a href="<?php echo admin_url( 'admin.php?page=ph-settings&tab=offices&section=add' ); ?>" class="button alignright"><?php echo __( 'Add New Office', 'propertyhive' ); ?></a>
511 + <a href="<?php echo esc_url(admin_url( 'admin.php?page=ph-settings&tab=offices&section=add' )); ?>" class="button alignright"><?php echo esc_html(__( 'Add New Office', 'propertyhive' )); ?></a>
508 512 </td>
509 513 </tr>
510 514 <?php
511 515 }
@@ -513,10 +517,22 @@
513 517 /**
514 518 * Save settings
515 519 */
516 520 public function save() {
521 + 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' ) ) {
522 + return;
523 + }
524 +
517 525 global $current_section, $post;
518 526
527 + if ( in_array( $current_section, array( 'edit', 'delete' ), true ) ) {
528 + $office_id = isset( $_REQUEST['id'] ) && is_scalar( $_REQUEST['id'] ) ? absint( $_REQUEST['id'] ) : 0;
529 + if ( ! $office_id || 'office' !== get_post_type( $office_id ) ) {
530 + PH_Admin_Settings::add_error( __( 'Please select a valid office.', 'propertyhive' ) );
531 + return;
532 + }
533 + }
534 +
519 535 if ( $current_section == 'add' ) {
520 536
521 537 // TODO: Validate (check for blank fields, and that office name doest exist already)
522 538
@@ -521,9 +537,9 @@
521 537 // TODO: Validate (check for blank fields, and that office name doest exist already)
522 538
523 539 // Insert office
524 540 $office_post = array(
525 - 'post_title' => wp_strip_all_tags( $_POST['office_name'] ),
541 + 'post_title' => wp_slash( $this->get_posted_text( 'office_name' ) ),
526 542 'post_content' => '',
527 543 'post_status' => 'publish',
528 544 'post_type' => 'office',
529 545 'comment_status' => 'closed',
@@ -539,18 +555,17 @@
539 555 PH_Admin_Settings::add_message( __( 'Office added successfully', 'propertyhive' ) . ' ' . '<a href="' . admin_url( 'admin.php?page=ph-settings&tab=offices' ) . '">' . __( 'Return to offices', 'propertyhive' ) . '</a>' );
540 556
541 557 } elseif ( $current_section == 'edit' ) {
542 558
543 - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] );
559 + $current_id = isset( $_REQUEST['id'] ) && is_scalar( $_REQUEST['id'] ) ? absint( $_REQUEST['id'] ) : 0;
544 560
545 561 // TODO: Validate
546 - // TODO: Make sure this ID belongs to an office
547 562 // TODO: Update slug?
548 563
549 564 // Update office
550 565 $office_post = array(
551 566 'ID' => $current_id,
552 - 'post_title' => wp_strip_all_tags( $_POST['office_name'] )
567 + 'post_title' => wp_slash( $this->get_posted_text( 'office_name' ) )
553 568 );
554 569
555 570 wp_update_post( $office_post );
556 571
@@ -562,11 +577,11 @@
562 577 PH_Admin_Settings::add_message( __( 'Office details updated successfully', 'propertyhive' ) . ' ' . '<a href="' . admin_url( 'admin.php?page=ph-settings&tab=offices' ) . '">' . __( 'Return to offices', 'propertyhive' ) . '</a>' );
563 578
564 579 } elseif ( $current_section == 'delete' ) {
565 580
566 - if ( isset($_POST['confirm_removal']) && $_POST['confirm_removal'] == '1' )
581 + if ( '1' === $this->get_posted_text( 'confirm_removal' ) )
567 582 {
568 - $current_id = empty( $_REQUEST['id'] ) ? '' : sanitize_title( $_REQUEST['id'] );
583 + $current_id = isset( $_REQUEST['id'] ) && is_scalar( $_REQUEST['id'] ) ? absint( $_REQUEST['id'] ) : 0;
569 584
570 585 // Get number of properties assigned to this term
571 586 $query_args = array(
572 587 'post_type' => 'property',
@@ -571,8 +586,9 @@
571 586 $query_args = array(
572 587 'post_type' => 'property',
573 588 'nopaging' => true,
574 589 'post_status' => array( 'pending', 'auto-draft', 'draft', 'private', 'publish', 'future', 'trash' ),
590 + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Office deletion must find every property assigned to this office so each one can be reassigned before the office is removed; the office ID is read from the verified admin form.
575 591 'meta_query' => array(
576 592 array(
577 593 'key' => '_office_id',
578 594 'value' => $current_id,
@@ -589,13 +605,14 @@
589 605 die("Not assigning properties to new office. Please try again");
590 606 }
591 607 else
592 608 {
593 - $post_type = get_post_type( $_POST['reassign_to'] );
609 + $reassign_to = absint( $this->get_posted_text( 'reassign_to' ) );
610 + $post_type = get_post_type( $reassign_to );
594 611
595 612 if ( $post_type != 'office' )
596 613 {
597 - die("New office isn't of type office. It's of type: " . $post_type);
614 + die("New office isn't of type office. It's of type: " . esc_html($post_type));
598 615 }
599 616 }
600 617
601 618 while ( $property_query->have_posts() )
@@ -601,9 +618,9 @@
601 618 while ( $property_query->have_posts() )
602 619 {
603 620 $property_query->the_post();
604 621
605 - update_post_meta( $post->ID, '_office_id', $_POST['reassign_to'] );
622 + update_post_meta( $post->ID, '_office_id', $reassign_to );
606 623
607 624 // TODO: Check for WP_ERROR
608 625 }
609 626 }
@@ -642,27 +659,33 @@
642 659
643 660 wp_reset_postdata();
644 661
645 662 // Set selected office as primary
646 - update_post_meta(wp_strip_all_tags( $_POST['primary'] ), 'primary', '1');
663 + update_post_meta( absint( $this->get_posted_text( 'primary' ) ), 'primary', '1');
647 664 }
648 665 else
649 666 {
650 - update_post_meta($office_post_id, '_office_address_1', wp_strip_all_tags( $_POST['_office_address_1'] ));
651 - update_post_meta($office_post_id, '_office_address_2', wp_strip_all_tags( $_POST['_office_address_2'] ));
652 - update_post_meta($office_post_id, '_office_address_3', wp_strip_all_tags( $_POST['_office_address_3'] ));
653 - update_post_meta($office_post_id, '_office_address_4', wp_strip_all_tags( $_POST['_office_address_4'] ));
654 - update_post_meta($office_post_id, '_office_address_postcode', wp_strip_all_tags( $_POST['_office_address_postcode'] ));
667 + update_post_meta($office_post_id, '_office_address_1', wp_slash( $this->get_posted_text( '_office_address_1' ) ));
668 + update_post_meta($office_post_id, '_office_address_2', wp_slash( $this->get_posted_text( '_office_address_2' ) ));
669 + update_post_meta($office_post_id, '_office_address_3', wp_slash( $this->get_posted_text( '_office_address_3' ) ));
670 + update_post_meta($office_post_id, '_office_address_4', wp_slash( $this->get_posted_text( '_office_address_4' ) ));
671 + update_post_meta($office_post_id, '_office_address_postcode', wp_slash( $this->get_posted_text( '_office_address_postcode' ) ));
655 672
656 - update_post_meta($office_post_id, '_office_telephone_number_sales', (isset($_POST['_office_telephone_number_sales'])) ? wp_strip_all_tags( $_POST['_office_telephone_number_sales'] ) : '');
657 - update_post_meta($office_post_id, '_office_email_address_sales', (isset($_POST['_office_email_address_sales'])) ? wp_strip_all_tags( $_POST['_office_email_address_sales'] ) : '');
658 - update_post_meta($office_post_id, '_office_telephone_number_lettings', (isset($_POST['_office_telephone_number_lettings'])) ? wp_strip_all_tags( $_POST['_office_telephone_number_lettings'] ) : '');
659 - update_post_meta($office_post_id, '_office_email_address_lettings', (isset($_POST['_office_email_address_lettings'])) ? wp_strip_all_tags( $_POST['_office_email_address_lettings'] ) : '');
660 - update_post_meta($office_post_id, '_office_telephone_number_commercial', (isset($_POST['_office_telephone_number_commercial'])) ? wp_strip_all_tags( $_POST['_office_telephone_number_commercial'] ) : '');
661 - update_post_meta($office_post_id, '_office_email_address_commercial', (isset($_POST['_office_email_address_commercial'])) ? wp_strip_all_tags( $_POST['_office_email_address_commercial'] ) : '');
673 + $departments = ph_get_departments();
662 674
663 - update_post_meta($office_post_id, '_office_latitude', wp_strip_all_tags( $_POST['_office_latitude'] ));
664 - update_post_meta($office_post_id, '_office_longitude', wp_strip_all_tags( $_POST['_office_longitude'] ));
675 + foreach ( $departments as $key => $value )
676 + {
677 + if ( get_option( 'propertyhive_active_departments_' . str_replace("residential-", "", $key) ) == 'yes' )
678 + {
679 + $ph_contact_telephone_value = ( isset( $_POST['_office_telephone_number_' . str_replace("residential-", "", $key)] ) && is_string( $_POST['_office_telephone_number_' . str_replace("residential-", "", $key)] ) ) ? sanitize_text_field( wp_unslash( $_POST['_office_telephone_number_' . str_replace("residential-", "", $key)] ) ) : '';
680 + update_post_meta( $office_post_id, '_office_telephone_number_' . str_replace("residential-", "", $key), wp_slash( $ph_contact_telephone_value ) );
681 + $ph_contact_email_value = ( isset( $_POST['_office_email_address_' . str_replace("residential-", "", $key)] ) && is_string( $_POST['_office_email_address_' . str_replace("residential-", "", $key)] ) ) ? sanitize_text_field( wp_unslash( $_POST['_office_email_address_' . str_replace("residential-", "", $key)] ) ) : '';
682 + update_post_meta( $office_post_id, '_office_email_address_' . str_replace("residential-", "", $key), wp_slash( $ph_contact_email_value ) );
683 + }
684 + }
685 +
686 + update_post_meta($office_post_id, '_office_latitude', wp_slash( $this->get_posted_text( '_office_latitude' ) ));
687 + update_post_meta($office_post_id, '_office_longitude', wp_slash( $this->get_posted_text( '_office_longitude' ) ));
665 688
666 689 do_action( 'propertyhive_save_office', $office_post_id );
667 690 }
668 691 }
@@ -671,5 +694,5 @@
671 694 }
672 695
673 696 endif;
674 697
675 -return new PH_Settings_Offices();
698 +return new PH_Settings_Offices();