PluginProbe
Tableberg – Simple Gutenberg Table Block / 1.1.5
Tableberg – Simple Gutenberg Table Block v1.1.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 / Table / InnerBlocksAttrsAdapter.php

InnerBlocksAttrsAdapter.php in Tableberg – Simple Gutenberg Table Block 1.1.5, at renderer/Table/InnerBlocksAttrsAdapter.php

175 lines 6.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\Table;
4
5 /**
6 * Adapts a v4 native-blocks table (rows -> cells -> elements innerBlocks)
7 * into the v3-shaped attrs array that TableRenderer::render() consumes.
8 * This keeps the whole PHP renderer working unchanged for both formats.
9 */
10 class InnerBlocksAttrsAdapter {
11 const ELEMENT_PREFIX = 'tableberg/';
12
13 /**
14 * @param array $attributes v4 table block attrs.
15 * @param array $innerBlocks Parsed inner blocks (tableberg/row list).
16 * @return array v3-shaped attrs array.
17 */
18 public static function to_attrs($attributes, $innerBlocks) {
19 $attrs = is_array($attributes) ? $attributes : [];
20 $innerBlocks = is_array($innerBlocks) ? $innerBlocks : [];
21
22 $cells = [];
23 $rowConfigs = [];
24 // Positions occupied by a rowSpan/colSpan anchor.
25 $covered = [];
26 $colsCount = 0;
27
28 $row = 0;
29 foreach ($innerBlocks as $rowBlock) {
30 if (
31 !is_array($rowBlock) ||
32 !isset($rowBlock['blockName']) ||
33 $rowBlock['blockName'] !== 'tableberg/row'
34 ) {
35 continue;
36 }
37
38 $rowAttrs = isset($rowBlock['attrs']) && is_array($rowBlock['attrs'])
39 ? $rowBlock['attrs']
40 : [];
41 // Pass every row attribute through untouched (not just `height`)
42 // so pro-registered keys survive without this adapter needing to
43 // know their names.
44 $rowConfigs[$row] = empty($rowAttrs) ? null : $rowAttrs;
45
46 $col = 0;
47 $rowInner = isset($rowBlock['innerBlocks']) && is_array($rowBlock['innerBlocks'])
48 ? $rowBlock['innerBlocks']
49 : [];
50
51 foreach ($rowInner as $cellBlock) {
52 if (
53 !is_array($cellBlock) ||
54 !isset($cellBlock['blockName']) ||
55 $cellBlock['blockName'] !== 'tableberg/cell'
56 ) {
57 continue;
58 }
59
60 // Advance past positions covered by spans from earlier rows.
61 while (isset($covered["{$row},{$col}"])) {
62 $col++;
63 }
64
65 $cellAttrs = isset($cellBlock['attrs']) && is_array($cellBlock['attrs'])
66 ? $cellBlock['attrs']
67 : [];
68
69 // Everything the cell block carries is passed straight
70 // through, not just the keys this file knows about. Pro
71 // registers its own cell attributes, and they have to reach
72 // its renderer without free having to name them here.
73 $cellEntry = $cellAttrs;
74
75 $cellEntry['elements'] = self::to_elements(
76 isset($cellBlock['innerBlocks']) && is_array($cellBlock['innerBlocks'])
77 ? $cellBlock['innerBlocks']
78 : []
79 );
80
81 $cells["{$row},{$col}"] = $cellEntry;
82
83 $rowSpan = 1;
84 $colSpan = 1;
85 if (isset($cellAttrs['span']) && is_array($cellAttrs['span'])) {
86 if (isset($cellAttrs['span']['rowSpan']) && is_numeric($cellAttrs['span']['rowSpan'])) {
87 $rowSpan = max(1, (int) $cellAttrs['span']['rowSpan']);
88 }
89 if (isset($cellAttrs['span']['colSpan']) && is_numeric($cellAttrs['span']['colSpan'])) {
90 $colSpan = max(1, (int) $cellAttrs['span']['colSpan']);
91 }
92 }
93
94 for ($dr = 0; $dr < $rowSpan; $dr++) {
95 for ($dc = 0; $dc < $colSpan; $dc++) {
96 if ($dr === 0 && $dc === 0) {
97 continue;
98 }
99 $covered[($row + $dr) . ',' . ($col + $dc)] = true;
100 }
101 }
102
103 $col += $colSpan;
104 if ($col > $colsCount) {
105 $colsCount = $col;
106 }
107 }
108
109 // Trailing covered positions still widen the row.
110 while (isset($covered["{$row},{$col}"])) {
111 $col++;
112 if ($col > $colsCount) {
113 $colsCount = $col;
114 }
115 }
116
117 $row++;
118 }
119
120 // When the whole object is absent Gutenberg supplies the block
121 // schema's complete default. Starting from an empty array here would
122 // create a partial object just to add row/column counts and would
123 // silently lose nested defaults such as search.placeholder.
124 $table = isset($attrs['table']) && is_array($attrs['table'])
125 ? $attrs['table']
126 : TableAttrs::get_table_defaults();
127 $table['rows'] = $row;
128 $table['cols'] = $colsCount;
129
130 $adapted = $attrs;
131 $adapted['version'] = 3;
132 $adapted['table'] = $table;
133 $adapted['rows'] = $rowConfigs;
134 $adapted['cells'] = $cells;
135
136 return $adapted;
137 }
138
139 /**
140 * @param array $elementBlocks Parsed element blocks inside a cell.
141 * @return array v3 cell elements array.
142 */
143 private static function to_elements($elementBlocks) {
144 $elements = [];
145
146 foreach ($elementBlocks as $elementBlock) {
147 if (
148 !is_array($elementBlock) ||
149 !isset($elementBlock['blockName']) ||
150 strpos($elementBlock['blockName'], self::ELEMENT_PREFIX) !== 0
151 ) {
152 continue;
153 }
154
155 $name = substr($elementBlock['blockName'], strlen(self::ELEMENT_PREFIX));
156 $attrs = isset($elementBlock['attrs']) && is_array($elementBlock['attrs'])
157 ? $elementBlock['attrs']
158 : [];
159
160 $element = ['name' => $name];
161
162 if (isset($attrs['bindings']) && is_array($attrs['bindings']) && !empty($attrs['bindings'])) {
163 $element['bindings'] = $attrs['bindings'];
164 unset($attrs['bindings']);
165 }
166
167 $element['attributes'] = $attrs;
168
169 $elements[] = $element;
170 }
171
172 return $elements;
173 }
174 }
175