public static function do_migration()
 {
     Jetpack_Options::update_option('custom_css_4.7_migration', true);
     Jetpack::log('custom_css_4.7_migration', 'start');
     if (!post_type_exists('safecss')) {
         self::register_legacy_post_type();
     }
     /** This filter is documented in modules/custom-css/custom-css.php */
     $preprocessors = apply_filters('jetpack_custom_css_preprocessors', array());
     $core_css_post = wp_get_custom_css_post();
     $jetpack_css_post = self::get_post();
     $revisions = self::get_all_revisions();
     // Migrate the settings from revision meta to theme mod.
     $options = self::get_options($jetpack_css_post->ID);
     set_theme_mod('jetpack_custom_css', $options);
     if (empty($revisions) || !is_array($revisions)) {
         if ($jetpack_css_post instanceof WP_Post) {
             // Feed in the raw, if the current setting is Sass/LESS, it'll filter it inside.
             wp_update_custom_css_post($jetpack_css_post->post_content);
             return 1;
         }
         return null;
     }
     $revisions = array_reverse($revisions);
     $themes = Jetpack_Custom_CSS_Enhancements::get_themes();
     $migrated = array();
     foreach ($revisions as $post_id => $post) {
         // Jetpack had stored the theme Name, not the stylesheet directory, for ... reasons.
         // Get the stylesheet.  If null, the theme is no longer available.  Skip.
         $stylesheet = isset($themes[$post->post_excerpt]) ? $themes[$post->post_excerpt] : null;
         if (empty($stylesheet)) {
             continue;
         }
         $migrated[] = $post->ID;
         $preprocessor = get_post_meta($post->ID, 'custom_css_preprocessor', true);
         $css = $post->post_content;
         $pre = '';
         // Do a revision by revision parsing.
         if ($preprocessor && isset($preprocessors[$preprocessor])) {
             $pre = $css;
             $css = call_user_func($preprocessors[$preprocessor]['callback'], $pre);
         }
         // Do we need to remove any filters here for users without `unfiltered_html` ?
         wp_update_custom_css_post($css, array('stylesheet' => $stylesheet, 'preprocessed' => $pre));
     }
     // If we've migrated some CSS for the current theme and there was already something there in the Core dataset ...
     if ($core_css_post && $jetpack_css_post) {
         $preprocessor = $options['preprocessor'];
         $css = $core_css_post->post_content;
         $pre = $core_css_post->post_content_filtered;
         if ($preprocessor) {
             if ($pre) {
                 $pre .= "\r\n\r\n/*\r\n\t" . esc_js(__('CSS Migrated from Jetpack:', 'jetpack')) . "\r\n*/\r\n\r\n";
             }
             $pre .= $jetpack_css_post->post_content;
             $css .= "\r\n\r\n/*\r\n\t" . esc_js(__('CSS Migrated from Jetpack:', 'jetpack')) . "\r\n*/\r\n\r\n";
             $css .= call_user_func($preprocessors[$preprocessor]['callback'], $jetpack_css_post->post_content);
         } else {
             $css .= "\r\n\r\n/*\r\n\t" . esc_js(__('CSS Migrated from Jetpack:', 'jetpack')) . "\r\n*/\r\n\r\n";
             $css .= $jetpack_css_post->post_content;
         }
         wp_update_custom_css_post($css, array('preprocessed' => $pre));
     }
     Jetpack::log('custom_css_4.7_migration', sizeof($migrated) . 'revisions migrated');
     return sizeof($migrated);
 }
 /**
  * Store the CSS setting value in the custom_css custom post type for the stylesheet.
  *
  * @since 4.7.0
  * @access public
  *
  * @param string $css The input value.
  * @return int|false The post ID or false if the value could not be saved.
  */
 public function update($css)
 {
     $setting = $this;
     if (empty($css)) {
         $css = '';
     }
     $args = array('post_content' => $css, 'post_content_filtered' => '');
     /**
      * Filters the `post_content` and `post_content_filtered` args for a `custom_css` post being updated.
      *
      * This filter can be used by plugin that offer CSS pre-processors, to store the original
      * pre-processed CSS in `post_content_filtered` and then store processed CSS in `post_content`.
      * When used in this way, the `post_content_filtered` should be supplied as the setting value
      * instead of `post_content` via a the `customize_value_custom_css` filter, for example:
      *
      * <code>
      * add_filter( 'customize_value_custom_css', function( $value, $setting ) {
      *     $post = wp_get_custom_css_post( $setting->stylesheet );
      *     if ( $post && ! empty( $post->post_content_filtered ) ) {
      *         $css = $post->post_content_filtered;
      *     }
      *     return $css;
      * }, 10, 2 );
      * </code>
      *
      * @since 4.7.0
      * @param array  $args {
      *     Content post args (unslashed) for `wp_update_post()`/`wp_insert_post()`.
      *
      *     @type string $post_content          CSS.
      *     @type string $post_content_filtered Pre-processed CSS. Normally empty string.
      * }
      * @param string                          $css     Original CSS being updated.
      * @param WP_Customize_Custom_CSS_Setting $setting Custom CSS Setting.
      */
     $args = apply_filters('customize_update_custom_css_post_content_args', $args, $css, $setting);
     $args = wp_array_slice_assoc($args, array('post_content', 'post_content_filtered'));
     $args = array_merge($args, array('post_title' => $this->stylesheet, 'post_name' => sanitize_title($this->stylesheet), 'post_type' => 'custom_css', 'post_status' => 'publish'));
     // Update post if it already exists, otherwise create a new one.
     $post = wp_get_custom_css_post($this->stylesheet);
     if ($post) {
         $args['ID'] = $post->ID;
         $post_id = wp_update_post(wp_slash($args));
     } else {
         $post_id = wp_insert_post(wp_slash($args));
     }
     if (!$post_id) {
         return false;
     }
     // Cache post ID in theme mod for performance to avoid additional DB query.
     if ($this->manager->get_stylesheet() === $this->stylesheet) {
         set_theme_mod('custom_css_post_id', $post_id);
     }
     return $post_id;
 }
