MethodsStrategy::cleanName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 1
eloc 1
c 2
b 1
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
namespace Maiorano\ObjectHydrator\Strategies\Reflection;
4
5
use Generator;
6
use Maiorano\ObjectHydrator\Attributes\HydrationKey;
7
use Maiorano\ObjectHydrator\Mappings\MethodMapping;
8
use Maiorano\ObjectHydrator\Strategies\DirectKeyAccessTrait;
9
use Maiorano\ObjectHydrator\Strategies\HydrationStrategyInterface;
10
use Maiorano\ObjectHydrator\Strategies\RecursiveCheckTrait;
11
use ReflectionClass;
12
use ReflectionMethod;
13
14
final class MethodsStrategy implements HydrationStrategyInterface
15
{
16
    use DirectKeyAccessTrait;
17
    use RecursiveCheckTrait;
18
19
    /**
20
     * @var int|null
21
     */
22
    private ?int $methodTypes;
23
    /**
24
     * @var string
25
     */
26
    private string $prefix;
27
    /**
28
     * @var ReflectionClass
29
     */
30
    private ReflectionClass $reflectionClass;
31
    /**
32
     * @var MethodMapping[]
33
     */
34
    private array $mappings;
35
36
    /**
37
     * @param int|null $methodTypes
38
     * @param string   $prefix
39
     */
40 8
    public function __construct(?int $methodTypes = ReflectionMethod::IS_PUBLIC, string $prefix = 'set')
41
    {
42 8
        $this->methodTypes = $methodTypes;
43 8
        $this->prefix = $prefix;
44 8
    }
45
46
    /**
47
     * @param object $object
48
     *
49
     * @return void
50
     */
51 6
    public function initialize(object $object): void
52
    {
53 6
        $this->reflectionClass = new ReflectionClass($object);
54 6
        $this->mappings = iterator_to_array($this->generateKeyMap());
55 6
    }
56
57
    /**
58
     * @return Generator
59
     */
60 6
    private function generateKeyMap(): Generator
61
    {
62 6
        foreach ($this->reflectionClass->getMethods($this->methodTypes) as $reflector) {
63 6
            $attributes = $reflector->getAttributes(HydrationKey::class);
64 6
            yield from $attributes
65 5
                ? $this->generateKeysFromAttributes($reflector, $attributes)
66 6
                : $this->generateKeysFromNames($reflector);
67
        }
68 6
    }
69
70
    /**
71
     * @param ReflectionMethod $method
72
     * @param array            $attributes
73
     *
74
     * @return Generator
75
     */
76 5
    private function generateKeysFromAttributes(ReflectionMethod $method, array $attributes): Generator
77
    {
78 5
        foreach ($attributes as $attribute) {
79 5
            $mapping = new MethodMapping($method, $attribute->newInstance());
80 5
            yield $mapping->getKey() => $mapping;
81
        }
82 5
    }
83
84
    /**
85
     * @param ReflectionMethod $method
86
     *
87
     * @return Generator
88
     */
89 6
    private function generateKeysFromNames(ReflectionMethod $method): Generator
90
    {
91 6
        $maybeProp = preg_match("/^{$this->prefix}(.*)/i", $method->getName(), $matches);
92 6
        if ($maybeProp && isset($matches[1])) {
93 6
            yield from $this->checkPropertyNames($method, $this->cleanName($matches[1]));
94
        }
95 6
    }
96
97
    /**
98
     * @param ReflectionMethod $method
99
     * @param string           $name
100
     *
101
     * @return Generator
102
     */
103 6
    private function checkPropertyNames(ReflectionMethod $method, string $name): Generator
104
    {
105 6
        foreach ($this->reflectionClass->getProperties() as $property) {
106 6
            if ($name === $this->cleanName($property->getName())) {
107 6
                $mapping = new MethodMapping($method, new HydrationKey($name));
108 6
                yield $mapping->getKey() => $mapping;
109 6
                break;
110
            }
111
        }
112 6
    }
113
114
    /**
115
     * @param string $name
116
     *
117
     * @return string
118
     */
119 6
    private function cleanName(string $name): string
120
    {
121 6
        return lcfirst(preg_replace('/[^a-zA-Z]/', '', $name));
122
    }
123
}
124