Passed
Push — master ( 6137ca...01151b )
by Kevin
02:21
created

SpecificationNormalizer::supports()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
c 1
b 0
f 1
nc 1
nop 2
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
1
<?php
2
3
namespace Zenstruck\Porpaginas\Specification;
4
5
use Zenstruck\Porpaginas\Specification\Normalizer\NormalizerAware;
6
7
/**
8
 * @author Kevin Bond <[email protected]>
9
 */
10
final class SpecificationNormalizer implements Normalizer
11
{
12
    private iterable $normalizers;
13
    private array $normalizerCache = [];
14
15
    /**
16
     * @param Normalizer[] $normalizers
17
     */
18 2
    public function __construct(iterable $normalizers)
19
    {
20 2
        $this->normalizers = $normalizers;
21 2
    }
22
23 74
    public function normalize($specification, $context)
24
    {
25 74
        if (!$normalizer = $this->getNormalizer($specification, $context)) {
26
            throw new \RuntimeException(\sprintf('Specification "%s" with context "%s" does not have a supported visitor registered.', get_debug_type($specification), get_debug_type($context)));
27
        }
28
29 74
        return $normalizer->normalize($specification, $context);
30
    }
31
32
    public function supports($specification, $context): bool
33
    {
34
        return null !== $this->getNormalizer($specification, $context);
35
    }
36
37
    public function isCacheable(): bool
38
    {
39
        return true;
40
    }
41
42 74
    private function getNormalizer($specification, $context): ?Normalizer
43
    {
44 74
        $specificationCacheKey = \is_object($specification) ? \get_class($specification) : 'native-'.\gettype($specification);
45 74
        $contextCacheKey = \is_object($context) ? \get_class($context) : 'native-'.\gettype($context);
46
47 74
        if (isset($this->normalizerCache[$specificationCacheKey][$contextCacheKey])) {
48 48
            return $this->normalizerCache[$specificationCacheKey][$contextCacheKey];
49
        }
50
51 28
        foreach ($this->normalizers as $normalizer) {
52 28
            if (!$normalizer->supports($specification, $context)) {
53 28
                continue;
54
            }
55
56 28
            if ($normalizer instanceof NormalizerAware) {
57 4
                $normalizer->setNormalizer($this);
58
            }
59
60 28
            if ($normalizer->isCacheable()) {
61 28
                return $this->normalizerCache[$specificationCacheKey][$contextCacheKey] = $normalizer;
62
            }
63
64
            return $normalizer;
65
        }
66
67
        return null;
68
    }
69
}
70