*/ class Collection implements ArrayAccess, Countable, Iterator { /** * 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 "dump" * @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; } /** * Return the count of the models in this collection * * @author Phil Burton * @return int */ public function count(): int { return count($this->models); } /** * Filter by input * * @author Phil Burton * @param Input $input */ public function filterByInput(Input $input) { // filter by time if ($time = $input->getOption('t')) { $day = $input->getOption('d'); $this->filterByDateTime($day, $time); } if ($location = $input->getOption('l')) { $this->filterByLocation($location); } if ($covers = (int) $input->getOption('c')) { $this->filterByCovers($covers); } } /** * Filter this collection by a given date and time * * @author Phil Burton * @param string $date * @param string $time */ public function filterByDateTime(string $date, string $time) { $dateTime = DateTime::createFromFormat('d/m/y G:i', $date . ' ' . $time); if (!$dateTime) { throw new Exception( 'Unable to parse datetime. Required time format: `G:i` (e.g. 05:30). ' . 'Required date format: `d/m/y` (e.g. 22/06/18)' ); } $out = []; foreach ($this->models as $model) { if ($model->checkDate($dateTime)) { $out[] = $model; } } $this->models = $out; } /** * Filter this collection by a given location postcode * * @author Phil Burton * @param string $location */ public function filterByLocation(string $location) { $location = substr($location, 0, 2); $out = []; foreach ($this->models as $model) { if ($model->checkLocation($location)) { $out[] = $model; } } $this->models = $out; } /** * Filter this collection by a given max covers integer * * @author Phil Burton * @param int $covers */ public function filterByCovers(int $covers) { $out = []; foreach ($this->models as $model) { if ($model->checkMaxCovers($covers)) { $out[] = $model; } } $this->models = $out; } /** * Return string representation of this collection * * @author Phil Burton * @return string */ public function toString() : string { $out = []; foreach ($this->models as $model) { $out[] = $model->toString(); } return implode("\n\n", $out); } }