PluginProbe
Tableberg – Simple Gutenberg Table Block / 1.0.5
Tableberg – Simple Gutenberg Table Block v1.0.5
1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.5 1.0.4 1.0.3 1.0.2 1.0.1 trunk 0.0.2 0.2.1 0.3.2 0.3.3 0.4.1 0.5.0 0.5.1 0.5.2 0.5.3 0.5.4 0.5.5 0.5.6 0.5.7 All 42 releases
tableberg / renderer / Migrations / TableBlockMigratorV0ToV1.php

TableBlockMigratorV0ToV1.php in Tableberg – Simple Gutenberg Table Block 1.0.5, at renderer/Migrations/TableBlockMigratorV0ToV1.php

2,224 lines 76.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Tableberg\Renderer\Migrations;
4
5 class TableBlockMigratorV0ToV1 {
6 public function migrate($attrs, $block = null) {
7 if (!is_array($attrs)) {
8 return $attrs;
9 }
10
11 $legacy_cells = $this->get_legacy_cell_blocks($block);
12
13 $rows = (int) $this->get_scalar($attrs, 'rows', 0);
14 $cols = (int) $this->get_scalar($attrs, 'cols', 0);
15
16 foreach ($legacy_cells as $legacy_cell) {
17 $legacy_cell_attrs = $this->get_block_attrs($legacy_cell);
18 $row = (int) $this->get_scalar($legacy_cell_attrs, 'row', 0);
19 $col = (int) $this->get_scalar($legacy_cell_attrs, 'col', 0);
20 $rowspan = max(1, (int) $this->get_scalar($legacy_cell_attrs, 'rowspan', 1));
21 $colspan = max(1, (int) $this->get_scalar($legacy_cell_attrs, 'colspan', 1));
22
23 $rows = max($rows, $row + $rowspan);
24 $cols = max($cols, $col + $colspan);
25 }
26
27 if (count($legacy_cells) === 0 && $rows > 0 && $cols > 0) {
28 $legacy_cells = $this->create_synthetic_cells($rows, $cols);
29 }
30
31 $structure_cells = array();
32 $data_cells = array();
33 $cell_style_cells = array();
34
35 foreach ($legacy_cells as $legacy_cell) {
36 $legacy_cell_attrs = $this->get_block_attrs($legacy_cell);
37 $row = (int) $this->get_scalar($legacy_cell_attrs, 'row', 0);
38 $col = (int) $this->get_scalar($legacy_cell_attrs, 'col', 0);
39 $rowspan = max(1, (int) $this->get_scalar($legacy_cell_attrs, 'rowspan', 1));
40 $colspan = max(1, (int) $this->get_scalar($legacy_cell_attrs, 'colspan', 1));
41 $coords = array($row, $col);
42
43 if ($rowspan !== 1 || $colspan !== 1) {
44 $structure_cells[] = array(
45 $coords,
46 array(
47 'rowSpan' => $rowspan,
48 'colSpan' => $colspan,
49 ),
50 );
51 }
52
53 $migrated_cell = $this->migrate_legacy_cell(
54 $legacy_cell,
55 $attrs,
56 $rows,
57 $cols
58 );
59
60 $data_cells[] = array($coords, $migrated_cell['elements']);
61
62 if (
63 !empty($migrated_cell['styles']) ||
64 $migrated_cell['ribbon'] !== null
65 ) {
66 $style_entry = $migrated_cell['styles'];
67
68 if ($migrated_cell['ribbon'] !== null) {
69 $style_entry['ribbon'] = $migrated_cell['ribbon'];
70 }
71
72 $cell_style_cells[] = array($coords, $style_entry);
73 }
74 }
75
76 return array(
77 'version' => 1,
78 'isExample' => isset($attrs['isExample']) ? (bool) $attrs['isExample'] : false,
79 'structure' => array(
80 'rows' => $rows,
81 'cols' => $cols,
82 'cells' => $structure_cells,
83 'columns' => $this->migrate_columns($attrs, $cols),
84 'rowConfigs' => $this->migrate_row_configs($attrs, $rows),
85 ),
86 'data' => array(
87 'cells' => $data_cells,
88 ),
89 'tableConfig' => $this->migrate_table_config($attrs, $rows, $cols),
90 'cellStyles' => array(
91 'cells' => $cell_style_cells,
92 'padding' => $this->get_legacy_cell_padding($attrs),
93 'border' => $this->get_legacy_global_cell_border($attrs),
94 'borderRadius' => $this->normalize_border_radius(
95 $this->get_scalar($attrs, 'cellBorderRadius', array())
96 ),
97 'orientation' => 'vertical',
98 'elementGap' => $this->normalize_css_value(
99 $this->get_scalar($attrs, 'blockSpacing', '0')
100 ),
101 'wrap' => 'nowrap',
102 'verticalAlign' => 'middle',
103 'backgroundColor' => '',
104 ),
105 'bindings' => array(),
106 );
107 }
108
109 private function migrate_table_config($attrs, $rows, $cols) {
110 $table_dimensions = $this->map_table_dimensions(
111 $this->get_scalar($attrs, 'tableWidth', ''),
112 $this->get_scalar($attrs, 'tableAlignment', '')
113 );
114 $legacy_search_position = $this->get_scalar($attrs, 'searchPosition', 'left');
115 $legacy_responsive = $this->get_array($attrs, 'responsive', array());
116 $legacy_breakpoints = $this->get_array($legacy_responsive, 'breakpoints', array());
117
118 return array(
119 'headerEnabled' => $this->is_legacy_section_enabled(
120 $this->get_scalar($attrs, 'enableTableHeader', '')
121 ),
122 'footerEnabled' => $this->is_legacy_section_enabled(
123 $this->get_scalar($attrs, 'enableTableFooter', '')
124 ),
125 'stickyHeader' => !empty($attrs['stickyTopRow']),
126 'caption' => (string) $this->get_scalar($attrs, 'caption', ''),
127 'tableWidth' => $table_dimensions['tableWidth'],
128 'tableAlignment' => $table_dimensions['tableAlignment'],
129 'cellSpacing' => array(
130 'horizontal' => $this->pick_spacing_side(
131 $this->get_scalar($attrs, 'cellSpacing', array()),
132 array('left', 'right'),
133 '0'
134 ),
135 'vertical' => $this->pick_spacing_side(
136 $this->get_scalar($attrs, 'cellSpacing', array()),
137 array('top', 'bottom'),
138 '0'
139 ),
140 ),
141 'tableBorder' => $this->normalize_border_sides(
142 $this->get_scalar($attrs, 'tableBorder', array())
143 ),
144 'fixedColumnWidths' => array_key_exists('fixedColWidth', $attrs)
145 ? (bool) $attrs['fixedColWidth']
146 : true,
147 'pagination' => array(
148 'enabled' => false,
149 'pageSize' => 10,
150 'showPageNumbers' => true,
151 'showPrevNext' => true,
152 ),
153 'search' => array(
154 'enabled' => !empty($attrs['search']),
155 'placeholder' => (string) $this->get_scalar(
156 $attrs,
157 'searchPlaceholder',
158 'Search...'
159 ),
160 'highlightColor' => '',
161 'position' => $legacy_search_position === 'right' ? 'right' : 'left',
162 ),
163 'responsive' => array(
164 'tablet' => $this->migrate_responsive_breakpoint(
165 $this->get_array($legacy_breakpoints, 'tablet', array()),
166 array(
167 'enabled' => false,
168 'maxWidth' => 1024,
169 'mode' => 'scroll',
170 'transpose' => false,
171 'stackCount' => 3,
172 'repeatFirstCol' => false,
173 )
174 ),
175 'mobile' => $this->migrate_responsive_breakpoint(
176 $this->get_array($legacy_breakpoints, 'mobile', array()),
177 array(
178 'enabled' => false,
179 'maxWidth' => 700,
180 'mode' => 'scroll',
181 'transpose' => false,
182 'stackCount' => 1,
183 'repeatFirstCol' => false,
184 )
185 ),
186 ),
187 'rows' => $rows,
188 'cols' => $cols,
189 );
190 }
191
192 private function migrate_columns($attrs, $cols) {
193 $columns = array();
194 $col_styles = $this->get_array($attrs, 'colStyles', array());
195 $legacy_col_widths = $this->get_scalar($attrs, 'colWidths', array());
196
197 for ($column = 0; $column < $cols; $column++) {
198 $legacy_column = $this->get_array($col_styles, $column, array());
199 $width = $this->normalize_css_value(
200 $this->get_scalar(
201 $legacy_column,
202 'width',
203 is_array($legacy_col_widths) && isset($legacy_col_widths[$column])
204 ? $legacy_col_widths[$column]
205 : ''
206 )
207 );
208
209 if ($width !== '') {
210 $columns[$column] = array('width' => $width);
211 }
212 }
213
214 return $columns;
215 }
216
217 private function migrate_row_configs($attrs, $rows) {
218 $row_configs = array();
219 $row_styles = $this->get_array($attrs, 'rowStyles', array());
220 $legacy_row_heights = $this->get_scalar($attrs, 'rowHeights', array());
221
222 for ($row = 0; $row < $rows; $row++) {
223 $legacy_row = $this->get_array($row_styles, $row, array());
224 $height = $this->normalize_css_value(
225 $this->get_scalar(
226 $legacy_row,
227 'height',
228 is_array($legacy_row_heights) && isset($legacy_row_heights[$row])
229 ? $legacy_row_heights[$row]
230 : ''
231 )
232 );
233
234 if ($height !== '') {
235 $row_configs[$row] = array('height' => $height);
236 }
237 }
238
239 return $row_configs;
240 }
241
242 private function migrate_responsive_breakpoint($legacy_breakpoint, $defaults) {
243 $legacy_breakpoint = is_array($legacy_breakpoint) ? $legacy_breakpoint : array();
244 $legacy_direction = $this->get_scalar($legacy_breakpoint, 'direction', null);
245
246 return array(
247 'enabled' => array_key_exists('enabled', $legacy_breakpoint)
248 ? (bool) $legacy_breakpoint['enabled']
249 : $defaults['enabled'],
250 'maxWidth' => (int) $this->get_scalar(
251 $legacy_breakpoint,
252 'maxWidth',
253 $defaults['maxWidth']
254 ),
255 'mode' => (string) $this->get_scalar(
256 $legacy_breakpoint,
257 'mode',
258 $defaults['mode']
259 ),
260 'transpose' => $legacy_direction === null
261 ? $defaults['transpose']
262 : $legacy_direction === 'row',
263 'stackCount' => max(
264 1,
265 (int) $this->get_scalar(
266 $legacy_breakpoint,
267 'stackCount',
268 $defaults['stackCount']
269 )
270 ),
271 'repeatFirstCol' => array_key_exists('headerAsCol', $legacy_breakpoint)
272 ? (bool) $legacy_breakpoint['headerAsCol']
273 : $defaults['repeatFirstCol'],
274 );
275 }
276
277 private function migrate_legacy_cell($cell_block, $table_attrs, $rows, $cols) {
278 $legacy_cell_attrs = $this->get_block_attrs($cell_block);
279 $elements = array();
280 $ribbon = null;
281
282 foreach ($this->get_block_inner_blocks($cell_block) as $inner_block) {
283 $migrated_block = $this->migrate_legacy_inner_block(
284 $inner_block,
285 $legacy_cell_attrs,
286 $table_attrs
287 );
288
289 if (!empty($migrated_block['elements'])) {
290 $elements = array_merge($elements, $migrated_block['elements']);
291 }
292
293 if ($ribbon === null && $migrated_block['ribbon'] !== null) {
294 $ribbon = $migrated_block['ribbon'];
295 }
296 }
297
298 $styles = $this->build_cell_style_overrides(
299 $legacy_cell_attrs,
300 $table_attrs,
301 $rows,
302 $cols
303 );
304
305 return array(
306 'elements' => $elements,
307 'styles' => $styles,
308 'ribbon' => $ribbon,
309 );
310 }
311
312 private function build_cell_style_overrides($cell_attrs, $table_attrs, $rows, $cols) {
313 $styles = array();
314 $background_color = $this->resolve_cell_background_color(
315 $cell_attrs,
316 $table_attrs,
317 $rows
318 );
319
320 if ($background_color !== '') {
321 $styles['backgroundColor'] = $background_color;
322 }
323
324 $border = $this->resolve_cell_border($cell_attrs, $table_attrs, $rows, $cols);
325 if ($this->has_any_non_empty_value($border)) {
326 $styles['border'] = $border;
327 }
328
329 $border_radius = $this->resolve_cell_border_radius(
330 $cell_attrs,
331 $table_attrs,
332 $rows,
333 $cols
334 );
335 if ($this->has_any_non_empty_value($border_radius)) {
336 $styles['borderRadius'] = $border_radius;
337 }
338
339 if (!empty($cell_attrs['isHorizontal'])) {
340 $styles['orientation'] = 'horizontal';
341 }
342
343 $wrap_items = array_key_exists('wrapItems', $cell_attrs)
344 ? (bool) $cell_attrs['wrapItems']
345 : true;
346 if (!empty($cell_attrs['isHorizontal']) || array_key_exists('wrapItems', $cell_attrs)) {
347 $styles['wrap'] = $wrap_items ? 'wrap' : 'nowrap';
348 }
349
350 $vertical_align = $this->map_vertical_align(
351 $this->get_scalar($cell_attrs, 'vAlign', 'center')
352 );
353 if ($vertical_align !== 'middle') {
354 $styles['verticalAlign'] = $vertical_align;
355 }
356
357 $global_gap = $this->normalize_css_value(
358 $this->get_scalar($table_attrs, 'blockSpacing', '0')
359 );
360 $cell_gap = $this->normalize_css_value(
361 $this->get_scalar($cell_attrs, 'blockSpacing', '')
362 );
363
364 if ($cell_gap !== '' && $cell_gap !== $global_gap) {
365 $styles['elementGap'] = $cell_gap;
366 }
367
368 return $styles;
369 }
370
371 private function resolve_cell_background_color($cell_attrs, $table_attrs, $rows) {
372 $background_color = $this->get_background_value(
373 $this->get_array(
374 $this->get_array($table_attrs, 'colStyles', array()),
375 (int) $this->get_scalar($cell_attrs, 'col', 0),
376 array()
377 )
378 );
379
380 $row = (int) $this->get_scalar($cell_attrs, 'row', 0);
381 if ($this->is_header_cell($cell_attrs, $table_attrs)) {
382 $header_background = $this->normalize_css_value(
383 $this->get_scalar($table_attrs, 'headerBackgroundColor', '')
384 );
385 if ($header_background !== '') {
386 $background_color = $header_background;
387 }
388 } elseif ($this->is_footer_cell($cell_attrs, $table_attrs, $rows)) {
389 $footer_background = $this->normalize_css_value(
390 $this->get_scalar($table_attrs, 'footerBackgroundColor', '')
391 );
392 if ($footer_background !== '') {
393 $background_color = $footer_background;
394 }
395 } else {
396 $row_background = $this->normalize_css_value(
397 $this->get_scalar(
398 $table_attrs,
399 $this->is_odd_data_row($row, $table_attrs)
400 ? 'oddRowBackgroundColor'
401 : 'evenRowBackgroundColor',
402 ''
403 )
404 );
405 if ($row_background !== '') {
406 $background_color = $row_background;
407 }
408 }
409
410 $row_background = $this->get_background_value(
411 $this->get_array(
412 $this->get_array($table_attrs, 'rowStyles', array()),
413 $row,
414 array()
415 )
416 );
417 if ($row_background !== '') {
418 $background_color = $row_background;
419 }
420
421 $cell_background = $this->get_background_value($cell_attrs);
422 if ($cell_background !== '') {
423 $background_color = $cell_background;
424 }
425
426 return $background_color;
427 }
428
429 private function resolve_cell_border($cell_attrs, $table_attrs, $rows, $cols) {
430 $row = (int) $this->get_scalar($cell_attrs, 'row', 0);
431 $col = (int) $this->get_scalar($cell_attrs, 'col', 0);
432 $rowspan = max(1, (int) $this->get_scalar($cell_attrs, 'rowspan', 1));
433 $colspan = max(1, (int) $this->get_scalar($cell_attrs, 'colspan', 1));
434 $touches_first_row = $row === 0;
435 $touches_last_row = $row + $rowspan >= $rows;
436 $touches_first_col = $col === 0;
437 $touches_last_col = $col + $colspan >= $cols;
438
439 $border = $this->get_inner_border_for_cell($cell_attrs, $table_attrs, $rows, $cols);
440
441 $col_style = $this->get_array(
442 $this->get_array($table_attrs, 'colStyles', array()),
443 $col,
444 array()
445 );
446 $col_border = $this->normalize_border_sides(
447 $this->get_scalar($col_style, 'border', array())
448 );
449 if ($col_border['left'] !== '') {
450 $border['left'] = $col_border['left'];
451 }
452 if ($col_border['right'] !== '') {
453 $border['right'] = $col_border['right'];
454 }
455 if ($touches_first_row && $col_border['top'] !== '') {
456 $border['top'] = $col_border['top'];
457 }
458 if ($touches_last_row && $col_border['bottom'] !== '') {
459 $border['bottom'] = $col_border['bottom'];
460 }
461
462 $row_style = $this->get_array(
463 $this->get_array($table_attrs, 'rowStyles', array()),
464 $row,
465 array()
466 );
467 $row_border = $this->normalize_border_sides(
468 $this->get_scalar($row_style, 'border', array())
469 );
470 $border['top'] = $row_border['top'] !== '' ? $row_border['top'] : $border['top'];
471 $border['bottom'] = $row_border['bottom'] !== ''
472 ? $row_border['bottom']
473 : $border['bottom'];
474 if ($touches_first_col && $row_border['left'] !== '') {
475 $border['left'] = $row_border['left'];
476 }
477 if ($touches_last_col && $row_border['right'] !== '') {
478 $border['right'] = $row_border['right'];
479 }
480
481 $cell_border = $this->normalize_border_sides(
482 $this->get_scalar($cell_attrs, 'border', array())
483 );
484
485 return array_merge($border, array_filter($cell_border, function ($value) {
486 return $value !== '';
487 }));
488 }
489
490 private function get_inner_border_for_cell($cell_attrs, $table_attrs, $rows, $cols) {
491 if (!$this->is_legacy_inner_border_enabled($table_attrs)) {
492 return $this->get_empty_border_sides();
493 }
494
495 $row = (int) $this->get_scalar($cell_attrs, 'row', 0);
496 $col = (int) $this->get_scalar($cell_attrs, 'col', 0);
497 $rowspan = max(1, (int) $this->get_scalar($cell_attrs, 'rowspan', 1));
498 $colspan = max(1, (int) $this->get_scalar($cell_attrs, 'colspan', 1));
499 $touches_first_row = $row === 0;
500 $touches_last_row = $row + $rowspan >= $rows;
501 $touches_first_col = $col === 0;
502 $touches_last_col = $col + $colspan >= $cols;
503
504 $border = $this->get_legacy_inner_border($table_attrs);
505
506 $inner_border_type = $this->get_scalar($table_attrs, 'innerBorderType', '');
507 if ($inner_border_type === 'row') {
508 if (!$touches_first_col) {
509 $border['left'] = '';
510 }
511 if (!$touches_last_col) {
512 $border['right'] = '';
513 }
514 } elseif ($inner_border_type === 'col') {
515 if (!$touches_first_row) {
516 $border['top'] = '';
517 }
518 if (!$touches_last_row) {
519 $border['bottom'] = '';
520 }
521 }
522
523 if (!empty($table_attrs['hideCellOutsideBorders'])) {
524 if ($touches_first_row) {
525 $border['top'] = '';
526 }
527 if ($touches_last_row) {
528 $border['bottom'] = '';
529 }
530 if ($touches_first_col) {
531 $border['left'] = '';
532 }
533 if ($touches_last_col) {
534 $border['right'] = '';
535 }
536 }
537
538 return $border;
539 }
540
541 private function get_legacy_global_cell_border($attrs) {
542 if (!$this->is_legacy_inner_border_enabled($attrs)) {
543 return $this->get_empty_border_sides();
544 }
545
546 return $this->get_legacy_inner_border($attrs);
547 }
548
549 private function get_legacy_cell_padding($attrs) {
550 $cell_padding = $this->normalize_spacing(
551 $this->get_scalar($attrs, 'cellPadding', array())
552 );
553
554 $default_padding = array(
555 'top' => 'var(--wp--preset--spacing--20)',
556 'right' => 'var(--wp--preset--spacing--20)',
557 'bottom' => 'var(--wp--preset--spacing--20)',
558 'left' => 'var(--wp--preset--spacing--20)',
559 );
560
561 foreach ($default_padding as $side => $default_value) {
562 if ($cell_padding[$side] === '') {
563 $cell_padding[$side] = $default_value;
564 }
565 }
566
567 return $cell_padding;
568 }
569
570 private function is_legacy_inner_border_enabled($attrs) {
571 if (!is_array($attrs) || !array_key_exists('enableInnerBorder', $attrs)) {
572 return true;
573 }
574
575 return (bool) $attrs['enableInnerBorder'];
576 }
577
578 private function get_legacy_inner_border($attrs) {
579 $legacy_inner_border = $this->get_scalar(
580 $attrs,
581 'innerBorder',
582 array(
583 'color' => '#000000',
584 'width' => '1px',
585 )
586 );
587
588 if (!is_array($legacy_inner_border) || empty($legacy_inner_border)) {
589 $legacy_inner_border = array(
590 'color' => '#000000',
591 'width' => '1px',
592 );
593 }
594
595 return $this->normalize_border_sides($legacy_inner_border);
596 }
597
598 private function resolve_cell_border_radius($cell_attrs, $table_attrs, $rows, $cols) {
599 $row = (int) $this->get_scalar($cell_attrs, 'row', 0);
600 $col = (int) $this->get_scalar($cell_attrs, 'col', 0);
601 $rowspan = max(1, (int) $this->get_scalar($cell_attrs, 'rowspan', 1));
602 $colspan = max(1, (int) $this->get_scalar($cell_attrs, 'colspan', 1));
603 $touches_first_row = $row === 0;
604 $touches_last_row = $row + $rowspan >= $rows;
605 $touches_first_col = $col === 0;
606 $touches_last_col = $col + $colspan >= $cols;
607
608 $border_radius = $this->get_empty_border_radius();
609
610 $col_style = $this->get_array(
611 $this->get_array($table_attrs, 'colStyles', array()),
612 $col,
613 array()
614 );
615 $col_radius = $this->normalize_border_radius(
616 $this->get_scalar($col_style, 'borderRadius', array())
617 );
618 if ($touches_first_row) {
619 $border_radius['topLeft'] = $col_radius['topLeft'];
620 $border_radius['topRight'] = $col_radius['topRight'];
621 }
622 if ($touches_last_row) {
623 $border_radius['bottomLeft'] = $col_radius['bottomLeft'];
624 $border_radius['bottomRight'] = $col_radius['bottomRight'];
625 }
626
627 $row_style = $this->get_array(
628 $this->get_array($table_attrs, 'rowStyles', array()),
629 $row,
630 array()
631 );
632 $row_radius = $this->normalize_border_radius(
633 $this->get_scalar($row_style, 'borderRadius', array())
634 );
635 if ($touches_first_col) {
636 if ($row_radius['topLeft'] !== '') {
637 $border_radius['topLeft'] = $row_radius['topLeft'];
638 }
639 if ($row_radius['bottomLeft'] !== '') {
640 $border_radius['bottomLeft'] = $row_radius['bottomLeft'];
641 }
642 }
643 if ($touches_last_col) {
644 if ($row_radius['topRight'] !== '') {
645 $border_radius['topRight'] = $row_radius['topRight'];
646 }
647 if ($row_radius['bottomRight'] !== '') {
648 $border_radius['bottomRight'] = $row_radius['bottomRight'];
649 }
650 }
651
652 $cell_radius = $this->normalize_border_radius(
653 $this->get_scalar($cell_attrs, 'borderRadius', array())
654 );
655
656 return array_merge($border_radius, array_filter($cell_radius, function ($value) {
657 return $value !== '';
658 }));
659 }
660
661 private function migrate_legacy_inner_block($block, $legacy_cell_attrs, $table_attrs) {
662 $block_name = $this->get_block_name($block);
663 $block_attrs = $this->get_block_attrs($block);
664
665 switch ($block_name) {
666 case 'core/paragraph':
667 return array(
668 'elements' => array($this->migrate_paragraph_element(
669 $block,
670 $block_attrs,
671 $legacy_cell_attrs,
672 $table_attrs
673 )),
674 'ribbon' => null,
675 );
676
677 case 'tableberg/button':
678 return array(
679 'elements' => array($this->migrate_button_element(
680 $block_attrs,
681 $legacy_cell_attrs,
682 $table_attrs
683 )),
684 'ribbon' => null,
685 );
686
687 case 'tableberg/image':
688 return array(
689 'elements' => array($this->migrate_image_element(
690 $block_attrs,
691 $legacy_cell_attrs
692 )),
693 'ribbon' => null,
694 );
695
696 case 'core/list':
697 return array(
698 'elements' => array($this->migrate_core_list_element(
699 $block,
700 $block_attrs,
701 $legacy_cell_attrs,
702 $table_attrs
703 )),
704 'ribbon' => null,
705 );
706
707 case 'tableberg/styled-list':
708 return array(
709 'elements' => array($this->migrate_styled_list_element(
710 $block,
711 $block_attrs,
712 $legacy_cell_attrs,
713 $table_attrs
714 )),
715 'ribbon' => null,
716 );
717
718 case 'tableberg/icon':
719 return array(
720 'elements' => array($this->migrate_icon_element(
721 $block_attrs,
722 $legacy_cell_attrs
723 )),
724 'ribbon' => null,
725 );
726
727 case 'tableberg/star-rating':
728 return array(
729 'elements' => array($this->migrate_star_rating_element(
730 $block_attrs,
731 $legacy_cell_attrs,
732 $table_attrs
733 )),
734 'ribbon' => null,
735 );
736
737 case 'tableberg/html':
738 return array(
739 'elements' => array($this->migrate_custom_html_element(
740 $block_attrs,
741 $legacy_cell_attrs
742 )),
743 'ribbon' => null,
744 );
745
746 case 'tableberg/ribbon':
747 return array(
748 'elements' => array(),
749 'ribbon' => $this->migrate_ribbon($block_attrs),
750 );
751
752 case 'tableberg/dynamic-field':
753 return $this->migrate_dynamic_field_block(
754 $block,
755 $legacy_cell_attrs,
756 $table_attrs
757 );
758 }
759
760 $inner_blocks = $this->get_block_inner_blocks($block);
761 if (!empty($inner_blocks)) {
762 $elements = array();
763 $ribbon = null;
764
765 foreach ($inner_blocks as $inner_block) {
766 $migrated_inner_block = $this->migrate_legacy_inner_block(
767 $inner_block,
768 $legacy_cell_attrs,
769 $table_attrs
770 );
771
772 if (!empty($migrated_inner_block['elements'])) {
773 $elements = array_merge($elements, $migrated_inner_block['elements']);
774 }
775
776 if ($ribbon === null && $migrated_inner_block['ribbon'] !== null) {
777 $ribbon = $migrated_inner_block['ribbon'];
778 }
779 }
780
781 return array(
782 'elements' => $elements,
783 'ribbon' => $ribbon,
784 );
785 }
786
787 $html = $this->extract_block_html($block);
788 if ($html === '') {
789 return array(
790 'elements' => array(),
791 'ribbon' => null,
792 );
793 }
794
795 return array(
796 'elements' => array(array(
797 'name' => 'custom-html',
798 'attributes' => array(
799 'content' => $html,
800 'align' => $this->resolve_element_alignment(null, $legacy_cell_attrs),
801 ),
802 )),
803 'ribbon' => null,
804 );
805 }
806
807 private function migrate_dynamic_field_block($block, $legacy_cell_attrs, $table_attrs) {
808 $elements = array();
809 $ribbon = null;
810
811 foreach ($this->get_block_inner_blocks($block) as $inner_block) {
812 $migrated_inner_block = $this->migrate_legacy_inner_block(
813 $inner_block,
814 $legacy_cell_attrs,
815 $table_attrs
816 );
817
818 if (!empty($migrated_inner_block['elements'])) {
819 $elements = array_merge($elements, $migrated_inner_block['elements']);
820 }
821
822 if ($ribbon === null && $migrated_inner_block['ribbon'] !== null) {
823 $ribbon = $migrated_inner_block['ribbon'];
824 }
825 }
826
827 return array(
828 'elements' => $elements,
829 'ribbon' => $ribbon,
830 );
831 }
832
833 private function migrate_paragraph_element($block, $attrs, $legacy_cell_attrs, $table_attrs) {
834 return array(
835 'name' => 'text',
836 'attributes' => array(
837 'content' => $this->extract_legacy_paragraph_content($block, $attrs),
838 'align' => $this->resolve_legacy_text_alignment(
839 $attrs,
840 $legacy_cell_attrs,
841 $table_attrs
842 ),
843 'styles' => array(
844 'textColor' => $this->extract_text_color(
845 $attrs,
846 $this->normalize_css_value(
847 $this->get_scalar($table_attrs, 'fontColor', '')
848 )
849 ),
850 'linkColor' => $this->extract_link_color(
851 $attrs,
852 $this->normalize_css_value(
853 $this->get_scalar($table_attrs, 'linkColor', '')
854 )
855 ),
856 'backgroundColor' => $this->extract_background_color($attrs),
857 'fontSize' => $this->extract_legacy_paragraph_font_size(
858 $block,
859 $attrs,
860 $this->normalize_css_value(
861 $this->get_scalar($table_attrs, 'fontSize', '')
862 )
863 ),
864 ),
865 ),
866 );
867 }
868
869 private function extract_legacy_paragraph_font_size($block, $attrs, $fallback) {
870 $font_size = $this->extract_font_size($attrs, '');
871 if ($font_size !== '') {
872 return $font_size;
873 }
874
875 $html = $this->extract_block_html($block);
876 if ($html === '') {
877 $html = $this->extract_block_html_from_attrs($attrs);
878 }
879
880 $html_font_size = $this->extract_first_tag_style_value($html, 'p', 'font-size');
881 if ($html_font_size !== null && $html_font_size !== '') {
882 return $html_font_size;
883 }
884
885 $html_font_size_slug = $this->extract_first_tag_class_font_size_slug($html, 'p');
886 if ($html_font_size_slug !== null && $html_font_size_slug !== '') {
887 return $this->map_legacy_font_size_slug($html_font_size_slug);
888 }
889
890 return $fallback;
891 }
892
893 private function resolve_legacy_text_alignment($attrs, $legacy_cell_attrs, $table_attrs) {
894 $align = $this->get_scalar($attrs, 'align', null);
895 if ($this->map_text_alignment($align, '') !== '') {
896 return $this->resolve_element_alignment($align, $legacy_cell_attrs);
897 }
898
899 $table_rows = max(1, (int) $this->get_scalar($table_attrs, 'rows', 0));
900 if (
901 $this->is_header_cell($legacy_cell_attrs, $table_attrs) ||
902 $this->is_footer_cell($legacy_cell_attrs, $table_attrs, $table_rows)
903 ) {
904 return 'center';
905 }
906
907 return $this->resolve_element_alignment($align, $legacy_cell_attrs);
908 }
909
910 private function extract_legacy_paragraph_content($block, $attrs) {
911 $content = $this->get_scalar($attrs, 'content', null);
912 if (is_string($content) && $content !== '') {
913 return $content;
914 }
915
916 $html = $this->extract_block_html($block);
917 if ($html === '') {
918 $html = $this->extract_block_html_from_attrs($attrs);
919 }
920 if ($html === '') {
921 return '';
922 }
923
924 $inner_html = $this->extract_first_tag_inner_html($html, 'p');
925 if ($inner_html !== null) {
926 return $inner_html;
927 }
928
929 return $html;
930 }
931
932 private function migrate_button_element($attrs, $legacy_cell_attrs, $table_attrs) {
933 return array(
934 'name' => 'button',
935 'attributes' => array(
936 'content' => (string) $this->get_scalar($attrs, 'text', ''),
937 'id' => (string) $this->get_scalar($attrs, 'id', ''),
938 'align' => $this->resolve_element_alignment(
939 $this->get_scalar($attrs, 'align', null),
940 $legacy_cell_attrs
941 ),
942 'link' => array(
943 'url' => (string) $this->get_scalar($attrs, 'url', ''),
944 'target' => $this->get_scalar($attrs, 'linkTarget', '') === '_blank'
945 ? '_blank'
946 : '_self',
947 ),
948 'styles' => array(
949 'backgroundColor' => $this->normalize_css_value(
950 $this->get_scalar($attrs, 'backgroundColor', '#000000')
951 ),
952 'textColor' => $this->normalize_css_value(
953 $this->get_scalar($attrs, 'textColor', '#ffffff')
954 ),
955 'backgroundHoverColor' => $this->normalize_css_value(
956 $this->get_scalar($attrs, 'backgroundHoverColor', '')
957 ),
958 'textHoverColor' => $this->normalize_css_value(
959 $this->get_scalar($attrs, 'textHoverColor', '')
960 ),
961 'textAlign' => $this->map_text_alignment(
962 $this->get_scalar($attrs, 'textAlign', 'center'),
963 'center'
964 ),
965 'width' => $this->map_button_width(
966 $this->get_scalar($attrs, 'width', null)
967 ),
968 'padding' => $this->normalize_spacing(
969 $this->get_scalar($attrs, 'padding', array())
970 ),
971 'borderRadius' => $this->normalize_border_radius(
972 $this->get_nested_value($attrs, array('style', 'border', 'radius'), array())
973 ),
974 'fontSize' => $this->extract_font_size(
975 $attrs,
976 $this->normalize_css_value(
977 $this->get_scalar($table_attrs, 'fontSize', '')
978 )
979 ),
980 ),
981 ),
982 );
983 }
984
985 private function migrate_image_element($attrs, $legacy_cell_attrs) {
986 $media = $this->get_array($attrs, 'media', array());
987
988 return array(
989 'name' => 'image',
990 'attributes' => array(
991 'media' => array(
992 'id' => is_numeric($this->get_scalar($media, 'id', null))
993 ? (int) $media['id']
994 : null,
995 'url' => (string) $this->get_scalar($media, 'url', ''),
996 'alt' => (string) $this->get_scalar($media, 'alt', ''),
997 'title' => (string) $this->get_scalar($media, 'title', ''),
998 'sizes' => $this->get_array($media, 'sizes', array()),
999 ),
1000 'height' => $this->normalize_css_value(
1001 $this->get_scalar($attrs, 'height', '')
1002 ),
1003 'width' => $this->normalize_css_value(
1004 $this->get_scalar($attrs, 'width', '')
1005 ),
1006 'alt' => (string) $this->get_scalar(
1007 $attrs,
1008 'alt',
1009 $this->get_scalar($media, 'alt', '')
1010 ),
1011 'align' => $this->resolve_element_alignment(
1012 $this->get_scalar($attrs, 'align', null),
1013 $legacy_cell_attrs
1014 ),
1015 'aspectRatio' => (string) $this->get_scalar($attrs, 'aspectRatio', ''),
1016 'scale' => (string) $this->get_scalar($attrs, 'scale', ''),
1017 'sizeSlug' => (string) $this->get_scalar($attrs, 'sizeSlug', 'large'),
1018 'caption' => (string) $this->get_scalar($attrs, 'caption', ''),
1019 'href' => (string) $this->get_scalar($attrs, 'href', ''),
1020 'linkTarget' => (string) $this->get_scalar($attrs, 'linkTarget', '_self'),
1021 'border' => $this->normalize_border_sides(
1022 $this->get_scalar($attrs, 'border', array())
1023 ),
1024 'borderRadius' => $this->normalize_border_radius(
1025 $this->get_scalar($attrs, 'borderRadius', array())
1026 ),
1027 ),
1028 );
1029 }
1030
1031 private function migrate_core_list_element($block, $attrs, $legacy_cell_attrs, $table_attrs) {
1032 $items = $this->parse_core_list_items($block, $attrs);
1033
1034 return array(
1035 'name' => 'list',
1036 'attributes' => array(
1037 'align' => $this->resolve_element_alignment(
1038 $this->get_scalar($attrs, 'align', null),
1039 $legacy_cell_attrs
1040 ),
1041 'items' => $items,
1042 'listType' => 'basic',
1043 'listStyle' => $this->resolve_core_list_style($attrs),
1044 'icon' => null,
1045 'styles' => array(
1046 'itemSpacing' => '0',
1047 'iconColor' => '',
1048 'iconSize' => '',
1049 'iconSpacing' => '',
1050 'fontSize' => $this->extract_font_size(
1051 $attrs,
1052 $this->normalize_css_value(
1053 $this->get_scalar($table_attrs, 'fontSize', '')
1054 )
1055 ),
1056 'textColor' => $this->extract_text_color(
1057 $attrs,
1058 $this->normalize_css_value(
1059 $this->get_scalar($table_attrs, 'fontColor', '')
1060 )
1061 ),
1062 'linkColor' => $this->extract_link_color(
1063 $attrs,
1064 $this->normalize_css_value(
1065 $this->get_scalar($table_attrs, 'linkColor', '')
1066 )
1067 ),
1068 'backgroundColor' => $this->extract_background_color($attrs),
1069 ),
1070 ),
1071 );
1072 }
1073
1074 private function parse_core_list_items($block, $attrs) {
1075 $items = array();
1076 $this->append_core_list_items($this->get_block_inner_blocks($block), 0, $items);
1077
1078 if (!empty($items)) {
1079 return $items;
1080 }
1081
1082 return $this->parse_list_items_from_html(
1083 (string) $this->get_scalar($attrs, 'values', $this->extract_block_html($block))
1084 );
1085 }
1086
1087 private function append_core_list_items($blocks, $indent_level, &$items) {
1088 foreach ($blocks as $block) {
1089 if (!is_array($block)) {
1090 continue;
1091 }
1092
1093 $block_name = $this->get_block_name($block);
1094
1095 if ($block_name === 'core/list') {
1096 $this->append_core_list_items(
1097 $this->get_block_inner_blocks($block),
1098 $indent_level,
1099 $items
1100 );
1101 continue;
1102 }
1103
1104 if ($block_name !== 'core/list-item') {
1105 continue;
1106 }
1107
1108 $block_attrs = $this->get_block_attrs($block);
1109 $items[] = array(
1110 'content' => $this->extract_core_list_item_content($block, $block_attrs),
1111 'indentLevel' => $indent_level,
1112 );
1113
1114 foreach ($this->get_block_inner_blocks($block) as $inner_block) {
1115 if ($this->get_block_name($inner_block) !== 'core/list') {
1116 continue;
1117 }
1118
1119 $this->append_core_list_items(
1120 $this->get_block_inner_blocks($inner_block),
1121 $indent_level + 1,
1122 $items
1123 );
1124 }
1125 }
1126 }
1127
1128 private function extract_core_list_item_content($block, $attrs) {
1129 $content = $this->get_scalar($attrs, 'content', null);
1130 if (is_string($content) && $content !== '') {
1131 return $content;
1132 }
1133
1134 $html = $this->extract_block_html($block);
1135 if ($html === '') {
1136 return '';
1137 }
1138
1139 $inner_html = $this->extract_first_tag_inner_html($html, 'li', array('ul', 'ol'));
1140 if ($inner_html !== null) {
1141 return trim($inner_html);
1142 }
1143
1144 return trim($html);
1145 }
1146
1147 private function migrate_styled_list_element($block, $attrs, $legacy_cell_attrs, $table_attrs) {
1148 $first_item_attrs = $this->get_first_styled_list_item_attrs($block);
1149 $icon = $this->migrate_legacy_icon_payload(
1150 $this->get_scalar($attrs, 'icon', null)
1151 );
1152 if ($icon === null) {
1153 $icon = $this->migrate_legacy_icon_payload(
1154 $this->get_scalar($first_item_attrs, 'icon', null)
1155 );
1156 }
1157 if ($icon === null && (!array_key_exists('icon', $attrs) || empty($attrs['icon']))) {
1158 $icon = $this->get_default_legacy_icon_payload();
1159 }
1160
1161 $parent_icon_color = $this->normalize_css_value(
1162 $this->get_scalar($attrs, 'iconColor', '')
1163 );
1164 $parent_icon_size = $this->normalize_css_value(
1165 $this->get_scalar($attrs, 'iconSize', '')
1166 );
1167 $parent_icon_spacing = $this->normalize_css_value(
1168 $this->get_scalar($attrs, 'iconSpacing', '')
1169 );
1170 $item_icon_spacing = $this->normalize_css_value(
1171 $this->get_scalar($first_item_attrs, 'iconSpacing', '')
1172 );
1173 $parent_font_size = $this->extract_font_size(
1174 $attrs,
1175 $this->normalize_css_value(
1176 $this->get_scalar($table_attrs, 'fontSize', '')
1177 )
1178 );
1179 $parent_text_color = $this->normalize_css_value(
1180 $this->get_scalar($attrs, 'textColor', '')
1181 );
1182
1183 return array(
1184 'name' => 'list',
1185 'attributes' => array(
1186 'align' => $this->resolve_element_alignment(
1187 $this->get_scalar($attrs, 'alignment', null),
1188 $legacy_cell_attrs
1189 ),
1190 'items' => $this->parse_styled_list_items($block),
1191 'listType' => 'styled',
1192 'listStyle' => 'none',
1193 'icon' => $icon,
1194 'styles' => array(
1195 'itemSpacing' => $this->normalize_css_value(
1196 $this->get_scalar($attrs, 'itemSpacing', '')
1197 ),
1198 'iconColor' => $parent_icon_color !== ''
1199 ? $parent_icon_color
1200 : $this->normalize_css_value(
1201 $this->get_scalar($first_item_attrs, 'iconColor', '')
1202 ),
1203 'iconSize' => $parent_icon_size !== ''
1204 ? $parent_icon_size
1205 : $this->normalize_css_value(
1206 $this->get_scalar($first_item_attrs, 'iconSize', '')
1207 ),
1208 'iconSpacing' => $parent_icon_spacing !== ''
1209 ? $parent_icon_spacing
1210 : ($item_icon_spacing !== ''
1211 ? $item_icon_spacing
1212 : 'var(--wp--preset--spacing--20)'),
1213 'fontSize' => $parent_font_size !== ''
1214 ? $parent_font_size
1215 : $this->extract_font_size(
1216 $first_item_attrs,
1217 $this->normalize_css_value(
1218 $this->get_scalar($table_attrs, 'fontSize', '')
1219 )
1220 ),
1221 'textColor' => $parent_text_color !== ''
1222 ? $parent_text_color
1223 : $this->normalize_css_value(
1224 $this->get_scalar($first_item_attrs, 'textColor', '')
1225 ),
1226 'linkColor' => $this->normalize_css_value(
1227 $this->get_scalar($table_attrs, 'linkColor', '')
1228 ),
1229 'backgroundColor' => $this->normalize_css_value(
1230 $this->get_scalar($attrs, 'backgroundColor', '')
1231 ),
1232 ),
1233 ),
1234 );
1235 }
1236
1237 private function get_first_styled_list_item_attrs($block) {
1238 foreach ($this->get_block_inner_blocks($block) as $inner_block) {
1239 $block_name = $this->get_block_name($inner_block);
1240
1241 if ($block_name === 'tableberg/styled-list-item') {
1242 return $this->get_block_attrs($inner_block);
1243 }
1244
1245 if ($block_name === 'tableberg/styled-list') {
1246 $nested_attrs = $this->get_first_styled_list_item_attrs($inner_block);
1247 if (!empty($nested_attrs)) {
1248 return $nested_attrs;
1249 }
1250 }
1251 }
1252
1253 return array();
1254 }
1255
1256 private function migrate_icon_element($attrs, $legacy_cell_attrs) {
1257 $icon = $this->migrate_legacy_icon_payload(
1258 $this->get_scalar($attrs, 'icon', null)
1259 );
1260 if ($icon === null) {
1261 $icon = $this->get_default_legacy_icon_payload();
1262 }
1263
1264 return array(
1265 'name' => 'icon',
1266 'attributes' => array(
1267 'icon' => $icon,
1268 'size' => $this->normalize_css_value(
1269 $this->get_scalar($attrs, 'size', '40px')
1270 ),
1271 'behavior' => $this->get_scalar($attrs, 'behavior', 'paragraph') === 'char'
1272 ? 'char'
1273 : 'paragraph',
1274 'link' => array(
1275 'url' => (string) $this->get_scalar($attrs, 'linkUrl', ''),
1276 'target' => $this->get_scalar($attrs, 'linkTarget', '') === '_blank'
1277 ? '_blank'
1278 : '_self',
1279 ),
1280 'styles' => array(
1281 'align' => $this->resolve_element_alignment(
1282 $this->get_scalar($attrs, 'justify', null),
1283 $legacy_cell_attrs
1284 ),
1285 'rotation' => (int) $this->get_scalar($attrs, 'rotation', 0),
1286 'color' => $this->normalize_css_value(
1287 $this->get_scalar($attrs, 'color', '')
1288 ),
1289 'colorHover' => $this->normalize_css_value(
1290 $this->get_scalar($attrs, 'colorHover', '')
1291 ),
1292 'background' => $this->normalize_css_value(
1293 $this->get_scalar($attrs, 'background', '')
1294 ),
1295 'backgroundHover' => $this->normalize_css_value(
1296 $this->get_scalar($attrs, 'backgroundHover', '')
1297 ),
1298 'padding' => $this->normalize_spacing(
1299 $this->get_scalar($attrs, 'padding', array())
1300 ),
1301 'border' => $this->normalize_border_sides(
1302 $this->get_scalar($attrs, 'border', array())
1303 ),
1304 'borderRadius' => $this->normalize_border_radius(
1305 $this->get_scalar($attrs, 'borderRadius', array())
1306 ),
1307 ),
1308 ),
1309 );
1310 }
1311
1312 private function migrate_star_rating_element($attrs, $legacy_cell_attrs, $table_attrs) {
1313 return array(
1314 'name' => 'star-rating',
1315 'attributes' => array(
1316 'starCount' => (int) $this->get_scalar($attrs, 'starCount', 5),
1317 'starSize' => (int) $this->get_scalar($attrs, 'starSize', 20),
1318 'starColor' => $this->normalize_css_value(
1319 $this->get_scalar($attrs, 'starColor', '#FF912C')
1320 ),
1321 'selectedStars' => (float) $this->get_scalar($attrs, 'selectedStars', 0),
1322 'enableText' => !empty($attrs['enableText']),
1323 'reviewText' => (string) $this->get_scalar($attrs, 'reviewText', ''),
1324 'reviewTextAlign' => $this->map_text_alignment(
1325 $this->get_scalar($attrs, 'reviewTextAlign', 'left'),
1326 'left'
1327 ),
1328 'reviewTextColor' => $this->normalize_css_value(
1329 $this->get_scalar($attrs, 'reviewTextColor', '')
1330 ),
1331 'reviewTextLinkColor' => $this->normalize_css_value(
1332 $this->get_scalar($table_attrs, 'linkColor', '')
1333 ),
1334 'reviewTextFontSize' => $this->extract_font_size(
1335 $attrs,
1336 $this->normalize_css_value(
1337 $this->get_scalar($table_attrs, 'fontSize', '')
1338 )
1339 ),
1340 'align' => $this->resolve_element_alignment(
1341 $this->get_scalar($attrs, 'starAlign', null),
1342 $legacy_cell_attrs
1343 ),
1344 ),
1345 );
1346 }
1347
1348 private function migrate_custom_html_element($attrs, $legacy_cell_attrs) {
1349 return array(
1350 'name' => 'custom-html',
1351 'attributes' => array(
1352 'content' => (string) $this->get_scalar($attrs, 'content', ''),
1353 'align' => $this->resolve_element_alignment(null, $legacy_cell_attrs),
1354 ),
1355 );
1356 }
1357
1358 private function migrate_ribbon($attrs) {
1359 $type = $this->get_scalar($attrs, 'type', 'side');
1360 if (!in_array($type, array('badge', 'bookmark', 'corner', 'side', 'icon'), true)) {
1361 $type = 'side';
1362 }
1363
1364 $ribbon_attrs = $this->get_default_ribbon_attrs($type);
1365 $individual = $this->get_array($attrs, 'individual', array());
1366
1367 $ribbon_attrs['text'] = (string) $this->get_scalar(
1368 $attrs,
1369 'text',
1370 $ribbon_attrs['text']
1371 );
1372 $ribbon_attrs['style']['color'] = $this->normalize_css_value(
1373 $this->get_scalar($attrs, 'color', $ribbon_attrs['style']['color'])
1374 );
1375 $ribbon_attrs['style']['background'] = $this->normalize_css_value(
1376 $this->get_scalar($attrs, 'background', $ribbon_attrs['style']['background'])
1377 );
1378 $ribbon_attrs['style']['bgGradient'] = $this->normalize_css_value(
1379 $this->get_scalar($attrs, 'bgGradient', $ribbon_attrs['style']['bgGradient'])
1380 );
1381 $ribbon_attrs['style']['fontSize'] = $this->normalize_css_value(
1382 $this->get_scalar($attrs, 'fontSize', $ribbon_attrs['style']['fontSize'])
1383 );
1384
1385 if (isset($individual['side']) && is_string($individual['side'])) {
1386 $ribbon_attrs['originX'] = $individual['side'] === 'right' ? 'right' : 'left';
1387 }
1388 if (isset($individual['originY']) && is_string($individual['originY'])) {
1389 $ribbon_attrs['originY'] = $individual['originY'];
1390 }
1391 foreach (array('x', 'y', 'height', 'width', 'iconSize', 'shape') as $key) {
1392 if (isset($individual[$key]) && is_string($individual[$key])) {
1393 $ribbon_attrs[$key] = $individual[$key];
1394 }
1395 }
1396 if (isset($individual['rotate']) && is_numeric($individual['rotate'])) {
1397 $ribbon_attrs['rotate'] = (int) $individual['rotate'];
1398 }
1399
1400 return array(
1401 'enabled' => true,
1402 'type' => $type,
1403 'attrs' => $ribbon_attrs,
1404 );
1405 }
1406
1407 private function get_default_ribbon_attrs($type) {
1408 $attrs = array(
1409 'text' => 'New',
1410 'originX' => 'left',
1411 'originY' => 'top',
1412 'x' => '-1px',
1413 'y' => '-3px',
1414 'rotate' => 0,
1415 'height' => '70px',
1416 'width' => '30px',
1417 'iconSize' => '20px',
1418 'shape' => 'up',
1419 'icon' => null,
1420 'style' => array(
1421 'color' => '#ffffff',
1422 'background' => '#671FEB',
1423 'bgGradient' => '',
1424 'fontSize' => '1.38rem',
1425 'padding' => array(
1426 'top' => 'var(--wp--preset--spacing--20)',
1427 'right' => 'var(--wp--preset--spacing--40)',
1428 'bottom' => 'var(--wp--preset--spacing--20)',
1429 'left' => 'var(--wp--preset--spacing--40)',
1430 ),
1431 'borderRadius' => array(
1432 'topLeft' => '4px',
1433 'topRight' => '4px',
1434 'bottomRight' => '4px',
1435 'bottomLeft' => '4px',
1436 ),
1437 ),
1438 );
1439
1440 switch ($type) {
1441 case 'bookmark':
1442 $attrs['x'] = '20px';
1443 $attrs['originX'] = 'right';
1444 break;
1445
1446 case 'corner':
1447 $attrs['y'] = '50px';
1448 break;
1449
1450 case 'icon':
1451 $attrs['x'] = '20px';
1452 $attrs['originX'] = 'right';
1453 $attrs['icon'] = array(
1454 'iconName' => 'star',
1455 'svg' => array(
1456 'viewBox' => '0 0 576 512',
1457 'path' => 'M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z',
1458 ),
1459 );
1460 break;
1461
1462 case 'side':
1463 $attrs['y'] = '10px';
1464 break;
1465 }
1466
1467 return $attrs;
1468 }
1469
1470 private function parse_styled_list_items($block) {
1471 $items = array();
1472 $this->append_styled_list_items($this->get_block_inner_blocks($block), 0, $items);
1473
1474 return $items;
1475 }
1476
1477 private function append_styled_list_items($blocks, $indent_level, &$items) {
1478 foreach ($blocks as $block) {
1479 if (!is_array($block)) {
1480 continue;
1481 }
1482
1483 $block_name = $this->get_block_name($block);
1484 if ($block_name === 'tableberg/styled-list') {
1485 $this->append_styled_list_items(
1486 $this->get_block_inner_blocks($block),
1487 $indent_level,
1488 $items
1489 );
1490 continue;
1491 }
1492
1493 if ($block_name !== 'tableberg/styled-list-item') {
1494 continue;
1495 }
1496
1497 $block_attrs = $this->get_block_attrs($block);
1498 $items[] = array(
1499 'content' => (string) $this->get_scalar($block_attrs, 'text', ''),
1500 'indentLevel' => $indent_level,
1501 );
1502
1503 foreach ($this->get_block_inner_blocks($block) as $inner_block) {
1504 if ($this->get_block_name($inner_block) !== 'tableberg/styled-list') {
1505 continue;
1506 }
1507
1508 $this->append_styled_list_items(
1509 $this->get_block_inner_blocks($inner_block),
1510 $indent_level + 1,
1511 $items
1512 );
1513 }
1514 }
1515 }
1516
1517 private function parse_list_items_from_html($html) {
1518 if (!is_string($html) || trim($html) === '') {
1519 return array();
1520 }
1521
1522 $items = array();
1523
1524 if (preg_match_all('/<li\b[^>]*>(.*?)<\/li>/is', $html, $matches)) {
1525 foreach ($matches[1] as $item_html) {
1526 $items[] = array(
1527 'content' => trim($this->strip_nested_list_markup($item_html)),
1528 'indentLevel' => 0,
1529 );
1530 }
1531 }
1532
1533 if (!empty($items)) {
1534 return $items;
1535 }
1536
1537 return array(array(
1538 'content' => $html,
1539 'indentLevel' => 0,
1540 ));
1541 }
1542
1543 private function resolve_core_list_style($attrs) {
1544 if (!empty($attrs['ordered'])) {
1545 return 'decimal';
1546 }
1547
1548 $class_name = (string) $this->get_scalar($attrs, 'className', '');
1549
1550 if (strpos($class_name, 'is-style-circle') !== false) {
1551 return 'circle';
1552 }
1553
1554 if (strpos($class_name, 'is-style-square') !== false) {
1555 return 'square';
1556 }
1557
1558 if (strpos($class_name, 'no-bullet') !== false) {
1559 return 'none';
1560 }
1561
1562 return 'disc';
1563 }
1564
1565 private function resolve_element_alignment($align, $legacy_cell_attrs) {
1566 $mapped_align = $this->map_text_alignment($align, '');
1567 if ($mapped_align !== '') {
1568 return $mapped_align;
1569 }
1570
1571 $justify_content = $this->get_scalar($legacy_cell_attrs, 'justifyContent', 'left');
1572 if ($justify_content === 'right') {
1573 return 'right';
1574 }
1575 if ($justify_content === 'center') {
1576 return 'center';
1577 }
1578
1579 return 'left';
1580 }
1581
1582 private function extract_text_color($attrs, $fallback) {
1583 $style_color = $this->get_nested_value($attrs, array('style', 'color', 'text'), null);
1584 if (is_string($style_color) && $style_color !== '') {
1585 return $this->normalize_css_value($style_color);
1586 }
1587
1588 $text_color_slug = $this->get_scalar($attrs, 'textColor', null);
1589 if (is_string($text_color_slug) && $text_color_slug !== '') {
1590 return $this->preset_slug_to_css_var('color', $text_color_slug);
1591 }
1592
1593 return $fallback;
1594 }
1595
1596 private function extract_link_color($attrs, $fallback) {
1597 $link_color = $this->get_nested_value(
1598 $attrs,
1599 array('style', 'elements', 'link', 'color', 'text'),
1600 null
1601 );
1602 if (is_string($link_color) && $link_color !== '') {
1603 return $this->normalize_css_value($link_color);
1604 }
1605
1606 return $fallback;
1607 }
1608
1609 private function extract_background_color($attrs) {
1610 $background_color = $this->get_nested_value($attrs, array('style', 'color', 'background'), null);
1611 if (is_string($background_color) && $background_color !== '') {
1612 return $this->normalize_css_value($background_color);
1613 }
1614
1615 $background_slug = $this->get_scalar($attrs, 'backgroundColor', null);
1616 if (is_string($background_slug) && $background_slug !== '') {
1617 return $this->preset_slug_to_css_var('color', $background_slug);
1618 }
1619
1620 return '';
1621 }
1622
1623 private function extract_font_size($attrs, $fallback) {
1624 $font_size = $this->get_nested_value($attrs, array('style', 'typography', 'fontSize'), null);
1625 if (is_string($font_size) && $font_size !== '') {
1626 return $this->normalize_css_value($font_size);
1627 }
1628
1629 $font_size_slug = $this->get_scalar($attrs, 'fontSize', null);
1630 if (is_string($font_size_slug) && $font_size_slug !== '') {
1631 return $this->map_legacy_font_size_slug($font_size_slug);
1632 }
1633
1634 return $fallback;
1635 }
1636
1637 private function get_background_value($attrs) {
1638 $background = $this->normalize_css_value($this->get_scalar($attrs, 'background', ''));
1639 if ($background !== '') {
1640 return $background;
1641 }
1642
1643 return $this->extract_background_color($attrs);
1644 }
1645
1646 private function map_vertical_align($align) {
1647 if ($align === 'top') {
1648 return 'top';
1649 }
1650
1651 if ($align === 'bottom') {
1652 return 'bottom';
1653 }
1654
1655 return 'middle';
1656 }
1657
1658 private function map_text_alignment($align, $default) {
1659 if (in_array($align, array('left', 'center', 'right'), true)) {
1660 return $align;
1661 }
1662
1663 return $default;
1664 }
1665
1666 private function map_button_width($width) {
1667 if ($width === null || $width === '' || $width === 0 || $width === '0') {
1668 return 'auto';
1669 }
1670
1671 if (is_numeric($width)) {
1672 $width = (string) max(1, min(100, (int) $width)) . '%';
1673 }
1674
1675 if (!is_string($width)) {
1676 return 'auto';
1677 }
1678
1679 return $width;
1680 }
1681
1682 private function map_table_dimensions($legacy_table_width, $legacy_table_alignment) {
1683 $table_width = $this->normalize_css_value(
1684 is_string($legacy_table_width) ? $legacy_table_width : ''
1685 );
1686 $table_alignment = $this->map_text_alignment($legacy_table_alignment, 'left');
1687
1688 if ($table_width === '') {
1689 $table_width = in_array($legacy_table_alignment, array('wide', 'full'), true)
1690 ? $legacy_table_alignment
1691 : 'auto';
1692 }
1693
1694 if (!in_array($table_width, array('auto', 'wide', 'full'), true) && $table_alignment === '') {
1695 $table_alignment = 'left';
1696 }
1697
1698 return array(
1699 'tableWidth' => $table_width,
1700 'tableAlignment' => $table_alignment === '' ? 'left' : $table_alignment,
1701 );
1702 }
1703
1704 private function is_legacy_section_enabled($value) {
1705 return is_string($value) && $value !== '';
1706 }
1707
1708 private function is_header_cell($cell_attrs, $table_attrs) {
1709 return $this->is_legacy_section_enabled(
1710 $this->get_scalar($table_attrs, 'enableTableHeader', '')
1711 ) && (int) $this->get_scalar($cell_attrs, 'row', 0) === 0;
1712 }
1713
1714 private function is_footer_cell($cell_attrs, $table_attrs, $rows) {
1715 return $this->is_legacy_section_enabled(
1716 $this->get_scalar($table_attrs, 'enableTableFooter', '')
1717 ) && (int) $this->get_scalar($cell_attrs, 'row', 0) + 1 === $rows;
1718 }
1719
1720 private function is_odd_data_row($row, $table_attrs) {
1721 $has_header = $this->is_legacy_section_enabled(
1722 $this->get_scalar($table_attrs, 'enableTableHeader', '')
1723 );
1724
1725 return (($row + ($has_header ? 0 : 1)) % 2) === 1;
1726 }
1727
1728 private function pick_spacing_side($spacing, $sides, $default) {
1729 if (!is_array($spacing)) {
1730 return $default;
1731 }
1732
1733 foreach ($sides as $side) {
1734 if (isset($spacing[$side]) && $spacing[$side] !== '') {
1735 return $this->normalize_css_value($spacing[$side]);
1736 }
1737 }
1738
1739 return $default;
1740 }
1741
1742 private function normalize_spacing($spacing) {
1743 $normalized = array(
1744 'top' => '',
1745 'right' => '',
1746 'bottom' => '',
1747 'left' => '',
1748 );
1749
1750 if (is_string($spacing) && $spacing !== '') {
1751 $spacing = array(
1752 'top' => $spacing,
1753 'right' => $spacing,
1754 'bottom' => $spacing,
1755 'left' => $spacing,
1756 );
1757 }
1758
1759 if (!is_array($spacing)) {
1760 return $normalized;
1761 }
1762
1763 foreach ($normalized as $side => $value) {
1764 if (isset($spacing[$side])) {
1765 $normalized[$side] = $this->normalize_css_value($spacing[$side]);
1766 }
1767 }
1768
1769 return $normalized;
1770 }
1771
1772 private function normalize_border_sides($border) {
1773 $normalized = $this->get_empty_border_sides();
1774
1775 if (is_string($border) && $border !== '') {
1776 foreach (array_keys($normalized) as $side) {
1777 $normalized[$side] = $border;
1778 }
1779 return $normalized;
1780 }
1781
1782 if (!is_array($border)) {
1783 return $normalized;
1784 }
1785
1786 $has_split_sides = false;
1787 foreach (array_keys($normalized) as $side) {
1788 if (isset($border[$side])) {
1789 $has_split_sides = true;
1790 break;
1791 }
1792 }
1793
1794 if ($has_split_sides) {
1795 foreach (array_keys($normalized) as $side) {
1796 $normalized[$side] = $this->normalize_single_border(
1797 isset($border[$side]) ? $border[$side] : null
1798 );
1799 }
1800 return $normalized;
1801 }
1802
1803 $single_border = $this->normalize_single_border($border);
1804 foreach (array_keys($normalized) as $side) {
1805 $normalized[$side] = $single_border;
1806 }
1807
1808 return $normalized;
1809 }
1810
1811 private function normalize_single_border($border) {
1812 if (is_string($border)) {
1813 return $border;
1814 }
1815
1816 if (!is_array($border)) {
1817 return '';
1818 }
1819
1820 $width = isset($border['width']) ? trim((string) $border['width']) : '';
1821 if ($width === '') {
1822 return '';
1823 }
1824
1825 $style = isset($border['style']) ? trim((string) $border['style']) : '';
1826 $color = isset($border['color']) ? trim((string) $border['color']) : '';
1827
1828 if ($style === '') {
1829 $style = 'solid';
1830 }
1831
1832 return trim($width . ' ' . $style . ' ' . $color);
1833 }
1834
1835 private function normalize_border_radius($radius) {
1836 $normalized = $this->get_empty_border_radius();
1837
1838 if (is_string($radius) && $radius !== '') {
1839 foreach (array_keys($normalized) as $corner) {
1840 $normalized[$corner] = $radius;
1841 }
1842 return $normalized;
1843 }
1844
1845 if (!is_array($radius)) {
1846 return $normalized;
1847 }
1848
1849 foreach (array_keys($normalized) as $corner) {
1850 if (isset($radius[$corner])) {
1851 $normalized[$corner] = $this->normalize_css_value($radius[$corner]);
1852 }
1853 }
1854
1855 return $normalized;
1856 }
1857
1858 private function migrate_legacy_icon_payload($icon) {
1859 if (!is_array($icon)) {
1860 return null;
1861 }
1862
1863 $migrated_icon = array(
1864 'iconName' => (string) $this->get_scalar($icon, 'iconName', ''),
1865 );
1866
1867 $url = $this->get_scalar($icon, 'url', null);
1868 if (is_string($url) && $url !== '') {
1869 $migrated_icon['url'] = $url;
1870 }
1871
1872 $svg = $this->extract_legacy_icon_svg($icon);
1873 if ($svg !== null) {
1874 $migrated_icon['svg'] = $svg;
1875 }
1876
1877 if (
1878 $migrated_icon['iconName'] === '' &&
1879 !isset($migrated_icon['svg']) &&
1880 !isset($migrated_icon['url'])
1881 ) {
1882 return null;
1883 }
1884
1885 return $migrated_icon;
1886 }
1887
1888 private function get_default_legacy_icon_payload() {
1889 return array(
1890 'iconName' => 'check',
1891 'svg' => array(
1892 'viewBox' => '0 0 512 512',
1893 'path' => 'M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z',
1894 ),
1895 );
1896 }
1897
1898 private function extract_legacy_icon_svg($icon) {
1899 $svg = $this->get_array($icon, 'svg', array());
1900 if (
1901 isset($svg['viewBox']) &&
1902 is_string($svg['viewBox']) &&
1903 isset($svg['path']) &&
1904 is_string($svg['path'])
1905 ) {
1906 return array(
1907 'viewBox' => $svg['viewBox'],
1908 'path' => $svg['path'],
1909 );
1910 }
1911
1912 $legacy_svg = $this->get_nested_value($icon, array('icon', 'props'), null);
1913 if (!is_array($legacy_svg)) {
1914 return null;
1915 }
1916
1917 $path = $this->get_nested_value($legacy_svg, array('children', 'props', 'd'), null);
1918 $view_box = $this->get_scalar($legacy_svg, 'viewBox', null);
1919
1920 if (!is_string($path) || $path === '' || !is_string($view_box) || $view_box === '') {
1921 return null;
1922 }
1923
1924 return array(
1925 'viewBox' => $view_box,
1926 'path' => $path,
1927 );
1928 }
1929
1930 private function extract_block_html($block) {
1931 if (!is_array($block)) {
1932 return '';
1933 }
1934
1935 if (isset($block['innerHTML']) && is_string($block['innerHTML'])) {
1936 return trim($block['innerHTML']);
1937 }
1938
1939 if (!isset($block['innerContent']) || !is_array($block['innerContent'])) {
1940 return '';
1941 }
1942
1943 $html = '';
1944 foreach ($block['innerContent'] as $content) {
1945 if (is_string($content)) {
1946 $html .= $content;
1947 }
1948 }
1949
1950 return trim($html);
1951 }
1952
1953 private function extract_block_html_from_attrs($attrs) {
1954 $html = $this->get_scalar($attrs, 'originalContent', null);
1955 if (is_string($html) && trim($html) !== '') {
1956 return trim($html);
1957 }
1958
1959 $html = $this->get_scalar($attrs, '__unstableOriginalContent', null);
1960 if (is_string($html) && trim($html) !== '') {
1961 return trim($html);
1962 }
1963
1964 return '';
1965 }
1966
1967 private function extract_first_tag_inner_html($html, $tag_name, $excluded_tags = array()) {
1968 if (!is_string($html) || trim($html) === '') {
1969 return null;
1970 }
1971
1972 $pattern = '/<' . preg_quote($tag_name, '/') . '\b[^>]*>(.*)<\/' . preg_quote($tag_name, '/') . '>/is';
1973 if (preg_match($pattern, $html, $matches)) {
1974 return trim($this->strip_tag_markup($matches[1], $excluded_tags));
1975 }
1976
1977 return null;
1978 }
1979
1980 private function extract_first_tag_style_value($html, $tag_name, $css_property) {
1981 if (!is_string($html) || trim($html) === '') {
1982 return null;
1983 }
1984
1985 $pattern = '/<' . preg_quote($tag_name, '/') . '\b[^>]*style=["\']([^"\']*)["\'][^>]*>/i';
1986 if (preg_match($pattern, $html, $matches)) {
1987 return $this->extract_style_declaration_value($matches[1], $css_property);
1988 }
1989
1990 return null;
1991 }
1992
1993 private function extract_style_declaration_value($style, $css_property) {
1994 if (!is_string($style) || trim($style) === '') {
1995 return null;
1996 }
1997
1998 $pattern = '/(?:^|;)\s*' . preg_quote($css_property, '/') . '\s*:\s*([^;]+)\s*(?:;|$)/i';
1999 if (!preg_match($pattern, $style, $matches)) {
2000 return null;
2001 }
2002
2003 return trim($matches[1]);
2004 }
2005
2006 private function extract_first_tag_class_font_size_slug($html, $tag_name) {
2007 if (!is_string($html) || trim($html) === '') {
2008 return null;
2009 }
2010
2011 $class_name = null;
2012 $pattern = '/<' . preg_quote($tag_name, '/') . '\b[^>]*class=["\']([^"\']*)["\'][^>]*>/i';
2013 if (preg_match($pattern, $html, $matches)) {
2014 $class_name = $matches[1];
2015 }
2016
2017 if (!is_string($class_name) || $class_name === '') {
2018 return null;
2019 }
2020
2021 if (preg_match('/(?:^|\s)has-([a-z0-9-]+)-font-size(?:\s|$)/i', $class_name, $matches)) {
2022 return strtolower($matches[1]);
2023 }
2024
2025 return null;
2026 }
2027
2028 private function strip_nested_list_markup($html) {
2029 return preg_replace('/<(ul|ol)\b[^>]*>.*?<\/\1>/is', '', $html);
2030 }
2031
2032 private function strip_tag_markup($html, $tag_names = array()) {
2033 if (!is_string($html) || empty($tag_names)) {
2034 return $html;
2035 }
2036
2037 foreach ($tag_names as $tag_name) {
2038 $html = preg_replace(
2039 '/<' . preg_quote($tag_name, '/') . '\b[^>]*>.*?<\/' . preg_quote($tag_name, '/') . '>/is',
2040 '',
2041 $html
2042 );
2043 }
2044
2045 return $html;
2046 }
2047
2048 private function normalize_css_value($value) {
2049 if (!is_string($value)) {
2050 return '';
2051 }
2052
2053 $value = trim($value);
2054 if ($value === '') {
2055 return '';
2056 }
2057
2058 if (preg_match('/^var:preset\|([^|]+)\|(.+)$/', $value, $matches)) {
2059 if ($matches[1] === 'spacing' && $matches[2] === '10') {
2060 return 'var(--wp--preset--spacing--20)';
2061 }
2062
2063 return 'var(--wp--preset--' . $matches[1] . '--' . $matches[2] . ')';
2064 }
2065
2066 return $value;
2067 }
2068
2069 private function preset_slug_to_css_var($group, $slug) {
2070 return 'var(--wp--preset--' . $group . '--' . $slug . ')';
2071 }
2072
2073 private function map_legacy_font_size_slug($slug) {
2074 $built_in_font_sizes = array(
2075 's' => '0.75rem',
2076 'small' => '0.75rem',
2077 'm' => '0.875rem',
2078 'normal' => '0.875rem',
2079 'medium' => '0.875rem',
2080 'l' => '1rem',
2081 'large' => '1rem',
2082 'xl' => '1.38rem',
2083 'x-large' => '1.38rem',
2084 'xlarge' => '1.38rem',
2085 'xxl' => '1.75rem',
2086 'xx-large' => '1.75rem',
2087 'xxlarge' => '1.75rem',
2088 'huge' => '1.75rem',
2089 );
2090
2091 $slug = strtolower((string) $slug);
2092
2093 if (isset($built_in_font_sizes[$slug])) {
2094 return $built_in_font_sizes[$slug];
2095 }
2096
2097 return $this->preset_slug_to_css_var('font-size', $slug);
2098 }
2099
2100 private function has_any_non_empty_value($values) {
2101 if (!is_array($values)) {
2102 return false;
2103 }
2104
2105 foreach ($values as $value) {
2106 if (is_string($value) && trim($value) !== '') {
2107 return true;
2108 }
2109 }
2110
2111 return false;
2112 }
2113
2114 private function create_synthetic_cells($rows, $cols) {
2115 $cells = array();
2116
2117 for ($row = 0; $row < $rows; $row++) {
2118 for ($col = 0; $col < $cols; $col++) {
2119 $cells[] = array(
2120 'blockName' => 'tableberg/cell',
2121 'attrs' => array(
2122 'row' => $row,
2123 'col' => $col,
2124 'rowspan' => 1,
2125 'colspan' => 1,
2126 ),
2127 'innerBlocks' => array(),
2128 );
2129 }
2130 }
2131
2132 return $cells;
2133 }
2134
2135 private function get_legacy_cell_blocks($block) {
2136 $cells = array();
2137
2138 foreach ($this->get_block_inner_blocks($block) as $inner_block) {
2139 if ($this->get_block_name($inner_block) !== 'tableberg/cell') {
2140 continue;
2141 }
2142
2143 $cells[] = $inner_block;
2144 }
2145
2146 return $cells;
2147 }
2148
2149 private function get_block_name($block) {
2150 if (!is_array($block) || !isset($block['blockName']) || !is_string($block['blockName'])) {
2151 return '';
2152 }
2153
2154 return $block['blockName'];
2155 }
2156
2157 private function get_block_attrs($block) {
2158 if (!is_array($block) || !isset($block['attrs']) || !is_array($block['attrs'])) {
2159 return array();
2160 }
2161
2162 return $block['attrs'];
2163 }
2164
2165 private function get_block_inner_blocks($block) {
2166 if (!is_array($block) || !isset($block['innerBlocks']) || !is_array($block['innerBlocks'])) {
2167 return array();
2168 }
2169
2170 return $block['innerBlocks'];
2171 }
2172
2173 private function get_array($array, $key, $default) {
2174 if (!is_array($array) || !isset($array[$key]) || !is_array($array[$key])) {
2175 return $default;
2176 }
2177
2178 return $array[$key];
2179 }
2180
2181 private function get_scalar($array, $key, $default) {
2182 if (!is_array($array) || !array_key_exists($key, $array)) {
2183 return $default;
2184 }
2185
2186 return $array[$key];
2187 }
2188
2189 private function get_nested_value($array, $keys, $default) {
2190 if (!is_array($array)) {
2191 return $default;
2192 }
2193
2194 $current = $array;
2195 foreach ($keys as $key) {
2196 if (!is_array($current) || !array_key_exists($key, $current)) {
2197 return $default;
2198 }
2199
2200 $current = $current[$key];
2201 }
2202
2203 return $current;
2204 }
2205
2206 private function get_empty_border_sides() {
2207 return array(
2208 'top' => '',
2209 'right' => '',
2210 'bottom' => '',
2211 'left' => '',
2212 );
2213 }
2214
2215 private function get_empty_border_radius() {
2216 return array(
2217 'topLeft' => '',
2218 'topRight' => '',
2219 'bottomRight' => '',
2220 'bottomLeft' => '',
2221 );
2222 }
2223 }
2224