Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
96.15% |
25 / 26 |
|
100.00% |
2 / 2 |
CRAP | |
100.00% |
1 / 1 |
| RelationGridMetadata | |
100.00% |
25 / 25 |
|
100.00% |
2 / 2 |
8 | |
100.00% |
1 / 1 |
| __construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| fromRow | |
100.00% |
24 / 24 |
|
100.00% |
1 / 1 |
7 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | /** @license For full copyright and license information, please see the LICENSE.md file. */ |
| 6 | |
| 7 | namespace App\Core\Engine\Domain\Model; |
| 8 | |
| 9 | defined('AMMONLY_APP') || exit('Direct script access is forbidden.'); |
| 10 | |
| 11 | /** |
| 12 | * Relation Grid Metadata Value Object. |
| 13 | * |
| 14 | * Immutable value object representing a widget placement instance on a module GRID view |
| 15 | * from a_core_relation_grid_records. Defines Gridstack coordinates, dimension, lock status, |
| 16 | * runtime parameters, and optional linked WidgetMetadata. |
| 17 | * |
| 18 | * @package App\Core\Engine\Domain\Model |
| 19 | */ |
| 20 | final readonly class RelationGridMetadata |
| 21 | { |
| 22 | /** |
| 23 | * RelationGridMetadata constructor. |
| 24 | * |
| 25 | * @param int $id Relation primary key. |
| 26 | * @param string $name Unique machine name for placement. |
| 27 | * @param string $label Human-readable widget tile title. |
| 28 | * @param int $moduleId FK to a_core_module_records. |
| 29 | * @param int|null $gridFilterId FK to a_core_filter_grid_records (optional). |
| 30 | * @param int $widgetId FK to a_core_widget_records. |
| 31 | * @param int $posX Gridstack column offset (0-11). |
| 32 | * @param int $posY Gridstack row index. |
| 33 | * @param int $width Gridstack column width (1-12). |
| 34 | * @param int $height Gridstack row span. |
| 35 | * @param bool $isLocked Whether the tile position is fixed. |
| 36 | * @param array<string, mixed> $widgetParams Runtime dynamic parameters JSON. |
| 37 | * @param bool $isActive Whether relation is active. |
| 38 | * @param int $sortOrder Evaluation and rendering order. |
| 39 | * @param WidgetMetadata|null $widget Optional joined widget definition. |
| 40 | * @param string|null $moduleName Optional joined source module name. |
| 41 | */ |
| 42 | public function __construct( |
| 43 | public int $id, |
| 44 | public string $name, |
| 45 | public string $label, |
| 46 | public int $moduleId, |
| 47 | public ?int $gridFilterId = null, |
| 48 | public int $widgetId = 1, |
| 49 | public int $posX = 0, |
| 50 | public int $posY = 0, |
| 51 | public int $width = 12, |
| 52 | public int $height = 8, |
| 53 | public bool $isLocked = false, |
| 54 | public array $widgetParams = [], |
| 55 | public bool $isActive = true, |
| 56 | public int $sortOrder = 10, |
| 57 | public ?WidgetMetadata $widget = null, |
| 58 | public ?string $moduleName = null, |
| 59 | ) { |
| 60 | } |
| 61 | |
| 62 | /** |
| 63 | * Creates a RelationGridMetadata instance from a raw database row array. |
| 64 | * |
| 65 | * @param array<string, mixed> $row Raw database row from a_core_relation_grid_records. |
| 66 | * @param WidgetMetadata|null $widget Optional joined widget metadata. |
| 67 | * @return self Hydrated RelationGridMetadata value object. |
| 68 | */ |
| 69 | public static function fromRow(array $row, ?WidgetMetadata $widget = null): self |
| 70 | { |
| 71 | $params = []; |
| 72 | if (isset($row['widget_params']) && is_string($row['widget_params'])) { |
| 73 | $decoded = json_decode($row['widget_params'], true); |
| 74 | $params = is_array($decoded) ? $decoded : []; |
| 75 | } elseif (is_array($row['widget_params'] ?? null)) { |
| 76 | $params = $row['widget_params']; |
| 77 | } |
| 78 | |
| 79 | return new self( |
| 80 | id: (int) $row['id'], |
| 81 | name: (string) $row['name'], |
| 82 | label: (string) $row['label'], |
| 83 | moduleId: (int) $row['module_id'], |
| 84 | gridFilterId: isset($row['grid_filter_id']) ? (int) $row['grid_filter_id'] : null, |
| 85 | widgetId: (int) ($row['widget_id'] ?? 1), |
| 86 | posX: (int) ($row['pos_x'] ?? 0), |
| 87 | posY: (int) ($row['pos_y'] ?? 0), |
| 88 | width: (int) ($row['width'] ?? 12), |
| 89 | height: (int) ($row['height'] ?? 8), |
| 90 | isLocked: (bool) ($row['is_locked'] ?? false), |
| 91 | widgetParams: $params, |
| 92 | isActive: (bool) ($row['is_active'] ?? true), |
| 93 | sortOrder: (int) ($row['sort_order'] ?? 10), |
| 94 | widget: $widget, |
| 95 | moduleName: isset($row['source_module_name']) ? (string) $row['source_module_name'] : null, |
| 96 | ); |
| 97 | } |
| 98 | } |