PropertyRangeLoader::create()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 6
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Remorhaz\UCD;
6
7
use Remorhaz\IntRangeSets\RangeSetInterface;
8
9
use function error_clear_last;
10
use function error_get_last;
11
use function is_string;
12
13
final class PropertyRangeLoader implements PropertyRangeLoaderInterface
14
{
15
16
    /**
17
     * @var string
18
     */
19
    private $path;
20
21
    /**
22
     * @var string[]
23
     * @psalm-var array<string, mixed>
24
     */
25
    private $index;
26
27
    /**
28
     * @var RangeSetInterface[]
29
     */
30
    private $cache = [];
31
32 248
    public static function create(): self
33
    {
34
        /** @psalm-var array<string, string> $index */
35 248
        $index = require __DIR__ . '/../config/ranges.php';
36
37 248
        return new self(__DIR__, $index);
38
    }
39
40
    /**
41
     * @param string                     $path
42
     * @param array                      $index
43
     * @psalm-param array<string, string> $index
44
     */
45 252
    public function __construct(string $path, array $index)
46
    {
47 252
        $this->path = $path;
48 252
        $this->index = $index;
49 252
    }
50
51 252
    public function getRangeSet(string $propertyName): RangeSetInterface
52
    {
53 252
        if (!isset($this->cache[$propertyName])) {
54 252
            $this->cache[$propertyName] = $this->loadRangeSet($propertyName);
55
        }
56
57 248
        return $this->cache[$propertyName];
58
    }
59
60 252
    private function loadRangeSet(string $propertyName): RangeSetInterface
61
    {
62 252
        if (!isset($this->index[$propertyName])) {
63 1
            throw new Exception\PropertyRangeSetNotFoundException($propertyName);
64
        }
65
66
        /** @var mixed $file */
67 251
        $file = $this->index[$propertyName];
68 251
        if (!is_string($file)) {
69 1
            throw new Exception\InvalidPropertyConfigException($propertyName, $file);
70
        }
71 250
        $fileName = $this->path . $file;
72 250
        error_clear_last();
73
        /**
74
         * @noinspection   PhpIncludeInspection
75
         * @psalm-suppress UnresolvableInclude
76
         * @var RangeSetInterface|false $rangeSet
77
         */
78 250
        $rangeSet = @include $fileName;
79 250
        if (false === $rangeSet) {
80 1
            $lastError = error_get_last();
81 1
            if (isset($lastError)) {
82 1
                throw new Exception\PropertyFileNotLoadedException(
83 1
                    $propertyName,
84
                    $fileName,
85 1
                    $lastError['message'] ?? null
86
                );
87
            }
88
        }
89 249
        if ($rangeSet instanceof RangeSetInterface) {
90 248
            return $rangeSet;
91
        }
92
93 1
        throw new Exception\InvalidPropertyRangeSetException($propertyName, $fileName, $rangeSet);
94
    }
95
}
96