diff --git a/src/BaseCollection.php b/src/BaseCollection.php index 8bad3b8d28..4d5803d585 100644 --- a/src/BaseCollection.php +++ b/src/BaseCollection.php @@ -28,6 +28,30 @@ abstract class BaseCollection extends \ArrayIterator $this->totalCount = $totalCount ?? count($models); } + /** + * @inheritDoc + */ + public function offsetSet($offset, $value) + { + if (is_null($offset)) { + $this->totalCount++; + } + + parent::offsetSet($offset, $value); + } + + /** + * @inheritDoc + */ + public function offsetUnset($offset) + { + if ($this->offsetExists($offset)) { + $this->totalCount--; + } + + parent::offsetUnset($offset); + } + /** * @return int */ @@ -35,4 +59,42 @@ abstract class BaseCollection extends \ArrayIterator { return $this->totalCount; } + + /** + * Return the values from a single field in the collection + * + * @param string $column + * @param int|null $index_key + * @return array + * @see array_column() + */ + public function column($column, $index_key = null) + { + return array_column($this->getArrayCopy(), $column, $index_key); + } + + /** + * Apply a callback function on all elements in the collection and returns a new collection with the updated elements + * + * @param callable $callback + * @return BaseCollection + * @see array_map() + */ + public function map(callable $callback) + { + return new static(array_map($callback, $this->getArrayCopy()), $this->getTotalCount()); + } + + /** + * Filters the collection based on a callback that returns a boolean whether the current item should be kept. + * + * @param callable|null $callback + * @param int $flag + * @return BaseCollection + * @see array_filter() + */ + public function filter(callable $callback = null, int $flag = 0) + { + return new static(array_filter($this->getArrayCopy(), $callback, $flag)); + } } diff --git a/src/BaseModel.php b/src/BaseModel.php index 5a27089143..b2dc7eedaf 100644 --- a/src/BaseModel.php +++ b/src/BaseModel.php @@ -69,6 +69,18 @@ abstract class BaseModel return $model; } + /** + * Magic isset method. Returns true if the field exists, either in the data prperty array or in any of the local properties. + * Used by array_column() on an array of objects. + * + * @param $name + * @return bool + */ + public function __isset($name) + { + return in_array($name, array_merge(array_keys($this->data), array_keys(get_object_vars($this)))); + } + /** * Magic getter. This allows to retrieve model fields with the following syntax: * - $model->field (outside of class) @@ -80,9 +92,7 @@ abstract class BaseModel */ public function __get($name) { - if (empty($this->data['id'])) { - throw new HTTPException\InternalServerErrorException(static::class . ' record uninitialized'); - } + $this->checkValid(); if (!array_key_exists($name, $this->data)) { throw new HTTPException\InternalServerErrorException('Field ' . $name . ' not found in ' . static::class); @@ -104,4 +114,11 @@ abstract class BaseModel { return $this->data; } + + protected function checkValid() + { + if (empty($this->data['id'])) { + throw new HTTPException\InternalServerErrorException(static::class . ' record uninitialized'); + } + } } diff --git a/src/BaseRepository.php b/src/BaseRepository.php index 30822091e1..c0bcab18f9 100644 --- a/src/BaseRepository.php +++ b/src/BaseRepository.php @@ -199,4 +199,12 @@ abstract class BaseRepository extends BaseFactory return $models; } + + /** + * @param BaseCollection $collection + */ + public function saveCollection(BaseCollection $collection) + { + $collection->map([$this, 'update']); + } }