Make WordPress Core

Changeset 39350


Ignore:
Timestamp:
11/23/2016 05:33:21 PM (7 years ago)
Author:
westonruter
Message:

Customize: Refactor logic for updating custom_css posts by introducing wp_update_custom_css_post() function and renaming update filter.

  • Moves logic from WP_Customize_Custom_CSS_Setting::update() into a re-usable wp_update_custom_css_post() function, useful for future REST API endpoint, WP-CLI command, or plugin migrations.
  • Renames customize_update_custom_css_post_content_args filter to update_custom_css_data and improves the naming of the parameters. Instead of passing post_content and post_content_filtered the filtered array now contains css and preprocessed respectively.
  • The second context param for the update_custom_css_data filter is now an array of the original args passed to wp_update_custom_css_post() and there is now no more $setting arg since it isn't necessarily being called in the customizer context.

Props westonruter, georgestephanis.
See #35395.
Fixes #38672.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/customize/class-wp-customize-custom-css-setting.php

    r39345 r39350  
    242242     */
    243243    public function update( $css ) {
    244         $setting = $this;
    245 
    246244        if ( empty( $css ) ) {
    247245            $css = '';
    248246        }
    249247
    250         $args = array(
    251             'post_content' => $css,
    252             'post_content_filtered' => '',
    253         );
    254 
    255         /**
    256          * Filters the `post_content` and `post_content_filtered` args for a `custom_css` post being updated.
    257          *
    258          * This filter can be used by plugin that offer CSS pre-processors, to store the original
    259          * pre-processed CSS in `post_content_filtered` and then store processed CSS in `post_content`.
    260          * When used in this way, the `post_content_filtered` should be supplied as the setting value
    261          * instead of `post_content` via a the `customize_value_custom_css` filter, for example:
    262          *
    263          * <code>
    264          * add_filter( 'customize_value_custom_css', function( $value, $setting ) {
    265          *     $post = wp_get_custom_css_post( $setting->stylesheet );
    266          *     if ( $post && ! empty( $post->post_content_filtered ) ) {
    267          *         $css = $post->post_content_filtered;
    268          *     }
    269          *     return $css;
    270          * }, 10, 2 );
    271          * </code>
    272          *
    273          * @since 4.7.0
    274          * @param array  $args {
    275          *     Content post args (unslashed) for `wp_update_post()`/`wp_insert_post()`.
    276          *
    277          *     @type string $post_content          CSS.
    278          *     @type string $post_content_filtered Pre-processed CSS. Normally empty string.
    279          * }
    280          * @param string                          $css     Original CSS being updated.
    281          * @param WP_Customize_Custom_CSS_Setting $setting Custom CSS Setting.
    282          */
    283         $args = apply_filters( 'customize_update_custom_css_post_content_args', $args, $css, $setting );
    284         $args = wp_array_slice_assoc( $args, array( 'post_content', 'post_content_filtered' ) );
    285 
    286         $args = array_merge(
    287             $args,
    288             array(
    289                 'post_title' => $this->stylesheet,
    290                 'post_name' => sanitize_title( $this->stylesheet ),
    291                 'post_type' => 'custom_css',
    292                 'post_status' => 'publish',
    293             )
    294         );
    295 
    296         // Update post if it already exists, otherwise create a new one.
    297         $post = wp_get_custom_css_post( $this->stylesheet );
    298         if ( $post ) {
    299             $args['ID'] = $post->ID;
    300             $post_id = wp_update_post( wp_slash( $args ) );
    301         } else {
    302             $post_id = wp_insert_post( wp_slash( $args ) );
    303         }
    304         if ( ! $post_id ) {
     248        $r = wp_update_custom_css_post( $css, array(
     249            'stylesheet' => $this->stylesheet,
     250        ) );
     251
     252        if ( $r instanceof WP_Error ) {
    305253            return false;
    306254        }
     255        $post_id = $r->ID;
    307256
    308257        // Cache post ID in theme mod for performance to avoid additional DB query.
  • trunk/src/wp-includes/theme.php

    r39346 r39350  
    17061706
    17071707    return $css;
     1708}
     1709
     1710/**
     1711 * Update the `custom_css` post for a given theme.
     1712 *
     1713 * Inserts a `custom_css` post when one doesn't yet exist.
     1714 *
     1715 * @since 4.7.0
     1716 * @access public
     1717 *
     1718 * @param string $css CSS, stored in `post_content`.
     1719 * @param array  $args {
     1720 *     Args.
     1721 *
     1722 *     @type string $preprocessed Pre-processed CSS, stored in `post_content_filtered`. Normally empty string. Optional.
     1723 *     @type string $stylesheet   Stylesheet (child theme) to update. Optional, defaults to current theme/stylesheet.
     1724 * }
     1725 * @return WP_Post|WP_Error Post on success, error on failure.
     1726 */
     1727function wp_update_custom_css_post( $css, $args = array() ) {
     1728    $args = wp_parse_args( $args, array(
     1729        'preprocessed' => '',
     1730        'stylesheet' => get_stylesheet(),
     1731    ) );
     1732
     1733    $data = array(
     1734        'css' => $css,
     1735        'preprocessed' => $args['preprocessed'],
     1736    );
     1737
     1738    /**
     1739     * Filters the `css` (`post_content`) and `preprocessed` (`post_content_filtered`) args for a `custom_css` post being updated.
     1740     *
     1741     * This filter can be used by plugin that offer CSS pre-processors, to store the original
     1742     * pre-processed CSS in `post_content_filtered` and then store processed CSS in `post_content`.
     1743     * When used in this way, the `post_content_filtered` should be supplied as the setting value
     1744     * instead of `post_content` via a the `customize_value_custom_css` filter, for example:
     1745     *
     1746     * <code>
     1747     * add_filter( 'customize_value_custom_css', function( $value, $setting ) {
     1748     *     $post = wp_get_custom_css_post( $setting->stylesheet );
     1749     *     if ( $post && ! empty( $post->post_content_filtered ) ) {
     1750     *         $css = $post->post_content_filtered;
     1751     *     }
     1752     *     return $css;
     1753     * }, 10, 2 );
     1754     * </code>
     1755     *
     1756     * @since 4.7.0
     1757     * @param array $data {
     1758     *     Custom CSS data.
     1759     *
     1760     *     @type string $css          CSS stored in `post_content`.
     1761     *     @type string $preprocessed Pre-processed CSS stored in `post_content_filtered`. Normally empty string.
     1762     * }
     1763     * @param array $args {
     1764     *     The args passed into `wp_update_custom_css_post()` merged with defaults.
     1765     *
     1766     *     @type string $css          The original CSS passed in to be updated.
     1767     *     @type string $preprocessed The original preprocessed CSS passed in to be updated.
     1768     *     @type string $stylesheet   The stylesheet (theme) being updated.
     1769     * }
     1770     */
     1771    $data = apply_filters( 'update_custom_css_data', $data, array_merge( $args, compact( 'css' ) ) );
     1772
     1773    $post_data = array(
     1774        'post_title' => $args['stylesheet'],
     1775        'post_name' => sanitize_title( $args['stylesheet'] ),
     1776        'post_type' => 'custom_css',
     1777        'post_status' => 'publish',
     1778        'post_content' => $data['css'],
     1779        'post_content_filtered' => $data['preprocessed'],
     1780    );
     1781
     1782    // Update post if it already exists, otherwise create a new one.
     1783    $post = wp_get_custom_css_post( $args['stylesheet'] );
     1784    if ( $post ) {
     1785        $post_data['ID'] = $post->ID;
     1786        $r = wp_update_post( wp_slash( $post_data ), true );
     1787    } else {
     1788        $r = wp_insert_post( wp_slash( $post_data ), true );
     1789    }
     1790
     1791    if ( $r instanceof WP_Error ) {
     1792        return $r;
     1793    }
     1794    return get_post( $r );
    17081795}
    17091796
  • trunk/tests/phpunit/tests/customize/custom-css-setting.php

    r39209 r39350  
    152152        $this->assertEquals( $updated_css, $this->setting->value() );
    153153        $this->assertEquals( $updated_css, wp_get_custom_css( $this->setting->stylesheet ) );
     154        $this->assertEquals( $updated_css, get_post( $post_id )->post_content );
    154155
    155156        $previewed_css = 'body { color: red; }';
     
    159160        $this->assertEquals( $previewed_css, wp_get_custom_css( $this->setting->stylesheet ) );
    160161
     162        // Make sure that wp_update_custom_css_post() works as expected for updates.
     163        $r = wp_update_custom_css_post( 'body { color:red; }', array(
     164            'stylesheet' => $this->setting->stylesheet,
     165            'preprocessed' => "body\n\tcolor:red;",
     166        ) );
     167        $this->assertInstanceOf( 'WP_Post', $r );
     168        $this->assertEquals( $post_id, $r->ID );
     169        $this->assertEquals( 'body { color:red; }', get_post( $r )->post_content );
     170        $this->assertEquals( "body\n\tcolor:red;", get_post( $r )->post_content_filtered );
     171        $r = wp_update_custom_css_post( 'body { content: "\o/"; }' );
     172        $this->assertEquals( $this->wp_customize->get_stylesheet(), get_post( $r )->post_name );
     173        $this->assertEquals( 'body { content: "\o/"; }', get_post( $r )->post_content );
     174        $this->assertEquals( '', get_post( $r )->post_content_filtered );
     175
     176        // Make sure that wp_update_custom_css_post() works as expected for insertion.
     177        $r = wp_update_custom_css_post( 'body { background:black; }', array(
     178            'stylesheet' => 'other',
     179        ) );
     180        $this->assertInstanceOf( 'WP_Post', $r );
     181        $this->assertEquals( 'other', get_post( $r )->post_name );
     182        $this->assertEquals( 'body { background:black; }', get_post( $r )->post_content );
     183        $this->assertEquals( 'publish', get_post( $r )->post_status );
     184
     185        // Test deletion.
    161186        wp_delete_post( $post_id );
    162187        $this->assertNull( wp_get_custom_css_post() );
     
    226251        $original_title = $post->post_title;
    227252
    228         add_filter( 'customize_update_custom_css_post_content_args', array( $this, 'filter_update_post_content_args' ), 10, 3 );
     253        add_filter( 'update_custom_css_data', array( $this, 'filter_update_custom_css_data' ), 10, 3 );
    229254        $this->setting->save();
    230255
     
    239264     * Filter `customize_update_custom_css_post_content_args`.
    240265     *
    241      * @param array                $args    Post array.
    242      * @param string               $css     CSS.
    243      * @param WP_Customize_Setting $setting Setting.
    244      * @return array Args.
    245      */
    246     function filter_update_post_content_args( $args, $css, $setting ) {
     266     * @param array  $data Data.
     267     * @param string $args Args.
     268     * @return array Data.
     269     */
     270    function filter_update_custom_css_data( $data, $args ) {
     271        $this->assertInternalType( 'array', $data );
     272        $this->assertEqualSets( array( 'css', 'preprocessed' ), array_keys( $data ) );
     273        $this->assertEquals( '', $data['preprocessed'] );
    247274        $this->assertInternalType( 'array', $args );
    248         $this->assertEqualSets( array( 'post_content', 'post_content_filtered' ), array_keys( $args ) );
    249         $this->assertEquals( $css, $args['post_content'] );
    250         $this->assertEquals( '', $args['post_content_filtered'] );
    251         $this->assertInstanceOf( 'WP_Customize_Custom_CSS_Setting', $setting );
    252 
    253         $args['post_content'] .= '/* filtered post_content */';
    254         $args['post_content_filtered'] = '/* filtered post_content_filtered */';
    255         $args['post_title'] = 'Ignored';
    256         return $args;
     275        $this->assertEqualSets( array( 'css', 'preprocessed', 'stylesheet' ), array_keys( $args ) );
     276        $this->assertEquals( $args['css'], $data['css'] );
     277        $this->assertEquals( $args['preprocessed'], $data['preprocessed'] );
     278
     279        $data['css'] .= '/* filtered post_content */';
     280        $data['preprocessed'] = '/* filtered post_content_filtered */';
     281        $data['post_title'] = 'Ignored';
     282        return $data;
    257283    }
    258284
Note: See TracChangeset for help on using the changeset viewer.