Passed
Push — master ( 02213d...e7d330 )
by butschster
21:00 queued 13s
created

TokenizerBootloader::ensureScopeExists()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.576

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 13
ccs 6
cts 10
cp 0.6
rs 10
c 0
b 0
f 0
cc 3
nc 4
nop 2
crap 3.576
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Tokenizer\Bootloader;
6
7
use Spiral\Boot\Bootloader\Bootloader;
8
use Spiral\Boot\DirectoriesInterface;
9
use Spiral\Boot\EnvironmentInterface;
10
use Spiral\Config\ConfiguratorInterface;
11
use Spiral\Config\Patch\Append;
12
use Spiral\Config\Patch\Set;
13
use Spiral\Core\Attribute\Singleton;
14
use Spiral\Core\BinderInterface;
15
use Spiral\Tokenizer\ClassesInterface;
16
use Spiral\Tokenizer\ClassLocator;
17
use Spiral\Tokenizer\ClassLocatorInjector;
18
use Spiral\Tokenizer\Config\TokenizerConfig;
19
use Spiral\Tokenizer\EnumLocator;
20
use Spiral\Tokenizer\EnumLocatorInjector;
21
use Spiral\Tokenizer\EnumsInterface;
22
use Spiral\Tokenizer\InterfaceLocator;
23
use Spiral\Tokenizer\InterfaceLocatorInjector;
24
use Spiral\Tokenizer\InterfacesInterface;
25
use Spiral\Tokenizer\InvocationLocator;
26
use Spiral\Tokenizer\InvocationLocatorInjector;
27
use Spiral\Tokenizer\InvocationsInterface;
28
use Spiral\Tokenizer\ScopedClassesInterface;
29
use Spiral\Tokenizer\ScopedClassLocator;
30
use Spiral\Tokenizer\ScopedEnumLocator;
31
use Spiral\Tokenizer\ScopedEnumsInterface;
32
use Spiral\Tokenizer\ScopedInterfaceLocator;
33
use Spiral\Tokenizer\ScopedInterfacesInterface;
34
35
#[Singleton]
36
final class TokenizerBootloader extends Bootloader
37
{
38
    protected const BINDINGS = [
39
        ScopedClassesInterface::class => ScopedClassLocator::class,
40
        ScopedEnumsInterface::class => ScopedEnumLocator::class,
41
        ScopedInterfacesInterface::class => ScopedInterfaceLocator::class,
42
        ClassesInterface::class => ClassLocator::class,
43
        EnumsInterface::class => EnumLocator::class,
44
        InterfacesInterface::class => InterfaceLocator::class,
45
        InvocationsInterface::class => InvocationLocator::class,
46
    ];
47
48 442
    public function __construct(
49
        private readonly ConfiguratorInterface $config,
50
    ) {
51 442
    }
52
53 442
    public function init(BinderInterface $binder, DirectoriesInterface $dirs, EnvironmentInterface $env): void
54
    {
55 442
        $binder->bindInjector(ClassLocator::class, ClassLocatorInjector::class);
56 442
        $binder->bindInjector(EnumLocator::class, EnumLocatorInjector::class);
57 442
        $binder->bindInjector(InterfaceLocator::class, InterfaceLocatorInjector::class);
58 442
        $binder->bindInjector(InvocationLocator::class, InvocationLocatorInjector::class);
59
60 442
        $this->config->setDefaults(
61 442
            TokenizerConfig::CONFIG,
62 442
            [
63 442
                'debug' => false,
64 442
                'directories' => [$dirs->get('app')],
65 442
                'exclude' => [
66 442
                    $dirs->get('resources'),
67 442
                    $dirs->get('config'),
68 442
                    'tests',
69 442
                    'migrations',
70 442
                ],
71 442
                'cache' => [
72 442
                    'directory' => $dirs->get('runtime') . 'cache/listeners',
73 442
                    'enabled' => \filter_var($env->get('TOKENIZER_CACHE_TARGETS', false), \FILTER_VALIDATE_BOOL),
74 442
                ],
75 442
                'load' => [
76 442
                    'classes' => \filter_var($env->get('TOKENIZER_LOAD_CLASSES', true), \FILTER_VALIDATE_BOOL),
77 442
                    'enums' => \filter_var($env->get('TOKENIZER_LOAD_ENUMS', false), \FILTER_VALIDATE_BOOL),
78 442
                    'interfaces' => \filter_var($env->get('TOKENIZER_LOAD_INTERFACES', false), \FILTER_VALIDATE_BOOL),
79 442
                ],
80 442
            ],
81 442
        );
82
    }
83
84
    /**
85
     * Add directory for indexation.
86
     */
87 324
    public function addDirectory(string $directory): void
88
    {
89 324
        $this->config->modify(
90 324
            TokenizerConfig::CONFIG,
91 324
            new Append('directories', null, $directory),
92 324
        );
93
    }
94
95
    /**
96
     * Add directory for indexation into specific scope.
97
     * @param non-empty-string $scope
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
98
     * @param non-empty-string $directory
99
     */
100 2
    public function addScopedDirectory(string $scope, string $directory): void
101
    {
102 2
        $this->ensureScopeExists($scope, 'directories');
103
104 2
        $this->config->modify(
105 2
            TokenizerConfig::CONFIG,
106 2
            new Append('scopes.' . $scope . '.directories', null, $directory),
107 2
        );
108
    }
109
110
    /**
111
     * Exclude directory from indexation in specific scope.
112
     * @param non-empty-string $scope
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
113
     * @param non-empty-string $directory
114
     */
115 2
    public function excludeScopedDirectory(string $scope, string $directory): void
116
    {
117 2
        $this->ensureScopeExists($scope, 'exclude');
118
119 2
        $this->config->modify(
120 2
            TokenizerConfig::CONFIG,
121 2
            new Append('scopes.' . $scope . '.exclude', null, $directory),
122 2
        );
123
    }
124
125 4
    private function ensureScopeExists(string $scope, string $section): void
126
    {
127 4
        if (!isset($this->config->getConfig(TokenizerConfig::CONFIG)['scopes'])) {
128
            $this->config->modify(
129
                TokenizerConfig::CONFIG,
130
                new Set('scopes', []),
131
            );
132
        }
133
134 4
        if (!isset($this->config->getConfig(TokenizerConfig::CONFIG)['scopes'][$scope])) {
135 2
            $this->config->modify(
136 2
                TokenizerConfig::CONFIG,
137 2
                new Append('scopes', $scope, [$section => []]),
138 2
            );
139
        }
140
    }
141
}
142