Make WordPress Core

Changeset 46548


Ignore:
Timestamp:
10/15/2019 04:41:51 PM (5 years ago)
Author:
SergeyBiryukov
Message:

Customize: Ensure that WP_Customize_Manager::import_theme_starter_content() properly handles starter content with (nested) arrays as values.

Previously, searching for symbol references to replace with post or attachment IDs in array values resulted in a PHP warning.

Props timph, JarretC, SergeyBiryukov.
Fixes #45484.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r46225 r46548  
    15181518        // Options.
    15191519        foreach ( $options as $name => $value ) {
    1520             if ( preg_match( '/^{{(?P<symbol>.+)}}$/', $value, $matches ) ) {
     1520
     1521            // Serialize the value to check for post symbols.
     1522            $value = maybe_serialize( $value );
     1523
     1524            if ( is_serialized( $value ) ) {
     1525                if ( preg_match( '/s:\d+:"{{(?P<symbol>.+)}}"/', $value, $matches ) ) {
     1526                    if ( isset( $posts[ $matches['symbol'] ] ) ) {
     1527                        $symbol_match = $posts[ $matches['symbol'] ]['ID'];
     1528                    } elseif ( isset( $attachment_ids[ $matches['symbol'] ] ) ) {
     1529                        $symbol_match = $attachment_ids[ $matches['symbol'] ];
     1530                    }
     1531
     1532                    // If we have any symbol matches, update the values.
     1533                    if ( isset( $symbol_match ) ) {
     1534                        // Replace found string matches with post IDs.
     1535                        $value = str_replace( $matches[0], "i:{$symbol_match}", $value );
     1536                    } else {
     1537                        continue;
     1538                    }
     1539                }
     1540            } elseif ( preg_match( '/^{{(?P<symbol>.+)}}$/', $value, $matches ) ) {
    15211541                if ( isset( $posts[ $matches['symbol'] ] ) ) {
    15221542                    $value = $posts[ $matches['symbol'] ]['ID'];
     
    15281548            }
    15291549
     1550            // Unserialize values after checking for post symbols, so they can be properly referenced.
     1551            $value = maybe_unserialize( $value );
     1552
    15301553            if ( empty( $changeset_data[ $name ] ) || ! empty( $changeset_data[ $name ]['starter_content'] ) ) {
    15311554                $this->set_post_value( $name, $value );
     
    15361559        // Theme mods.
    15371560        foreach ( $theme_mods as $name => $value ) {
    1538             if ( preg_match( '/^{{(?P<symbol>.+)}}$/', $value, $matches ) ) {
     1561
     1562            // Serialize the value to check for post symbols.
     1563            $value = maybe_serialize( $value );
     1564
     1565            // Check if value was serialized.
     1566            if ( is_serialized( $value ) ) {
     1567                if ( preg_match( '/s:\d+:"{{(?P<symbol>.+)}}"/', $value, $matches ) ) {
     1568                    if ( isset( $posts[ $matches['symbol'] ] ) ) {
     1569                        $symbol_match = $posts[ $matches['symbol'] ]['ID'];
     1570                    } elseif ( isset( $attachment_ids[ $matches['symbol'] ] ) ) {
     1571                        $symbol_match = $attachment_ids[ $matches['symbol'] ];
     1572                    }
     1573
     1574                    // If we have any symbol matches, update the values.
     1575                    if ( isset( $symbol_match ) ) {
     1576                        // Replace found string matches with post IDs.
     1577                        $value = str_replace( $matches[0], "i:{$symbol_match}", $value );
     1578                    } else {
     1579                        continue;
     1580                    }
     1581                }
     1582            } elseif ( preg_match( '/^{{(?P<symbol>.+)}}$/', $value, $matches ) ) {
    15391583                if ( isset( $posts[ $matches['symbol'] ] ) ) {
    15401584                    $value = $posts[ $matches['symbol'] ]['ID'];
     
    15451589                }
    15461590            }
     1591
     1592            // Unserialize values after checking for post symbols, so they can be properly referenced.
     1593            $value = maybe_unserialize( $value );
    15471594
    15481595            // Handle header image as special case since setting has a legacy format.
  • trunk/tests/phpunit/tests/customize/manager.php

    r46283 r46548  
    742742        $wp_customize->import_theme_starter_content();
    743743        $changeset_data = $wp_customize->changeset_data();
    744         $this->assertEqualSets( array_values( $posts_by_name ), $changeset_data['nav_menus_created_posts']['value'] ); // Auto-drafts should not get re-created and amended with each import.
     744        // Auto-drafts should not get re-created and amended with each import.
     745        $this->assertEqualSets( array_values( $posts_by_name ), $changeset_data['nav_menus_created_posts']['value'] );
    745746
    746747        // Test that saving non-starter content on top of the changeset clears the starter_content flag.
     
    756757        $this->assertArrayHasKey( 'starter_content', $changeset_data['blogdescription'] );
    757758
    758         // Test that adding blogname starter content is ignored now that it is modified, but updating a non-modified starter content blog description passes.
     759        /*
     760         * Test that adding blogname starter content is ignored now that it is modified,
     761         * but updating a non-modified starter content blog description passes.
     762         */
    759763        $previous_blogname        = $changeset_data['blogname']['value'];
    760764        $previous_blogdescription = $changeset_data['blogdescription']['value'];
     
    802806
    803807    /**
     808     * Test WP_Customize_Manager::import_theme_starter_content() with nested arrays.
     809     *
     810     * @ticket 45484
     811     * @covers WP_Customize_Manager::import_theme_starter_content()
     812     */
     813    function test_import_theme_starter_content_with_nested_arrays() {
     814        wp_set_current_user( self::$admin_user_id );
     815
     816        $existing_published_home_page_id = $this->factory()->post->create(
     817            array(
     818                'post_name'   => 'home',
     819                'post_type'   => 'page',
     820                'post_status' => 'publish',
     821            )
     822        );
     823
     824        global $wp_customize;
     825        $wp_customize           = new WP_Customize_Manager();
     826        $starter_content_config = array(
     827            'posts'      => array(
     828                'home',
     829            ),
     830            'options'    => array(
     831                'array_option'        => array(
     832                    0,
     833                    1,
     834                    'home_page_id' => '{{home}}',
     835                ),
     836                'nested_array_option' => array(
     837                    0,
     838                    1,
     839                    array(
     840                        2,
     841                        'home_page_id' => '{{home}}',
     842                    ),
     843                ),
     844            ),
     845            'theme_mods' => array(
     846                'array_theme_mod'        => array(
     847                    0,
     848                    1,
     849                    'home_page_id' => '{{home}}',
     850                ),
     851                'nested_array_theme_mod' => array(
     852                    0,
     853                    1,
     854                    array(
     855                        2,
     856                        'home_page_id' => '{{home}}',
     857                    ),
     858                ),
     859            ),
     860        );
     861
     862        add_theme_support( 'starter-content', $starter_content_config );
     863        $this->assertEmpty( $wp_customize->unsanitized_post_values() );
     864        $wp_customize->import_theme_starter_content();
     865        $changeset_values     = $wp_customize->unsanitized_post_values();
     866        $expected_setting_ids = array(
     867            'array_option',
     868            'array_theme_mod',
     869            'nav_menus_created_posts',
     870            'nested_array_option',
     871            'nested_array_theme_mod',
     872        );
     873        $this->assertEqualSets( $expected_setting_ids, array_keys( $changeset_values ) );
     874
     875        $this->assertSame( $existing_published_home_page_id, $changeset_values['array_option']['home_page_id'] );
     876        $this->assertSame( $existing_published_home_page_id, $changeset_values['nested_array_option'][2]['home_page_id'] );
     877        $this->assertSame( $existing_published_home_page_id, $changeset_values['array_theme_mod']['home_page_id'] );
     878        $this->assertSame( $existing_published_home_page_id, $changeset_values['nested_array_theme_mod'][2]['home_page_id'] );
     879    }
     880
     881    /**
    804882     * Test WP_Customize_Manager::customize_preview_init().
    805883     *
Note: See TracChangeset for help on using the changeset viewer.