Bez popisu

class-wp-block-supports.php 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <?php
  2. /**
  3. * Block support flags.
  4. *
  5. * @package WordPress
  6. *
  7. * @since 5.6.0
  8. */
  9. /**
  10. * Class encapsulating and implementing Block Supports.
  11. *
  12. * @since 5.6.0
  13. *
  14. * @access private
  15. */
  16. class WP_Block_Supports {
  17. /**
  18. * Config.
  19. *
  20. * @since 5.6.0
  21. * @var array
  22. */
  23. private $block_supports = array();
  24. /**
  25. * Tracks the current block to be rendered.
  26. *
  27. * @since 5.6.0
  28. * @var array
  29. */
  30. public static $block_to_render = null;
  31. /**
  32. * Container for the main instance of the class.
  33. *
  34. * @since 5.6.0
  35. * @var WP_Block_Supports|null
  36. */
  37. private static $instance = null;
  38. /**
  39. * Utility method to retrieve the main instance of the class.
  40. *
  41. * The instance will be created if it does not exist yet.
  42. *
  43. * @since 5.6.0
  44. *
  45. * @return WP_Block_Supports The main instance.
  46. */
  47. public static function get_instance() {
  48. if ( null === self::$instance ) {
  49. self::$instance = new self();
  50. }
  51. return self::$instance;
  52. }
  53. /**
  54. * Initializes the block supports. It registes the block supports block attributes.
  55. *
  56. * @since 5.6.0
  57. */
  58. public static function init() {
  59. $instance = self::get_instance();
  60. $instance->register_attributes();
  61. }
  62. /**
  63. * Registers a block support.
  64. *
  65. * @since 5.6.0
  66. *
  67. * @param string $block_support_name Block support name.
  68. * @param array $block_support_config Array containing the properties of the block support.
  69. */
  70. public function register( $block_support_name, $block_support_config ) {
  71. $this->block_supports[ $block_support_name ] = array_merge(
  72. $block_support_config,
  73. array( 'name' => $block_support_name )
  74. );
  75. }
  76. /**
  77. * Generates an array of HTML attributes, such as classes, by applying to
  78. * the given block all of the features that the block supports.
  79. *
  80. * @since 5.6.0
  81. *
  82. * @return array Array of HTML attributes.
  83. */
  84. public function apply_block_supports() {
  85. $block_attributes = self::$block_to_render['attrs'];
  86. $block_type = WP_Block_Type_Registry::get_instance()->get_registered(
  87. self::$block_to_render['blockName']
  88. );
  89. // If no render_callback, assume styles have been previously handled.
  90. if ( ! $block_type || empty( $block_type ) ) {
  91. return array();
  92. }
  93. $output = array();
  94. foreach ( $this->block_supports as $block_support_config ) {
  95. if ( ! isset( $block_support_config['apply'] ) ) {
  96. continue;
  97. }
  98. $new_attributes = call_user_func(
  99. $block_support_config['apply'],
  100. $block_type,
  101. $block_attributes
  102. );
  103. if ( ! empty( $new_attributes ) ) {
  104. foreach ( $new_attributes as $attribute_name => $attribute_value ) {
  105. if ( empty( $output[ $attribute_name ] ) ) {
  106. $output[ $attribute_name ] = $attribute_value;
  107. } else {
  108. $output[ $attribute_name ] .= " $attribute_value";
  109. }
  110. }
  111. }
  112. }
  113. return $output;
  114. }
  115. /**
  116. * Registers the block attributes required by the different block supports.
  117. *
  118. * @since 5.6.0
  119. */
  120. private function register_attributes() {
  121. $block_registry = WP_Block_Type_Registry::get_instance();
  122. $registered_block_types = $block_registry->get_all_registered();
  123. foreach ( $registered_block_types as $block_type ) {
  124. if ( ! property_exists( $block_type, 'supports' ) ) {
  125. continue;
  126. }
  127. if ( ! $block_type->attributes ) {
  128. $block_type->attributes = array();
  129. }
  130. foreach ( $this->block_supports as $block_support_config ) {
  131. if ( ! isset( $block_support_config['register_attribute'] ) ) {
  132. continue;
  133. }
  134. call_user_func(
  135. $block_support_config['register_attribute'],
  136. $block_type
  137. );
  138. }
  139. }
  140. }
  141. }
  142. /**
  143. * Generates a string of attributes by applying to the current block being
  144. * rendered all of the features that the block supports.
  145. *
  146. * @since 5.6.0
  147. *
  148. * @param array $extra_attributes Optional. Extra attributes to render on the block wrapper.
  149. *
  150. * @return string String of HTML classes.
  151. */
  152. function get_block_wrapper_attributes( $extra_attributes = array() ) {
  153. $new_attributes = WP_Block_Supports::get_instance()->apply_block_supports();
  154. if ( empty( $new_attributes ) && empty( $extra_attributes ) ) {
  155. return '';
  156. }
  157. // This is hardcoded on purpose.
  158. // We only support a fixed list of attributes.
  159. $attributes_to_merge = array( 'style', 'class' );
  160. $attributes = array();
  161. foreach ( $attributes_to_merge as $attribute_name ) {
  162. if ( empty( $new_attributes[ $attribute_name ] ) && empty( $extra_attributes[ $attribute_name ] ) ) {
  163. continue;
  164. }
  165. if ( empty( $new_attributes[ $attribute_name ] ) ) {
  166. $attributes[ $attribute_name ] = $extra_attributes[ $attribute_name ];
  167. continue;
  168. }
  169. if ( empty( $extra_attributes[ $attribute_name ] ) ) {
  170. $attributes[ $attribute_name ] = $new_attributes[ $attribute_name ];
  171. continue;
  172. }
  173. $attributes[ $attribute_name ] = $extra_attributes[ $attribute_name ] . ' ' . $new_attributes[ $attribute_name ];
  174. }
  175. foreach ( $extra_attributes as $attribute_name => $value ) {
  176. if ( ! in_array( $attribute_name, $attributes_to_merge, true ) ) {
  177. $attributes[ $attribute_name ] = $value;
  178. }
  179. }
  180. if ( empty( $attributes ) ) {
  181. return '';
  182. }
  183. $normalized_attributes = array();
  184. foreach ( $attributes as $key => $value ) {
  185. $normalized_attributes[] = $key . '="' . esc_attr( $value ) . '"';
  186. }
  187. return implode( ' ', $normalized_attributes );
  188. }