Passed
Push — master ( af06a0...9b6403 )
by Jesse
03:39
created

HasMany::oneProxyInThe()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stratadox\Hydration\Mapper\Instruction\Relation;
6
7
use function class_implements;
8
use function in_array;
9
use Stratadox\Collection\Alterable;
10
use Stratadox\Hydration\Hydrates;
11
use Stratadox\Hydration\Hydrator\ArrayHydrator;
12
use Stratadox\Hydration\Hydrator\SimpleHydrator;
13
use Stratadox\Hydration\Hydrator\VariadicConstructor;
14
use Stratadox\Hydration\Mapper\NoContainerAvailable;
15
use Stratadox\Hydration\Mapper\NoLoaderAvailable;
16
use Stratadox\Hydration\Mapping\Property\Relationship\HasManyNested;
17
use Stratadox\Hydration\Mapping\Property\Relationship\HasManyProxies;
18
use Stratadox\Hydration\Mapping\Property\Relationship\HasOneProxy;
19
use Stratadox\Hydration\MapsProperty;
20
use Stratadox\Hydration\ProducesOwnerUpdaters;
21
use Stratadox\Hydration\Proxy;
22
use Stratadox\Hydration\Proxying\AlterableCollectionEntryUpdaterFactory;
23
use Stratadox\Hydration\Proxying\ArrayEntryUpdaterFactory;
24
use Stratadox\Hydration\Proxying\PropertyUpdaterFactory;
25
use Stratadox\Hydration\Proxying\ProxyFactory;
26
27
final class HasMany extends Relationship
28
{
29
    public function followFor(string $property) : MapsProperty
30
    {
31
        if ($this->shouldNest) {
32
            return $this->manyNestedInThe($property);
33
        }
34
        if (!isset($this->loader)) {
35
            throw NoLoaderAvailable::for($this->class);
36
        }
37
        if ($this->implements(Proxy::class, $this->class)) {
38
            return $this->manyProxiesInThe($property);
39
        }
40
        if (!isset($this->container)) {
41
            throw NoContainerAvailable::for($this->class);
42
        }
43
        return $this->oneProxyInThe($property);
44
    }
45
46
    private function manyNestedInThe(string $property) : MapsProperty
47
    {
48
        return HasManyNested::inPropertyWithDifferentKey($property,
49
            $this->keyOr($property),
50
            $this->container(),
51
            $this->hydrator()
52
        );
53
    }
54
55
    private function manyProxiesInThe(string $property) : MapsProperty
56
    {
57
        return HasManyProxies::inPropertyWithDifferentKey($property,
58
            $this->keyOr($property),
59
            $this->container(),
60
            ProxyFactory::fromThis(
61
                SimpleHydrator::forThe($this->class),
62
                $this->loader,
0 ignored issues
show
Bug introduced by
It seems like $this->loader can also be of type null; however, parameter $loaderFactory of Stratadox\Hydration\Prox...roxyFactory::fromThis() does only seem to accept Stratadox\Hydration\ProducesProxyLoaders, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

62
                /** @scrutinizer ignore-type */ $this->loader,
Loading history...
63
                $this->updaterFactory()
64
            )
65
        );
66
    }
67
68
    private function oneProxyInThe(string $property) : MapsProperty
69
    {
70
        return HasOneProxy::inProperty($property,
71
            ProxyFactory::fromThis(
72
                SimpleHydrator::forThe($this->container),
0 ignored issues
show
Bug introduced by
It seems like $this->container can also be of type null; however, parameter $class of Stratadox\Hydration\Hydr...impleHydrator::forThe() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

72
                SimpleHydrator::forThe(/** @scrutinizer ignore-type */ $this->container),
Loading history...
73
                $this->loader,
0 ignored issues
show
Bug introduced by
It seems like $this->loader can also be of type null; however, parameter $loaderFactory of Stratadox\Hydration\Prox...roxyFactory::fromThis() does only seem to accept Stratadox\Hydration\ProducesProxyLoaders, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

73
                /** @scrutinizer ignore-type */ $this->loader,
Loading history...
74
                new PropertyUpdaterFactory
75
            )
76
        );
77
    }
78
79
    private function container() : Hydrates
80
    {
81
        if (isset($this->container)) {
82
            return VariadicConstructor::forThe($this->container);
83
        }
84
        return ArrayHydrator::create();
85
    }
86
87
    private function updaterFactory() : ProducesOwnerUpdaters
88
    {
89
        if ($this->implements(Alterable::class, $this->container)) {
90
            return new AlterableCollectionEntryUpdaterFactory;
91
        }
92
        return new ArrayEntryUpdaterFactory;
93
    }
94
95
    private function implements(string $interface, $class)
96
    {
97
        return isset($class) && in_array($interface, class_implements($class));
98
    }
99
}
100