WordPress.org

Make WordPress Core


Ignore:
Timestamp:
10/18/2016 08:04:36 PM (5 years ago)
Author:
westonruter
Message:

Customize: Implement customized state persistence with changesets.

Includes infrastructure developed in the Customize Snapshots feature plugin.

See https://make.wordpress.org/core/2016/10/12/customize-changesets-technical-design-decisions/

Props westonruter, valendesigns, utkarshpatel, stubgo, lgedeon, ocean90, ryankienstra, mihai2u, dlh, aaroncampbell, jonathanbardo, jorbin.
See #28721.
See #31089.
Fixes #30937.
Fixes #31517.
Fixes #30028.
Fixes #23225.
Fixes #34142.
Fixes #36485.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/theme.php

    r38649 r38810  
    20672067 *
    20682068 * Loads the Customizer at plugins_loaded when accessing the customize.php admin
    2069  * page or when any request includes a wp_customize=on param, either as a GET
    2070  * query var or as POST data. This param is a signal for whether to bootstrap
    2071  * the Customizer when WordPress is loading, especially in the Customizer preview
     2069 * page or when any request includes a wp_customize=on param or a customize_changeset
     2070 * param (a UUID). This param is a signal for whether to bootstrap the Customizer when
     2071 * WordPress is loading, especially in the Customizer preview
    20722072 * or when making Customizer Ajax requests for widgets or menus.
    20732073 *
     
    20772077 */
    20782078function _wp_customize_include() {
    2079     if ( ! ( ( isset( $_REQUEST['wp_customize'] ) && 'on' == $_REQUEST['wp_customize'] )
    2080         || ( is_admin() && 'customize.php' == basename( $_SERVER['PHP_SELF'] ) )
    2081     ) ) {
     2079
     2080    $is_customize_admin_page = ( is_admin() && 'customize.php' == basename( $_SERVER['PHP_SELF'] ) );
     2081    $should_include = (
     2082        $is_customize_admin_page
     2083        ||
     2084        ( isset( $_REQUEST['wp_customize'] ) && 'on' == $_REQUEST['wp_customize'] )
     2085        ||
     2086        ( ! empty( $_GET['customize_changeset_uuid'] ) || ! empty( $_POST['customize_changeset_uuid'] ) )
     2087    );
     2088
     2089    if ( ! $should_include ) {
    20822090        return;
    20832091    }
    20842092
    2085     require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
    2086     $GLOBALS['wp_customize'] = new WP_Customize_Manager();
     2093    /*
     2094     * Note that wp_unslash() is not being used on the input vars because it is
     2095     * called before wp_magic_quotes() gets called. Besides this fact, none of
     2096     * the values should contain any characters needing slashes anyway.
     2097     */
     2098    $keys = array( 'changeset_uuid', 'customize_changeset_uuid', 'customize_theme', 'theme', 'customize_messenger_channel' );
     2099    $input_vars = array_merge(
     2100        wp_array_slice_assoc( $_GET, $keys ),
     2101        wp_array_slice_assoc( $_POST, $keys )
     2102    );
     2103
     2104    $theme = null;
     2105    $changeset_uuid = null;
     2106    $messenger_channel = null;
     2107
     2108    if ( $is_customize_admin_page && isset( $input_vars['changeset_uuid'] ) ) {
     2109        $changeset_uuid = sanitize_key( $input_vars['changeset_uuid'] );
     2110    } elseif ( ! empty( $input_vars['customize_changeset_uuid'] ) ) {
     2111        $changeset_uuid = sanitize_key( $input_vars['customize_changeset_uuid'] );
     2112    }
     2113
     2114    // Note that theme will be sanitized via WP_Theme.
     2115    if ( $is_customize_admin_page && isset( $input_vars['theme'] ) ) {
     2116        $theme = $input_vars['theme'];
     2117    } elseif ( isset( $input_vars['customize_theme'] ) ) {
     2118        $theme = $input_vars['customize_theme'];
     2119    }
     2120    if ( isset( $input_vars['customize_messenger_channel'] ) ) {
     2121        $messenger_channel = sanitize_key( $input_vars['customize_messenger_channel'] );
     2122    }
     2123
     2124    require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
     2125    $GLOBALS['wp_customize'] = new WP_Customize_Manager( compact( 'changeset_uuid', 'theme', 'messenger_channel' ) );
     2126}
     2127
     2128/**
     2129 * Publish a snapshot's changes.
     2130 *
     2131 * @param string  $new_status     New post status.
     2132 * @param string  $old_status     Old post status.
     2133 * @param WP_Post $changeset_post Changeset post object.
     2134 */
     2135function _wp_customize_publish_changeset( $new_status, $old_status, $changeset_post ) {
     2136    global $wp_customize;
     2137
     2138    $is_publishing_changeset = (
     2139        'customize_changeset' === $changeset_post->post_type
     2140        &&
     2141        'publish' === $new_status
     2142        &&
     2143        'publish' !== $old_status
     2144    );
     2145    if ( ! $is_publishing_changeset ) {
     2146        return;
     2147    }
     2148
     2149    if ( empty( $wp_customize ) ) {
     2150        require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
     2151        $wp_customize = new WP_Customize_Manager( $changeset_post->post_name );
     2152    }
     2153
     2154    if ( ! did_action( 'customize_register' ) ) {
     2155        /*
     2156         * When running from CLI or Cron, the customize_register action will need
     2157         * to be triggered in order for core, themes, and plugins to register their
     2158         * settings. Normally core will add_action( 'customize_register' ) at
     2159         * priority 10 to register the core settings, and if any themes/plugins
     2160         * also add_action( 'customize_register' ) at the same priority, they
     2161         * will have a $wp_customize with those settings registered since they
     2162         * call add_action() afterward, normally. However, when manually doing
     2163         * the customize_register action after the setup_theme, then the order
     2164         * will be reversed for two actions added at priority 10, resulting in
     2165         * the core settings no longer being available as expected to themes/plugins.
     2166         * So the following manually calls the method that registers the core
     2167         * settings up front before doing the action.
     2168         */
     2169        remove_action( 'customize_register', array( $wp_customize, 'register_controls' ) );
     2170        $wp_customize->register_controls();
     2171
     2172        /** This filter is documented in /wp-includes/class-wp-customize-manager.php */
     2173        do_action( 'customize_register', $wp_customize );
     2174    }
     2175    $wp_customize->_publish_changeset_values( $changeset_post->ID ) ;
     2176
     2177    /*
     2178     * Trash the changeset post if revisions are not enabled. Unpublished
     2179     * changesets by default get garbage collected due to the auto-draft status.
     2180     * When a changeset post is published, however, it would no longer get cleaned
     2181     * out. Ths is a problem when the changeset posts are never displayed anywhere,
     2182     * since they would just be endlessly piling up. So here we use the revisions
     2183     * feature to indicate whether or not a published changeset should get trashed
     2184     * and thus garbage collected.
     2185     */
     2186    if ( ! wp_revisions_enabled( $changeset_post ) ) {
     2187        wp_trash_post( $changeset_post->ID );
     2188    }
     2189}
     2190
     2191/**
     2192 * Filters changeset post data upon insert to ensure post_name is intact.
     2193 *
     2194 * This is needed to prevent the post_name from being dropped when the post is
     2195 * transitioned into pending status by a contributor.
     2196 *
     2197 * @since 4.7.0
     2198 * @see wp_insert_post()
     2199 *
     2200 * @param array $post_data          An array of slashed post data.
     2201 * @param array $supplied_post_data An array of sanitized, but otherwise unmodified post data.
     2202 * @returns array Filtered data.
     2203 */
     2204function _wp_customize_changeset_filter_insert_post_data( $post_data, $supplied_post_data ) {
     2205    if ( isset( $post_data['post_type'] ) && 'customize_changeset' === $post_data['post_type'] ) {
     2206
     2207        // Prevent post_name from being dropped, such as when contributor saves a changeset post as pending.
     2208        if ( empty( $post_data['post_name'] ) && ! empty( $supplied_post_data['post_name'] ) ) {
     2209            $post_data['post_name'] = $supplied_post_data['post_name'];
     2210        }
     2211    }
     2212    return $post_data;
    20872213}
    20882214
Note: See TracChangeset for help on using the changeset viewer.