class-wp-style-engine-css-declarations.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <?php
  2. /**
  3. * WP_Style_Engine_CSS_Declarations
  4. *
  5. * Holds, sanitizes and prints CSS rules declarations
  6. *
  7. * @package WordPress
  8. * @subpackage StyleEngine
  9. * @since 6.1.0
  10. */
  11. /**
  12. * Class WP_Style_Engine_CSS_Declarations.
  13. *
  14. * Holds, sanitizes, processes and prints CSS declarations for the style engine.
  15. *
  16. * @since 6.1.0
  17. */
  18. #[AllowDynamicProperties]
  19. class WP_Style_Engine_CSS_Declarations {
  20. /**
  21. * An array of CSS declarations (property => value pairs).
  22. *
  23. * @since 6.1.0
  24. *
  25. * @var array
  26. */
  27. protected $declarations = array();
  28. /**
  29. * Constructor for this object.
  30. *
  31. * If a `$declarations` array is passed, it will be used to populate
  32. * the initial $declarations prop of the object by calling add_declarations().
  33. *
  34. * @since 6.1.0
  35. *
  36. * @param string[] $declarations An associative array of CSS definitions, e.g., array( "$property" => "$value", "$property" => "$value" ).
  37. */
  38. public function __construct( $declarations = array() ) {
  39. $this->add_declarations( $declarations );
  40. }
  41. /**
  42. * Adds a single declaration.
  43. *
  44. * @since 6.1.0
  45. *
  46. * @param string $property The CSS property.
  47. * @param string $value The CSS value.
  48. *
  49. * @return WP_Style_Engine_CSS_Declarations Returns the object to allow chaining methods.
  50. */
  51. public function add_declaration( $property, $value ) {
  52. // Sanitizes the property.
  53. $property = $this->sanitize_property( $property );
  54. // Bails early if the property is empty.
  55. if ( empty( $property ) ) {
  56. return $this;
  57. }
  58. // Trims the value. If empty, bail early.
  59. $value = trim( $value );
  60. if ( '' === $value ) {
  61. return $this;
  62. }
  63. // Adds the declaration property/value pair.
  64. $this->declarations[ $property ] = $value;
  65. return $this;
  66. }
  67. /**
  68. * Removes a single declaration.
  69. *
  70. * @since 6.1.0
  71. *
  72. * @param string $property The CSS property.
  73. *
  74. * @return WP_Style_Engine_CSS_Declarations Returns the object to allow chaining methods.
  75. */
  76. public function remove_declaration( $property ) {
  77. unset( $this->declarations[ $property ] );
  78. return $this;
  79. }
  80. /**
  81. * Adds multiple declarations.
  82. *
  83. * @since 6.1.0
  84. *
  85. * @param array $declarations An array of declarations.
  86. *
  87. * @return WP_Style_Engine_CSS_Declarations Returns the object to allow chaining methods.
  88. */
  89. public function add_declarations( $declarations ) {
  90. foreach ( $declarations as $property => $value ) {
  91. $this->add_declaration( $property, $value );
  92. }
  93. return $this;
  94. }
  95. /**
  96. * Removes multiple declarations.
  97. *
  98. * @since 6.1.0
  99. *
  100. * @param array $properties An array of properties.
  101. *
  102. * @return WP_Style_Engine_CSS_Declarations Returns the object to allow chaining methods.
  103. */
  104. public function remove_declarations( $properties = array() ) {
  105. foreach ( $properties as $property ) {
  106. $this->remove_declaration( $property );
  107. }
  108. return $this;
  109. }
  110. /**
  111. * Gets the declarations array.
  112. *
  113. * @since 6.1.0
  114. *
  115. * @return array
  116. */
  117. public function get_declarations() {
  118. return $this->declarations;
  119. }
  120. /**
  121. * Filters a CSS property + value pair.
  122. *
  123. * @since 6.1.0
  124. *
  125. * @param string $property The CSS property.
  126. * @param string $value The value to be filtered.
  127. * @param string $spacer The spacer between the colon and the value. Defaults to an empty string.
  128. *
  129. * @return string The filtered declaration or an empty string.
  130. */
  131. protected static function filter_declaration( $property, $value, $spacer = '' ) {
  132. $filtered_value = wp_strip_all_tags( $value, true );
  133. if ( '' !== $filtered_value ) {
  134. return safecss_filter_attr( "{$property}:{$spacer}{$filtered_value}" );
  135. }
  136. return '';
  137. }
  138. /**
  139. * Filters and compiles the CSS declarations.
  140. *
  141. * @since 6.1.0
  142. *
  143. * @param bool $should_prettify Whether to add spacing, new lines and indents.
  144. * @param number $indent_count The number of tab indents to apply to the rule. Applies if `prettify` is `true`.
  145. *
  146. * @return string The CSS declarations.
  147. */
  148. public function get_declarations_string( $should_prettify = false, $indent_count = 0 ) {
  149. $declarations_array = $this->get_declarations();
  150. $declarations_output = '';
  151. $indent = $should_prettify ? str_repeat( "\t", $indent_count ) : '';
  152. $suffix = $should_prettify ? ' ' : '';
  153. $suffix = $should_prettify && $indent_count > 0 ? "\n" : $suffix;
  154. $spacer = $should_prettify ? ' ' : '';
  155. foreach ( $declarations_array as $property => $value ) {
  156. $filtered_declaration = static::filter_declaration( $property, $value, $spacer );
  157. if ( $filtered_declaration ) {
  158. $declarations_output .= "{$indent}{$filtered_declaration};$suffix";
  159. }
  160. }
  161. return rtrim( $declarations_output );
  162. }
  163. /**
  164. * Sanitizes property names.
  165. *
  166. * @since 6.1.0
  167. *
  168. * @param string $property The CSS property.
  169. *
  170. * @return string The sanitized property name.
  171. */
  172. protected function sanitize_property( $property ) {
  173. return sanitize_key( $property );
  174. }
  175. }