PluginProbe
Tableberg – Simple Gutenberg Table Block / 1.0.3
Tableberg – Simple Gutenberg Table Block v1.0.3
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 / TableAttrs.php

TableAttrs.php in Tableberg – Simple Gutenberg Table Block 1.0.3, at renderer/Table/TableAttrs.php

753 lines 20.6 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 use Tableberg\Renderer\Attrs\NumberAttr;
6 use Tableberg\Renderer\Attrs\BoolAttr;
7 use Tableberg\Renderer\Attrs\StringAttr;
8 use Tableberg\Renderer\Attrs\Sides;
9 use Tableberg\Renderer\Attrs\Corners;
10
11 use function Tableberg\Renderer\getOrNull;
12
13 class TableAttrs {
14 /** @var NumberAttr */
15 public $version;
16
17 /** @var BoolAttr */
18 public $isExample;
19
20 /** @var TableConfig */
21 public $table;
22
23 /** @var array<int, RowConfig> */
24 public $rows;
25
26 /** @var array<int, ColumnConfig> */
27 public $columns;
28
29 /** @var array<string, CellData> */
30 public $cells;
31
32 /** @var array<string, array<string, mixed>> */
33 public $bindings;
34
35 /** @var CellDefaults */
36 public $cellDefaults;
37
38 /**
39 * @param array $data
40 * @return self
41 */
42 public static function from_array($data) {
43 $data = is_array($data) ? $data : [];
44 $defaults = Defaults::get_defaults();
45
46 $instance = new self();
47 $instance->version = new NumberAttr(
48 getOrNull($data['version']),
49 $defaults['version']
50 );
51 $instance->isExample = new BoolAttr(getOrNull($data['isExample']), $defaults['isExample']);
52 $instance->table = TableConfig::from_array(getOrNull($data['table']));
53 $instance->rows = self::parse_row_configs(getOrNull($data['rows']));
54 $instance->columns = self::parse_columns(getOrNull($data['columns']));
55 $instance->cells = self::parse_cells(getOrNull($data['cells']));
56 $instance->bindings = self::parse_bindings(getOrNull($data['bindings']));
57 $instance->cellDefaults = CellDefaults::from_array(getOrNull($data['cellDefaults']));
58
59 return $instance;
60 }
61
62 /** @return array<string, mixed> */
63 public static function get_table_defaults() {
64 $defaults = Defaults::get_defaults();
65
66 if (isset($defaults['table']) && is_array($defaults['table'])) {
67 return $defaults['table'];
68 }
69
70 if (isset($defaults['tableConfig']) && is_array($defaults['tableConfig'])) {
71 return $defaults['tableConfig'];
72 }
73
74 return [];
75 }
76
77 /** @return array<string, mixed> */
78 public static function get_cell_style_defaults() {
79 $defaults = Defaults::get_defaults();
80
81 if (
82 isset($defaults['cellDefaults']) &&
83 is_array($defaults['cellDefaults']) &&
84 isset($defaults['cellDefaults']['styles']) &&
85 is_array($defaults['cellDefaults']['styles'])
86 ) {
87 return array_merge(
88 ['cells' => []],
89 $defaults['cellDefaults']['styles']
90 );
91 }
92
93 if (isset($defaults['cellStyles']) && is_array($defaults['cellStyles'])) {
94 return array_merge(['cells' => []], $defaults['cellStyles']);
95 }
96
97 return ['cells' => []];
98 }
99
100 /** @return array<int, array{array{int, int}, array<int, mixed>}> */
101 public static function get_data_defaults() {
102 $defaults = Defaults::get_defaults();
103
104 if (
105 isset($defaults['data']) &&
106 is_array($defaults['data']) &&
107 isset($defaults['data']['cells']) &&
108 is_array($defaults['data']['cells'])
109 ) {
110 return $defaults['data']['cells'];
111 }
112
113 return [];
114 }
115
116 /** @return array<int, RowConfig> */
117 private static function parse_row_configs($data) {
118 if (!is_array($data)) {
119 return [];
120 }
121
122 $row_configs = [];
123
124 foreach ($data as $row => $row_config) {
125 $row_configs[(int) $row] = RowConfig::from_array($row_config);
126 }
127
128 return $row_configs;
129 }
130
131 /** @return array<int, ColumnConfig> */
132 private static function parse_columns($data) {
133 if (!is_array($data)) {
134 return [];
135 }
136
137 $columns = [];
138
139 foreach ($data as $column => $column_config) {
140 $columns[(int) $column] = ColumnConfig::from_array(
141 $column_config,
142 'text',
143 true
144 );
145 }
146
147 return $columns;
148 }
149
150 /** @return array<string, CellData> */
151 private static function parse_cells($data) {
152 if (!is_array($data)) {
153 return [];
154 }
155
156 $cells = [];
157
158 foreach ($data as $key => $cell) {
159 if (!is_string($key)) {
160 continue;
161 }
162
163 $cells[$key] = CellData::from_array($cell);
164 }
165
166 return $cells;
167 }
168
169 /** @return array<string, array<string, mixed>> */
170 private static function parse_bindings($data) {
171 if (!is_array($data)) {
172 return [];
173 }
174
175 $bindings = [];
176
177 foreach ($data as $key => $binding) {
178 if (!is_string($key) || !is_array($binding)) {
179 continue;
180 }
181
182 $bindings[$key] = $binding;
183 }
184
185 return $bindings;
186 }
187 }
188
189 class Data {
190 /** @var array<int, array{array{int, int}, array<int, CellElement>}> */
191 public $cells;
192
193 /** @return self */
194 public static function from_array($data) {
195 $data = is_array($data) ? $data : [];
196 $default_cells = TableAttrs::get_data_defaults();
197
198 $instance = new self();
199 $instance->cells = self::parse_cells(getOrNull($data['cells']), $default_cells);
200
201 return $instance;
202 }
203
204 /** @return array<int, array{array{int, int}, array<int, CellElement>}> */
205 private static function parse_cells($data, $default) {
206 if (!is_array($data)) {
207 return $default;
208 }
209
210 $cells = [];
211
212 foreach ($data as $cell) {
213 if (!is_array($cell[0])) {
214 continue;
215 }
216
217 $coords = [(int) $cell[0][0], (int) $cell[0][1]];
218 $elements = [];
219
220 if (is_array($cell[1])) {
221 foreach ($cell[1] as $element) {
222 $elements[] = CellElement::from_array($element);
223 }
224 }
225
226 $cells[] = [$coords, $elements];
227 }
228
229 return $cells;
230 }
231 }
232
233 class PaginationConfig {
234 /** @var BoolAttr */
235 public $enabled;
236
237 /** @var NumberAttr */
238 public $pageSize;
239
240 /** @var BoolAttr */
241 public $showPageNumbers;
242
243 /** @var BoolAttr */
244 public $showPrevNext;
245
246 /** @return self */
247 public static function from_array($data) {
248 $data = is_array($data) ? $data : [];
249 $table_defaults = TableAttrs::get_table_defaults();
250 $d = isset($table_defaults['pagination']) && is_array($table_defaults['pagination'])
251 ? $table_defaults['pagination']
252 : [];
253
254 $instance = new self();
255 $instance->enabled = new BoolAttr(getOrNull($data['enabled']), $d['enabled']);
256 $instance->pageSize = new NumberAttr(getOrNull($data['pageSize']), $d['pageSize']);
257 $instance->showPageNumbers = new BoolAttr(getOrNull($data['showPageNumbers']), $d['showPageNumbers']);
258 $instance->showPrevNext = new BoolAttr(getOrNull($data['showPrevNext']), $d['showPrevNext']);
259
260 return $instance;
261 }
262 }
263
264 class SearchConfig {
265 /** @var BoolAttr */
266 public $enabled;
267
268 /** @var StringAttr */
269 public $placeholder;
270
271 /** @var StringAttr */
272 public $highlightColor;
273
274 /** @var StringAttr */
275 public $position;
276
277 /** @return self */
278 public static function from_array($data) {
279 $data = is_array($data) ? $data : [];
280 $table_defaults = TableAttrs::get_table_defaults();
281 $d = isset($table_defaults['search']) && is_array($table_defaults['search'])
282 ? $table_defaults['search']
283 : [];
284
285 $instance = new self();
286 $instance->enabled = new BoolAttr(getOrNull($data['enabled']), $d['enabled']);
287 $instance->placeholder = new StringAttr(getOrNull($data['placeholder']), $d['placeholder']);
288 $instance->highlightColor = new StringAttr(getOrNull($data['highlightColor']), $d['highlightColor']);
289 $instance->position = new StringAttr(getOrNull($data['position']), $d['position'], ['left', 'right']);
290
291 return $instance;
292 }
293 }
294
295 class ResponsiveBreakpointConfig {
296 /** @var BoolAttr */
297 public $enabled;
298
299 /** @var NumberAttr */
300 public $maxWidth;
301
302 /** @var StringAttr */
303 public $mode;
304
305 /** @var BoolAttr */
306 public $transpose;
307
308 /** @var NumberAttr */
309 public $stackCount;
310
311 /** @var BoolAttr */
312 public $repeatFirstCol;
313
314 /**
315 * @param array|null $data
316 * @param array<string, mixed> $defaults
317 * @return self
318 */
319 public static function from_array($data, $defaults) {
320 $data = is_array($data) ? $data : [];
321
322 $instance = new self();
323 $instance->enabled = new BoolAttr(getOrNull($data['enabled']), $defaults['enabled']);
324 $instance->maxWidth = new NumberAttr(getOrNull($data['maxWidth']), $defaults['maxWidth']);
325 $instance->mode = new StringAttr(
326 getOrNull($data['mode']),
327 $defaults['mode'],
328 ['', 'scroll', 'stack']
329 );
330 $transposeInput = getOrNull($data['transpose']);
331 $legacyDirectionInput = getOrNull($data['direction']);
332 if ($transposeInput === null && is_string($legacyDirectionInput)) {
333 $transposeInput = $legacyDirectionInput === 'row';
334 }
335
336 $instance->transpose = new BoolAttr(
337 $transposeInput,
338 $defaults['transpose']
339 );
340 $instance->stackCount = new NumberAttr(
341 getOrNull($data['stackCount']),
342 $defaults['stackCount']
343 );
344
345 $repeatFirstColInput = getOrNull($data['repeatFirstCol']);
346 if ($repeatFirstColInput === null) {
347 $repeatFirstColInput = getOrNull($data['headerAsCol']);
348 }
349
350 $instance->repeatFirstCol = new BoolAttr(
351 $repeatFirstColInput,
352 $defaults['repeatFirstCol']
353 );
354
355 return $instance;
356 }
357 }
358
359 class ResponsiveConfig {
360 /** @var ResponsiveBreakpointConfig */
361 public $tablet;
362
363 /** @var ResponsiveBreakpointConfig */
364 public $mobile;
365
366 /** @return self */
367 public static function from_array($data) {
368 $data = is_array($data) ? $data : [];
369 $table_defaults = TableAttrs::get_table_defaults();
370 $defaults = isset($table_defaults['responsive']) && is_array($table_defaults['responsive'])
371 ? $table_defaults['responsive']
372 : [];
373
374 $instance = new self();
375 $instance->tablet = ResponsiveBreakpointConfig::from_array(
376 getOrNull($data['tablet']),
377 $defaults['tablet']
378 );
379 $instance->mobile = ResponsiveBreakpointConfig::from_array(
380 getOrNull($data['mobile']),
381 $defaults['mobile']
382 );
383
384 return $instance;
385 }
386 }
387
388 class CellSpacingConfig {
389 /** @var StringAttr */
390 public $horizontal;
391
392 /** @var StringAttr */
393 public $vertical;
394
395 /** @return self */
396 public static function from_array($data) {
397 $data = is_array($data) ? $data : [];
398 $table_defaults = TableAttrs::get_table_defaults();
399 $defaults = isset($table_defaults['cellSpacing']) && is_array($table_defaults['cellSpacing'])
400 ? $table_defaults['cellSpacing']
401 : [];
402
403 $instance = new self();
404 $instance->horizontal = new StringAttr(
405 getOrNull($data['horizontal']),
406 $defaults['horizontal']
407 );
408 $instance->vertical = new StringAttr(
409 getOrNull($data['vertical']),
410 $defaults['vertical']
411 );
412
413 return $instance;
414 }
415 }
416
417 class CellDefaults {
418 /** @var CellStyles */
419 public $styles;
420
421 /** @return self */
422 public static function from_array($data) {
423 $data = is_array($data) ? $data : [];
424
425 $instance = new self();
426 $instance->styles = CellStyles::from_array(getOrNull($data['styles']));
427
428 return $instance;
429 }
430 }
431
432 class CellData {
433 /** @var Span */
434 public $span;
435
436 /** @var StringAttr */
437 public $className;
438
439 /** @var array<int, CellElement> */
440 public $elements;
441
442 /** @var array<string, mixed>|null */
443 public $styles;
444
445 /** @var array<string, mixed>|null */
446 public $ribbon;
447
448 /** @return self */
449 public static function from_array($data) {
450 $data = is_array($data) ? $data : [];
451
452 $instance = new self();
453 $instance->span = Span::from_array(getOrNull($data['span']));
454 $instance->className = new StringAttr(getOrNull($data['className']), '');
455 $instance->elements = [];
456
457 $elements = getOrNull($data['elements']);
458 if (is_array($elements)) {
459 foreach ($elements as $element) {
460 $instance->elements[] = CellElement::from_array($element);
461 }
462 }
463
464 $styles = getOrNull($data['styles']);
465 $instance->styles = is_array($styles) ? $styles : null;
466
467 $ribbon = getOrNull($data['ribbon']);
468 $instance->ribbon = is_array($ribbon) ? $ribbon : null;
469
470 return $instance;
471 }
472 }
473
474 class TableConfig {
475 /** @var NumberAttr */
476 public $rows;
477
478 /** @var NumberAttr */
479 public $cols;
480
481 /** @var StringAttr */
482 public $className;
483
484 /** @var BoolAttr */
485 public $headerEnabled;
486
487 /** @var BoolAttr */
488 public $footerEnabled;
489
490 /** @var BoolAttr */
491 public $stickyHeader;
492
493 /** @var StringAttr */
494 public $caption;
495
496 /** @var StringAttr */
497 public $tableWidth;
498
499 /** @var StringAttr */
500 public $tableAlignment;
501
502 /** @var CellSpacingConfig */
503 public $cellSpacing;
504
505 /** @var Sides */
506 public $tableBorder;
507
508 /** @var BoolAttr */
509 public $fixedColumnWidths;
510
511 /** @var PaginationConfig */
512 public $pagination;
513
514 /** @var SearchConfig */
515 public $search;
516
517 /** @var ResponsiveConfig */
518 public $responsive;
519
520 /** @return self */
521 public static function from_array($data) {
522 $data = is_array($data) ? $data : [];
523 $d = TableAttrs::get_table_defaults();
524
525 $instance = new self();
526 $instance->rows = new NumberAttr(getOrNull($data['rows']), $d['rows']);
527 $instance->cols = new NumberAttr(getOrNull($data['cols']), $d['cols']);
528 $instance->className = new StringAttr(getOrNull($data['className']), '');
529 $instance->headerEnabled = new BoolAttr(getOrNull($data['headerEnabled']), $d['headerEnabled']);
530 $instance->footerEnabled = new BoolAttr(getOrNull($data['footerEnabled']), $d['footerEnabled']);
531 $instance->stickyHeader = new BoolAttr(getOrNull($data['stickyHeader']), $d['stickyHeader']);
532 $instance->caption = new StringAttr(getOrNull($data['caption']), $d['caption']);
533 $instance->tableWidth = new StringAttr(
534 getOrNull($data['tableWidth']),
535 $d['tableWidth']
536 );
537 $instance->tableAlignment = new StringAttr(
538 getOrNull($data['tableAlignment']),
539 $d['tableAlignment'],
540 ['left', 'center', 'right']
541 );
542 $instance->cellSpacing = CellSpacingConfig::from_array(getOrNull($data['cellSpacing']));
543 $instance->tableBorder = Sides::from_array(
544 getOrNull($data['tableBorder']),
545 $d['tableBorder']
546 );
547 $instance->fixedColumnWidths = new BoolAttr(
548 getOrNull($data['fixedColumnWidths']),
549 $d['fixedColumnWidths']
550 );
551 $instance->pagination = PaginationConfig::from_array(getOrNull($data['pagination']));
552 $instance->search = SearchConfig::from_array(getOrNull($data['search']));
553 $instance->responsive = ResponsiveConfig::from_array(getOrNull($data['responsive']));
554
555 return $instance;
556 }
557 }
558
559 class CellStyles {
560 /** @var Sides */
561 public $padding;
562
563 /** @var StringAttr */
564 public $orientation;
565
566 /** @var StringAttr */
567 public $elementGap;
568
569 /** @var StringAttr */
570 public $wrap;
571
572 /** @var StringAttr */
573 public $verticalAlign;
574
575 /** @var StringAttr */
576 public $backgroundColor;
577
578 /** @var Sides */
579 public $border;
580
581 /** @var Corners */
582 public $borderRadius;
583
584 /** @var array<int, array{array{int, int}, array<string, mixed>}> */
585 public $cells;
586
587 /** @return self */
588 public static function from_array($data) {
589 $data = is_array($data) ? $data : [];
590 $d = TableAttrs::get_cell_style_defaults();
591
592 $instance = new self();
593 $instance->padding = Sides::from_array(getOrNull($data['padding']), $d['padding']);
594 $instance->orientation = new StringAttr(
595 getOrNull($data['orientation']),
596 $d['orientation'],
597 ['vertical', 'horizontal']
598 );
599 $instance->elementGap = new StringAttr(
600 getOrNull($data['elementGap']),
601 $d['elementGap']
602 );
603 $instance->wrap = new StringAttr(
604 getOrNull($data['wrap']),
605 $d['wrap'],
606 ['wrap', 'nowrap']
607 );
608 $instance->verticalAlign = new StringAttr(
609 getOrNull($data['verticalAlign']),
610 $d['verticalAlign'],
611 ['top', 'middle', 'bottom']
612 );
613 $instance->backgroundColor = new StringAttr(getOrNull($data['backgroundColor']), $d['backgroundColor']);
614 $instance->border = Sides::from_array(getOrNull($data['border']), $d['border']);
615 $instance->borderRadius = Corners::from_array(getOrNull($data['borderRadius']), $d['borderRadius']);
616 $instance->cells = is_array(getOrNull($data['cells'])) ? $data['cells'] : $d['cells'];
617
618 return $instance;
619 }
620 }
621
622 class Span {
623 /** @var NumberAttr */
624 public $rowSpan;
625
626 /** @var NumberAttr */
627 public $colSpan;
628
629 /**
630 * @param array|null $data
631 * @param array<string, int> $defaults
632 * @return self
633 */
634 public static function from_array($data, $defaults = ['rowSpan' => 1, 'colSpan' => 1]) {
635 $data = is_array($data) ? $data : [];
636
637 $defaultRowSpan = $defaults['rowSpan'];
638 $defaultColSpan = $defaults['colSpan'];
639
640 $instance = new self();
641 $instance->rowSpan = new NumberAttr(getOrNull($data['rowSpan']), $defaultRowSpan);
642 $instance->colSpan = new NumberAttr(getOrNull($data['colSpan']), $defaultColSpan);
643
644 return $instance;
645 }
646 }
647
648 class ColumnConfig {
649 /** @var StringAttr|null */
650 public $sortable;
651
652 /** @var StringAttr|null */
653 public $width;
654
655 /**
656 * @param array|null $data
657 * @param string $defaultSortable
658 * @param bool $allowNull
659 * @return self
660 */
661 public static function from_array($data, $defaultSortable = 'text', $allowNull = false) {
662 $data = is_array($data) ? $data : [];
663 $sortable = getOrNull($data['sortable']);
664 $width = getOrNull($data['width']);
665
666 $instance = new self();
667
668 if ($allowNull && ($sortable === null || $sortable === '')) {
669 $instance->sortable = null;
670 } else {
671 $instance->sortable = new StringAttr(
672 $sortable,
673 $defaultSortable,
674 ['text', 'number', 'date']
675 );
676 }
677
678 if ($width === null || $width === '') {
679 $instance->width = null;
680 } else {
681 $instance->width = new StringAttr($width, '');
682 }
683
684 return $instance;
685 }
686 }
687
688 class RowConfig {
689 /** @var StringAttr|null */
690 public $height;
691
692 /**
693 * @param array|null $data
694 * @return self
695 */
696 public static function from_array($data) {
697 $data = is_array($data) ? $data : [];
698 $height = getOrNull($data['height']);
699
700 $instance = new self();
701
702 if ($height === null || $height === '') {
703 $instance->height = null;
704 } else {
705 $instance->height = new StringAttr($height, '');
706 }
707
708 return $instance;
709 }
710 }
711
712 class CellElement {
713 /** @var StringAttr */
714 public $name;
715
716 /** @var array<string, mixed> */
717 public $attributes;
718
719 /** @var array<string, mixed>|null */
720 public $bindings;
721
722 /**
723 * @param array|null $data
724 * @param string $defaultName
725 * @param array<int, string>|null $allowedNames
726 * @return self
727 */
728 public static function from_array($data, $defaultName = 'text', $allowedNames = null) {
729 $data = is_array($data) ? $data : [];
730
731 if (!is_array($allowedNames)) {
732 $allowedNames = [
733 'text',
734 'button',
735 'image',
736 'list',
737 'icon',
738 'star-rating',
739 'custom-html',
740 ];
741 }
742
743 $instance = new self();
744 $instance->name = new StringAttr(getOrNull($data['name']), $defaultName, $allowedNames);
745 $attributes = getOrNull($data['attributes']);
746 $instance->attributes = is_array($attributes) ? $attributes : [];
747 $bindings = getOrNull($data['bindings']);
748 $instance->bindings = is_array($bindings) ? $bindings : null;
749
750 return $instance;
751 }
752 }
753