Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
34 / 34
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
RunResourceMethodDefinition
100.00% covered (success)
100.00%
34 / 34
100.00% covered (success)
100.00%
6 / 6
14
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
 getResourceName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBoundedContextId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMethod
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getActionOptions
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 provideActionDefinitions
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
1 / 1
9
1<?php
2namespace Apie\Common\ActionDefinitions;
3
4use Apie\Core\Attributes\ActionOptions;
5use Apie\Core\BoundedContext\BoundedContext;
6use Apie\Core\BoundedContext\BoundedContextId;
7use Apie\Core\Context\ApieContext;
8use Apie\Core\ContextConstants;
9use Apie\Core\Entities\EntityInterface;
10use Apie\Core\Entities\PolymorphicEntityInterface;
11use Apie\Core\Utils\EntityUtils;
12use ReflectionClass;
13use ReflectionMethod;
14
15/**
16 * Action definition for modifying a single resource by id in a specific bounded context.
17 */
18final class RunResourceMethodDefinition implements ActionDefinitionInterface
19{
20    /**
21     * @param ReflectionClass<covariant EntityInterface> $resourceName
22     */
23    public function __construct(
24        private readonly ReflectionClass $resourceName,
25        private readonly ReflectionMethod $method,
26        private readonly BoundedContextId $boundedContextId,
27        private readonly ?ActionOptions $actionOptions = null
28    ) {
29    }
30
31    /**
32     * @return ReflectionClass<covariant EntityInterface>
33     */
34    public function getResourceName(): ReflectionClass
35    {
36        return $this->resourceName;
37    }
38
39    public function getBoundedContextId(): BoundedContextId
40    {
41        return $this->boundedContextId;
42    }
43
44    public function getMethod(): ReflectionMethod
45    {
46        return $this->method;
47    }
48
49    public function getActionOptions(): ?ActionOptions
50    {
51        return $this->actionOptions;
52    }
53
54    /**
55     * Business logic:
56     * - Check apie context with ContextConstants::RESOURCE_METHOD
57     */
58    public static function provideActionDefinitions(BoundedContext $boundedContext, ApieContext $apieContext, bool $runtimeChecks = false): array
59    {
60        $actionDefinitions = [];
61        $resourceActionContext = $apieContext->withContext(ContextConstants::RESOURCE_METHOD, true);
62        foreach ($boundedContext->resources->filterOnApieContext($resourceActionContext, $runtimeChecks) as $resource) {
63            $resourceList = [$resource];
64            if (in_array(PolymorphicEntityInterface::class, $resource->getInterfaceNames())) {
65                if ($runtimeChecks) {
66                    if ($resourceActionContext->hasContext(ContextConstants::RESOURCE)) {
67                        $resourceList = [new ReflectionClass($resourceActionContext->getContext(ContextConstants::RESOURCE))];
68                    }
69                } else {
70                    $resourceList = EntityUtils::getDiscriminatorClasses($resource);
71                }
72            }
73            foreach ($resourceList as $actualClass) {
74                foreach ($resourceActionContext->withContext(ContextConstants::RESOURCE_NAME, $actualClass->name)->getApplicableMethods($actualClass, $runtimeChecks) as $method) {
75                    $attributes = $method->getAttributes(ActionOptions::class);
76                    if (empty($attributes)) {
77                        $definition = new RunResourceMethodDefinition(
78                            $resource,
79                            $method,
80                            $boundedContext->getId()
81                        );
82                        $actionDefinitions[] = $definition;
83                    } else {
84                        foreach ($attributes as $attribute) {
85                            $actionOptions = $attribute->newInstance();
86                            $definition = new RunResourceMethodDefinition(
87                                $resource,
88                                $method,
89                                $boundedContext->getId(),
90                                $actionOptions
91                            );
92                            $actionDefinitions[] = $definition;
93                        }
94                    }
95                }
96            }
97        }
98        return $actionDefinitions;
99    }
100}