Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
PdfTemplateVersion
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
2 / 2
12
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fromDatabaseRow
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
11
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\Modules\Pdf\Domain\Model;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11/**
12 * Immutable PDF Template Version Snapshot Model.
13 *
14 * Preserves historical revisions of template blocks, body HTML, header/footer,
15 * and custom stylesheets for auditing and one-click rollback.
16 *
17 * @package App\Modules\Pdf\Domain\Model
18 */
19final readonly class PdfTemplateVersion
20{
21    /**
22     * PdfTemplateVersion constructor.
23     *
24     * @param int                       $id            Primary version snapshot ID.
25     * @param int                       $templateId    Referenced parent template ID.
26     * @param int                       $versionNumber Sequential revision number.
27     * @param string|null               $changeSummary Description of changes in this version.
28     * @param array<string, mixed>|null $blocksJson    Serialized visual block configuration.
29     * @param string                    $bodyHtml      Compiled HTML body content.
30     * @param string|null               $headerHtml    Running header HTML markup.
31     * @param string|null               $footerHtml    Running footer HTML markup.
32     * @param string|null               $cssStyles     Custom CSS stylesheet.
33     * @param int                       $recordStatus  Lifecycle status.
34     * @param string                    $createdAt     Snapshot timestamp.
35     * @param int                       $createdBy     Author user ID.
36     */
37    public function __construct(
38        public int $id,
39        public int $templateId,
40        public int $versionNumber,
41        public ?string $changeSummary = null,
42        public ?array $blocksJson = null,
43        public string $bodyHtml = '',
44        public ?string $headerHtml = null,
45        public ?string $footerHtml = null,
46        public ?string $cssStyles = null,
47        public int $recordStatus = 1,
48        public string $createdAt = '',
49        public int $createdBy = 1
50    ) {
51    }
52
53    /**
54     * Instantiates version snapshot from raw database array.
55     *
56     * @param array<string, mixed> $data Raw database associative row.
57     * @return self Populated version model.
58     */
59    public static function fromDatabaseRow(array $data): self
60    {
61        $blocks = null;
62        if (isset($data['blocks_json']) && is_string($data['blocks_json']) && trim($data['blocks_json']) !== '') {
63            $blocks = json_decode($data['blocks_json'], true);
64        } elseif (isset($data['blocks_json']) && is_array($data['blocks_json'])) {
65            $blocks = $data['blocks_json'];
66        }
67
68        return new self(
69            id: (int)($data['id'] ?? 0),
70            templateId: (int)($data['template_id'] ?? 0),
71            versionNumber: (int)($data['version_number'] ?? 1),
72            changeSummary: isset($data['change_summary']) ? (string)$data['change_summary'] : null,
73            blocksJson: is_array($blocks) ? $blocks : null,
74            bodyHtml: (string)($data['body_html'] ?? ''),
75            headerHtml: isset($data['header_html']) ? (string)$data['header_html'] : null,
76            footerHtml: isset($data['footer_html']) ? (string)$data['footer_html'] : null,
77            cssStyles: isset($data['css_styles']) ? (string)$data['css_styles'] : null,
78            recordStatus: (int)($data['special_access'] ?? $data['record_status'] ?? 1),
79            createdAt: (string)($data['created_at'] ?? ''),
80            createdBy: (int)($data['created_by'] ?? 1)
81        );
82    }
83}