Completed
Push — master ( 6366df...fbe022 )
by Kirill
23s queued 19s
created

CachedReader::iterableToArray()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 7
rs 10
1
<?php
2
3
/**
4
 * This file is part of Spiral Framework package.
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Attributes\Internal;
13
14
use Spiral\Attributes\Internal\Key\ConcatKeyGenerator;
15
use Spiral\Attributes\Internal\Key\HashKeyGenerator;
16
use Spiral\Attributes\Internal\Key\KeyGeneratorInterface;
17
use Spiral\Attributes\Internal\Key\ModificationTimeKeyGenerator;
18
use Spiral\Attributes\Internal\Key\NameKeyGenerator;
19
use Spiral\Attributes\ReaderInterface;
20
21
abstract class CachedReader extends Decorator
22
{
23
    /**
24
     * @var KeyGeneratorInterface
25
     */
26
    protected $key;
27
28
    /**
29
     * @param ReaderInterface $reader
30
     * @param KeyGeneratorInterface|null $generator
31
     */
32
    public function __construct(ReaderInterface $reader, KeyGeneratorInterface $generator = null)
33
    {
34
        $this->key = $generator ?? $this->createDefaultKeyGenerator();
35
36
        parent::__construct($reader);
37
    }
38
39
    /**
40
     * {@inheritDoc}
41
     */
42
    public function getClassMetadata(\ReflectionClass $class, string $name = null): iterable
43
    {
44
        $result = $this->cached($this->key->forClass($class), function () use ($class) {
45
            return $this->iterableToArray(parent::getClassMetadata($class));
46
        });
47
48
        return $this->filter($name, $result);
49
    }
50
51
    /**
52
     * {@inheritDoc}
53
     */
54
    public function getFunctionMetadata(\ReflectionFunctionAbstract $function, string $name = null): iterable
55
    {
56
        $result = $this->cached($this->key->forFunction($function), function () use ($function) {
57
            return $this->iterableToArray(parent::getFunctionMetadata($function));
58
        });
59
60
        return $this->filter($name, $result);
61
    }
62
63
    /**
64
     * {@inheritDoc}
65
     */
66
    public function getPropertyMetadata(\ReflectionProperty $property, string $name = null): iterable
67
    {
68
        $result = $this->cached($this->key->forProperty($property), function () use ($property) {
69
            return $this->iterableToArray(parent::getPropertyMetadata($property));
70
        });
71
72
        return $this->filter($name, $result);
73
    }
74
75
    /**
76
     * {@inheritDoc}
77
     */
78
    public function getConstantMetadata(\ReflectionClassConstant $constant, string $name = null): iterable
79
    {
80
        $result = $this->cached($this->key->forConstant($constant), function () use ($constant) {
81
            return $this->iterableToArray(parent::getConstantMetadata($constant));
82
        });
83
84
        return $this->filter($name, $result);
85
    }
86
87
    /**
88
     * {@inheritDoc}
89
     */
90
    public function getParameterMetadata(\ReflectionParameter $parameter, string $name = null): iterable
91
    {
92
        $result = $this->cached($this->key->forParameter($parameter), function () use ($parameter) {
93
            return $this->iterableToArray(parent::getParameterMetadata($parameter));
94
        });
95
96
        return $this->filter($name, $result);
97
    }
98
99
    /**
100
     * @return KeyGeneratorInterface
101
     */
102
    protected function createDefaultKeyGenerator(): KeyGeneratorInterface
103
    {
104
        return new HashKeyGenerator(
105
            new ConcatKeyGenerator([
106
                new NameKeyGenerator(),
107
                new ModificationTimeKeyGenerator(),
108
            ])
109
        );
110
    }
111
112
    /**
113
     * @template T of object
114
     * @param string $key
115
     * @param callable(): array<T> $then
116
     * @return iterable<T>
117
     */
118
    abstract protected function cached(string $key, callable $then): iterable;
119
120
    /**
121
     * @template T of object
122
     * @param iterable<T> $attributes
123
     * @return array<T>
124
     */
125
    protected function iterableToArray(iterable $attributes): array
126
    {
127
        if ($attributes instanceof \Traversable) {
128
            return \iterator_to_array($attributes, false);
129
        }
130
131
        return $attributes;
132
    }
133
}
134