Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
14 / 14
CRAP
100.00% covered (success)
100.00%
1 / 1
MenuItem
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
14 / 14
18
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
 getId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getParentId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLabel
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRouteUrl
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIconClass
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSortOrder
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isActive
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCreatedAt
n/a
0 / 0
n/a
0 / 0
1
 getUpdatedAt
n/a
0 / 0
n/a
0 / 0
1
 getCreatedBy
n/a
0 / 0
n/a
0 / 0
1
 getOwner
n/a
0 / 0
n/a
0 / 0
1
 addChild
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getChildren
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setChildren
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 withChildren
100.00% covered (success)
100.00%
3 / 3
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
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\Menu\Domain\Model;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use DateTimeImmutable;
12
13/**
14 * Menu Item Domain Entity Aggregate.
15 *
16 * Represents a menu item record in tree hierarchy (group, module, view, separator).
17 *
18 * @package App\Modules\Menu\Domain\Model
19 */
20final class MenuItem
21{
22    /**
23     * @var array<int, MenuItem> Child menu items.
24     */
25    private array $children = [];
26
27    /**
28     * MenuItem constructor.
29     *
30     * @param int|null $id Primary menu item ID.
31     * @param int|null $parentId Parent menu item ID if nested.
32     * @param string $type Item type ('group', 'module', 'view', 'separator').
33     * @param string $label Human-readable label.
34     * @param string|null $routeUrl Target URL route.
35     * @param string|null $iconClass CSS icon class string.
36     * @param int $sortOrder Sort order sequence integer.
37     * @param bool $isActive Active flag state.
38     * @param DateTimeImmutable|null $createdAt Creation timestamp.
39     * @param DateTimeImmutable|null $updatedAt Modification timestamp.
40     * @param int $createdBy Creator user ID.
41     * @param int $owner Owner user ID.
42     */
43    public function __construct(
44        private ?int $id,
45        private ?int $parentId,
46        private string $type,
47        private string $label,
48        private ?string $routeUrl = null,
49        private ?string $iconClass = null,
50        private int $sortOrder = 0,
51        private bool $isActive = true,
52        private ?DateTimeImmutable $createdAt = null,
53        private ?DateTimeImmutable $updatedAt = null,
54        private int $createdBy = 1,
55        private int $owner = 1
56    ) {
57    }
58
59    public function getId(): ?int
60    {
61        return $this->id;
62    }
63
64    public function getParentId(): ?int
65    {
66        return $this->parentId;
67    }
68
69    public function getType(): string
70    {
71        return $this->type;
72    }
73
74    public function getLabel(): string
75    {
76        return $this->label;
77    }
78
79    public function getRouteUrl(): ?string
80    {
81        return $this->routeUrl;
82    }
83
84    public function getIconClass(): ?string
85    {
86        return $this->iconClass;
87    }
88
89    public function getSortOrder(): int
90    {
91        return $this->sortOrder;
92    }
93
94    public function isActive(): bool
95    {
96        return $this->isActive;
97    }
98
99    public function getCreatedAt(): ?DateTimeImmutable
100    {
101        // @codeCoverageIgnoreStart
102        return $this->createdAt;
103        // @codeCoverageIgnoreEnd
104    }
105
106    public function getUpdatedAt(): ?DateTimeImmutable
107    {
108        // @codeCoverageIgnoreStart
109        return $this->updatedAt;
110        // @codeCoverageIgnoreEnd
111    }
112
113    public function getCreatedBy(): int
114    {
115        // @codeCoverageIgnoreStart
116        return $this->createdBy;
117        // @codeCoverageIgnoreEnd
118    }
119
120    public function getOwner(): int
121    {
122        // @codeCoverageIgnoreStart
123        return $this->owner;
124        // @codeCoverageIgnoreEnd
125    }
126
127    /**
128     * Adds a child MenuItem to tree hierarchy.
129     *
130     * @param MenuItem $child Child MenuItem instance.
131     * @return void
132     */
133    public function addChild(MenuItem $child): void
134    {
135        $this->children[] = $child;
136    }
137
138    /**
139     * Gets array of child MenuItem instances.
140     *
141     * @return array<int, MenuItem> Children items.
142     */
143    public function getChildren(): array
144    {
145        return $this->children;
146    }
147
148    /**
149     * Sets children items array.
150     *
151     * @param array<int, MenuItem> $children Child items list.
152     * @return void
153     */
154    public function setChildren(array $children): void
155    {
156        $this->children = $children;
157    }
158
159    /**
160     * Returns a clone with updated children list.
161     *
162     * @param array<int, MenuItem> $children Child items list.
163     * @return self New MenuItem instance with updated children.
164     */
165    public function withChildren(array $children): self
166    {
167        $clone = clone $this;
168        $clone->children = $children;
169        return $clone;
170    }
171
172    /**
173     * Converts MenuItem to array for JSON serialization.
174     *
175     * @return array<string, mixed> Serialized array.
176     */
177    public function toArray(): array
178    {
179        return [
180            'id'         => $this->id,
181            'parent_id'  => $this->parentId,
182            'type'       => $this->type,
183            'label'      => $this->label,
184            'route_url'  => $this->routeUrl,
185            'icon_class' => $this->iconClass,
186            'sort_order' => $this->sortOrder,
187            'is_active'  => $this->isActive,
188            'children'   => array_map(static fn(MenuItem $c): array => $c->toArray(), $this->children),
189        ];
190    }
191}