PluginProbe
Tableberg – Simple Gutenberg Table Block / 1.1.1
Tableberg – Simple Gutenberg Table Block v1.1.1
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.1.1, at renderer/Migrations/TableBlockMigratorV0ToV1.php

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