Changeset 4578
- Timestamp:
- 12/23/2016 05:27:43 PM (9 years ago)
- Location:
- sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css
- Files:
-
- 3 added
- 9 edited
-
app/common.php (modified) (3 diffs)
-
app/output-cached-css.php (modified) (5 diffs)
-
app/synchronize-remote-css.php (modified) (3 diffs)
-
app/user-interface.php (modified) (8 diffs)
-
app/webhook-handler.php (modified) (1 diff)
-
images (added)
-
images/github-mark.svg (added)
-
tests/test-synchronize-remote-css.php (modified) (1 diff)
-
views/help-overview.php (modified) (2 diffs)
-
views/help-tips.php (modified) (2 diffs)
-
views/page-remote-css.php (modified) (5 diffs)
-
views/template-discovery-notice.php (added)
Legend:
- Unmodified
- Added
- Removed
-
sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/app/common.php
r2124 r4578 2 2 3 3 namespace WordCamp\RemoteCSS; 4 use WP_Post; 5 use WP_Customize_Manager; 6 use Exception; 4 7 5 8 defined( 'WPINC' ) or die(); 6 9 10 const POST_TYPE = 'wc_remote_css'; 7 11 const SAFE_CSS_POST_SLUG = 'wcrcss_safe_cached_version'; 8 12 const OPTION_LAST_UPDATE = 'wcrcss_last_update'; … … 14 18 const GITHUB_API_HOSTNAME = 'api.github.com'; 15 19 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 20 add_action( 'init', __NAMESPACE__ . '\register_post_types' ); 21 add_action( 'customize_register', __NAMESPACE__ . '\add_discovery_notice' ); 22 23 /** 24 * Register our custom post types 25 */ 26 function 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 */ 67 function 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 32 80 */ 33 81 function 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 */ 112 function get_jetpack_post() { 113 $post = false; 114 34 115 $safe_css_post = get_posts( array( 35 116 'posts_per_page' => 1, … … 41 122 if ( $safe_css_post ) { 42 123 $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 post47 '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 }54 124 } 55 125 56 126 return $post; 57 127 } 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 */ 145 function 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 */ 173 function 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 */ 204 function 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 */ 224 function 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 2 2 3 3 namespace WordCamp\RemoteCSS; 4 use Jetpack; 5 use Exception; 4 6 5 7 defined( 'WPINC' ) or die(); 6 8 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' ); 9 if ( 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 } 11 16 12 17 /** … … 16 21 */ 17 22 function 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' ); 26 27 } 27 28 … … 36 37 37 38 /** 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 */ 50 function 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 /** 38 59 * Get the ID of the latest revision of the safe CSS post 39 60 * 40 * @return int |bool61 * @return int 41 62 */ 42 63 function get_latest_revision_id() { 43 64 $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 }48 65 $latest_revision = wp_get_post_revisions( $safe_css->ID, array( 'posts_per_page' => 1 ) ); 49 66 50 67 if ( empty( $latest_revision ) ) { 51 return false; 68 $latest_revision = $safe_css; 69 } else { 70 $latest_revision = array_shift( $latest_revision ); 52 71 } 53 54 $latest_revision = array_shift( $latest_revision );55 72 56 73 return $latest_revision->ID; … … 72 89 } 73 90 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 ) { 77 94 return $cache_headers; 78 95 } … … 95 112 */ 96 113 function output_cached_css() { 114 // Explicitly tell the browser that this is CSS, to avoid MIME sniffing vulnerabilities 97 115 header( 'Content-Type: text/css; charset=' . get_option( 'blog_charset' ) ); 98 116 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 } 100 123 101 if ( is_a( $safe_css, 'WP_Post' ) ) { 102 echo $safe_css->post_content_filtered; 103 } 124 echo $safe_css; 104 125 105 126 wp_die(); -
sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/app/synchronize-remote-css.php
r2124 r4578 2 2 3 3 namespace WordCamp\RemoteCSS; 4 use Jetpack_Custom_CSS_Enhancements; 5 use Exception; 4 6 5 7 defined( 'WPINC' ) or die(); … … 8 10 * Synchronizes the local safe/cached copy of the CSS with the canonical, remote source. 9 11 * 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 * 10 15 * @param string $remote_css_url 11 16 */ 12 17 function 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 ); 14 22 update_option( OPTION_LAST_UPDATE, time() ); 15 23 } … … 50 58 51 59 /** 52 * Sanitize unsafe CSS and save the safe version60 * Sanitize unsafe CSS 53 61 * 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. 57 67 * 58 68 * @param string $unsafe_css 59 69 * 60 * @throws \Exception if Jetpack's Custom CSS module isn't available 70 * @return string 71 * 72 * @throws Exception 61 73 */ 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 ); 74 function 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 ) ); 68 86 } 69 87 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 ) ); 74 89 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 } 76 97 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 } 84 100 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 */ 106 function save_safe_css( $safe_css ) { 107 $post = get_safe_css_post(); 108 $post->post_content = $safe_css; 86 109 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 ); 93 111 } -
sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/app/user-interface.php
r2148 r4578 2 2 3 3 namespace WordCamp\RemoteCSS; 4 5 4 defined( 'WPINC' ) or die(); 6 5 … … 43 42 $remote_css_url = get_option( OPTION_REMOTE_CSS_URL , '' ); 44 43 $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' );47 44 48 45 require_once( dirname( __DIR__ ) . '/views/page-remote-css.php' ); … … 50 47 51 48 /** 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 configured55 * with opposite values.56 *57 * @return string58 */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 $mode70 }71 72 return $mode;73 }74 75 /**76 49 * Get or set the mode for outputting the custom CSS. 77 50 * … … 81 54 */ 82 55 function 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 ); 151 60 } 152 61 … … 169 78 if ( '' === $remote_css_url ) { 170 79 $notice = ''; 171 wp_delete_post( get_safe_css_post_id() ); 80 $post = get_safe_css_post(); 81 82 wp_delete_post( $post->ID ); 172 83 } else { 173 84 $notice = __( 'The remote CSS file was successfully synchronized.', 'wordcamporg' ); … … 175 86 176 87 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'] ); 180 91 update_option( OPTION_REMOTE_CSS_URL, $remote_css_url ); 181 92 … … 233 144 * Vanilla CSS only 234 145 * 235 * We need to force the user to do their own pre-processing, because Jetpack_Custom_CSS ::save() doesn't146 * We need to force the user to do their own pre-processing, because Jetpack_Custom_CSS_Enhancements::sanitize() doesn't 236 147 * sanitize the unsafe CSS when a preprocessor is present. We'd have to add more logic to make sure it gets 237 148 * sanitized, which would further couple the plugin to Jetpack. … … 297 208 switch ( $view_slug ) { 298 209 case 'overview': 299 $ jetpack_editor_url = admin_url( 'themes.php?page=editcss' );210 $custom_css_url = admin_url( 'customize.php?autofocus[section]=custom_css' ); 300 211 break; 301 212 -
sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/app/webhook-handler.php
r3192 r4578 5 5 defined( 'WPINC' ) or die(); 6 6 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' ); 7 if ( 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 } 10 12 11 13 /* -
sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/tests/test-synchronize-remote-css.php
r2960 r4578 13 13 $unsanitized_css = file_get_contents( __DIR__ . '/unsanitized.css' ); 14 14 $known_good_sanitized_css = file_get_contents( __DIR__ . '/sanitized.css' ); 15 $maybe_sanitized_css = sanitize_unsafe_css( $unsanitized_css ); 15 16 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 ); 21 18 } 22 19 } -
sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/views/help-overview.php
r2134 r4578 4 4 defined( 'WPINC' ) or die(); 5 5 6 /** 7 * @var string $custom_css_url 8 */ 9 6 10 ?> 7 11 8 12 <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. 10 14 For instance, you can:', 'wordcamporg' ); ?> 11 15 </p> … … 34 38 <p> 35 39 <?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 ) 38 42 ); ?> 39 43 </p> -
sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/views/help-tips.php
r2124 r4578 3 3 namespace WordCamp\RemoteCSS; 4 4 defined( 'WPINC' ) or die(); 5 6 /** 7 * @var string $fonts_tool_url 8 * @var string $media_library_url 9 */ 5 10 6 11 ?> … … 37 42 38 43 <li> 39 <?php _e( "This tool plays nicely with Jetpack's CSSeditor, 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' ); ?> 41 46 </li> 42 47 </ul> -
sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-remote-css/views/page-remote-css.php
r2148 r4578 4 4 defined( 'WPINC' ) or die(); 5 5 6 /** 7 * @var string $notice 8 * @var string $notice_class 9 * @var string $remote_css_url 10 * @var string $output_mode 11 */ 12 6 13 ?> 7 14 8 15 <div class="wrap"> 9 16 <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 <?php14 /*15 * Jetpack_Custom_CSS is used to sanitize the unsafe CSS, and for removing the theme's stylesheet16 * in `replace` mode. Methods from Jetpack_Custom_CSS are called throughout this plugin, so we17 * 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; ?>32 17 33 18 <?php … … 40 25 <?php if ( $notice ) : ?> 41 26 <div id="message" class="notice <?php echo esc_attr( $notice_class ); ?> is-dismissible"> 42 <?php43 /*44 * Typically KSES is discouraged when displaying text because it's expensive, but in this case45 * it's appropriate because the underlying layers need to pass HTML-formatted error messages, and46 * this only only runs when the options are updated.47 */48 ?>49 50 27 <p><?php echo wp_kses( $notice, wp_kses_allowed_html( 'data' ) ); ?></p> 51 28 </div> … … 53 30 54 31 <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 ); ?> 59 37 </p> 60 38 … … 62 40 <?php wp_nonce_field( 'wcrcss-options-submit', 'wcrcss-options-nonce' ); ?> 63 41 64 <fieldset <?php disabled( $jetpack_custom_css_active, false ); ?>>65 42 <p> 66 43 <label> 67 <?php _e( 'Remote CSS File:', 'wordcamporg' ); ?><br />44 <?php _e( 'Remote CSS URL:', 'wordcamporg' ); ?><br /> 68 45 <input type="text" name="wcrcss-remote-css-url" class="large-text" value="<?php echo esc_url( $remote_css_url ); ?>" /> 69 46 </label> … … 91 68 92 69 <?php submit_button( __( 'Update', 'wordcamporg' ) ); ?> 93 </fieldset>94 70 </form> 95 71 </div>
Note: See TracChangeset
for help on using the changeset viewer.