--- a/wp/wp-includes/class-wp-customize-manager.php Thu Sep 29 08:06:27 2022 +0200
+++ b/wp/wp-includes/class-wp-customize-manager.php Fri Sep 05 18:40:08 2025 +0200
@@ -20,6 +20,7 @@
*
* @since 3.4.0
*/
+#[AllowDynamicProperties]
final class WP_Customize_Manager {
/**
* An instance of the theme being previewed.
@@ -99,7 +100,7 @@
* @since 4.5.0
* @var array
*/
- protected $components = array( 'widgets', 'nav_menus' );
+ protected $components = array( 'nav_menus' );
/**
* Registered instances of WP_Customize_Section.
@@ -270,8 +271,10 @@
$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'] );
@@ -283,6 +286,11 @@
$args['messenger_channel'] = sanitize_key( wp_unslash( $_REQUEST['customize_messenger_channel'] ) );
}
+ // Do not load 'widgets' component if a block theme is activated.
+ if ( ! wp_is_block_theme() ) {
+ $this->components[] = 'widgets';
+ }
+
$this->original_stylesheet = get_stylesheet();
$this->theme = wp_get_theme( 0 === validate_file( $args['theme'] ) ? $args['theme'] : null );
$this->messenger_channel = $args['messenger_channel'];
@@ -461,6 +469,8 @@
),
'error' => $ajax_message,
);
+ $message .= ob_get_clean();
+ ob_start();
?>
<script>
( function( api, settings ) {
@@ -469,7 +479,7 @@
} )( wp.customize, <?php echo wp_json_encode( $settings ); ?> );
</script>
<?php
- $message .= ob_get_clean();
+ $message .= wp_get_inline_script_tag( wp_remove_surrounding_empty_script_tags( ob_get_clean() ) );
}
wp_die( $message );
@@ -564,8 +574,10 @@
// 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.' ) );
}
@@ -904,8 +916,10 @@
*/
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' );
@@ -1070,7 +1084,7 @@
continue;
}
if ( update_post_meta( $autosave_autodraft_post->ID, '_customize_restore_dismissed', true ) ) {
- $dismissed++;
+ ++$dismissed;
}
}
return $dismissed;
@@ -1472,7 +1486,7 @@
if ( ! $nav_menu_term_id ) {
while ( isset( $changeset_data[ sprintf( 'nav_menu[%d]', $placeholder_id ) ] ) ) {
- $placeholder_id--;
+ --$placeholder_id;
}
$nav_menu_term_id = $placeholder_id;
$nav_menu_setting_id = sprintf( 'nav_menu[%d]', $placeholder_id );
@@ -1902,6 +1916,7 @@
if ( ! headers_sent() ) {
nocache_headers();
header( 'X-Robots: noindex, nofollow, noarchive' );
+ header( 'X-Robots-Tag: noindex, nofollow, noarchive' );
}
add_filter( 'wp_robots', 'wp_robots_no_robots' );
add_filter( 'wp_headers', array( $this, 'filter_iframe_security_headers' ) );
@@ -1980,7 +1995,7 @@
&&
$parsed_allowed_url['host'] === $parsed_original_url['host']
&&
- 0 === strpos( $parsed_original_url['path'], $parsed_allowed_url['path'] )
+ str_starts_with( $parsed_original_url['path'], $parsed_allowed_url['path'] )
);
if ( $is_allowed ) {
break;
@@ -2075,29 +2090,22 @@
if ( ! $this->messenger_channel ) {
return;
}
+ ob_start();
?>
<script>
( function() {
- var urlParser, oldQueryParams, newQueryParams, i;
if ( parent !== window ) {
return;
}
- urlParser = document.createElement( 'a' );
- urlParser.href = location.href;
- oldQueryParams = urlParser.search.substr( 1 ).split( /&/ );
- newQueryParams = [];
- for ( i = 0; i < oldQueryParams.length; i += 1 ) {
- if ( ! /^customize_messenger_channel=/.test( oldQueryParams[ i ] ) ) {
- newQueryParams.push( oldQueryParams[ i ] );
- }
- }
- urlParser.search = newQueryParams.join( '&' );
- if ( urlParser.search !== location.search ) {
- location.replace( urlParser.href );
+ const url = new URL( location.href );
+ if ( url.searchParams.has( 'customize_messenger_channel' ) ) {
+ url.searchParams.delete( 'customize_messenger_channel' );
+ location.replace( url );
}
} )();
</script>
<?php
+ wp_print_inline_script_tag( wp_remove_surrounding_empty_script_tags( ob_get_clean() ) );
}
/**
@@ -2111,7 +2119,7 @@
$exported_setting_validities = array_map( array( $this, 'prepare_setting_validity_for_js' ), $setting_validities );
// Note that the REQUEST_URI is not passed into home_url() since this breaks subdirectory installations.
- $self_url = empty( $_SERVER['REQUEST_URI'] ) ? home_url( '/' ) : esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) );
+ $self_url = empty( $_SERVER['REQUEST_URI'] ) ? home_url( '/' ) : sanitize_url( wp_unslash( $_SERVER['REQUEST_URI'] ) );
$state_query_params = array(
'customize_theme',
'customize_changeset_uuid',
@@ -2133,7 +2141,7 @@
$allowed_hosts[] = $host;
}
- $switched_locale = switch_to_locale( get_user_locale() );
+ $switched_locale = switch_to_user_locale( get_current_user_id() );
$l10n = array(
'shiftClickToEdit' => __( 'Shift-click to edit this element.' ),
'linkUnpreviewable' => __( 'This link is not live-previewable.' ),
@@ -2158,7 +2166,7 @@
),
'url' => array(
'self' => $self_url,
- 'allowed' => array_map( 'esc_url_raw', $this->get_allowed_urls() ),
+ 'allowed' => array_map( 'sanitize_url', $this->get_allowed_urls() ),
'allowedHosts' => array_unique( $allowed_hosts ),
'isCrossDomain' => $this->is_cross_domain(),
),
@@ -2193,8 +2201,9 @@
}
}
+ ob_start();
?>
- <script type="text/javascript">
+ <script>
var _wpCustomizeSettings = <?php echo wp_json_encode( $settings ); ?>;
_wpCustomizeSettings.values = {};
(function( v ) {
@@ -2217,6 +2226,7 @@
})( _wpCustomizeSettings.values );
</script>
<?php
+ wp_print_inline_script_tag( wp_remove_surrounding_empty_script_tags( ob_get_clean() ) );
}
/**
@@ -3074,25 +3084,26 @@
return false;
}
+ $previous_status = $post->post_status;
+
/** This filter is documented in wp-includes/post.php */
- $check = apply_filters( 'pre_trash_post', null, $post );
+ $check = apply_filters( 'pre_trash_post', null, $post, $previous_status );
if ( null !== $check ) {
return $check;
}
/** This action is documented in wp-includes/post.php */
- do_action( 'wp_trash_post', $post_id );
-
- add_post_meta( $post_id, '_wp_trash_meta_status', $post->post_status );
+ do_action( 'wp_trash_post', $post_id, $previous_status );
+
+ add_post_meta( $post_id, '_wp_trash_meta_status', $previous_status );
add_post_meta( $post_id, '_wp_trash_meta_time', time() );
- $old_status = $post->post_status;
$new_status = 'trash';
$wpdb->update( $wpdb->posts, array( 'post_status' => $new_status ), array( 'ID' => $post->ID ) );
clean_post_cache( $post->ID );
$post->post_status = $new_status;
- wp_transition_post_status( $new_status, $old_status, $post );
+ wp_transition_post_status( $new_status, $previous_status, $post );
/** This action is documented in wp-includes/post.php */
do_action( "edit_post_{$post->post_type}", $post->ID, $post );
@@ -3114,7 +3125,7 @@
wp_trash_post_comments( $post_id );
/** This action is documented in wp-includes/post.php */
- do_action( 'trashed_post', $post_id );
+ do_action( 'trashed_post', $post_id, $previous_status );
return $post;
}
@@ -3427,12 +3438,12 @@
* @since 4.7.0
*
* @param bool $post_has_changed Whether the post has changed.
- * @param WP_Post $last_revision The last revision post object.
+ * @param WP_Post $latest_revision The latest 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 ) {
- unset( $last_revision );
+ public function _filter_revision_post_has_changed( $post_has_changed, $latest_revision, $post ) {
+ unset( $latest_revision );
if ( 'customize_changeset' === $post->post_type ) {
$post_has_changed = $this->store_changeset_revision;
}
@@ -3609,7 +3620,7 @@
*/
$revisions = wp_get_post_revisions( $changeset_post_id, array( 'check_enabled' => false ) );
foreach ( $revisions as $revision ) {
- if ( false !== strpos( $revision->post_name, "{$changeset_post_id}-autosave" ) ) {
+ if ( str_contains( $revision->post_name, "{$changeset_post_id}-autosave" ) ) {
$wpdb->update(
$wpdb->posts,
array(
@@ -4284,7 +4295,12 @@
<li class="notice notice-{{ data.type || 'info' }} {{ data.alt ? 'notice-alt' : '' }} {{ data.dismissible ? 'is-dismissible' : '' }} {{ data.containerClasses || '' }}" data-code="{{ data.code }}" data-type="{{ data.type }}">
<div class="notification-message">{{{ data.message || data.code }}}</div>
<# if ( data.dismissible ) { #>
- <button type="button" class="notice-dismiss"><span class="screen-reader-text"><?php _e( 'Dismiss' ); ?></span></button>
+ <button type="button" class="notice-dismiss"><span class="screen-reader-text">
+ <?php
+ /* translators: Hidden accessibility text. */
+ _e( 'Dismiss' );
+ ?>
+ </span></button>
<# } #>
</li>
</script>
@@ -4351,10 +4367,20 @@
<p class="description customize-control-description"><?php esc_html_e( 'See how changes would look live on your website, and share the preview with people who can\'t access the Customizer.' ); ?></p>
<div class="customize-control-notifications-container"></div>
<div class="preview-link-wrapper">
- <label for="{{ elementPrefix }}customize-preview-link-input" class="screen-reader-text"><?php esc_html_e( 'Preview Link' ); ?></label>
+ <label for="{{ elementPrefix }}customize-preview-link-input" class="screen-reader-text">
+ <?php
+ /* translators: Hidden accessibility text. */
+ esc_html_e( 'Preview Link' );
+ ?>
+ </label>
<a href="" target="">
<span class="preview-control-element" data-component="url"></span>
- <span class="screen-reader-text"><?php _e( '(opens in a new tab)' ); ?></span>
+ <span class="screen-reader-text">
+ <?php
+ /* translators: Hidden accessibility text. */
+ _e( '(opens in a new tab)' );
+ ?>
+ </span>
</a>
<input id="{{ elementPrefix }}customize-preview-link-input" readonly tabindex="-1" class="preview-control-element" data-component="input">
<button class="customize-copy-preview-link preview-control-element button button-secondary" data-component="button" data-copy-text="<?php esc_attr_e( 'Copy' ); ?>" data-copied-text="<?php esc_attr_e( 'Copied' ); ?>" ><?php esc_html_e( 'Copy' ); ?></button>
@@ -4574,7 +4600,7 @@
* @param string $preview_url URL to be previewed.
*/
public function set_preview_url( $preview_url ) {
- $preview_url = esc_url_raw( $preview_url );
+ $preview_url = sanitize_url( $preview_url );
$this->preview_url = wp_validate_redirect( $preview_url, home_url( '/' ) );
}
@@ -4662,7 +4688,7 @@
* @param string $return_url URL for return link.
*/
public function set_return_url( $return_url ) {
- $return_url = esc_url_raw( $return_url );
+ $return_url = sanitize_url( $return_url );
$return_url = remove_query_arg( wp_removable_query_args(), $return_url );
$return_url = wp_validate_redirect( $return_url );
$this->return_url = $return_url;
@@ -4685,6 +4711,21 @@
if ( $this->return_url ) {
$return_url = $this->return_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 it 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' );
+ }
+ }
} elseif ( $referer && ! in_array( wp_basename( parse_url( $referer, PHP_URL_PATH ) ), $excluded_referer_basenames, true ) ) {
$return_url = $referer;
} elseif ( $this->preview_url ) {
@@ -4693,21 +4734,6 @@
$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 it 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;
}
@@ -4894,15 +4920,15 @@
'_canInstall' => current_user_can( 'install_themes' ),
),
'url' => array(
- 'preview' => esc_url_raw( $this->get_preview_url() ),
- 'return' => esc_url_raw( $this->get_return_url() ),
- 'parent' => esc_url_raw( admin_url() ),
- 'activated' => esc_url_raw( home_url( '/' ) ),
- 'ajax' => esc_url_raw( admin_url( 'admin-ajax.php', 'relative' ) ),
- 'allowed' => array_map( 'esc_url_raw', $this->get_allowed_urls() ),
+ 'preview' => sanitize_url( $this->get_preview_url() ),
+ 'return' => sanitize_url( $this->get_return_url() ),
+ 'parent' => sanitize_url( admin_url() ),
+ 'activated' => sanitize_url( home_url( '/' ) ),
+ 'ajax' => sanitize_url( admin_url( 'admin-ajax.php', 'relative' ) ),
+ 'allowed' => array_map( 'sanitize_url', $this->get_allowed_urls() ),
'isCrossDomain' => $this->is_cross_domain(),
- 'home' => esc_url_raw( home_url( '/' ) ),
- 'login' => esc_url_raw( $login_url ),
+ 'home' => sanitize_url( home_url( '/' ) ),
+ 'login' => sanitize_url( $login_url ),
),
'browser' => array(
'mobile' => wp_is_mobile(),
@@ -4953,8 +4979,9 @@
}
}
+ ob_start();
?>
- <script type="text/javascript">
+ <script>
var _wpCustomizeSettings = <?php echo wp_json_encode( $settings ); ?>;
_wpCustomizeSettings.initialClientTimestamp = _.now();
_wpCustomizeSettings.controls = {};
@@ -4989,6 +5016,7 @@
?>
</script>
<?php
+ wp_print_inline_script_tag( wp_remove_surrounding_empty_script_tags( ob_get_clean() ) );
}
/**
@@ -5175,10 +5203,9 @@
array(
'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. */
- '<p>' . __( 'Site Icons should be square and at least %s pixels.' ) . '</p>',
- '<strong>512 × 512</strong>'
+ /* translators: %s: Site Icon size in pixels. */
+ '<p>' . __( 'The Site Icon is what you see in browser tabs, bookmark bars, and within the WordPress mobile apps. It should be square and at least %s pixels.' ) . '</p>',
+ '<code>512 × 512</code>'
),
'section' => 'title_tagline',
'priority' => 60,
@@ -5253,8 +5280,7 @@
)
);
- // Input type: checkbox.
- // With custom value.
+ // Input type: checkbox, with custom value.
$this->add_control(
'display_header_text',
array(
@@ -5277,8 +5303,7 @@
)
);
- // Input type: color.
- // With sanitize_callback.
+ // Input type: color, with sanitize_callback.
$this->add_setting(
'background_color',
array(
@@ -5586,8 +5611,10 @@
)
);
- // If the theme is using the default background callback, we can update
- // the background CSS using postMessage.
+ /*
+ * If the theme is using the default background callback, we can update
+ * the background CSS using postMessage.
+ */
if ( get_theme_support( 'custom-background', 'wp-head-callback' ) === '_custom_background_cb' ) {
foreach ( array( 'color', 'image', 'preset', 'position_x', 'position_y', 'size', 'repeat', 'attachment' ) as $prop ) {
$this->get_setting( 'background_' . $prop )->transport = 'postMessage';
@@ -5673,9 +5700,9 @@
$section_description .= __( 'Add your own CSS code here to customize the appearance and layout of your site.' );
$section_description .= sprintf(
' <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' ) ),
+ esc_url( __( 'https://developer.wordpress.org/advanced-administration/wordpress/css/' ) ),
__( 'Learn more about CSS' ),
- /* translators: Accessibility text. */
+ /* translators: Hidden accessibility text. */
__( '(opens in a new tab)' )
);
$section_description .= '</p>';
@@ -5696,7 +5723,7 @@
'class="external-link" target="_blank"',
sprintf(
'<span class="screen-reader-text"> %s</span>',
- /* translators: Accessibility text. */
+ /* translators: Hidden accessibility text. */
__( '(opens in a new tab)' )
)
);
@@ -5763,7 +5790,15 @@
}
}
}
- return 0 !== count( get_pages( array( 'number' => 1 ) ) );
+
+ return 0 !== count(
+ get_pages(
+ array(
+ 'number' => 1,
+ 'hierarchical' => 0,
+ )
+ )
+ );
}
/**
@@ -6006,7 +6041,7 @@
return new WP_Error( 'invalid_value', __( 'Invalid value for background size.' ) );
}
} elseif ( 'background_image' === $setting->id || 'background_image_thumb' === $setting->id ) {
- $value = empty( $value ) ? '' : esc_url_raw( $value );
+ $value = empty( $value ) ? '' : sanitize_url( $value );
} else {
return new WP_Error( 'unrecognized_setting', __( 'Unrecognized background setting.' ) );
}
@@ -6052,7 +6087,7 @@
__( '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.' )
);
}
- if ( '.mp4' !== substr( $video, -4 ) && '.mov' !== substr( $video, -4 ) ) { // Check for .mp4 or .mov format, which (assuming h.264 encoding) are the only cross-browser-supported formats.
+ if ( ! str_ends_with( $video, '.mp4' ) && ! str_ends_with( $video, '.mov' ) ) { // Check for .mp4 or .mov format, which (assuming h.264 encoding) are the only cross-browser-supported formats.
$validity->add(
'invalid_file_type',
sprintf(
@@ -6079,7 +6114,7 @@
* @return mixed
*/
public function _validate_external_header_video( $validity, $value ) {
- $video = esc_url_raw( $value );
+ $video = sanitize_url( $value );
if ( $video ) {
if ( ! preg_match( '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#', $video ) ) {
$validity->add( 'invalid_url', __( 'Please enter a valid YouTube URL.' ) );
@@ -6097,7 +6132,7 @@
* @return string Sanitized URL.
*/
public function _sanitize_external_header_video( $value ) {
- return esc_url_raw( trim( $value ) );
+ return sanitize_url( trim( $value ) );
}
/**