Test Failed
Push — master ( 6eea59...bfd094 )
by Chris
31:05
created

PropertyResolver::getPropertyAsMethod()   A

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 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace WebTheory\Collection\Resolution;
4
5
use LogicException;
6
use ReflectionProperty;
7
use WebTheory\Collection\Contracts\PropertyResolverInterface;
8
9
class PropertyResolver implements PropertyResolverInterface
10
{
11
    protected array $defined = [];
12
13
    protected array $methods = [];
14
15
    protected array $members = [];
16
17 187
    public function __construct(array $defined = [])
18
    {
19 187
        $this->defined = $defined;
20
    }
21
22 187
    public function resolveProperty(object $object, string $property)
23
    {
24 187
        if ($definedMethod = $this->getDefinedMethod($property)) {
25 6
            return $object->{$definedMethod}();
26
        }
27
28 187
        if ($this->isAccessibleProperty($object, $property)) {
29 187
            return $object->{$property};
30
        }
31
32 4
        $inferredMethod = $this->getInferredMethod($property);
33
34 4
        if (is_callable([$object, $inferredMethod])) {
35 2
            return $object->{$inferredMethod}();
36
        }
37
38 2
        $inferredMember = $this->getInferredMember($property);
39
40 2
        if ($this->isAccessibleProperty($object, $inferredMember)) {
41
            return $object->{$inferredMember};
42
        }
43
44 2
        if (is_callable([$object, $property])) {
45
            return $object->{$property}();
46
        }
47
48 2
        throw new LogicException(
49 2
            sprintf(
50 2
                'No method of access has been defined or can be resolved for value "%s" in instances of class %s.',
51 2
                $property,
52 2
                get_class($object)
53 2
            )
54 2
        );
55
    }
56
57 187
    protected function isAccessibleProperty(object $object, string $property): bool
58
    {
59 187
        return property_exists($object, $property)
60 187
            && (new ReflectionProperty($object, $property))->isPublic();
61
    }
62
63 187
    protected function getDefinedMethod(string $property): ?string
64
    {
65 187
        return $this->defined[$property] ?? null;
66
    }
67
68 4
    protected function getInferredMethod(string $property): string
69
    {
70 4
        return $this->methods[$property]
71 4
            ??= $this->getPropertyAsMethod($property);
72
    }
73
74 2
    protected function getInferredMember(string $property): string
75
    {
76 2
        return $this->members[$property]
77 2
            ??= $this->getPropertyAsMember($property);
78
    }
79
80 4
    protected function getPropertyAsMethod(string $property): string
81
    {
82 4
        return 'get' . $this->convertToStudlyCaps($property);
83
    }
84
85 2
    protected function getPropertyAsMember(string $property): string
86
    {
87 2
        return lcfirst($this->convertToStudlyCaps($property));
88
    }
89
90 4
    protected function convertToStudlyCaps(string $string): string
91
    {
92 4
        return str_replace(' ', '', ucwords(str_replace('_', ' ', $string)));
93
    }
94
}
95