MNT Add generics to relation lists

This commit is contained in:
Guy Sartorelli 2023-11-15 12:39:59 +13:00
parent 2301b1025b
commit f3fcfdf1aa
No known key found for this signature in database
GPG Key ID: F313E3B9504D496A
7 changed files with 76 additions and 49 deletions

View File

@ -6,10 +6,12 @@ use InvalidArgumentException;
/**
* Subclass of {@link DataList} representing a has_many relation.
*
* @template T of DataObject
* @extends RelationList<T>
*/
class HasManyList extends RelationList
{
/**
* @var string
*/
@ -21,7 +23,7 @@ class HasManyList extends RelationList
* {@link DataList} methods. Addition arguments are used to support {@link add()}
* and {@link remove()} methods.
*
* @param string $dataClass The class of the DataObjects that this will list.
* @param class-string<T> $dataClass The class of the DataObjects that this will list.
* @param string $foreignKey The name of the foreign key field to set the ID filter against.
*/
public function __construct($dataClass, $foreignKey)
@ -43,7 +45,7 @@ class HasManyList extends RelationList
/**
* @param null|int|array|string $id
* @return array
* @return array|null
*/
protected function foreignIDFilter($id = null)
{
@ -68,7 +70,7 @@ class HasManyList extends RelationList
*
* It does so by setting the relationFilters.
*
* @param DataObject|int $item The DataObject to be added, or its ID
* @param T|int $item The DataObject to be added, or its ID
*/
public function add($item)
{
@ -118,7 +120,7 @@ class HasManyList extends RelationList
* Remove an item from this relation.
* Doesn't actually remove the item, it just clears the foreign key value.
*
* @param DataObject $item The DataObject to be removed
* @param T $item The DataObject to be removed
*/
public function remove($item)
{

View File

@ -12,6 +12,9 @@ use Exception;
/**
* Subclass of {@link DataList} representing a many_many relation.
*
* @template T of DataObject
* @extends RelationList<T>
*/
class ManyManyList extends RelationList
{
@ -50,7 +53,7 @@ class ManyManyList extends RelationList
* the normal {@link DataList} methods. Addition arguments are used to
* support {@link add()} and {@link remove()} methods.
*
* @param string $dataClass The class of the DataObjects that this will list.
* @param class-string<T> $dataClass The class of the DataObjects that this will list.
* @param string $joinTable The name of the table whose entries define the content of this many_many relation.
* @param string $localKey The key in the join table that maps to the dataClass' PK.
* @param string $foreignKey The key in the join table that maps to joined class' PK.
@ -124,7 +127,7 @@ class ManyManyList extends RelationList
* Create a DataObject from the given SQL row.
*
* @param array $row
* @return DataObject
* @return T
*/
public function createDataObject($row)
{
@ -166,7 +169,7 @@ class ManyManyList extends RelationList
*
* @param int|null|string|array $id
*
* @return array
* @return array|null
*/
protected function foreignIDFilter($id = null)
{
@ -214,10 +217,11 @@ class ManyManyList extends RelationList
* @throws InvalidArgumentException
* @throws Exception
*
* @param DataObject|int $item
* @param T|int $item
* @param array $extraFields A map of additional columns to insert into the joinTable.
* Column names should be ANSI quoted.
* @throws Exception
* @throws BadMethodCallException
* @throws InvalidArgumentException
*/
public function add($item, $extraFields = [])
{
@ -335,7 +339,7 @@ class ManyManyList extends RelationList
* Note that for a ManyManyList, the item is never actually deleted, only
* the join table is affected.
*
* @param DataObject $item
* @param T $item
*/
public function remove($item)
{

View File

@ -9,6 +9,9 @@ use SilverStripe\Core\Injector\Injector;
/**
* ManyManyList backed by a dataobject join table
*
* @template T of DataObject
* @extends RelationList<T>
*/
class ManyManyThroughList extends RelationList
{
@ -21,7 +24,7 @@ class ManyManyThroughList extends RelationList
* Create a new ManyManyRelationList object. This relation will utilise an intermediary dataobject
* as a join table, unlike ManyManyList which scaffolds a table automatically.
*
* @param string $dataClass The class of the DataObjects that this will list.
* @param class-string<T> $dataClass The class of the DataObjects that this will list.
* @param string $joinClass Class name of the joined dataobject record
* @param string $localKey The key in the join table that maps to the dataClass' PK.
* @param string $foreignKey The key in the join table that maps to joined class' PK.
@ -101,7 +104,7 @@ class ManyManyThroughList extends RelationList
* Note that for a ManyManyList, the item is never actually deleted, only
* the join table is affected.
*
* @param DataObject $item
* @param T $item
*/
public function remove($item)
{
@ -169,7 +172,7 @@ class ManyManyThroughList extends RelationList
}
/**
* @param mixed $item
* @param T $item
* @param array $extraFields
*/
public function add($item, $extraFields = [])
@ -216,7 +219,7 @@ class ManyManyThroughList extends RelationList
$foreignKey = $this->manipulator->getForeignIDKey();
$hasManyList = $this->manipulator->getParentRelationship($this->dataQuery());
$records = $hasManyList->filter($localKey, $itemID);
/** @var DataObject $record */
foreach ($records as $record) {
if ($extraFields) {
foreach ($extraFields as $field => $value) {

View File

@ -9,6 +9,10 @@ use SilverStripe\ORM\Queries\SQLSelect;
/**
* Injected into DataQuery to augment getFinalisedQuery() with a join table
*
* @template TJoin of DataObject
* @template TParent of DataObject
* @template TForeign of DataObject
*/
class ManyManyThroughQueryManipulator implements DataQueryManipulator
{
@ -18,7 +22,7 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
/**
* DataObject that backs the joining table
*
* @var string
* @var class-string<TJoin>
*/
protected $joinClass;
@ -39,20 +43,24 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
/**
* Foreign class 'from' property. Normally not needed unless polymorphic.
*
* @var string
* @var class-string<TForeign>
*/
protected $foreignClass;
/**
* Class name of instance that owns this list
*
* @var string
* @var class-string<TParent>
*/
protected $parentClass;
/**
* Build query manipulator for a given join table. Additional parameters (foreign key, etc)
* will be inferred at evaluation from query parameters set via the ManyManyThroughList
*
* @param class-string<TJoin> $joinClass
* @param class-string<TForeign> $foreignClass
* @param class-string<TParent> $parentClass
*/
public function __construct(string $joinClass, string $localKey, string $foreignKey, string $foreignClass, string $parentClass)
{
@ -68,7 +76,7 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
}
/**
* @return string
* @return class-string<TJoin>
*/
public function getJoinClass()
{
@ -76,7 +84,7 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
}
/**
* @param mixed $joinClass
* @param class-string<TJoin> $joinClass
* @return $this
*/
public function setJoinClass($joinClass)
@ -152,7 +160,7 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
* Get has_many relationship between parent and join table (for a given DataQuery)
*
* @param DataQuery $query
* @return HasManyList
* @return HasManyList<TJoin>
*/
public function getParentRelationship(DataQuery $query)
{
@ -280,7 +288,7 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
}
/**
* @return string
* @return class-string<TForeign>
*/
public function getForeignClass()
{
@ -288,7 +296,7 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
}
/**
* @param string $foreignClass
* @param class-string<TForeign> $foreignClass
* @return $this
*/
public function setForeignClass($foreignClass)
@ -298,7 +306,7 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
}
/**
* @return string
* @return class-string<TParent>
*/
public function getParentClass()
{
@ -306,8 +314,8 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
}
/**
* @param string $parentClass
* @return ManyManyThroughQueryManipulator
* @param class-string<TParent> $parentClass
* @return $this
*/
public function setParentClass($parentClass)
{

View File

@ -8,6 +8,10 @@ use InvalidArgumentException;
/**
* Represents a has_many list linked against a polymorphic relationship
*
* @template T of DataObject
* @template TForeign of DataObject
* @extends HasManyList<T>
*/
class PolymorphicHasManyList extends HasManyList
{
@ -22,7 +26,7 @@ class PolymorphicHasManyList extends HasManyList
/**
* Retrieve the name of the class this relation is filtered by
*
* @return string
* @return class-string<TForeign>
*/
public function getForeignClass()
{
@ -40,10 +44,10 @@ class PolymorphicHasManyList extends HasManyList
/**
* Create a new PolymorphicHasManyList relation list.
*
* @param string $dataClass The class of the DataObjects that this will list.
* @param class-string<T> $dataClass The class of the DataObjects that this will list.
* @param string $foreignField The name of the composite foreign relation field. Used
* to generate the ID and Class foreign keys.
* @param string $foreignClass Name of the class filter this relation is filtered against
* @param class-string<TForeign> $foreignClass Name of the class filter this relation is filtered against
*/
public function __construct($dataClass, $foreignField, $foreignClass)
{
@ -68,7 +72,7 @@ class PolymorphicHasManyList extends HasManyList
*
* It does so by setting the relationFilters.
*
* @param DataObject|int $item The DataObject to be added, or its ID
* @param T|int $item The DataObject to be added, or its ID
*/
public function add($item)
{
@ -110,7 +114,7 @@ class PolymorphicHasManyList extends HasManyList
* Remove an item from this relation.
* Doesn't actually remove the item, it just clears the foreign key value.
*
* @param DataObject $item The DataObject to be removed
* @param T $item The DataObject to be removed
*/
public function remove($item)
{

View File

@ -10,6 +10,10 @@ use SilverStripe\ORM\DB;
* A DataList that represents a relation.
*
* Adds the notion of a foreign ID that can be optionally set.
*
* @template T of DataObject
* @extends DataList<T>
* @implements Relation<T>
*/
abstract class RelationList extends DataList implements Relation
{
@ -34,8 +38,6 @@ abstract class RelationList extends DataList implements Relation
* every time they're called.
*
* Note that subclasses of RelationList must implement the callback for it to function
*
* @return this
*/
public function addCallbacks(): CallbackList
{
@ -75,8 +77,6 @@ abstract class RelationList extends DataList implements Relation
* when adding records to this list.
*
* Subclasses of RelationList must implement the callback for it to function
*
* @return this
*/
public function removeCallbacks(): CallbackList
{
@ -118,7 +118,7 @@ abstract class RelationList extends DataList implements Relation
*
* @param int|array $id An ID or an array of IDs.
*
* @return static
* @return static<T>
*/
public function forForeignID($id)
{

View File

@ -17,6 +17,9 @@ use Traversable;
* It can store both saved objects (as IDs) or unsaved objects (as instances
* of $dataClass). Unsaved objects are then written when the list is saved
* into an instance of {@link RelationList}.
*
* @template T of DataObject
* @implements Relation<T>
*/
class UnsavedRelationList extends ArrayList implements Relation
{
@ -38,7 +41,7 @@ class UnsavedRelationList extends ArrayList implements Relation
/**
* The DataObject class name that this relation is querying
*
* @var string
* @var class-string<T>
*/
protected $dataClass;
@ -52,7 +55,7 @@ class UnsavedRelationList extends ArrayList implements Relation
/**
* Create a new UnsavedRelationList
*
* @param string $baseClass
* @param class-string<T> $baseClass
* @param string $relationName
* @param string $dataClass The DataObject class used in the relation
*/
@ -67,7 +70,7 @@ class UnsavedRelationList extends ArrayList implements Relation
/**
* Add an item to this relationship
*
* @param mixed $item
* @param T $item
* @param array $extraFields A map of additional columns to insert into the joinTable in the case of a many_many relation
*/
public function add($item, $extraFields = null)
@ -78,7 +81,7 @@ class UnsavedRelationList extends ArrayList implements Relation
/**
* Save all the items in this list into the RelationList
*
* @param RelationList $list
* @param RelationList<T> $list
*/
public function changeToList(RelationList $list)
{
@ -90,7 +93,7 @@ class UnsavedRelationList extends ArrayList implements Relation
/**
* Pushes an item onto the end of this list.
*
* @param array|object $item
* @param array|T $item
* @param array $extraFields
*/
public function push($item, $extraFields = null)
@ -112,7 +115,7 @@ class UnsavedRelationList extends ArrayList implements Relation
/**
* Get the dataClass name for this relation, ie the DataObject ClassName
*
* @return string
* @return class-string<T>
*/
public function dataClass()
{
@ -121,6 +124,8 @@ class UnsavedRelationList extends ArrayList implements Relation
/**
* Returns an Iterator for this relation.
*
* @return iterator<T>
*/
public function getIterator(): Traversable
{
@ -131,7 +136,7 @@ class UnsavedRelationList extends ArrayList implements Relation
* Return an array of the actual items that this relation contains at this stage.
* This is when the query is actually executed.
*
* @return array
* @return array<T>
*/
public function toArray()
{
@ -151,7 +156,7 @@ class UnsavedRelationList extends ArrayList implements Relation
/**
* Add a number of items to the relation.
*
* @param array $items Items to add, as either DataObjects or IDs.
* @param array<T> $items Items to add, as either DataObjects or IDs.
* @return $this
*/
public function addMany($items)
@ -174,7 +179,7 @@ class UnsavedRelationList extends ArrayList implements Relation
/**
* Remove the items from this list with the given IDs
*
* @param array $items
* @param array<T> $items
* @return $this
*/
public function removeMany($items)
@ -233,7 +238,7 @@ class UnsavedRelationList extends ArrayList implements Relation
/**
* Returns the first item in the list
*
* @return mixed
* @return T|null
*/
public function first()
{
@ -250,7 +255,7 @@ class UnsavedRelationList extends ArrayList implements Relation
/**
* Returns the last item in the list
*
* @return mixed
* @return T|null
*/
public function last()
{
@ -287,8 +292,9 @@ class UnsavedRelationList extends ArrayList implements Relation
/**
* Returns a copy of this list with the relationship linked to the given foreign ID.
*
* @param int|array $id An ID or an array of IDs.
* @return Relation
* @return Relation<T>
*/
public function forForeignID($id)
{
@ -300,7 +306,7 @@ class UnsavedRelationList extends ArrayList implements Relation
/**
* @param string $relationName
* @return Relation
* @return Relation<T>
*/
public function relation($relationName)
{