Lines
90.90%
40 / 44
Functions and Methods
80.95%
17 / 21
Classes and Traits
0.00%
0 / 1
| Name | Lines | Functions and Methods | CRAP | Classes and Traits | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| EntityRegistryUpdate | 90.90% | 40 / 44 | 80.95% | 17 / 21 | 36.97 | 0.00% | 0 / 1 | |||
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| withName | 0.00% | 0 / 1 | 0.00% | 0 / 1 | 2 | |||||
| withoutName | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| withIcon | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| withoutIcon | 0.00% | 0 / 1 | 0.00% | 0 / 1 | 2 | |||||
| withArea | 0.00% | 0 / 1 | 0.00% | 0 / 1 | 2 | |||||
| withoutArea | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| withLabels | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| withAddedLabels | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| withRemovedLabels | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| withAliases | 0.00% | 0 / 1 | 0.00% | 0 / 1 | 2 | |||||
| withAddedAliases | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| withRemovedAliases | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| withHidden | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| withDisabled | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| isEmpty | 100.00% | 7 / 7 | 100.00% | 1 / 1 | 7 | |||||
| needsCurrentEntry | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 2 | |||||
| resolveAgainst | 100.00% | 4 / 4 | 100.00% | 1 / 1 | 1 | |||||
| applyTo | 100.00% | 12 / 12 | 100.00% | 1 / 1 | 8 | |||||
| collectLabelIds | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| collectAliases | 100.00% | 4 / 4 | 100.00% | 1 / 1 | 2 | |||||
| 1 | <?php | |
| 2 | ||
| 3 | declare(strict_types=1); | |
| 4 | ||
| 5 | namespace Stewart\Contracts\Registry\Update; | |
| 6 | ||
| 7 | use Stewart\Contracts\Exception\IdentifierException; | |
| 8 | use Stewart\Contracts\Registry\AreaId; | |
| 9 | use Stewart\Contracts\Registry\Collection\EntityAliasCollection; | |
| 10 | use Stewart\Contracts\Registry\Collection\LabelIdCollection; | |
| 11 | use Stewart\Contracts\Registry\EntityAlias; | |
| 12 | use Stewart\Contracts\Registry\LabelId; | |
| 13 | use Stewart\Contracts\Registry\RegisteredEntity; | |
| 14 | ||
| 15 | // A null field leaves that part of the registry entry as it is. | |
| 16 | final readonly class EntityRegistryUpdate | |
| 17 | { | |
| 18 | public const string CHANGED_BY_USER = 'user'; | |
| 19 | ||
| 20 | public function __construct( | |
| 21 | public ?EntityNameChange $name = null, | |
| 22 | public ?EntityIconChange $icon = null, | |
| 23 | public ?EntityAreaChange $area = null, | |
| 24 | public ?EntityLabelsChange $labels = null, | |
| 25 | public ?EntityAliasesChange $aliases = null, | |
| 26 | public ?bool $hidden = null, | |
| 27 | public ?bool $disabled = null, | |
| 28 | ) {} | |
| 29 | ||
| 30 | public function withName(string $name): self | |
| 31 | { | |
| 32 | return clone($this, ['name' => new EntityNameChange($name)]); | |
| 33 | } | |
| 34 | ||
| 35 | public function withoutName(): self | |
| 36 | { | |
| 37 | return clone($this, ['name' => new EntityNameChange(null)]); | |
| 38 | } | |
| 39 | ||
| 40 | public function withIcon(string $icon): self | |
| 41 | { | |
| 42 | return clone($this, ['icon' => new EntityIconChange($icon)]); | |
| 43 | } | |
| 44 | ||
| 45 | public function withoutIcon(): self | |
| 46 | { | |
| 47 | return clone($this, ['icon' => new EntityIconChange(null)]); | |
| 48 | } | |
| 49 | ||
| 50 | /** @throws IdentifierException */ | |
| 51 | public function withArea(AreaId|string $areaId): self | |
| 52 | { | |
| 53 | return clone($this, ['area' => new EntityAreaChange(AreaId::fromStringOrId($areaId))]); | |
| 54 | } | |
| 55 | ||
| 56 | public function withoutArea(): self | |
| 57 | { | |
| 58 | return clone($this, ['area' => new EntityAreaChange(null)]); | |
| 59 | } | |
| 60 | ||
| 61 | /** @throws IdentifierException */ | |
| 62 | public function withLabels(LabelId|string ...$labelIds): self | |
| 63 | { | |
| 64 | return clone($this, ['labels' => EntityLabelsChange::replacingWith($this->collectLabelIds($labelIds))]); | |
| 65 | } | |
| 66 | ||
| 67 | /** @throws IdentifierException */ | |
| 68 | public function withAddedLabels(LabelId|string ...$labelIds): self | |
| 69 | { | |
| 70 | return clone($this, ['labels' => ($this->labels ?? new EntityLabelsChange())->withAdded($this->collectLabelIds($labelIds))]); | |
| 71 | } | |
| 72 | ||
| 73 | /** @throws IdentifierException */ | |
| 74 | public function withRemovedLabels(LabelId|string ...$labelIds): self | |
| 75 | { | |
| 76 | return clone($this, ['labels' => ($this->labels ?? new EntityLabelsChange())->withRemoved($this->collectLabelIds($labelIds))]); | |
| 77 | } | |
| 78 | ||
| 79 | public function withAliases(EntityAlias|string ...$aliases): self | |
| 80 | { | |
| 81 | return clone($this, ['aliases' => EntityAliasesChange::replacingWith($this->collectAliases($aliases))]); | |
| 82 | } | |
| 83 | ||
| 84 | public function withAddedAliases(EntityAlias|string ...$aliases): self | |
| 85 | { | |
| 86 | return clone($this, ['aliases' => ($this->aliases ?? new EntityAliasesChange())->withAdded($this->collectAliases($aliases))]); | |
| 87 | } | |
| 88 | ||
| 89 | public function withRemovedAliases(EntityAlias|string ...$aliases): self | |
| 90 | { | |
| 91 | return clone($this, ['aliases' => ($this->aliases ?? new EntityAliasesChange())->withRemoved($this->collectAliases($aliases))]); | |
| 92 | } | |
| 93 | ||
| 94 | public function withHidden(bool $hidden): self | |
| 95 | { | |
| 96 | return clone($this, ['hidden' => $hidden]); | |
| 97 | } | |
| 98 | ||
| 99 | public function withDisabled(bool $disabled): self | |
| 100 | { | |
| 101 | return clone($this, ['disabled' => $disabled]); | |
| 102 | } | |
| 103 | ||
| 104 | public function isEmpty(): bool | |
| 105 | { | |
| 106 | return $this->name === null | |
| 107 | && $this->icon === null | |
| 108 | && $this->area === null | |
| 109 | && $this->labels === null | |
| 110 | && $this->aliases === null | |
| 111 | && $this->hidden === null | |
| 112 | && $this->disabled === null; | |
| 113 | } | |
| 114 | ||
| 115 | public function needsCurrentEntry(): bool | |
| 116 | { | |
| 117 | return $this->labels?->needsCurrentLabels() === true || $this->aliases?->needsCurrentAliases() === true; | |
| 118 | } | |
| 119 | ||
| 120 | public function resolveAgainst(RegisteredEntity $current): self | |
| 121 | { | |
| 122 | return clone($this, [ | |
| 123 | 'labels' => $this->labels?->resolveAgainst($current->listLabelIds()), | |
| 124 | 'aliases' => $this->aliases?->resolveAgainst($current->listAliases() ?? EntityAliasCollection::empty()), | |
| 125 | ]); | |
| 126 | } | |
| 127 | ||
| 128 | public function applyTo(RegisteredEntity $current): RegisteredEntity | |
| 129 | { | |
| 130 | return new RegisteredEntity( | |
| 131 | entityId: $current->entityId, | |
| 132 | deviceId: $current->deviceId, | |
| 133 | areaId: $this->area === null ? $current->areaId : $this->area->areaId, | |
| 134 | labelIds: $this->labels?->applyTo($current->listLabelIds())->listValues() ?? $current->labelIds, | |
| 135 | name: $this->name === null ? $current->name : $this->name->name, | |
| 136 | entityCategory: $current->entityCategory, | |
| 137 | hiddenBy: $this->hidden === null ? $current->hiddenBy : ($this->hidden ? self::CHANGED_BY_USER : null), | |
| 138 | disabledBy: $this->disabled === null ? $current->disabledBy : ($this->disabled ? self::CHANGED_BY_USER : null), | |
| 139 | icon: $this->icon === null ? $current->icon : $this->icon->icon, | |
| 140 | aliases: $this->aliases?->applyTo($current->listAliases() ?? EntityAliasCollection::empty())->listValues() ?? $current->aliases, | |
| 141 | ); | |
| 142 | } | |
| 143 | ||
| 144 | /** | |
| 145 | * @param array<LabelId|string> $labelIds | |
| 146 | * @throws IdentifierException | |
| 147 | */ | |
| 148 | private function collectLabelIds(array $labelIds): LabelIdCollection | |
| 149 | { | |
| 150 | return LabelIdCollection::fromList(array_map(LabelId::fromStringOrId(...), array_values($labelIds))); | |
| 151 | } | |
| 152 | ||
| 153 | /** @param array<EntityAlias|string> $aliases */ | |
| 154 | private function collectAliases(array $aliases): EntityAliasCollection | |
| 155 | { | |
| 156 | return EntityAliasCollection::fromList(array_map( | |
| 157 | static fn(EntityAlias|string $alias): EntityAlias => $alias instanceof EntityAlias ? $alias : EntityAlias::named($alias), | |
| 158 | array_values($aliases), | |
| 159 | )); | |
| 160 | } | |
| 161 | } |