Lines 89.44% 195 / 218
Methods 80.70% 46 / 57
Classes 0.00% 0 / 1
Name Lines Methods CRAP
 getDefaults 100.00% 7 / 7 100.00% 1 / 1 1
 getQueuePreference 100.00% 6 / 6 100.00% 1 / 1 5
 getUseraccount 100.00% 3 / 3 100.00% 1 / 1 2
 getDepartmentById 100.00% 1 / 1 100.00% 1 / 1 1
 getDepartmentList 100.00% 4 / 4 100.00% 1 / 1 2
 testDepartmentList 100.00% 2 / 2 100.00% 1 / 1 2
 getProviderOfGivenScope 100.00% 1 / 1 100.00% 1 / 1 1
 hasSuperUseraccount 100.00% 1 / 1 100.00% 1 / 1 1
 hasAuditAccount 100.00% 1 / 1 100.00% 1 / 1 1
 getAuthKey 100.00% 1 / 1 100.00% 1 / 1 1
 hasAuthKey 100.00% 1 / 1 100.00% 1 / 1 2
 getVariantName 100.00% 1 / 1 100.00% 1 / 1 2
 getName 100.00% 1 / 1 100.00% 1 / 1 2
 getScope 100.00% 5 / 5 100.00% 1 / 1 3
 getProcess 0.00% 0 / 5 0.00% 0 / 1 12
 getScopeList 100.00% 6 / 6 100.00% 1 / 1 3
 getScopeListFromAssignedDepartments 100.00% 7 / 7 100.00% 1 / 1 4
 validateProcessScopeAccess 94.44% 17 / 18 0.00% 0 / 1 5.00
 setValidatedName 100.00% 5 / 5 100.00% 1 / 1 5
 setValidatedHint 100.00% 5 / 5 100.00% 1 / 1 5
 setValidatedScope 100.00% 8 / 8 100.00% 1 / 1 4
 setValidatedAppointmentsOnly 100.00% 4 / 4 100.00% 1 / 1 2
 isClusterEnabled 0.00% 0 / 1 0.00% 0 / 1 6
 hasAccessToUseraccount 0.00% 0 / 3 0.00% 0 / 1 6
 [BO\Zmsentities\Schema\Entity] __construct 100.00% 4 / 4 100.00% 1 / 1 2
 [BO\Zmsentities\Schema\Entity] exchangeArray 100.00% 4 / 4 100.00% 1 / 1 1
 [BO\Zmsentities\Schema\Entity] offsetSet 100.00% 1 / 1 100.00% 1 / 1 1
 [BO\Zmsentities\Schema\Entity] getUnflattenedArray 100.00% 5 / 5 100.00% 1 / 1 2
 [BO\Zmsentities\Schema\Entity] getValidator 100.00% 6 / 6 100.00% 1 / 1 2
 [BO\Zmsentities\Schema\Entity] isValid 100.00% 2 / 2 100.00% 1 / 1 1
 [BO\Zmsentities\Schema\Entity] testValid 100.00% 7 / 7 100.00% 1 / 1 2
 [BO\Zmsentities\Schema\Entity] createExample 100.00% 2 / 2 100.00% 1 / 1 1
 [BO\Zmsentities\Schema\Entity] getExample 100.00% 5 / 5 100.00% 1 / 1 2
 [BO\Zmsentities\Schema\Entity] readJsonSchema 66.66% 6 / 9 0.00% 0 / 1 3.33
 [BO\Zmsentities\Schema\Entity] getEntityName 100.00% 4 / 4 100.00% 1 / 1 1
 [BO\Zmsentities\Schema\Entity] setJsonCompressLevel 100.00% 2 / 2 100.00% 1 / 1 1
 [BO\Zmsentities\Schema\Entity] jsonSerialize 100.00% 11 / 11 100.00% 1 / 1 2
 [BO\Zmsentities\Schema\Entity] __toString 100.00% 2 / 2 100.00% 1 / 1 2
 [BO\Zmsentities\Schema\Entity] __get 0.00% 0 / 1 0.00% 0 / 1 2
 [BO\Zmsentities\Schema\Entity] __isset 0.00% 0 / 1 0.00% 0 / 1 2
 [BO\Zmsentities\Schema\Entity] __set 0.00% 0 / 1 0.00% 0 / 1 2
 [BO\Zmsentities\Schema\Entity] __unset 0.00% 0 / 1 0.00% 0 / 1 2
 [BO\Zmsentities\Schema\Entity] __clone 100.00% 3 / 3 100.00% 1 / 1 3
 [BO\Zmsentities\Schema\Entity] addData 100.00% 14 / 14 100.00% 1 / 1 6
 [BO\Zmsentities\Schema\Entity] withData 0.00% 0 / 3 0.00% 0 / 1 2
 [BO\Zmsentities\Schema\Entity] hasId 100.00% 1 / 1 100.00% 1 / 1 2
 [BO\Zmsentities\Schema\Entity] getId 100.00% 2 / 2 100.00% 1 / 1 3
 [BO\Zmsentities\Schema\Entity] toProperty 100.00% 1 / 1 100.00% 1 / 1 1
 [BO\Zmsentities\Schema\Entity] hasProperty 100.00% 1 / 1 100.00% 1 / 1 1
 [BO\Zmsentities\Schema\Entity] getProperty 100.00% 1 / 1 100.00% 1 / 1 1
 [BO\Zmsentities\Schema\Entity] withProperty 0.00% 0 / 3 0.00% 0 / 1 2
 [BO\Zmsentities\Schema\Entity] withLessData 100.00% 1 / 1 100.00% 1 / 1 1
 [BO\Zmsentities\Schema\Entity] withCleanedUpFormData 100.00% 6 / 6 100.00% 1 / 1 3
 [BO\Zmsentities\Schema\Entity] getResolveLevel 100.00% 1 / 1 100.00% 1 / 1 1
 [BO\Zmsentities\Schema\Entity] setResolveLevel 100.00% 2 / 2 100.00% 1 / 1 1
 [BO\Zmsentities\Schema\Entity] withResolveLevel 100.00% 9 / 9 100.00% 1 / 1 5
 [BO\Zmsentities\Schema\Entity] withReference 100.00% 5 / 5 100.00% 1 / 1 2
