Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
39 / 39
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
RegularObjectStrategy
100.00% covered (success)
100.00%
39 / 39
100.00% covered (success)
100.00%
5 / 5
35
100.00% covered (success)
100.00%
1 / 1
 supports
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getModificationMetadata
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
9
 getCreationMetadata
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
13
 getResultMetadata
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
10
1<?php
2namespace Apie\Core\Metadata\Strategy;
3
4use Apie\Core\Attributes\Internal;
5use Apie\Core\Attributes\Optional;
6use Apie\Core\Context\ApieContext;
7use Apie\Core\Context\MetadataFieldHashmap;
8use Apie\Core\Metadata\CompositeMetadata;
9use Apie\Core\Metadata\Fields\ConstructorParameter;
10use Apie\Core\Metadata\Fields\GetterMethod;
11use Apie\Core\Metadata\Fields\PublicProperty;
12use Apie\Core\Metadata\Fields\SetterMethod;
13use Apie\Core\Metadata\StrategyInterface;
14use ReflectionClass;
15use ReflectionMethod;
16use ReflectionProperty;
17
18final class RegularObjectStrategy implements StrategyInterface
19{
20    /**
21     * @param ReflectionClass<object> $class
22     */
23    public static function supports(ReflectionClass $class): bool
24    {
25        return $class->isInstantiable() || $class->isInterface();
26    }
27
28    /**
29     * @param ReflectionClass<object> $class
30     */
31    public function __construct(private ReflectionClass $class)
32    {
33    }
34
35    public function getModificationMetadata(ApieContext $context): CompositeMetadata
36    {
37        $list = [];
38        foreach ($this->class->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {
39            if ($property->isReadOnly() || !$context->appliesToContext($property, false)) {
40                continue;
41            }
42            $list[$property->getName()] = new PublicProperty($property, true, true);
43        }
44        foreach ($this->class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
45            if (preg_match('/^(set).+$/i', $method->name) && !$method->isStatic() && !$method->isAbstract() && $context->appliesToContext($method, false)) {
46                $list[lcfirst(substr($method->name, 3))] = new SetterMethod($method);
47            }
48        }
49
50        return new CompositeMetadata((new MetadataFieldHashmap($list))->sort(), $this->class);
51    }
52
53    public function getCreationMetadata(ApieContext $context): CompositeMetadata
54    {
55        $list = [];
56        foreach ($this->class->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {
57            if (($property->isReadOnly() && !$property->isPromoted()) || !$context->appliesToContext($property, false)) {
58                continue;
59            }
60            $optional = false;
61            if (PHP_VERSION_ID >= 80400) {
62                $optional = !empty($property->getHooks());
63            }
64            $list[$property->getName()] = new PublicProperty($property, $optional, true);
65        }
66        foreach ($this->class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
67            if (preg_match('/^(set).+$/i', $method->name) && !$method->isStatic() && !$method->isAbstract() && $context->appliesToContext($method, false)) {
68                $list[lcfirst(substr($method->name, 3))] = new SetterMethod($method);
69            }
70        }
71
72        $constructor = $this->class->getConstructor();
73        if ($constructor) {
74            foreach ($constructor->getParameters() as $parameter) {
75                $list[$parameter->name] = new ConstructorParameter($parameter);
76            }
77        }
78
79        return new CompositeMetadata((new MetadataFieldHashmap($list))->sort(), $this->class);
80    }
81
82    public function getResultMetadata(ApieContext $context): CompositeMetadata
83    {
84        $list = [];
85        foreach ($this->class->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {
86            if (!$property->getAttributes(Internal::class) && $context->appliesToContext($property, false)) {
87                $list[$property->getName()] = new PublicProperty(
88                    $property,
89                    !empty($property->getAttributes(Optional::class)),
90                    false
91                );
92            }
93        }
94        foreach ($this->class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
95            if (preg_match('/^(get|is|has).+$/i', $method->name) && !$method->isStatic() && !$method->isAbstract() && !$method->getAttributes(Internal::class)) {
96                $list[lcfirst(substr($method->name, str_starts_with($method->name, 'is') ? 2 : 3))] = new GetterMethod($method);
97            }
98        }
99
100        return new CompositeMetadata((new MetadataFieldHashmap($list))->sort(), $this->class);
101    }
102}