2015-08-17 17:00:26 -07:00
< ? php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
* LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license . For more information , see
* < http :// www . doctrine - project . org >.
*/
namespace Doctrine\Common\Collections ;
2015-10-08 11:40:12 -07:00
use ArrayIterator ;
use Closure ;
2015-08-17 17:00:26 -07:00
use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor ;
/**
* An ArrayCollection is a Collection implementation that wraps a regular PHP array .
*
2017-04-13 15:53:35 +01:00
* Warning : Using ( un - ) serialize () on a collection is not a supported use - case
* and may break when we change the internals in the future . If you need to
* serialize a collection use { @ link toArray ()} and reconstruct the collection
* manually .
*
2015-08-17 17:00:26 -07:00
* @ since 2.0
* @ author Guilherme Blanco < guilhermeblanco @ hotmail . com >
* @ author Jonathan Wage < jonwage @ gmail . com >
* @ author Roman Borschel < roman @ code - factory . org >
*/
class ArrayCollection implements Collection , Selectable
{
/**
* An array containing the entries of this collection .
*
* @ var array
*/
2015-10-08 11:40:12 -07:00
private $elements ;
2015-08-17 17:00:26 -07:00
/**
* Initializes a new ArrayCollection .
*
* @ param array $elements
*/
2018-11-23 12:29:20 +00:00
public function __construct ( array $elements = [])
2015-08-17 17:00:26 -07:00
{
2015-10-08 11:40:12 -07:00
$this -> elements = $elements ;
2015-08-17 17:00:26 -07:00
}
2017-04-13 15:53:35 +01:00
/**
* Creates a new instance from the specified elements .
*
* This method is provided for derived classes to specify how a new
* instance should be created when constructor semantics have changed .
*
* @ param array $elements Elements .
*
* @ return static
*/
protected function createFrom ( array $elements )
{
return new static ( $elements );
}
2015-08-17 17:00:26 -07:00
/**
* { @ inheritDoc }
*/
public function toArray ()
{
2015-10-08 11:40:12 -07:00
return $this -> elements ;
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function first ()
{
2015-10-08 11:40:12 -07:00
return reset ( $this -> elements );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function last ()
{
2015-10-08 11:40:12 -07:00
return end ( $this -> elements );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function key ()
{
2015-10-08 11:40:12 -07:00
return key ( $this -> elements );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function next ()
{
2015-10-08 11:40:12 -07:00
return next ( $this -> elements );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function current ()
{
2015-10-08 11:40:12 -07:00
return current ( $this -> elements );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function remove ( $key )
{
2015-10-08 11:40:12 -07:00
if ( ! isset ( $this -> elements [ $key ]) && ! array_key_exists ( $key , $this -> elements )) {
return null ;
2015-08-17 17:00:26 -07:00
}
2015-10-08 11:40:12 -07:00
$removed = $this -> elements [ $key ];
unset ( $this -> elements [ $key ]);
return $removed ;
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function removeElement ( $element )
{
2015-10-08 11:40:12 -07:00
$key = array_search ( $element , $this -> elements , true );
2015-08-17 17:00:26 -07:00
2015-10-08 11:40:12 -07:00
if ( $key === false ) {
return false ;
2015-08-17 17:00:26 -07:00
}
2015-10-08 11:40:12 -07:00
unset ( $this -> elements [ $key ]);
return true ;
2015-08-17 17:00:26 -07:00
}
/**
* Required by interface ArrayAccess .
*
* { @ inheritDoc }
*/
public function offsetExists ( $offset )
{
return $this -> containsKey ( $offset );
}
/**
* Required by interface ArrayAccess .
*
* { @ inheritDoc }
*/
public function offsetGet ( $offset )
{
return $this -> get ( $offset );
}
/**
* Required by interface ArrayAccess .
*
* { @ inheritDoc }
*/
public function offsetSet ( $offset , $value )
{
if ( ! isset ( $offset )) {
2018-11-23 12:29:20 +00:00
$this -> add ( $value );
return ;
2015-08-17 17:00:26 -07:00
}
2015-10-08 11:40:12 -07:00
$this -> set ( $offset , $value );
2015-08-17 17:00:26 -07:00
}
/**
* Required by interface ArrayAccess .
*
* { @ inheritDoc }
*/
public function offsetUnset ( $offset )
{
2018-11-23 12:29:20 +00:00
$this -> remove ( $offset );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function containsKey ( $key )
{
2015-10-08 11:40:12 -07:00
return isset ( $this -> elements [ $key ]) || array_key_exists ( $key , $this -> elements );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function contains ( $element )
{
2015-10-08 11:40:12 -07:00
return in_array ( $element , $this -> elements , true );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function exists ( Closure $p )
{
2015-10-08 11:40:12 -07:00
foreach ( $this -> elements as $key => $element ) {
2015-08-17 17:00:26 -07:00
if ( $p ( $key , $element )) {
return true ;
}
}
2015-10-08 11:40:12 -07:00
2015-08-17 17:00:26 -07:00
return false ;
}
/**
* { @ inheritDoc }
*/
public function indexOf ( $element )
{
2015-10-08 11:40:12 -07:00
return array_search ( $element , $this -> elements , true );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function get ( $key )
{
2018-11-23 12:29:20 +00:00
return $this -> elements [ $key ] ? ? null ;
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function getKeys ()
{
2015-10-08 11:40:12 -07:00
return array_keys ( $this -> elements );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function getValues ()
{
2015-10-08 11:40:12 -07:00
return array_values ( $this -> elements );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function count ()
{
2015-10-08 11:40:12 -07:00
return count ( $this -> elements );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function set ( $key , $value )
{
2015-10-08 11:40:12 -07:00
$this -> elements [ $key ] = $value ;
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
2017-04-13 15:53:35 +01:00
public function add ( $element )
2015-08-17 17:00:26 -07:00
{
2017-04-13 15:53:35 +01:00
$this -> elements [] = $element ;
2015-10-08 11:40:12 -07:00
2015-08-17 17:00:26 -07:00
return true ;
}
/**
* { @ inheritDoc }
*/
public function isEmpty ()
{
2015-10-08 11:40:12 -07:00
return empty ( $this -> elements );
2015-08-17 17:00:26 -07:00
}
/**
* Required by interface IteratorAggregate .
*
* { @ inheritDoc }
*/
public function getIterator ()
{
2015-10-08 11:40:12 -07:00
return new ArrayIterator ( $this -> elements );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
2018-11-23 12:29:20 +00:00
*
* @ return static
2015-08-17 17:00:26 -07:00
*/
public function map ( Closure $func )
{
2017-04-13 15:53:35 +01:00
return $this -> createFrom ( array_map ( $func , $this -> elements ));
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
2018-11-23 12:29:20 +00:00
*
* @ return static
2015-08-17 17:00:26 -07:00
*/
public function filter ( Closure $p )
{
2017-04-13 15:53:35 +01:00
return $this -> createFrom ( array_filter ( $this -> elements , $p ));
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function forAll ( Closure $p )
{
2015-10-08 11:40:12 -07:00
foreach ( $this -> elements as $key => $element ) {
2015-08-17 17:00:26 -07:00
if ( ! $p ( $key , $element )) {
return false ;
}
}
return true ;
}
/**
* { @ inheritDoc }
*/
public function partition ( Closure $p )
{
2018-11-23 12:29:20 +00:00
$matches = $noMatches = [];
2015-10-08 11:40:12 -07:00
foreach ( $this -> elements as $key => $element ) {
2015-08-17 17:00:26 -07:00
if ( $p ( $key , $element )) {
2015-10-08 11:40:12 -07:00
$matches [ $key ] = $element ;
2015-08-17 17:00:26 -07:00
} else {
2015-10-08 11:40:12 -07:00
$noMatches [ $key ] = $element ;
2015-08-17 17:00:26 -07:00
}
}
2015-10-08 11:40:12 -07:00
2018-11-23 12:29:20 +00:00
return [ $this -> createFrom ( $matches ), $this -> createFrom ( $noMatches )];
2015-08-17 17:00:26 -07:00
}
/**
* Returns a string representation of this object .
*
* @ return string
*/
public function __toString ()
{
return __CLASS__ . '@' . spl_object_hash ( $this );
}
/**
* { @ inheritDoc }
*/
public function clear ()
{
2018-11-23 12:29:20 +00:00
$this -> elements = [];
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function slice ( $offset , $length = null )
{
2015-10-08 11:40:12 -07:00
return array_slice ( $this -> elements , $offset , $length , true );
2015-08-17 17:00:26 -07:00
}
/**
* { @ inheritDoc }
*/
public function matching ( Criteria $criteria )
{
$expr = $criteria -> getWhereExpression ();
2015-10-08 11:40:12 -07:00
$filtered = $this -> elements ;
2015-08-17 17:00:26 -07:00
if ( $expr ) {
$visitor = new ClosureExpressionVisitor ();
$filter = $visitor -> dispatch ( $expr );
$filtered = array_filter ( $filtered , $filter );
}
if ( $orderings = $criteria -> getOrderings ()) {
2017-04-13 15:53:35 +01:00
$next = null ;
2015-08-17 17:00:26 -07:00
foreach ( array_reverse ( $orderings ) as $field => $ordering ) {
2017-04-13 15:53:35 +01:00
$next = ClosureExpressionVisitor :: sortByField ( $field , $ordering == Criteria :: DESC ? - 1 : 1 , $next );
2015-08-17 17:00:26 -07:00
}
2015-10-08 11:40:12 -07:00
uasort ( $filtered , $next );
2015-08-17 17:00:26 -07:00
}
$offset = $criteria -> getFirstResult ();
$length = $criteria -> getMaxResults ();
if ( $offset || $length ) {
$filtered = array_slice ( $filtered , ( int ) $offset , $length );
}
2017-04-13 15:53:35 +01:00
return $this -> createFrom ( $filtered );
2015-08-17 17:00:26 -07:00
}
}