wp/wp-includes/customize/class-wp-customize-custom-css-setting.php
changeset 7 cf61fcea0001
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
       
     1 <?php
       
     2 /**
       
     3  * Customize API: WP_Customize_Custom_CSS_Setting class
       
     4  *
       
     5  * This handles validation, sanitization and saving of the value.
       
     6  *
       
     7  * @package WordPress
       
     8  * @subpackage Customize
       
     9  * @since 4.7.0
       
    10  */
       
    11 
       
    12 /**
       
    13  * Custom Setting to handle WP Custom CSS.
       
    14  *
       
    15  * @since 4.7.0
       
    16  *
       
    17  * @see WP_Customize_Setting
       
    18  */
       
    19 final class WP_Customize_Custom_CSS_Setting extends WP_Customize_Setting {
       
    20 
       
    21 	/**
       
    22 	 * The setting type.
       
    23 	 *
       
    24 	 * @since 4.7.0
       
    25 	 * @var string
       
    26 	 */
       
    27 	public $type = 'custom_css';
       
    28 
       
    29 	/**
       
    30 	 * Setting Transport
       
    31 	 *
       
    32 	 * @since 4.7.0
       
    33 	 * @var string
       
    34 	 */
       
    35 	public $transport = 'postMessage';
       
    36 
       
    37 	/**
       
    38 	 * Capability required to edit this setting.
       
    39 	 *
       
    40 	 * @since 4.7.0
       
    41 	 * @var string
       
    42 	 */
       
    43 	public $capability = 'edit_css';
       
    44 
       
    45 	/**
       
    46 	 * Stylesheet
       
    47 	 *
       
    48 	 * @since 4.7.0
       
    49 	 * @var string
       
    50 	 */
       
    51 	public $stylesheet = '';
       
    52 
       
    53 	/**
       
    54 	 * WP_Customize_Custom_CSS_Setting constructor.
       
    55 	 *
       
    56 	 * @since 4.7.0
       
    57 	 *
       
    58 	 * @throws Exception If the setting ID does not match the pattern `custom_css[$stylesheet]`.
       
    59 	 *
       
    60 	 * @param WP_Customize_Manager $manager The Customize Manager class.
       
    61 	 * @param string               $id      An specific ID of the setting. Can be a
       
    62 	 *                                      theme mod or option name.
       
    63 	 * @param array                $args    Setting arguments.
       
    64 	 */
       
    65 	public function __construct( $manager, $id, $args = array() ) {
       
    66 		parent::__construct( $manager, $id, $args );
       
    67 		if ( 'custom_css' !== $this->id_data['base'] ) {
       
    68 			throw new Exception( 'Expected custom_css id_base.' );
       
    69 		}
       
    70 		if ( 1 !== count( $this->id_data['keys'] ) || empty( $this->id_data['keys'][0] ) ) {
       
    71 			throw new Exception( 'Expected single stylesheet key.' );
       
    72 		}
       
    73 		$this->stylesheet = $this->id_data['keys'][0];
       
    74 	}
       
    75 
       
    76 	/**
       
    77 	 * Add filter to preview post value.
       
    78 	 *
       
    79 	 * @since 4.7.9
       
    80 	 *
       
    81 	 * @return bool False when preview short-circuits due no change needing to be previewed.
       
    82 	 */
       
    83 	public function preview() {
       
    84 		if ( $this->is_previewed ) {
       
    85 			return false;
       
    86 		}
       
    87 		$this->is_previewed = true;
       
    88 		add_filter( 'wp_get_custom_css', array( $this, 'filter_previewed_wp_get_custom_css' ), 9, 2 );
       
    89 		return true;
       
    90 	}
       
    91 
       
    92 	/**
       
    93 	 * Filter `wp_get_custom_css` for applying the customized value.
       
    94 	 *
       
    95 	 * This is used in the preview when `wp_get_custom_css()` is called for rendering the styles.
       
    96 	 *
       
    97 	 * @since 4.7.0
       
    98 	 * @see wp_get_custom_css()
       
    99 	 *
       
   100 	 * @param string $css        Original CSS.
       
   101 	 * @param string $stylesheet Current stylesheet.
       
   102 	 * @return string CSS.
       
   103 	 */
       
   104 	public function filter_previewed_wp_get_custom_css( $css, $stylesheet ) {
       
   105 		if ( $stylesheet === $this->stylesheet ) {
       
   106 			$customized_value = $this->post_value( null );
       
   107 			if ( ! is_null( $customized_value ) ) {
       
   108 				$css = $customized_value;
       
   109 			}
       
   110 		}
       
   111 		return $css;
       
   112 	}
       
   113 
       
   114 	/**
       
   115 	 * Fetch the value of the setting. Will return the previewed value when `preview()` is called.
       
   116 	 *
       
   117 	 * @since 4.7.0
       
   118 	 * @see WP_Customize_Setting::value()
       
   119 	 *
       
   120 	 * @return string
       
   121 	 */
       
   122 	public function value() {
       
   123 		if ( $this->is_previewed ) {
       
   124 			$post_value = $this->post_value( null );
       
   125 			if ( null !== $post_value ) {
       
   126 				return $post_value;
       
   127 			}
       
   128 		}
       
   129 		$id_base = $this->id_data['base'];
       
   130 		$value = '';
       
   131 		$post = wp_get_custom_css_post( $this->stylesheet );
       
   132 		if ( $post ) {
       
   133 			$value = $post->post_content;
       
   134 		}
       
   135 		if ( empty( $value ) ) {
       
   136 			$value = $this->default;
       
   137 		}
       
   138 
       
   139 		/** This filter is documented in wp-includes/class-wp-customize-setting.php */
       
   140 		$value = apply_filters( "customize_value_{$id_base}", $value, $this );
       
   141 
       
   142 		return $value;
       
   143 	}
       
   144 
       
   145 	/**
       
   146 	 * Validate CSS.
       
   147 	 *
       
   148 	 * Checks for imbalanced braces, brackets, and comments.
       
   149 	 * Notifications are rendered when the customizer state is saved.
       
   150 	 *
       
   151 	 * @since 4.7.0
       
   152 	 * @since 4.9.0 Checking for balanced characters has been moved client-side via linting in code editor.
       
   153 	 *
       
   154 	 * @param string $css The input string.
       
   155 	 * @return true|WP_Error True if the input was validated, otherwise WP_Error.
       
   156 	 */
       
   157 	public function validate( $css ) {
       
   158 		$validity = new WP_Error();
       
   159 
       
   160 		if ( preg_match( '#</?\w+#', $css ) ) {
       
   161 			$validity->add( 'illegal_markup', __( 'Markup is not allowed in CSS.' ) );
       
   162 		}
       
   163 
       
   164 		if ( empty( $validity->errors ) ) {
       
   165 			$validity = parent::validate( $css );
       
   166 		}
       
   167 		return $validity;
       
   168 	}
       
   169 
       
   170 	/**
       
   171 	 * Store the CSS setting value in the custom_css custom post type for the stylesheet.
       
   172 	 *
       
   173 	 * @since 4.7.0
       
   174 	 *
       
   175 	 * @param string $css The input value.
       
   176 	 * @return int|false The post ID or false if the value could not be saved.
       
   177 	 */
       
   178 	public function update( $css ) {
       
   179 		if ( empty( $css ) ) {
       
   180 			$css = '';
       
   181 		}
       
   182 
       
   183 		$r = wp_update_custom_css_post( $css, array(
       
   184 			'stylesheet' => $this->stylesheet,
       
   185 		) );
       
   186 
       
   187 		if ( $r instanceof WP_Error ) {
       
   188 			return false;
       
   189 		}
       
   190 		$post_id = $r->ID;
       
   191 
       
   192 		// Cache post ID in theme mod for performance to avoid additional DB query.
       
   193 		if ( $this->manager->get_stylesheet() === $this->stylesheet ) {
       
   194 			set_theme_mod( 'custom_css_post_id', $post_id );
       
   195 		}
       
   196 
       
   197 		return $post_id;
       
   198 	}
       
   199 }