7ddd068e56264f73e8a2e492c5c7e9b71daf8876
[yaffs-website] / vendor / doctrine / collections / lib / Doctrine / Common / Collections / ArrayCollection.php
1 <?php
2 /*
3  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14  *
15  * This software consists of voluntary contributions made by many individuals
16  * and is licensed under the MIT license. For more information, see
17  * <http://www.doctrine-project.org>.
18  */
19
20 namespace Doctrine\Common\Collections;
21
22 use ArrayIterator;
23 use Closure;
24 use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor;
25
26 /**
27  * An ArrayCollection is a Collection implementation that wraps a regular PHP array.
28  *
29  * Warning: Using (un-)serialize() on a collection is not a supported use-case
30  * and may break when we change the internals in the future. If you need to
31  * serialize a collection use {@link toArray()} and reconstruct the collection
32  * manually.
33  *
34  * @since  2.0
35  * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
36  * @author Jonathan Wage <jonwage@gmail.com>
37  * @author Roman Borschel <roman@code-factory.org>
38  */
39 class ArrayCollection implements Collection, Selectable
40 {
41     /**
42      * An array containing the entries of this collection.
43      *
44      * @var array
45      */
46     private $elements;
47
48     /**
49      * Initializes a new ArrayCollection.
50      *
51      * @param array $elements
52      */
53     public function __construct(array $elements = array())
54     {
55         $this->elements = $elements;
56     }
57
58     /**
59      * Creates a new instance from the specified elements.
60      *
61      * This method is provided for derived classes to specify how a new
62      * instance should be created when constructor semantics have changed.
63      *
64      * @param array $elements Elements.
65      *
66      * @return static
67      */
68     protected function createFrom(array $elements)
69     {
70         return new static($elements);
71     }
72
73     /**
74      * {@inheritDoc}
75      */
76     public function toArray()
77     {
78         return $this->elements;
79     }
80
81     /**
82      * {@inheritDoc}
83      */
84     public function first()
85     {
86         return reset($this->elements);
87     }
88
89     /**
90      * {@inheritDoc}
91      */
92     public function last()
93     {
94         return end($this->elements);
95     }
96
97     /**
98      * {@inheritDoc}
99      */
100     public function key()
101     {
102         return key($this->elements);
103     }
104
105     /**
106      * {@inheritDoc}
107      */
108     public function next()
109     {
110         return next($this->elements);
111     }
112
113     /**
114      * {@inheritDoc}
115      */
116     public function current()
117     {
118         return current($this->elements);
119     }
120
121     /**
122      * {@inheritDoc}
123      */
124     public function remove($key)
125     {
126         if ( ! isset($this->elements[$key]) && ! array_key_exists($key, $this->elements)) {
127             return null;
128         }
129
130         $removed = $this->elements[$key];
131         unset($this->elements[$key]);
132
133         return $removed;
134     }
135
136     /**
137      * {@inheritDoc}
138      */
139     public function removeElement($element)
140     {
141         $key = array_search($element, $this->elements, true);
142
143         if ($key === false) {
144             return false;
145         }
146
147         unset($this->elements[$key]);
148
149         return true;
150     }
151
152     /**
153      * Required by interface ArrayAccess.
154      *
155      * {@inheritDoc}
156      */
157     public function offsetExists($offset)
158     {
159         return $this->containsKey($offset);
160     }
161
162     /**
163      * Required by interface ArrayAccess.
164      *
165      * {@inheritDoc}
166      */
167     public function offsetGet($offset)
168     {
169         return $this->get($offset);
170     }
171
172     /**
173      * Required by interface ArrayAccess.
174      *
175      * {@inheritDoc}
176      */
177     public function offsetSet($offset, $value)
178     {
179         if ( ! isset($offset)) {
180             return $this->add($value);
181         }
182
183         $this->set($offset, $value);
184     }
185
186     /**
187      * Required by interface ArrayAccess.
188      *
189      * {@inheritDoc}
190      */
191     public function offsetUnset($offset)
192     {
193         return $this->remove($offset);
194     }
195
196     /**
197      * {@inheritDoc}
198      */
199     public function containsKey($key)
200     {
201         return isset($this->elements[$key]) || array_key_exists($key, $this->elements);
202     }
203
204     /**
205      * {@inheritDoc}
206      */
207     public function contains($element)
208     {
209         return in_array($element, $this->elements, true);
210     }
211
212     /**
213      * {@inheritDoc}
214      */
215     public function exists(Closure $p)
216     {
217         foreach ($this->elements as $key => $element) {
218             if ($p($key, $element)) {
219                 return true;
220             }
221         }
222
223         return false;
224     }
225
226     /**
227      * {@inheritDoc}
228      */
229     public function indexOf($element)
230     {
231         return array_search($element, $this->elements, true);
232     }
233
234     /**
235      * {@inheritDoc}
236      */
237     public function get($key)
238     {
239         return isset($this->elements[$key]) ? $this->elements[$key] : null;
240     }
241
242     /**
243      * {@inheritDoc}
244      */
245     public function getKeys()
246     {
247         return array_keys($this->elements);
248     }
249
250     /**
251      * {@inheritDoc}
252      */
253     public function getValues()
254     {
255         return array_values($this->elements);
256     }
257
258     /**
259      * {@inheritDoc}
260      */
261     public function count()
262     {
263         return count($this->elements);
264     }
265
266     /**
267      * {@inheritDoc}
268      */
269     public function set($key, $value)
270     {
271         $this->elements[$key] = $value;
272     }
273
274     /**
275      * {@inheritDoc}
276      */
277     public function add($element)
278     {
279         $this->elements[] = $element;
280
281         return true;
282     }
283
284     /**
285      * {@inheritDoc}
286      */
287     public function isEmpty()
288     {
289         return empty($this->elements);
290     }
291
292     /**
293      * Required by interface IteratorAggregate.
294      *
295      * {@inheritDoc}
296      */
297     public function getIterator()
298     {
299         return new ArrayIterator($this->elements);
300     }
301
302     /**
303      * {@inheritDoc}
304      */
305     public function map(Closure $func)
306     {
307         return $this->createFrom(array_map($func, $this->elements));
308     }
309
310     /**
311      * {@inheritDoc}
312      */
313     public function filter(Closure $p)
314     {
315         return $this->createFrom(array_filter($this->elements, $p));
316     }
317
318     /**
319      * {@inheritDoc}
320      */
321     public function forAll(Closure $p)
322     {
323         foreach ($this->elements as $key => $element) {
324             if ( ! $p($key, $element)) {
325                 return false;
326             }
327         }
328
329         return true;
330     }
331
332     /**
333      * {@inheritDoc}
334      */
335     public function partition(Closure $p)
336     {
337         $matches = $noMatches = array();
338
339         foreach ($this->elements as $key => $element) {
340             if ($p($key, $element)) {
341                 $matches[$key] = $element;
342             } else {
343                 $noMatches[$key] = $element;
344             }
345         }
346
347         return array($this->createFrom($matches), $this->createFrom($noMatches));
348     }
349
350     /**
351      * Returns a string representation of this object.
352      *
353      * @return string
354      */
355     public function __toString()
356     {
357         return __CLASS__ . '@' . spl_object_hash($this);
358     }
359
360     /**
361      * {@inheritDoc}
362      */
363     public function clear()
364     {
365         $this->elements = array();
366     }
367
368     /**
369      * {@inheritDoc}
370      */
371     public function slice($offset, $length = null)
372     {
373         return array_slice($this->elements, $offset, $length, true);
374     }
375
376     /**
377      * {@inheritDoc}
378      */
379     public function matching(Criteria $criteria)
380     {
381         $expr     = $criteria->getWhereExpression();
382         $filtered = $this->elements;
383
384         if ($expr) {
385             $visitor  = new ClosureExpressionVisitor();
386             $filter   = $visitor->dispatch($expr);
387             $filtered = array_filter($filtered, $filter);
388         }
389
390         if ($orderings = $criteria->getOrderings()) {
391             $next = null;
392             foreach (array_reverse($orderings) as $field => $ordering) {
393                 $next = ClosureExpressionVisitor::sortByField($field, $ordering == Criteria::DESC ? -1 : 1, $next);
394             }
395
396             uasort($filtered, $next);
397         }
398
399         $offset = $criteria->getFirstResult();
400         $length = $criteria->getMaxResults();
401
402         if ($offset || $length) {
403             $filtered = array_slice($filtered, (int)$offset, $length);
404         }
405
406         return $this->createFrom($filtered);
407     }
408 }