*/ class Collection implements ArrayAccess, Iterator, Countable { /** * Raw array of models * * @var Model[] */ protected $models; /** * Current index of array * * @var int */ protected $position; /** * Initalise the collection * * @author Phil Burton * @param $array */ public function __construct($array = []) { // Initalise Index $this->position = 0; // Initalise empty array $this->setFromArray($array); } /** * Reset array to a new array of models * * @author Phil Burton * @param array $array */ public function setFromArray(array $array) { $this->models = []; foreach ($array as $model) { $this->models[] = $model; } } /** * Set the offset * Only allow values that are an instance of User * * @author Phil Burton * @param mixed $offset * @param mixed $value */ public function offsetSet($offset, $value) { if (!$value instanceof Model) { throw new Exception( 'Collection expects a value of type ' . Model::class . ', ' . gettype($value) . ' given' ); } if (is_null($offset)) { $this->models[] = $value; } else { $this->models[$offset] = $value; } } /** * Return true if the given offset exists * Otherwise return false * * @author Phil Burton * @param mixed $offset */ public function offsetExists($offset) { return isset($this->models[$offset]); } /** * Unset a given offset * * @author Phil Burton * @param mixed $offset */ public function offsetUnset($offset) { unset($this->models[$offset]); } /** * Get the value at a given offset * * @author Phil Burton * @param mixed $offset */ public function offsetGet($offset) { return isset($this->models[$offset]) ? $this->models[$offset] : null; } /** * Return current user * * @author Phil Burton * @return Model */ public function current() { return $this->models[$this->position]; } /** * Return true if the current index exists in user array * Otherwise return false * * @author Phil Burton * @return bool */ public function valid() { return isset($this->models[$this->position]); } /** * Reset index back to 0 * * @author Phil Burton */ public function rewind() { $this->position = 0; } /** * Return the current index * * @author Phil Burton * @return int */ public function key() { return $this->position; } /** * Increment index by 1 * * @author Phil Burton */ public function next() { ++$this->position; } /** * Create and return new collection of the merged arrays from thsi and a given collection * * @author Phil Burton * @param Collection $collection * @return Collection */ public function merge(Collection $collection): Collection { return new Collection(array_merge($collection->toArray(), $this->toArray())); } /** * Return count of users * * @author Phil Burton * @return int */ public function count(): int { return count($this->models); } }