Пример #3
0
 /**
  * Test crud methods on WP_Customize_Custom_CSS_Setting.
  *
  * @covers wp_get_custom_css()
  * @covers WP_Customize_Custom_CSS_Setting::value()
  * @covers WP_Customize_Custom_CSS_Setting::preview()
  * @covers WP_Customize_Custom_CSS_Setting::update()
  */
 function test_crud()
 {
     $this->setting->default = '/* Hello World */';
     $this->assertEquals($this->setting->default, $this->setting->value());
     $this->assertNull(wp_get_custom_css_post());
     $this->assertNull(wp_get_custom_css_post($this->setting->stylesheet));
     $this->assertNull(wp_get_custom_css_post('twentyten'));
     $original_css = 'body { color: black; }';
     $post_id = $this->factory()->post->create(array('post_title' => $this->setting->stylesheet, 'post_name' => $this->setting->stylesheet, 'post_content' => $original_css, 'post_status' => 'publish', 'post_type' => 'custom_css'));
     $twentyten_css = 'body { color: red; }';
     $twentyten_post_id = $this->factory()->post->create(array('post_title' => 'twentyten', 'post_name' => 'twentyten', 'post_content' => $twentyten_css, 'post_status' => 'publish', 'post_type' => 'custom_css'));
     $twentyten_setting = new WP_Customize_Custom_CSS_Setting($this->wp_customize, 'custom_css[twentyten]');
     $this->assertEquals($post_id, wp_get_custom_css_post()->ID);
     $this->assertEquals($post_id, wp_get_custom_css_post($this->setting->stylesheet)->ID);
     $this->assertEquals($twentyten_post_id, wp_get_custom_css_post('twentyten')->ID);
     $this->assertEquals($original_css, wp_get_custom_css($this->setting->stylesheet));
     $this->assertEquals($original_css, $this->setting->value());
     $this->assertEquals($twentyten_css, wp_get_custom_css('twentyten'));
     $this->assertEquals($twentyten_css, $twentyten_setting->value());
     $updated_css = 'body { color: blue; }';
     $this->wp_customize->set_post_value($this->setting->id, $updated_css);
     $saved = $this->setting->save();
     $this->assertTrue(false !== $saved);
     $this->assertEquals($updated_css, $this->setting->value());
     $this->assertEquals($updated_css, wp_get_custom_css($this->setting->stylesheet));
     $this->assertEquals($updated_css, get_post($post_id)->post_content);
     $previewed_css = 'body { color: red; }';
     $this->wp_customize->set_post_value($this->setting->id, $previewed_css);
     $this->setting->preview();
     $this->assertEquals($previewed_css, $this->setting->value());
     $this->assertEquals($previewed_css, wp_get_custom_css($this->setting->stylesheet));
     // Make sure that wp_update_custom_css_post() works as expected for updates.
     $r = wp_update_custom_css_post('body { color:red; }', array('stylesheet' => $this->setting->stylesheet, 'preprocessed' => "body\n\tcolor:red;"));
     $this->assertInstanceOf('WP_Post', $r);
     $this->assertEquals($post_id, $r->ID);
     $this->assertEquals('body { color:red; }', get_post($r)->post_content);
     $this->assertEquals("body\n\tcolor:red;", get_post($r)->post_content_filtered);
     $r = wp_update_custom_css_post('body { content: "\\o/"; }');
     $this->assertEquals($this->wp_customize->get_stylesheet(), get_post($r)->post_name);
     $this->assertEquals('body { content: "\\o/"; }', get_post($r)->post_content);
     $this->assertEquals('', get_post($r)->post_content_filtered);
     // Make sure that wp_update_custom_css_post() works as expected for insertion.
     $r = wp_update_custom_css_post('body { background:black; }', array('stylesheet' => 'other'));
     $this->assertInstanceOf('WP_Post', $r);
     $this->assertEquals('other', get_post($r)->post_name);
     $this->assertEquals('body { background:black; }', get_post($r)->post_content);
     $this->assertEquals('publish', get_post($r)->post_status);
     // Test deletion.
     wp_delete_post($post_id);
     $this->assertNull(wp_get_custom_css_post());
     $this->assertNull(wp_get_custom_css_post(get_stylesheet()));
     $this->assertEquals($previewed_css, wp_get_custom_css(get_stylesheet()), 'Previewed value remains in spite of deleted post.');
     wp_delete_post($twentyten_post_id);
     $this->assertNull(wp_get_custom_css_post('twentyten'));
     $this->assertEquals('', wp_get_custom_css('twentyten'));
 }
 /**
  * Fetch the value of the setting. Will return the previewed value when `preview()` is called.
  *
  * @since 4.7.0
  * @access public
  * @see WP_Customize_Setting::value()
  *
  * @return string
  */
 public function value()
 {
     if ($this->is_previewed) {
         $post_value = $this->post_value(null);
         if (null !== $post_value) {
             return $post_value;
         }
     }
     $id_base = $this->id_data['base'];
     $value = '';
     $post = wp_get_custom_css_post($this->stylesheet);
     if ($post) {
         $value = $post->post_content;
     }
     if (empty($value)) {
         $value = $this->default;
     }
     /** This filter is documented in wp-includes/class-wp-customize-setting.php */
     $value = apply_filters("customize_value_{$id_base}", $value, $this);
     return $value;
 }
