primo commit
This commit is contained in:
336
libraries/fof40/Model/DataModel/Collection.php
Normal file
336
libraries/fof40/Model/DataModel/Collection.php
Normal file
@ -0,0 +1,336 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FOF
|
||||
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||
* @license GNU General Public License version 3, or later
|
||||
*/
|
||||
|
||||
namespace FOF40\Model\DataModel;
|
||||
|
||||
defined('_JEXEC') || die;
|
||||
|
||||
use FOF40\Model\DataModel;
|
||||
use FOF40\Utils\Collection as BaseCollection;
|
||||
|
||||
/**
|
||||
* A collection of data models. You can enumerate it like an array, use it everywhere a collection is expected (e.g. a
|
||||
* foreach loop) and even implements a countable interface. You can also batch-apply DataModel methods on it thanks to
|
||||
* its magic __call() method, hence the type-hinting below.
|
||||
*
|
||||
* @method void setFieldValue(string $name, mixed $value = '')
|
||||
* @method void archive()
|
||||
* @method void save(mixed $data, string $orderingFilter = '', bool $ignore = null)
|
||||
* @method void push(mixed $data, string $orderingFilter = '', bool $ignore = null, array $relations = null)
|
||||
* @method void bind(mixed $data, array $ignore = [])
|
||||
* @method void check()
|
||||
* @method void reorder(string $where = '')
|
||||
* @method void delete(mixed $id = null)
|
||||
* @method void trash(mixed $id)
|
||||
* @method void forceDelete(mixed $id = null)
|
||||
* @method void lock(int $userId = null)
|
||||
* @method void move(int $delta, string $where = '')
|
||||
* @method void publish()
|
||||
* @method void restore(mixed $id)
|
||||
* @method void touch(int $userId = null)
|
||||
* @method void unlock()
|
||||
* @method void unpublish()
|
||||
*/
|
||||
class Collection extends BaseCollection
|
||||
{
|
||||
/**
|
||||
* Find a model in the collection by key.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return DataModel
|
||||
*/
|
||||
public function find($key, $default = null)
|
||||
{
|
||||
if ($key instanceof DataModel)
|
||||
{
|
||||
$key = $key->getId();
|
||||
}
|
||||
|
||||
return array_first($this->items, function ($itemKey, $model) use ($key) {
|
||||
/** @var DataModel $model */
|
||||
return $model->getId() == $key;
|
||||
|
||||
}, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item in the collection by key
|
||||
*
|
||||
* @param mixed $key
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function removeById($key)
|
||||
{
|
||||
if ($key instanceof DataModel)
|
||||
{
|
||||
$key = $key->getId();
|
||||
}
|
||||
|
||||
$index = array_search($key, $this->modelKeys());
|
||||
|
||||
if ($index !== false)
|
||||
{
|
||||
unset($this->items[$index]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item to the collection.
|
||||
*
|
||||
* @param mixed $item
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function add($item)
|
||||
{
|
||||
$this->items[] = $item;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a key exists in the collection.
|
||||
*
|
||||
* @param mixed $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains($key)
|
||||
{
|
||||
return !is_null($this->find($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a nested element of the collection.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function fetch(string $key): BaseCollection
|
||||
{
|
||||
return new static(array_fetch($this->toArray(), $key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the max value of a given key.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function max($key)
|
||||
{
|
||||
return $this->reduce(function ($result, $item) use ($key) {
|
||||
return (is_null($result) || $item->{$key} > $result) ? $item->{$key} : $result;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the min value of a given key.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function min($key)
|
||||
{
|
||||
return $this->reduce(function ($result, $item) use ($key) {
|
||||
return (is_null($result) || $item->{$key} < $result) ? $item->{$key} : $result;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array of primary keys
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function modelKeys()
|
||||
{
|
||||
return array_map(
|
||||
function ($m) {
|
||||
/** @var DataModel $m */
|
||||
return $m->getId();
|
||||
},
|
||||
$this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the collection with the given items.
|
||||
*
|
||||
* @param BaseCollection|array $collection
|
||||
*
|
||||
* @return BaseCollection
|
||||
*/
|
||||
public function merge($collection): BaseCollection
|
||||
{
|
||||
$dictionary = $this->getDictionary($this);
|
||||
|
||||
foreach ($collection as $item)
|
||||
{
|
||||
$dictionary[$item->getId()] = $item;
|
||||
}
|
||||
|
||||
return new static(array_values($dictionary));
|
||||
}
|
||||
|
||||
/**
|
||||
* Diff the collection with the given items.
|
||||
*
|
||||
* @param BaseCollection|array $collection
|
||||
*
|
||||
* @return BaseCollection
|
||||
*/
|
||||
public function diff($collection): BaseCollection
|
||||
{
|
||||
$diff = new static;
|
||||
|
||||
$dictionary = $this->getDictionary($collection);
|
||||
|
||||
foreach ($this->items as $item)
|
||||
{
|
||||
/** @var DataModel $item */
|
||||
if (!isset($dictionary[$item->getId()]))
|
||||
{
|
||||
$diff->add($item);
|
||||
}
|
||||
}
|
||||
|
||||
return $diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Intersect the collection with the given items.
|
||||
*
|
||||
* @param BaseCollection|array $collection
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function intersect($collection): BaseCollection
|
||||
{
|
||||
$intersect = new static;
|
||||
|
||||
$dictionary = $this->getDictionary($collection);
|
||||
|
||||
foreach ($this->items as $item)
|
||||
{
|
||||
/** @var DataModel $item */
|
||||
if (isset($dictionary[$item->getId()]))
|
||||
{
|
||||
$intersect->add($item);
|
||||
}
|
||||
}
|
||||
|
||||
return $intersect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only unique items from the collection.
|
||||
*
|
||||
* @return BaseCollection
|
||||
*/
|
||||
public function unique(): BaseCollection
|
||||
{
|
||||
$dictionary = $this->getDictionary($this);
|
||||
|
||||
return new static(array_values($dictionary));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a base Support collection instance from this collection.
|
||||
*
|
||||
* @return BaseCollection
|
||||
*/
|
||||
public function toBase()
|
||||
{
|
||||
return new BaseCollection($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method which allows you to run a DataModel method to all items in the collection.
|
||||
*
|
||||
* For example, you can do $collection->save('foobar' => 1) to update the 'foobar' column to 1 across all items in
|
||||
* the collection.
|
||||
*
|
||||
* IMPORTANT: The return value of the method call is not returned back to you!
|
||||
*
|
||||
* @param string $name The method to call
|
||||
* @param array $arguments The arguments to the method
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
if (count($this) === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$class = get_class($this->first());
|
||||
|
||||
if (method_exists($class, $name))
|
||||
{
|
||||
foreach ($this as $item)
|
||||
{
|
||||
switch (count($arguments))
|
||||
{
|
||||
case 0:
|
||||
$item->$name();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
$item->$name($arguments[0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
$item->$name($arguments[0], $arguments[1]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
$item->$name($arguments[0], $arguments[1], $arguments[2]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
$item->$name($arguments[0], $arguments[1], $arguments[2], $arguments[3]);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
$item->$name($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4]);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
$item->$name($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5]);
|
||||
break;
|
||||
|
||||
default:
|
||||
call_user_func_array([$item, $name], $arguments);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a dictionary keyed by primary keys.
|
||||
*
|
||||
* @param BaseCollection $collection
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getDictionary($collection)
|
||||
{
|
||||
$dictionary = [];
|
||||
|
||||
foreach ($collection as $value)
|
||||
{
|
||||
$dictionary[$value->getId()] = $value;
|
||||
}
|
||||
|
||||
return $dictionary;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user