17class Workstation extends Schema\Entity
18{
19    public const string PRIMARY = 'id';
20
21    public static $schema = "workstation.json";
22
23    /**
24     * @return (Process|Scope|Useraccount|int|string)[]
25     *
26     */
27    #[\Override]
28    public function getDefaults()
29    {
30        return [
31            'id' => 0,
32            'useraccount' => new Useraccount(),
33            'process' => new Process(),
34            'name' => '',
35            'scope' => new Scope()
36        ];
37    }
38
39    public function getQueuePreference(mixed $key, bool $isBoolean = false): mixed
40    {
41        $result = null;
42        if (isset($this['queue']) && Property::__keyExists($key, $this['queue'])) {
43            if ($isBoolean) {
44                $result = ($this['queue'][$key]) ? 1 : 0;
45            } else {
46                $result = $this['queue'][$key];
47            }
48        }
49        return $result;
50    }
51
52    public function getUseraccount(): Useraccount
53    {
54        if (!$this->useraccount instanceof Useraccount) {
55            $this->useraccount = new Useraccount($this->useraccount);
56        }
57        return $this->useraccount;
58    }
59
60    public function getDepartmentById(mixed $departmentId): \BO\Zmsentities\Department
61    {
62        return $this->getUseraccount()->getDepartmentById($departmentId);
63    }
64
65    public function getDepartmentList(): Collection\DepartmentList
66    {
67        $departmentList = new Collection\DepartmentList();
68        foreach ($this->getUseraccount()->getDepartmentList() as $department) {
69            $departmentList->addEntity(new Department($department));
70        }
71        return $departmentList;
72    }
73
74    /**
75     * @return void
76     */
77    public function testDepartmentList()
78    {
79        if (0 == $this->getDepartmentList()->count()) {
80            throw new Exception\WorkstationMissingAssignedDepartments();
81        }
82    }
83
84    public function getProviderOfGivenScope(): mixed
85    {
86        return $this->toProperty()->scope->provider->id->get();
87    }
88
89    public function hasSuperUseraccount(): bool
90    {
91        return $this->getUseraccount()->isSuperUser();
92    }
93
94    public function hasAuditAccount(): bool
95    {
96        return $this->getUseraccount()->hasPermissions(['logs']);
97    }
98
99    public function getAuthKey(): string
100    {
101        return bin2hex(openssl_random_pseudo_bytes(16));
102    }
103
104    public function hasAuthKey(): bool
105    {
106        return (isset($this->authkey)) ? true : false;
107    }
108
109    public function getVariantName(): string
110    {
111        return (! trim($this->name)) ? 'counter' : 'workstation';
112    }
113
114    public function getName(): mixed
115    {
116        return ($this->name) ? $this->name : "Tresen";
117    }
118
119    public function getScope(): Scope
120    {
121        $scope = $this->offsetExists('scope') ? $this['scope'] : null;
122        if (!$scope instanceof Scope) {
123            $scope = new Scope($scope);
124            $this['scope'] = $scope;
125        }
126        return $scope;
127    }
128
129    public function getProcess(): Process
130    {
131        $process = $this->offsetExists('process') ? $this['process'] : null;
132        if (!$process instanceof Process) {
133            $process = new Process($process);
134            $this['process'] = $process;
135        }
136        return $process;
137    }
138
139    public function getScopeList(mixed $cluster = null): Collection\ScopeList
140    {
141        $scopeList = new Collection\ScopeList();
142        $scopeList->addEntity(new Scope($this->getScope()));
143        if ($cluster && 1 == $this->queue['clusterEnabled']) {
144            $scopeList = new Collection\ScopeList();
145            $scopeList->addList($cluster->scopes);
146        }
147        return $scopeList;
148    }
149
150    public function getScopeListFromAssignedDepartments(): Collection\ScopeList
151    {
152        $scopeList = new Collection\ScopeList();
153        foreach ($this->getDepartmentList() as $department) {
154            $scopeList->addList($department->getScopeList());
155        }
156        foreach ($this->getScopeList() as $scope) {
157            if (! $scopeList->hasEntity($scope->id)) {
158                $scopeList->addEntity($scope);
159            }
160        }
161        return $scopeList;
162    }
163
164    /**
165     * @return void
166     */
167    public function validateProcessScopeAccess(mixed $scopeList, mixed $process = null)
168    {
169        if (null === $process) {
170            $process = $this->process;
171        }
172        if (! $scopeList->hasEntity($process->getScopeId())) {
173            $exception = new Exception\WorkstationProcessMatchScopeFailed();
174            $scopeContactName = null;
175            $currentScope = $process->getCurrentScope();
176            if ($currentScope instanceof Scope && isset($currentScope['contact']['name'])) {
177                $scopeContactName = $currentScope['contact']['name'];
178            }
179
180            $exception->data = [
181                'id' => $process->getId(),
182                'scope' => [
183                    'id' => $process->getScopeId(),
184                    'contact' => [
185                        'name' => $scopeContactName
186                    ]
187                ]
188            ];
189            throw $exception;
190        }
191    }
192
193    public function setValidatedName(array $formData): static
194    {
195        if (isset($formData['workstation']) && trim($formData['workstation']->getValue())) {
196            $this->name = $formData['workstation']->getValue();
197        } elseif (isset($formData['workstation']) && ! trim($formData['workstation']->getValue())) {
198            $this->name = '';
199        }
200        return $this;
201    }
202
203    public function setValidatedHint(array $formData): static
204    {
205        if (isset($formData['hint']) && $formData['hint']->getValue()) {
206            $this->hint = $formData['hint']->getValue();
207        } elseif (isset($formData['hint']) && ! $formData['hint']->getValue()) {
208            $this->hint = '';
209        }
210        return $this;
211    }
212
213    public function setValidatedScope(array $formData): static
214    {
215        if (isset($formData['scope']) && 'cluster' === $formData['scope']->getValue()) {
216            $this->queue['clusterEnabled'] = 1;
217        } elseif (isset($formData['scope'])) {
218            $this->queue['clusterEnabled'] = 0;
219            $this->scope = new Scope([
220                'id' => $formData['scope']->getValue(),
221            ]);
222        }
223        return $this;
224    }
225
226    public function setValidatedAppointmentsOnly(array $formData): static
227    {
228        $this->queue['appointmentsOnly'] = (isset($formData['appointmentsOnly'])) ?
229            $formData['appointmentsOnly']->getValue() :
230            0;
231        return $this;
232    }
233
234    public function isClusterEnabled(): bool
235    {
236        return $this->queue['clusterEnabled'] ? true : false;
237    }
238
239    public function hasAccessToUseraccount(mixed $useraccount): bool
240    {
241        $departmentList = $this->getDepartmentList();
242        $accessedList = $departmentList->withAccess($useraccount);
243        return ($accessedList->count()) ? true : false;
244    }
245}

