bce575120ea794a29004b51749252c8a63e6cc8c
[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  * @since  2.0
30  * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
31  * @author Jonathan Wage <jonwage@gmail.com>
32  * @author Roman Borschel <roman@code-factory.org>
33  */
34 class ArrayCollection implements Collection, Selectable
35 {
36     /**
37      * An array containing the entries of this collection.
38      *
39      * @var array
40      */
41     private $elements;
42
43     /**
44      * Initializes a new ArrayCollection.
45      *
46      * @param array $elements
47      */
48     public function __construct(array $elements = array())
49     {
50         $this->elements = $elements;
51     }
52
53     /**
54      * {@inheritDoc}
55      */
56     public function toArray()
57     {
58         return $this->elements;
59     }
60
61     /**
62      * {@inheritDoc}
63      */
64     public function first()
65     {
66         return reset($this->elements);
67     }
68
69     /**
70      * {@inheritDoc}
71      */
72     public function last()
73     {
74         return end($this->elements);
75     }
76
77     /**
78      * {@inheritDoc}
79      */
80     public function key()
81     {
82         return key($this->elements);
83     }
84
85     /**
86      * {@inheritDoc}
87      */
88     public function next()
89     {
90         return next($this->elements);
91     }
92
93     /**
94      * {@inheritDoc}
95      */
96     public function current()
97     {
98         return current($this->elements);
99     }
100
101     /**
102      * {@inheritDoc}
103      */
104     public function remove($key)
105     {
106         if ( ! isset($this->elements[$key]) && ! array_key_exists($key, $this->elements)) {
107             return null;
108         }
109
110         $removed = $this->elements[$key];
111         unset($this->elements[$key]);
112
113         return $removed;
114     }
115
116     /**
117      * {@inheritDoc}
118      */
119     public function removeElement($element)
120     {
121         $key = array_search($element, $this->elements, true);
122
123         if ($key === false) {
124             return false;
125         }
126
127         unset($this->elements[$key]);
128
129         return true;
130     }
131
132     /**
133      * Required by interface ArrayAccess.
134      *
135      * {@inheritDoc}
136      */
137     public function offsetExists($offset)
138     {
139         return $this->containsKey($offset);
140     }
141
142     /**
143      * Required by interface ArrayAccess.
144      *
145      * {@inheritDoc}
146      */
147     public function offsetGet($offset)
148     {
149         return $this->get($offset);
150     }
151
152     /**
153      * Required by interface ArrayAccess.
154      *
155      * {@inheritDoc}
156      */
157     public function offsetSet($offset, $value)
158     {
159         if ( ! isset($offset)) {
160             return $this->add($value);
161         }
162
163         $this->set($offset, $value);
164     }
165
166     /**
167      * Required by interface ArrayAccess.
168      *
169      * {@inheritDoc}
170      */
171     public function offsetUnset($offset)
172     {
173         return $this->remove($offset);
174     }
175
176     /**
177      * {@inheritDoc}
178      */
179     public function containsKey($key)
180     {
181         return isset($this->elements[$key]) || array_key_exists($key, $this->elements);
182     }
183
184     /**
185      * {@inheritDoc}
186      */
187     public function contains($element)
188     {
189         return in_array($element, $this->elements, true);
190     }
191
192     /**
193      * {@inheritDoc}
194      */
195     public function exists(Closure $p)
196     {
197         foreach ($this->elements as $key => $element) {
198             if ($p($key, $element)) {
199                 return true;
200             }
201         }
202
203         return false;
204     }
205
206     /**
207      * {@inheritDoc}
208      */
209     public function indexOf($element)
210     {
211         return array_search($element, $this->elements, true);
212     }
213
214     /**
215      * {@inheritDoc}
216      */
217     public function get($key)
218     {
219         return isset($this->elements[$key]) ? $this->elements[$key] : null;
220     }
221
222     /**
223      * {@inheritDoc}
224      */
225     public function getKeys()
226     {
227         return array_keys($this->elements);
228     }
229
230     /**
231      * {@inheritDoc}
232      */
233     public function getValues()
234     {
235         return array_values($this->elements);
236     }
237
238     /**
239      * {@inheritDoc}
240      */
241     public function count()
242     {
243         return count($this->elements);
244     }
245
246     /**
247      * {@inheritDoc}
248      */
249     public function set($key, $value)
250     {
251         $this->elements[$key] = $value;
252     }
253
254     /**
255      * {@inheritDoc}
256      */
257     public function add($value)
258     {
259         $this->elements[] = $value;
260
261         return true;
262     }
263
264     /**
265      * {@inheritDoc}
266      */
267     public function isEmpty()
268     {
269         return empty($this->elements);
270     }
271
272     /**
273      * Required by interface IteratorAggregate.
274      *
275      * {@inheritDoc}
276      */
277     public function getIterator()
278     {
279         return new ArrayIterator($this->elements);
280     }
281
282     /**
283      * {@inheritDoc}
284      */
285     public function map(Closure $func)
286     {
287         return new static(array_map($func, $this->elements));
288     }
289
290     /**
291      * {@inheritDoc}
292      */
293     public function filter(Closure $p)
294     {
295         return new static(array_filter($this->elements, $p));
296     }
297
298     /**
299      * {@inheritDoc}
300      */
301     public function forAll(Closure $p)
302     {
303         foreach ($this->elements as $key => $element) {
304             if ( ! $p($key, $element)) {
305                 return false;
306             }
307         }
308
309         return true;
310     }
311
312     /**
313      * {@inheritDoc}
314      */
315     public function partition(Closure $p)
316     {
317         $matches = $noMatches = array();
318
319         foreach ($this->elements as $key => $element) {
320             if ($p($key, $element)) {
321                 $matches[$key] = $element;
322             } else {
323                 $noMatches[$key] = $element;
324             }
325         }
326
327         return array(new static($matches), new static($noMatches));
328     }
329
330     /**
331      * Returns a string representation of this object.
332      *
333      * @return string
334      */
335     public function __toString()
336     {
337         return __CLASS__ . '@' . spl_object_hash($this);
338     }
339
340     /**
341      * {@inheritDoc}
342      */
343     public function clear()
344     {
345         $this->elements = array();
346     }
347
348     /**
349      * {@inheritDoc}
350      */
351     public function slice($offset, $length = null)
352     {
353         return array_slice($this->elements, $offset, $length, true);
354     }
355
356     /**
357      * {@inheritDoc}
358      */
359     public function matching(Criteria $criteria)
360     {
361         $expr     = $criteria->getWhereExpression();
362         $filtered = $this->elements;
363
364         if ($expr) {
365             $visitor  = new ClosureExpressionVisitor();
366             $filter   = $visitor->dispatch($expr);
367             $filtered = array_filter($filtered, $filter);
368         }
369
370         if ($orderings = $criteria->getOrderings()) {
371             foreach (array_reverse($orderings) as $field => $ordering) {
372                 $next = ClosureExpressionVisitor::sortByField($field, $ordering == Criteria::DESC ? -1 : 1);
373             }
374
375             uasort($filtered, $next);
376         }
377
378         $offset = $criteria->getFirstResult();
379         $length = $criteria->getMaxResults();
380
381         if ($offset || $length) {
382             $filtered = array_slice($filtered, (int)$offset, $length);
383         }
384
385         return new static($filtered);
386     }
387 }