Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.44% covered (success)
94.44%
34 / 36
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
DocumentTypeData
94.44% covered (success)
94.44%
34 / 36
75.00% covered (warning)
75.00%
3 / 4
10.02
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fromRow
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
1
 toArray
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 decodeMimeList
80.00% covered (warning)
80.00%
8 / 10
0.00% covered (danger)
0.00%
0 / 1
7.39
1<?php
2
3declare(strict_types=1);
4
5namespace App\Domain\Document\Type\Data;
6
7use App\Support\Row;
8
9/**
10 * Read-only view of a document_types row.
11 *
12 * The catalog drives the upload-form dropdown and per-type validation
13 * (max size, allowed MIMEs, requires_review flag).
14 */
15final readonly class DocumentTypeData
16{
17    /**
18     * @param list<string> $allowedMimeTypes Empty list means no MIME restriction.
19     * @param int $documentTypeId
20     * @param string $code
21     * @param string $label
22     * @param ?string $description
23     * @param int $maxSizeBytes
24     * @param bool $requiresReview
25     * @param bool $isActive
26     * @param int $sortOrder
27     */
28    public function __construct(
29        public int $documentTypeId,
30        public string $code,
31        public string $label,
32        public ?string $description,
33        public array $allowedMimeTypes,
34        public int $maxSizeBytes,
35        public bool $requiresReview,
36        public bool $isActive,
37        public int $sortOrder,
38    ) {}
39
40    /**
41     * @param array<mixed> $row
42     */
43    public static function fromRow(array $row): self
44    {
45        $allowedMimeTypes = self::decodeMimeList(
46            Row::nullableString($row, 'allowedMimeTypes'),
47        );
48
49        return new self(
50            documentTypeId: Row::int($row, 'documentTypeId'),
51            code: Row::string($row, 'code'),
52            label: Row::string($row, 'label'),
53            description: Row::nullableString($row, 'description'),
54            allowedMimeTypes: $allowedMimeTypes,
55            maxSizeBytes: Row::int($row, 'maxSizeBytes'),
56            requiresReview: Row::bool($row, 'requiresReview'),
57            isActive: Row::bool($row, 'isActive'),
58            sortOrder: Row::int($row, 'sortOrder'),
59        );
60    }
61
62    /**
63     * @return array<string, mixed>
64     */
65    public function toArray(): array
66    {
67        return [
68            'documentTypeId' => $this->documentTypeId,
69            'code' => $this->code,
70            'label' => $this->label,
71            'description' => $this->description,
72            'allowedMimeTypes' => $this->allowedMimeTypes,
73            'maxSizeBytes' => $this->maxSizeBytes,
74            'requiresReview' => $this->requiresReview,
75            'isActive' => $this->isActive,
76            'sortOrder' => $this->sortOrder,
77        ];
78    }
79
80    /**
81     * @param ?string $json
82     * @return list<string>
83     */
84    private static function decodeMimeList(?string $json): array
85    {
86        if ($json === null || $json === '') {
87            return [];
88        }
89
90        $decoded = json_decode($json, true);
91        if (!is_array($decoded)) {
92            return [];
93        }
94
95        $result = [];
96        foreach ($decoded as $value) {
97            if (is_string($value) && $value !== '') {
98                $result[] = $value;
99            }
100        }
101
102        return $result;
103    }
104}