PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / trunk
JetFormBuilder — Dynamic Blocks Form Builder vtrunk
3.6.4 3.6.3.1 3.6.3 3.6.2.2 3.6.2.1 3.6.2 3.6.1.1 3.6.1 3.6.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.10 2.1.11 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.0.1 3.0.0.2 3.0.0.3 3.0.1 3.0.1.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.0.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.3.1 3.3.4 3.3.4.1 3.3.4.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.5.1 3.4.5.2 3.4.6 3.4.7 3.4.7.1 3.5.0 3.5.1 3.5.1.1 3.5.1.2 3.5.2 3.5.2.1 3.5.3 3.5.4 3.5.5 3.5.6 3.5.6.1 3.5.6.2 3.5.6.3 3.6.0
jetformbuilder / modules / framework / blocks-style-manager / block.php
jetformbuilder / modules / framework / blocks-style-manager Last commit date
assets 2 months ago field-handlers 2 months ago migrator 2 months ago block.php 2 months ago editor.php 2 months ago path-url-trait.php 2 months ago proxy.php 2 months ago registry.php 2 months ago style-cache.php 2 months ago style-engine.php 2 months ago style-inserter.php 2 months ago style-manager.php 2 months ago webpack.config.js 2 months ago
block.php
517 lines
1 <?php
2 namespace Crocoblock\Blocks_Style;
3
4 /**
5 * Block handler class
6 *
7 * @since 1.0.0
8 */
9 class Block {
10
11 /**
12 * Block name
13 *
14 * @var string
15 */
16 protected $name;
17
18 /**
19 * Block attributes
20 *
21 * @var array
22 */
23 protected $attributes;
24
25 /**
26 * Block styles
27 *
28 * @var array
29 */
30 protected $styles;
31
32 /**
33 * Block controls stack
34 *
35 * @var array
36 */
37 protected $controls_stack = array(
38 'children' => array(),
39 );
40
41 /**
42 * Whether the block is rendered via REST API.
43 *
44 * @var bool
45 */
46 protected $is_rest_render = false;
47
48 /**
49 * Currently processed section for registration.
50 */
51 protected $_current_section = null;
52
53 /**
54 * Currently processed tabs for registration.
55 */
56 protected $_current_tabs = null;
57
58 /**
59 * Currently processed tab for registration.
60 */
61 protected $_current_tab = null;
62
63 protected $css_props = array();
64
65 protected $defaults = null;
66
67 /**
68 * Constructor
69 *
70 * @param string $name Block name.
71 * @param array $attributes Block attributes.
72 */
73 public function __construct( $name, $attributes = array() ) {
74 $this->name = $name;
75 $this->attributes = $attributes;
76
77 add_filter(
78 'rest_request_before_callbacks',
79 array( $this, 'prevent_styles_on_self_render' ),
80 10, 3
81 );
82
83 add_filter(
84 'render_block_' . $this->get_block_name(),
85 array( $this, 'render_block_styles' ),
86 10, 3
87 );
88 }
89
90 /**
91 * Set block attributes
92 *
93 * @param array $attributes Block attributes.
94 */
95 public function set_attributes( $attributes ) {
96 $this->attributes = array_merge( $this->attributes, $attributes );
97 }
98
99 /**
100 * Prevent styles from being rendered when there is a Rest API request
101 * to render the block itself.
102 *
103 * @param mixed $response The response object.
104 * @param mixed $handler The handler for the request.
105 * @param WP_REST_Request $request The request object.
106 * @return mixed
107 */
108 public function prevent_styles_on_self_render( $response, $handler, $request ) {
109
110 if ( strpos( $request->get_route(), '/wp/v2/block-renderer/' ) === 0 ) {
111 $block_name = $request->get_param( 'name' );
112
113 if ( ! $block_name ) {
114 $route_parts = explode( '/', trim( $request->get_route(), '/' ) );
115 $block_name = end( $route_parts );
116 }
117
118 if ( $block_name === $this->get_block_name() ) {
119 /*remove_filter(
120 'render_block_' . $this->get_block_name(),
121 array( $this, 'render_block_styles' ),
122 10, 3
123 );*/
124 $this->is_rest_render = true;
125 }
126 }
127
128 return $response;
129 }
130
131 /**
132 * Render block styles
133 *
134 * @param string $block_content Block content.
135 * @param array $block Block data.
136 * @param bool $is_preview Is preview mode.
137 * @return string
138 */
139 public function render_block_styles( $block_content, $parsed_block, $wp_block ) {
140
141 if ( ! empty( $parsed_block['attrs'][ Registry::instance()->get_support_name() ] ) ) {
142
143 if ( $this->is_rest_render ) {
144
145 $block_class_name = Style_Engine::get_classname_from_attrs(
146 $parsed_block['attrs'][ Registry::instance()->get_support_name() ]
147 );
148
149 $style_inserter = new Style_Inserter( $block_class_name, [] );
150
151 return $style_inserter->with_class_name( $block_content );
152 }
153
154 $style_engine = new Style_Engine(
155 $parsed_block['attrs'][ Registry::instance()->get_support_name() ],
156 $this->css_props
157 );
158
159 $styles_data = Style_Cache::get_instance()->get_cached( $style_engine );
160
161 $style_inserter = new Style_Inserter(
162 $style_engine->get_class_name(),
163 $styles_data
164 );
165
166 $block_content = $style_inserter->insert_styles( $block_content );
167
168 if ( ! apply_filters( 'jet-styles-manager/block/force-print-styles', false, $this ) ) {
169 Style_Cache::get_instance()->add_printed( $style_engine->get_class_name() );
170 }
171 }
172
173 return $block_content;
174 }
175
176 /**
177 * Get block name
178 *
179 * @return string
180 */
181 public function get_block_name() {
182 return $this->name;
183 }
184
185 /**
186 * Get currently registered controls.
187 *
188 * @return array
189 */
190 public function get_controls_stack() {
191 return $this->controls_stack['children'];
192 }
193
194 /**
195 * Get default values for the registered controls,
196 * if there were any.
197 *
198 * @return array|null
199 */
200 public function get_defaults() {
201 return $this->defaults;
202 }
203
204 /**
205 * Whether to register full controls or only CSS-render-related.
206 *
207 * @return bool
208 */
209 public function should_register_full_controls() {
210 return is_admin();
211 }
212
213 /**
214 * Start a new section for block styles
215 *
216 * @param array $args
217 * @return void
218 */
219 public function start_section( $args = array() ) {
220
221 if ( ! $this->should_register_full_controls() ) {
222 return;
223 }
224
225 if ( ! isset( $args['id'] ) ) {
226 _doing_it_wrong(
227 'Blocks_Style\Proxy::start_section',
228 'Section id is required.',
229 '1.0.0'
230 );
231 return;
232 }
233
234 $section_id = $args['id'];
235
236 $this->_current_section = $section_id;
237
238 if ( ! isset( $this->controls_stack['children'][ $this->_current_section ] ) ) {
239 $this->controls_stack['children'][ $this->_current_section ] = $args;
240 $this->controls_stack['children'][ $this->_current_section ]['children'] = array();
241 }
242 }
243
244 /**
245 * End the current section
246 *
247 * @return void
248 */
249 public function end_section() {
250
251 if ( ! $this->should_register_full_controls() ) {
252 return;
253 }
254
255 $this->_current_section = null;
256 }
257
258 /**
259 * Add a new control to the current section
260 *
261 * @param array $args
262 * @return void
263 */
264 public function add_control( $args = array() ) {
265
266 if ( ! $this->should_register_full_controls() ) {
267
268 $control_id = ! empty( $args['id'] ) ? $args['id'] : false;
269
270 $this->css_props[ $control_id ] = array(
271 'type' => ! empty( $args['type'] ) ? $args['type'] : 'text',
272 'css_var' => ! empty( $args['css_var'] ) ? $args['css_var'] : array(),
273 'css_selector' => ! empty( $args['css_selector'] ) ? $args['css_selector'] : array(),
274 );
275
276 return;
277 }
278
279 if ( ! $this->_current_section ) {
280
281 _doing_it_wrong(
282 'Block::add_control',
283 'You must call start_section() before adding controls.',
284 '1.0.0'
285 );
286
287 return;
288 }
289
290 $control_id = ! empty( $args['id'] ) ? $args['id'] : false;
291
292 if ( ! $control_id ) {
293 _doing_it_wrong(
294 'Block::add_control',
295 'You must provide a control `id` parameter.',
296 '1.0.0'
297 );
298
299 return;
300 }
301
302 // Ensure correct format of CSS variable prop
303 $css_var = ! empty( $args['css_var'] ) ? (array) $args['css_var'] : array();
304
305 if ( ! empty( $css_var ) ) {
306
307 $css_var = array_merge(
308 array(
309 'prefix' => '--csm',
310 'name' => $control_id,
311 ),
312 $css_var
313 );
314
315 $args['css_var'] = $css_var;
316 }
317
318 if ( $this->_current_tabs && $this->_current_tab ) {
319 $this->register_children(
320 array( $this->_current_section, $this->_current_tabs, $this->_current_tab ),
321 $control_id,
322 $args
323 );
324 } else {
325 $this->register_children(
326 array( $this->_current_section ),
327 $control_id,
328 $args
329 );
330 }
331
332 if ( ! empty( $args['default'] ) ) {
333
334 if ( is_null( $this->defaults ) ) {
335 $this->defaults = array();
336 }
337
338 $this->defaults[ $control_id ] = $args['default'];
339 }
340
341 $this->css_props[ $control_id ] = array(
342 'type' => ! empty( $args['type'] ) ? $args['type'] : 'text',
343 'css_var' => ! empty( $args['css_var'] ) ? $args['css_var'] : array(),
344 'css_selector' => ! empty( $args['css_selector'] ) ? $args['css_selector'] : array(),
345 );
346 }
347
348 /**
349 * Start tabs group
350 *
351 * @param array $args
352 * @return void
353 */
354 public function start_tabs( $args = array() ) {
355
356 if ( ! $this->should_register_full_controls() ) {
357 return;
358 }
359
360 if ( ! empty( $args['id'] ) ) {
361 $id = $args['id'];
362 } else {
363 _doing_it_wrong(
364 'Block::start_tabs',
365 'You must provide a tabs `id` parameter.',
366 '1.0.0'
367 );
368 return;
369 }
370
371 $this->_current_tabs = $id;
372
373 $args['type'] = 'tabs';
374
375 $this->register_children(
376 array( $this->_current_section ),
377 $this->_current_tabs,
378 $args
379 );
380 }
381
382 /**
383 * Start a new tab
384 *
385 * @param array $args
386 * @return void
387 */
388 public function start_tab( $args = array() ) {
389
390 if ( ! $this->should_register_full_controls() ) {
391 return;
392 }
393
394 if ( ! empty( $args['id'] ) ) {
395 $id = $args['id'];
396 } else {
397 _doing_it_wrong(
398 'Block::start_tab',
399 'You must provide a tabs `id` parameter.',
400 '1.0.0'
401 );
402 return;
403 }
404
405 $this->_current_tab = $id;
406
407 $args['type'] = 'tab';
408
409 $this->register_children(
410 array( $this->_current_section, $this->_current_tabs ),
411 $this->_current_tab,
412 $args
413 );
414 }
415
416 /**
417 * End tabs group
418 *
419 * @return void
420 */
421 public function end_tabs() {
422
423 if ( ! $this->should_register_full_controls() ) {
424 return;
425 }
426
427 $this->_current_tabs = null;
428 $this->_current_tab = null;
429 }
430
431 /**
432 * End the current tab
433 *
434 * @return void
435 */
436 public function end_tab() {
437
438 if ( ! $this->should_register_full_controls() ) {
439 return;
440 }
441
442 $this->_current_tab = null;
443 }
444
445 /**
446 * Register children controls recursively
447 *
448 * This method registers child controls under the specified parent trace.
449 *
450 * @param array $parents_trace Array of parent keys representing the trace.
451 * Example: ['section1', 'tabs1', 'tab1'].
452 * Each key must be a non-empty string.
453 * @param string $control_id The control ID. Must be a unique, non-empty string.
454 * Example: 'control1'.
455 * @param array $args The control arguments. Should include control-specific
456 * settings such as 'type', 'label', etc.
457 * Example: ['type' => 'text', 'label' => 'Enter text'].
458 * @return void
459 */
460 public function register_children( $parents_trace, $control_id, $args ) {
461
462 // Validate $parents_trace to ensure it contains valid keys
463 if ( ! is_array( $parents_trace ) || empty( $parents_trace ) ) {
464 _doing_it_wrong(
465 'Block::register_children',
466 'The $parents_trace parameter must be a non-empty array of valid keys.',
467 '1.0.0'
468 );
469 return;
470 }
471
472 // Validate $control_id to ensure it's a non-empty string
473 if ( ! is_string( $control_id ) || empty( $control_id ) ) {
474 _doing_it_wrong(
475 'Block::register_children',
476 'The $control_id parameter must be a non-empty string.',
477 '1.0.0'
478 );
479 return;
480 }
481
482 // Validate $args to ensure it's an array
483 if ( ! is_array( $args ) || empty( $args ) ) {
484 _doing_it_wrong(
485 'Block::register_children',
486 'The $args parameter must be a non-empty array.',
487 '1.0.0'
488 );
489 return;
490 }
491
492 $controls = &$this->controls_stack;
493
494 foreach ( $parents_trace as $parent ) {
495
496 if ( ! isset( $controls['children'][ $parent ] ) ) {
497 _doing_it_wrong(
498 'Block::register_children',
499 "Parent control `$parent` not found in the controls stack.",
500 '1.0.0'
501 );
502 return;
503 }
504
505 $controls = &$controls['children'][ $parent ];
506
507 if ( ! isset( $controls['children'] ) ) {
508 $controls['children'] = array();
509 }
510
511 // Check if is last parent in the trace and register the control
512 if ( end( $parents_trace ) === $parent ) {
513 $controls['children'][ $control_id ] = $args;
514 }
515 }
516 }
517 }