| @@ -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 | * Load assets. |
| 4 | 7 | * |
| 5 | 8 | * @author PropertyHive |
| @@ -14,8 +17,9 @@ | ||
| 14 | 17 | |
| 15 | 18 | /** |
| 16 | 19 | * PH_Admin_Assets Class |
| 17 | 20 | */ |
| 21 | +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- Legacy public global class PH_Admin_Assets; preserving the existing PH_* class name is required for plugin and extension compatibility. | |
| 18 | 22 | class PH_Admin_Assets { |
| 19 | 23 | |
| 20 | 24 | /** |
| 21 | 25 | * Hook in tabs. |
| @@ -62,11 +66,17 @@ | ||
| 62 | 66 | wp_enqueue_style('mapbox', PH()->plugin_url() . '/assets/js/mapbox/mapbox-gl.css', array(), '3.8.0' ); |
| 63 | 67 | } |
| 64 | 68 | } |
| 65 | 69 | |
| 70 | + if ( in_array( $screen->id, array( 'dashboard_page_ph-onboarding' ), true ) ) | |
| 71 | + { | |
| 72 | + wp_enqueue_style( 'propertyhive_admin_onboarding', PH()->plugin_url() . '/assets/css/admin-onboarding.css', array(), PH_VERSION ); | |
| 73 | + } | |
| 74 | + | |
| 66 | 75 | if ( in_array( $screen->id, array( 'property' ) ) ) |
| 67 | 76 | { |
| 68 | - if ( isset($_GET['tutorial']) && sanitize_text_field($_GET['tutorial']) == 'yes' ) | |
| 77 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only tour asset selection; no data is changed. | |
| 78 | + if ( isset( $_GET['tutorial'] ) && is_string( $_GET['tutorial'] ) && sanitize_text_field( wp_unslash( $_GET['tutorial'] ) ) === 'yes' ) | |
| 69 | 79 | { |
| 70 | 80 | wp_register_style( 'tour-css', PH()->plugin_url() . '/assets/css/tours/style.css', array(), '1.0.1' ); |
| 71 | 81 | wp_register_style( 'driver-css', PH()->plugin_url() . '/assets/css/tours/driver-js.css', array(), '1.0.1' ); |
| 72 | 82 | wp_enqueue_style( 'tour-css' ); |
| @@ -75,14 +85,14 @@ | ||
| 75 | 85 | } |
| 76 | 86 | |
| 77 | 87 | if ( in_array( $screen->id, array( 'edit-contact', 'edit-enquiry', 'edit-appraisal', 'edit-viewing', 'edit-offer', 'edit-sale', 'edit-key_date' ) ) ) |
| 78 | 88 | { |
| 79 | - wp_enqueue_style( 'daterangepicker.css', '//cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css' ); | |
| 89 | + wp_enqueue_style( 'daterangepicker.css', PH()->plugin_url() . '/assets/js/daterangepicker/daterangepicker.css', array(), '3.1.0' ); | |
| 80 | 90 | } |
| 81 | 91 | |
| 82 | 92 | if ( in_array( $screen->id, array( 'edit-key_date') ) ) |
| 83 | 93 | { |
| 84 | - wp_enqueue_style( 'admin-hide-default-post-data.css', PH()->plugin_url() . '/assets/css/admin-hide-default-post-data.css', PH_VERSION ); | |
| 94 | + wp_enqueue_style( 'admin-hide-default-post-data.css', PH()->plugin_url() . '/assets/css/admin-hide-default-post-data.css', array(), PH_VERSION ); | |
| 85 | 95 | } |
| 86 | 96 | |
| 87 | 97 | if ( |
| 88 | 98 | get_option('propertyhive_module_disabled_viewings', '') != 'yes' && |
| @@ -117,33 +127,34 @@ | ||
| 117 | 127 | public function admin_scripts() { |
| 118 | 128 | global $wp_query, $post, $tabs; |
| 119 | 129 | |
| 120 | 130 | $screen = get_current_screen(); |
| 121 | - $ph_screen_id = sanitize_title( __( 'PropertyHive', 'propertyhive' ) ); | |
| 122 | 131 | $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; |
| 123 | 132 | |
| 124 | 133 | // Register scripts |
| 125 | - wp_register_script( 'propertyhive_dashboard', PH()->plugin_url() . '/assets/js/admin/dashboard' . /*$suffix .*/ '.js', array( 'jquery' ), PH_VERSION ); | |
| 134 | + wp_register_script( 'propertyhive_dashboard', PH()->plugin_url() . '/assets/js/admin/dashboard' . /*$suffix .*/ '.js', array( 'jquery' ), PH_VERSION, true ); | |
| 126 | 135 | |
| 127 | - wp_register_script( 'propertyhive_admin', PH()->plugin_url() . '/assets/js/admin/admin' . /*$suffix .*/ '.js', array( 'jquery', 'jquery-tiptip' ), PH_VERSION ); | |
| 136 | + wp_register_script( 'propertyhive_admin', PH()->plugin_url() . '/assets/js/admin/admin' . /*$suffix .*/ '.js', array( 'jquery', 'jquery-tiptip' ), PH_VERSION, true ); | |
| 128 | 137 | |
| 129 | 138 | wp_register_script( 'jquery-tiptip', PH()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip' . /*$suffix .*/ '.js', array( 'jquery' ), PH_VERSION, true ); |
| 130 | 139 | |
| 131 | - wp_register_script( 'propertyhive_admin_meta_boxes', PH()->plugin_url() . '/assets/js/admin/meta-boxes' . /*$suffix .*/ '.js', array( 'jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable' ), PH_VERSION ); | |
| 140 | + wp_register_script( 'propertyhive_admin_meta_boxes', PH()->plugin_url() . '/assets/js/admin/meta-boxes' . /*$suffix .*/ '.js', array( 'jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable' ), PH_VERSION, true ); | |
| 132 | 141 | |
| 133 | - wp_register_script( 'propertyhive_admin_settings', PH()->plugin_url() . '/assets/js/admin/settings' . /*$suffix .*/ '.js', array( 'jquery', 'wp-color-picker' ), PH_VERSION ); | |
| 142 | + wp_register_script( 'propertyhive_admin_settings', PH()->plugin_url() . '/assets/js/admin/settings' . /*$suffix .*/ '.js', array( 'jquery', 'wp-color-picker' ), PH_VERSION, true ); | |
| 134 | 143 | |
| 135 | - wp_register_script( 'propertyhive_admin_recently_viewed', PH()->plugin_url() . '/assets/js/admin/recently-viewed' . /*$suffix .*/ '.js', array( 'jquery' ), PH_VERSION ); | |
| 144 | + wp_register_script( 'propertyhive_admin_onboarding', PH()->plugin_url() . '/assets/js/admin/onboarding' . /*$suffix .*/ '.js', array( 'jquery' ), PH_VERSION, true ); | |
| 136 | 145 | |
| 137 | - wp_register_script( 'ajax-chosen', PH()->plugin_url() . '/assets/js/chosen/ajax-chosen.jquery' . /*$suffix .*/ '.js', array('jquery', 'chosen'), PH_VERSION ); | |
| 146 | + wp_register_script( 'propertyhive_admin_recently_viewed', PH()->plugin_url() . '/assets/js/admin/recently-viewed' . /*$suffix .*/ '.js', array( 'jquery' ), PH_VERSION, true ); | |
| 138 | 147 | |
| 139 | - wp_register_script( 'chosen', PH()->plugin_url() . '/assets/js/chosen/chosen.jquery' . /*$suffix .*/ '.js', array('jquery'), PH_VERSION ); | |
| 148 | + wp_register_script( 'ajax-chosen', PH()->plugin_url() . '/assets/js/chosen/ajax-chosen.jquery' . /*$suffix .*/ '.js', array('jquery', 'chosen'), PH_VERSION, true ); | |
| 140 | 149 | |
| 141 | - wp_register_script( 'multiselect', PH()->plugin_url() . '/assets/js/multiselect/jquery.multiselect' . /*$suffix .*/ '.js', array('jquery'), '2.4.18' ); | |
| 150 | + wp_register_script( 'chosen', PH()->plugin_url() . '/assets/js/chosen/chosen.jquery' . /*$suffix .*/ '.js', array('jquery'), PH_VERSION, true ); | |
| 142 | 151 | |
| 143 | - wp_register_script( 'flot', PH()->plugin_url() . '/assets/js/jquery-flot/jquery.flot' . $suffix . '.js', array( 'jquery' ), PH_VERSION ); | |
| 144 | - wp_register_script( 'flot-resize', PH()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.resize' . $suffix . '.js', array( 'jquery', 'flot' ), PH_VERSION ); | |
| 145 | - wp_register_script( 'flot-time', PH()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.time' . $suffix . '.js', array( 'jquery', 'flot' ), PH_VERSION ); | |
| 152 | + wp_register_script( 'multiselect', PH()->plugin_url() . '/assets/js/multiselect/jquery.multiselect' . /*$suffix .*/ '.js', array('jquery'), '2.4.18', true ); | |
| 153 | + | |
| 154 | + wp_register_script( 'flot', PH()->plugin_url() . '/assets/js/jquery-flot/jquery.flot' . $suffix . '.js', array( 'jquery' ), PH_VERSION, true ); | |
| 155 | + wp_register_script( 'flot-resize', PH()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.resize' . $suffix . '.js', array( 'jquery', 'flot' ), PH_VERSION, true ); | |
| 156 | + wp_register_script( 'flot-time', PH()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.time' . $suffix . '.js', array( 'jquery', 'flot' ), PH_VERSION, true ); | |
| 146 | 157 | //wp_register_script( 'flot-pie', PH()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.pie' . $suffix . '.js', array( 'jquery', 'flot' ), PH_VERSION ); |
| 147 | 158 | //wp_register_script( 'flot-stack', PH()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.stack' . $suffix . '.js', array( 'jquery', 'flot' ), PH_VERSION ); |
| 148 | 159 | |
| 149 | 160 | wp_enqueue_script( 'propertyhive_admin' ); |
| @@ -154,8 +165,9 @@ | ||
| 154 | 165 | if ( |
| 155 | 166 | isset($post->ID) && |
| 156 | 167 | function_exists( 'use_block_editor_for_post_type' ) && |
| 157 | 168 | use_block_editor_for_post_type( get_post_type($post->ID) ) && |
| 169 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only classic/block editor selection controls the scripts loaded. | |
| 158 | 170 | !isset( $_GET['classic-editor'] ) && |
| 159 | 171 | is_array($tabs) && |
| 160 | 172 | !empty($tabs) |
| 161 | 173 | ) |
| @@ -211,18 +223,23 @@ | ||
| 211 | 223 | ); |
| 212 | 224 | wp_localize_script( 'propertyhive_dashboard', 'propertyhive_dashboard', $params ); |
| 213 | 225 | } |
| 214 | 226 | |
| 227 | + if ( in_array( $screen->id, array( 'dashboard_page_ph-onboarding' ), true ) ) | |
| 228 | + { | |
| 229 | + wp_enqueue_script( 'propertyhive_admin_onboarding' ); | |
| 230 | + } | |
| 231 | + | |
| 215 | 232 | if ( in_array( $screen->id, array( 'edit-contact', 'edit-enquiry', 'edit-appraisal', 'edit-viewing', 'edit-offer', 'edit-sale', 'edit-key_date' ) ) ) |
| 216 | 233 | { |
| 217 | - wp_enqueue_script( 'moment.js', '//cdn.jsdelivr.net/momentjs/latest/moment.min.js' ); | |
| 218 | - wp_enqueue_script( 'daterangepicker.js', '//cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js' ); | |
| 219 | - wp_enqueue_script( 'date_range_filter.js', PH()->plugin_url() . '/assets/js/admin/date_range_filter.js', array('jquery', 'moment.js', 'daterangepicker.js'), PH_VERSION ); | |
| 234 | + wp_enqueue_script( 'moment' ); | |
| 235 | + wp_enqueue_script( 'daterangepicker.js', PH()->plugin_url() . '/assets/js/daterangepicker/daterangepicker.js', array( 'jquery', 'moment' ), '3.1.0', true ); | |
| 236 | + wp_enqueue_script( 'date_range_filter.js', PH()->plugin_url() . '/assets/js/admin/date_range_filter.js', array( 'jquery', 'moment', 'daterangepicker.js' ), PH_VERSION, true ); | |
| 220 | 237 | } |
| 221 | 238 | |
| 222 | 239 | if ( in_array( $screen->id, array( 'edit-key_date' ) ) ) |
| 223 | 240 | { |
| 224 | - wp_enqueue_script( 'inline-edit-key_date.js', PH()->plugin_url() . '/assets/js/admin/inline-edit-key_date.js', array('jquery'), PH_VERSION ); | |
| 241 | + wp_enqueue_script( 'inline-edit-key_date.js', PH()->plugin_url() . '/assets/js/admin/inline-edit-key_date.js', array('jquery'), PH_VERSION, true ); | |
| 225 | 242 | } |
| 226 | 243 | |
| 227 | 244 | if ( |
| 228 | 245 | get_option('propertyhive_module_disabled_viewings', '') != 'yes' && |
| @@ -228,9 +245,9 @@ | ||
| 228 | 245 | get_option('propertyhive_module_disabled_viewings', '') != 'yes' && |
| 229 | 246 | in_array( $screen->id, array( 'property', 'contact' ) ) |
| 230 | 247 | ) |
| 231 | 248 | { |
| 232 | - wp_enqueue_script( 'propertyhive_fancybox', PH()->plugin_url() . '/assets/js/fancybox/jquery.fancybox.js', array('jquery'), '3.5.7' ); | |
| 249 | + wp_enqueue_script( 'propertyhive_fancybox', PH()->plugin_url() . '/assets/js/fancybox/jquery.fancybox.js', array('jquery'), '3.5.7', true ); | |
| 233 | 250 | } |
| 234 | 251 | |
| 235 | 252 | if ( in_array( $screen->id, array( 'property' ) ) ) |
| 236 | 253 | { |
| @@ -239,12 +256,13 @@ | ||
| 239 | 256 | require( ABSPATH . WPINC . '/class-wp-editor.php' ); |
| 240 | 257 | } |
| 241 | 258 | add_action( 'admin_print_footer_scripts', array( '_WP_Editors', 'print_default_editor_scripts' ) ); |
| 242 | 259 | |
| 243 | - if ( isset($_GET['tutorial']) && sanitize_text_field($_GET['tutorial']) == 'yes' ) | |
| 260 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only tour asset selection; no data is changed. | |
| 261 | + if ( isset( $_GET['tutorial'] ) && is_string( $_GET['tutorial'] ) && sanitize_text_field( wp_unslash( $_GET['tutorial'] ) ) === 'yes' ) | |
| 244 | 262 | { |
| 245 | - wp_enqueue_script( 'driver-js', PH()->plugin_url() . '/assets/js/tours/driver-js.js', array(), '1.0.1' ); | |
| 246 | - wp_register_script( 'tour', PH()->plugin_url() . '/assets/js/tours/tour.js', array( 'driver-js' ), '1.0.1' ); | |
| 263 | + wp_enqueue_script( 'driver-js', PH()->plugin_url() . '/assets/js/tours/driver-js.js', array(), '1.0.1', true ); | |
| 264 | + wp_register_script( 'tour', PH()->plugin_url() . '/assets/js/tours/tour.js', array( 'driver-js' ), '1.0.1', true ); | |
| 247 | 265 | wp_enqueue_script( 'tour' ); |
| 248 | 266 | |
| 249 | 267 | $tours = [ |
| 250 | 268 | 'add-property' => [ |
| @@ -314,15 +332,15 @@ | ||
| 314 | 332 | wp_enqueue_script( 'wp-tinymce' ); |
| 315 | 333 | |
| 316 | 334 | if ( get_option('propertyhive_maps_provider') == 'mapbox' ) |
| 317 | 335 | { |
| 318 | - wp_register_script('mapbox', PH()->plugin_url() . '/assets/js/mapbox/mapbox-gl.js', false, '3.8.0'); | |
| 336 | + wp_register_script('mapbox', PH()->plugin_url() . '/assets/js/mapbox/mapbox-gl.js', false, '3.8.0', true ); | |
| 319 | 337 | wp_enqueue_script('mapbox'); |
| 320 | 338 | |
| 321 | 339 | if ( get_option('propertyhive_geocoding_provider') == '' ) |
| 322 | 340 | { |
| 323 | 341 | $api_key = get_option('propertyhive_google_maps_geocoding_api_key'); |
| 324 | - wp_register_script('googlemaps', '//maps.googleapis.com/maps/api/js?' . ( ( $api_key != '' && $api_key !== FALSE ) ? 'key=' . $api_key : '' ), false, '3'); | |
| 342 | + wp_register_script('googlemaps', '//maps.googleapis.com/maps/api/js?' . ( ( $api_key != '' && $api_key !== FALSE ) ? 'key=' . $api_key : '' ), false, '3', true ); | |
| 325 | 343 | wp_enqueue_script('googlemaps'); |
| 326 | 344 | } |
| 327 | 345 | } |
| 328 | 346 | elseif ( get_option('propertyhive_maps_provider') == 'osm' ) |
| @@ -335,9 +353,9 @@ | ||
| 335 | 353 | |
| 336 | 354 | if ( get_option('propertyhive_geocoding_provider') == '' ) |
| 337 | 355 | { |
| 338 | 356 | $api_key = get_option('propertyhive_google_maps_geocoding_api_key'); |
| 339 | - wp_register_script('googlemaps', '//maps.googleapis.com/maps/api/js?' . ( ( $api_key != '' && $api_key !== FALSE ) ? 'key=' . $api_key : '' ), false, '3'); | |
| 357 | + wp_register_script('googlemaps', '//maps.googleapis.com/maps/api/js?' . ( ( $api_key != '' && $api_key !== FALSE ) ? 'key=' . $api_key : '' ), false, '3', true ); | |
| 340 | 358 | wp_enqueue_script('googlemaps'); |
| 341 | 359 | } |
| 342 | 360 | } |
| 343 | 361 | else |
| @@ -342,9 +360,9 @@ | ||
| 342 | 360 | } |
| 343 | 361 | else |
| 344 | 362 | { |
| 345 | 363 | $api_key = get_option('propertyhive_google_maps_api_key'); |
| 346 | - wp_register_script('googlemaps', '//maps.googleapis.com/maps/api/js?' . ( ( $api_key != '' && $api_key !== FALSE ) ? 'key=' . $api_key : '' ), false, '3'); | |
| 364 | + wp_register_script('googlemaps', '//maps.googleapis.com/maps/api/js?' . ( ( $api_key != '' && $api_key !== FALSE ) ? 'key=' . $api_key : '' ), false, '3', true ); | |
| 347 | 365 | wp_enqueue_script('googlemaps'); |
| 348 | 366 | } |
| 349 | 367 | |
| 350 | 368 | wp_enqueue_media(); |
| @@ -362,8 +380,10 @@ | ||
| 362 | 380 | 'get_notes_nonce' => wp_create_nonce("get-notes"), |
| 363 | 381 | 'pin_note_nonce' => wp_create_nonce("pin-note"), |
| 364 | 382 | 'add_note_nonce' => wp_create_nonce("add-note"), |
| 365 | 383 | 'delete_note_nonce' => wp_create_nonce("delete-note"), |
| 384 | + 'add_key_date_nonce' => wp_create_nonce( 'propertyhive-add-key-date' ), | |
| 385 | + 'export_sub_grid_nonce' => wp_create_nonce( 'propertyhive-export-sub-grid' ), | |
| 366 | 386 | 'viewing_details_meta_nonce' => wp_create_nonce( 'viewing-details-meta-box' ), |
| 367 | 387 | 'viewing_actions_nonce' => wp_create_nonce( 'viewing-actions' ), |
| 368 | 388 | 'save_key_date_nonce' => wp_create_nonce( 'save-key-date' ), |
| 369 | 389 | 'delete_key_date_nonce' => wp_create_nonce( 'delete-key-date' ), |
| @@ -395,13 +415,15 @@ | ||
| 395 | 415 | 'primary_department_not_active_warning' => __( 'The chosen primary department has not been selected as active', 'propertyhive' ), |
| 396 | 416 | 'no_countries_selected' => __( 'Please select which countries you operate in', 'propertyhive' ), |
| 397 | 417 | 'default_country_not_in_selected' => __( 'The default country hasn\'t been selected as a country you operate in', 'propertyhive' ), |
| 398 | 418 | 'admin_url' => admin_url(), |
| 399 | - 'taxonomy_section' => ( ( isset($_GET['section']) ) ? sanitize_text_field($_GET['section']) : '' ), | |
| 419 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only settings section passed through WordPress script localization. | |
| 420 | + 'taxonomy_section' => isset( $_GET['section'] ) && is_string( $_GET['section'] ) ? sanitize_text_field( wp_unslash( $_GET['section'] ) ) : '', | |
| 400 | 421 | 'ajax_nonce' => wp_create_nonce("updates"), |
| 401 | 422 | 'features_settings_url' => admin_url('admin.php?page=ph-settings&tab=features'), |
| 402 | 423 | ); |
| 403 | - if ( isset($_GET['tab']) && ph_clean($_GET['tab']) == 'licensekey' ) | |
| 424 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Settings tab determines whether the existing license status is refreshed. | |
| 425 | + if ( isset( $_GET['tab'] ) && is_string( $_GET['tab'] ) && sanitize_text_field( wp_unslash( $_GET['tab'] ) ) === 'licensekey' ) | |
| 404 | 426 | { |
| 405 | 427 | $params['valid_pro_license_key'] = PH()->license->is_valid_pro_license_key(true); |
| 406 | 428 | } |
| 407 | 429 | else |
| @@ -465,5 +487,5 @@ | ||
| 465 | 487 | } |
| 466 | 488 | |
| 467 | 489 | endif; |
| 468 | 490 | |
| 469 | -return new PH_Admin_Assets(); | |
| 491 | +return new PH_Admin_Assets(); | |