/**
 * Fetch the saved Custom CSS content for rendering.
 *
 * @since 4.7.0
 * @access public
 *
 * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the current theme.
 * @return string The Custom CSS Post content.
 */
function wp_get_custom_css($stylesheet = '')
{
    $css = '';
    if (empty($stylesheet)) {
        $stylesheet = get_stylesheet();
    }
    $post = wp_get_custom_css_post($stylesheet);
    if ($post) {
        $css = $post->post_content;
    }
    /**
     * Modify the Custom CSS Output into the <head>.
     *
     * @since 4.7.0
     *
     * @param string $css        CSS pulled in from the Custom CSS CPT.
     * @param string $stylesheet The theme stylesheet name.
     */
    $css = apply_filters('wp_get_custom_css', $css, $stylesheet);
    return $css;
}
Пример #6
0
/**
 * Update the `custom_css` post for a given theme.
 *
 * Inserts a `custom_css` post when one doesn't yet exist.
 *
 * @since 4.7.0
 * @access public
 *
 * @param string $css CSS, stored in `post_content`.
 * @param array  $args {
 *     Args.
 *
 *     @type string $preprocessed Pre-processed CSS, stored in `post_content_filtered`. Normally empty string. Optional.
 *     @type string $stylesheet   Stylesheet (child theme) to update. Optional, defaults to current theme/stylesheet.
 * }
 * @return WP_Post|WP_Error Post on success, error on failure.
 */
