silverstripe-framework/ORM/ListDecorator.php
2016-09-09 18:43:05 +12:00

244 lines
6.4 KiB
PHP

<?php
namespace SilverStripe\ORM;
use SilverStripe\View\ViewableData;
use LogicException;
/**
* A base class for decorators that wrap around a list to provide additional
* functionality. It passes through list methods to the underlying list
* implementation.
*/
abstract class ListDecorator extends ViewableData implements SS_List, Sortable, Filterable, Limitable {
/**
* @var SS_List
*/
protected $list;
public function __construct(SS_List $list) {
$this->list = $list;
$this->failover = $this->list;
parent::__construct();
}
/**
* Returns the list this decorator wraps around.
*
* @return SS_List
*/
public function getList() {
return $this->list;
}
// PROXIED METHODS ---------------------------------------------------------
public function offsetExists($key) {
return $this->list->offsetExists($key);
}
public function offsetGet($key) {
return $this->list->offsetGet($key);
}
public function offsetSet($key, $value) {
$this->list->offsetSet($key, $value);
}
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);
}
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();
}
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);
}
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() {
$args = func_get_args();
return call_user_func_array(array($this->list, 'sort'), $args);
}
public function canFilterBy($by) {
return $this->list->canFilterBy($by);
}
/**
* Filter the list to include items with these charactaristics
*
* @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(){
$args = func_get_args();
return call_user_func_array(array($this->list, 'filter'), $args);
}
/**
* Return a copy of this list which contains items matching any of these charactaristics.
*
* @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() {
return call_user_func_array(array($this->list, __FUNCTION__), func_get_args());
}
/**
* 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) {
if(call_user_func($callback, $item, $this->list)) $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);
}
/**
* Exclude the list to not contain items with these charactaristics
*
* @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(){
$args = func_get_args();
return call_user_func_array(array($this->list, 'exclude'), $args);
}
public function debug() {
return $this->list->debug();
}
}