PluginProbe
Property Hive / 2.3.1
Property Hive v2.3.1
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 1.4.61 All 261 releases
← All changes | includes/admin/class-ph-admin-menus.php +30 -13 2.2.22.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 * Setup menus in WP admin.
4 7 *
5 8 * @author PropertyHive
@@ -14,8 +17,9 @@
14 17
15 18 /**
16 19 * PH_Admin_Menus Class
17 20 */
21 +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- Legacy public global class PH_Admin_Menus; preserving the existing PH_* class name is required for plugin and extension compatibility.
18 22 class PH_Admin_Menus {
19 23
20 24 /**
21 25 * Hook in tabs.
@@ -47,19 +51,26 @@
47 51 // Include settings pages.
48 52 PH_Admin_Settings::get_settings_pages();
49 53
50 54 // Get current tab/section.
51 - $current_tab = empty( $_GET['tab'] ) ? 'general' : sanitize_title( wp_unslash( $_GET['tab'] ) ); // WPCS: input var okay, CSRF ok.
52 - $current_section = empty( $_REQUEST['section'] ) ? '' : sanitize_title( wp_unslash( $_REQUEST['section'] ) ); // WPCS: input var okay, CSRF ok.
55 + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound, WordPress.Security.NonceVerification.Recommended -- Read-only settings routing; saved data is separately nonce/capability checked by PH_Admin_Settings::save(). Shared admin settings-view state; this global is intentionally used to control the common settings template and is not an arbitrary application global.
56 + $current_tab = empty( $_GET['tab'] ) || ! is_string( $_GET['tab'] ) ? 'general' : sanitize_title( wp_unslash( $_GET['tab'] ) ); // WPCS: input var okay, CSRF ok.
57 + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound, WordPress.Security.NonceVerification.Recommended -- Read-only settings routing; saved data is separately nonce/capability checked by PH_Admin_Settings::save(). Shared admin settings-view state; this global is intentionally used to control the common settings template and is not an arbitrary application global.
58 + $current_section = empty( $_REQUEST['section'] ) || ! is_string( $_REQUEST['section'] ) ? '' : sanitize_title( wp_unslash( $_REQUEST['section'] ) ); // WPCS: input var okay, CSRF ok.
53 59
54 - // Save settings if data has been posted.
55 - if ( '' !== $current_section && apply_filters( "propertyhive_save_settings_{$current_tab}_{$current_section}", ! empty( $_POST['save'] ) ) ) { // WPCS: input var okay, CSRF ok.
60 + // Save settings if data has been posted. The called save method verifies nonce and capabilities.
61 + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only save intent; PH_Admin_Settings::save() validates before changing any settings.
62 + $save_requested = ! empty( $_POST['save'] );
63 + if ( '' !== $current_section && apply_filters( "propertyhive_save_settings_{$current_tab}_{$current_section}", $save_requested ) ) { // WPCS: input var okay, CSRF ok.
56 64 PH_Admin_Settings::save();
57 - } elseif ( '' === $current_section && apply_filters( "propertyhive_save_settings_{$current_tab}", ! empty( $_POST['save'] ) ) ) { // WPCS: input var okay, CSRF ok.
65 + } elseif ( '' === $current_section && apply_filters( "propertyhive_save_settings_{$current_tab}", $save_requested ) ) { // WPCS: input var okay, CSRF ok.
58 66 PH_Admin_Settings::save();
59 67 }
60 68
61 - $redirect_after_save = empty( $_POST['redirect'] ) ? '' : sanitize_url( wp_unslash( $_POST['redirect'] ) );
69 + $redirect_after_save = '';
70 + 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' ) ) {
71 + $redirect_after_save = isset( $_POST['redirect'] ) && is_string( $_POST['redirect'] ) ? sanitize_url( wp_unslash( $_POST['redirect'] ) ) : '';
72 + }
62 73 if ( !empty($redirect_after_save) )
63 74 {
64 75 wp_safe_redirect($redirect_after_save . '&ph_message=' . __( 'Your settings have been saved.', 'propertyhive' ) );
65 76 die();
@@ -196,11 +207,13 @@
196 207 if ( apply_filters( 'propertyhive_show_admin_menu_enquiry_count', TRUE ) === TRUE )
197 208 {
198 209 $args = array(
199 210 'post_type' => 'enquiry',
200 - 'nopaging' => true,
211 + 'posts_per_page' => 1,
212 + 'no_found_rows' => false,
201 213 'fields' => 'ids',
202 - 'meta_query' => array(
214 + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Count-only menu query fetches one ID while retaining found_rows for the complete total.
215 + 'meta_query' => array(
203 216 array(
204 217 'key' => '_status',
205 218 'value' => 'open'
206 219 ),
@@ -244,11 +257,13 @@
244 257 if ( apply_filters( 'propertyhive_show_admin_menu_key_date_count', TRUE ) === TRUE )
245 258 {
246 259 $args = array(
247 260 'post_type' => 'key_date',
248 - 'nopaging' => true,
261 + 'posts_per_page' => 1,
262 + 'no_found_rows' => false,
249 263 'fields' => 'ids',
250 - 'meta_query' => array(
264 + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Count-only menu query fetches one ID while retaining found_rows for the complete total.
265 + 'meta_query' => array(
251 266 array(
252 267 'key' => '_key_date_status',
253 268 'value' => 'pending'
254 269 ),
@@ -253,9 +268,9 @@
253 268 'value' => 'pending'
254 269 ),
255 270 array(
256 271 'key' => '_date_due',
257 - 'value' => date('Y-m-d'),
272 + 'value' => gmdate('Y-m-d'),
258 273 'type' => 'date',
259 274 'compare' => '<=',
260 275 ),
261 276 ),
@@ -409,11 +424,13 @@
409 424 $crm_only_mode = get_user_meta( $user_id, 'crm_only_mode', TRUE );
410 425
411 426 if ( $crm_only_mode == '1' )
412 427 {
413 - if ( $post_type == 'contact' && isset($_GET['_contact_type']) && !empty(ph_clean($_GET['_contact_type'])) )
428 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only CRM navigation highlighting, not a data mutation.
429 + $contact_type = isset( $_GET['_contact_type'] ) && is_string( $_GET['_contact_type'] ) ? sanitize_text_field( wp_unslash( $_GET['_contact_type'] ) ) : '';
430 + if ( $post_type == 'contact' && '' !== $contact_type )
414 431 {
415 - $parent_file = 'edit.php?post_type=contact&_contact_type=' . ph_clean($_GET['_contact_type']);
432 + $parent_file = 'edit.php?post_type=contact&_contact_type=' . rawurlencode( $contact_type );
416 433 }
417 434 }
418 435 else
419 436 {