PluginProbe
Gutenberg / 8.9.3
Gutenberg v8.9.3
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / lib / class-wp-block.php

class-wp-block.php in Gutenberg 8.9.3, at lib/class-wp-block.php

244 lines 6.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Blocks API: WP_Block class
4 *
5 * @package Gutenberg
6 */
7
8 /**
9 * Class representing a parsed instance of a block.
10 *
11 * This class can be removed when plugin support requires WordPress 5.5.0+.
12 *
13 * @see https://core.trac.wordpress.org/ticket/49926
14 * @see https://core.trac.wordpress.org/changeset/48159
15 *
16 * @property array $attributes
17 */
18 class WP_Block {
19
20 /**
21 * Original parsed array representation of block.
22 *
23 * @var array
24 */
25 public $parsed_block;
26
27 /**
28 * Name of block.
29 *
30 * @example "core/paragraph"
31 *
32 * @var string
33 */
34 public $name;
35
36 /**
37 * Block type associated with the instance.
38 *
39 * @var WP_Block_Type
40 */
41 public $block_type;
42
43 /**
44 * Block context values.
45 *
46 * @var array
47 */
48 public $context = array();
49
50 /**
51 * All available context of the current hierarchy.
52 *
53 * @var array
54 * @access protected
55 */
56 protected $available_context;
57
58 /**
59 * List of inner blocks (of this same class)
60 *
61 * @var WP_Block[]
62 */
63 public $inner_blocks = array();
64
65 /**
66 * Resultant HTML from inside block comment delimiters after removing inner
67 * blocks.
68 *
69 * @example "...Just <!-- wp:test /--> testing..." -> "Just testing..."
70 *
71 * @var string
72 */
73 public $inner_html = '';
74
75 /**
76 * List of string fragments and null markers where inner blocks were found
77 *
78 * @example array(
79 * 'inner_html' => 'BeforeInnerAfter',
80 * 'inner_blocks' => array( block, block ),
81 * 'inner_content' => array( 'Before', null, 'Inner', null, 'After' ),
82 * )
83 *
84 * @var array
85 */
86 public $inner_content = array();
87
88 /**
89 * Constructor.
90 *
91 * Populates object properties from the provided block instance argument.
92 *
93 * The given array of context values will not necessarily be available on
94 * the instance itself, but is treated as the full set of values provided by
95 * the block's ancestry. This is assigned to the private `available_context`
96 * property. Only values which are configured to consumed by the block via
97 * its registered type will be assigned to the block's `context` property.
98 *
99 * @param array $block Array of parsed block properties.
100 * @param array $available_context Optional array of ancestry context values.
101 * @param WP_Block_Type_Registry $registry Optional block type registry.
102 */
103 public function __construct( $block, $available_context = array(), $registry = null ) {
104 $this->parsed_block = $block;
105 $this->name = $block['blockName'];
106
107 if ( is_null( $registry ) ) {
108 $registry = WP_Block_Type_Registry::get_instance();
109 }
110
111 $this->block_type = $registry->get_registered( $this->name );
112
113 if ( ! empty( $this->block_type->context ) ) {
114 $message = sprintf(
115 /* translators: 1: Block name. */
116 __( 'The "context" parameter provided in block type "%s" is deprecated. Please use "uses_context" instead.', 'gutenberg' ),
117 $this->name
118 );
119 _doing_it_wrong( __CLASS__, $message, '8.6.0' );
120 $this->block_type->uses_context = $this->block_type->context;
121 }
122 if ( ! empty( $this->block_type->providesContext ) ) {
123 $message = sprintf(
124 /* translators: 1: Block name. */
125 __( 'The "providesContext" parameter provided in block type "%s" is deprecated. Please use "provides_context".', 'gutenberg' ),
126 $this->name
127 );
128 _doing_it_wrong( __CLASS__, $message, '8.6.0' );
129 $this->block_type->provides_context = $this->block_type->providesContext;
130 }
131
132 $this->available_context = $available_context;
133
134 if ( ! empty( $this->block_type->uses_context ) ) {
135 foreach ( $this->block_type->uses_context as $context_name ) {
136 if ( array_key_exists( $context_name, $this->available_context ) ) {
137 $this->context[ $context_name ] = $this->available_context[ $context_name ];
138 }
139 }
140 }
141
142 if ( ! empty( $block['innerBlocks'] ) ) {
143 $child_context = $this->available_context;
144
145 if ( ! empty( $this->block_type->provides_context ) ) {
146 foreach ( $this->block_type->provides_context as $context_name => $attribute_name ) {
147 if ( array_key_exists( $attribute_name, $this->attributes ) ) {
148 $child_context[ $context_name ] = $this->attributes[ $attribute_name ];
149 }
150 }
151 }
152
153 $this->inner_blocks = new WP_Block_List( $block['innerBlocks'], $child_context, $registry );
154 }
155
156 if ( ! empty( $block['innerHTML'] ) ) {
157 $this->inner_html = $block['innerHTML'];
158 }
159
160 if ( ! empty( $block['innerContent'] ) ) {
161 $this->inner_content = $block['innerContent'];
162 }
163 }
164
165 /**
166 * Returns a value from an inaccessible property.
167 *
168 * This is used to lazily initialize the `attributes` property of a block,
169 * such that it is only prepared with default attributes at the time that
170 * the property is accessed. For all other inaccessible properties, a `null`
171 * value is returned.
172 *
173 * @param string $name Property name.
174 *
175 * @return array|null Prepared attributes, or null.
176 */
177 public function __get( $name ) {
178 if ( 'attributes' === $name ) {
179 $this->attributes = isset( $this->parsed_block['attrs'] ) ?
180 $this->parsed_block['attrs'] :
181 array();
182
183 if ( ! is_null( $this->block_type ) ) {
184 $this->attributes = $this->block_type->prepare_attributes_for_render( $this->attributes );
185 }
186
187 return $this->attributes;
188 }
189
190 return null;
191 }
192
193 /**
194 * Generates the render output for the block.
195 *
196 * @param array $options {
197 * Optional options object.
198 *
199 * @type bool $dynamic Defaults to 'true'. Optionally set to false to avoid using the block's render_callback.
200 * }
201 *
202 * @return string Rendered block output.
203 */
204 public function render( $options = array() ) {
205 global $post;
206 $options = array_replace(
207 array(
208 'dynamic' => true,
209 ),
210 $options
211 );
212
213 $is_dynamic = $options['dynamic'] && $this->name && null !== $this->block_type && $this->block_type->is_dynamic();
214 $block_content = '';
215
216 if ( ! $options['dynamic'] || empty( $this->block_type->skip_inner_blocks ) ) {
217 $index = 0;
218 foreach ( $this->inner_content as $chunk ) {
219 $block_content .= is_string( $chunk ) ?
220 $chunk :
221 $this->inner_blocks[ $index++ ]->render();
222 }
223 }
224
225 if ( $is_dynamic ) {
226 $global_post = $post;
227 $block_content = (string) call_user_func( $this->block_type->render_callback, $this->attributes, $block_content, $this );
228 $post = $global_post;
229 }
230
231 if ( ! empty( $this->block_type->script ) ) {
232 wp_enqueue_script( $this->block_type->script );
233 }
234
235 if ( ! empty( $this->block_type->style ) ) {
236 wp_enqueue_style( $this->block_type->style );
237 }
238
239 /** This filter is documented in src/wp-includes/blocks.php */
240 return apply_filters( 'render_block', $block_content, $this->parsed_block );
241 }
242
243 }
244