Passed
Push — master ( 8d5c50...f86379 )
by Alexander
01:44
created

SchemaManager::getProviders()   A

Complexity

Conditions 6
Paths 9

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 8
c 1
b 0
f 0
dl 0
loc 16
ccs 9
cts 9
cp 1
rs 9.2222
cc 6
nc 9
nop 0
crap 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Cycle\Schema;
6
7
use Generator;
8
use Psr\Container\ContainerInterface;
9
use Yiisoft\Yii\Cycle\Exception\BadDeclarationException;
10
use Yiisoft\Yii\Cycle\Exception\CumulativeException;
11
12
/**
13
 * SchemaManager allows reading schema from providers available and clearing the schema in providers.
14
 */
15
final class SchemaManager
16
{
17
    private ContainerInterface $container;
18
    /** @var string[]|SchemaProviderInterface[] */
19
    private array $providers;
20
21 18
    public function __construct(ContainerInterface $container, array $providers)
22
    {
23 18
        $this->container = $container;
24 18
        $this->providers = $providers;
25 18
    }
26
27 13
    public function read(): ?array
28
    {
29 13
        $toWrite = new \SplStack();
30 13
        $schema = null;
31
32 13
        foreach ($this->getProviders() as $provider) {
33 11
            if ($provider->isReadable()) {
34 11
                $schema = $provider->read();
35 11
                if ($schema !== null) {
36 10
                    break;
37
                }
38
            }
39 5
            if ($provider->isWritable()) {
40 4
                $toWrite->push($provider);
41
            }
42
        }
43
44 12
        if ($schema === null) {
45 2
            return null;
46
        }
47
48
        // Save schema
49
        /** @var SchemaProviderInterface $provider */
50 10
        foreach ($toWrite as $provider) {
51 3
            $provider->write($schema);
52
        }
53
54 10
        return $schema;
55
    }
56
57 5
    public function clear(): void
58
    {
59 5
        $providers = iterator_to_array($this->getProviders());
60 5
        array_pop($providers);
61
62 5
        $exceptions = [];
63 5
        foreach ($providers as $provider) {
64 3
            if ($provider->isWritable()) {
65
                try {
66 3
                    $provider->clear();
67 1
                } catch (\Throwable $e) {
68 1
                    $exceptions[] = $e;
69
                }
70
            }
71
        }
72 5
        if (count($exceptions)) {
73 1
            throw new CumulativeException(...$exceptions);
74
        }
75 4
    }
76
77
    /**
78
     * @return Generator|SchemaProviderInterface[]
79
     * @throws BadDeclarationException
80
     */
81 18
    private function getProviders(): Generator
82
    {
83 18
        foreach ($this->providers as $key => &$provider) {
84
            // Providers resolving
85 16
            if (is_string($provider)) {
86 3
                $provider = $this->container->get($provider);
87
            }
88
            // If Provider defined as ClassName => ConfigArray
89 16
            if (is_array($provider) && is_string($key)) {
90 1
                $provider = $this->container->get($key)->withConfig($provider);
91
            }
92
93 16
            if (!$provider instanceof SchemaProviderInterface) {
94 1
                throw new BadDeclarationException('Provider', SchemaProviderInterface::class, $provider);
95
            }
96 15
            yield $provider;
97
        }
98 7
    }
99
}
100