diff options
Diffstat (limited to 'plugins/jetpack/modules/custom-css/custom-css.php')
-rw-r--r-- | plugins/jetpack/modules/custom-css/custom-css.php | 995 |
1 files changed, 637 insertions, 358 deletions
diff --git a/plugins/jetpack/modules/custom-css/custom-css.php b/plugins/jetpack/modules/custom-css/custom-css.php index 179fef4d..6bd2d296 100644 --- a/plugins/jetpack/modules/custom-css/custom-css.php +++ b/plugins/jetpack/modules/custom-css/custom-css.php @@ -1,11 +1,18 @@ -<?php +<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName use Automattic\Jetpack\Assets; -use Automattic\Jetpack\Redirect; use Automattic\Jetpack\Device_Detection\User_Agent_Info; +use Automattic\Jetpack\Redirect; +/** + * Custom CSS class. + */ class Jetpack_Custom_CSS { - static function init() { + + /** + * Initialize the class. + */ + public static function init() { add_action( 'switch_theme', array( __CLASS__, 'reset' ) ); add_action( 'wp_restore_post_revision', array( __CLASS__, 'restore_revision' ), 10, 2 ); @@ -19,8 +26,9 @@ class Jetpack_Custom_CSS { add_action( 'template_redirect', array( __CLASS__, 'set_content_width' ) ); add_action( 'admin_init', array( __CLASS__, 'set_content_width' ) ); - if ( ! is_admin() ) + if ( ! is_admin() ) { add_filter( 'stylesheet_uri', array( __CLASS__, 'style_filter' ) ); + } define( 'SAFECSS_USE_ACE', @@ -28,6 +36,7 @@ class Jetpack_Custom_CSS { ! User_Agent_Info::is_ipad() && /** * Should the Custom CSS module use ACE to process CSS. + * * @see https://ace.c9.io/ * * @module custom-css @@ -41,40 +50,45 @@ class Jetpack_Custom_CSS { // Register safecss as a custom post_type // Explicit capability definitions are largely unnecessary because the posts are manipulated in code via an options page, managing CSS revisions does check the capabilities, so let's ensure that the proper caps are checked. - register_post_type( 'safecss', array( - // These are the defaults - // 'exclude_from_search' => true, - // 'public' => false, - // 'publicly_queryable' => false, - // 'show_ui' => false, - 'supports' => array( 'revisions' ), - 'label' => 'Custom CSS', - 'can_export' => false, - 'rewrite' => false, - 'capabilities' => array( - 'edit_post' => 'edit_theme_options', - 'read_post' => 'read', - 'delete_post' => 'edit_theme_options', - 'edit_posts' => 'edit_theme_options', - 'edit_others_posts' => 'edit_theme_options', - 'publish_posts' => 'edit_theme_options', - 'read_private_posts' => 'read' + register_post_type( + 'safecss', + array( + /** + * These are the defaults + * 'exclude_from_search' => true, + * 'public' => false, + * 'publicly_queryable' => false, + * 'show_ui' => false, + */ + 'supports' => array( 'revisions' ), + 'label' => 'Custom CSS', + 'can_export' => false, + 'rewrite' => false, + 'capabilities' => array( + 'edit_post' => 'edit_theme_options', + 'read_post' => 'read', + 'delete_post' => 'edit_theme_options', + 'edit_posts' => 'edit_theme_options', + 'edit_others_posts' => 'edit_theme_options', + 'publish_posts' => 'edit_theme_options', + 'read_private_posts' => 'read', + ), ) - ) ); + ); // Short-circuit WP if this is a CSS stylesheet request if ( isset( $_GET['custom-css'] ) ) { header( 'Content-Type: text/css', true, 200 ); - header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + 31536000) . ' GMT' ); // 1 year - Jetpack_Custom_CSS::print_css(); + header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + 31536000 ) . ' GMT' ); // 1 year + self::print_css(); exit; } add_action( 'admin_enqueue_scripts', array( 'Jetpack_Custom_CSS', 'enqueue_scripts' ) ); - if ( isset( $_GET['page'] ) && 'editcss' == $_GET['page'] && is_admin() ) { + if ( isset( $_GET['page'] ) && 'editcss' === $_GET['page'] && is_admin() ) { // Do migration routine if necessary - Jetpack_Custom_CSS::upgrade(); + self::upgrade(); /** * Allows additional work when migrating safecss from wp_options to wp_post. @@ -90,6 +104,7 @@ class Jetpack_Custom_CSS { * Never embed the style in the head on wpcom. * Yes, this filter should be added to an unsynced file on wpcom, but * there is no good syntactically-correct location to put it yet. + * * @link https://github.com/Automattic/jetpack/commit/a1be114e9179f64d147124727a58e2cf76c7e5a1#commitcomment-7763921 */ if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) { @@ -103,45 +118,39 @@ class Jetpack_Custom_CSS { add_filter( 'jetpack_content_width', array( 'Jetpack_Custom_CSS', 'jetpack_content_width' ) ); add_filter( 'editor_max_image_size', array( 'Jetpack_Custom_CSS', 'editor_max_image_size' ), 10, 3 ); - if ( !current_user_can( 'switch_themes' ) && !is_super_admin() ) + if ( ! current_user_can( 'switch_themes' ) && ! is_super_admin() ) { return; + } add_action( 'admin_menu', array( 'Jetpack_Custom_CSS', 'menu' ) ); - if ( isset( $_POST['safecss'] ) && false == strstr( $_SERVER[ 'REQUEST_URI' ], 'options.php' ) ) { + if ( isset( $_POST['safecss'] ) && ( ! isset( $_SERVER['REQUEST_URI'] ) || false === strstr( filter_var( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'options.php' ) ) ) { check_admin_referer( 'safecss' ); - $save_result = self::save( array( - 'css' => stripslashes( $_POST['safecss'] ), - 'is_preview' => isset( $_POST['action'] ) && $_POST['action'] == 'preview', - 'preprocessor' => isset( $_POST['custom_css_preprocessor'] ) ? $_POST['custom_css_preprocessor'] : '', - 'add_to_existing' => isset( $_POST['add_to_existing'] ) ? $_POST['add_to_existing'] == 'true' : true, - 'content_width' => isset( $_POST['custom_content_width'] ) ? $_POST['custom_content_width'] : false, - ) ); + $save_result = self::save( + array( + 'css' => filter_var( wp_unslash( $_POST['safecss'] ) ), + 'is_preview' => isset( $_POST['action'] ) && $_POST['action'] === 'preview', + 'preprocessor' => isset( $_POST['custom_css_preprocessor'] ) ? sanitize_key( $_POST['custom_css_preprocessor'] ) : '', + 'add_to_existing' => isset( $_POST['add_to_existing'] ) ? $_POST['add_to_existing'] === 'true' : true, + 'content_width' => isset( $_POST['custom_content_width'] ) ? intval( $_POST['custom_content_width'] ) : false, + ) + ); - if ( $_POST['action'] == 'preview' ) { + if ( $_POST['action'] === 'preview' ) { wp_safe_redirect( add_query_arg( 'csspreview', 'true', get_option( 'home' ) ) ); exit; } - if ( $save_result ) + if ( $save_result ) { add_action( 'admin_notices', array( 'Jetpack_Custom_CSS', 'saved_message' ) ); - } - - // Prevent content filters running on CSS when restoring revisions - if ( isset( $_REQUEST[ 'action' ] ) && 'restore' === $_REQUEST[ 'action' ] && false !== strstr( $_SERVER[ 'REQUEST_URI' ], 'revision.php' ) ) { - $parent_post = get_post( wp_get_post_parent_id( (int) $_REQUEST['revision'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated - if ( $parent_post && ! is_wp_error( $parent_post ) && 'safecss' === $parent_post->post_type ) { - // Remove wp_filter_post_kses, this causes CSS escaping issues - remove_filter( 'content_save_pre', 'wp_filter_post_kses' ); - remove_filter( 'content_filtered_save_pre', 'wp_filter_post_kses' ); - remove_all_filters( 'content_save_pre' ); } } // Modify all internal links so that preview state persists - if ( Jetpack_Custom_CSS::is_preview() ) + if ( self::is_preview() ) { ob_start( array( 'Jetpack_Custom_CSS', 'buffer' ) ); + } } /** @@ -158,11 +167,11 @@ class Jetpack_Custom_CSS { */ public static function save( $args = array() ) { $defaults = array( - 'css' => '', - 'is_preview' => false, - 'preprocessor' => '', + 'css' => '', + 'is_preview' => false, + 'preprocessor' => '', 'add_to_existing' => true, - 'content_width' => false, + 'content_width' => false, ); $args = wp_parse_args( $args, $defaults ); @@ -180,11 +189,6 @@ class Jetpack_Custom_CSS { $args['content_width'] = false; } - // Remove wp_filter_post_kses, this causes CSS escaping issues - remove_filter( 'content_save_pre', 'wp_filter_post_kses' ); - remove_filter( 'content_filtered_save_pre', 'wp_filter_post_kses' ); - remove_all_filters( 'content_save_pre' ); - /** * Fires prior to saving custom css values. Necessitated because the * core WordPress save_pre filters were removed: @@ -197,11 +201,11 @@ class Jetpack_Custom_CSS { * * @param array $args { * Array of custom CSS arguments. - * @type string $css The CSS (or LESS or Sass). - * @type bool $is_preview Whether this CSS is preview or published. - * @type string preprocessor Which CSS preprocessor to use. - * @type bool $add_to_existing Whether this CSS replaces the theme's CSS or supplements it. - * @type int $content_width A custom $content_width to go along with this CSS. + * @type string $css The CSS (or LESS or Sass). + * @type bool $is_preview Whether this CSS is preview or published. + * @type string preprocessor Which CSS preprocessor to use. + * @type bool $add_to_existing Whether this CSS replaces the theme's CSS or supplements it. + * @type int $content_width A custom $content_width to go along with this CSS. * } */ do_action( 'safecss_save_pre', $args ); @@ -209,39 +213,41 @@ class Jetpack_Custom_CSS { $warnings = array(); safecss_class(); - $csstidy = new csstidy(); + $csstidy = new csstidy(); $csstidy->optimise = new safecss( $csstidy ); - $csstidy->set_cfg( 'remove_bslash', false ); - $csstidy->set_cfg( 'compress_colors', false ); - $csstidy->set_cfg( 'compress_font-weight', false ); - $csstidy->set_cfg( 'optimise_shorthands', 0 ); - $csstidy->set_cfg( 'remove_last_;', false ); - $csstidy->set_cfg( 'case_properties', false ); + $csstidy->set_cfg( 'remove_bslash', false ); + $csstidy->set_cfg( 'compress_colors', false ); + $csstidy->set_cfg( 'compress_font-weight', false ); + $csstidy->set_cfg( 'optimise_shorthands', 0 ); + $csstidy->set_cfg( 'remove_last_;', false ); + $csstidy->set_cfg( 'case_properties', false ); $csstidy->set_cfg( 'discard_invalid_properties', true ); - $csstidy->set_cfg( 'css_level', 'CSS3.0' ); - $csstidy->set_cfg( 'preserve_css', true ); - $csstidy->set_cfg( 'template', dirname( __FILE__ ) . '/csstidy/wordpress-standard.tpl' ); - - $css = $orig = $args['css']; + $csstidy->set_cfg( 'css_level', 'CSS3.0' ); + $csstidy->set_cfg( 'preserve_css', true ); + $csstidy->set_cfg( 'template', __DIR__ . '/csstidy/wordpress-standard.tpl' ); - $css = preg_replace( '/\\\\([0-9a-fA-F]{4})/', '\\\\\\\\$1', $prev = $css ); + $prev = $args['css']; + $css = preg_replace( '/\\\\([0-9a-fA-F]{4})/', '\\\\\\\\$1', $prev ); // prevent content: '\3434' from turning into '\\3434' $css = str_replace( array( '\'\\\\', '"\\\\' ), array( '\'\\', '"\\' ), $css ); - if ( $css != $prev ) + if ( $css !== $prev ) { $warnings[] = 'preg_replace found stuff'; + } // Some people put weird stuff in their CSS, KSES tends to be greedy $css = str_replace( '<=', '<=', $css ); // Why KSES instead of strip_tags? Who knows? - $css = wp_kses_split( $prev = $css, array(), array() ); - $css = str_replace( '>', '>', $css ); // kses replaces lone '>' with > + $prev = $css; + $css = wp_kses_split( $prev, array(), array() ); + $css = str_replace( '>', '>', $css ); // kses replaces lone '>' with > // Why both KSES and strip_tags? Because we just added some '>'. - $css = strip_tags( $css ); + $css = strip_tags( $css ); // phpcs:ignore WordPress.WP.AlternativeFunctions.strip_tags_strip_tags - if ( $css != $prev ) + if ( $css !== $prev ) { $warnings[] = 'kses found stuff'; + } // if we're not using a preprocessor if ( ! $args['preprocessor'] ) { @@ -279,14 +285,15 @@ class Jetpack_Custom_CSS { $css = $csstidy->print->plain(); } - if ( $args['add_to_existing'] ) + if ( $args['add_to_existing'] ) { $add_to_existing = 'yes'; - else + } else { $add_to_existing = 'no'; + } - if ( $args['is_preview'] || Jetpack_Custom_CSS::is_freetrial() ) { + if ( $args['is_preview'] || self::is_freetrial() ) { // Save the CSS - $safecss_revision_id = Jetpack_Custom_CSS::save_revision( $css, true, $args['preprocessor'] ); + $safecss_revision_id = self::save_revision( $css, true, $args['preprocessor'] ); // Cache Buster update_option( 'safecss_preview_rev', (int) get_option( 'safecss_preview_rev' ) + 1 ); @@ -313,9 +320,9 @@ class Jetpack_Custom_CSS { } // Save the CSS - $safecss_post_id = Jetpack_Custom_CSS::save_revision( $css, false, $args['preprocessor'] ); + $safecss_post_id = self::save_revision( $css, false, $args['preprocessor'] ); - $safecss_post_revision = Jetpack_Custom_CSS::get_current_revision(); + $safecss_post_revision = self::get_current_revision(); update_option( 'safecss_rev', (int) get_option( 'safecss_rev' ) + 1 ); @@ -340,11 +347,12 @@ class Jetpack_Custom_CSS { * * @return array */ - static function get_post() { - $custom_css_post_id = Jetpack_Custom_CSS::post_id(); + public static function get_post() { + $custom_css_post_id = self::post_id(); - if ( $custom_css_post_id ) + if ( $custom_css_post_id ) { return get_post( $custom_css_post_id, ARRAY_A ); + } return array(); } @@ -354,7 +362,7 @@ class Jetpack_Custom_CSS { * * @return int|bool The post ID if it exists; false otherwise. */ - static function post_id() { + public static function post_id() { /** * Filter the ID of the post where Custom CSS is stored, before the ID is retrieved. * @@ -368,32 +376,36 @@ class Jetpack_Custom_CSS { * @param null null The ID to return instead of the normal ID. */ $custom_css_post_id = apply_filters( 'jetpack_custom_css_pre_post_id', null ); - if ( ! is_null( $custom_css_post_id ) ) { + if ( $custom_css_post_id !== null ) { return $custom_css_post_id; } $custom_css_post_id = wp_cache_get( 'custom_css_post_id' ); if ( false === $custom_css_post_id ) { - $custom_css_posts = get_posts( array( - 'posts_per_page' => 1, - 'post_type' => 'safecss', - 'post_status' => 'publish', - 'orderby' => 'date', - 'order' => 'DESC' - ) ); + $custom_css_posts = get_posts( + array( + 'posts_per_page' => 1, + 'post_type' => 'safecss', + 'post_status' => 'publish', + 'orderby' => 'date', + 'order' => 'DESC', + ) + ); - if ( count( $custom_css_posts ) > 0 ) + if ( count( $custom_css_posts ) > 0 ) { $custom_css_post_id = $custom_css_posts[0]->ID; - else + } else { $custom_css_post_id = 0; + } // Save post_id=0 to note that no safecss post exists. wp_cache_set( 'custom_css_post_id', $custom_css_post_id ); } - if ( ! $custom_css_post_id ) + if ( ! $custom_css_post_id ) { return false; + } return $custom_css_post_id; } @@ -403,14 +415,21 @@ class Jetpack_Custom_CSS { * * @return object */ - static function get_current_revision() { - $safecss_post = Jetpack_Custom_CSS::get_post(); + public static function get_current_revision() { + $safecss_post = self::get_post(); if ( empty( $safecss_post ) ) { return false; } - $revisions = wp_get_post_revisions( $safecss_post['ID'], array( 'posts_per_page' => 1, 'orderby' => 'date', 'order' => 'DESC' ) ); + $revisions = wp_get_post_revisions( + $safecss_post['ID'], + array( + 'posts_per_page' => 1, + 'orderby' => 'date', + 'order' => 'DESC', + ) + ); // Empty array if no revisions exist if ( empty( $revisions ) ) { @@ -427,45 +446,50 @@ class Jetpack_Custom_CSS { * Save new revision of CSS * Checks to see if content was modified before really saving * - * @param string $css - * @param bool $is_preview + * @param string $css - the CSS. + * @param bool $is_preview - if we're in preview mode. + * @param string $preprocessor - what preprocessor we're using. + * * @return bool|int If nothing was saved, returns false. If a post * or revision was saved, returns the post ID. */ - static function save_revision( $css, $is_preview = false, $preprocessor = '' ) { - $safecss_post = Jetpack_Custom_CSS::get_post(); + public static function save_revision( $css, $is_preview = false, $preprocessor = '' ) { + $safecss_post = self::get_post(); - $compressed_css = Jetpack_Custom_CSS::minify( $css, $preprocessor ); + $compressed_css = self::minify( $css, $preprocessor ); // If null, there was no original safecss record, so create one - if ( null == $safecss_post ) { - if ( ! $css ) + if ( ! $safecss_post ) { + if ( ! $css ) { return false; + } - $post = array(); - $post['post_content'] = wp_slash( $css ); - $post['post_title'] = 'safecss'; - $post['post_status'] = 'publish'; - $post['post_type'] = 'safecss'; + $post = array(); + $post['post_content'] = wp_slash( $css ); + $post['post_title'] = 'safecss'; + $post['post_status'] = 'publish'; + $post['post_type'] = 'safecss'; $post['post_content_filtered'] = wp_slash( $compressed_css ); // Set excerpt to current theme, for display in revisions list - $current_theme = wp_get_theme(); - $post['post_excerpt'] = $current_theme->Name; + $current_theme = wp_get_theme(); + $post['post_excerpt'] = $current_theme->Name; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase + add_filter( 'wp_insert_post_data', array( __CLASS__, 'restore_unsafe_postcss_content' ), 9, 3 ); // Insert the CSS into wp_posts $post_id = wp_insert_post( $post ); + remove_filter( 'wp_insert_post_data', array( __CLASS__, 'restore_unsafe_postcss_content' ), 9 ); wp_cache_set( 'custom_css_post_id', $post_id ); return $post_id; } // Update CSS in post array with new value passed to this function - $safecss_post['post_content'] = $css; + $safecss_post['post_content'] = $css; $safecss_post['post_content_filtered'] = $compressed_css; // Set excerpt to current theme, for display in revisions list - $current_theme = wp_get_theme(); - $safecss_post['post_excerpt'] = $current_theme->Name; + $current_theme = wp_get_theme(); + $safecss_post['post_excerpt'] = $current_theme->Name; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase // Don't carry over last revision's timestamps, otherwise revisions all have matching timestamps unset( $safecss_post['post_date'] ); @@ -475,18 +499,54 @@ class Jetpack_Custom_CSS { // Do not update post if we are only saving a preview if ( false === $is_preview ) { - $safecss_post['post_content'] = wp_slash( $safecss_post['post_content'] ); + $safecss_post['post_content'] = wp_slash( $safecss_post['post_content'] ); $safecss_post['post_content_filtered'] = wp_slash( $safecss_post['post_content_filtered'] ); + add_filter( 'wp_insert_post_data', array( __CLASS__, 'restore_unsafe_postcss_content' ), 9, 3 ); $post_id = wp_update_post( $safecss_post ); + remove_filter( 'wp_insert_post_data', array( __CLASS__, 'restore_unsafe_postcss_content' ), 9 ); wp_cache_set( 'custom_css_post_id', $post_id ); return $post_id; + } elseif ( ! defined( 'DOING_MIGRATE' ) ) { + add_filter( 'wp_insert_post_data', array( __CLASS__, 'restore_unsafe_postcss_content' ), 9, 3 ); + $revision = _wp_put_post_revision( $safecss_post ); + remove_filter( 'wp_insert_post_data', array( __CLASS__, 'restore_unsafe_postcss_content' ), 9 ); + return $revision; } - else if ( ! defined( 'DOING_MIGRATE' ) ) { - return _wp_put_post_revision( $safecss_post ); + } + + /** + * Restore Unsafe Post CSS Content. + * + * @param array $data The post data being filtered. + * @param array $postarray Unused. + * @param array $unsanitized The unsanitized post data. + * + * @return array Post data. + */ + public static function restore_unsafe_postcss_content( $data, $postarray, $unsanitized ) { + $replace_content = + isset( $data['post_type'] ) && + isset( $unsanitized['post_content'] ) && + ( + 'safecss' === $data['post_type'] || + ( + 'revision' === $data['post_type'] && + ! empty( $data['post_parent'] ) && + 'safecss' === get_post_type( $data['post_parent'] ) + ) + ); + if ( $replace_content ) { + $data['post_content'] = $unsanitized['post_content']; } + return $data; } - static function skip_stylesheet() { + /** + * Prevent the stylesheet from being enqued. + * + * @return bool + */ + public static function skip_stylesheet() { /** * Prevent the Custom CSS stylesheet from being enqueued. * @@ -500,19 +560,19 @@ class Jetpack_Custom_CSS { if ( null !== $skip_stylesheet ) { return $skip_stylesheet; - } elseif ( Jetpack_Custom_CSS::is_customizer_preview() ) { + } elseif ( self::is_customizer_preview() ) { return false; } else { - if ( Jetpack_Custom_CSS::is_preview() ) { - $safecss_post = Jetpack_Custom_CSS::get_current_revision(); + if ( self::is_preview() ) { + $safecss_post = self::get_current_revision(); - if ( $safecss_post ) - return (bool) ( get_post_meta( $safecss_post['ID'], 'custom_css_add', true ) == 'no' ); - else - return (bool) ( get_option( 'safecss_preview_add' ) == 'no' ); - } - else { - $custom_css_post_id = Jetpack_Custom_CSS::post_id(); + if ( $safecss_post ) { + return (bool) ( get_post_meta( $safecss_post['ID'], 'custom_css_add', true ) === 'no' ); + } else { + return (bool) ( get_option( 'safecss_preview_add' ) === 'no' ); + } + } else { + $custom_css_post_id = self::post_id(); if ( $custom_css_post_id ) { $custom_css_add = get_post_meta( $custom_css_post_id, 'custom_css_add', true ); @@ -520,17 +580,23 @@ class Jetpack_Custom_CSS { // It is possible for the CSS to be stored in a post but for the safecss_add option // to have not been upgraded yet if the user hasn't opened their Custom CSS editor // since October 2012. - if ( ! empty( $custom_css_add ) ) + if ( ! empty( $custom_css_add ) ) { return (bool) ( $custom_css_add === 'no' ); + } } - return (bool) ( Jetpack_Options::get_option_and_ensure_autoload( 'safecss_add', '' ) == 'no' ); + return (bool) ( Jetpack_Options::get_option_and_ensure_autoload( 'safecss_add', '' ) === 'no' ); } } } - static function is_preview() { - return isset( $_GET['csspreview'] ) && $_GET['csspreview'] === 'true'; + /** + * Checks if we're in a preview mode. + * + * @return bool + */ + public static function is_preview() { + return isset( $_GET['csspreview'] ) && $_GET['csspreview'] === 'true'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- no changes made to the site. } /** @@ -538,20 +604,23 @@ class Jetpack_Custom_CSS { * 'template_redirect' action and * 'admin_init' action */ - static function set_content_width(){ + public static function set_content_width() { // Don't apply this filter on the Edit CSS page - if ( isset( $_GET ) && isset( $_GET['page'] ) && 'editcss' == $_GET['page'] && is_admin() ) { + if ( isset( $_GET ) && isset( $_GET['page'] ) && 'editcss' === $_GET['page'] && is_admin() ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nothing changing on the site, it's not applying a filter if set. return; } $GLOBALS['content_width'] = Jetpack::get_content_width(); } - /* + /** * False when the site has the Custom Design upgrade. * Used only on WordPress.com. + * + * @return bool + * @todo see if we can remove this, I don't believe WordPress.com uses free trials anymore. */ - static function is_freetrial() { + public static function is_freetrial() { /** * Determine if a WordPress.com site uses a Free trial of the Custom Design Upgrade. * Used only on WordPress.com. @@ -565,20 +634,37 @@ class Jetpack_Custom_CSS { return apply_filters( 'safecss_is_freetrial', false ); } - static function get_preprocessor_key() { - $safecss_post = Jetpack_Custom_CSS::get_current_revision(); + /** + * Get the preprocessor key. + * + * @return string|false + */ + public static function get_preprocessor_key() { + $safecss_post = self::get_current_revision(); return get_post_meta( $safecss_post['ID'], 'custom_css_preprocessor', true ); } - static function get_preprocessor() { + /** + * Get the prepocessor. + * + * @return string|null + */ + public static function get_preprocessor() { /** This filter is documented in modules/custom-css/custom-css.php */ - $preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() ); + $preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() ); $selected_preprocessor_key = self::get_preprocessor_key(); - $selected_preprocessor = isset( $preprocessors[ $selected_preprocessor_key ] ) ? $preprocessors[ $selected_preprocessor_key ] : null; + $selected_preprocessor = isset( $preprocessors[ $selected_preprocessor_key ] ) ? $preprocessors[ $selected_preprocessor_key ] : null; return $selected_preprocessor; } - static function get_css( $compressed = false ) { + /** + * Get the CSS. + * + * @param boolean $compressed - if the CSS is compressed. + * + * @return string + */ + public static function get_css( $compressed = false ) { /** * Filter the Custom CSS returned. * Can be used to return an error, or no CSS at all. @@ -591,21 +677,22 @@ class Jetpack_Custom_CSS { */ $default_css = apply_filters( 'safecss_get_css_error', false ); - if ( $default_css !== false ) + if ( $default_css !== false ) { return $default_css; + } - $option = ( Jetpack_Custom_CSS::is_preview() || Jetpack_Custom_CSS::is_freetrial() ) ? 'safecss_preview' : 'safecss'; - $css = ''; + $option = ( self::is_preview() || self::is_freetrial() ) ? 'safecss_preview' : 'safecss'; + $css = ''; - if ( 'safecss' == $option ) { + if ( 'safecss' === $option ) { // Don't bother checking for a migrated 'safecss' option if it never existed. if ( false === get_option( 'safecss' ) || get_option( 'safecss_revision_migrated' ) ) { - $safecss_post = Jetpack_Custom_CSS::get_post(); + $safecss_post = self::get_post(); if ( ! empty( $safecss_post ) ) { $css = ( $compressed && $safecss_post['post_content_filtered'] ) ? $safecss_post['post_content_filtered'] : $safecss_post['post_content']; } } else { - $current_revision = Jetpack_Custom_CSS::get_current_revision(); + $current_revision = self::get_current_revision(); if ( false === $current_revision ) { $css = ''; } else { @@ -616,15 +703,14 @@ class Jetpack_Custom_CSS { // Fix for un-migrated Custom CSS if ( empty( $safecss_post ) ) { $_css = get_option( 'safecss' ); - if ( !empty( $_css ) ) { + if ( ! empty( $_css ) ) { $css = $_css; } } - } - else if ( 'safecss_preview' == $option ) { - $safecss_post = Jetpack_Custom_CSS::get_current_revision(); - $css = $safecss_post['post_content']; - $css = Jetpack_Custom_CSS::minify( $css, get_post_meta( $safecss_post['ID'], 'custom_css_preprocessor', true ) ); + } elseif ( 'safecss_preview' === $option ) { + $safecss_post = self::get_current_revision(); + $css = $safecss_post['post_content']; + $css = self::minify( $css, get_post_meta( $safecss_post['ID'], 'custom_css_preprocessor', true ) ); } $css = str_replace( array( '\\\00BB \\\0020', '\0BB \020', '0BB 020' ), '\00BB \0020', $css ); @@ -643,7 +729,14 @@ class Jetpack_Custom_CSS { return $css; } - static function replace_insecure_urls( $css ) { + /** + * Replace insecure URLs. + * + * @param string $css - the CSS. + * + * @return string + */ + public static function replace_insecure_urls( $css ) { if ( ! function_exists( '_sa_get_frontend_https_url_replacement_map' ) ) { return $css; } @@ -652,7 +745,10 @@ class Jetpack_Custom_CSS { return str_replace( $http_urls, $secure_urls, $css ); } - static function print_css() { + /** + * Print the CSS. + */ + public static function print_css() { /** * Fires right before printing the custom CSS inside the <head> element. @@ -662,16 +758,26 @@ class Jetpack_Custom_CSS { * @since 1.7.0 */ do_action( 'safecss_print_pre' ); - $css = Jetpack_Custom_CSS::get_css( true ); - echo self::replace_insecure_urls( $css ); + $css = self::get_css( true ); + echo self::replace_insecure_urls( $css ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } - static function should_we_inline_custom_css( $should_we, $css ) { - // If the CSS is less than 2,000 characters, inline it! otherwise return what was passed in. + /** + * If the CSS is less than 2,000 characters, inline it! otherwise return what was passed in. + * + * @param bool $should_we if we should inline the CSS. + * @param string $css - the CSS object. + * + * @return bool + */ + public static function should_we_inline_custom_css( $should_we, $css ) { return ( strlen( $css ) < 2000 ) ? true : $should_we; } - static function link_tag() { + /** + * Add the link tag to inline CSS. + */ + public static function link_tag() { global $blog_id, $current_blog; if ( @@ -690,24 +796,26 @@ class Jetpack_Custom_CSS { return; } - if ( ! is_super_admin() && isset( $current_blog ) && ( 1 == $current_blog->spam || 1 == $current_blog->deleted ) ) + if ( ! is_super_admin() && isset( $current_blog ) && ( $current_blog->spam || $current_blog->deleted ) ) { return; + } - if ( Jetpack_Custom_CSS::is_customizer_preview() ) + if ( self::is_customizer_preview() ) { return; + } $css = ''; - $option = Jetpack_Custom_CSS::is_preview() ? 'safecss_preview' : 'safecss'; + $option = self::is_preview() ? 'safecss_preview' : 'safecss'; - if ( 'safecss' == $option ) { + if ( 'safecss' === $option ) { if ( Jetpack_Options::get_option_and_ensure_autoload( 'safecss_revision_migrated', '0' ) ) { - $safecss_post = Jetpack_Custom_CSS::get_post(); + $safecss_post = self::get_post(); if ( ! empty( $safecss_post['post_content'] ) ) { $css = $safecss_post['post_content']; } } else { - $current_revision = Jetpack_Custom_CSS::get_current_revision(); + $current_revision = self::get_current_revision(); if ( ! empty( $current_revision['post_content'] ) ) { $css = $current_revision['post_content']; @@ -717,24 +825,25 @@ class Jetpack_Custom_CSS { // Fix for un-migrated Custom CSS if ( empty( $safecss_post ) ) { $_css = Jetpack_Options::get_option_and_ensure_autoload( 'safecss', '' ); - if ( !empty( $_css ) ) { + if ( ! empty( $_css ) ) { $css = $_css; } } } - if ( 'safecss_preview' == $option ) { - $safecss_post = Jetpack_Custom_CSS::get_current_revision(); + if ( 'safecss_preview' === $option ) { + $safecss_post = self::get_current_revision(); - if ( !empty( $safecss_post['post_content'] ) ) { + if ( ! empty( $safecss_post['post_content'] ) ) { $css = $safecss_post['post_content']; } } $css = str_replace( array( '\\\00BB \\\0020', '\0BB \020', '0BB 020' ), '\00BB \0020', $css ); - if ( $css == '' ) + if ( $css === '' ) { return; + } if ( /** @@ -750,7 +859,7 @@ class Jetpack_Custom_CSS { apply_filters( 'safecss_embed_style', false, $css ) ) { - echo "\r\n" . '<style id="custom-css-css">' . Jetpack_Custom_CSS::get_css( true ) . "</style>\r\n"; + echo "\r\n" . '<style id="custom-css-css">' . self::get_css( true ) . "</style>\r\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } else { @@ -772,11 +881,12 @@ class Jetpack_Custom_CSS { */ $href = apply_filters( 'safecss_href', $href, $blog_id ); - if ( Jetpack_Custom_CSS::is_preview() ) + if ( self::is_preview() ) { $href = add_query_arg( 'csspreview', 'true', $href ); + } ?> - <link rel="stylesheet" id="custom-css-css" type="text/css" href="<?php echo esc_url( $href ); ?>" /> + <link rel="stylesheet" id="custom-css-css" type="text/css" href="<?php echo esc_url( $href ); // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet ?>" /> <?php } @@ -791,10 +901,17 @@ class Jetpack_Custom_CSS { do_action( 'safecss_link_tag_post' ); } - static function style_filter( $current ) { - if ( Jetpack_Custom_CSS::is_freetrial() && ( ! Jetpack_Custom_CSS::is_preview() || ! current_user_can( 'switch_themes' ) ) ) + /** + * Filter the default blank Custom CSS URL. + * + * @param string $current - the current CSS. + * + * @return string + */ + public static function style_filter( $current ) { + if ( self::is_freetrial() && ( ! self::is_preview() || ! current_user_can( 'switch_themes' ) ) ) { return $current; - else if ( Jetpack_Custom_CSS::skip_stylesheet() ) + } elseif ( self::skip_stylesheet() ) { /** * Filter the default blank Custom CSS URL. * @@ -805,18 +922,34 @@ class Jetpack_Custom_CSS { * @param string $url Default blank Custom CSS URL. */ return apply_filters( 'safecss_style_filter_url', plugins_url( 'custom-css/css/blank.css', __FILE__ ) ); + } return $current; } - static function buffer( $html ) { - $html = str_replace( '</body>', Jetpack_Custom_CSS::preview_flag(), $html ); + /** + * Buffer the HTML. + * + * @param string $html - the HTML. + * + * @return string + */ + public static function buffer( $html ) { + $html = str_replace( '</body>', self::preview_flag(), $html ); return preg_replace_callback( '!href=([\'"])(.*?)\\1!', array( 'Jetpack_Custom_CSS', 'preview_links' ), $html ); } - static function preview_links( $matches ) { - if ( 0 !== strpos( $matches[2], get_option( 'home' ) ) ) + /** + * Preview links. + * + * @param array $matches - the matches. + * + * @return string + */ + public static function preview_links( $matches ) { + if ( 0 !== strpos( $matches[2], get_option( 'home' ) ) ) { return $matches[0]; + } $link = wp_specialchars_decode( $matches[2] ); $link = add_query_arg( 'csspreview', 'true', $link ); @@ -827,9 +960,10 @@ class Jetpack_Custom_CSS { /** * Places a black bar above every preview page */ - static function preview_flag() { - if ( is_admin() ) + public static function preview_flag() { + if ( is_admin() ) { return; + } $message = esc_html__( 'Preview: changes must be saved or they will be lost', 'jetpack' ); /** @@ -844,7 +978,7 @@ class Jetpack_Custom_CSS { $message = apply_filters( 'safecss_preview_message', $message ); $preview_flag_js = "var flag = document.createElement('div'); - flag.innerHTML = " . json_encode( $message ) . "; + flag.innerHTML = " . wp_json_encode( $message ) . "; flag.style.background = '#FF6600'; flag.style.color = 'white'; flag.style.textAlign = 'center'; @@ -876,12 +1010,14 @@ class Jetpack_Custom_CSS { return $preview_flag_js; } - static function menu() { - $parent = 'themes.php'; - $title = __( 'Additional CSS', 'jetpack' ); - $hook = add_theme_page( $title, $title, 'edit_theme_options', 'editcss', array( 'Jetpack_Custom_CSS', 'admin' ) ); + /** + * Add the additional CSS menu. + */ + public static function menu() { + $title = __( 'Additional CSS', 'jetpack' ); + $hook = add_theme_page( $title, $title, 'edit_theme_options', 'editcss', array( 'Jetpack_Custom_CSS', 'admin' ) ); - add_action( "load-revision.php", array( 'Jetpack_Custom_CSS', 'prettify_post_revisions' ) ); + add_action( 'load-revision.php', array( 'Jetpack_Custom_CSS', 'prettify_post_revisions' ) ); add_action( "load-$hook", array( 'Jetpack_Custom_CSS', 'update_title' ) ); } @@ -889,34 +1025,53 @@ class Jetpack_Custom_CSS { * Adds a menu item in the appearance section for this plugin's administration * page. Also adds hooks to enqueue the CSS and JS for the admin page. */ - static function update_title() { + public static function update_title() { global $title; - $title = __( 'CSS', 'jetpack' ); + $title = __( 'CSS', 'jetpack' ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited } - static function prettify_post_revisions() { + /** + * Prettify the post revision. + */ + public static function prettify_post_revisions() { add_filter( 'the_title', array( 'Jetpack_Custom_CSS', 'post_title' ), 10, 2 ); } - static function post_title( $title, $post_id ) { - if ( !$post_id = (int) $post_id ) { + /** + * Get the post title. + * + * @param string $title - the post title. + * @param int $post_id - the post ID. + * + * @return string + */ + public static function post_title( $title, $post_id ) { + $post_id = (int) $post_id; + if ( ! $post_id ) { return $title; } - if ( !$post = get_post( $post_id ) ) { + $post = get_post( $post_id ); + if ( ! $post ) { return $title; } - if ( 'safecss' != $post->post_type ) { + if ( 'safecss' !== $post->post_type ) { return $title; } return __( 'Custom CSS Stylesheet', 'jetpack' ); } - static function enqueue_scripts( $hook ) { - if ( 'appearance_page_editcss' != $hook ) + /** + * Enqueue scripts. + * + * @param string $hook - the hook. + */ + public static function enqueue_scripts( $hook ) { + if ( 'appearance_page_editcss' !== $hook ) { return; + } wp_enqueue_script( 'postbox' ); wp_enqueue_script( @@ -929,7 +1084,7 @@ class Jetpack_Custom_CSS { '20130325', true ); - wp_enqueue_style( 'custom-css-editor', plugins_url( 'custom-css/css/css-editor.css', __FILE__ ) ); + wp_enqueue_style( 'custom-css-editor', plugins_url( 'custom-css/css/css-editor.css', __FILE__ ) ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion if ( defined( 'SAFECSS_USE_ACE' ) && SAFECSS_USE_ACE ) { wp_register_style( 'jetpack-css-codemirror', plugins_url( 'custom-css/css/codemirror.css', __FILE__ ), array(), '20120905' ); @@ -949,18 +1104,25 @@ class Jetpack_Custom_CSS { } } - static function saved_message() { - echo '<div id="message" class="updated fade"><p><strong>' . __( 'Stylesheet saved.', 'jetpack' ) . '</strong></p></div>'; + /** + * Render the saved message. + */ + public static function saved_message() { + echo '<div id="message" class="updated fade"><p><strong>' . esc_html__( 'Stylesheet saved.', 'jetpack' ) . '</strong></p></div>'; } - static function admin() { + /** + * Render the admin page. + */ + public static function admin() { add_meta_box( 'submitdiv', __( 'Publish', 'jetpack' ), array( __CLASS__, 'publish_box' ), 'editcss', 'side' ); add_action( 'custom_css_submitbox_misc_actions', array( __CLASS__, 'content_width_settings' ) ); - $safecss_post = Jetpack_Custom_CSS::get_post(); + $safecss_post = self::get_post(); - if ( ! empty( $safecss_post ) && 0 < $safecss_post['ID'] && wp_get_post_revisions( $safecss_post['ID'], array( 'posts_per_page' => 1 ) ) ) + if ( ! empty( $safecss_post ) && 0 < $safecss_post['ID'] && wp_get_post_revisions( $safecss_post['ID'], array( 'posts_per_page' => 1 ) ) ) { add_meta_box( 'revisionsdiv', __( 'CSS Revisions', 'jetpack' ), array( __CLASS__, 'revisions_meta_box' ), 'editcss', 'side' ); + } ?> <div class="wrap"> <?php @@ -975,9 +1137,9 @@ class Jetpack_Custom_CSS { do_action( 'custom_design_header' ); ?> - <h1><?php _e( 'CSS Stylesheet Editor', 'jetpack' ); ?></h1> + <h1><?php esc_html_e( 'CSS Stylesheet Editor', 'jetpack' ); ?></h1> <form id="safecssform" action="" method="post"> - <?php wp_nonce_field( 'safecss' ) ?> + <?php wp_nonce_field( 'safecss' ); ?> <?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?> <?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?> <input type="hidden" name="action" value="save" /> @@ -993,15 +1155,28 @@ class Jetpack_Custom_CSS { * * @param string $str Intro text appearing above the Custom CSS editor. */ - echo apply_filters( 'safecss_intro_text', __( 'New to CSS? Start with a <a href="https://www.htmldog.com/guides/css/beginner/" rel="noopener noreferrer" target="_blank">beginner tutorial</a>. Questions? - Ask in the <a href="https://wordpress.org/support/forum/themes-and-templates" rel="noopener noreferrer" target="_blank">Themes and Templates forum</a>.', 'jetpack' ) ); - ?></p> - <p class="css-support"><?php echo __( 'Note: Custom CSS will be reset when changing themes.', 'jetpack' ); ?></p> + echo apply_filters( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + 'safecss_intro_text', + __( + 'New to CSS? Start with a <a href="https://www.htmldog.com/guides/css/beginner/" rel="noopener noreferrer" target="_blank">beginner tutorial</a>. Questions? + Ask in the <a href="https://wordpress.org/support/forum/themes-and-templates" rel="noopener noreferrer" target="_blank">Themes and Templates forum</a>.', + 'jetpack' + ) + ); + ?> + </p> + <p class="css-support"><?php echo esc_html__( 'Note: Custom CSS will be reset when changing themes.', 'jetpack' ); ?></p> <div id="post-body" class="metabox-holder columns-2"> <div id="post-body-content"> <div class="postarea"> - <textarea id="safecss" name="safecss"<?php if ( SAFECSS_USE_ACE ) echo ' class="hide-if-js"'; ?>><?php echo esc_textarea( Jetpack_Custom_CSS::get_css() ); ?></textarea> + <textarea id="safecss" name="safecss" + <?php + if ( SAFECSS_USE_ACE ) { + echo ' class="hide-if-js"'; + } + ?> + ><?php echo esc_textarea( self::get_css() ); ?></textarea> <div class="clear"></div> </div> </div> @@ -1019,22 +1194,34 @@ class Jetpack_Custom_CSS { /** * Content width setting callback */ - static function content_width_settings() { - $safecss_post = Jetpack_Custom_CSS::get_current_revision(); + public static function content_width_settings() { + $safecss_post = self::get_current_revision(); $custom_content_width = get_post_meta( $safecss_post['ID'], 'content_width', true ); // If custom content width hasn't been overridden and the theme has a content_width value, use that as a default. - if ( $custom_content_width <= 0 && ! empty( $GLOBALS['content_width'] ) ) + if ( $custom_content_width <= 0 && ! empty( $GLOBALS['content_width'] ) ) { $custom_content_width = $GLOBALS['content_width']; + } - if ( ! $custom_content_width || ( isset( $GLOBALS['content_width'] ) && $custom_content_width == $GLOBALS['content_width'] ) ) + if ( ! $custom_content_width || ( isset( $GLOBALS['content_width'] ) && $custom_content_width == $GLOBALS['content_width'] ) ) { // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual $custom_content_width = ''; + } ?> <div class="misc-pub-section"> <label><?php esc_html_e( 'Media Width:', 'jetpack' ); ?></label> - <span id="content-width-display" data-default-text="<?php esc_attr_e( 'Default', 'jetpack' ); ?>" data-custom-text="<?php esc_attr_e( '%s px', 'jetpack' ); ?>"><?php echo $custom_content_width ? sprintf( esc_html__( '%s px', 'jetpack' ), $custom_content_width ) : esc_html_e( 'Default', 'jetpack' ); ?></span> + <span id="content-width-display" data-default-text="<?php esc_attr_e( 'Default', 'jetpack' ); ?>" data-custom-text=" + <?php + // translators: the custom content width. + esc_attr_e( '%s px', 'jetpack' ); + ?> + "> + <?php + // translators: the custom content width. + echo esc_html( $custom_content_width ? sprintf( __( '%s px', 'jetpack' ), $custom_content_width ) : __( 'Default', 'jetpack' ) ); + ?> + </span> <a class="edit-content-width hide-if-no-js" href="#content-width"><?php echo esc_html_e( 'Edit', 'jetpack' ); ?></a> <div id="content-width-select" class="hide-if-js"> <input type="hidden" name="custom_content_width" id="custom_content_width" value="<?php echo esc_attr( $custom_content_width ); ?>" /> @@ -1042,7 +1229,7 @@ class Jetpack_Custom_CSS { <?php printf( /* translators: %1$s is replaced with an input field for numbers. */ - __( 'Limit width to %1$s pixels for full size images. (<a href="%2$s" rel="noopener noreferrer" target="_blank">More info</a>.)', 'jetpack' ), + wp_kses_post( __( 'Limit width to %1$s pixels for full size images. (<a href="%2$s" rel="noopener noreferrer" target="_blank">More info</a>.)', 'jetpack' ) ), '<input type="text" id="custom_content_width_visible" value="' . esc_attr( $custom_content_width ) . '" size="4" />', /** * Filter the Custom CSS limited width's support doc URL. @@ -1064,7 +1251,7 @@ class Jetpack_Custom_CSS { if ( ! empty( $GLOBALS['content_width'] ) - && $custom_content_width != $GLOBALS['content_width'] + && $custom_content_width != $GLOBALS['content_width'] // phpcs:ignore Universal.Operators.StrictComparisons.LooseNotEqual ) { $current_theme = wp_get_theme()->Name; @@ -1095,7 +1282,7 @@ class Jetpack_Custom_CSS { </div> <script type="text/javascript"> jQuery( function ( $ ) { - var defaultContentWidth = <?php echo isset( $GLOBALS['content_width'] ) ? json_encode( (int) $GLOBALS['content_width'] ) : 0; ?>; + var defaultContentWidth = <?php echo isset( $GLOBALS['content_width'] ) ? wp_json_encode( (int) $GLOBALS['content_width'] ) : 0; ?>; $( '.edit-content-width' ).bind( 'click', function ( e ) { e.preventDefault(); @@ -1140,7 +1327,10 @@ class Jetpack_Custom_CSS { <?php } - static function publish_box() { + /** + * Render the publish box. + */ + public static function publish_box() { ?> <div id="minor-publishing"> <div id="misc-publishing-actions"> @@ -1158,9 +1348,9 @@ class Jetpack_Custom_CSS { $preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() ); if ( ! empty( $preprocessors ) ) { - $safecss_post = Jetpack_Custom_CSS::get_current_revision(); + $safecss_post = self::get_current_revision(); $selected_preprocessor_key = get_post_meta( $safecss_post['ID'], 'custom_css_preprocessor', true ); - $selected_preprocessor = isset( $preprocessors[$selected_preprocessor_key] ) ? $preprocessors[$selected_preprocessor_key] : null; + $selected_preprocessor = isset( $preprocessors[ $selected_preprocessor_key ] ) ? $preprocessors[ $selected_preprocessor_key ] : null; ?> <div class="misc-pub-section"> @@ -1174,7 +1364,7 @@ class Jetpack_Custom_CSS { <?php foreach ( $preprocessors as $preprocessor_key => $preprocessor ) { - ?> + ?> <option value="<?php echo esc_attr( $preprocessor_key ); ?>" <?php selected( $selected_preprocessor_key, $preprocessor_key ); ?>><?php echo esc_html( $preprocessor['name'] ); ?></option> <?php } @@ -1188,9 +1378,9 @@ class Jetpack_Custom_CSS { <?php } - $safecss_post = Jetpack_Custom_CSS::get_current_revision(); + $safecss_post = self::get_current_revision(); - $add_css = ( get_post_meta( $safecss_post['ID'], 'custom_css_add', true ) != 'no' ); + $add_css = ( get_post_meta( $safecss_post['ID'], 'custom_css_add', true ) !== 'no' ); ?> <div class="misc-pub-section"> @@ -1202,13 +1392,15 @@ class Jetpack_Custom_CSS { <p> <label> <input type="radio" name="add_to_existing_display" value="true" <?php checked( $add_css ); ?>/> - <?php _e( 'Add-on CSS <b>(Recommended)</b>', 'jetpack' ); ?> + <?php echo wp_kses( __( 'Add-on CSS <b>(Recommended)</b>', 'jetpack' ), array( 'b' => array() ) ); ?> </label> <br /> <label> <input type="radio" name="add_to_existing_display" value="false" <?php checked( ! $add_css ); ?>/> - <?php printf( - __( 'Replace <a href="%s">theme\'s CSS</a> <b>(Advanced)</b>', 'jetpack' ), + <?php + printf( + // translators: the theme's stylesheet URL. + wp_kses_post( __( 'Replace <a href="%s">theme\'s CSS</a> <b>(Advanced)</b>', 'jetpack' ) ), /** * Filter the theme's stylesheet URL. * @@ -1218,8 +1410,9 @@ class Jetpack_Custom_CSS { * * @param string $url Active theme's stylesheet URL. Default to get_stylesheet_uri(). */ - apply_filters( 'safecss_theme_stylesheet_url', get_stylesheet_uri() ) - ); ?> + esc_url( apply_filters( 'safecss_theme_stylesheet_url', get_stylesheet_uri() ) ) + ); + ?> </label> </p> <a class="save-css-mode hide-if-no-js button" href="#css-mode"><?php esc_html_e( 'OK', 'jetpack' ); ?></a> @@ -1241,9 +1434,9 @@ class Jetpack_Custom_CSS { </div> </div> <div id="major-publishing-actions"> - <input type="button" class="button" id="preview" name="preview" value="<?php esc_attr_e( 'Preview', 'jetpack' ) ?>" /> + <input type="button" class="button" id="preview" name="preview" value="<?php esc_attr_e( 'Preview', 'jetpack' ); ?>" /> <div id="publishing-action"> - <input type="submit" class="button-primary" id="save" name="save" value="<?php ( Jetpack_Custom_CSS::is_freetrial() ) ? esc_attr_e( 'Save & Buy Upgrade', 'jetpack' ) : esc_attr_e( 'Save Stylesheet', 'jetpack' ); ?>" /> + <input type="submit" class="button-primary" id="save" name="save" value="<?php ( self::is_freetrial() ) ? esc_attr_e( 'Save & Buy Upgrade', 'jetpack' ) : esc_attr_e( 'Save Stylesheet', 'jetpack' ); ?>" /> </div> </div> <?php @@ -1254,7 +1447,7 @@ class Jetpack_Custom_CSS { * Called by safecss_admin * * @global $post - * @param array $safecss_post + * @param array $safecss_post - the safecss array. * @uses wp_revisions_to_keep * @uses WP_Query * @uses wp_post_revision_title @@ -1262,11 +1455,12 @@ class Jetpack_Custom_CSS { * @uses add_query_arg * @uses menu_page_url * @uses wp_reset_query - * @return string + * + * @todo can this be removed? The revision page seems to work via the customizer now. */ - static function revisions_meta_box( $safecss_post ) { + public static function revisions_meta_box( $safecss_post ) { - $show_all_revisions = isset( $_GET['show_all_rev'] ); + $show_all_revisions = isset( $_GET['show_all_rev'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nothing on the site is changing if ( function_exists( 'wp_revisions_to_keep' ) ) { $max_revisions = wp_revisions_to_keep( (object) $safecss_post ); @@ -1276,62 +1470,71 @@ class Jetpack_Custom_CSS { $posts_per_page = $show_all_revisions ? $max_revisions : 6; - $revisions = new WP_Query( array( - 'posts_per_page' => $posts_per_page, - 'post_type' => 'revision', - 'post_status' => 'inherit', - 'post_parent' => $safecss_post['ID'], - 'orderby' => 'date', - 'order' => 'DESC' - ) ); + $revisions = new WP_Query( + array( + 'posts_per_page' => $posts_per_page, + 'post_type' => 'revision', + 'post_status' => 'inherit', + 'post_parent' => $safecss_post['ID'], + 'orderby' => 'date', + 'order' => 'DESC', + ) + ); - if ( $revisions->have_posts() ) { ?> - <ul class="post-revisions"><?php + if ( $revisions->have_posts() ) { + ?> + <ul class="post-revisions"> + <?php global $post; while ( $revisions->have_posts() ) : $revisions->the_post(); - ?><li> + ?> + <li> <?php - echo wp_post_revision_title( $post ); + echo wp_post_revision_title( $post ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - if ( ! empty( $post->post_excerpt ) ) - echo ' (' . esc_html( $post->post_excerpt ) . ')'; + if ( ! empty( $post->post_excerpt ) ) { + echo ' (' . esc_html( $post->post_excerpt ) . ')'; + } ?> - </li><?php + </li> + <?php endwhile; - ?></ul><?php + ?> + </ul> + <?php - if ( $revisions->found_posts > 6 && !$show_all_revisions ) { + if ( $revisions->found_posts > 6 && ! $show_all_revisions ) { ?> <br> - <a href="<?php echo add_query_arg( 'show_all_rev', 'true', menu_page_url( 'editcss', false ) ); ?>"><?php esc_html_e( 'Show all', 'jetpack' ); ?></a> + <a href="<?php echo esc_url( add_query_arg( 'show_all_rev', 'true', menu_page_url( 'editcss', false ) ) ); ?>"><?php esc_html_e( 'Show all', 'jetpack' ); ?></a> <?php } } - wp_reset_query(); + wp_reset_postdata(); } /** * Hook in init at priority 11 to disable custom CSS. */ - static function disable() { + public static function disable() { remove_action( 'wp_head', array( 'Jetpack_Custom_CSS', 'link_tag' ), 101 ); - remove_filter( 'stylesheet_uri', array( 'Jetpack_Custom_CSS', 'style_filter' ) ); + remove_filter( 'stylesheet_uri', array( 'Jetpack_Custom_CSS', 'style_filter' ) ); } /** * Reset all aspects of Custom CSS on a theme switch so that changing * themes is a sure-fire way to get a clean start. */ - static function reset() { - $safecss_post_id = Jetpack_Custom_CSS::save_revision( '' ); - $safecss_revision = Jetpack_Custom_CSS::get_current_revision(); + public static function reset() { + $safecss_post_id = self::save_revision( '' ); + $safecss_revision = self::get_current_revision(); update_option( 'safecss_rev', (int) get_option( 'safecss_rev' ) + 1 ); @@ -1349,38 +1552,53 @@ class Jetpack_Custom_CSS { delete_option( 'safecss_preview_add' ); } - static function is_customizer_preview() { - if ( isset ( $GLOBALS['wp_customize'] ) ) + /** + * Checks of we're in the customizer. + * + * @return bool + */ + public static function is_customizer_preview() { + if ( isset( $GLOBALS['wp_customize'] ) ) { return ! $GLOBALS['wp_customize']->is_theme_active(); + } return false; } - static function minify( $css, $preprocessor = '' ) { - if ( ! $css ) + /** + * Handle minifying CSS. + * + * @param string $css - the CSS. + * @param string $preprocessor - the preprocessor we want to use. + * + * @return string + */ + public static function minify( $css, $preprocessor = '' ) { + if ( ! $css ) { return ''; + } if ( $preprocessor ) { /** This filter is documented in modules/custom-css/custom-css.php */ $preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() ); - if ( isset( $preprocessors[$preprocessor] ) ) { - $css = call_user_func( $preprocessors[$preprocessor]['callback'], $css ); + if ( isset( $preprocessors[ $preprocessor ] ) ) { + $css = call_user_func( $preprocessors[ $preprocessor ]['callback'], $css ); } } safecss_class(); - $csstidy = new csstidy(); + $csstidy = new csstidy(); $csstidy->optimise = new safecss( $csstidy ); - $csstidy->set_cfg( 'remove_bslash', false ); - $csstidy->set_cfg( 'compress_colors', true ); - $csstidy->set_cfg( 'compress_font-weight', true ); - $csstidy->set_cfg( 'remove_last_;', true ); - $csstidy->set_cfg( 'case_properties', true ); + $csstidy->set_cfg( 'remove_bslash', false ); + $csstidy->set_cfg( 'compress_colors', true ); + $csstidy->set_cfg( 'compress_font-weight', true ); + $csstidy->set_cfg( 'remove_last_;', true ); + $csstidy->set_cfg( 'case_properties', true ); $csstidy->set_cfg( 'discard_invalid_properties', true ); - $csstidy->set_cfg( 'css_level', 'CSS3.0' ); - $csstidy->set_cfg( 'template', 'highest'); + $csstidy->set_cfg( 'css_level', 'CSS3.0' ); + $csstidy->set_cfg( 'template', 'highest' ); $csstidy->parse( $css ); return $csstidy->print->plain(); @@ -1389,18 +1607,22 @@ class Jetpack_Custom_CSS { /** * When restoring a SafeCSS post revision, also copy over the * content_width and custom_css_add post metadata. + * + * @param int $_post_id - the post ID. + * @param int $_revision_id - the revision ID. */ - static function restore_revision( $_post_id, $_revision_id ) { + public static function restore_revision( $_post_id, $_revision_id ) { $_post = get_post( $_post_id ); - if ( 'safecss' != $_post->post_type ) + if ( 'safecss' !== $_post->post_type ) { return; + } - $safecss_revision = Jetpack_Custom_CSS::get_current_revision(); + $safecss_revision = self::get_current_revision(); - $content_width = get_post_meta( $_revision_id, 'content_width', true ); + $content_width = get_post_meta( $_revision_id, 'content_width', true ); $custom_css_add = get_post_meta( $_revision_id, 'custom_css_add', true ); - $preprocessor = get_post_meta( $_revision_id, 'custom_css_preprocessor', true ); + $preprocessor = get_post_meta( $_revision_id, 'custom_css_preprocessor', true ); update_metadata( 'post', $safecss_revision['ID'], 'content_width', $content_width ); update_metadata( 'post', $safecss_revision['ID'], 'custom_css_add', $custom_css_add ); @@ -1418,10 +1640,8 @@ class Jetpack_Custom_CSS { /** * Migration routine for moving safecss from wp_options to wp_posts to support revisions - * - * @return void */ - static function upgrade() { + public static function upgrade() { $css = get_option( 'safecss' ); if ( get_option( 'safecss_revision_migrated' ) ) { @@ -1433,17 +1653,18 @@ class Jetpack_Custom_CSS { // Remove the async actions from publish_post remove_action( 'publish_post', 'queue_publish_post' ); - $post = array(); + $post = array(); $post['post_content'] = $css; - $post['post_title'] = 'safecss'; - $post['post_status'] = 'publish'; - $post['post_type'] = 'safecss'; + $post['post_title'] = 'safecss'; + $post['post_status'] = 'publish'; + $post['post_type'] = 'safecss'; // Insert the CSS into wp_posts $post_id = wp_insert_post( $post ); // Check for errors - if ( !$post_id or is_wp_error( $post_id ) ) - die( $post_id->get_error_message() ); + if ( ! $post_id || is_wp_error( $post_id ) ) { + die( $post_id->get_error_message() ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + } // Delete safecss option delete_option( 'safecss' ); @@ -1452,26 +1673,28 @@ class Jetpack_Custom_CSS { unset( $css ); // Check if we have already done this - if ( !get_option( 'safecss_revision_migrated' ) ) { + if ( ! get_option( 'safecss_revision_migrated' ) ) { define( 'DOING_MIGRATE', true ); // Get hashes of safecss post and current revision - $safecss_post = Jetpack_Custom_CSS::get_post(); + $safecss_post = self::get_post(); - if ( empty( $safecss_post ) ) + if ( empty( $safecss_post ) ) { return; + } $safecss_post_hash = md5( $safecss_post['post_content'] ); - $current_revision = Jetpack_Custom_CSS::get_current_revision(); + $current_revision = self::get_current_revision(); - if ( null == $current_revision ) + if ( null === $current_revision ) { return; + } $current_revision_hash = md5( $current_revision['post_content'] ); // If hashes are not equal, set safecss post with content from current revision if ( $safecss_post_hash !== $current_revision_hash ) { - Jetpack_Custom_CSS::save_revision( $current_revision['post_content'] ); + self::save_revision( $current_revision['post_content'] ); // Reset post_content to display the migrated revsion $safecss_post['post_content'] = $current_revision['post_content']; } @@ -1480,7 +1703,7 @@ class Jetpack_Custom_CSS { update_option( 'safecss_revision_migrated', time() ); } - $newest_safecss_post = Jetpack_Custom_CSS::get_current_revision(); + $newest_safecss_post = self::get_current_revision(); if ( $newest_safecss_post ) { if ( get_option( 'safecss_content_width' ) ) { @@ -1503,7 +1726,7 @@ class Jetpack_Custom_CSS { /** * Adds a filter to the redirect location in `wp-admin/revisions.php`. */ - static function add_revision_redirect() { + public static function add_revision_redirect() { add_filter( 'wp_redirect', array( __CLASS__, 'revision_redirect' ) ); } @@ -1513,13 +1736,13 @@ class Jetpack_Custom_CSS { * @param string $location The path to redirect to. * @return string */ - static function revision_redirect( $location ) { + public static function revision_redirect( $location ) { $post = get_post(); - if ( ! empty( $post->post_type ) && 'safecss' == $post->post_type ) { + if ( ! empty( $post->post_type ) && 'safecss' === $post->post_type ) { $location = 'themes.php?page=editcss'; - if ( 'edit.php' == $location ) { + if ( 'edit.php' === $location ) { $location = ''; } } @@ -1527,22 +1750,33 @@ class Jetpack_Custom_CSS { return $location; } - static function revision_post_link( $post_link, $post_id, $context ) { - if ( !$post_id = (int) $post_id ) { + /** + * The revision post link. + * + * @param string $post_link - the post link. + * @param int $post_id - the post ID. + * @param string $context - the context. + * + * @return string + */ + public static function revision_post_link( $post_link, $post_id, $context ) { + $post_id = (int) $post_id; + if ( ! $post_id ) { return $post_link; } - if ( !$post = get_post( $post_id ) ) { + $post = get_post( $post_id ); + if ( ! $post ) { return $post_link; } - if ( 'safecss' != $post->post_type ) { + if ( 'safecss' !== $post->post_type ) { return $post_link; } $post_link = admin_url( 'themes.php?page=editcss' ); - if ( 'display' == $context ) { + if ( 'display' === $context ) { return esc_url( $post_link ); } @@ -1552,45 +1786,69 @@ class Jetpack_Custom_CSS { /** * When on the edit screen, make sure the custom content width * setting is applied to the large image size. + * + * @param array $dims - the width and height dimensions. + * @param string $size - the size. + * @param string $context - the context in which we're applying dimensions. + * + * @return array */ - static function editor_max_image_size( $dims, $size = 'medium', $context = null ) { + public static function editor_max_image_size( $dims, $size = 'medium', $context = null ) { list( $width, $height ) = $dims; - if ( 'large' == $size && 'edit' == $context ) + if ( 'large' === $size && 'edit' === $context ) { $width = Jetpack::get_content_width(); + } return array( $width, $height ); } /** * Override the content_width with a custom value if one is set. + * + * @param int $content_width - the content width in pixels. + * + * @return int */ - static function jetpack_content_width( $content_width ) { + public static function jetpack_content_width( $content_width ) { $custom_content_width = 0; - if ( Jetpack_Custom_CSS::is_preview() ) { - $safecss_post = Jetpack_Custom_CSS::get_current_revision(); + if ( self::is_preview() ) { + $safecss_post = self::get_current_revision(); $custom_content_width = (int) get_post_meta( $safecss_post['ID'], 'content_width', true ); - } else if ( ! Jetpack_Custom_CSS::is_freetrial() ) { - $custom_css_post_id = Jetpack_Custom_CSS::post_id(); - if ( $custom_css_post_id ) + } elseif ( ! self::is_freetrial() ) { + $custom_css_post_id = self::post_id(); + if ( $custom_css_post_id ) { $custom_content_width = (int) get_post_meta( $custom_css_post_id, 'content_width', true ); + } } - if ( $custom_content_width > 0 ) + if ( $custom_content_width > 0 ) { $content_width = $custom_content_width; + } return $content_width; } } -class Jetpack_Safe_CSS { - static function filter_attr( $css, $element = 'div' ) { +/** + * The Safe CSS Class. + */ +class Jetpack_Safe_CSS { // phpcs:ignore Generic.Files.OneObjectStructurePerFile.MultipleFound, Generic.Classes.OpeningBraceSameLine.ContentAfterBrace + /** + * Filter attriburtes. + * + * @param string $css - the CSS. + * @param string $element - the HTML element. + * + * @return string + */ + public static function filter_attr( $css, $element = 'div' ) { safecss_class(); $css = $element . ' {' . $css . '}'; - $csstidy = new csstidy(); + $csstidy = new csstidy(); $csstidy->optimise = new safecss( $csstidy ); $csstidy->set_cfg( 'remove_bslash', false ); $csstidy->set_cfg( 'compress_colors', false ); @@ -1610,66 +1868,87 @@ class Jetpack_Safe_CSS { $css = $csstidy->print->plain(); - $css = str_replace( array( "\n","\r","\t" ), '', $css ); + $css = str_replace( array( "\n", "\r", "\t" ), '', $css ); preg_match( "/^{$element}\s*{(.*)}\s*$/", $css, $matches ); - if ( empty( $matches[1] ) ) + if ( empty( $matches[1] ) ) { return ''; + } return $matches[1]; } } if ( ! function_exists( 'safecss_class' ) ) : -function safecss_class() { - // Wrapped so we don't need the parent class just to load the plugin - if ( class_exists('safecss') ) - return; - - require_once( dirname( __FILE__ ) . '/csstidy/class.csstidy.php' ); + /** + * Setup safecss class. + */ + function safecss_class() { + // Wrapped so we don't need the parent class just to load the plugin + if ( class_exists( 'safecss' ) ) { + return; + } - class safecss extends csstidy_optimise { + require_once __DIR__ . '/csstidy/class.csstidy.php'; - function postparse() { + /** + * Safe CSS Class. + */ + class safecss extends csstidy_optimise { // phpcs:ignore /** - * Fires after parsing the css. - * - * @module custom-css - * - * @since 1.8.0 - * - * @param obj $this CSSTidy object. + * Add action to fire after parsing CSS. */ - do_action( 'csstidy_optimize_postparse', $this ); + public function postparse() { // phpcs:ignore MediaWiki.Usage.NestedFunctions.NestedFunction - return parent::postparse(); - } + /** + * Fires after parsing the css. + * + * @module custom-css + * + * @since 1.8.0 + * + * @param obj $this CSSTidy object. + */ + do_action( 'csstidy_optimize_postparse', $this ); - function subvalue() { + return parent::postparse(); + } /** - * Fires before optimizing the Custom CSS subvalue. - * - * @module custom-css - * - * @since 1.8.0 - * - * @param obj $this CSSTidy object. - **/ - do_action( 'csstidy_optimize_subvalue', $this ); + * Handle subvalue action. + */ + public function subvalue() { // phpcs:ignore MediaWiki.Usage.NestedFunctions.NestedFunction + + /** + * Fires before optimizing the Custom CSS subvalue. + * + * @module custom-css + * + * @since 1.8.0 + * + * @param obj $this CSSTidy object. + */ + do_action( 'csstidy_optimize_subvalue', $this ); - return parent::subvalue(); + return parent::subvalue(); + } } } -} endif; if ( ! function_exists( 'safecss_filter_attr' ) ) { + + /** + * Filter safecss attriburtes. + * + * @param string $css - the CSS. + * @param string $element - the HTML element. + */ function safecss_filter_attr( $css, $element = 'div' ) { return Jetpack_Safe_CSS::filter_attr( $css, $element ); } } -include_once dirname( __FILE__ ) . '/custom-css/preprocessors.php'; +require_once __DIR__ . '/custom-css/preprocessors.php'; |