Completed
Push — develop ( 9659b8...659b85 )
by Mathias
13:02
created

DependencyResultCollection::addResult()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @license MIT
7
 * @copyright  2013 - 2018 Cross Solution <http://cross-solution.de>
8
 */
9
  
10
/** */
11
namespace Core\Service\EntityEraser;
12
13
use Core\Entity\EntityInterface;
14
15
/**
16
 * DependencyResult collection
17
 * 
18
 * @author Mathias Gelhausen <[email protected]>
19
 * @todo write test 
20
 */
21
class DependencyResultCollection implements \IteratorAggregate
22
{
23
24
    /**
25
     * The DependencyResult objects.
26
     *
27
     * @var array
28
     */
29
    private $results = [];
30
31
    /**
32
     * Add a result in various formats.
33
     *
34
     * Possible are
35
     * - a DependencyResult object
36
     * - any \Traversable object (in that case, the name is set to the class name of the first item)
37
     * - an array of DependencyResult objects.
38
     * - an array in the format
39
     *   [ name, entities, options]
40
     * -an array in the format
41
     *  [
42
     *      'name' => name,
43
     *      'entities' => entities,
44
     *      'options' => [ ... ]
45
     *  ]
46
     * - an array of arrays in any of the two formats above or \Traversable objects. Can be mixed.
47
     *
48
     * @param DependencyResult|array|\Traversable|string           $name
49
     * @param null|array|\Traversable       $entities
50
     * @param array|null $options
51
     *
52
     * @return DependencyResultCollection
53
     */
54
    public function add($name, $entities = null, array $options = null)
55
    {
56
        if ($name instanceOf DependencyResult) {
57
            return $this->addResult($name);
58
        }
59
60
        if ($name instanceOf \Traversable) {
61
            return $this->addTraversable($name);
62
        }
63
64
        if (is_array($name)) {
65
            return $this->addArray($name);
66
        }
67
68
        if (null === $entities) {
69
            throw new \UnexpectedValueException('$entities must not be null.');
70
        }
71
72
        return $this->addArray([
73
            'name' => $name,
74
            'entities' => $entities,
75
            'options' => $options,
76
        ]);
77
    }
78
79
    /**
80
     * Add a DependencyResult object.
81
     *
82
     * @param DependencyResult $result
83
     *
84
     * @return self
85
     */
86
    private function addResult(DependencyResult $result)
87
    {
88
        $this->results[] = $result;
89
90
        return $this;
91
    }
92
93
    /**
94
     * Add a \Traversable object.
95
     *
96
     * Sets the name of the result to the class name of the first item in the object collection.
97
     * Therefor, the \Traversable object must not be empty.
98
     *
99
     * @param \Traversable $result
100
     *
101
     * @return DependencyResultCollection
102
     * @throws \InvalidArgumentException
103
     */
104
    private function addTraversable(\Traversable $result)
105
    {
106
        /*
107
         * Since we only know, that $result is an instance of \Traversable
108
         * (and thus, usable in a foreach), we cannot relay on methods like first()
109
         * which are defined in the \Iterable interface.
110
         * We must use a foreach to get the first item.
111
         *
112
         * Because PHP does not unset the loop variable, this works.
113
         */
114
        foreach ($result as $item) {
115
            break;
116
        }
117
118
        /* @var null|object|mixed $item */
119
        if (!$item instanceOf EntityInterface) {
0 ignored issues
show
Bug introduced by
The variable $item seems to be defined by a foreach iteration on line 114. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
120
            throw new \InvalidArgumentException('Traversable objects must be a non-empty collection of Entity instances.');
121
        }
122
123
        $name = get_class($item);
124
125
        return $this->addArray([
126
            'name' => $name,
127
            'entities' => $result,
128
        ]);
129
    }
130
131
    /**
132
     * Add an array.
133
     *
134
     * please see {@link add} for a list of possible values.
135
     *
136
     * @param array $result
137
     *
138
     * @return self
139
     */
140
    private function addArray(array $result)
141
    {
142
        if (1 < count($result) && !isset($result['name']) && !is_string($result[0])) {
143
            foreach ($result as $r) {
144
                if (is_array($r)) {
145
                    $this->add($r);
146
                } else {
147
                    return $this->addTraversable(new \ArrayIterator($result));
148
                }
149
            }
150
            return $this;
151
        }
152
153
        if (is_string($result[0])) {
154
            $result = [
155
                'name' => $result[0],
156
                'entities' => isset($result[1]) ? $result[1] : null,
157
                'options' => [
158
                    'description' => isset($result[2]) ? $result[2] : null,
159
                    'viewScript' => isset($result[3]) ? $result[3] : null,
160
                ],
161
            ];
162
        }
163
164
        if (!isset($result['name']) || !isset($result['entities'])) {
165
            throw new \UnexpectedValueException('Array must have the keys "name" and "entities".');
166
        }
167
168
        if (!count($result['entities'])) {
169
            throw new \UnexpectedValueException('Entities must be non-empty.');
170
        }
171
172
        $result = new DependencyResult($result['name'], $result['entities'], isset($result['options']) ? $result['options'] : null);
173
174
        return $this->addResult($result);
175
    }
176
177
    public function getIterator()
178
    {
179
        return new \ArrayIterator($this->results);
180
    }
181
}
182