mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-08-28 21:46:10 +02:00
In 3.0 there was some confusion about whether DataLists and ArrayLists were mutable or not. If DataLists were immutable, they'd return the result, and your code would look like $list = $list->filter(....); If DataLists were mutable, they'd operate on themselves, returning nothing, and your code would look like $list->filter(....); This makes all DataLists and ArrayList immutable for all _searching_ operations. Operations on DataList that modify the underlying SQL data store remain mutating. - These functions no longer mutate the existing object, and if you do not capture the value returned by them will have no effect: ArrayList#reverse ArrayList#sort ArrayList#filter ArrayList#exclude DataList#dataQuery (use DataList#alterDataQuery to modify dataQuery in a safe manner) DataList#where DataList#limit DataList#sort DataList#addFilter DataList#applyFilterContext DataList#innerJoin DataList#leftJoin DataList#find DataList#byIDs DataList#reverse - DataList#setDataQueryParam has been added as syntactic sugar around the most common cause of accessing the dataQuery directly - setting query parameters - RelationList#setForeignID has been removed. Always use RelationList#forForeignID when querying, and overload RelationList#foreignIDList when subclassing. - Relatedly,the protected variable RelationList->foreignID has been removed, as the ID is now stored on a query parameter. Use RelationList#getForeignID to read it.
96 lines
2.7 KiB
PHP
96 lines
2.7 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Subclass of {@link DataList} representing a has_many relation
|
|
*/
|
|
class HasManyList extends RelationList {
|
|
protected $foreignKey;
|
|
|
|
/**
|
|
* Create a new HasManyList object.
|
|
* Generation of the appropriate record set is left up to the caller, using the normal
|
|
* {@link DataList} methods. Addition arguments are used to support {@@link add()}
|
|
* and {@link remove()} methods.
|
|
*
|
|
* @param $dataClass The class of the DataObjects that this will list.
|
|
* @param $relationFilters A map of key => value filters that define which records
|
|
* in the $dataClass table actually belong to this relationship.
|
|
*/
|
|
public function __construct($dataClass, $foreignKey) {
|
|
parent::__construct($dataClass);
|
|
$this->foreignKey = $foreignKey;
|
|
}
|
|
|
|
protected function foreignIDFilter($id = null) {
|
|
if ($id === null) $id = $this->getForeignID();
|
|
|
|
// Apply relation filter
|
|
if(is_array($id)) {
|
|
return "\"$this->foreignKey\" IN ('" .
|
|
implode("', '", array_map('Convert::raw2sql', $id)) . "')";
|
|
} else if($id !== null){
|
|
return "\"$this->foreignKey\" = '" .
|
|
Convert::raw2sql($id) . "'";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds the item to this relation.
|
|
* It does so by setting the relationFilters.
|
|
* @param $item The DataObject to be added, or its ID
|
|
*/
|
|
public function add($item) {
|
|
if(is_numeric($item)) {
|
|
$item = DataObject::get_by_id($this->dataClass, $item);
|
|
} else if(!($item instanceof $this->dataClass)) {
|
|
user_error("HasManyList::add() expecting a $this->dataClass object, or ID value", E_USER_ERROR);
|
|
}
|
|
|
|
$foreignID = $this->getForeignID();
|
|
|
|
// Validate foreignID
|
|
if(!$foreignID) {
|
|
user_error("ManyManyList::add() can't be called until a foreign ID is set", E_USER_WARNING);
|
|
return;
|
|
}
|
|
if(is_array($foreignID)) {
|
|
user_error("ManyManyList::add() can't be called on a list linked to mulitple foreign IDs", E_USER_WARNING);
|
|
return;
|
|
}
|
|
|
|
$fk = $this->foreignKey;
|
|
$item->$fk = $foreignID;
|
|
|
|
$item->write();
|
|
}
|
|
|
|
/**
|
|
* Remove an item from this relation.
|
|
* Doesn't actually remove the item, it just clears the foreign key value.
|
|
* @param $itemID The ID of the item to be removed
|
|
*/
|
|
public function removeByID($itemID) {
|
|
$item = $this->byID($itemID);
|
|
return $this->remove($item);
|
|
}
|
|
|
|
/**
|
|
* Remove an item from this relation.
|
|
* Doesn't actually remove the item, it just clears the foreign key value.
|
|
* @param $item The DataObject to be removed
|
|
* @todo Maybe we should delete the object instead?
|
|
*/
|
|
public function remove($item) {
|
|
if(!($item instanceof $this->dataClass)) {
|
|
throw new InvalidArgumentException("HasManyList::remove() expecting a $this->dataClass object, or ID",
|
|
E_USER_ERROR);
|
|
}
|
|
|
|
$fk = $this->foreignKey;
|
|
$item->$fk = null;
|
|
|
|
$item->write();
|
|
}
|
|
|
|
}
|