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