Passed
Push — master ( d5dda9...c69dbe )
by Alexander
02:26
created

SchemaProviderPipeline   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 65
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 16
eloc 36
c 1
b 0
f 0
dl 0
loc 65
ccs 38
cts 38
cp 1
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A createPipeline() 0 15 4
A __construct() 0 3 1
A withConfig() 0 5 1
A clear() 0 18 6
A read() 0 10 4
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 Yiisoft\Yii\Cycle\Exception\CumulativeException;
11
use Yiisoft\Yii\Cycle\Schema\SchemaProviderInterface;
12
13
/**
14
 * A class for working with a group of schema providers.
15
 * When the schema is read, it queues the specified schema providers using the {@see DeferredSchemaProviderDecorator}.
16
 */
17
final class SchemaProviderPipeline implements SchemaProviderInterface
18
{
19
    /** @var null|SplDoublyLinkedList<int, DeferredSchemaProviderDecorator> */
20
    private ?SplDoublyLinkedList $providers = null;
21
    private ContainerInterface $container;
22
23 19
    public function __construct(ContainerInterface $container)
24
    {
25 19
        $this->container = $container;
26 19
    }
27
28 17
    public function withConfig(array $config): self
29
    {
30 17
        $new = clone $this;
31 17
        $new->providers = $this->createPipeline($new->container, $config);
32 17
        return $new;
33
    }
34
35 14
    public function read(?SchemaProviderInterface $nextProvider = null): ?array
36
    {
37 14
        if ($this->providers === null) {
38 1
            throw new RuntimeException(self::class . ' is not configured.');
39
        }
40 13
        if ($this->providers->count() === 0) {
41 3
            return $nextProvider === null ? null : $nextProvider->read();
42
        }
43 11
        $this->providers->rewind();
44 11
        return $this->providers->current()->read($nextProvider);
45
    }
46
47 5
    public function clear(): bool
48
    {
49 5
        if ($this->providers === null) {
50 1
            throw new RuntimeException(self::class . ' is not configured.');
51
        }
52 4
        $exceptions = [];
53 4
        $result = true;
54 4
        foreach ($this->providers as $provider) {
55
            try {
56 3
                $result = $provider->clear() || $result;
0 ignored issues
show
introduced by
The condition $result is always true.
Loading history...
57 1
            } catch (\Throwable $e) {
58 1
                $exceptions[] = $e;
59
            }
60
        }
61 4
        if (count($exceptions)) {
62 1
            throw new CumulativeException(...$exceptions);
63
        }
64 3
        return $result;
65
    }
66
67 17
    private function createPipeline(ContainerInterface $container, array $providers): SplDoublyLinkedList
68
    {
69 17
        $stack = new SplDoublyLinkedList();
70 17
        $nextProvider = null;
71 17
        foreach (array_reverse($providers) as $key => $definition) {
72 14
            $config = [];
73 14
            if (is_string($key) && is_array($definition)) {
74 2
                $config = $definition;
75 2
                $definition = $key;
76
            }
77 14
            $nextProvider = (new DeferredSchemaProviderDecorator($container, $definition, $nextProvider))
78 14
                ->withConfig($config);
79 14
            $stack->unshift($nextProvider);
80
        }
81 17
        return $stack;
82
    }
83
}
84