Inherited from BO\Zmsentities\Schema\Entity

59    public function __construct(mixed $input = null, int $flags = \ArrayObject::ARRAY_AS_PROPS, string $iterator_class = "ArrayIterator")
60    {
61        /** @var class-string<\ArrayIterator> $iterator_class */
62        parent::__construct($this->getDefaults(), $flags, $iterator_class);
63        if ($input) {
64            $input = $this->getUnflattenedArray($input);
65            $this->addData($input);
66        }
67    }
70    public function exchangeArray(object|array $input): array
71    {
72        parent::exchangeArray($this->getDefaults());
73        $input = $this->getUnflattenedArray($input);
74        $this->addData($input);
75        return $this->getArrayCopy();
76    }
82    public function offsetSet(mixed $key, mixed $value): void
83    {
84        /** @psalm-suppress PossiblyNullArgument */
85        parent::offsetSet($key, $value);
86    }
88    public function getUnflattenedArray(mixed $input): mixed
89    {
90        if (!$input instanceof UnflattedArray) {
91            $input = new UnflattedArray($input);
92            $input->getUnflattenedArray();
93        }
94        $input = $input->getValue();
95        return $input;
96    }
112    public function getValidator(string $locale = 'de_DE', int $resolveLevel = 0): Validator
113    {
114        $jsonSchema = self::readJsonSchema()->withResolvedReferences($resolveLevel);
115        $data = (new Schema($this))->withoutRefs();
116        if (Property::__keyExists('$schema', $data)) {
117            unset($data['$schema']);
118        }
119        $validator = new Validator($data->toJsonObject(true), $jsonSchema, $locale);
120        return $validator;
121    }
128    public function isValid(int $resolveLevel = 0): bool
129    {
130        $validator = $this->getValidator('de_DE', $resolveLevel = 0);
131        return $validator->isValid();
132    }
140    public function testValid(string $locale = 'de_DE', int $resolveLevel = 0): bool
141    {
142        $validator = $this->getValidator($locale, $resolveLevel);
143        if (!$validator->isValid()) {
144            $exception = new \BO\Zmsentities\Exception\SchemaValidation();
145            $exception->setSchemaName($this->getEntityName());
146            $exception->setValidationError($validator->getErrors());
147            throw $exception;
148        }
149        return true;
150    }
157    public static function createExample()
158    {
159        $object = new static();
160        return $object->getExample();
161    }
168    public static function getExample()
169    {
170        $class = get_called_class();
171        $jsonSchema = self::readJsonSchema();
172        if ($jsonSchema->offsetExists('example')) {
173            return new $class($jsonSchema['example']);
174        }
175        return new $class();
176    }
178    protected static function readJsonSchema(): mixed
179    {
180        $class = get_called_class();
181        if (!array_key_exists($class, self::$schemaCache)) {
182            $schemaFile = $class::$schema;
183            if (!is_string($schemaFile)) {
184                throw new \BO\Zmsentities\Exception\SchemaMissingJsonFile(
185                    'Missing JSON-Schema file for ' . $class
186                );
187            }
188            self::$schemaCache[$class] = Loader::asArray($schemaFile);
189        }
190        return self::$schemaCache[$class];
191    }
193    public function getEntityName(): string
194    {
195        $entity = get_class($this);
196        $entity = preg_replace('#.*[\\\]#', '', $entity) ?? '';
197        $entity = strtolower($entity);
198        return $entity;
199    }
201    public function setJsonCompressLevel(mixed $jsonCompressLevel): static
202    {
203        $this->jsonCompressLevel = $jsonCompressLevel;
204        return $this;
205    }
208    public function jsonSerialize(): mixed
209    {
210        $schema = array(
211            '$schema' => 'https://schema.berlin.de/queuemanagement/' . $this->getEntityName() . '.json'
212        );
213        $schema = array_merge($schema, $this->getArrayCopy());
214        if ($this instanceof \BO\Zmsentities\Helper\NoSanitize) {
215            $serialize = $schema;
216        } else {
217            $schema = new Schema($schema);
218            $schema->setDefaults($this->getDefaults());
219            $schema->setJsonCompressLevel($this->jsonCompressLevel);
220            $serialize = $schema->toJsonObject();
221        }
222        return $serialize;
223    }
225    public function __toString()
226    {
227        $encoded = json_encode($this->jsonSerialize(), JSON_HEX_QUOT);
228        return $encoded !== false ? $encoded : '';
229    }
235    public function __get(string $name): mixed
236    {
237        return $this->offsetGet($name);
238    }
240    public function __isset(string $name): bool
241    {
242        return $this->offsetExists($name);
243    }
245    public function __set(string $name, mixed $value): void
246    {
247        $this->offsetSet($name, $value);
248    }
250    public function __unset(string $name): void
251    {
252        $this->offsetUnset($name);
253    }
255    public function __clone()
256    {
257        foreach ($this as $key => $property) {
258            if (is_object($property)) {
259                $this[$key] = clone $property;
260            }
261        }
262    }
268    public function addData(array|object $mergeData): static
269    {
270        foreach ($mergeData as $key => $item) {
271            if (isset($this[$key])) {
272                if ($this[$key] instanceof Entity) {
273                    $this[$key]->setResolveLevel(($this->getResolveLevel() ?? 0) - 1);
274                    $this[$key]->addData($item);
275                } elseif ($this[$key] instanceof \BO\Zmsentities\Collection\Base) {
276                    $this[$key]->exchangeArray([]);
277                    $this[$key]->setResolveLevel(($this->getResolveLevel() ?? 0) - 1);
278                    $this[$key]->addData($item);
279                } elseif (is_array($this[$key])) {
280                    $this[$key] = array_replace_recursive($this[$key], $item);
281                } else {
282                    $this[$key] = $item;
283                }
284            } else {
285                $this[$key] = $item;
286            }
287        }
288        return $this;
289    }
294    public function withData(mixed $mergeData): static
295    {
296        $entity = clone $this;
297        $entity->addData($mergeData);
298        return $entity;
299    }
301    public function hasId(): bool
302    {
303        return (false !== $this->getId()) ? true : false;
304    }
306    public function getId(): mixed
307    {
308        $idName = $this::PRIMARY;
309        return ($this->offsetExists($idName) && $this[$idName]) ? $this[$idName] : false;
310    }
317    public function toProperty()
318    {
319        return new \BO\Zmsentities\Helper\Property($this);
320    }
322    public function hasProperty(mixed $propertyName): mixed
323    {
324        return $this->toProperty()->{$propertyName}->isAvailable();
325    }
327    public function getProperty(string $propertyName, mixed $default = ''): mixed
328    {
329        return $this->toProperty()->{$propertyName}->get($default);
330    }
335    public function withProperty(mixed $propertyName, mixed $newValue): static
336    {
337        $entity = clone $this;
338        $entity[$propertyName] = $newValue;
339        return $entity;
340    }
347    public function withLessData()
348    {
349        return clone $this;
350    }
357    public function withCleanedUpFormData()
358    {
359        $entity = clone $this;
360        if (isset($entity['save'])) {
361            unset($entity['save']);
362        }
363        if (isset($entity['removeImage'])) {
364            unset($entity['removeImage']);
365        }
366        return $entity;
367    }
372    public function getResolveLevel()
373    {
374        return $this->resolveLevel;
375    }
381    public function setResolveLevel($resolveLevel)
382    {
383        $this->resolveLevel = $resolveLevel;
384        return $this;
385    }
393    public function withResolveLevel($resolveLevel): self|array
394    {
395        if ($resolveLevel >= 0) {
396            $entity = clone $this;
397            foreach ($entity as $key => $value) {
398                if ($value instanceof Entity || $value instanceof \BO\Zmsentities\Collection\Base) {
399                    $entity[$key] = $value->withResolveLevel($resolveLevel - 1);
400                } else {
401                    $entity[$key] = $value;
402                }
403            }
404            $entity->setResolveLevel($resolveLevel);
405            return $entity;
406        } else {
407            return $this->withReference();
408        }
409    }
417    public function withReference($additionalData = []): self|array
418    {
419        if (isset($this[$this::PRIMARY])) {
420            $additionalData['$ref'] =
421                $this::$schemaRefPrefix . $this->getEntityName() . '/' . $this[$this::PRIMARY] . '/';
422            return $additionalData;
423        } else {
424            return $this->withResolveLevel(0);
425        }
426    }