Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
FieldMetadataHydrator
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
3 / 3
10
100.00% covered (success)
100.00%
1 / 1
 hydrateFromRow
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
1 / 1
3
 decodeJsonArray
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
5
 nullableString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Core\Engine\Domain\Model\Support;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use App\Core\Engine\Domain\Model\FieldMetadata;
12
13/**
14 * Field Metadata Hydrator.
15 *
16 * Hydrates immutable FieldMetadata value objects from raw database rows.
17 *
18 * @package App\Core\Engine\Domain\Model\Support
19 */
20final readonly class FieldMetadataHydrator
21{
22    /**
23     * Creates a FieldMetadata instance from a raw database row array.
24     *
25     * @param array<string, mixed> $row Raw database row from a_core_field_records.
26     * @return FieldMetadata Hydrated FieldMetadata value object.
27     */
28    public function hydrateFromRow(array $row): FieldMetadata
29    {
30        return new FieldMetadata(
31            id:               (int)    $row['id'],
32            moduleId:         (int)    $row['module_id'],
33            fieldKey:         (string) $row['field_key'],
34            columnExpression: (string) $row['column_expression'],
35            label:            (string) $row['label'],
36            uitypeName:       (string) ($row['uitype_name'] ?? 'string_input'),
37            isSortable:       (bool)   $row['is_sortable'],
38            isFilterable:     (bool)   $row['is_filterable'],
39            isMandatory:      (bool)   $row['is_mandatory'],
40            isUnique:         (bool)   $row['is_unique'],
41            isSystem:         (bool)   $row['is_system'],
42            isReadonly:       (bool)   $row['is_readonly'],
43            sortOrder:        (int)    $row['sort_order'],
44            isSummary:        (bool)   ($row['is_summary'] ?? false),
45            isQuickCreate:    (bool)   ($row['is_quick_create'] ?? false),
46            isGlobalSearch:   (bool)   ($row['is_global_search'] ?? false),
47            sectionId:        isset($row['section_id']) ? (int) $row['section_id'] : null,
48            picklistId:       isset($row['picklist_id']) ? (int) $row['picklist_id'] : null,
49            relationModule:   self::nullableString($row['relation_module'] ?? null),
50            relationTable:    self::nullableString($row['relation_table'] ?? null),
51            relationKey:      self::nullableString($row['relation_key'] ?? null),
52            relationLabel:    self::nullableString($row['relation_label'] ?? null),
53            relationDisplay:  self::nullableString($row['relation_display'] ?? null),
54            validationRules:  self::decodeJsonArray($row['validation_rules'] ?? null),
55            filterOptions:    self::decodeJsonArray($row['filter_options'] ?? null),
56            defaultValue:     self::nullableString($row['default_value'] ?? null),
57            placeholder:      self::nullableString($row['placeholder'] ?? null),
58            hiddenViews:      self::nullableString($row['hidden_views'] ?? null),
59        );
60    }
61
62    /**
63     * Decodes JSON string into array.
64     *
65     * @param mixed $raw Raw JSON payload.
66     * @return array<string, mixed> Decoded array.
67     */
68    public static function decodeJsonArray(mixed $raw): array
69    {
70        if (is_array($raw)) {
71            return $raw;
72        }
73        if (!is_string($raw) || $raw === '') {
74            return [];
75        }
76        $decoded = json_decode($raw, true);
77        return is_array($decoded) ? $decoded : [];
78    }
79
80    /**
81     * Converts nullable value to string or null.
82     */
83    public static function nullableString(mixed $val): ?string
84    {
85        return $val !== null ? (string) $val : null;
86    }
87}