2011-04-01 06:09:48 +02:00
|
|
|
<?php
|
2016-06-15 06:03:16 +02:00
|
|
|
|
|
|
|
namespace SilverStripe\ORM;
|
|
|
|
|
2016-08-19 00:51:35 +02:00
|
|
|
use SilverStripe\View\ViewableData;
|
2016-06-15 06:03:16 +02:00
|
|
|
use LogicException;
|
|
|
|
|
2011-04-01 06:09:48 +02:00
|
|
|
/**
|
|
|
|
* A base class for decorators that wrap around a list to provide additional
|
2012-01-17 00:34:54 +01:00
|
|
|
* functionality. It passes through list methods to the underlying list
|
2011-05-02 10:12:39 +02:00
|
|
|
* implementation.
|
2011-04-01 06:09:48 +02:00
|
|
|
*/
|
2016-11-29 00:31:16 +01:00
|
|
|
abstract class ListDecorator extends ViewableData implements SS_List, Sortable, Filterable, Limitable
|
|
|
|
{
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var SS_List
|
|
|
|
*/
|
|
|
|
protected $list;
|
|
|
|
|
|
|
|
public function __construct(SS_List $list)
|
|
|
|
{
|
2017-01-17 13:23:41 +01:00
|
|
|
$this->setList($list);
|
2016-11-29 00:31:16 +01:00
|
|
|
|
|
|
|
parent::__construct();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the list this decorator wraps around.
|
|
|
|
*
|
|
|
|
* @return SS_List
|
|
|
|
*/
|
|
|
|
public function getList()
|
|
|
|
{
|
|
|
|
return $this->list;
|
|
|
|
}
|
|
|
|
|
2017-01-17 13:23:41 +01:00
|
|
|
/**
|
|
|
|
* Set the list this decorator wraps around.
|
|
|
|
*
|
|
|
|
* Useful for keeping a decorator/paginated list configuration intact while modifying
|
|
|
|
* the underlying list.
|
|
|
|
*
|
|
|
|
* @return SS_List
|
|
|
|
*/
|
|
|
|
public function setList($list)
|
|
|
|
{
|
|
|
|
$this->list = $list;
|
|
|
|
$this->failover = $this->list;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
// PROXIED METHODS ---------------------------------------------------------
|
|
|
|
|
2022-04-14 03:12:59 +02:00
|
|
|
#[\ReturnTypeWillChange]
|
2016-11-29 00:31:16 +01:00
|
|
|
public function offsetExists($key)
|
|
|
|
{
|
|
|
|
return $this->list->offsetExists($key);
|
|
|
|
}
|
|
|
|
|
2022-04-14 03:12:59 +02:00
|
|
|
#[\ReturnTypeWillChange]
|
2016-11-29 00:31:16 +01:00
|
|
|
public function offsetGet($key)
|
|
|
|
{
|
|
|
|
return $this->list->offsetGet($key);
|
|
|
|
}
|
|
|
|
|
2022-04-14 03:12:59 +02:00
|
|
|
#[\ReturnTypeWillChange]
|
2016-11-29 00:31:16 +01:00
|
|
|
public function offsetSet($key, $value)
|
|
|
|
{
|
|
|
|
$this->list->offsetSet($key, $value);
|
|
|
|
}
|
|
|
|
|
2022-04-14 03:12:59 +02:00
|
|
|
#[\ReturnTypeWillChange]
|
2016-11-29 00:31:16 +01:00
|
|
|
public function offsetUnset($key)
|
|
|
|
{
|
|
|
|
$this->list->offsetUnset($key);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function toArray()
|
|
|
|
{
|
|
|
|
return $this->list->toArray();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function toNestedArray()
|
|
|
|
{
|
|
|
|
return $this->list->toNestedArray();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function add($item)
|
|
|
|
{
|
|
|
|
$this->list->add($item);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function remove($itemObject)
|
|
|
|
{
|
|
|
|
$this->list->remove($itemObject);
|
|
|
|
}
|
|
|
|
|
2022-04-14 03:12:59 +02:00
|
|
|
#[\ReturnTypeWillChange]
|
2016-11-29 00:31:16 +01:00
|
|
|
public function getIterator()
|
|
|
|
{
|
|
|
|
return $this->list->getIterator();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function exists()
|
|
|
|
{
|
|
|
|
return $this->list->exists();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function first()
|
|
|
|
{
|
|
|
|
return $this->list->first();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function last()
|
|
|
|
{
|
|
|
|
return $this->list->last();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function TotalItems()
|
|
|
|
{
|
|
|
|
return $this->list->count();
|
|
|
|
}
|
|
|
|
|
2022-04-14 03:12:59 +02:00
|
|
|
#[\ReturnTypeWillChange]
|
2016-11-29 00:31:16 +01:00
|
|
|
public function Count()
|
|
|
|
{
|
|
|
|
return $this->list->count();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function forTemplate()
|
|
|
|
{
|
|
|
|
return $this->list->forTemplate();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function map($index = 'ID', $titleField = 'Title')
|
|
|
|
{
|
|
|
|
return $this->list->map($index, $titleField);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function find($key, $value)
|
|
|
|
{
|
|
|
|
return $this->list->find($key, $value);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function column($value = 'ID')
|
|
|
|
{
|
|
|
|
return $this->list->column($value);
|
|
|
|
}
|
|
|
|
|
2018-07-12 03:44:32 +02:00
|
|
|
public function columnUnique($value = "ID")
|
|
|
|
{
|
|
|
|
return $this->list->columnUnique($value);
|
|
|
|
}
|
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
public function each($callback)
|
|
|
|
{
|
|
|
|
return $this->list->each($callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function canSortBy($by)
|
|
|
|
{
|
|
|
|
return $this->list->canSortBy($by);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function reverse()
|
|
|
|
{
|
|
|
|
return $this->list->reverse();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sorts this list by one or more fields. You can either pass in a single
|
|
|
|
* field name and direction, or a map of field names to sort directions.
|
|
|
|
*
|
|
|
|
* @example $list->sort('Name'); // default ASC sorting
|
|
|
|
* @example $list->sort('Name DESC'); // DESC sorting
|
|
|
|
* @example $list->sort('Name', 'ASC');
|
|
|
|
* @example $list->sort(array('Name'=>'ASC,'Age'=>'DESC'));
|
|
|
|
*/
|
|
|
|
public function sort()
|
|
|
|
{
|
2018-11-09 12:59:14 +01:00
|
|
|
return $this->list->sort(...func_get_args());
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function canFilterBy($by)
|
|
|
|
{
|
|
|
|
return $this->list->canFilterBy($by);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-04-28 14:02:48 +02:00
|
|
|
* Filter the list to include items with these characteristics
|
2016-11-29 00:31:16 +01:00
|
|
|
*
|
|
|
|
* @example $list->filter('Name', 'bob'); // only bob in list
|
|
|
|
* @example $list->filter('Name', array('aziz', 'bob'); // aziz and bob in list
|
|
|
|
* @example $list->filter(array('Name'=>'bob, 'Age'=>21)); // bob or someone with Age 21
|
|
|
|
* @example $list->filter(array('Name'=>'bob, 'Age'=>array(21, 43))); // bob or anyone with Age 21 or 43
|
|
|
|
*/
|
|
|
|
public function filter()
|
|
|
|
{
|
2018-11-09 12:59:14 +01:00
|
|
|
return $this->list->filter(...func_get_args());
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-04-28 14:02:48 +02:00
|
|
|
* Return a copy of this list which contains items matching any of these characteristics.
|
2016-11-29 00:31:16 +01:00
|
|
|
*
|
|
|
|
* @example // only bob in the list
|
|
|
|
* $list = $list->filterAny('Name', 'bob');
|
|
|
|
* // SQL: WHERE "Name" = 'bob'
|
|
|
|
* @example // azis or bob in the list
|
|
|
|
* $list = $list->filterAny('Name', array('aziz', 'bob');
|
|
|
|
* // SQL: WHERE ("Name" IN ('aziz','bob'))
|
|
|
|
* @example // bob or anyone aged 21 in the list
|
|
|
|
* $list = $list->filterAny(array('Name'=>'bob, 'Age'=>21));
|
|
|
|
* // SQL: WHERE ("Name" = 'bob' OR "Age" = '21')
|
|
|
|
* @example // bob or anyone aged 21 or 43 in the list
|
|
|
|
* $list = $list->filterAny(array('Name'=>'bob, 'Age'=>array(21, 43)));
|
|
|
|
* // SQL: WHERE ("Name" = 'bob' OR ("Age" IN ('21', '43'))
|
|
|
|
* @example // all bobs, phils or anyone aged 21 or 43 in the list
|
|
|
|
* $list = $list->filterAny(array('Name'=>array('bob','phil'), 'Age'=>array(21, 43)));
|
|
|
|
* // SQL: WHERE (("Name" IN ('bob', 'phil')) OR ("Age" IN ('21', '43'))
|
|
|
|
*
|
|
|
|
* @param string|array See {@link filter()}
|
|
|
|
* @return DataList
|
|
|
|
*/
|
|
|
|
public function filterAny()
|
|
|
|
{
|
2018-11-09 12:59:14 +01:00
|
|
|
return $this->list->filterAny(...func_get_args());
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Note that, in the current implementation, the filtered list will be an ArrayList, but this may change in a
|
|
|
|
* future implementation.
|
|
|
|
* @see Filterable::filterByCallback()
|
|
|
|
*
|
|
|
|
* @example $list = $list->filterByCallback(function($item, $list) { return $item->Age == 9; })
|
|
|
|
* @param callable $callback
|
|
|
|
* @return ArrayList (this may change in future implementations)
|
|
|
|
*/
|
|
|
|
public function filterByCallback($callback)
|
|
|
|
{
|
|
|
|
if (!is_callable($callback)) {
|
|
|
|
throw new LogicException(sprintf(
|
|
|
|
"SS_Filterable::filterByCallback() passed callback must be callable, '%s' given",
|
|
|
|
gettype($callback)
|
|
|
|
));
|
|
|
|
}
|
|
|
|
$output = ArrayList::create();
|
|
|
|
foreach ($this->list as $item) {
|
2018-11-09 12:59:14 +01:00
|
|
|
if ($callback($item, $this->list)) {
|
2016-11-29 00:31:16 +01:00
|
|
|
$output->push($item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function limit($limit, $offset = 0)
|
|
|
|
{
|
|
|
|
return $this->list->limit($limit, $offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the first item with the given ID
|
|
|
|
*
|
|
|
|
* @param int $id
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
public function byID($id)
|
|
|
|
{
|
|
|
|
return $this->list->byID($id);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Filter this list to only contain the given Primary IDs
|
|
|
|
*
|
|
|
|
* @param array $ids Array of integers
|
|
|
|
* @return SS_List
|
|
|
|
*/
|
|
|
|
public function byIDs($ids)
|
|
|
|
{
|
|
|
|
return $this->list->byIDs($ids);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-04-28 14:02:48 +02:00
|
|
|
* Exclude the list to not contain items with these characteristics
|
2016-11-29 00:31:16 +01:00
|
|
|
*
|
|
|
|
* @example $list->exclude('Name', 'bob'); // exclude bob from list
|
|
|
|
* @example $list->exclude('Name', array('aziz', 'bob'); // exclude aziz and bob from list
|
|
|
|
* @example $list->exclude(array('Name'=>'bob, 'Age'=>21)); // exclude bob or someone with Age 21
|
|
|
|
* @example $list->exclude(array('Name'=>'bob, 'Age'=>array(21, 43))); // exclude bob or anyone with Age 21 or 43
|
|
|
|
*/
|
|
|
|
public function exclude()
|
|
|
|
{
|
2018-11-09 12:59:14 +01:00
|
|
|
return $this->list->exclude(...func_get_args());
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function debug()
|
|
|
|
{
|
|
|
|
return $this->list->debug();
|
|
|
|
}
|
2012-03-24 04:04:52 +01:00
|
|
|
}
|