Passed
Branch 2.0 (72e182)
by Philippe
02:18
created

ScopeCollection::guessKeyFromRoot()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 25
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 5
nop 1
dl 0
loc 25
ccs 8
cts 8
cp 1
crap 4
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
namespace Thinktomorrow\Locale;
4
5
use Thinktomorrow\Locale\Exceptions\InvalidScope;
6
use Thinktomorrow\Locale\Values\Config;
7
use Thinktomorrow\Locale\Values\Root;
8
9
final class ScopeCollection
10
{
11
    /**
12
     * @var Config
13
     */
14
    private $config;
15
16 86
    private function __construct(Config $config)
17
    {
18 86
        $this->config = $config;
19 86
    }
20
21 21
    public static function fromArray(array $config)
22
    {
23 21
        return new static(Config::from($config));
24
    }
25
26 70
    public static function fromConfig(Config $config)
27
    {
28 70
        return new static($config);
29
    }
30
31 84
    public function findByRoot(string $root): Scope
32
    {
33 84
        return $this->findByKey( $this->guessKeyFromRoot($root) );
34
    }
35
36
    /**
37
     * @param string $locale
38
     * @return null|Scope
39
     */
40 13
    public function findCanonical(string $locale): ?Scope
41
    {
42 13
        $canonicals = $this->config->get('canonicals');
43
44 13
        if(!isset($canonicals[$locale])) return null;
45
46 10
        $scope = $this->findByRoot($canonicals[$locale]);
47
48 10
        return $scope->setCustomRoot(Root::fromString($canonicals[$locale]));
49
    }
50
51 84
    private function guessKeyFromRoot(string $value): string
52
    {
53 84
        foreach($this->config->get('locales') as $scopeKey => $locales)
54
        {
55 84
            $pattern = preg_quote($scopeKey,'#');
56
57
            /**
58
             * The host pattern allows for an asterix which stands for a
59
             * wildcard of characters when matching the scope keys.
60
             * The default '*' scope will match anything
61
             */
62 84
            if(false !== strpos($pattern, '*'))
63
            {
64 34
                $pattern = str_replace('\*','(.+)',$pattern);
65
            }
66
67 84
            if( preg_match("#^(https?://)?(www\.)?$pattern/?$#", $value) )
68
            {
69 84
                return $scopeKey;
70
            }
71
        }
72
73
        // In case value remains empty, we return the default routing.
74 1
        return '*';
75
    }
76
77
    // We limit the available locales to the current domain space, including the default ones
78 84
    private function findByKey(string $scopeKey): Scope
79
    {
80 84
        if(!$scopeKey || !isset($this->config['locales'][$scopeKey]))
81
        {
82
            throw new InvalidScope('Scope key [' . $scopeKey . '] does not exist.');
83
        }
84
85 84
        $locales = $this->config->get('locales');
86
87 84
        $locales = array_merge($locales['*'], $locales[$scopeKey]);
88
89
        // We flip our values so in case of duplicate locales, the default one
90
        // is omitted and the one from the specific scope is preserved.
91 84
        return new Scope(array_flip(array_flip($locales)));
92
    }
93
}