<?php
namespace Spot\Entity;
/**
* Collection of Spot_Entity objects
*
* @package Spot
* @link http://spot.os.ly
*/
class Collection implements \Iterator, \Countable, \ArrayAccess
{
protected $_results = array();
protected $_resultsIdentities = array();
/**
* Constructor function
*
* @param array $results Array of pre-loaded Spot_Entity objects or Iterator that will fetch them lazily
* @param array $resultsIdentities Array of key values for given result set primary key
*/
public function __construct(array $results = array(), array $resultsIdentities = array())
{
$this->_results = $results;
$this->_resultsIdentities = $resultsIdentities;
}
/**
* Returns first result in set
*
* @return The first result in the set
*/
public function first()
{
$this->rewind();
return $this->current();
}
/**
* Add a single entity to the collection
*
* @param object $entity to add
*/
public function add($entity)
{
$this->_results[] = $entity;
}
/**
* Merge another collection into this collections set of entities
* This will only add entitys that don't already exist in the current
* collection
*
* @param Spot_Entity_Collection $collection
* @todo Implement faster uniqueness checking by hash, entity manager, primary key field, etc.
*/
public function merge(\Spot\Entity\Collection $collection, $onlyUnique = true)
{
foreach($collection as $entity) {
if($onlyUnique && in_array($entity, $this->_results)) {
continue; // Skip - entity already exists in collection
}
$this->add($entity);
}
return $this;
}
/**
* Return an array representation of the Collection.
*
* @param mixed $keyColumn
* @param mixed $valueColumn
* @return array If $keyColumn and $valueColumn are not set, or are both null
* then this will return the array of entity objects
* @return array If $keyColumn is not null, and the value column is null or undefined
* then this will return an array of the values of the entities in the column defined
* @returns array If $keyColumn and $valueColumn are both defined and not null
* then this will return an array where the key is defined by each entities value in $keyColumn
* and the value will be the value of the each entity in $valueColumn
*
* @todo Write unit tests for this function
*/
public function toArray($keyColumn = null, $valueColumn = null)
{
// Both empty
if(null === $keyColumn && null === $valueColumn) {
$return = $this->_results;
// Key column name
} elseif(null !== $keyColumn && null === $valueColumn) {
$return = array();
foreach($this->_results as $row) {
$return[] = $row->$keyColumn;
}
// Both key and valud columns filled in
} else {
$return = array();
foreach($this->_results as $row) {
$return[$row->$keyColumn] = $row->$valueColumn;
}
}
return $return;
}
/**
* Run a function on the set of entities
*
* @param string|array $function A callback of the function to run
*/
public function run($callback)
{
return call_user_func_array($callback, array($this->_results));
}
/**
* Provides a string representation of the class
* Brackets contain the number of elements contained
* in the collection
*
*/
public function __toString()
{
return __CLASS__ . "[".$this->count()."]";
}
// SPL - Countable functions
// ----------------------------------------------
/**
* Get a count of all the records in the result set
*/
public function count()
{
return count($this->_results);
}
// ----------------------------------------------
// SPL - Iterator functions
// ----------------------------------------------
public function current()
{
return current($this->_results);
}
public function key()
{
return key($this->_results);
}
public function next()
{
next($this->_results);
}
public function rewind()
{
reset($this->_results);
}
public function valid()
{
return (current($this->_results) !== FALSE);
}
// ----------------------------------------------
// SPL - ArrayAccess functions
// ----------------------------------------------
public function offsetExists($key) {
return isset($this->_results[$key]);
}
public function offsetGet($key) {
return $this->_results[$key];
}
public function offsetSet($key, $value) {
if($key === null) {
return $this->_results[] = $value;
} else {
return $this->_results[$key] = $value;
}
}
public function offsetUnset($key) {
if(is_int($key)) {
array_splice($this->_results, $key, 1);
} else {
unset($this->_results[$key]);
}
}
// ----------------------------------------------
}