--- a/wp/wp-includes/class-wp-customize-manager.php Tue Oct 22 16:11:46 2019 +0200
+++ b/wp/wp-includes/class-wp-customize-manager.php Tue Dec 15 13:49:49 2020 +0100
@@ -232,7 +232,7 @@
* Changeset data loaded from a customize_changeset post.
*
* @since 4.7.0
- * @var array
+ * @var array|null
*/
private $_changeset_data;
@@ -270,7 +270,8 @@
$args['changeset_uuid'] = wp_generate_uuid4();
}
- // The theme and messenger_channel should be supplied via $args, but they are also looked at in the $_REQUEST global here for back-compat.
+ // The theme and messenger_channel should be supplied via $args,
+ // but they are also looked at in the $_REQUEST global here for back-compat.
if ( ! isset( $args['theme'] ) ) {
if ( isset( $_REQUEST['customize_theme'] ) ) {
$args['theme'] = wp_unslash( $_REQUEST['customize_theme'] );
@@ -293,46 +294,44 @@
}
}
- require_once( ABSPATH . WPINC . '/class-wp-customize-setting.php' );
- require_once( ABSPATH . WPINC . '/class-wp-customize-panel.php' );
- require_once( ABSPATH . WPINC . '/class-wp-customize-section.php' );
- require_once( ABSPATH . WPINC . '/class-wp-customize-control.php' );
-
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-color-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-media-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-upload-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-image-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-position-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-cropped-image-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-site-icon-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-theme-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-code-editor-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-widget-area-customize-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-widget-form-customize-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-location-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-name-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-locations-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-auto-add-control.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-control.php' ); // @todo Remove in a future release. See #42364.
-
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menus-panel.php' );
-
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-themes-panel.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-themes-section.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-sidebar-section.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-section.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-section.php' ); // @todo Remove in a future release. See #42364.
-
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-custom-css-setting.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-filter-setting.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-setting.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-setting.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-setting.php' );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-setting.php' );
+ require_once ABSPATH . WPINC . '/class-wp-customize-setting.php';
+ require_once ABSPATH . WPINC . '/class-wp-customize-panel.php';
+ require_once ABSPATH . WPINC . '/class-wp-customize-section.php';
+ require_once ABSPATH . WPINC . '/class-wp-customize-control.php';
+
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-color-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-media-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-upload-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-image-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-background-image-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-background-position-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-cropped-image-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-site-icon-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-header-image-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-theme-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-code-editor-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-widget-area-customize-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-widget-form-customize-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-location-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-name-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-locations-control.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-auto-add-control.php';
+
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-nav-menus-panel.php';
+
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-themes-panel.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-themes-section.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-sidebar-section.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-section.php';
+
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-custom-css-setting.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-filter-setting.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-header-image-setting.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-background-image-setting.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-setting.php';
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-setting.php';
/**
* Filters the core Customizer components to load.
@@ -351,16 +350,16 @@
*/
$components = apply_filters( 'customize_loaded_components', $this->components, $this );
- require_once( ABSPATH . WPINC . '/customize/class-wp-customize-selective-refresh.php' );
+ require_once ABSPATH . WPINC . '/customize/class-wp-customize-selective-refresh.php';
$this->selective_refresh = new WP_Customize_Selective_Refresh( $this );
if ( in_array( 'widgets', $components, true ) ) {
- require_once( ABSPATH . WPINC . '/class-wp-customize-widgets.php' );
+ require_once ABSPATH . WPINC . '/class-wp-customize-widgets.php';
$this->widgets = new WP_Customize_Widgets( $this );
}
if ( in_array( 'nav_menus', $components, true ) ) {
- require_once( ABSPATH . WPINC . '/class-wp-customize-nav-menus.php' );
+ require_once ABSPATH . WPINC . '/class-wp-customize-nav-menus.php';
$this->nav_menus = new WP_Customize_Nav_Menus( $this );
}
@@ -385,7 +384,7 @@
add_action( 'wp_ajax_customize_dismiss_autosave_or_lock', array( $this, 'handle_dismiss_autosave_or_lock_request' ) );
add_action( 'customize_register', array( $this, 'register_controls' ) );
- add_action( 'customize_register', array( $this, 'register_dynamic_settings' ), 11 ); // allow code to create settings first
+ add_action( 'customize_register', array( $this, 'register_dynamic_settings' ), 11 ); // Allow code to create settings first.
add_action( 'customize_controls_init', array( $this, 'prepare_controls' ) );
add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_control_scripts' ) );
@@ -438,8 +437,8 @@
*
* @since 3.4.0
*
- * @param mixed $ajax_message Ajax return
- * @param mixed $message UI message
+ * @param string|WP_Error $ajax_message Ajax return.
+ * @param string $message Optional. UI message.
*/
protected function wp_die( $ajax_message, $message = null ) {
if ( $this->doing_ajax() ) {
@@ -506,7 +505,7 @@
public function setup_theme() {
global $pagenow;
- // Check permissions for customize.php access since this method is called before customize.php can run any code,
+ // Check permissions for customize.php access since this method is called before customize.php can run any code.
if ( 'customize.php' === $pagenow && ! current_user_can( 'customize' ) ) {
if ( ! is_user_logged_in() ) {
auth_redirect();
@@ -565,8 +564,8 @@
// Once the theme is loaded, we'll validate it.
add_action( 'after_setup_theme', array( $this, 'after_setup_theme' ) );
} else {
- // If the requested theme is not the active theme and the user doesn't have the
- // switch_themes cap, bail.
+ // If the requested theme is not the active theme and the user doesn't have
+ // the switch_themes cap, bail.
if ( ! current_user_can( 'switch_themes' ) ) {
$this->wp_die( -1, __( 'Sorry, you are not allowed to edit theme options on this site.' ) );
}
@@ -607,6 +606,7 @@
* enabled, then a new UUID will be generated.
*
* @since 4.9.0
+ *
* @global string $pagenow
*/
public function establish_loaded_changeset() {
@@ -738,6 +738,7 @@
* Gets whether settings are or will be previewed.
*
* @since 4.9.0
+ *
* @see WP_Customize_Setting::preview()
*
* @return bool
@@ -750,6 +751,7 @@
* Gets whether data from a changeset's autosaved revision should be loaded if it exists.
*
* @since 4.9.0
+ *
* @see WP_Customize_Manager::changeset_data()
*
* @return bool Is using autosaved changeset revision.
@@ -762,6 +764,7 @@
* Whether the changeset branching is allowed.
*
* @since 4.9.0
+ *
* @see WP_Customize_Manager::establish_loaded_changeset()
*
* @return bool Is changeset branching.
@@ -802,6 +805,7 @@
* Get the changeset UUID.
*
* @since 4.7.0
+ *
* @see WP_Customize_Manager::establish_loaded_changeset()
*
* @return string UUID.
@@ -890,7 +894,7 @@
* @return bool
*/
public function is_theme_active() {
- return $this->get_stylesheet() == $this->original_stylesheet;
+ return $this->get_stylesheet() === $this->original_stylesheet;
}
/**
@@ -900,7 +904,8 @@
*/
public function wp_loaded() {
- // Unconditionally register core types for panels, sections, and controls in case plugin unhooks all customize_register actions.
+ // Unconditionally register core types for panels, sections, and controls
+ // in case plugin unhooks all customize_register actions.
$this->register_panel_type( 'WP_Customize_Panel' );
$this->register_panel_type( 'WP_Customize_Themes_Panel' );
$this->register_section_type( 'WP_Customize_Section' );
@@ -1072,7 +1077,7 @@
}
/**
- * Get the changeset post id for the loaded changeset.
+ * Get the changeset post ID for the loaded changeset.
*
* @since 4.7.0
*
@@ -1116,8 +1121,9 @@
return new WP_Error( 'wrong_post_type' );
}
$changeset_data = json_decode( $changeset_post->post_content, true );
- if ( function_exists( 'json_last_error' ) && json_last_error() ) {
- return new WP_Error( 'json_parse_error', '', json_last_error() );
+ $last_error = json_last_error();
+ if ( $last_error ) {
+ return new WP_Error( 'json_parse_error', '', $last_error );
}
if ( ! is_array( $changeset_data ) ) {
return new WP_Error( 'expected_array' );
@@ -1229,7 +1235,7 @@
$widget_numbers = array_keys( $settings );
if ( count( $widget_numbers ) > 0 ) {
$widget_numbers[] = 1;
- $max_widget_numbers[ $id_base ] = call_user_func_array( 'max', $widget_numbers );
+ $max_widget_numbers[ $id_base ] = max( ...$widget_numbers );
} else {
$max_widget_numbers[ $id_base ] = 1;
}
@@ -1375,13 +1381,6 @@
)
);
- // In PHP < 5.6 filesize() returns 0 for the temp files unless we clear the file status cache.
- // Technically, PHP < 5.6.0 || < 5.5.13 || < 5.4.29 but no need to be so targeted.
- // See https://bugs.php.net/bug.php?id=65701
- if ( version_compare( PHP_VERSION, '5.6', '<' ) ) {
- clearstatcache();
- }
-
$attachment_id = media_handle_sideload( $file_array, 0, null, $attachment_post_data );
if ( is_wp_error( $attachment_id ) ) {
continue;
@@ -1523,7 +1522,27 @@
// Options.
foreach ( $options as $name => $value ) {
- if ( preg_match( '/^{{(?P<symbol>.+)}}$/', $value, $matches ) ) {
+
+ // Serialize the value to check for post symbols.
+ $value = maybe_serialize( $value );
+
+ if ( is_serialized( $value ) ) {
+ if ( preg_match( '/s:\d+:"{{(?P<symbol>.+)}}"/', $value, $matches ) ) {
+ if ( isset( $posts[ $matches['symbol'] ] ) ) {
+ $symbol_match = $posts[ $matches['symbol'] ]['ID'];
+ } elseif ( isset( $attachment_ids[ $matches['symbol'] ] ) ) {
+ $symbol_match = $attachment_ids[ $matches['symbol'] ];
+ }
+
+ // If we have any symbol matches, update the values.
+ if ( isset( $symbol_match ) ) {
+ // Replace found string matches with post IDs.
+ $value = str_replace( $matches[0], "i:{$symbol_match}", $value );
+ } else {
+ continue;
+ }
+ }
+ } elseif ( preg_match( '/^{{(?P<symbol>.+)}}$/', $value, $matches ) ) {
if ( isset( $posts[ $matches['symbol'] ] ) ) {
$value = $posts[ $matches['symbol'] ]['ID'];
} elseif ( isset( $attachment_ids[ $matches['symbol'] ] ) ) {
@@ -1533,6 +1552,9 @@
}
}
+ // Unserialize values after checking for post symbols, so they can be properly referenced.
+ $value = maybe_unserialize( $value );
+
if ( empty( $changeset_data[ $name ] ) || ! empty( $changeset_data[ $name ]['starter_content'] ) ) {
$this->set_post_value( $name, $value );
$this->pending_starter_content_settings_ids[] = $name;
@@ -1541,7 +1563,28 @@
// Theme mods.
foreach ( $theme_mods as $name => $value ) {
- if ( preg_match( '/^{{(?P<symbol>.+)}}$/', $value, $matches ) ) {
+
+ // Serialize the value to check for post symbols.
+ $value = maybe_serialize( $value );
+
+ // Check if value was serialized.
+ if ( is_serialized( $value ) ) {
+ if ( preg_match( '/s:\d+:"{{(?P<symbol>.+)}}"/', $value, $matches ) ) {
+ if ( isset( $posts[ $matches['symbol'] ] ) ) {
+ $symbol_match = $posts[ $matches['symbol'] ]['ID'];
+ } elseif ( isset( $attachment_ids[ $matches['symbol'] ] ) ) {
+ $symbol_match = $attachment_ids[ $matches['symbol'] ];
+ }
+
+ // If we have any symbol matches, update the values.
+ if ( isset( $symbol_match ) ) {
+ // Replace found string matches with post IDs.
+ $value = str_replace( $matches[0], "i:{$symbol_match}", $value );
+ } else {
+ continue;
+ }
+ }
+ } elseif ( preg_match( '/^{{(?P<symbol>.+)}}$/', $value, $matches ) ) {
if ( isset( $posts[ $matches['symbol'] ] ) ) {
$value = $posts[ $matches['symbol'] ]['ID'];
} elseif ( isset( $attachment_ids[ $matches['symbol'] ] ) ) {
@@ -1551,6 +1594,9 @@
}
}
+ // Unserialize values after checking for post symbols, so they can be properly referenced.
+ $value = maybe_unserialize( $value );
+
// Handle header image as special case since setting has a legacy format.
if ( 'header_image' === $name ) {
$name = 'header_image_data';
@@ -1600,9 +1646,9 @@
}
// Such is The WordPress Way.
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
- require_once( ABSPATH . 'wp-admin/includes/media.php' );
- require_once( ABSPATH . 'wp-admin/includes/image.php' );
+ require_once ABSPATH . 'wp-admin/includes/file.php';
+ require_once ABSPATH . 'wp-admin/includes/media.php';
+ require_once ABSPATH . 'wp-admin/includes/image.php';
foreach ( $attachments as $symbol => $attachment ) {
@@ -1768,7 +1814,7 @@
* @param WP_Customize_Setting $setting A WP_Customize_Setting derived object.
* @param mixed $default Value returned $setting has no post value (added in 4.2.0)
* or the post value is invalid (added in 4.6.0).
- * @return string|mixed $post_value Sanitized value or the $default provided.
+ * @return string|mixed Sanitized value or the $default provided.
*/
public function post_value( $setting, $default = null ) {
$post_values = $this->unsanitized_post_values();
@@ -1861,7 +1907,14 @@
* that the user's session has expired and they need to re-authenticate.
*/
if ( $this->messenger_channel && ! current_user_can( 'customize' ) ) {
- $this->wp_die( -1, __( 'Unauthorized. You may remove the customize_messenger_channel param to preview as frontend.' ) );
+ $this->wp_die(
+ -1,
+ sprintf(
+ /* translators: %s: customize_messenger_channel */
+ __( 'Unauthorized. You may remove the %s param to preview as frontend.' ),
+ '<code>customize_messenger_channel<code>'
+ )
+ );
return;
}
@@ -1905,6 +1958,7 @@
* Add customize state query params to a given URL if preview is allowed.
*
* @since 4.7.0
+ *
* @see wp_redirect()
* @see WP_Customize_Manager::get_allowed_url()
*
@@ -2245,7 +2299,7 @@
*
* @since 3.4.0
*
- * @param $current_theme {@internal Parameter is not used}
+ * @param mixed $current_theme {@internal Parameter is not used}
* @return string Theme name.
*/
public function current_theme( $current_theme ) {
@@ -2500,7 +2554,7 @@
$this->dismiss_user_auto_draft_changesets();
}
- // Note that if the changeset status was publish, then it will get set to trash if revisions are not supported.
+ // Note that if the changeset status was publish, then it will get set to Trash if revisions are not supported.
$response['changeset_status'] = $changeset_post->post_status;
if ( $is_publish && 'trash' === $response['changeset_status'] ) {
$response['changeset_status'] = 'publish';
@@ -2729,7 +2783,7 @@
if ( $update_transactionally && $invalid_setting_count > 0 ) {
$response = array(
'setting_validities' => $setting_validities,
- /* translators: %s: number of invalid settings */
+ /* translators: %s: Number of invalid settings. */
'message' => sprintf( _n( 'Unable to save due to %s invalid setting.', 'Unable to save due to %s invalid settings.', $invalid_setting_count ), number_format_i18n( $invalid_setting_count ) ),
);
return new WP_Error( 'transaction_fail', '', $response );
@@ -2843,13 +2897,9 @@
}
// Gather the data for wp_insert_post()/wp_update_post().
- $json_options = 0;
- if ( defined( 'JSON_UNESCAPED_SLASHES' ) ) {
- $json_options |= JSON_UNESCAPED_SLASHES; // Introduced in PHP 5.4. This is only to improve readability as slashes needn't be escaped in storage.
- }
- $json_options |= JSON_PRETTY_PRINT; // Also introduced in PHP 5.4, but WP defines constant for back compat. See WP Trac #30139.
- $post_array = array(
- 'post_content' => wp_json_encode( $data, $json_options ),
+ $post_array = array(
+ // JSON_UNESCAPED_SLASHES is only to improve readability as slashes needn't be escaped in storage.
+ 'post_content' => wp_json_encode( $data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ),
);
if ( $args['title'] ) {
$post_array['post_title'] = $args['title'];
@@ -2886,33 +2936,26 @@
add_filter( 'wp_save_post_revision_post_has_changed', array( $this, '_filter_revision_post_has_changed' ), 5, 3 );
/*
- * Update the changeset post. The publish_customize_changeset action
- * will cause the settings in the changeset to be saved via
- * WP_Customize_Setting::save().
+ * Update the changeset post. The publish_customize_changeset action will cause the settings in the
+ * changeset to be saved via WP_Customize_Setting::save(). Updating a post with publish status will
+ * trigger WP_Customize_Manager::publish_changeset_values().
*/
-
- // Prevent content filters from corrupting JSON in post_content.
- $has_kses = ( false !== has_filter( 'content_save_pre', 'wp_filter_post_kses' ) );
- if ( $has_kses ) {
- kses_remove_filters();
- }
- $has_targeted_link_rel_filters = ( false !== has_filter( 'content_save_pre', 'wp_targeted_link_rel' ) );
- if ( $has_targeted_link_rel_filters ) {
- wp_remove_targeted_link_rel_filters();
- }
-
- // Note that updating a post with publish status will trigger WP_Customize_Manager::publish_changeset_values().
+ add_filter( 'wp_insert_post_data', array( $this, 'preserve_insert_changeset_post_content' ), 5, 3 );
if ( $changeset_post_id ) {
if ( $args['autosave'] && 'auto-draft' !== get_post_status( $changeset_post_id ) ) {
// See _wp_translate_postdata() for why this is required as it will use the edit_post meta capability.
add_filter( 'map_meta_cap', array( $this, 'grant_edit_post_capability_for_changeset' ), 10, 4 );
+
$post_array['post_ID'] = $post_array['ID'];
$post_array['post_type'] = 'customize_changeset';
- $r = wp_create_post_autosave( wp_slash( $post_array ) );
+
+ $r = wp_create_post_autosave( wp_slash( $post_array ) );
+
remove_filter( 'map_meta_cap', array( $this, 'grant_edit_post_capability_for_changeset' ), 10 );
} else {
$post_array['edit_date'] = true; // Prevent date clearing.
- $r = wp_update_post( wp_slash( $post_array ), true );
+
+ $r = wp_update_post( wp_slash( $post_array ), true );
// Delete autosave revision for user when the changeset is updated.
if ( ! empty( $args['user_id'] ) ) {
@@ -2928,14 +2971,7 @@
$this->_changeset_post_id = $r; // Update cached post ID for the loaded changeset.
}
}
-
- // Restore removed content filters.
- if ( $has_kses ) {
- kses_init_filters();
- }
- if ( $has_targeted_link_rel_filters ) {
- wp_init_targeted_link_rel_filters();
- }
+ remove_filter( 'wp_insert_post_data', array( $this, 'preserve_insert_changeset_post_content' ), 5 );
$this->_changeset_data = null; // Reset so WP_Customize_Manager::changeset_data() will re-populate with updated contents.
@@ -2954,6 +2990,51 @@
}
/**
+ * Preserve the initial JSON post_content passed to save into the post.
+ *
+ * This is needed to prevent KSES and other {@see 'content_save_pre'} filters
+ * from corrupting JSON data.
+ *
+ * Note that WP_Customize_Manager::validate_setting_values() have already
+ * run on the setting values being serialized as JSON into the post content
+ * so it is pre-sanitized.
+ *
+ * Also, the sanitization logic is re-run through the respective
+ * WP_Customize_Setting::sanitize() method when being read out of the
+ * changeset, via WP_Customize_Manager::post_value(), and this sanitized
+ * value will also be sent into WP_Customize_Setting::update() for
+ * persisting to the DB.
+ *
+ * Multiple users can collaborate on a single changeset, where one user may
+ * have the unfiltered_html capability but another may not. A user with
+ * unfiltered_html may add a script tag to some field which needs to be kept
+ * intact even when another user updates the changeset to modify another field
+ * when they do not have unfiltered_html.
+ *
+ * @since 5.4.1
+ *
+ * @param array $data An array of slashed and processed post data.
+ * @param array $postarr An array of sanitized (and slashed) but otherwise unmodified post data.
+ * @param array $unsanitized_postarr An array of slashed yet *unsanitized* and unprocessed post data as originally passed to wp_insert_post().
+ * @return array Filtered post data.
+ */
+ public function preserve_insert_changeset_post_content( $data, $postarr, $unsanitized_postarr ) {
+ if (
+ isset( $data['post_type'] ) &&
+ isset( $unsanitized_postarr['post_content'] ) &&
+ 'customize_changeset' === $data['post_type'] ||
+ (
+ 'revision' === $data['post_type'] &&
+ ! empty( $data['post_parent'] ) &&
+ 'customize_changeset' === get_post_type( $data['post_parent'] )
+ )
+ ) {
+ $data['post_content'] = $unsanitized_postarr['post_content'];
+ }
+ return $data;
+ }
+
+ /**
* Trash or delete a changeset post.
*
* The following re-formulates the logic from `wp_trash_post()` as done in
@@ -2962,8 +3043,9 @@
* untouched.
*
* @since 4.9.0
+ *
+ * @see wp_trash_post()
* @global wpdb $wpdb WordPress database abstraction object.
- * @see wp_trash_post()
*
* @param int|WP_Post $post The changeset post.
* @return mixed A WP_Post object for the trashed post or an empty value on failure.
@@ -3064,13 +3146,27 @@
return;
}
- if ( $changeset_post_id && ! current_user_can( get_post_type_object( 'customize_changeset' )->cap->delete_post, $changeset_post_id ) ) {
- wp_send_json_error(
- array(
- 'code' => 'changeset_trash_unauthorized',
- 'message' => __( 'Unable to trash changes.' ),
- )
- );
+ if ( $changeset_post_id ) {
+ if ( ! current_user_can( get_post_type_object( 'customize_changeset' )->cap->delete_post, $changeset_post_id ) ) {
+ wp_send_json_error(
+ array(
+ 'code' => 'changeset_trash_unauthorized',
+ 'message' => __( 'Unable to trash changes.' ),
+ )
+ );
+ }
+
+ $lock_user = (int) wp_check_post_lock( $changeset_post_id );
+
+ if ( $lock_user && get_current_user_id() !== $lock_user ) {
+ wp_send_json_error(
+ array(
+ 'code' => 'changeset_locked',
+ 'message' => __( 'Changeset is being edited by other user.' ),
+ 'lockUser' => $this->get_lock_user_data( $lock_user ),
+ )
+ );
+ }
}
if ( 'trash' === get_post_status( $changeset_post_id ) ) {
@@ -3111,6 +3207,7 @@
* This should be able to be removed once #40922 is addressed in core.
*
* @since 4.9.0
+ *
* @link https://core.trac.wordpress.org/ticket/40922
* @see WP_Customize_Manager::save_changeset_post()
* @see _wp_translate_postdata()
@@ -3119,7 +3216,7 @@
* @param string $cap Capability name.
* @param int $user_id The user ID.
* @param array $args Adds the context to the cap. Typically the object ID.
- * @return array Capabilities.
+ * @return array Capabilities.
*/
public function grant_edit_post_capability_for_changeset( $caps, $cap, $user_id, $args ) {
if ( 'edit_post' === $cap && ! empty( $args[0] ) && 'customize_changeset' === get_post_type( $args[0] ) ) {
@@ -3134,8 +3231,8 @@
*
* @since 4.9.0
*
- * @param int $changeset_post_id Changeset post id.
- * @param bool $take_over Take over the changeset, default is false.
+ * @param int $changeset_post_id Changeset post ID.
+ * @param bool $take_over Whether to take over the changeset. Default false.
*/
public function set_changeset_lock( $changeset_post_id, $take_over = false ) {
if ( $changeset_post_id ) {
@@ -3159,7 +3256,7 @@
*
* @since 4.9.0
*
- * @param int $changeset_post_id Changeset post id.
+ * @param int $changeset_post_id Changeset post ID.
*/
public function refresh_changeset_lock( $changeset_post_id ) {
if ( ! $changeset_post_id ) {
@@ -3315,7 +3412,6 @@
* @param bool $post_has_changed Whether the post has changed.
* @param WP_Post $last_revision The last revision post object.
* @param WP_Post $post The post object.
- *
* @return bool Whether a revision should be made.
*/
public function _filter_revision_post_has_changed( $post_has_changed, $last_revision, $post ) {
@@ -3340,8 +3436,9 @@
* invoking this method.
*
* @since 4.7.0
+ *
* @see _wp_customize_publish_changeset()
- * @global wpdb $wpdb
+ * @global wpdb $wpdb WordPress database abstraction object.
*
* @param int $changeset_post_id ID for customize_changeset post. Defaults to the changeset for the current manager instance.
* @return true|WP_Error True or error info.
@@ -3639,26 +3736,14 @@
* @since 3.4.0
* @since 4.5.0 Return added WP_Customize_Setting instance.
*
+ * @see WP_Customize_Setting::__construct()
+ * @link https://developer.wordpress.org/themes/customize-api
+ *
* @param WP_Customize_Setting|string $id Customize Setting object, or ID.
- * @param array $args {
- * Optional. Array of properties for the new WP_Customize_Setting. Default empty array.
- *
- * @type string $type Type of the setting. Default 'theme_mod'.
- * @type string $capability Capability required for the setting. Default 'edit_theme_options'
- * @type string|array $theme_supports Theme features required to support the panel. Default is none.
- * @type string $default Default value for the setting. Default is empty string.
- * @type string $transport Options for rendering the live preview of changes in Customizer.
- * Using 'refresh' makes the change visible by reloading the whole preview.
- * Using 'postMessage' allows a custom JavaScript to handle live changes.
- * @link https://developer.wordpress.org/themes/customize-api
- * Default is 'refresh'
- * @type callable $validate_callback Server-side validation callback for the setting's value.
- * @type callable $sanitize_callback Callback to filter a Customize setting value in un-slashed form.
- * @type callable $sanitize_js_callback Callback to convert a Customize PHP setting value to a value that is
- * JSON serializable.
- * @type bool $dirty Whether or not the setting is initially dirty when created.
- * }
- * @return WP_Customize_Setting The instance of the setting that was added.
+ * @param array $args Optional. Array of properties for the new Setting object.
+ * See WP_Customize_Setting::__construct() for information
+ * on accepted arguments. Default empty array.
+ * @return WP_Customize_Setting The instance of the setting that was added.
*/
public function add_setting( $id, $args = array() ) {
if ( $id instanceof WP_Customize_Setting ) {
@@ -3696,7 +3781,7 @@
public function add_dynamic_settings( $setting_ids ) {
$new_settings = array();
foreach ( $setting_ids as $setting_id ) {
- // Skip settings already created
+ // Skip settings already created.
if ( $this->get_setting( $setting_id ) ) {
continue;
}
@@ -3757,6 +3842,8 @@
/**
* Remove a customize setting.
*
+ * Note that removing the setting doesn't destroy the WP_Customize_Setting instance or remove its filters.
+ *
* @since 3.4.0
*
* @param string $id Customize Setting ID.
@@ -3771,19 +3858,13 @@
* @since 4.0.0
* @since 4.5.0 Return added WP_Customize_Panel instance.
*
- * @param WP_Customize_Panel|string $id Customize Panel object, or Panel ID.
- * @param array $args {
- * Optional. Array of properties for the new Panel object. Default empty array.
- * @type int $priority Priority of the panel, defining the display order of panels and sections.
- * Default 160.
- * @type string $capability Capability required for the panel. Default `edit_theme_options`
- * @type string|array $theme_supports Theme features required to support the panel.
- * @type string $title Title of the panel to show in UI.
- * @type string $description Description to show in the UI.
- * @type string $type Type of the panel.
- * @type callable $active_callback Active callback.
- * }
- * @return WP_Customize_Panel The instance of the panel that was added.
+ * @see WP_Customize_Panel::__construct()
+ *
+ * @param WP_Customize_Panel|string $id Customize Panel object, or ID.
+ * @param array $args Optional. Array of properties for the new Panel object.
+ * See WP_Customize_Panel::__construct() for information
+ * on accepted arguments. Default empty array.
+ * @return WP_Customize_Panel The instance of the panel that was added.
*/
public function add_panel( $id, $args = array() ) {
if ( $id instanceof WP_Customize_Panel ) {
@@ -3813,6 +3894,8 @@
/**
* Remove a customize panel.
*
+ * Note that removing the panel doesn't destroy the WP_Customize_Panel instance or remove its filters.
+ *
* @since 4.0.0
*
* @param string $id Panel ID to remove.
@@ -3820,11 +3903,15 @@
public function remove_panel( $id ) {
// Removing core components this way is _doing_it_wrong().
if ( in_array( $id, $this->components, true ) ) {
- /* translators: 1: panel id, 2: link to 'customize_loaded_components' filter reference */
$message = sprintf(
+ /* translators: 1: Panel ID, 2: Link to 'customize_loaded_components' filter reference. */
__( 'Removing %1$s manually will cause PHP warnings. Use the %2$s filter instead.' ),
$id,
- '<a href="' . esc_url( 'https://developer.wordpress.org/reference/hooks/customize_loaded_components/' ) . '"><code>customize_loaded_components</code></a>'
+ sprintf(
+ '<a href="%1$s">%2$s</a>',
+ esc_url( 'https://developer.wordpress.org/reference/hooks/customize_loaded_components/' ),
+ '<code>customize_loaded_components</code>'
+ )
);
_doing_it_wrong( __METHOD__, $message, '4.5.0' );
@@ -3865,21 +3952,13 @@
* @since 3.4.0
* @since 4.5.0 Return added WP_Customize_Section instance.
*
- * @param WP_Customize_Section|string $id Customize Section object, or Section ID.
- * @param array $args {
- * Optional. Array of properties for the new Section object. Default empty array.
- * @type int $priority Priority of the section, defining the display order of panels and sections.
- * Default 160.
- * @type string $panel The panel this section belongs to (if any). Default empty.
- * @type string $capability Capability required for the section. Default 'edit_theme_options'
- * @type string|array $theme_supports Theme features required to support the section.
- * @type string $title Title of the section to show in UI.
- * @type string $description Description to show in the UI.
- * @type string $type Type of the section.
- * @type callable $active_callback Active callback.
- * @type bool $description_hidden Hide the description behind a help icon, instead of inline above the first control. Default false.
- * }
- * @return WP_Customize_Section The instance of the section that was added.
+ * @see WP_Customize_Section::__construct()
+ *
+ * @param WP_Customize_Section|string $id Customize Section object, or ID.
+ * @param array $args Optional. Array of properties for the new Section object.
+ * See WP_Customize_Section::__construct() for information
+ * on accepted arguments. Default empty array.
+ * @return WP_Customize_Section The instance of the section that was added.
*/
public function add_section( $id, $args = array() ) {
if ( $id instanceof WP_Customize_Section ) {
@@ -3909,6 +3988,8 @@
/**
* Remove a customize section.
*
+ * Note that removing the section doesn't destroy the WP_Customize_Section instance or remove its filters.
+ *
* @since 3.4.0
*
* @param string $id Section ID.
@@ -3950,28 +4031,13 @@
* @since 3.4.0
* @since 4.5.0 Return added WP_Customize_Control instance.
*
+ * @see WP_Customize_Control::__construct()
+ *
* @param WP_Customize_Control|string $id Customize Control object, or ID.
- * @param array $args {
- * Optional. Array of properties for the new Control object. Default empty array.
- *
- * @type array $settings All settings tied to the control. If undefined, defaults to `$setting`.
- * IDs in the array correspond to the ID of a registered `WP_Customize_Setting`.
- * @type string $setting The primary setting for the control (if there is one). Default is 'default'.
- * @type string $capability Capability required to use this control. Normally derived from `$settings`.
- * @type int $priority Order priority to load the control. Default 10.
- * @type string $section The section this control belongs to. Default empty.
- * @type string $label Label for the control. Default empty.
- * @type string $description Description for the control. Default empty.
- * @type array $choices List of choices for 'radio' or 'select' type controls, where values
- * are the keys, and labels are the values. Default empty array.
- * @type array $input_attrs List of custom input attributes for control output, where attribute
- * names are the keys and values are the values. Default empty array.
- * @type bool $allow_addition Show UI for adding new content, currently only used for the
- * dropdown-pages control. Default false.
- * @type string $type The type of the control. Default 'text'.
- * @type callback $active_callback Active callback.
- * }
- * @return WP_Customize_Control The instance of the control that was added.
+ * @param array $args Optional. Array of properties for the new Control object.
+ * See WP_Customize_Control::__construct() for information
+ * on accepted arguments. Default empty array.
+ * @return WP_Customize_Control The instance of the control that was added.
*/
public function add_control( $id, $args = array() ) {
if ( $id instanceof WP_Customize_Control ) {
@@ -4001,6 +4067,8 @@
/**
* Remove a customize control.
*
+ * Note that removing the control doesn't destroy the WP_Customize_Control instance or remove its filters.
+ *
* @since 3.4.0
*
* @param string $id ID of the control.
@@ -4467,10 +4535,10 @@
*/
public function get_document_title_template() {
if ( $this->is_theme_active() ) {
- /* translators: %s: document title from the preview */
+ /* translators: %s: Document title from the preview. */
$document_title_tmpl = __( 'Customize: %s' );
} else {
- /* translators: %s: document title from the preview */
+ /* translators: %s: Document title from the preview. */
$document_title_tmpl = __( 'Live Preview: %s' );
}
$document_title_tmpl = html_entity_decode( $document_title_tmpl, ENT_QUOTES, 'UTF-8' ); // Because exported to JS and assigned to document.title.
@@ -4533,7 +4601,7 @@
*
* @since 4.7.0
*
- * @returns array Allowed URLs.
+ * @return array Allowed URLs.
*/
public function get_allowed_urls() {
$allowed_urls = array( home_url( '/' ) );
@@ -4586,9 +4654,13 @@
*
* @since 4.4.0
*
+ * @global array $_registered_pages
+ *
* @return string URL for link to close Customizer.
*/
public function get_return_url() {
+ global $_registered_pages;
+
$referer = wp_get_referer();
$excluded_referer_basenames = array( 'customize.php', 'wp-login.php' );
@@ -4601,6 +4673,22 @@
} else {
$return_url = home_url( '/' );
}
+
+ $return_url_basename = wp_basename( parse_url( $this->return_url, PHP_URL_PATH ) );
+ $return_url_query = parse_url( $this->return_url, PHP_URL_QUERY );
+
+ if ( 'themes.php' === $return_url_basename && $return_url_query ) {
+ parse_str( $return_url_query, $query_vars );
+
+ /*
+ * If the return URL is a page added by a theme to the Appearance menu via add_submenu_page(),
+ * verify that belongs to the active theme, otherwise fall back to the Themes screen.
+ */
+ if ( isset( $query_vars['page'] ) && ! isset( $_registered_pages[ "appearance_page_{$query_vars['page']}" ] ) ) {
+ $return_url = admin_url( 'themes.php' );
+ }
+ }
+
return $return_url;
}
@@ -4612,9 +4700,9 @@
* @param array $autofocus {
* Mapping of 'panel', 'section', 'control' to the ID which should be autofocused.
*
- * @type string [$control] ID for control to be autofocused.
- * @type string [$section] ID for section to be autofocused.
- * @type string [$panel] ID for panel to be autofocused.
+ * @type string $control ID for control to be autofocused.
+ * @type string $section ID for section to be autofocused.
+ * @type string $panel ID for panel to be autofocused.
* }
*/
public function set_autofocus( $autofocus ) {
@@ -4629,9 +4717,9 @@
* @return array {
* Mapping of 'panel', 'section', 'control' to the ID which should be autofocused.
*
- * @type string [$control] ID for control to be autofocused.
- * @type string [$section] ID for section to be autofocused.
- * @type string [$panel] ID for panel to be autofocused.
+ * @type string $control ID for control to be autofocused.
+ * @type string $section ID for section to be autofocused.
+ * @type string $panel ID for panel to be autofocused.
* }
*/
public function get_autofocus() {
@@ -4809,11 +4897,11 @@
'previewableDevices' => $this->get_previewable_devices(),
'l10n' => array(
'confirmDeleteTheme' => __( 'Are you sure you want to delete this theme?' ),
- /* translators: %d: number of theme search results, which cannot currently consider singular vs. plural forms */
+ /* translators: %d: Number of theme search results, which cannot currently consider singular vs. plural forms. */
'themeSearchResults' => __( '%d themes found' ),
- /* translators: %d: number of themes being displayed, which cannot currently consider singular vs. plural forms */
+ /* translators: %d: Number of themes being displayed, which cannot currently consider singular vs. plural forms. */
'announceThemeCount' => __( 'Displaying %d themes' ),
- /* translators: %s: theme name */
+ /* translators: %s: Theme name. */
'announceThemeDetails' => __( 'Showing details for theme: %s' ),
),
);
@@ -5069,7 +5157,7 @@
'label' => __( 'Site Icon' ),
'description' => sprintf(
'<p>' . __( 'Site Icons are what you see in browser tabs, bookmark bars, and within the WordPress mobile apps. Upload one here!' ) . '</p>' .
- /* translators: %s: site icon size in pixels */
+ /* translators: %s: Site icon size in pixels. */
'<p>' . __( 'Site Icons should be square and at least %s pixels.' ) . '</p>',
'<strong>512 × 512</strong>'
),
@@ -5098,10 +5186,10 @@
'label' => __( 'Logo' ),
'section' => 'title_tagline',
'priority' => 8,
- 'height' => $custom_logo_args[0]['height'],
- 'width' => $custom_logo_args[0]['width'],
- 'flex_height' => $custom_logo_args[0]['flex-height'],
- 'flex_width' => $custom_logo_args[0]['flex-width'],
+ 'height' => isset( $custom_logo_args[0]['height'] ) ? $custom_logo_args[0]['height'] : null,
+ 'width' => isset( $custom_logo_args[0]['width'] ) ? $custom_logo_args[0]['width'] : null,
+ 'flex_height' => isset( $custom_logo_args[0]['flex-height'] ) ? $custom_logo_args[0]['flex-height'] : null,
+ 'flex_width' => isset( $custom_logo_args[0]['flex-width'] ) ? $custom_logo_args[0]['flex-width'] : null,
'button_labels' => array(
'select' => __( 'Select logo' ),
'change' => __( 'Change logo' ),
@@ -5146,8 +5234,8 @@
)
);
- // Input type: checkbox
- // With custom value
+ // Input type: checkbox.
+ // With custom value.
$this->add_control(
'display_header_text',
array(
@@ -5170,8 +5258,8 @@
)
);
- // Input type: Color
- // With sanitize_callback
+ // Input type: color.
+ // With sanitize_callback.
$this->add_setting(
'background_color',
array(
@@ -5204,21 +5292,21 @@
$height = absint( get_theme_support( 'custom-header', 'height' ) );
if ( $width && $height ) {
$control_description = sprintf(
- /* translators: 1: .mp4, 2: header size in pixels */
+ /* translators: 1: .mp4, 2: Header size in pixels. */
__( 'Upload your video in %1$s format and minimize its file size for best results. Your theme recommends dimensions of %2$s pixels.' ),
'<code>.mp4</code>',
sprintf( '<strong>%s × %s</strong>', $width, $height )
);
} elseif ( $width ) {
$control_description = sprintf(
- /* translators: 1: .mp4, 2: header width in pixels */
+ /* translators: 1: .mp4, 2: Header width in pixels. */
__( 'Upload your video in %1$s format and minimize its file size for best results. Your theme recommends a width of %2$s pixels.' ),
'<code>.mp4</code>',
sprintf( '<strong>%s</strong>', $width )
);
} else {
$control_description = sprintf(
- /* translators: 1: .mp4, 2: header height in pixels */
+ /* translators: 1: .mp4, 2: Header height in pixels. */
__( 'Upload your video in %1$s format and minimize its file size for best results. Your theme recommends a height of %2$s pixels.' ),
'<code>.mp4</code>',
sprintf( '<strong>%s</strong>', $height )
@@ -5436,7 +5524,7 @@
'section' => 'background_image',
'type' => 'select',
'choices' => array(
- 'auto' => __( 'Original' ),
+ 'auto' => _x( 'Original', 'Original Size' ),
'contain' => __( 'Fit to Screen' ),
'cover' => __( 'Fill Screen' ),
),
@@ -5568,7 +5656,7 @@
' <a href="%1$s" class="external-link" target="_blank">%2$s<span class="screen-reader-text"> %3$s</span></a>',
esc_url( __( 'https://codex.wordpress.org/CSS' ) ),
__( 'Learn more about CSS' ),
- /* translators: accessibility text */
+ /* translators: Accessibility text. */
__( '(opens in a new tab)' )
);
$section_description .= '</p>';
@@ -5577,19 +5665,19 @@
$section_description .= '<ul>';
$section_description .= '<li id="editor-keyboard-trap-help-2">' . __( 'In the editing area, the Tab key enters a tab character.' ) . '</li>';
$section_description .= '<li id="editor-keyboard-trap-help-3">' . __( 'To move away from this area, press the Esc key followed by the Tab key.' ) . '</li>';
- $section_description .= '<li id="editor-keyboard-trap-help-4">' . __( 'Screen reader users: when in forms mode, you may need to press the escape key twice.' ) . '</li>';
+ $section_description .= '<li id="editor-keyboard-trap-help-4">' . __( 'Screen reader users: when in forms mode, you may need to press the Esc key twice.' ) . '</li>';
$section_description .= '</ul>';
if ( 'false' !== wp_get_current_user()->syntax_highlighting ) {
$section_description .= '<p>';
$section_description .= sprintf(
- /* translators: 1: link to user profile, 2: additional link attributes, 3: accessibility text */
+ /* translators: 1: Link to user profile, 2: Additional link attributes, 3: Accessibility text. */
__( 'The edit field automatically highlights code syntax. You can disable this in your <a href="%1$s" %2$s>user profile%3$s</a> to work in plain text mode.' ),
esc_url( get_edit_profile_url() ),
'class="external-link" target="_blank"',
sprintf(
'<span class="screen-reader-text"> %s</span>',
- /* translators: accessibility text */
+ /* translators: Accessibility text. */
__( '(opens in a new tab)' )
)
);
@@ -5644,7 +5732,7 @@
*
* @since 4.7.0
*
- * @returns bool Whether there are published (or to be published) pages.
+ * @return bool Whether there are published (or to be published) pages.
*/
public function has_published_pages() {
@@ -5799,9 +5887,11 @@
$theme->active = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme->slug );
// Map available theme properties to installed theme properties.
- $theme->id = $theme->slug;
- $theme->screenshot = array( $theme->screenshot_url );
- $theme->authorAndUri = wp_kses( $theme->author['display_name'], $themes_allowedtags );
+ $theme->id = $theme->slug;
+ $theme->screenshot = array( $theme->screenshot_url );
+ $theme->authorAndUri = wp_kses( $theme->author['display_name'], $themes_allowedtags );
+ $theme->compatibleWP = is_wp_version_compatible( $theme->requires ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName
+ $theme->compatiblePHP = is_php_version_compatible( $theme->requires_php ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName
if ( isset( $theme->parent ) ) {
$theme->parent = $theme->parent['slug'];
@@ -5866,17 +5956,17 @@
*
* @since 4.7.0
*
- * @param string $value Repeat value.
+ * @param string $value Repeat value.
* @param WP_Customize_Setting $setting Setting.
* @return string|WP_Error Background value or validation error.
*/
public function _sanitize_background_setting( $value, $setting ) {
if ( 'background_repeat' === $setting->id ) {
- if ( ! in_array( $value, array( 'repeat-x', 'repeat-y', 'repeat', 'no-repeat' ) ) ) {
+ if ( ! in_array( $value, array( 'repeat-x', 'repeat-y', 'repeat', 'no-repeat' ), true ) ) {
return new WP_Error( 'invalid_value', __( 'Invalid value for background repeat.' ) );
}
} elseif ( 'background_attachment' === $setting->id ) {
- if ( ! in_array( $value, array( 'fixed', 'scroll' ) ) ) {
+ if ( ! in_array( $value, array( 'fixed', 'scroll' ), true ) ) {
return new WP_Error( 'invalid_value', __( 'Invalid value for background attachment.' ) );
}
} elseif ( 'background_position_x' === $setting->id ) {
@@ -5908,9 +5998,9 @@
*
* @since 4.7.0
*
- * @param array $response Response.
+ * @param array $response Response.
* @param WP_Customize_Selective_Refresh $selective_refresh Selective refresh component.
- * @param array $partials Array of partials.
+ * @param array $partials Array of partials.
* @return array
*/
public function export_header_video_settings( $response, $selective_refresh, $partials ) {
@@ -5929,14 +6019,14 @@
* @since 4.7.0
*
* @param WP_Error $validity
- * @param mixed $value
+ * @param mixed $value
* @return mixed
*/
public function _validate_header_video( $validity, $value ) {
$video = get_attached_file( absint( $value ) );
if ( $video ) {
$size = filesize( $video );
- if ( 8 < $size / pow( 1024, 2 ) ) { // Check whether the size is larger than 8MB.
+ if ( $size > 8 * MB_IN_BYTES ) {
$validity->add(
'size_too_large',
__( 'This video file is too large to use as a header video. Try a shorter video or optimize the compression settings and re-upload a file that is less than 8MB. Or, upload your video to YouTube and link it with the option below.' )
@@ -5965,7 +6055,7 @@
* @since 4.7.0
*
* @param WP_Error $validity
- * @param mixed $value
+ * @param mixed $value
* @return mixed
*/
public function _validate_external_header_video( $validity, $value ) {