ApiVersionFeaturesProvider   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Test Coverage

Coverage 87.5%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 33
c 2
b 1
f 0
dl 0
loc 130
ccs 35
cts 40
cp 0.875
rs 10
wmc 16

8 Methods

Rating   Name   Duplication   Size   Complexity  
A isFeatureAvailable() 0 3 2
A getFeature() 0 3 1
A getAllKnownFeatures() 0 3 1
A getAvailableFeatures() 0 17 4
A __construct() 0 5 1
A addFeature() 0 9 1
A addFeatures() 0 14 3
A assertVersionCompatibleString() 0 7 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiechu\SymfonyCommonsBundle\Service;
6
7
use Spiechu\SymfonyCommonsBundle\ApiFeature\Definition;
8
9
class ApiVersionFeaturesProvider
10
{
11
    /**
12
     * @var ApiVersionProvider
13
     */
14
    protected $apiVersionProvider;
15
16
    /**
17
     * @var Definition[]
18
     */
19
    protected $features;
20
21
    /**
22
     * @param ApiVersionProvider $apiVersionProvider
23
     */
24 3
    public function __construct(ApiVersionProvider $apiVersionProvider)
25
    {
26 3
        $this->apiVersionProvider = $apiVersionProvider;
27
28 3
        $this->features = [];
29 3
    }
30
31
    /**
32
     * @param string      $name
33
     * @param null|string $since
34
     * @param null|string $until
35
     *
36
     * @throws \InvalidArgumentException When feature with given name already exists
37
     */
38 1
    public function addFeature(string $name, ?string $since, ?string $until): void
39
    {
40 1
        $this->assertVersionCompatibleString($since);
41 1
        $this->assertVersionCompatibleString($until);
42
43 1
        $this->addFeatures([
44
            $name => [
45 1
                'since' => $since,
46 1
                'until' => $until,
47
            ],
48
        ]);
49 1
    }
50
51
    /**
52
     * @param iterable $features [string featureName => array featureRange ['since' => numeric|nll, 'until' => numeric|null] ]
53
     *
54
     * @throws \InvalidArgumentException When feature with given name already exists
55
     */
56 3
    public function addFeatures(iterable $features): void
57
    {
58 3
        foreach ($features as $name => $options) {
59 3
            if (isset($this->features[$name])) {
60
                throw new \InvalidArgumentException(sprintf('Feature with given name "%s" already exists', $name));
61
            }
62
63 3
            $since = $options['since'] ?? null;
64 3
            $this->assertVersionCompatibleString($since);
65
66 3
            $until = $options['until'] ?? null;
67 3
            $this->assertVersionCompatibleString($until);
68
69 3
            $this->features[$name] = Definition::create($name, $since, $until);
70
        }
71 3
    }
72
73
    /**
74
     * @param string $name
75
     *
76
     * @return null|Definition
77
     */
78 1
    public function getFeature(string $name): ?Definition
79
    {
80 1
        return $this->getAllKnownFeatures()[$name] ?? null;
81
    }
82
83
    /**
84
     * @return Definition[]
85
     */
86 1
    public function getAllKnownFeatures(): array
87
    {
88 1
        return $this->features;
89
    }
90
91
    /**
92
     * @param Definition $definition
93
     *
94
     * @throws \RuntimeException When API version is not set
95
     *
96
     * @return bool
97
     */
98
    public function isFeatureAvailable(Definition $definition): bool
99
    {
100
        return isset($this->getAvailableFeatures()[$definition->getName()]) ? true : false;
101
    }
102
103
    /**
104
     * @throws \RuntimeException When API version is not set
105
     *
106
     * @return Definition[]
107
     */
108 3
    public function getAvailableFeatures(): array
109
    {
110 3
        $currentVersion = $this->apiVersionProvider->getApiVersion();
111
112 3
        if (null === $currentVersion) {
113
            throw new \RuntimeException('API version is not set');
114
        }
115
116 3
        $matchingFeatures = [];
117
118 3
        foreach ($this->features as $feature) {
119 3
            if ($feature->isAvailableForVersion($currentVersion)) {
120 3
                $matchingFeatures[$feature->getName()] = $feature;
121
            }
122
        }
123
124 3
        return $matchingFeatures;
125
    }
126
127
    /**
128
     * @param null|string $string
129
     *
130
     * @throws \InvalidArgumentException When $string is not version compatible
131
     */
132 3
    protected function assertVersionCompatibleString(?string $string): void
133
    {
134 3
        if (null === $string || is_numeric($string)) {
135 3
            return;
136
        }
137
138
        throw new \InvalidArgumentException(sprintf('"%s" is not version compatible string', $string));
139
    }
140
}
141