annotate vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php @ 19:fa3358dc1485 tip

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