From 7996c82427d4a68f6c0a321d4faefdff0a82ddcb Mon Sep 17 00:00:00 2001 From: Andrew Nacin Date: Wed, 6 Jun 2012 20:34:24 +0000 Subject: [PATCH] Theme Customizer: Block non-existent or non-allowed themes, unless the non-allowed theme is the active theme. Support a user having edit_theme_options xor switch_themes. fixes #20852. git-svn-id: https://develop.svn.wordpress.org/trunk@21010 602fd350-edb4-49c9-b593-d223f7449a82 --- wp-admin/admin-header.php | 2 +- wp-admin/customize.php | 7 +-- .../includes/class-wp-themes-list-table.php | 18 +++++--- wp-admin/includes/theme.php | 12 ++--- wp-admin/themes.php | 46 +++++++++++++------ wp-includes/class-wp-customize-manager.php | 36 +++++++-------- wp-includes/js/customize-loader.dev.js | 3 -- 7 files changed, 67 insertions(+), 57 deletions(-) diff --git a/wp-admin/admin-header.php b/wp-admin/admin-header.php index c7a0066a3f..248897c987 100644 --- a/wp-admin/admin-header.php +++ b/wp-admin/admin-header.php @@ -102,7 +102,7 @@ $admin_body_class .= ' no-customize-support'; diff --git a/wp-admin/customize.php b/wp-admin/customize.php index 8a13b36322..41ffdb4d3e 100644 --- a/wp-admin/customize.php +++ b/wp-admin/customize.php @@ -13,11 +13,6 @@ if ( ! current_user_can( 'edit_theme_options' ) ) global $wp_scripts, $wp_customize; -wp_reset_vars( array( 'theme' ) ); - -if ( ! $theme ) - $theme = get_stylesheet(); - $registered = $wp_scripts->registered; $wp_scripts = new WP_Scripts; $wp_scripts->registered = $registered; @@ -48,7 +43,7 @@ do_action( 'customize_controls_print_scripts' );
- + get_stylesheet() ); ?>
is_theme_active() ? __( 'Save & Publish' ) : __( 'Save & Activate' ); diff --git a/wp-admin/includes/class-wp-themes-list-table.php b/wp-admin/includes/class-wp-themes-list-table.php index d6164f24a5..003d1ab03d 100644 --- a/wp-admin/includes/class-wp-themes-list-table.php +++ b/wp-admin/includes/class-wp-themes-list-table.php @@ -125,21 +125,25 @@ class WP_Themes_List_Table extends WP_List_Table { $version = $theme->display('Version'); $author = $theme->display('Author'); - $activate_link = wp_nonce_url( "themes.php?action=activate&template=" . urlencode( $template ) . "&stylesheet=" . urlencode( $stylesheet ), 'switch-theme_' . $template ); + $activate_link = wp_nonce_url( "themes.php?action=activate&template=" . urlencode( $template ) . "&stylesheet=" . urlencode( $stylesheet ), 'switch-theme_' . $stylesheet ); $preview_link = esc_url( add_query_arg( array( 'preview' => 1, 'template' => $template, 'stylesheet' => $stylesheet, 'preview_iframe' => true, 'TB_iframe' => 'true' ), home_url( '/' ) ) ); $actions = array(); - $actions[] = '' . __( 'Activate' ) . ''; - $actions[] = '' . __( 'Preview' ) . '' - . '' - . __( 'Live Preview' ) . ''; + + $actions['preview'] = '' . __( 'Preview' ) . ''; + + if ( current_user_can( 'edit_theme_options' ) ) + $actions['preview'] .= '' + . __( 'Live Preview' ) . ''; + if ( ! is_multisite() && current_user_can( 'delete_themes' ) ) - $actions['delete'] = '' . __( 'Delete' ) . ''; diff --git a/wp-admin/includes/theme.php b/wp-admin/includes/theme.php index 6e5767e52d..af1960e478 100644 --- a/wp-admin/includes/theme.php +++ b/wp-admin/includes/theme.php @@ -11,19 +11,19 @@ * * @since 2.8.0 * - * @param string $template Template directory of the theme to delete + * @param string $stylesheet Stylesheet of the theme to delete * @param string $redirect Redirect to page when complete. * @return mixed */ -function delete_theme($template, $redirect = '') { +function delete_theme($stylesheet, $redirect = '') { global $wp_filesystem; - if ( empty($template) ) + if ( empty($stylesheet) ) return false; ob_start(); if ( empty( $redirect ) ) - $redirect = wp_nonce_url('themes.php?action=delete&template=' . $template, 'delete-theme_' . $template); + $redirect = wp_nonce_url('themes.php?action=delete&stylesheet=' . $stylesheet, 'delete-theme_' . $stylesheet); if ( false === ($credentials = request_filesystem_credentials($redirect)) ) { $data = ob_get_contents(); ob_end_clean(); @@ -61,11 +61,11 @@ function delete_theme($template, $redirect = '') { return new WP_Error('fs_no_themes_dir', __('Unable to locate WordPress theme directory.')); $themes_dir = trailingslashit( $themes_dir ); - $theme_dir = trailingslashit($themes_dir . $template); + $theme_dir = trailingslashit($themes_dir . $stylesheet); $deleted = $wp_filesystem->delete($theme_dir, true); if ( ! $deleted ) - return new WP_Error('could_not_remove_theme', sprintf(__('Could not fully remove the theme %s.'), $template) ); + return new WP_Error('could_not_remove_theme', sprintf(__('Could not fully remove the theme %s.'), $stylesheet) ); // Force refresh of theme update information delete_site_transient('update_themes'); diff --git a/wp-admin/themes.php b/wp-admin/themes.php index 42e9e60366..6353235d61 100644 --- a/wp-admin/themes.php +++ b/wp-admin/themes.php @@ -16,15 +16,19 @@ $wp_list_table = _get_list_table('WP_Themes_List_Table'); if ( current_user_can( 'switch_themes' ) && isset($_GET['action'] ) ) { if ( 'activate' == $_GET['action'] ) { - check_admin_referer('switch-theme_' . $_GET['template']); + check_admin_referer('switch-theme_' . $_GET['stylesheet']); + $theme = wp_get_theme( $_GET['stylesheet'] ); + if ( ! $theme->exists() || ! $theme->is_allowed() ) + wp_die( __( 'Cheatin’ uh?' ) ); switch_theme($_GET['template'], $_GET['stylesheet']); wp_redirect( admin_url('themes.php?activated=true') ); exit; } elseif ( 'delete' == $_GET['action'] ) { - check_admin_referer('delete-theme_' . $_GET['template']); - if ( !current_user_can('delete_themes') ) + check_admin_referer('delete-theme_' . $_GET['stylesheet']); + $theme = wp_get_theme( $_GET['stylesheet'] ); + if ( !current_user_can('delete_themes') || ! $theme->exists() ) wp_die( __( 'Cheatin’ uh?' ) ); - delete_theme($_GET['template']); + delete_theme($_GET['stylesheet']); wp_redirect( admin_url('themes.php?deleted=true') ); exit; } @@ -60,6 +64,8 @@ if ( current_user_can( 'install_themes' ) ) { ) ); } +endif; // switch_themes + if ( current_user_can( 'edit_theme_options' ) ) { $help_customize = '

' . __('Click on the "Live Preview" link under any theme to preview that theme and change theme options in a separate, full-screen view. Any installed theme can be previewed and customized in this way.') . '

'. @@ -83,8 +89,6 @@ get_current_screen()->set_help_sidebar( wp_enqueue_script( 'theme' ); wp_enqueue_script( 'customize-loader' ); -endif; - require_once('./admin-header.php'); ?> @@ -120,9 +124,11 @@ $customize_title = sprintf( __( 'Customize “%s”' ), $ct->display('Na ?>
+ <?php esc_attr_e( 'Current theme preview' ); ?> + <?php esc_attr_e( 'Current theme preview' ); ?> @@ -140,9 +146,6 @@ $customize_title = sprintf( __( 'Customize “%s”' ), $ct->display('Na
-
- - display('Na } } + if ( $options || current_user_can( 'edit_theme_options' ) ) : + ?> +
+ + + + +
    + +
  • + +
+
+ -
    - -
  • - -
-
diff --git a/wp-includes/class-wp-customize-manager.php b/wp-includes/class-wp-customize-manager.php index a3bd2b8c49..0e1ab13a51 100644 --- a/wp-includes/class-wp-customize-manager.php +++ b/wp-includes/class-wp-customize-manager.php @@ -78,11 +78,22 @@ final class WP_Customize_Manager { * @since 3.4.0 */ public function setup_theme() { - if ( ! ( isset( $_REQUEST['customize'] ) && 'on' == $_REQUEST['customize'] ) && ! basename( $_SERVER['PHP_SELF'] ) == 'customize.php' ) - return; - send_origin_headers(); + $this->original_stylesheet = get_stylesheet(); + + $this->theme = wp_get_theme( isset( $_REQUEST['theme'] ) ? $_REQUEST['theme'] : null ); + + // You can't preview a theme if it doesn't exist, or if it is not allowed (unless active). + if ( ! $this->theme->exists() ) + wp_die( __( 'Cheatin’ uh?' ) ); + + if ( $this->theme->get_stylesheet() != get_stylesheet() && ( ! $this->theme()->is_allowed() || ! current_user_can( 'switch_themes' ) ) ) + wp_die( __( 'Cheatin’ uh?' ) ); + + if ( ! current_user_can( 'edit_theme_options' ) ) + wp_die( __( 'Cheatin’ uh?' ) ); + $this->start_previewing_theme(); show_admin_bar( false ); } @@ -95,20 +106,10 @@ final class WP_Customize_Manager { * @since 3.4.0 */ public function start_previewing_theme() { - if ( $this->is_preview() || false === $this->theme || ( $this->theme && ! $this->theme->exists() ) ) + // Bail if we're already previewing. + if ( $this->is_preview() ) return; - // Initialize $theme and $original_stylesheet if they do not yet exist. - if ( ! isset( $this->theme ) ) { - $this->theme = wp_get_theme( isset( $_REQUEST['theme'] ) ? $_REQUEST['theme'] : null ); - if ( ! $this->theme->exists() ) { - $this->theme = false; - return; - } - } - - $this->original_stylesheet = get_stylesheet(); - $this->previewing = true; add_filter( 'template', array( $this, 'get_template' ) ); @@ -419,13 +420,10 @@ final class WP_Customize_Manager { if ( ! $this->is_preview() ) die; - check_ajax_referer( 'customize_controls', 'nonce' ); + check_ajax_referer( 'customize_controls-' . $this->get_stylesheet(), 'nonce' ); // Do we have to switch themes? if ( $this->get_stylesheet() != $this->original_stylesheet ) { - if ( ! current_user_can( 'switch_themes' ) ) - die; - // Temporarily stop previewing the theme to allow switch_themes() // to operate properly. $this->stop_previewing_theme(); diff --git a/wp-includes/js/customize-loader.dev.js b/wp-includes/js/customize-loader.dev.js index 66863c6c69..1a1764e655 100644 --- a/wp-includes/js/customize-loader.dev.js +++ b/wp-includes/js/customize-loader.dev.js @@ -17,12 +17,9 @@ if ( typeof wp === 'undefined' ) // Ensure the loader is supported. // Check for settings, postMessage support, and whether we require CORS support. if ( ! Loader.settings || ! $.support.postMessage || ( ! $.support.cors && Loader.settings.isCrossDomain ) ) { - this.body.removeClass( 'customize-support' ).addClass( 'no-customize-support' ); return; } - this.body.removeClass( 'no-customize-support' ).addClass( 'customize-support' ); - this.window = $( window ); this.element = $( '
' ).appendTo( this.body );