Passed
Pull Request — master (#86)
by Aleksei
02:19
created

BaseProviderCollector::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Cycle\Schema\Provider\Support;
6
7
use Psr\Container\ContainerInterface;
8
use RuntimeException;
9
use SplDoublyLinkedList;
10
use SplFixedArray;
11
use Yiisoft\Yii\Cycle\Exception\CumulativeException;
12
use Yiisoft\Yii\Cycle\Schema\SchemaProviderInterface;
13
14
abstract class BaseProviderCollector implements SchemaProviderInterface
15
{
16
    protected const IS_SEQUENCE_PIPELINE = true;
17
18
    /** @var SplFixedArray<DeferredSchemaProviderDecorator>|null */
19
    protected ?SplFixedArray $providers = null;
20
    private ContainerInterface $container;
21
22 23
    public function __construct(ContainerInterface $container)
23
    {
24 23
        $this->container = $container;
25 23
    }
26
27
    /**
28
     * @return $this
29
     *
30
     * @psalm-immutable
31
     */
32 21
    public function withConfig(array $config): self
33
    {
34 21
        $new = clone $this;
35 21
        $new->providers = $this->createSequence($new->container, $config);
36 21
        return $new;
37
    }
38
39
    public function read(?SchemaProviderInterface $nextProvider = null): ?array
40
    {
41
        if ($this->providers === null) {
42
            throw new RuntimeException(self::class . ' is not configured.');
43
        }
44
        if ($this->providers->count() === 0) {
45
            return $nextProvider === null ? null : $nextProvider->read();
46
        }
47
        $this->providers->rewind();
48
        return $this->providers->current()->read($nextProvider);
49
    }
50
51 5
    public function clear(): bool
52
    {
53 5
        if ($this->providers === null) {
54 1
            throw new RuntimeException(self::class . ' is not configured.');
55
        }
56 4
        $exceptions = [];
57 4
        $result = true;
58 4
        foreach ($this->providers as $provider) {
59
            try {
60 3
                $result = $provider->clear() || $result;
0 ignored issues
show
introduced by
The condition $result is always true.
Loading history...
61 1
            } catch (\Throwable $e) {
62 1
                $exceptions[] = $e;
63
            }
64
        }
65 4
        if (count($exceptions)) {
66 1
            throw new CumulativeException(...$exceptions);
67
        }
68 3
        return $result;
69
    }
70
71 21
    protected function createSequence(ContainerInterface $container, array $providers): SplFixedArray
72
    {
73 21
        $size = count($providers);
74 21
        $stack = new SplFixedArray($size);
75 21
        $nextProvider = null;
76 21
        foreach (array_reverse($providers) as $key => $definition) {
77 17
            $config = [];
78 17
            if (is_array($definition)) {
79 5
                if (is_string($key)) {
80 2
                    $config = $definition;
81 2
                    $definition = $key;
82
                } else {
83 3
                    $config = $definition[1] ?? [];
84 3
                    $definition = $definition[0];
85
                }
86
            }
87 17
            $nextProvider = (new DeferredSchemaProviderDecorator(
88 17
                $container,
89
                $definition,
90 17
                static::IS_SEQUENCE_PIPELINE ? $nextProvider : null
91 17
            ))->withConfig($config);
92 17
            $stack[--$size] = $nextProvider;
93
        }
94 21
        return $stack;
95
    }
96
}
97