function wp_update_custom_css_post($css, $args = array())
{
    $args = wp_parse_args($args, array('preprocessed' => '', 'stylesheet' => get_stylesheet()));
    $data = array('css' => $css, 'preprocessed' => $args['preprocessed']);
    /**
     * Filters the `css` (`post_content`) and `preprocessed` (`post_content_filtered`) args for a `custom_css` post being updated.
     *
     * This filter can be used by plugin that offer CSS pre-processors, to store the original
     * pre-processed CSS in `post_content_filtered` and then store processed CSS in `post_content`.
     * When used in this way, the `post_content_filtered` should be supplied as the setting value
     * instead of `post_content` via a the `customize_value_custom_css` filter, for example:
     *
     * <code>
     * add_filter( 'customize_value_custom_css', function( $value, $setting ) {
     *     $post = wp_get_custom_css_post( $setting->stylesheet );
     *     if ( $post && ! empty( $post->post_content_filtered ) ) {
     *         $css = $post->post_content_filtered;
     *     }
     *     return $css;
     * }, 10, 2 );
     * </code>
     *
     * @since 4.7.0
     * @param array $data {
     *     Custom CSS data.
     *
     *     @type string $css          CSS stored in `post_content`.
     *     @type string $preprocessed Pre-processed CSS stored in `post_content_filtered`. Normally empty string.
     * }
     * @param array $args {
     *     The args passed into `wp_update_custom_css_post()` merged with defaults.
     *
     *     @type string $css          The original CSS passed in to be updated.
     *     @type string $preprocessed The original preprocessed CSS passed in to be updated.
     *     @type string $stylesheet   The stylesheet (theme) being updated.
     * }
     */
    $data = apply_filters('update_custom_css_data', $data, array_merge($args, compact('css')));
    $post_data = array('post_title' => $args['stylesheet'], 'post_name' => sanitize_title($args['stylesheet']), 'post_type' => 'custom_css', 'post_status' => 'publish', 'post_content' => $data['css'], 'post_content_filtered' => $data['preprocessed']);
    // Update post if it already exists, otherwise create a new one.
    $post = wp_get_custom_css_post($args['stylesheet']);
    if ($post) {
        $post_data['ID'] = $post->ID;
        $r = wp_update_post(wp_slash($post_data), true);
    } else {
        $r = wp_insert_post(wp_slash($post_data), true);
        // Trigger creation of a revision. This should be removed once #30854 is resolved.
        if (!is_wp_error($r) && 0 === count(wp_get_post_revisions($r))) {
            wp_save_post_revision($r);
        }
    }
    if (is_wp_error($r)) {
        return $r;
    }
    return get_post($r);
}
 /**
  * Add CSS preprocessing to our CSS if it is supported.
  *
  * @param mixed                $css     Value of the setting.
  * @param WP_Customize_Setting $setting WP_Customize_Setting instance.
  *
  * @return string
  */
 public static function customize_value_custom_css($css, $setting)
 {
     // Find the current preprocessor.
     $jetpack_custom_css = get_theme_mod('jetpack_custom_css', array());
     if (isset($jetpack_custom_css['preprocessor'])) {
         $preprocessor = $jetpack_custom_css['preprocessor'];
     }
     // If it's not supported, just return.
     /** This filter is documented in modules/custom-css/custom-css.php */
     $preprocessors = apply_filters('jetpack_custom_css_preprocessors', array());
     if (!isset($preprocessors[$preprocessor])) {
         return $css;
     }
     // Swap it for the `post_content_filtered` instead.
     $post = wp_get_custom_css_post($setting->stylesheet);
     if ($post && !empty($post->post_content_filtered)) {
         $css = $post->post_content_filtered;
     }
     return $css;
 }
 /**
  * Test crud methods on WP_Customize_Custom_CSS_Setting.
  *
  * @covers wp_get_custom_css()
  * @covers WP_Customize_Custom_CSS_Setting::value()
  * @covers WP_Customize_Custom_CSS_Setting::preview()
  * @covers WP_Customize_Custom_CSS_Setting::update()
  */
 function test_crud()
 {
     $this->setting->default = '/* Hello World */';
     $this->assertEquals($this->setting->default, $this->setting->value());
     $this->assertNull(wp_get_custom_css_post());
     $this->assertNull(wp_get_custom_css_post($this->setting->stylesheet));
     $this->assertNull(wp_get_custom_css_post('twentyten'));
     $original_css = 'body { color: black; }';
     $post_id = $this->factory()->post->create(array('post_title' => $this->setting->stylesheet, 'post_name' => $this->setting->stylesheet, 'post_content' => $original_css, 'post_status' => 'publish', 'post_type' => 'custom_css'));
     $twentyten_css = 'body { color: red; }';
     $twentyten_post_id = $this->factory()->post->create(array('post_title' => 'twentyten', 'post_name' => 'twentyten', 'post_content' => $twentyten_css, 'post_status' => 'publish', 'post_type' => 'custom_css'));
     $twentyten_setting = new WP_Customize_Custom_CSS_Setting($this->wp_customize, 'custom_css[twentyten]');
     $this->assertEquals($post_id, wp_get_custom_css_post()->ID);
     $this->assertEquals($post_id, wp_get_custom_css_post($this->setting->stylesheet)->ID);
     $this->assertEquals($twentyten_post_id, wp_get_custom_css_post('twentyten')->ID);
     $this->assertEquals($original_css, wp_get_custom_css($this->setting->stylesheet));
     $this->assertEquals($original_css, $this->setting->value());
     $this->assertEquals($twentyten_css, wp_get_custom_css('twentyten'));
     $this->assertEquals($twentyten_css, $twentyten_setting->value());
     $updated_css = 'body { color: blue; }';
     $this->wp_customize->set_post_value($this->setting->id, $updated_css);
     $saved = $this->setting->save();
     $this->assertTrue(false !== $saved);
     $this->assertEquals($updated_css, $this->setting->value());
     $this->assertEquals($updated_css, wp_get_custom_css($this->setting->stylesheet));
     $previewed_css = 'body { color: red; }';
     $this->wp_customize->set_post_value($this->setting->id, $previewed_css);
     $this->setting->preview();
     $this->assertEquals($previewed_css, $this->setting->value());
     $this->assertEquals($previewed_css, wp_get_custom_css($this->setting->stylesheet));
     wp_delete_post($post_id);
     $this->assertNull(wp_get_custom_css_post());
     $this->assertNull(wp_get_custom_css_post(get_stylesheet()));
     $this->assertEquals($previewed_css, wp_get_custom_css(get_stylesheet()), 'Previewed value remains in spite of deleted post.');
     wp_delete_post($twentyten_post_id);
     $this->assertNull(wp_get_custom_css_post('twentyten'));
     $this->assertEquals('', wp_get_custom_css('twentyten'));
 }