CachedObjectAccess::isSupported()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 7
c 1
b 0
f 1
nc 1
nop 1
dl 0
loc 11
rs 10
1
<?php
2
3
4
namespace Apie\ObjectAccessNormalizer\ObjectAccess;
5
6
use Closure;
7
use Psr\Cache\CacheItemPoolInterface;
8
use ReflectionClass;
9
use ReflectionMethod;
10
11
class CachedObjectAccess implements ObjectAccessSupportedInterface
12
{
13
    /**
14
     * @var ObjectAccessInterface
15
     */
16
    private $internal;
17
18
    /**
19
     * @var CacheItemPoolInterface
20
     */
21
    private $cacheItemPool;
22
23
    /**
24
     * @param ObjectAccessInterface $internal
25
     * @param CacheItemPoolInterface $cacheItemPool
26
     */
27
    public function __construct(ObjectAccessInterface $internal, CacheItemPoolInterface $cacheItemPool)
28
    {
29
        $this->internal = $internal;
30
        $this->cacheItemPool = $cacheItemPool;
31
    }
32
33
    /**
34
     * {@inheritDoc}
35
     */
36
    public function getGetterFields(ReflectionClass $reflectionClass): array
37
    {
38
        return $this->cacheCheck(
39
            __FUNCTION__ . ',' . $reflectionClass->name,
40
            function (ReflectionClass $reflectionClass) {
41
                return $this->internal->getGetterFields($reflectionClass);
42
            },
43
            $reflectionClass
44
        );
45
    }
46
47
    /**
48
     * {@inheritDoc}
49
     */
50
    public function getSetterFields(ReflectionClass $reflectionClass): array
51
    {
52
        return $this->cacheCheck(
53
            __FUNCTION__ . ',' . $reflectionClass->name,
54
            function (ReflectionClass $reflectionClass) {
55
                return $this->internal->getSetterFields($reflectionClass);
56
            },
57
            $reflectionClass
58
        );
59
    }
60
61
    /**
62
     * {@inheritDoc}
63
     */
64
    public function getGetterTypes(ReflectionClass $reflectionClass, string $fieldName): array
65
    {
66
        return $this->cacheCheck(
67
            __FUNCTION__ . ',' . $reflectionClass->name . ',' . $fieldName,
68
            function (ReflectionClass $reflectionClass, string $fieldName) {
69
                return $this->internal->getGetterTypes($reflectionClass, $fieldName);
70
            },
71
            $reflectionClass,
72
            $fieldName
73
        );
74
    }
75
76
    /**
77
     * {@inheritDoc}
78
     */
79
    public function getSetterTypes(ReflectionClass $reflectionClass, string $fieldName): array
80
    {
81
        return $this->cacheCheck(
82
            __FUNCTION__ . ',' . $reflectionClass->name . ',' . $fieldName,
83
            function (ReflectionClass $reflectionClass, string $fieldName) {
84
                return $this->internal->getSetterTypes($reflectionClass, $fieldName);
85
            },
86
            $reflectionClass,
87
            $fieldName
88
        );
89
    }
90
91
    /**
92
     * {@inheritDoc}
93
     */
94
    public function getConstructorArguments(ReflectionClass $reflectionClass): array
95
    {
96
        return $this->cacheCheck(
97
            __FUNCTION__ . ',' . $reflectionClass->name,
98
            function (ReflectionClass $reflectionClass) {
99
                return $this->internal->getConstructorArguments($reflectionClass);
100
            },
101
            $reflectionClass
102
        );
103
    }
104
105
    /**
106
     * {@inheritDoc}
107
     */
108
    public function getValue(object $instance, string $fieldName)
109
    {
110
        return $this->internal->getValue($instance, $fieldName);
111
    }
112
113
    /**
114
     * {@inheritDoc}
115
     */
116
    public function setValue(object $instance, string $fieldName, $value)
117
    {
118
        return $this->internal->setValue($instance, $fieldName, $value);
119
    }
120
121
    /**
122
     * {@inheritDoc}
123
     */
124
    public function instantiate(ReflectionClass $reflectionClass, array $constructorArgs): object
125
    {
126
        return $this->internal->instantiate($reflectionClass, $constructorArgs);
127
    }
128
129
    /**
130
     * {@inheritDoc}
131
     */
132
    public function getDescription(ReflectionClass $reflectionClass, string $fieldName, bool $preferGetters): ?string
133
    {
134
        return $this->cacheCheck(
135
            __FUNCTION__ . ',' . $reflectionClass->name . ',' . $fieldName . ',' . json_encode($preferGetters),
136
            function (ReflectionClass $reflectionClass, string $fieldName, bool $preferGetters) {
137
                return $this->internal->getDescription($reflectionClass, $fieldName, $preferGetters);
138
            },
139
            $reflectionClass,
140
            $fieldName,
141
            $preferGetters
142
        );
143
    }
144
145
    /**
146
     * {@inheritDoc}
147
     */
148
    public function isSupported(ReflectionClass $reflectionClass): bool
149
    {
150
        return $this->cacheCheck(
151
            __FUNCTION__ . ',' . $reflectionClass->name,
152
            function (ReflectionClass $reflectionClass) {
153
                if ($this->internal instanceof ObjectAccessSupportedInterface) {
154
                    return $this->internal->isSupported($reflectionClass);
155
                }
156
                return true;
157
            },
158
            $reflectionClass
159
        );
160
    }
161
162
163
    /**
164
     * {@inheritDoc}
165
     */
166
    public function getMethodArguments(ReflectionMethod $method, ?ReflectionClass $reflectionClass = null): array
167
    {
168
        return $this->cacheCheck(
169
            __FUNCTION__ . ',' . $method->name . ',' . ($reflectionClass ? $reflectionClass->name : '(null)'),
170
            function (ReflectionMethod $method, ?ReflectionClass $reflectionClass = null) {
171
                return $this->internal->getMethodArguments($method, $reflectionClass);
172
            },
173
            $method,
174
            $reflectionClass
175
        );
176
    }
177
178
    /**
179
     * Cache helper method.
180
     *
181
     * @param string $cacheKey
182
     * @param Closure $callback
183
     * @param mixed ...$args
184
     * @return mixed
185
     */
186
    private function cacheCheck(string $cacheKey, Closure $callback, ...$args)
187
    {
188
        $cacheKey = str_replace('\\', '|', $cacheKey);
189
        $cacheItem = $this->cacheItemPool->getItem($cacheKey);
190
        if ($cacheItem->isHit()) {
191
            return $cacheItem->get();
192
        }
193
        $returnValue = $callback(...$args);
194
        $cacheItem->set($returnValue);
195
        $this->cacheItemPool->save($cacheItem);
196
        return $returnValue;
197
    }
198
}
199