DeferredSchemaProviderDecorator   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 35
c 1
b 0
f 0
dl 0
loc 80
ccs 33
cts 33
cp 1
rs 10
wmc 14

6 Methods

Rating   Name   Duplication   Size   Complexity  
A read() 0 9 3
A __construct() 0 8 1
A clear() 0 3 1
A withLatestProvider() 0 7 1
A getProvider() 0 15 5
A withConfig() 0 6 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cycle\Schema\Provider\Support;
6
7
use Cycle\Schema\Provider\Exception\BadDeclarationException;
8
use Cycle\Schema\Provider\SchemaProviderInterface;
9
use Psr\Container\ContainerInterface;
10
11
/**
12
 * Auxiliary class for building scheme providers in a pipeline.
13
 */
14
final class DeferredSchemaProviderDecorator implements SchemaProviderInterface
15
{
16
    private SchemaProviderInterface|string $provider;
17
    private array $config = [];
18
    private ?self $nextProvider;
19
    private ?SchemaProviderInterface $latestProvider = null;
20
    private bool $resolved = false;
21
    private ContainerInterface $container;
22
23 36
    public function __construct(
24
        ContainerInterface $container,
25
        SchemaProviderInterface|string $provider,
26
        ?self $nextProvider
27
    ) {
28 36
        $this->provider = $provider;
29 36
        $this->container = $container;
30 36
        $this->nextProvider = $nextProvider;
31
    }
32
33
    /**
34
     * @throws BadDeclarationException
35
     */
36 33
    public function withConfig(array $config): self
37
    {
38 33
        $provider = !$this->resolved && count($this->config) === 0 ? $this->provider : $this->getProvider();
39 33
        $new = new self($this->container, $provider, $this->nextProvider);
40 33
        $new->config = $config;
41 33
        return $new;
42
    }
43
44
    /**
45
     * @throws BadDeclarationException
46
     */
47 28
    public function read(?SchemaProviderInterface $nextProvider = null): ?array
48
    {
49 28
        $nextProvider ??= $this->latestProvider;
50 28
        if ($nextProvider !== null && $this->nextProvider !== null) {
51 4
            $nextProvider = $this->nextProvider->withLatestProvider($nextProvider);
52
        } else {
53 28
            $nextProvider = $this->nextProvider ?? $nextProvider;
54
        }
55 28
        return $this->getProvider()->read($nextProvider);
56
    }
57
58 8
    public function clear(): bool
59
    {
60 8
        return $this->getProvider()->clear();
61
    }
62
63
    /**
64
     * @psalm-suppress InvalidReturnType,InvalidReturnStatement
65
     * @throws BadDeclarationException
66
     */
67 36
    private function getProvider(): SchemaProviderInterface
68
    {
69 36
        if ($this->resolved) {
70 5
            return $this->provider;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->provider could return the type string which is incompatible with the type-hinted return Cycle\Schema\Provider\SchemaProviderInterface. Consider adding an additional type-check to rule them out.
Loading history...
71
        }
72 36
        $provider = $this->provider;
73 36
        if (\is_string($provider)) {
74 17
            $provider = $this->container->get($provider);
75
        }
76 36
        if (!$provider instanceof SchemaProviderInterface) {
77 2
            throw new BadDeclarationException('Provider', SchemaProviderInterface::class, $provider);
78
        }
79 34
        $this->provider = \count($this->config) > 0 ? $provider->withConfig($this->config) : $provider;
80 34
        $this->resolved = true;
81 34
        return $this->provider;
82
    }
83
84
    /**
85
     * @throws BadDeclarationException
86
     */
87 4
    private function withLatestProvider(SchemaProviderInterface $provider): self
88
    {
89
        // resolve provider
90 4
        $this->getProvider();
91 4
        $new = clone $this;
92 4
        $new->latestProvider = $provider;
93 4
        return $new;
94
    }
95
}
96