Making WordPress.org

Changeset 4578


Ignore:
Timestamp:
12/23/2016 05:27:43 PM (9 years ago)
Author:
iandunn
Message:

WordCamp Remote CSS: Refactor for compatibility with Jetpack 4.2.2

WordPress 4.7 added a Customizer feature that allows editing CSS. Jetpack 4.2.2 replaced the Custom CSS module with an entirely new one that is compatible with the Customizer feature, but broke backwards-compatibility with the Site Cloner and Remote CSS plugins.

This commit refactors Remote CSS to restore compatibility with Jetpack.

https://make.wordpress.org/core/2016/10/11/feature-proposal-better-theme-customizations-via-custom-css-with-live-previews/
https://make.wordpress.org/core/2016/11/26/extending-the-custom-css-editor/
https://github.com/Automattic/jetpack/issues/5539
https://github.com/Automattic/jetpack/pull/5804

Location:
sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css
Files:
3 added
9 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/app/common.php

    r2124 r4578  
    22
    33namespace WordCamp\RemoteCSS;
     4use WP_Post;
     5use WP_Customize_Manager;
     6use Exception;
    47
    58defined( 'WPINC' ) or die();
    69
     10const POST_TYPE             = 'wc_remote_css';
    711const SAFE_CSS_POST_SLUG    = 'wcrcss_safe_cached_version';
    812const OPTION_LAST_UPDATE    = 'wcrcss_last_update';
     
    1418const GITHUB_API_HOSTNAME   = 'api.github.com';
    1519
    16 /**
    17  * Find the ID of the post we use to store the safe CSS
    18  *
    19  * @return int|\WP_Error
    20  */
    21 function get_safe_css_post_id() {
    22     $post    = get_safe_css_post();
    23     $post_id = is_a( $post, 'WP_Post' ) ? $post->ID : $post;
    24 
    25     return $post_id;
    26 }
    27 
    28 /**
    29  * Find the post we use to store the safe CSS
    30  *
    31  * @return \WP_Post|\WP_Error
     20add_action( 'init',               __NAMESPACE__ . '\register_post_types'  );
     21add_action( 'customize_register', __NAMESPACE__ . '\add_discovery_notice' );
     22
     23/**
     24 * Register our custom post types
     25 */
     26function register_post_types() {
     27    $labels = array(
     28        'name'          => __( 'Remote CSS', 'wordcamporg' ),
     29        'singular_name' => __( 'Remote CSS', 'wordcamporg' ),
     30    );
     31
     32    $capabilities = array(
     33        'delete_posts'           => 'edit_theme_options',
     34        'delete_post'            => 'edit_theme_options',
     35        'delete_published_posts' => 'edit_theme_options',
     36        'delete_private_posts'   => 'edit_theme_options',
     37        'delete_others_posts'    => 'edit_theme_options',
     38        'edit_post'              => 'edit_css',
     39        'edit_posts'             => 'edit_css',
     40        'edit_others_posts'      => 'edit_css',
     41        'edit_published_posts'   => 'edit_css',
     42        'read_post'              => 'read',
     43        'read_private_posts'     => 'read',
     44        'publish_posts'          => 'edit_theme_options',
     45    );
     46
     47    $params = array(
     48        'labels'           => $labels,
     49        'public'           => false,
     50        'hierarchical'     => false,
     51        'rewrite'          => false,
     52        'query_var'        => false,
     53        'delete_with_user' => false,
     54        'can_export'       => true,
     55        'supports'         => array( 'title', 'revisions' ),
     56        'capabilities'     => $capabilities,
     57    );
     58
     59    register_post_type( POST_TYPE, $params );
     60}
     61
     62/**
     63 * Determines if the site's owner has configured the plugin
     64 *
     65 * @return bool
     66 */
     67function is_configured() {
     68    return ! empty( get_option( OPTION_REMOTE_CSS_URL ) );
     69}
     70
     71/**
     72 * Get the WP_Post where the sanitized CSS is stored
     73 *
     74 * If it doesn't exist, it will be created.
     75 *
     76 * @todo All of the code related to the old Jetpack posts can be removed once all sites have migrated.
     77 *       That only happens once something triggers `admin_init`, though.
     78 *
     79 * @return WP_Post
    3280 */
    3381function get_safe_css_post() {
     82    $posts = get_posts( array(
     83        'post_type'      => POST_TYPE,
     84        'post_status'    => 'private',
     85        'posts_per_page' => 1,
     86    ) );
     87
     88    if ( isset( $posts[0] ) ) {
     89        $post = $posts[0];
     90    } else {
     91        $jetpack_post = get_jetpack_post();
     92
     93        if ( $jetpack_post ) {
     94            $post = migrate_jetpack_post( $jetpack_post );
     95        } else {
     96            $post = create_new_post();
     97        }
     98    }
     99
     100    return $post;
     101}
     102
     103/**
     104 * Find Jetpack's safe CSS post
     105 *
     106 * Before WordPress 4.7 and Jetpack 4.2.2, Jetpack stored it's Custom CSS in a `safecss` post type, and Remote CSS
     107 * created it's own `safecss` post to store our sanitized CSS. Any site that hasn't been migrated to the
     108 * `wc_remote_css` post type yet will still have their CSS stored in a `safecss` post.
     109 *
     110 * @return WP_Post|false
     111 */
     112function get_jetpack_post() {
     113    $post = false;
     114
    34115    $safe_css_post = get_posts( array(
    35116        'posts_per_page' => 1,
     
    41122    if ( $safe_css_post ) {
    42123        $post = $safe_css_post[0];
    43     } else {
    44         $post = wp_insert_post( array(
    45             'post_type'   => 'safecss',
    46             'post_status' => 'private', // Jetpack_Custom_CSS::post_id() only searches for `public` posts, so this prevents Jetpack from fetching our post
    47             'post_title'  => SAFE_CSS_POST_SLUG,
    48             'post_name'   => SAFE_CSS_POST_SLUG,
    49         ), true );
    50 
    51         if ( ! is_wp_error( $post ) ) {
    52             $post = get_post( $post );
    53         }
    54124    }
    55125
    56126    return $post;
    57127}
     128
     129/**
     130 * Migrate an old `safecss` post to the new `wc_remote_css` post type
     131 *
     132 * @see get_jetpack_post() for some background information
     133 *
     134 * We don't want to delete the old post, just in case something goes wrong and we need to restore it. It does need
     135 * to be disabled, though, because otherwise it could cause problems. For instance, if it's migrated without being
     136 * disabled, then the user deletes the Remote CSS URL in order to stop using the plugin. In that scenario, the old
     137 * post would be restored, and there would be no way for the user to stop using the plugin.
     138 *
     139 * @param WP_Post $jetpack_post
     140 *
     141 * @return WP_Post
     142 *
     143 * @throws Exception
     144 */
     145function migrate_jetpack_post( $jetpack_post ) {
     146    $new_post = create_new_post( $jetpack_post->post_content );
     147
     148    $jetpack_post->post_status = 'draft';
     149    $jetpack_post->post_name   = SAFE_CSS_POST_SLUG . '_migrated';
     150
     151    $result = wp_update_post( $jetpack_post, true );
     152
     153    if ( is_wp_error( $result ) ) {
     154        throw new Exception( sprintf(
     155            // translators: %s is an email address
     156            __( "Could not migrate Jetpack post. Please notify us at %s.", 'wordcamporg' ),
     157            EMAIL_CENTRAL_SUPPORT
     158        ) );
     159    }
     160
     161    return $new_post;
     162}
     163
     164/**
     165 * Create a new Remote CSS post
     166 *
     167 * @param string $content
     168 *
     169 * @return WP_Post
     170 *
     171 * @throws Exception
     172 */
     173function create_new_post( $content = '' ) {
     174    $post = wp_insert_post( array(
     175        'post_type'    => POST_TYPE,
     176        'post_name'    => SAFE_CSS_POST_SLUG,
     177        'post_status'  => 'private',
     178        'post_content' => $content
     179    ), true );
     180
     181    if ( ! is_wp_error( $post ) ) {
     182        $post = get_post( $post );
     183    }
     184
     185    if ( ! is_a( $post, 'WP_Post' ) ) {
     186        throw new Exception( sprintf(
     187            // translators: %s is an email address
     188            __( "Could not create CSS post. Please notify us at %s.", 'wordcamporg' ),
     189            EMAIL_CENTRAL_SUPPORT
     190        ) );
     191    }
     192
     193    return $post;
     194}
     195
     196/**
     197 * Get the mode for outputting the custom CSS.
     198 *
     199 * This just uses the same mode as Jetpack's CSS post, because it wouldn't make any sense to have them configured
     200 * with opposite values.
     201 *
     202 * @return string
     203 */
     204function get_output_mode() {
     205    $mode = 'add-on';
     206    $jetpack_settings = (array) get_theme_mod( 'jetpack_custom_css' );
     207
     208    if ( isset( $jetpack_settings['replace'] ) && $jetpack_settings['replace'] ) {
     209        $mode = 'replace';
     210    }
     211
     212    return $mode;
     213}
     214
     215/**
     216 * Add a notice to Core's Custom CSS section to offer using Remote CSS
     217 *
     218 * The Core/Jetpack CSS editor is not designed to meet the needs of the typical WordCamp organizing team, but teams
     219 * who aren't satisfied with it may not be aware of Remote CSS. This helps them discover it, so that they can
     220 * choose which one they want to use.
     221 *
     222 * @param WP_Customize_Manager $wp_customize
     223 */
     224function add_discovery_notice( $wp_customize ) {
     225    $plugin_url = plugins_url( '', __DIR__ );
     226
     227    $notice_text = sprintf(
     228        __(
     229            'You can also build your CSS locally using your favorite tools, and collaborate on GitHub with <a href="%s">Remote CSS</a>.',
     230            'wordcamporg'
     231        ),
     232        admin_url( 'themes.php?page=remote-css' )
     233    );
     234
     235    ob_start();
     236    require_once( dirname( __DIR__ ) . '/views/template-discovery-notice.php' );
     237    $description = ob_get_clean();
     238
     239    $wp_customize->add_control(
     240        'wcrss_discovery',
     241        array(
     242            'priority'    => 1,
     243            'section'     => 'custom_css',
     244            'settings'    => array(),
     245            'description' => $description,
     246            'input_attrs' => array(
     247                'style' => 'display: none;',
     248            ),
     249        )
     250    );
     251}
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/app/output-cached-css.php

    r3192 r4578  
    22
    33namespace WordCamp\RemoteCSS;
     4use Jetpack;
     5use Exception;
    46
    57defined( 'WPINC' ) or die();
    68
    7 add_action( 'wp_enqueue_scripts',           __NAMESPACE__ . '\enqueue_cached_css', 11 );  // after the theme's stylesheet, but before Jetpack Custom CSS's stylesheet
    8 add_action( 'wp_ajax_'        . CSS_HANDLE, __NAMESPACE__ . '\output_cached_css'      );
    9 add_action( 'wp_ajax_nopriv_' . CSS_HANDLE, __NAMESPACE__ . '\output_cached_css'      );
    10 add_filter( 'nocache_headers',              __NAMESPACE__ . '\set_cache_headers'      );
     9if ( is_configured() ) {
     10    add_action( 'wp_enqueue_scripts',           __NAMESPACE__ . '\enqueue_cached_css', 11 );  // after the theme's stylesheet, but before Core's Custom CSS stylesheet
     11    add_filter( 'stylesheet_uri',               __NAMESPACE__ . '\skip_theme_stylesheet'  );
     12    add_action( 'wp_ajax_'        . CSS_HANDLE, __NAMESPACE__ . '\output_cached_css'      );
     13    add_action( 'wp_ajax_nopriv_' . CSS_HANDLE, __NAMESPACE__ . '\output_cached_css'      );
     14    add_filter( 'nocache_headers',              __NAMESPACE__ . '\set_cache_headers'      );
     15}
    1116
    1217/**
     
    1621 */
    1722function enqueue_cached_css() {
    18     if ( false === get_option( OPTION_REMOTE_CSS_URL ) ) {
    19         return;
    20     }
    21 
    22     $cachebuster = get_latest_revision_id();
    23 
    24     if ( ! $cachebuster ) {
    25         $cachebuster = date( 'Y-m-d' ); // We should always have a revision ID, but this will work as a fallback if we don't for some reason
     23    try {
     24        $cachebuster = get_latest_revision_id();
     25    } catch ( Exception $exception ) {
     26        $cachebuster = date( 'Y-m-d-H' );
    2627    }
    2728
     
    3637
    3738/**
     39 * Skip the theme's stylesheet when in `replace` mode
     40 *
     41 * Normally Jetpack handles this (via `Jetpack_Custom_CSS_Enhancements::style_filter`), but we still need to do it
     42 * even if the `custom-css` module isn't active. We can't include `custom-css-4.7.php`, because it has
     43 * side-effects. It doesn't seem worth it to require the module to be active just for this, so instead we're just
     44 * duplicating the functionality.
     45 *
     46 * @param string $stylesheet_url
     47 *
     48 * @return string
     49 */
     50function skip_theme_stylesheet( $stylesheet_url ) {
     51    if ( ! is_admin() && 'replace' === get_output_mode() && ! Jetpack::is_module_active( 'custom-css' ) ) {
     52        $stylesheet_url = plugins_url( 'custom-css/custom-css/css/blank.css', Jetpack::get_module_path( 'custom-css' ) );
     53    }
     54
     55    return $stylesheet_url;
     56}
     57
     58/**
    3859 * Get the ID of the latest revision of the safe CSS post
    3960 *
    40  * @return int|bool
     61 * @return int
    4162 */
    4263function get_latest_revision_id() {
    4364    $safe_css = get_safe_css_post();
    44 
    45     if ( ! is_a( $safe_css, 'WP_Post' ) || empty( $safe_css->post_content_filtered ) ) {
    46         return false;
    47     }
    4865    $latest_revision = wp_get_post_revisions( $safe_css->ID, array( 'posts_per_page' => 1 ) );
    4966
    5067    if ( empty( $latest_revision ) ) {
    51         return false;
     68        $latest_revision = $safe_css;
     69    } else {
     70        $latest_revision = array_shift( $latest_revision );
    5271    }
    53 
    54     $latest_revision = array_shift( $latest_revision );
    5572
    5673    return $latest_revision->ID;
     
    7289    }
    7390
    74     $safe_css = get_safe_css_post();
    75 
    76     if ( ! is_a( $safe_css, 'WP_Post' ) ) {
     91    try {
     92        $safe_css = get_safe_css_post();
     93    } catch ( Exception $exception ) {
    7794        return $cache_headers;
    7895    }
     
    95112 */
    96113function output_cached_css() {
     114    // Explicitly tell the browser that this is CSS, to avoid MIME sniffing vulnerabilities
    97115    header( 'Content-Type: text/css; charset=' . get_option( 'blog_charset' ) );
    98116
    99     $safe_css = get_safe_css_post();
     117    try {
     118        $safe_css_post = get_safe_css_post();
     119        $safe_css      = $safe_css_post->post_content;
     120    } catch ( Exception $exception ) {
     121        $safe_css = '';
     122    }
    100123
    101     if ( is_a( $safe_css, 'WP_Post' ) ) {
    102         echo $safe_css->post_content_filtered;
    103     }
     124    echo $safe_css;
    104125
    105126    wp_die();
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/app/synchronize-remote-css.php

    r2124 r4578  
    22
    33namespace WordCamp\RemoteCSS;
     4use Jetpack_Custom_CSS_Enhancements;
     5use Exception;
    46
    57defined( 'WPINC' ) or die();
     
    810 * Synchronizes the local safe/cached copy of the CSS with the canonical, remote source.
    911 *
     12 * @todo Minification was removed from Jetpack 4.2.2, but will probably be added back in the future. Once it is,
     13 *       make sure that it's being run here.
     14 *
    1015 * @param string $remote_css_url
    1116 */
    1217function synchronize_remote_css( $remote_css_url ) {
    13     sanitize_and_save_unsafe_css( fetch_unsafe_remote_css( $remote_css_url ) );
     18    $unsafe_css = fetch_unsafe_remote_css( $remote_css_url );
     19    $safe_css   = sanitize_unsafe_css( $unsafe_css );
     20
     21    save_safe_css( $safe_css );
    1422    update_option( OPTION_LAST_UPDATE, time() );
    1523}
     
    5058
    5159/**
    52  * Sanitize unsafe CSS and save the safe version
     60 * Sanitize unsafe CSS
    5361 *
    54  * Note: If we ever need to decouple from Jetpack Custom CSS, then https://github.com/google/caja might be
    55  * a viable alternative. It'd be nice to have a modular solution, but we'd also have to keep it up to date,
    56  * and we'd still need to mirror the Output Mode setting.
     62 * Jetpack/CSSTidy will validate and normalize the CSS, but they do _NOT_ perform comprehensive sanitization from
     63 * a security perspective. So, we still need to add our custom sanitization to the process. That's done in
     64 * `mu-plugins/jetpack-tweaks/css-sanitization.php`, but we need to confirm that it actually ran, to protect against
     65 * a situation where there was a change in Jetpack/CSSTidy, or in our sanitization, and this function wasn't updated
     66 * to reflect them.
    5767 *
    5868 * @param string $unsafe_css
    5969 *
    60  * @throws \Exception if Jetpack's Custom CSS module isn't available
     70 * @return string
     71 *
     72 * @throws Exception
    6173 */
    62 function sanitize_and_save_unsafe_css( $unsafe_css ) {
    63     if ( ! is_callable( array( '\Jetpack_Custom_CSS', 'save' ) ) ) {
    64         throw new \Exception(
    65             __( "<code>Jetpack_Custom_CSS::save()</code> is not available.
    66             Please make sure Jetpack's Custom CSS module has been activated.", 'wordcamporg' )
    67         );
     74function sanitize_unsafe_css( $unsafe_css ) {
     75    require_once( JETPACK__PLUGIN_DIR . '/modules/custom-css/custom-css-4.7.php' );
     76
     77    $parser_rules_setup          = has_filter( 'csstidy_optimize_postparse', 'WordCamp\Jetpack_Tweaks\sanitize_csstidy_parsed_rules' );
     78    $subvalue_sanitization_setup = has_filter( 'csstidy_optimize_subvalue',  'WordCamp\Jetpack_Tweaks\sanitize_csstidy_subvalues'    );
     79
     80    if ( ! $parser_rules_setup || ! $subvalue_sanitization_setup ) {
     81        throw new Exception( sprintf(
     82            // translators: %s is an email address
     83            __( "Could not update CSS because sanitization was not available. Please notify us at %s.", 'wordcamporg' ),
     84            EMAIL_CENTRAL_SUPPORT
     85        ) );
    6886    }
    6987
    70     /*
    71      * Note: In addition to the sanitization that Jetpack_Custom_CSS::save() does, there's additional sanitization
    72      * done by the callbacks in mu-plugins/jetpack-tweaks.php.
    73      */
     88    $safe_css = Jetpack_Custom_CSS_Enhancements::sanitize_css( $unsafe_css, array( 'force' => true ) );
    7489
    75     add_filter( 'jetpack_custom_css_pre_post_id', __NAMESPACE__ . '\get_safe_css_post_id' );
     90    if ( did_action( 'csstidy_optimize_postparse' ) < 1 || did_action( 'csstidy_optimize_subvalue' ) < 1 ) {
     91        throw new Exception( sprintf(
     92            // translators: %s is an email address
     93            __( "Could not update CSS because sanitization did not run. Please notify us at %s.", 'wordcamporg' ),
     94            EMAIL_CENTRAL_SUPPORT
     95        ) );
     96    }
    7697
    77     \Jetpack_Custom_CSS::save( array(
    78         'css'             => $unsafe_css,
    79         'is_preview'      => false,
    80         'preprocessor'    => '',     // This should never be changed to allow pre-processing. See note in validate_remote_css_url()
    81         'add_to_existing' => false,  // This isn't actually used, see get_output_mode()
    82         'content_width'   => false,
    83     ) );
     98    return $safe_css;
     99}
    84100
    85     remove_filter( 'jetpack_custom_css_pre_post_id', __NAMESPACE__ . '\get_safe_css_post_id' );
     101/**
     102 * Save the safe CSS
     103 *
     104 * @param string $safe_css
     105 */
     106function save_safe_css( $safe_css ) {
     107    $post = get_safe_css_post();
     108    $post->post_content = $safe_css;
    86109
    87     /*
    88      * Jetpack_Custom_CSS::save_revision() caches our post ID because it retrieves the post ID from
    89      * Jetpack_Custom_CSS::post_id() while the get_safe_css_post_id() callback is active. We need to clear that
    90      * to avoid unintended side-effects.
    91      */
    92     wp_cache_delete( 'custom_css_post_id' );
     110    wp_update_post( $post );
    93111}
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/app/user-interface.php

    r2148 r4578  
    22
    33namespace WordCamp\RemoteCSS;
    4 
    54defined( 'WPINC' ) or die();
    65
     
    4342    $remote_css_url            = get_option( OPTION_REMOTE_CSS_URL , '' );
    4443    $fonts_tool_url            = admin_url( 'themes.php?page=wc-fonts-options' );
    45     $jetpack_modules_url       = admin_url( 'admin.php?page=jetpack_modules' );
    46     $jetpack_custom_css_active = method_exists( '\Jetpack_Custom_CSS', 'init' );
    4744
    4845    require_once( dirname( __DIR__ ) . '/views/page-remote-css.php' );
     
    5047
    5148/**
    52  * Get the mode for outputting the custom CSS.
    53  *
    54  * This just uses the same mode as Jetpack's CSS post, because it wouldn't make any sense to have them configured
    55  * with opposite values.
    56  *
    57  * @return string
    58  */
    59 function get_output_mode() {
    60     $mode = 'add-on';
    61 
    62     try {
    63         $jetpack_css_post_id = get_jetpack_css_post_id();
    64 
    65         if ( 'no' === get_post_meta( $jetpack_css_post_id, 'custom_css_add', true ) ) {
    66             $mode = 'replace';
    67         }
    68     } catch( \Exception $exception ) {
    69         // Just fall back to the default $mode
    70     }
    71 
    72     return $mode;
    73 }
    74 
    75 /**
    7649 * Get or set the mode for outputting the custom CSS.
    7750 *
     
    8154 */
    8255function set_output_mode( $mode ) {
    83     $mode        = 'replace' === $mode ? 'no' : 'yes';
    84     $revision_id = get_jetpack_css_latest_revision_id();
    85 
    86     update_post_meta( get_jetpack_css_post_id(), 'custom_css_add', $mode );
    87 
    88     if ( $revision_id ) {
    89         update_metadata( 'post', $revision_id, 'custom_css_add', $mode );   // update_post_meta doesn't allow modifying revisions
    90     }
    91 }
    92 
    93 /**
    94  * Get the ID of Jetpack's safecss post
    95  *
    96  * If it doesn't exist yet, create it, because we'll need it for the Output Mode setting.
    97  *
    98  * @throws \Exception if Jetpack's Custom CSS module isn't available
    99  *
    100  * @return int
    101  */
    102 function get_jetpack_css_post_id() {
    103     if ( ! is_callable( array( '\Jetpack_Custom_CSS', 'post_id' ) ) ) {
    104         throw new \Exception(
    105             __( "<code>Jetpack_Custom_CSS::post_id()</code> is not available.
    106             Please make sure Jetpack's Custom CSS module has been activated.",
    107             'wordcamporg' )
    108         );
    109     }
    110 
    111     $post_id = \Jetpack_Custom_CSS::post_id();
    112 
    113     if ( ! is_int( $post_id ) || 0 === $post_id ) {
    114         $post_values = array(
    115             'post_content'          => '',
    116             'post_title'            => 'safecss',
    117             'post_status'           => 'publish',
    118             'post_type'             => 'safecss',
    119             'post_content_filtered' => '',
    120         );
    121 
    122         $post_id = wp_insert_post( $post_values, true );
    123 
    124         if ( is_wp_error( $post_id ) ) {
    125             throw new \Exception( $post_id->get_error_message() );
    126         }
    127     }
    128 
    129     return $post_id;
    130 }
    131 
    132 /**
    133  * Get the ID of the current Jetpack's safecss revision post
    134  *
    135  * @throws \Exception if Jetpack's Custom CSS module isn't available
    136  *
    137  * @return int|bool
    138  */
    139 function get_jetpack_css_latest_revision_id() {
    140     if ( ! is_callable( array( '\Jetpack_Custom_CSS', 'get_current_revision' ) ) ) {
    141         throw new \Exception(
    142             __( "<code>Jetpack_Custom_CSS::get_current_revision()</code> is not available.
    143             Please make sure Jetpack's Custom CSS module has been activated.",
    144             'wordcamporg' )
    145         );
    146     }
    147 
    148     $revision = \Jetpack_Custom_CSS::get_current_revision();
    149 
    150     return empty( $revision['ID'] ) ? false : $revision['ID'];
     56    $jetpack_settings            = (array) get_theme_mod( 'jetpack_custom_css' );
     57    $jetpack_settings['replace'] = 'replace' === $mode;
     58
     59    set_theme_mod( 'jetpack_custom_css', $jetpack_settings );
    15160}
    15261
     
    16978    if ( '' === $remote_css_url ) {
    17079        $notice = '';
    171         wp_delete_post( get_safe_css_post_id() );
     80        $post   = get_safe_css_post();
     81
     82        wp_delete_post( $post->ID );
    17283    } else {
    17384        $notice         = __( 'The remote CSS file was successfully synchronized.', 'wordcamporg' );
     
    17586
    17687        synchronize_remote_css( $remote_css_url );
    177         set_output_mode( $_POST['wcrcss-output-mode'] );
    178     }
    179 
     88    }
     89
     90    set_output_mode( $_POST['wcrcss-output-mode'] );
    18091    update_option( OPTION_REMOTE_CSS_URL, $remote_css_url );
    18192
     
    233144     * Vanilla CSS only
    234145     *
    235      * We need to force the user to do their own pre-processing, because Jetpack_Custom_CSS::save() doesn't
     146     * We need to force the user to do their own pre-processing, because Jetpack_Custom_CSS_Enhancements::sanitize() doesn't
    236147     * sanitize the unsafe CSS when a preprocessor is present. We'd have to add more logic to make sure it gets
    237148     * sanitized, which would further couple the plugin to Jetpack.
     
    297208    switch ( $view_slug ) {
    298209        case 'overview':
    299             $jetpack_editor_url = admin_url( 'themes.php?page=editcss' );
     210            $custom_css_url = admin_url( 'customize.php?autofocus[section]=custom_css' );
    300211            break;
    301212
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/app/webhook-handler.php

    r3192 r4578  
    55defined( 'WPINC' ) or die();
    66
    7 add_action( 'wp_ajax_'        . AJAX_ACTION, __NAMESPACE__ . '\webhook_handler'        ); // This is useless in production, but useful for manual testing
    8 add_action( 'wp_ajax_nopriv_' . AJAX_ACTION, __NAMESPACE__ . '\webhook_handler'        );
    9 add_action( SYNCHRONIZE_ACTION,              __NAMESPACE__ . '\synchronize_remote_css' );
     7if ( is_configured() ) {
     8    add_action( 'wp_ajax_'        . AJAX_ACTION, __NAMESPACE__ . '\webhook_handler'        ); // This is useless in production, but useful for manual testing
     9    add_action( 'wp_ajax_nopriv_' . AJAX_ACTION, __NAMESPACE__ . '\webhook_handler'        );
     10    add_action( SYNCHRONIZE_ACTION,              __NAMESPACE__ . '\synchronize_remote_css' );
     11}
    1012
    1113/*
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/tests/test-synchronize-remote-css.php

    r2960 r4578  
    1313        $unsanitized_css          = file_get_contents( __DIR__ . '/unsanitized.css' );
    1414        $known_good_sanitized_css = file_get_contents( __DIR__ . '/sanitized.css'   );
     15        $maybe_sanitized_css      = sanitize_unsafe_css( $unsanitized_css );
    1516
    16         sanitize_and_save_unsafe_css( $unsanitized_css );
    17 
    18         $maybe_sanitized_css = get_safe_css_post();
    19 
    20         $this->assertEquals( $maybe_sanitized_css->post_content, $known_good_sanitized_css );
     17        $this->assertEquals( $maybe_sanitized_css, $known_good_sanitized_css );
    2118    }
    2219}
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/views/help-overview.php

    r2134 r4578  
    44defined( 'WPINC' ) or die();
    55
     6/**
     7 * @var string $custom_css_url
     8 */
     9
    610?>
    711
    812<p>
    9     <?php _e( 'Remote CSS gives you a lot more flexibility in how you develop your site than the Jetpack Custom CSS module.
     13    <?php _e( 'Remote CSS gives you a lot more flexibility in how you develop your site than the Core/Jetpack editor.
    1014    For instance, you can:', 'wordcamporg' ); ?>
    1115</p>
     
    3438<p>
    3539    <?php printf(
    36         __( 'If you\'re looking for something simpler, <a href="%s">Jetpack\'s CSS Editor</a> is a great option.', 'wordcamporg' ),
    37         esc_url( $jetpack_editor_url )
     40        __( 'If you\'re looking for something simpler, <a href="%s">the Core/Jetpack editor</a> is a great option.', 'wordcamporg' ),
     41        esc_url( $custom_css_url )
    3842    ); ?>
    3943</p>
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/views/help-tips.php

    r2124 r4578  
    33namespace WordCamp\RemoteCSS;
    44defined( 'WPINC' ) or die();
     5
     6/**
     7 * @var string $fonts_tool_url
     8 * @var string $media_library_url
     9 */
    510
    611?>
     
    3742
    3843    <li>
    39         <?php _e( "This tool plays nicely with Jetpack's CSS editor, and it's possible to use both.
    40         If you do, the rules in the Jetpack editor will take precedence.", 'wordcamporg' ); ?>
     44        <?php _e( "This tool plays nicely with the Core/Jetpack editor, and it's possible to use both.
     45        If you do, the rules in the Core/Jetpack editor will take precedence.", 'wordcamporg' ); ?>
    4146    </li>
    4247</ul>
  • sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/views/page-remote-css.php

    r2148 r4578  
    44defined( 'WPINC' ) or die();
    55
     6/**
     7 * @var string $notice
     8 * @var string $notice_class
     9 * @var string $remote_css_url
     10 * @var string $output_mode
     11 */
     12
    613?>
    714
    815<div class="wrap">
    916    <h1><?php _e( 'Remote CSS', 'wordcamporg' ); ?></h1>
    10 
    11     <?php if ( ! $jetpack_custom_css_active ) : ?>
    12         <div id="message" class="notice notice-error inline">
    13             <?php
    14                 /*
    15                  * Jetpack_Custom_CSS is used to sanitize the unsafe CSS, and for removing the theme's stylesheet
    16                  * in `replace` mode. Methods from Jetpack_Custom_CSS are called throughout this plugin, so we
    17                  * need it to be active.
    18                  */
    19             ?>
    20 
    21             <p>
    22                 <?php printf(
    23                     __( 'This tool uses some functionality from Jetpack\'s Custom CSS module,
    24                     but it doesn\'t look like it\'s available.
    25                     Please <a href="%s">activate it</a>.',
    26                     'wordcamporg' ),
    27                     esc_url( $jetpack_modules_url )
    28                 ); ?>
    29             </p>
    30         </div>
    31     <?php endif; ?>
    3217
    3318    <?php
     
    4025    <?php if ( $notice ) : ?>
    4126        <div id="message" class="notice <?php echo esc_attr( $notice_class ); ?> is-dismissible">
    42             <?php
    43                 /*
    44                  * Typically KSES is discouraged when displaying text because it's expensive, but in this case
    45                  * it's appropriate because the underlying layers need to pass HTML-formatted error messages, and
    46                  * this only only runs when the options are updated.
    47                  */
    48             ?>
    49 
    5027            <p><?php echo wp_kses( $notice, wp_kses_allowed_html( 'data' ) ); ?></p>
    5128        </div>
     
    5330
    5431    <p>
    55         <?php _e( 'This tool allows you to develop your CSS in any environment that you choose, and with the tools that you prefer,
    56         rather than with Jetpack\'s CSS Editor.
    57         <button type="button" id="wcrcss-open-help-tab" class="button-link">Open the Help tab</button> for detailed instructions.',
    58         'wordcamporg' ); ?>
     32        <?php _e(
     33            'Remote CSS allows you to develop your CSS in any environment that you choose, and with whatever tools that you prefer.
     34            <button type="button" id="wcrcss-open-help-tab" class="button-link">Open the Help tab</button> for detailed instructions.',
     35            'wordcamporg'
     36        ); ?>
    5937    </p>
    6038
     
    6240        <?php wp_nonce_field( 'wcrcss-options-submit', 'wcrcss-options-nonce' ); ?>
    6341
    64         <fieldset <?php disabled( $jetpack_custom_css_active, false ); ?>>
    6542            <p>
    6643                <label>
    67                     <?php _e( 'Remote CSS File:', 'wordcamporg' ); ?><br />
     44                    <?php _e( 'Remote CSS URL:', 'wordcamporg' ); ?><br />
    6845                    <input type="text" name="wcrcss-remote-css-url" class="large-text" value="<?php echo esc_url( $remote_css_url ); ?>" />
    6946                </label>
     
    9168
    9269            <?php submit_button( __( 'Update', 'wordcamporg' ) ); ?>
    93         </fieldset>
    9470    </form>
    9571</div>
Note: See TracChangeset for help on using the changeset viewer.