Make WordPress Core


Ignore:
Timestamp:
09/17/2015 07:41:35 PM (9 years ago)
Author:
westonruter
Message:

Customize: Reduce peak memory usage by JSON-encoding settings and controls individually.

When there are hundreds of settings and controls (e.g. nav menu items and widget instances) the resulting object that is JSON-encoded can become very large, and wp_json_encode() can consume a lot of memory to serialize it. By breaking down the serialization into multiple calls the peak memory usage can be kept in line.

Moves logic out of wp-admin/customize.php into the WP_Customize_Manager class with new methods:

  • is_ios()
  • get_document_title_template()
  • get_preview_url()/set_preview_url()
  • get_return_url()/set_return_url()
  • get_autofocus()/set_autofocus()
  • customize_pane_settings()

Includes unit tests for these methods, for which the logic was formerly untestable in customize.php.

Fixes #33898.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/customize/manager.php

    r31622 r34269  
    11<?php
     2/**
     3 * WP_Customize_Manager tests.
     4 *
     5 * @package WordPress
     6 */
    27
    38/**
     
    813class Tests_WP_Customize_Manager extends WP_UnitTestCase {
    914
     15    /**
     16     * Customize manager instance re-instantiated with each test.
     17     *
     18     * @var WP_Customize_Manager
     19     */
     20    public $manager;
     21
     22    /**
     23     * Symbol.
     24     *
     25     * @var stdClass
     26     */
     27    public $undefined;
     28
     29    /**
     30     * Set up test.
     31     */
    1032    function setUp() {
    1133        parent::setUp();
     
    1638    }
    1739
     40    /**
     41     * Tear down test.
     42     */
    1843    function tearDown() {
    1944        $this->manager = null;
     
    157182    /**
    158183     * In lieu of closures, callback for customize_dynamic_setting_args filter added for test_register_dynamic_settings().
     184     *
     185     * @param array  $setting_args Setting args.
     186     * @param string $setting_id   Setting ID.
     187     * @return array
    159188     */
    160189    function filter_customize_dynamic_setting_args_for_test_dynamic_settings( $setting_args, $setting_id ) {
     
    169198    /**
    170199     * In lieu of closures, callback for customize_dynamic_setting_class filter added for test_register_dynamic_settings().
     200     *
     201     * @param string $setting_class Setting class.
     202     * @param string $setting_id    Setting ID.
     203     * @param array  $setting_args  Setting args.
     204     * @return string
    171205     */
    172206    function filter_customize_dynamic_setting_class_for_test_dynamic_settings( $setting_class, $setting_id, $setting_args ) {
     
    176210        return $setting_class;
    177211    }
     212
     213    /**
     214     * Test is_ios() method.
     215     *
     216     * @see WP_Customize_Manager::is_ios()
     217     */
     218    function test_is_ios() {
     219        $this->markTestSkipped( 'WP_Customize_Manager::is_ios() cannot be tested because it uses wp_is_mobile() which contains a static var.' );
     220    }
     221
     222    /**
     223     * Test get_document_title_template() method.
     224     *
     225     * @see WP_Customize_Manager::get_document_title_template()
     226     */
     227    function test_get_document_title_template() {
     228        $tpl = $this->manager->get_document_title_template();
     229        $this->assertContains( '%s', $tpl );
     230    }
     231
     232    /**
     233     * Test get_preview_url()/set_preview_url methods.
     234     *
     235     * @see WP_Customize_Manager::get_preview_url()
     236     * @see WP_Customize_Manager::set_preview_url()
     237     */
     238    function test_preview_url() {
     239        $this->assertEquals( home_url( '/' ), $this->manager->get_preview_url() );
     240        $preview_url = home_url( '/foo/bar/baz/' );
     241        $this->manager->set_preview_url( $preview_url );
     242        $this->assertEquals( $preview_url, $this->manager->get_preview_url() );
     243        $this->manager->set_preview_url( 'http://illegalsite.example.com/food/' );
     244        $this->assertEquals( home_url( '/' ), $this->manager->get_preview_url() );
     245    }
     246
     247    /**
     248     * Test get_return_url()/set_return_url() methods.
     249     *
     250     * @see WP_Customize_Manager::get_return_url()
     251     * @see WP_Customize_Manager::set_return_url()
     252     */
     253    function test_return_url() {
     254        wp_set_current_user( $this->factory->user->create( array( 'role' => 'author' ) ) );
     255        $this->assertEquals( get_admin_url(), $this->manager->get_return_url() );
     256
     257        wp_set_current_user( $this->factory->user->create( array( 'role' => 'administrator' ) ) );
     258        $this->assertTrue( current_user_can( 'edit_theme_options' ) );
     259        $this->assertEquals( admin_url( 'themes.php' ), $this->manager->get_return_url() );
     260
     261        $preview_url = home_url( '/foo/' );
     262        $this->manager->set_preview_url( $preview_url );
     263        $this->assertEquals( $preview_url, $this->manager->get_return_url() );
     264
     265        $this->manager->set_return_url( admin_url( 'edit.php?trashed=1' ) );
     266        $this->assertEquals( admin_url( 'edit.php' ), $this->manager->get_return_url() );
     267    }
     268
     269    /**
     270     * Test get_autofocus()/set_autofocus() methods.
     271     *
     272     * @see WP_Customize_Manager::get_autofocus()
     273     * @see WP_Customize_Manager::set_autofocus()
     274     */
     275    function test_autofocus() {
     276        $this->assertEmpty( $this->manager->get_autofocus() );
     277
     278        $this->manager->set_autofocus( array( 'unrecognized' => 'food' ) );
     279        $this->assertEmpty( $this->manager->get_autofocus() );
     280
     281        $autofocus = array( 'control' => 'blogname' );
     282        $this->manager->set_autofocus( $autofocus );
     283        $this->assertEquals( $autofocus, $this->manager->get_autofocus() );
     284
     285        $autofocus = array( 'section' => 'colors' );
     286        $this->manager->set_autofocus( $autofocus );
     287        $this->assertEquals( $autofocus, $this->manager->get_autofocus() );
     288
     289        $autofocus = array( 'panel' => 'widgets' );
     290        $this->manager->set_autofocus( $autofocus );
     291        $this->assertEquals( $autofocus, $this->manager->get_autofocus() );
     292
     293        $autofocus = array( 'control' => array( 'blogname', 'blogdescription' ) );
     294        $this->manager->set_autofocus( $autofocus );
     295        $this->assertEmpty( $this->manager->get_autofocus() );
     296    }
     297
     298    /**
     299     * Test customize_pane_settings() method.
     300     *
     301     * @see WP_Customize_Manager::customize_pane_settings()
     302     */
     303    function test_customize_pane_settings() {
     304        wp_set_current_user( $this->factory->user->create( array( 'role' => 'administrator' ) ) );
     305        $this->manager->register_controls();
     306        $this->manager->prepare_controls();
     307        $autofocus = array( 'control' => 'blogname' );
     308        $this->manager->set_autofocus( $autofocus );
     309
     310        ob_start();
     311        $this->manager->customize_pane_settings();
     312        $content = ob_get_clean();
     313
     314        $this->assertContains( 'var _wpCustomizeSettings =', $content );
     315        $this->assertContains( '"blogname"', $content );
     316        $this->assertContains( '_wpCustomizeSettings.controls', $content );
     317        $this->assertContains( '_wpCustomizeSettings.settings', $content );
     318        $this->assertContains( '</script>', $content );
     319
     320        $this->assertNotEmpty( preg_match( '#var _wpCustomizeSettings\s*=\s*({.*?});\s*\n#', $content, $matches ) );
     321        $json = $matches[1];
     322        $data = json_decode( $json, true );
     323        $this->assertNotEmpty( $data );
     324
     325        $this->assertEqualSets( array( 'theme', 'url', 'browser', 'panels', 'sections', 'nonce', 'autofocus', 'documentTitleTmpl' ), array_keys( $data ) );
     326        $this->assertEquals( $autofocus, $data['autofocus'] );
     327        $this->assertArrayHasKey( 'save', $data['nonce'] );
     328        $this->assertArrayHasKey( 'preview', $data['nonce'] );
     329    }
    178330}
Note: See TracChangeset for help on using the changeset viewer.