wp/wp-includes/theme-previews.php
changeset 21 48c4eec2b7e6
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
       
     1 <?php
       
     2 /**
       
     3  * Theme previews using the Site Editor for block themes.
       
     4  *
       
     5  * @package WordPress
       
     6  */
       
     7 
       
     8 /**
       
     9  * Filters the blog option to return the path for the previewed theme.
       
    10  *
       
    11  * @since 6.3.0
       
    12  *
       
    13  * @param string $current_stylesheet The current theme's stylesheet or template path.
       
    14  * @return string The previewed theme's stylesheet or template path.
       
    15  */
       
    16 function wp_get_theme_preview_path( $current_stylesheet = null ) {
       
    17 	if ( ! current_user_can( 'switch_themes' ) ) {
       
    18 		return $current_stylesheet;
       
    19 	}
       
    20 
       
    21 	$preview_stylesheet = ! empty( $_GET['wp_theme_preview'] ) ? sanitize_text_field( wp_unslash( $_GET['wp_theme_preview'] ) ) : null;
       
    22 	$wp_theme           = wp_get_theme( $preview_stylesheet );
       
    23 	if ( ! is_wp_error( $wp_theme->errors() ) ) {
       
    24 		if ( current_filter() === 'template' ) {
       
    25 			$theme_path = $wp_theme->get_template();
       
    26 		} else {
       
    27 			$theme_path = $wp_theme->get_stylesheet();
       
    28 		}
       
    29 
       
    30 		return sanitize_text_field( $theme_path );
       
    31 	}
       
    32 
       
    33 	return $current_stylesheet;
       
    34 }
       
    35 
       
    36 /**
       
    37  * Adds a middleware to `apiFetch` to set the theme for the preview.
       
    38  * This adds a `wp_theme_preview` URL parameter to API requests from the Site Editor, so they also respond as if the theme is set to the value of the parameter.
       
    39  *
       
    40  * @since 6.3.0
       
    41  */
       
    42 function wp_attach_theme_preview_middleware() {
       
    43 	// Don't allow non-admins to preview themes.
       
    44 	if ( ! current_user_can( 'switch_themes' ) ) {
       
    45 		return;
       
    46 	}
       
    47 
       
    48 	wp_add_inline_script(
       
    49 		'wp-api-fetch',
       
    50 		sprintf(
       
    51 			'wp.apiFetch.use( wp.apiFetch.createThemePreviewMiddleware( %s ) );',
       
    52 			wp_json_encode( sanitize_text_field( wp_unslash( $_GET['wp_theme_preview'] ) ) )
       
    53 		),
       
    54 		'after'
       
    55 	);
       
    56 }
       
    57 
       
    58 /**
       
    59  * Set a JavaScript constant for theme activation.
       
    60  *
       
    61  * Sets the JavaScript global WP_BLOCK_THEME_ACTIVATE_NONCE containing the nonce
       
    62  * required to activate a theme. For use within the site editor.
       
    63  *
       
    64  * @see https://github.com/WordPress/gutenberg/pull/41836
       
    65  *
       
    66  * @since 6.3.0
       
    67  * @access private
       
    68  */
       
    69 function wp_block_theme_activate_nonce() {
       
    70 	$nonce_handle = 'switch-theme_' . wp_get_theme_preview_path();
       
    71 	?>
       
    72 	<script type="text/javascript">
       
    73 		window.WP_BLOCK_THEME_ACTIVATE_NONCE = <?php echo wp_json_encode( wp_create_nonce( $nonce_handle ) ); ?>;
       
    74 	</script>
       
    75 	<?php
       
    76 }
       
    77 
       
    78 /**
       
    79  * Add filters and actions to enable Block Theme Previews in the Site Editor.
       
    80  *
       
    81  * The filters and actions should be added after `pluggable.php` is included as they may
       
    82  * trigger code that uses `current_user_can()` which requires functionality from `pluggable.php`.
       
    83  *
       
    84  * @since 6.3.2
       
    85  */
       
    86 function wp_initialize_theme_preview_hooks() {
       
    87 	if ( ! empty( $_GET['wp_theme_preview'] ) ) {
       
    88 		add_filter( 'stylesheet', 'wp_get_theme_preview_path' );
       
    89 		add_filter( 'template', 'wp_get_theme_preview_path' );
       
    90 		add_action( 'init', 'wp_attach_theme_preview_middleware' );
       
    91 		add_action( 'admin_head', 'wp_block_theme_activate_nonce' );
       
    92 	}
       
    93 }