Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
63.16% covered (warning)
63.16%
24 / 38
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
AccessControlListAttributeConverter
63.16% covered (warning)
63.16%
24 / 38
33.33% covered (danger)
33.33%
1 / 3
26.25
0.00% covered (danger)
0.00%
0 / 1
 applyToDomain
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toReflClass
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
3.14
 applyToStorage
60.61% covered (warning)
60.61%
20 / 33
0.00% covered (danger)
0.00%
0 / 1
18.40
1<?php
2namespace Apie\StorageMetadata\PropertyConverters;
3
4use Apie\Core\Permissions\RequiresPermissionsInterface;
5use Apie\Core\ValueObjects\Utils;
6use Apie\StorageMetadata\Attributes\AclLinkAttribute;
7use Apie\StorageMetadata\Interfaces\PropertyConverterInterface;
8use Apie\StorageMetadata\Interfaces\StorageDtoInterface;
9use Apie\StorageMetadata\Mediators\DomainToStorageContext;
10use ReflectionClass;
11use ReflectionProperty;
12
13class AccessControlListAttributeConverter implements PropertyConverterInterface
14{
15    public function applyToDomain(
16        DomainToStorageContext $context
17    ): void {
18    }
19
20    /**
21     * @template T of object
22     * @param class-string<T> $className
23     * @return ReflectionClass<T>
24     */
25    private function toReflClass(string $className, mixed $contextStorageObject): ReflectionClass
26    {
27        if (str_starts_with($className, 'apie_') && is_object($contextStorageObject)) {
28            $refl = new ReflectionClass($contextStorageObject);
29            // @phpstan-ignore-next-line return.type
30            return new ReflectionClass($refl->getNamespaceName() . '\\' . $className);
31        }
32        return new ReflectionClass($className);
33    }
34
35    public function applyToStorage(
36        DomainToStorageContext $context
37    ): void {
38        foreach ($context->storageProperty->getAttributes(AclLinkAttribute::class) as $oneToManyAttribute) {
39            $domainPropertyValue = $context->domainObject instanceof RequiresPermissionsInterface
40                ? $context->domainObject->getRequiredPermissions()->toStringList()->toArray()
41                : [];
42            $storageProperties = $context->storageProperty->isInitialized($context->storageObject)
43                ? Utils::toArray($context->storageProperty->getValue($context->storageObject))
44                : [];
45            // in case there are no required permissions, we need to add a '' record because we need the record with JOIN
46            // see RequiresPermissionFilter class.
47            if (empty($domainPropertyValue)) {
48                $domainPropertyValue = [''];
49            }
50            foreach ($domainPropertyValue as $arrayKey => $arrayValue) {
51                $arrayContext = $context->withArrayKey($arrayKey);
52                $storageClassRefl = $this->toReflClass($oneToManyAttribute->newInstance()->storageClass, $context->storageObject);
53                if (is_object($arrayValue) && in_array(StorageDtoInterface::class, $storageClassRefl->getInterfaceNames())) {
54                    if (isset($storageProperties[$arrayKey]) && $storageProperties[$arrayKey] instanceof StorageDtoInterface) {
55                        $arrayContext->domainToStorageConverter->injectExistingStorageObject(
56                            $arrayValue,
57                            $storageProperties[$arrayKey],
58                            $arrayContext
59                        );
60                    } else {
61                        $storageProperties[$arrayKey] = $arrayContext->domainToStorageConverter->createStorageObject(
62                            $arrayValue,
63                            $storageClassRefl,
64                            $arrayContext
65                        );
66                    }
67                } else {
68                    $storageProperties[$arrayKey] = $storageClassRefl->newInstance(Utils::toString($arrayValue));
69                    $properties = $storageClassRefl->getProperties(ReflectionProperty::IS_PUBLIC);
70                    foreach ($properties as $property) {
71                        ManyToOneAttributeConverter::applyToProperty(
72                            $property,
73                            $storageProperties[$arrayKey],
74                            $context->storageObject
75                        );
76                    }
77                }
78            }
79            $context->storageProperty->setValue($context->storageObject, $context->dynamicCast($storageProperties, $context->storageProperty->getType()));
80        }
81    }
82}