Completed
Push — develop ( bec80e...e58249 )
by
unknown
09:35
created

TreeSelectStrategy::setTreeRoot()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @license MIT
7
 * @copyright  2013 - 2016 Cross Solution <http://cross-solution.de>
8
 */
9
  
10
/** */
11
namespace Core\Form\Hydrator\Strategy;
12
13
use Core\Entity\Tree\AbstractLeafs;
14
use Core\Entity\Tree\NodeInterface;
15
use Doctrine\Common\Collections\ArrayCollection;
16
use Doctrine\Common\Collections\Collection;
17
use Zend\Hydrator\Strategy\StrategyInterface;
18
19
/**
20
 * Hydrator strategy for TreeSelect form element.
21
 * 
22
 * @author Mathias Gelhausen <[email protected]>
23
 * @since 0.29
24
 */
25
class TreeSelectStrategy implements StrategyInterface
26
{
27
28
    /**
29
     * The selected leafs.
30
     *
31
     * @var AbstractLeafs
32
     */
33
    private $attachedLeafs;
34
35
    /**
36
     * The root node.
37
     *
38
     * @var NodeInterface
39
     */
40
    private $treeRoot;
41
42
    /**
43
     * Flag wether multiple selections are allowed.
44
     *
45
     * @var bool|callable
46
     */
47
    private $allowSelectMultipleItems = false;
48
49
    /**
50
     * Set the selected leafs.
51
     *
52
     * @param AbstractLeafs $attachedLeafs
53
     *
54
     * @return self
55
     */
56
    public function setAttachedLeafs(AbstractLeafs $attachedLeafs)
57
    {
58
        $this->attachedLeafs = $attachedLeafs;
59
60
        return $this;
61
    }
62
63
    /**
64
     * Get the selected leafs.
65
     *
66
     * @return AbstractLeafs
67
     */
68
    public function getAttachedLeafs()
69
    {
70
        return $this->attachedLeafs;
71
    }
72
73
    /**
74
     * Set the root node.
75
     *
76
     * @param NodeInterface $treeRoot
77
     *
78
     * @return self
79
     */
80
    public function setTreeRoot(NodeInterface $treeRoot)
81
    {
82
        $this->treeRoot = $treeRoot;
83
84
        return $this;
85
    }
86
87
    /**
88
     * Get the root node.
89
     *
90
     * @return NodeInterface
91
     */
92
    public function getTreeRoot()
93
    {
94
        return $this->treeRoot;
95
    }
96
97
    /**
98
     * Set the allow multiple selections flag.
99
     *
100
     * @param Callable|bool $flagOrCallback When a Callable is passed, it must return bool.
101
     *
102
     * @return self
103
     */
104
    public function setAllowSelectMultipleItems($flagOrCallback)
105
    {
106
        $this->allowSelectMultipleItems = $flagOrCallback;
107
108
        return $this;
109
    }
110
111
    /**
112
     * Are multiple selections allowed?
113
     *
114
     * @return bool
115
     */
116
    public function allowSelectMultipleItems()
0 ignored issues
show
Coding Style introduced by
function allowSelectMultipleItems() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
117
    {
118
        $flagOrCallback = $this->allowSelectMultipleItems;
119
120
        return is_callable($flagOrCallback) ? (bool) $flagOrCallback() : (bool) $flagOrCallback;
121
    }
122
123
    public function extract($value)
124
    {
125
        if (!$value instanceOf AbstractLeafs) {
126
            throw new \InvalidArgumentException('$value must be an instance of ' . AbstractLeafs::class);
127
        }
128
        /* @var AbstractLeafs $value
129
         * @var NodeInterface $item */
130
131
        $this->setAttachedLeafs($value);
132
133
        if (!$this->allowSelectMultipleItems()) {
134
            $item = $value->getItems()->first();
135
            return $item ? $item->getValueWithParents() : null;
136
        }
137
138
        $data = [];
139
        foreach ($value->getItems() as $item) {
140
            $data[] = $item->getValueWithParents();
141
        }
142
143
        return $data;
144
    }
145
146
    public function hydrate($value)
147
    {
148
        $root = $this->getTreeRoot();
149
        $object = $this->getAttachedLeafs();
150
        $items = new ArrayCollection();
151
152
        if (!$this->allowSelectMultipleItems()) {
153
            $value = [$value];
154
        }
155
156
        foreach ($value as $itemValue) {
157
            $leaf = $this->findLeaf($root, $itemValue);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $leaf is correct as $this->findLeaf($root, $itemValue) (which targets Core\Form\Hydrator\Strat...ectStrategy::findLeaf()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
158
159
            if ($leaf) {
160
                $items->add($leaf);
161
            }
162
        }
163
164
        $object->setItems($items);
165
166
        return $object;
167
    }
168
169
    /**
170
     * Find a leaf with a concrete value in the tree.
171
     *
172
     * @param NodeInterface $leaf
173
     * @param string        $value
174
     *
175
     * @return NodeInterface|null
176
     */
177
    private function findLeaf(NodeInterface $leaf, $value)
178
    {
179
        $parts = is_array($value) ? $value : explode('-', $value);
180
        $value = array_shift($parts);
181
182
        /* @var NodeInterface $item */
183
        foreach ($leaf->getChildren() as $item) {
184
            if ($item->getValue() == $value) {
185
                if (count($parts)) {
186
                    return $this->findLeaf($item, $parts);
0 ignored issues
show
Documentation introduced by
$parts is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
187
                }
188
189
                return $item;
190
            }
191
        }
192
193
        return null;
194
    }
195
}