silverstripe-framework/model/RelationList.php

77 lines
1.9 KiB
PHP
Raw Normal View History

<?php
use SilverStripe\Model\Relation;
/**
* A DataList that represents a relation.
*
* Adds the notion of a foreign ID that can be optionally set.
2014-08-15 08:53:05 +02:00
*
* @package framework
* @subpackage model
*/
abstract class RelationList extends DataList implements Relation {
public function getForeignID() {
return $this->dataQuery->getQueryParam('Foreign.ID');
}
public function getQueryParams() {
$params = parent::getQueryParams();
// Remove `Foreign.` query parameters for created objects,
// as this would interfere with relations on those objects.
foreach(array_keys($params) as $key) {
if(stripos($key, 'Foreign.') !== 0) {
unset($params[$key]);
}
}
return $params;
}
/**
2014-08-15 08:53:05 +02:00
* Returns a copy of this list with the ManyMany relationship linked to
* the given foreign ID.
*
* @param int|array $id An ID or an array of IDs.
* @return static
*/
public function forForeignID($id) {
// Turn a 1-element array into a simple value
if(is_array($id) && sizeof($id) == 1) $id = reset($id);
// Calculate the new filter
$filter = $this->foreignIDFilter($id);
$list = $this->alterDataQuery(function($query, $list) use ($id, $filter){
// Check if there is an existing filter, remove if there is
$currentFilter = $query->getQueryParam('Foreign.Filter');
if($currentFilter) {
try {
$query->removeFilterOn($currentFilter);
}
catch (Exception $e) { /* NOP */ }
}
// Add the new filter
$query->setQueryParam('Foreign.ID', $id);
$query->setQueryParam('Foreign.Filter', $filter);
$query->where($filter);
});
return $list;
}
/**
2014-08-15 08:53:05 +02:00
* Returns a where clause that filters the members of this relationship to
* just the related items.
*
2014-08-15 08:53:05 +02:00
*
* @param array|integer $id (optional) An ID or an array of IDs - if not provided, will use the current ids as
* per getForeignID
* @return array Condition In array(SQL => parameters format)
*/
abstract protected function foreignIDFilter($id = null);
}