Completed
Push — master ( 3227e8...9ee0a2 )
by Karsten
03:50
created

AbstractCollectionMapper::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
crap 1
1
<?php
2
/**
3
 * File was created 11.05.2016 10:14
4
 */
5
6
namespace PeekAndPoke\Component\Slumber\Core\Codec\Property;
7
8
use PeekAndPoke\Component\Psi\Functions\Unary\Matcher\IsInstanceOf;
9
use PeekAndPoke\Component\Slumber\Annotation\Slumber\AsCollection;
10
use PeekAndPoke\Component\Slumber\Core\Codec\Mapper;
11
12
13
/**
14
 * @author Karsten J. Gerber <[email protected]>
15
 */
16
abstract class AbstractCollectionMapper extends AbstractPropertyMapper implements CollectionMapper
17
{
18
    /** @var Mapper */
19
    protected $nested;
20
    /** @var AsCollection */
21
    protected $options;
22
23
    /**
24
     * AbstractCollectionMapper constructor.
25
     *
26
     * @param AsCollection $options
27
     * @param Mapper       $nested
28
     */
29 48
    public function __construct(AsCollection $options, Mapper $nested)
30
    {
31 48
        $this->options = $options;
32 48
        $this->nested  = $nested;
33 48
    }
34
35
    /**
36
     * @param mixed $result
37
     *
38
     * @return mixed
39
     */
40 36
    protected function createAwakeResult($result)
41
    {
42
        // do we need to instantiate a collection class ?
43 36
        $collectionCls = $this->options->collection;
44
45 36
        if (null === $collectionCls) {
46 36
            return $result;
47
        }
48
49 17
        return new $collectionCls($result);
50
    }
51
52
    /**
53
     * @return AsCollection
54
     */
55 19
    public function getOptions()
56
    {
57 19
        return $this->options;
58
    }
59
60
    /**
61
     * @return Mapper
62
     */
63
    public function getNested()
64
    {
65
        return $this->nested;
66
    }
67
68
    /**
69
     * @param Mapper $nested
70
     *
71
     * @return $this
72
     */
73
    public function setNested(Mapper $nested)
74
    {
75
        $this->nested = $nested;
76
77
        return $this;
78
    }
79
80
    /**
81
     * @param string $class
82
     *
83
     * @return bool
84
     */
85
    public function isLeaveOfType($class)
86
    {
87
        $leave = $this->getLeaf();
88
89
        return (new IsInstanceOf($class))->__invoke($leave);
90
    }
91
92
    /**
93
     * @return Mapper
94
     */
95
    public function getLeaf()
96
    {
97
        $current = $this;
98
99
        while ($current instanceof CollectionMapper) {
100
            $current = $current->getNested();
101
        }
102
103
        return $current;
104
    }
105
106
    /**
107
     * @param Mapper $leave
108
     */
109
    public function setLeaf(Mapper $leave)
110
    {
111
        $current = $this;
112
113
        while ($current->getNested() instanceof CollectionMapper) {
114
            $current = $current->getNested();
115
        }
116
117
        $current->setNested($leave);
118
    }
119
120
    /**
121
     * @return null|CollectionMapper
122
     */
123
    public function getLeafParent()
124
    {
125
        $parent  = null;
126
        $current = $this;
127
128
        while ($current instanceof CollectionMapper) {
129
            $parent  = $current;
130
            $current = $current->getNested();
131
        }
132
133
        return $parent;
134
135
    }
136
137
    /**
138
     * @param string $collectionClass
139
     *
140
     * @return $this
141
     */
142
    public function setLeafParentsCollectionType($collectionClass)
143
    {
144
        $parent = $this->getLeafParent();
145
146
        if ($parent !== null) {
147
            $parent->getOptions()->setCollection($collectionClass);
148
        }
149
150
        return $this;
151
    }
152
153
    /**
154
     * Get the nesting level.
155
     *
156
     * If there is no nested element the level is 0.
157
     * If there is a nested element the level is 1.
158
     * If there is a nested element with a nested element as well the level 2.
159
     *
160
     * ... and so forth
161
     *
162
     * @return mixed
163
     */
164
    public function getNestingLevel()
165
    {
166
        // no child ... level 0
167
        if ($this->getNested() === null) {
168
            return 0;
169
        }
170
171
        $nested = $this->getNested();
172
173
        // another collection ... increase the level by 1
174
        if ($nested instanceof CollectionMapper) {
175
            return 1 + $nested->getNestingLevel();
176
        }
177
178
        // not another collection ... level is 1
179
        return 1;
180
    }
181
}
182