mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENH Add generic types (#11108)
There are also a few general corrections to PHPDocs that I noticed along the way (e.g. adding `|null` when the method is returning a null value. There are some cases where either the return type or the whole PHPDoc was duplicated from the parent class - in those cases I've simply removed the duplication.
This commit is contained in:
parent
583b762217
commit
357ed7ad7e
@ -164,7 +164,6 @@ class Director implements TemplateGlobalProvider
|
||||
// Build list of cleanup promises
|
||||
$finally = [];
|
||||
|
||||
/** @var Kernel $kernel */
|
||||
$kernel = Injector::inst()->get(Kernel::class);
|
||||
$kernel->nest();
|
||||
$finally[] = function () use ($kernel) {
|
||||
@ -1016,7 +1015,6 @@ class Director implements TemplateGlobalProvider
|
||||
*/
|
||||
public static function get_environment_type()
|
||||
{
|
||||
/** @var Kernel $kernel */
|
||||
$kernel = Injector::inst()->get(Kernel::class);
|
||||
return $kernel->getEnvironment();
|
||||
}
|
||||
|
@ -411,7 +411,6 @@ EOT
|
||||
// a more specific error description.
|
||||
$body = $this->getBody();
|
||||
if ($this->isError() && empty($body)) {
|
||||
/** @var HandlerInterface $handler */
|
||||
$handler = Injector::inst()->get(HandlerInterface::class);
|
||||
$formatter = $handler->getFormatter();
|
||||
echo $formatter->format([
|
||||
|
@ -16,7 +16,6 @@ class FlushMiddleware implements HTTPMiddleware
|
||||
{
|
||||
public function process(HTTPRequest $request, callable $delegate)
|
||||
{
|
||||
/** @var BaseKernel $kernel */
|
||||
$kernel = Injector::inst()->get(Kernel::class);
|
||||
if ((method_exists($kernel, 'isFlushed') && $kernel->isFlushed())) {
|
||||
// Disable cache when flushing
|
||||
|
@ -30,7 +30,6 @@ trait FlushScheduler
|
||||
{
|
||||
$flush = array_key_exists('flush', $request->getVars() ?? []) || ($request->getURL() === 'dev/build');
|
||||
|
||||
/** @var BaseKernel $kernel */
|
||||
$kernel = Injector::inst()->get(Kernel::class);
|
||||
if (!$flush || (method_exists($kernel, 'isFlushed') && $kernel->isFlushed())) {
|
||||
return false;
|
||||
|
@ -13,6 +13,8 @@ use SilverStripe\ORM\DataObject;
|
||||
* Every object instance gets its own set of extension instances,
|
||||
* meaning you can set parameters specific to the "owner instance"
|
||||
* in new Extension instances.
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
abstract class Extension
|
||||
{
|
||||
@ -25,14 +27,14 @@ abstract class Extension
|
||||
/**
|
||||
* The object this extension is applied to.
|
||||
*
|
||||
* @var Object
|
||||
* @var T
|
||||
*/
|
||||
protected $owner;
|
||||
|
||||
/**
|
||||
* Stack of all parent owners, not including current owner
|
||||
*
|
||||
* @var array
|
||||
* @var array<T>
|
||||
*/
|
||||
private $ownerStack = [];
|
||||
|
||||
@ -95,7 +97,7 @@ abstract class Extension
|
||||
/**
|
||||
* Returns the owner of this extension.
|
||||
*
|
||||
* @return Object
|
||||
* @return T
|
||||
*/
|
||||
public function getOwner()
|
||||
{
|
||||
|
@ -966,12 +966,13 @@ class Injector implements ContainerInterface
|
||||
*
|
||||
* @throws NotFoundExceptionInterface No entry was found for **this** identifier.
|
||||
*
|
||||
* @param string $name The name of the service to retrieve. If not a registered
|
||||
* @template T of object
|
||||
* @param class-string<T>|string $name The name of the service to retrieve. If not a registered
|
||||
* service, then a class of the given name is instantiated
|
||||
* @param bool $asSingleton If set to false a new instance will be returned.
|
||||
* If true a singleton will be returned unless the spec is type=prototype'
|
||||
* @param array $constructorArgs Args to pass in to the constructor. Note: Ignored for singletons
|
||||
* @return mixed Instance of the specified object
|
||||
* @return T|mixed Instance of the specified object
|
||||
*/
|
||||
public function get($name, $asSingleton = true, $constructorArgs = [])
|
||||
{
|
||||
@ -987,12 +988,13 @@ class Injector implements ContainerInterface
|
||||
/**
|
||||
* Returns the service, or `null` if it doesnt' exist. See {@link get()} for main usage.
|
||||
*
|
||||
* @param string $name The name of the service to retrieve. If not a registered
|
||||
* @template T of object
|
||||
* @param class-string<T>|string $name The name of the service to retrieve. If not a registered
|
||||
* service, then a class of the given name is instantiated
|
||||
* @param bool $asSingleton If set to false a new instance will be returned.
|
||||
* If true a singleton will be returned unless the spec is type=prototype'
|
||||
* @param array $constructorArgs Args to pass in to the constructor. Note: Ignored for singletons
|
||||
* @return mixed Instance of the specified object
|
||||
* @return T|mixed Instance of the specified object
|
||||
*/
|
||||
protected function getNamedService($name, $asSingleton = true, $constructorArgs = [])
|
||||
{
|
||||
@ -1111,9 +1113,9 @@ class Injector implements ContainerInterface
|
||||
/**
|
||||
* Magic method to return an item directly
|
||||
*
|
||||
* @param string $name
|
||||
* The named object to retrieve
|
||||
* @return mixed
|
||||
* @template T of object
|
||||
* @param class-string<T>|string $name The named object to retrieve
|
||||
* @return T|mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
@ -1125,9 +1127,10 @@ class Injector implements ContainerInterface
|
||||
*
|
||||
* Additional parameters are passed through as
|
||||
*
|
||||
* @param string $name
|
||||
* @template T of object
|
||||
* @param class-string<T>|string $name
|
||||
* @param mixed ...$argument arguments to pass to the constructor
|
||||
* @return mixed A new instance of the specified object
|
||||
* @return T|mixed A new instance of the specified object
|
||||
*/
|
||||
public function create($name, $argument = null)
|
||||
{
|
||||
@ -1139,9 +1142,10 @@ class Injector implements ContainerInterface
|
||||
/**
|
||||
* Creates an object with the supplied argument array
|
||||
*
|
||||
* @param string $name Name of the class to create an object of
|
||||
* @template T of object
|
||||
* @param class-string<T>|string $name Name of the class to create an object of
|
||||
* @param array $constructorArgs Arguments to pass to the constructor
|
||||
* @return mixed
|
||||
* @return T|mixed
|
||||
*/
|
||||
public function createWithArgs($name, $constructorArgs)
|
||||
{
|
||||
|
@ -148,7 +148,6 @@ class ModuleManifest
|
||||
{
|
||||
$modules = $this->getModules();
|
||||
// Work in reverse priority, so the higher priority modules get later execution
|
||||
/** @var Module $module */
|
||||
foreach (array_reverse($modules ?? []) as $module) {
|
||||
$module->activate();
|
||||
}
|
||||
@ -262,7 +261,6 @@ class ModuleManifest
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var Module $rootModule */
|
||||
$rootModule = null;
|
||||
|
||||
// Find based on loaded modules
|
||||
|
@ -88,7 +88,6 @@ class ModuleResource
|
||||
*/
|
||||
public function getURL()
|
||||
{
|
||||
/** @var ResourceURLGenerator $generator */
|
||||
$generator = Injector::inst()->get(ResourceURLGenerator::class);
|
||||
return $generator->urlForResource($this);
|
||||
}
|
||||
|
@ -51,7 +51,6 @@ class ModuleResourceLoader implements TemplateGlobalProvider
|
||||
$resource = $this->resolveResource($resource);
|
||||
|
||||
// Resolve resource to url
|
||||
/** @var ResourceURLGenerator $generator */
|
||||
$generator = Injector::inst()->get(ResourceURLGenerator::class);
|
||||
return $generator->urlForResource($resource);
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ class FixtureFactory
|
||||
*
|
||||
* @param string $class The data class, as specified in your fixture file. Parent classes won't work
|
||||
* @param string $identifier The identifier string, as provided in your fixture file
|
||||
* @return int
|
||||
* @return int|false
|
||||
*/
|
||||
public function getId($class, $identifier)
|
||||
{
|
||||
@ -162,9 +162,10 @@ class FixtureFactory
|
||||
/**
|
||||
* Get an object from the fixture.
|
||||
*
|
||||
* @param string $class The data class or table name, as specified in your fixture file. Parent classes won't work
|
||||
* @template T of DataObject
|
||||
* @param class-string<T> $class The data class or table name, as specified in your fixture file. Parent classes won't work
|
||||
* @param string $identifier The identifier string, as provided in your fixture file
|
||||
* @return DataObject
|
||||
* @return T|null
|
||||
*/
|
||||
public function get($class, $identifier)
|
||||
{
|
||||
|
@ -337,7 +337,6 @@ abstract class FunctionalTest extends SapphireTest implements TestOnly
|
||||
|
||||
$actuals = [];
|
||||
if ($items) {
|
||||
/** @var SimpleXMLElement $item */
|
||||
foreach ($items as $item) {
|
||||
$actuals[$item->asXML()] = true;
|
||||
}
|
||||
@ -371,7 +370,6 @@ abstract class FunctionalTest extends SapphireTest implements TestOnly
|
||||
|
||||
$actuals = [];
|
||||
if ($items) {
|
||||
/** @var SimpleXMLElement $item */
|
||||
foreach ($items as $item) {
|
||||
$actuals[] = $item->asXML();
|
||||
}
|
||||
|
@ -464,10 +464,11 @@ abstract class SapphireTest extends TestCase implements TestOnly
|
||||
/**
|
||||
* Get an object from the fixture.
|
||||
*
|
||||
* @param string $className The data class or table name, as specified in your fixture file. Parent classes won't work
|
||||
* @template T of DataObject
|
||||
* @param class-string<T> $className The data class or table name, as specified in your fixture file. Parent classes won't work
|
||||
* @param string $identifier The identifier string, as provided in your fixture file
|
||||
*
|
||||
* @return DataObject
|
||||
* @return T
|
||||
*/
|
||||
protected function objFromFixture($className, $identifier)
|
||||
{
|
||||
@ -563,7 +564,6 @@ abstract class SapphireTest extends TestCase implements TestOnly
|
||||
*/
|
||||
public function clearEmails()
|
||||
{
|
||||
/** @var MailerInterface $mailer */
|
||||
$mailer = Injector::inst()->get(MailerInterface::class);
|
||||
if ($mailer instanceof TestMailer) {
|
||||
$mailer->clearEmails();
|
||||
@ -584,7 +584,6 @@ abstract class SapphireTest extends TestCase implements TestOnly
|
||||
*/
|
||||
public static function findEmail($to, $from = null, $subject = null, $content = null)
|
||||
{
|
||||
/** @var MailerInterface $mailer */
|
||||
$mailer = Injector::inst()->get(MailerInterface::class);
|
||||
if ($mailer instanceof TestMailer) {
|
||||
return $mailer->findEmail($to, $from, $subject, $content);
|
||||
@ -1041,7 +1040,6 @@ abstract class SapphireTest extends TestCase implements TestOnly
|
||||
*/
|
||||
public function logOut()
|
||||
{
|
||||
/** @var IdentityStore $store */
|
||||
$store = Injector::inst()->get(IdentityStore::class);
|
||||
$store->logOut();
|
||||
}
|
||||
|
@ -175,7 +175,6 @@ class FixtureTestState implements TestState
|
||||
*/
|
||||
protected function loadFixture($fixtureFile, SapphireTest $test)
|
||||
{
|
||||
/** @var YamlFixture $fixture */
|
||||
$fixture = Injector::inst()->create(YamlFixture::class, $fixtureFile);
|
||||
$fixture->writeInto($this->getFixtureFactory(get_class($test)));
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ class LoggerState implements TestState
|
||||
{
|
||||
public function setUp(SapphireTest $test)
|
||||
{
|
||||
/** @var Logger $userLogger */
|
||||
$userLogger = Injector::inst()->get(LoggerInterface::class);
|
||||
if ($userLogger && $userLogger instanceof Logger) {
|
||||
$userLogger->setHandlers([new NullHandler()]);
|
||||
|
@ -72,7 +72,6 @@ class SapphireTestState implements TestState
|
||||
public function tearDown(SapphireTest $test)
|
||||
{
|
||||
// Tear down in reverse order
|
||||
/** @var TestState $state */
|
||||
foreach (array_reverse($this->states ?? []) as $state) {
|
||||
$state->tearDown($test);
|
||||
}
|
||||
@ -93,7 +92,6 @@ class SapphireTestState implements TestState
|
||||
public function tearDownOnce($class)
|
||||
{
|
||||
// Tear down in reverse order
|
||||
/** @var TestState $state */
|
||||
foreach (array_reverse($this->states ?? []) as $state) {
|
||||
$state->tearDownOnce($class);
|
||||
}
|
||||
|
@ -208,7 +208,6 @@ class TestSession
|
||||
*/
|
||||
public function submitForm(string $formID, string $button = null, array $data = [], bool $withSecurityToken = true): HTTPResponse
|
||||
{
|
||||
/** @var Crawler $page */
|
||||
$page = $this->lastPage();
|
||||
if ($page) {
|
||||
try {
|
||||
|
@ -9,6 +9,7 @@ use SilverStripe\ORM\DatabaseAdmin;
|
||||
/**
|
||||
* Hook up static validation to the deb/build process
|
||||
*
|
||||
* @extends Extension<DatabaseAdmin>
|
||||
*/
|
||||
class DatabaseAdminExtension extends Extension
|
||||
{
|
||||
|
@ -58,7 +58,7 @@ class CheckboxSetField extends MultiSelectField
|
||||
/**
|
||||
* Gets the list of options to render in this formfield
|
||||
*
|
||||
* @return ArrayList
|
||||
* @return ArrayList<ArrayData>
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
|
@ -76,7 +76,6 @@ class CompositeField extends FormField
|
||||
$children = $this->getChildren();
|
||||
if ($children && $children->count()) {
|
||||
$childSchema = [];
|
||||
/** @var FormField $child */
|
||||
foreach ($children as $child) {
|
||||
$childSchema[] = $child->getSchemaData();
|
||||
}
|
||||
@ -132,7 +131,6 @@ class CompositeField extends FormField
|
||||
$fieldList = $this->FieldList();
|
||||
$compositeTitle = '';
|
||||
$count = 0;
|
||||
/** @var FormField $subfield */
|
||||
foreach ($fieldList as $subfield) {
|
||||
$compositeTitle .= $subfield->getName();
|
||||
if ($subfield->getName()) {
|
||||
@ -415,7 +413,6 @@ class CompositeField extends FormField
|
||||
$clone = clone $this;
|
||||
if ($clone->getChildren()) {
|
||||
foreach ($clone->getChildren() as $child) {
|
||||
/** @var FormField $child */
|
||||
$child = $child->transform(new ReadonlyTransformation());
|
||||
$newChildren->push($child);
|
||||
}
|
||||
@ -441,7 +438,6 @@ class CompositeField extends FormField
|
||||
$clone = clone $this;
|
||||
if ($clone->getChildren()) {
|
||||
foreach ($clone->getChildren() as $child) {
|
||||
/** @var FormField $child */
|
||||
$child = $child->transform(new DisabledTransformation());
|
||||
$newChildren->push($child);
|
||||
}
|
||||
@ -482,7 +478,6 @@ class CompositeField extends FormField
|
||||
|
||||
$i = 0;
|
||||
foreach ($this->children as $child) {
|
||||
/** @var FormField $child */
|
||||
if ($child->getName() == $field->getName()) {
|
||||
return $i;
|
||||
}
|
||||
@ -540,7 +535,6 @@ class CompositeField extends FormField
|
||||
{
|
||||
$valid = true;
|
||||
foreach ($this->children as $child) {
|
||||
/** @var FormField $child */
|
||||
$valid = ($child && $child->validate($validator) && $valid);
|
||||
}
|
||||
return $this->extendValidationResult($valid, $validator);
|
||||
|
@ -30,22 +30,18 @@ use SilverStripe\ORM\ValidationResult;
|
||||
* {
|
||||
* $compositeValidator->addValidator(RequiredFields::create(['AdditionalContent']));
|
||||
* }
|
||||
*
|
||||
* Class CompositeValidator
|
||||
*
|
||||
* @package SilverStripe\Forms
|
||||
*/
|
||||
class CompositeValidator extends Validator
|
||||
{
|
||||
/**
|
||||
* @var array|Validator[]
|
||||
* @var array<Validator>
|
||||
*/
|
||||
private $validators;
|
||||
|
||||
/**
|
||||
* CompositeValidator constructor.
|
||||
*
|
||||
* @param array|Validator[] $validators
|
||||
* @param array<Validator> $validators
|
||||
*/
|
||||
public function __construct(array $validators = [])
|
||||
{
|
||||
@ -146,7 +142,7 @@ class CompositeValidator extends Validator
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|Validator[]
|
||||
* @return array<Validator>
|
||||
*/
|
||||
public function getValidators(): array
|
||||
{
|
||||
@ -159,8 +155,9 @@ class CompositeValidator extends Validator
|
||||
* The keys for the return array match the keys in the unfiltered array. You cannot assume the keys will be
|
||||
* sequential or that the first key will be ZERO.
|
||||
*
|
||||
* @param string $className
|
||||
* @return array|Validator[]
|
||||
* @template T of Validator
|
||||
* @param class-string<T> $className
|
||||
* @return T[]
|
||||
*/
|
||||
public function getValidatorsByType(string $className): array
|
||||
{
|
||||
|
@ -168,7 +168,6 @@ class ConfirmedPasswordField extends FormField
|
||||
|
||||
// disable auto complete
|
||||
foreach ($this->getChildren() as $child) {
|
||||
/** @var FormField $child */
|
||||
$child->setAttribute('autocomplete', 'off');
|
||||
}
|
||||
|
||||
@ -200,7 +199,6 @@ class ConfirmedPasswordField extends FormField
|
||||
// Build inner content
|
||||
$fieldContent = '';
|
||||
foreach ($this->getChildren() as $field) {
|
||||
/** @var FormField $field */
|
||||
$field->setDisabled($this->isDisabled());
|
||||
$field->setReadonly($this->isReadonly());
|
||||
|
||||
@ -321,7 +319,6 @@ class ConfirmedPasswordField extends FormField
|
||||
public function setRightTitle($title)
|
||||
{
|
||||
foreach ($this->getChildren() as $field) {
|
||||
/** @var FormField $field */
|
||||
$field->setRightTitle($title);
|
||||
}
|
||||
|
||||
@ -343,7 +340,6 @@ class ConfirmedPasswordField extends FormField
|
||||
if (is_array($titles) && count($titles ?? []) === $expectedChildren) {
|
||||
foreach ($this->getChildren() as $field) {
|
||||
if (isset($titles[0])) {
|
||||
/** @var FormField $field */
|
||||
$field->setTitle($titles[0]);
|
||||
|
||||
array_shift($titles);
|
||||
@ -613,7 +609,6 @@ class ConfirmedPasswordField extends FormField
|
||||
*/
|
||||
public function performReadonlyTransformation()
|
||||
{
|
||||
/** @var ReadonlyField $field */
|
||||
$field = $this->castedCopy(ReadonlyField::class)
|
||||
->setTitle($this->title ? $this->title : _t('SilverStripe\\Security\\Member.PASSWORD', 'Password'))
|
||||
->setValue('*****');
|
||||
|
@ -7,7 +7,7 @@ use SilverStripe\ORM\ArrayList;
|
||||
/**
|
||||
* A list designed to hold form field instances.
|
||||
*
|
||||
* @method FormField[] getIterator()
|
||||
* @extends ArrayList<FormField>
|
||||
*/
|
||||
class FieldList extends ArrayList
|
||||
{
|
||||
@ -65,7 +65,6 @@ class FieldList extends ArrayList
|
||||
{
|
||||
$stack = $this->toArray();
|
||||
while (!empty($stack)) {
|
||||
/** @var FormField $field */
|
||||
$field = array_shift($stack);
|
||||
$callback($field);
|
||||
if ($field instanceof CompositeField) {
|
||||
@ -399,7 +398,6 @@ class FieldList extends ArrayList
|
||||
$currentPointer = $this;
|
||||
|
||||
foreach ($parts as $k => $part) {
|
||||
/** @var FormField $currentPointer */
|
||||
$currentPointer = $currentPointer->fieldByName($part);
|
||||
}
|
||||
|
||||
@ -426,7 +424,6 @@ class FieldList extends ArrayList
|
||||
$currentPointer = $this;
|
||||
foreach ($parts as $k => $part) {
|
||||
$parentPointer = $currentPointer;
|
||||
/** @var FormField $currentPointer */
|
||||
$currentPointer = $currentPointer->fieldByName($part);
|
||||
// Create any missing tabs
|
||||
if (!$currentPointer) {
|
||||
|
@ -138,7 +138,6 @@ class FileField extends FormField implements FileHandleField
|
||||
File::get_file_extension($_FILES[$this->name]['name'])
|
||||
);
|
||||
|
||||
/** @var File $file */
|
||||
if ($this->relationAutoSetting) {
|
||||
// assume that the file is connected via a has-one
|
||||
$objectClass = DataObject::getSchema()->hasOneComponent(get_class($record), $this->name);
|
||||
|
@ -1372,7 +1372,6 @@ class Form extends ViewableData implements HasRequestHandler
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @var FormField $field */
|
||||
foreach ($dataFields as $field) {
|
||||
$name = $field->getName();
|
||||
|
||||
@ -1533,7 +1532,6 @@ class Form extends ViewableData implements HasRequestHandler
|
||||
$data = [];
|
||||
|
||||
if ($dataFields) {
|
||||
/** @var FormField $field */
|
||||
foreach ($dataFields as $field) {
|
||||
if ($field->getName()) {
|
||||
$data[$field->getName()] = $field->dataValue();
|
||||
|
@ -1352,9 +1352,10 @@ class FormField extends RequestHandler
|
||||
*
|
||||
* Does not copy custom field templates, since they probably won't apply to the new instance.
|
||||
*
|
||||
* @param mixed $classOrCopy Class name for copy, or existing copy instance to update
|
||||
* @template T
|
||||
* @param class-string<T>|T $classOrCopy Class name for copy, or existing copy instance to update
|
||||
*
|
||||
* @return FormField
|
||||
* @return T
|
||||
*/
|
||||
public function castedCopy($classOrCopy)
|
||||
{
|
||||
@ -1397,7 +1398,7 @@ class FormField extends RequestHandler
|
||||
* Sets the component type the FormField will be rendered as on the front-end.
|
||||
*
|
||||
* @param string $componentType
|
||||
* @return FormField
|
||||
* @return static
|
||||
*/
|
||||
public function setSchemaComponent($componentType)
|
||||
{
|
||||
@ -1422,7 +1423,7 @@ class FormField extends RequestHandler
|
||||
* If you want to pass around ad hoc data use the `data` array e.g. pass `['data' => ['myCustomKey' => 'yolo']]`.
|
||||
*
|
||||
* @param array $schemaData - The data to be merged with $this->schemaData.
|
||||
* @return FormField
|
||||
* @return static
|
||||
*/
|
||||
public function setSchemaData($schemaData = [])
|
||||
{
|
||||
@ -1494,7 +1495,7 @@ class FormField extends RequestHandler
|
||||
* If you want to pass around ad hoc data use the `data` array e.g. pass `['data' => ['myCustomKey' => 'yolo']]`.
|
||||
*
|
||||
* @param array $schemaState The data to be merged with $this->schemaData.
|
||||
* @return FormField
|
||||
* @return static
|
||||
*/
|
||||
public function setSchemaState($schemaState = [])
|
||||
{
|
||||
|
@ -335,7 +335,7 @@ class GridField extends FormField
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayList
|
||||
* @return ArrayList<GridFieldComponent>
|
||||
*/
|
||||
public function getComponents()
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ class GridFieldConfig
|
||||
use Configurable;
|
||||
|
||||
/**
|
||||
* @var ArrayList
|
||||
* @var ArrayList<GridFieldComponent>
|
||||
*/
|
||||
protected $components = null;
|
||||
|
||||
@ -111,7 +111,7 @@ class GridFieldConfig
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayList Of GridFieldComponent
|
||||
* @return ArrayList<GridFieldComponent>
|
||||
*/
|
||||
public function getComponents()
|
||||
{
|
||||
@ -124,8 +124,9 @@ class GridFieldConfig
|
||||
/**
|
||||
* Returns all components extending a certain class, or implementing a certain interface.
|
||||
*
|
||||
* @param string $type Class name or interface
|
||||
* @return ArrayList Of GridFieldComponent
|
||||
* @template T of GridFieldComponent
|
||||
* @param class-string<T> $type Class name or interface
|
||||
* @return ArrayList<T>
|
||||
*/
|
||||
public function getComponentsByType($type)
|
||||
{
|
||||
@ -141,8 +142,9 @@ class GridFieldConfig
|
||||
/**
|
||||
* Returns the first available component with the given class or interface.
|
||||
*
|
||||
* @param string $type ClassName
|
||||
* @return GridFieldComponent
|
||||
* @template T of GridFieldComponent
|
||||
* @param class-string<T> $type ClassName
|
||||
* @return T|null
|
||||
*/
|
||||
public function getComponentByType($type)
|
||||
{
|
||||
|
@ -340,7 +340,6 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
||||
$previousAndNextGroup->addExtraClass('btn-group--circular mr-2');
|
||||
$previousAndNextGroup->setFieldHolderTemplate(CompositeField::class . '_holder_buttongroup');
|
||||
|
||||
/** @var GridFieldDetailForm $component */
|
||||
$component = $this->gridField->getConfig()->getComponentByType(GridFieldDetailForm::class);
|
||||
$paginator = $this->getGridField()->getConfig()->getComponentByType(GridFieldPaginator::class);
|
||||
$gridState = $this->getGridField()->getState();
|
||||
@ -902,7 +901,7 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
||||
* see {@link LeftAndMain->Breadcrumbs()} for details.
|
||||
*
|
||||
* @param boolean $unlinked
|
||||
* @return ArrayList
|
||||
* @return ArrayList<ArrayData>
|
||||
*/
|
||||
public function Breadcrumbs($unlinked = false)
|
||||
{
|
||||
@ -910,7 +909,7 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var ArrayList $items */
|
||||
/** @var ArrayList<ArrayData> $items */
|
||||
$items = $this->popupController->Breadcrumbs($unlinked);
|
||||
|
||||
if (!$items) {
|
||||
|
@ -150,7 +150,6 @@ class GridFieldExportButton extends AbstractGridFieldComponent implements GridFi
|
||||
return $this->exportColumns;
|
||||
}
|
||||
|
||||
/** @var GridFieldDataColumns $dataCols */
|
||||
$dataCols = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class);
|
||||
if ($dataCols) {
|
||||
return $dataCols->getDisplayFields($gridField);
|
||||
@ -224,17 +223,15 @@ class GridFieldExportButton extends AbstractGridFieldComponent implements GridFi
|
||||
}
|
||||
}
|
||||
|
||||
/** @var GridFieldDataColumns|null $gridFieldColumnsComponent */
|
||||
$gridFieldColumnsComponent = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class);
|
||||
$columnsHandled = ($gridFieldColumnsComponent)
|
||||
? $gridFieldColumnsComponent->getColumnsHandled($gridField)
|
||||
: [];
|
||||
|
||||
/** @var ArrayList|DataList $items */
|
||||
/** @var SS_List<ViewableData> $items */
|
||||
// Remove limit as the list may be paginated, we want the full list for the export
|
||||
$items = $items->limit(null);
|
||||
|
||||
/** @var ViewableData $item */
|
||||
foreach ($items as $item) {
|
||||
// Assume item can be viewed if canView() isn't implemented
|
||||
if (!$item->hasMethod('canView') || $item->canView()) {
|
||||
|
@ -185,7 +185,6 @@ class GridFieldFilterHeader extends AbstractGridFieldComponent implements GridFi
|
||||
return $dataList;
|
||||
}
|
||||
|
||||
/** @var Filterable $dataList */
|
||||
/** @var array $filterArguments */
|
||||
$filterArguments = $this->getState($gridField)->Columns->toArray();
|
||||
if (empty($filterArguments)) {
|
||||
|
@ -46,7 +46,6 @@ class GridFieldPageCount extends AbstractGridFieldComponent implements GridField
|
||||
*/
|
||||
protected function getPaginator($gridField)
|
||||
{
|
||||
/** @var GridFieldPaginator $paginator */
|
||||
$paginator = $gridField->getConfig()->getComponentByType(GridFieldPaginator::class);
|
||||
|
||||
if (!$paginator && GridFieldPageCount::config()->uninherited('require_paginator')) {
|
||||
|
@ -156,7 +156,6 @@ class GridFieldPrintButton extends AbstractGridFieldComponent implements GridFie
|
||||
return $this->printColumns;
|
||||
}
|
||||
|
||||
/** @var GridFieldDataColumns $dataCols */
|
||||
$dataCols = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class);
|
||||
if ($dataCols) {
|
||||
return $dataCols->getDisplayFields($gridField);
|
||||
@ -232,7 +231,6 @@ class GridFieldPrintButton extends AbstractGridFieldComponent implements GridFie
|
||||
$items = $gridField->getManipulatedList();
|
||||
$itemRows = new ArrayList();
|
||||
|
||||
/** @var GridFieldDataColumns $gridFieldColumnsComponent */
|
||||
$gridFieldColumnsComponent = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class);
|
||||
|
||||
/** @var ViewableData $item */
|
||||
|
@ -124,7 +124,6 @@ class GridFieldSortableHeader extends AbstractGridFieldComponent implements Grid
|
||||
if (!$this->checkDataType($list)) {
|
||||
return null;
|
||||
}
|
||||
/** @var Sortable $list */
|
||||
$forTemplate = new ArrayData([]);
|
||||
$forTemplate->Fields = new ArrayList;
|
||||
|
||||
@ -247,7 +246,7 @@ class GridFieldSortableHeader extends AbstractGridFieldComponent implements Grid
|
||||
* {@link DataQuery} first.
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @param SS_List $dataList
|
||||
* @param SS_List&Sortable $dataList
|
||||
* @return SS_List
|
||||
*/
|
||||
public function getManipulatedData(GridField $gridField, SS_List $dataList)
|
||||
@ -256,14 +255,12 @@ class GridFieldSortableHeader extends AbstractGridFieldComponent implements Grid
|
||||
return $dataList;
|
||||
}
|
||||
|
||||
/** @var Sortable $dataList */
|
||||
$state = $this->getState($gridField);
|
||||
if ($state->SortColumn == "") {
|
||||
return $dataList;
|
||||
}
|
||||
|
||||
// Prevent SQL Injection by validating that SortColumn exists
|
||||
/** @var GridFieldDataColumns $columns */
|
||||
$columns = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class);
|
||||
$fields = $columns->getDisplayFields($gridField);
|
||||
if (!array_key_exists($state->SortColumn, $fields) &&
|
||||
|
@ -819,7 +819,6 @@ class TinyMCEConfig extends HTMLEditorConfig implements i18nEntityProvider
|
||||
*/
|
||||
public function getScriptURL()
|
||||
{
|
||||
/** @var TinyMCEScriptGenerator $generator */
|
||||
$generator = Injector::inst()->get(TinyMCEScriptGenerator::class);
|
||||
return $generator->getScriptURL($this);
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ class ListboxField extends MultiSelectField
|
||||
/**
|
||||
* Gets the list of options to render in this formfield
|
||||
*
|
||||
* @return ArrayList
|
||||
* @return ArrayList<ArrayData>
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
|
@ -103,12 +103,10 @@ class FormSchema
|
||||
'actions' => []
|
||||
];
|
||||
|
||||
/** @var FormField $action */
|
||||
foreach ($form->Actions() as $action) {
|
||||
$schema['actions'][] = $action->getSchemaData();
|
||||
}
|
||||
|
||||
/** @var FormField $field */
|
||||
foreach ($form->Fields() as $field) {
|
||||
$schema['fields'][] = $field->getSchemaData();
|
||||
}
|
||||
@ -197,10 +195,12 @@ class FormSchema
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param iterable<FormField> $fields
|
||||
*/
|
||||
protected function getFieldStates($fields)
|
||||
{
|
||||
$states = [];
|
||||
/** @var FormField $field */
|
||||
foreach ($fields as $field) {
|
||||
$states[] = $field->getSchemaState();
|
||||
|
||||
|
@ -177,6 +177,8 @@ trait SearchableDropdownTrait
|
||||
* If a search context has been set via setSearchContext() that will be used
|
||||
* Will fallback to using the dataobjects default search context if a sourceList has been set
|
||||
* Otherwise will return null
|
||||
*
|
||||
* @return SearchContext<DataObject>|null
|
||||
*/
|
||||
public function getSearchContext(): ?SearchContext
|
||||
{
|
||||
@ -368,7 +370,6 @@ trait SearchableDropdownTrait
|
||||
// Don't know what value is, handle gracefully. We should not raise an exception here because
|
||||
// of there is a bad data for whatever a content editor will not be able to resolve and it will
|
||||
// render part of the CMS unusable
|
||||
// /** @var LoggerInterface $logger */
|
||||
$logger = Injector::inst()->get(LoggerInterface::class);
|
||||
$logger->warning('Could not determine value in ' . __CLASS__ . '::getValueArray()');
|
||||
return [];
|
||||
@ -399,7 +400,7 @@ trait SearchableDropdownTrait
|
||||
if (!$record->hasMethod($name)) {
|
||||
throw new LogicException("Relation $name does not exist");
|
||||
}
|
||||
/** @var Relation $relation */
|
||||
/** @var Relation $relationList */
|
||||
$relationList = $record->$name();
|
||||
// Use RelationList rather than Relation here since some Relation classes don't allow setting value
|
||||
// but RelationList does
|
||||
@ -542,9 +543,9 @@ trait SearchableDropdownTrait
|
||||
}
|
||||
|
||||
/**
|
||||
* @var ArrayList $options The options list being updated that will become <options>
|
||||
* @var DataList|ArrayList $items The items to be turned into options
|
||||
* @var DataList|ArrayList $values The values that have been selected i.e. the value of the Field
|
||||
* @param ArrayList $options The options list being updated that will become <options>
|
||||
* @param DataList|ArrayList $items The items to be turned into options
|
||||
* @param DataList|ArrayList $values The values that have been selected i.e. the value of the Field
|
||||
*/
|
||||
private function updateOptionsForSchema(
|
||||
ArrayList $options,
|
||||
|
@ -240,8 +240,7 @@ abstract class SelectField extends FormField
|
||||
|
||||
public function performReadonlyTransformation()
|
||||
{
|
||||
/** @var LookupField $field */
|
||||
$field = $this->castedCopy('SilverStripe\\Forms\\LookupField');
|
||||
$field = $this->castedCopy(LookupField::class);
|
||||
$field->setSource($this->getSource());
|
||||
$field->setReadonly(true);
|
||||
|
||||
@ -255,14 +254,6 @@ abstract class SelectField extends FormField
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns another instance of this field, but "cast" to a different class.
|
||||
*
|
||||
* @see FormField::castedCopy()
|
||||
*
|
||||
* @param string $classOrCopy
|
||||
* @return FormField
|
||||
*/
|
||||
public function castedCopy($classOrCopy)
|
||||
{
|
||||
$field = parent::castedCopy($classOrCopy);
|
||||
|
@ -175,7 +175,6 @@ abstract class SingleSelectField extends SelectField
|
||||
*/
|
||||
public function performReadonlyTransformation()
|
||||
{
|
||||
/** @var SingleLookupField $field */
|
||||
$field = $this->castedCopy(SingleLookupField::class);
|
||||
$field->setSource($this->getSource());
|
||||
$field->setReadonly(true);
|
||||
|
@ -372,7 +372,6 @@ class TimeField extends TextField
|
||||
*/
|
||||
public function performReadonlyTransformation()
|
||||
{
|
||||
/** @var TimeField_Readonly $result */
|
||||
$result = $this->castedCopy(TimeField_Readonly::class);
|
||||
$result
|
||||
->setValue(false)
|
||||
|
@ -458,7 +458,6 @@ class TreeDropdownField extends FormField
|
||||
$this->populateIDs();
|
||||
}
|
||||
|
||||
/** @var DataObject|Hierarchy $obj */
|
||||
$obj = null;
|
||||
$sourceObject = $this->getSourceObject();
|
||||
|
||||
@ -837,7 +836,6 @@ class TreeDropdownField extends FormField
|
||||
*/
|
||||
public function performReadonlyTransformation()
|
||||
{
|
||||
/** @var TreeDropdownField_Readonly $copy */
|
||||
$copy = $this->castedCopy(TreeDropdownField_Readonly::class);
|
||||
$copy->setKeyField($this->getKeyField());
|
||||
$copy->setLabelField($this->getLabelField());
|
||||
@ -846,10 +844,6 @@ class TreeDropdownField extends FormField
|
||||
return $copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|FormField $classOrCopy
|
||||
* @return FormField
|
||||
*/
|
||||
public function castedCopy($classOrCopy)
|
||||
{
|
||||
$field = $classOrCopy;
|
||||
|
@ -281,7 +281,6 @@ class TreeMultiselectField extends TreeDropdownField
|
||||
*/
|
||||
public function performReadonlyTransformation()
|
||||
{
|
||||
/** @var TreeMultiselectField_Readonly $copy */
|
||||
$copy = $this->castedCopy(TreeMultiselectField_Readonly::class);
|
||||
$copy->setKeyField($this->getKeyField());
|
||||
$copy->setLabelField($this->getLabelField());
|
||||
|
@ -29,6 +29,12 @@ use Traversable;
|
||||
* - sort
|
||||
* - filter
|
||||
* - exclude
|
||||
*
|
||||
* @template T
|
||||
* @implements SS_List<T>
|
||||
* @implements Filterable<T>
|
||||
* @implements Sortable<T>
|
||||
* @implements Limitable<T>
|
||||
*/
|
||||
class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, Limitable
|
||||
{
|
||||
@ -45,13 +51,12 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
/**
|
||||
* Holds the items in the list
|
||||
*
|
||||
* @var array
|
||||
* @var array<array-key, T>
|
||||
*/
|
||||
protected $items = [];
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $items - an initial array to fill this object with
|
||||
* @param array<array-key, T> $items - an initial array to fill this object with
|
||||
*/
|
||||
public function __construct(array $items = [])
|
||||
{
|
||||
@ -62,14 +67,14 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
/**
|
||||
* Underlying type class for this list
|
||||
*
|
||||
* @var string
|
||||
* @var class-string<T>|null
|
||||
*/
|
||||
protected $dataClass = null;
|
||||
|
||||
/**
|
||||
* Return the class of items in this list, by looking at the first item inside it.
|
||||
*
|
||||
* @return string
|
||||
* @return class-string<T>|null
|
||||
*/
|
||||
public function dataClass()
|
||||
{
|
||||
@ -85,7 +90,7 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
/**
|
||||
* Hint this list to a specific type
|
||||
*
|
||||
* @param string $class
|
||||
* @param class-string<T> $class
|
||||
* @return $this
|
||||
*/
|
||||
public function setDataClass($class)
|
||||
@ -116,6 +121,8 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
/**
|
||||
* Returns an Iterator for this ArrayList.
|
||||
* This function allows you to use ArrayList in foreach loops
|
||||
*
|
||||
* @return Traversable<T>
|
||||
*/
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
@ -130,8 +137,6 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
|
||||
/**
|
||||
* Return an array of the actual items that this ArrayList contains.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
@ -164,8 +169,6 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
|
||||
/**
|
||||
* Return this list as an array and every object it as an sub array as well
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toNestedArray()
|
||||
{
|
||||
@ -263,7 +266,7 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
* Merges with another array or list by pushing all the items in it onto the
|
||||
* end of this list.
|
||||
*
|
||||
* @param array|object $with
|
||||
* @param iterable $with
|
||||
*/
|
||||
public function merge($with)
|
||||
{
|
||||
@ -342,11 +345,6 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
return array_shift($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first item in the list
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
if (empty($this->items)) {
|
||||
@ -356,11 +354,6 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
return reset($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last item in the list
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function last()
|
||||
{
|
||||
if (empty($this->items)) {
|
||||
@ -425,7 +418,7 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
/**
|
||||
* Reverses an {@link ArrayList}
|
||||
*
|
||||
* @return ArrayList
|
||||
* @return static<T>
|
||||
*/
|
||||
public function reverse()
|
||||
{
|
||||
@ -479,7 +472,6 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
*
|
||||
* Note that columns may be double quoted as per ANSI sql standard
|
||||
*
|
||||
* @return static
|
||||
* @see SS_List::sort()
|
||||
* @example $list->sort('Name'); // default ASC sorting
|
||||
* @example $list->sort('Name DESC'); // DESC sorting
|
||||
@ -596,8 +588,7 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
* Find the first item of this list where the given key = value
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @return mixed
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function find($key, $value)
|
||||
{
|
||||
@ -607,7 +598,6 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
/**
|
||||
* Filter the list to include items with these characteristics
|
||||
*
|
||||
* @return ArrayList
|
||||
* @see Filterable::filter()
|
||||
* @example $list->filter('Name', 'bob'); // only bob in the list
|
||||
* @example $list->filter('Name', array('aziz', 'bob'); // aziz and bob in list
|
||||
@ -645,7 +635,6 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
* $list = $list->filterAny('Name:PartialMatch', 'sam');
|
||||
*
|
||||
* @param string|array See {@link filter()}
|
||||
* @return static
|
||||
*/
|
||||
public function filterAny()
|
||||
{
|
||||
@ -656,7 +645,6 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
/**
|
||||
* Exclude the list to not contain items with these characteristics
|
||||
*
|
||||
* @return ArrayList
|
||||
* @see SS_List::exclude()
|
||||
* @example $list->exclude('Name', 'bob'); // exclude bob from list
|
||||
* @example $list->exclude('Name', array('aziz', 'bob'); // exclude aziz and bob from list
|
||||
@ -694,6 +682,7 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
* $list = $list->excludeAny('Name:PartialMatch', 'sam');
|
||||
*
|
||||
* @param string|array See {@link filter()}
|
||||
* @return static<T>
|
||||
*/
|
||||
public function excludeAny(): static
|
||||
{
|
||||
@ -703,6 +692,7 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
|
||||
/**
|
||||
* Apply the appropriate filtering or excluding
|
||||
* @return static<T>
|
||||
*/
|
||||
protected function filterOrExclude(array $filters, bool $inclusive = true, bool $any = false): static
|
||||
{
|
||||
@ -740,7 +730,6 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
foreach ($this->items as $item) {
|
||||
$matches = [];
|
||||
foreach ($filters as $filterKey => $filterValue) {
|
||||
/** @var SearchFilter $searchFilter */
|
||||
$searchFilter = $searchFilters[$filterKey];
|
||||
$extractedValue = $this->extractValue($item, $searchFilter->getFullName());
|
||||
$hasMatch = null;
|
||||
@ -840,7 +829,6 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
* Filter this list to only contain the given Primary IDs
|
||||
*
|
||||
* @param array $ids Array of integers, will be automatically cast/escaped.
|
||||
* @return ArrayList
|
||||
*/
|
||||
public function byIDs($ids)
|
||||
{
|
||||
@ -864,7 +852,7 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
*
|
||||
* @example $list = $list->filterByCallback(function($item, $list) { return $item->Age == 9; })
|
||||
* @param callable $callback
|
||||
* @return ArrayList
|
||||
* @return static<T>
|
||||
*/
|
||||
public function filterByCallback($callback)
|
||||
{
|
||||
@ -901,6 +889,7 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L
|
||||
|
||||
/**
|
||||
* Returns item stored in list with index $key
|
||||
* @return T|null
|
||||
*/
|
||||
public function offsetGet(mixed $offset): mixed
|
||||
{
|
||||
|
@ -167,8 +167,6 @@ abstract class DBSchemaManager
|
||||
// Clear update list for client code to mess around with
|
||||
$this->schemaUpdateTransaction = [];
|
||||
|
||||
/** @var Exception $error */
|
||||
$error = null;
|
||||
try {
|
||||
// Yield control to client code
|
||||
$callback();
|
||||
@ -425,7 +423,6 @@ abstract class DBSchemaManager
|
||||
$fieldObj->setTable($table);
|
||||
|
||||
if ($fieldObj instanceof DBPrimaryKey) {
|
||||
/** @var DBPrimaryKey $fieldObj */
|
||||
$fieldObj->setAutoIncrement($hasAutoIncPK);
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,6 @@ class MySQLDatabase extends Database implements TransactionManager
|
||||
$queryParameters = [];
|
||||
$totalCount = 0;
|
||||
foreach ($lists as $class => $list) {
|
||||
/** @var SQLSelect $query */
|
||||
$query = $list->dataQuery()->query();
|
||||
|
||||
// There's no need to do all that joining
|
||||
|
@ -198,7 +198,6 @@ class DB
|
||||
if (!Injector::inst()->has(HTTPRequest::class)) {
|
||||
return;
|
||||
}
|
||||
/** @var HTTPRequest $request */
|
||||
$request = Injector::inst()->get(HTTPRequest::class);
|
||||
if ($name) {
|
||||
$request->getSession()->set(self::ALT_DB_KEY, $name);
|
||||
@ -226,7 +225,6 @@ class DB
|
||||
if (!Injector::inst()->has(HTTPRequest::class)) {
|
||||
return null;
|
||||
}
|
||||
/** @var HTTPRequest $request */
|
||||
$request = Injector::inst()->get(HTTPRequest::class);
|
||||
// Skip if the session hasn't been started
|
||||
if (!$request->getSession()->isStarted()) {
|
||||
|
@ -13,7 +13,8 @@ use Exception;
|
||||
/**
|
||||
* An extension that adds additional functionality to a {@link DataObject}.
|
||||
*
|
||||
* @property DataObject $owner
|
||||
* @template T of DataObject
|
||||
* @extends Extension<T>
|
||||
*/
|
||||
abstract class DataExtension extends Extension
|
||||
{
|
||||
|
@ -35,6 +35,12 @@ use SilverStripe\ORM\Filters\SearchFilterable;
|
||||
* - removeAll
|
||||
*
|
||||
* Subclasses of DataList may add other methods that have the same effect.
|
||||
*
|
||||
* @template T of DataObject
|
||||
* @implements SS_List<T>
|
||||
* @implements Filterable<T>
|
||||
* @implements Sortable<T>
|
||||
* @implements Limitable<T>
|
||||
*/
|
||||
class DataList extends ViewableData implements SS_List, Filterable, Sortable, Limitable
|
||||
{
|
||||
@ -49,7 +55,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
/**
|
||||
* The DataObject class name that this data list is querying
|
||||
*
|
||||
* @var string
|
||||
* @var class-string<T>
|
||||
*/
|
||||
protected $dataClass;
|
||||
|
||||
@ -63,7 +69,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
/**
|
||||
* A cached Query to save repeated database calls. {@see DataList::getTemplateIteratorCount()}
|
||||
*
|
||||
* @var SilverStripe\ORM\Connect\Query
|
||||
* @var Query
|
||||
*/
|
||||
protected $finalisedQuery;
|
||||
|
||||
@ -89,7 +95,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* Create a new DataList.
|
||||
* No querying is done on construction, but the initial query schema is set up.
|
||||
*
|
||||
* @param string $dataClass - The DataObject class to query.
|
||||
* @param class-string<T> $dataClass - The DataObject class to query.
|
||||
*/
|
||||
public function __construct($dataClass)
|
||||
{
|
||||
@ -102,7 +108,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
/**
|
||||
* Get the dataClass name for this DataList, ie the DataObject ClassName
|
||||
*
|
||||
* @return string
|
||||
* @return class-string<T>
|
||||
*/
|
||||
public function dataClass()
|
||||
{
|
||||
@ -150,7 +156,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* alterDataQuery
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return static
|
||||
* @return static<T>
|
||||
* @throws Exception
|
||||
*/
|
||||
public function alterDataQuery($callback)
|
||||
@ -187,7 +193,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* Return a new DataList instance with the underlying {@link DataQuery} object changed
|
||||
*
|
||||
* @param DataQuery $dataQuery
|
||||
* @return static
|
||||
* @return static<T>
|
||||
*/
|
||||
public function setDataQuery(DataQuery $dataQuery)
|
||||
{
|
||||
@ -201,7 +207,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
*
|
||||
* @param string|array $keyOrArray Either the single key to set, or an array of key value pairs to set
|
||||
* @param mixed $val If $keyOrArray is not an array, this is the value to set
|
||||
* @return static
|
||||
* @return static<T>
|
||||
*/
|
||||
public function setDataQueryParam($keyOrArray, $val = null)
|
||||
{
|
||||
@ -242,7 +248,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
*
|
||||
* @param string|array|SQLConditionGroup $filter Predicate(s) to set, as escaped SQL statements or
|
||||
* paramaterised queries
|
||||
* @return static
|
||||
* @return static<T>
|
||||
*/
|
||||
public function where($filter)
|
||||
{
|
||||
@ -264,7 +270,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
*
|
||||
* @param string|array|SQLConditionGroup $filter Predicate(s) to set, as escaped SQL statements or
|
||||
* paramaterised queries
|
||||
* @return static
|
||||
* @return static<T>
|
||||
*/
|
||||
public function whereAny($filter)
|
||||
{
|
||||
@ -336,7 +342,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* Return a new DataList instance with distinct records or not
|
||||
*
|
||||
* @param bool $value
|
||||
* @return static
|
||||
* @return static<T>
|
||||
*/
|
||||
public function distinct($value)
|
||||
{
|
||||
@ -446,6 +452,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
*
|
||||
* This method accepts raw SQL so could be vulnerable to SQL injection attacks if used incorrectly,
|
||||
* it's preferable to use sort() instead which does not allow raw SQL
|
||||
* @return static<T>
|
||||
*/
|
||||
public function orderBy(string $orderBy): static
|
||||
{
|
||||
@ -473,7 +480,6 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* ->filter('Field:not', null) will generate '"Field" IS NOT NULL'
|
||||
*
|
||||
* @param string|array Escaped SQL statement. If passed as array, all keys and values will be escaped internally
|
||||
* @return $this
|
||||
*/
|
||||
public function filter()
|
||||
{
|
||||
@ -499,7 +505,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* Return a new instance of the list with an added filter
|
||||
*
|
||||
* @param array $filterArray
|
||||
* @return $this
|
||||
* @return static<T>
|
||||
*/
|
||||
public function addFilter($filterArray)
|
||||
{
|
||||
@ -535,7 +541,6 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* // SQL: WHERE (("Name" IN ('bob', 'phil')) OR ("Age" IN ('21', '43'))
|
||||
*
|
||||
* @param string|array See {@link filter()}
|
||||
* @return static
|
||||
*/
|
||||
public function filterAny()
|
||||
{
|
||||
@ -580,7 +585,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
*
|
||||
* @example $list = $list->filterByCallback(function($item, $list) { return $item->Age == 9; })
|
||||
* @param callable $callback
|
||||
* @return ArrayList (this may change in future implementations)
|
||||
* @return ArrayList<T>
|
||||
*/
|
||||
public function filterByCallback($callback)
|
||||
{
|
||||
@ -590,7 +595,6 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
gettype($callback)
|
||||
));
|
||||
}
|
||||
/** @var ArrayList $output */
|
||||
$output = ArrayList::create();
|
||||
foreach ($this as $item) {
|
||||
if (call_user_func($callback, $item, $this)) {
|
||||
@ -620,7 +624,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* @param string $columnName Quoted column name (by reference)
|
||||
* @param bool $linearOnly Set to true to restrict to linear relations only. Set this
|
||||
* if this relation will be used for sorting, and should not include duplicate rows.
|
||||
* @return $this DataList with this relation applied
|
||||
* @return static<T> DataList with this relation applied
|
||||
*/
|
||||
public function applyRelation($field, &$columnName = null, $linearOnly = false)
|
||||
{
|
||||
@ -677,8 +681,6 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
*
|
||||
* @param string|array
|
||||
* @param string [optional]
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function exclude()
|
||||
{
|
||||
@ -718,7 +720,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* @param string|array
|
||||
* @param string [optional]
|
||||
*
|
||||
* @return $this
|
||||
* @return static<T>
|
||||
*/
|
||||
public function excludeAny()
|
||||
{
|
||||
@ -747,8 +749,8 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
*
|
||||
* The $list passed needs to contain the same dataclass as $this
|
||||
*
|
||||
* @param DataList $list
|
||||
* @return static
|
||||
* @param DataList<DataObject> $list
|
||||
* @return static<T>
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function subtract(DataList $list)
|
||||
@ -772,7 +774,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* will cause the query to appear first. The default is 20, and joins created automatically by the
|
||||
* ORM have a value of 10.
|
||||
* @param array $parameters Any additional parameters if the join is a parameterised subquery
|
||||
* @return static
|
||||
* @return static<T>
|
||||
*/
|
||||
public function innerJoin($table, $onClause, $alias = null, $order = 20, $parameters = [])
|
||||
{
|
||||
@ -791,7 +793,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* will cause the query to appear first. The default is 20, and joins created automatically by the
|
||||
* ORM have a value of 10.
|
||||
* @param array $parameters Any additional parameters if the join is a parameterised subquery
|
||||
* @return static
|
||||
* @return static<T>
|
||||
*/
|
||||
public function leftJoin($table, $onClause, $alias = null, $order = 20, $parameters = [])
|
||||
{
|
||||
@ -810,7 +812,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* will cause the query to appear first. The default is 20, and joins created automatically by the
|
||||
* ORM have a value of 10.
|
||||
* @param array $parameters Any additional parameters if the join is a parameterised subquery
|
||||
* @return static
|
||||
* @return static<T>
|
||||
*/
|
||||
public function rightJoin($table, $onClause, $alias = null, $order = 20, $parameters = [])
|
||||
{
|
||||
@ -822,8 +824,6 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
/**
|
||||
* Return an array of the actual items that this DataList contains at this stage.
|
||||
* This is when the query is actually executed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
@ -852,12 +852,6 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks the list using the specified callback
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function each($callback)
|
||||
{
|
||||
foreach ($this as $row) {
|
||||
@ -894,7 +888,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* If called without $row['ID'] set, then a new object will be created rather than rehydrated.
|
||||
*
|
||||
* @param array $row
|
||||
* @return DataObject
|
||||
* @return T
|
||||
*/
|
||||
public function createDataObject($row)
|
||||
{
|
||||
@ -946,6 +940,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
/**
|
||||
* Returns an Iterator for this DataList.
|
||||
* This function allows you to use DataLists in foreach loops
|
||||
* @return Traversable<T>
|
||||
*/
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
@ -1048,10 +1043,10 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
foreach ($this->eagerLoadRelationChains as $relationChain) {
|
||||
$parentDataClass = $this->dataClass();
|
||||
$parentIDs = $topLevelIDs;
|
||||
/** @var Query|array<DataObject|EagerLoadedList> */
|
||||
$parentRelationData = $query;
|
||||
$chainToDate = [];
|
||||
foreach (explode('.', $relationChain) as $relationName) {
|
||||
/** @var Query|array<DataObject|EagerLoadedList> $parentRelationData */
|
||||
$chainToDate[] = $relationName;
|
||||
list(
|
||||
$relationDataClass,
|
||||
@ -1457,6 +1452,8 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
*
|
||||
* IMPORTANT: Calling eagerLoad() will cause any relations on DataObjects to be returned as an EagerLoadedList
|
||||
* instead of a subclass of DataList such as HasManyList i.e. MyDataObject->MyHasManyRelation() returns an EagerLoadedList
|
||||
*
|
||||
* @return static<T>
|
||||
*/
|
||||
public function eagerLoad(...$relationChains): static
|
||||
{
|
||||
@ -1548,11 +1545,9 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
|
||||
|
||||
/**
|
||||
* Returns the first item in this DataList (instanceof DataObject)
|
||||
* Returns the first item in this DataList
|
||||
*
|
||||
* The object returned is not cached, unlike {@link DataObject::get_one()}
|
||||
*
|
||||
* @return DataObject|null
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
@ -1568,11 +1563,9 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last item in this DataList (instanceof DataObject)
|
||||
* Returns the last item in this DataList
|
||||
*
|
||||
* The object returned is not cached, unlike {@link DataObject::get_one()}
|
||||
*
|
||||
* @return DataObject|null
|
||||
*/
|
||||
public function last()
|
||||
{
|
||||
@ -1605,7 +1598,6 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @return DataObject|null
|
||||
*/
|
||||
public function find($key, $value)
|
||||
{
|
||||
@ -1616,7 +1608,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* Restrict the columns to fetch into this DataList
|
||||
*
|
||||
* @param array $queriedColumns
|
||||
* @return static
|
||||
* @return static<T>
|
||||
*/
|
||||
public function setQueriedColumns($queriedColumns)
|
||||
{
|
||||
@ -1625,12 +1617,6 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter this list to only contain the given Primary IDs
|
||||
*
|
||||
* @param array $ids Array of integers
|
||||
* @return $this
|
||||
*/
|
||||
public function byIDs($ids)
|
||||
{
|
||||
return $this->filter('ID', $ids);
|
||||
@ -1640,9 +1626,6 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* Return the first DataObject with the given ID
|
||||
*
|
||||
* The object returned is not cached, unlike {@link DataObject::get_by_id()}
|
||||
*
|
||||
* @param int $id
|
||||
* @return DataObject|null
|
||||
*/
|
||||
public function byID($id)
|
||||
{
|
||||
@ -1683,7 +1666,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* Sets the ComponentSet to be the given ID list.
|
||||
* Records will be added and deleted as appropriate.
|
||||
*
|
||||
* @param array $idList List of IDs.
|
||||
* @param array<int> $idList List of IDs.
|
||||
*/
|
||||
public function setByIDList($idList)
|
||||
{
|
||||
@ -1716,7 +1699,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* Returns an array with both the keys and values set to the IDs of the records in this list.
|
||||
* Does not respect sort order. Use ->column("ID") to get an ID list with the current sort.
|
||||
*
|
||||
* @return array
|
||||
* @return array<int>
|
||||
*/
|
||||
public function getIDList()
|
||||
{
|
||||
@ -1734,13 +1717,13 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* DataList::Create(\SilverStripe\Security\Group::class)->relation("Members")
|
||||
*
|
||||
* @param string $relationName
|
||||
* @return HasManyList|ManyManyList
|
||||
* @return RelationList
|
||||
*/
|
||||
public function relation($relationName)
|
||||
{
|
||||
$ids = $this->column('ID');
|
||||
$singleton = DataObject::singleton($this->dataClass);
|
||||
/** @var HasManyList|ManyManyList $relation */
|
||||
/** @var RelationList $relation */
|
||||
$relation = $singleton->$relationName($ids);
|
||||
return $relation;
|
||||
}
|
||||
@ -1753,8 +1736,8 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
/**
|
||||
* Add a number of items to the component set.
|
||||
*
|
||||
* @param array $items Items to add, as either DataObjects or IDs.
|
||||
* @return $this
|
||||
* @param array<DataObject> $items Items to add, as either DataObjects or IDs.
|
||||
* @return static<T>
|
||||
*/
|
||||
public function addMany($items)
|
||||
{
|
||||
@ -1767,8 +1750,8 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
/**
|
||||
* Remove the items from this list with the given IDs
|
||||
*
|
||||
* @param array $idList
|
||||
* @return $this
|
||||
* @param array<int> $idList
|
||||
* @return static<T>
|
||||
*/
|
||||
public function removeMany($idList)
|
||||
{
|
||||
@ -1782,7 +1765,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* Remove every element in this DataList matching the given $filter.
|
||||
*
|
||||
* @param string|array $filter - a sql type where filter
|
||||
* @return $this
|
||||
* @return static<T>
|
||||
*/
|
||||
public function removeByFilter($filter)
|
||||
{
|
||||
@ -1795,7 +1778,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
/**
|
||||
* Shuffle the datalist using a random function provided by the SQL engine
|
||||
*
|
||||
* @return $this
|
||||
* @return static<T>
|
||||
*/
|
||||
public function shuffle()
|
||||
{
|
||||
@ -1805,7 +1788,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
/**
|
||||
* Remove every element in this DataList.
|
||||
*
|
||||
* @return $this
|
||||
* @return static<T>
|
||||
*/
|
||||
public function removeAll()
|
||||
{
|
||||
@ -1819,7 +1802,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* This method are overloaded by HasManyList and ManyMany list to perform more sophisticated
|
||||
* list manipulation
|
||||
*
|
||||
* @param mixed $item
|
||||
* @param DataObject|int $item
|
||||
*/
|
||||
public function add($item)
|
||||
{
|
||||
@ -1831,7 +1814,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* Return a new item to add to this DataList.
|
||||
*
|
||||
* @param array $initialFields
|
||||
* @return DataObject
|
||||
* @return T
|
||||
*/
|
||||
public function newObject($initialFields = null)
|
||||
{
|
||||
@ -1867,7 +1850,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
/**
|
||||
* Reverses a list of items.
|
||||
*
|
||||
* @return static
|
||||
* @return static<T>
|
||||
*/
|
||||
public function reverse()
|
||||
{
|
||||
@ -1888,6 +1871,8 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
* Returns item stored in list with index $key
|
||||
*
|
||||
* The object returned is not cached, unlike {@link DataObject::get_one()}
|
||||
*
|
||||
* @return T|null
|
||||
*/
|
||||
public function offsetGet(mixed $key): ?DataObject
|
||||
{
|
||||
@ -1922,7 +1907,7 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li
|
||||
*
|
||||
* @param int $chunkSize
|
||||
* @throws InvalidArgumentException If `$chunkSize` has an invalid size.
|
||||
* @return Generator|DataObject[]
|
||||
* @return iterable<T>
|
||||
*/
|
||||
public function chunkedFetch(int $chunkSize = 1000): iterable
|
||||
{
|
||||
|
@ -109,7 +109,6 @@ use stdClass;
|
||||
*/
|
||||
class DataObject extends ViewableData implements DataObjectInterface, i18nEntityProvider, Resettable
|
||||
{
|
||||
|
||||
/**
|
||||
* Human-readable singular name.
|
||||
* @var string
|
||||
@ -525,7 +524,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
// Create unsaved raw duplicate
|
||||
$map = $this->toMap();
|
||||
unset($map['Created']);
|
||||
/** @var static $clone */
|
||||
$clone = Injector::inst()->create(static::class, $map, false, $this->getSourceQueryParams());
|
||||
$clone->ID = 0;
|
||||
|
||||
@ -628,7 +626,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
$source = $sourceObject->getComponents($relation);
|
||||
$dest = $destinationObject->getComponents($relation);
|
||||
|
||||
/** @var DataObject $item */
|
||||
foreach ($source as $item) {
|
||||
// Don't write on duplicate; Wait until ParentID is available later.
|
||||
// writeRelations() will eventually write these records when converting
|
||||
@ -742,9 +739,10 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
* there is no record, or the record has no ID. In this case, we do have an ID but
|
||||
* we still need to repopulate the defaults.
|
||||
*
|
||||
* @param string $newClassName The name of the new class
|
||||
* @template T of DataObject
|
||||
* @param class-string<T> $newClassName The name of the new class
|
||||
*
|
||||
* @return DataObject The new instance of the new class, The exact type will be of the class name provided.
|
||||
* @return T The new instance of the new class, The exact type will be of the class name provided.
|
||||
*/
|
||||
public function newClassInstance($newClassName)
|
||||
{
|
||||
@ -963,7 +961,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
* Returns the associated database record - in this case, the object itself.
|
||||
* This is included so that you can call $dataOrController->data() and get a DataObject all the time.
|
||||
*
|
||||
* @return DataObject Associated database record
|
||||
* @return static Associated database record
|
||||
*/
|
||||
public function data()
|
||||
{
|
||||
@ -1012,7 +1010,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
* whitelist the allowed keys.
|
||||
*
|
||||
* @param array $data A map of field name to data values to update.
|
||||
* @return DataObject $this
|
||||
* @return static $this
|
||||
*/
|
||||
public function update($data)
|
||||
{
|
||||
@ -1021,7 +1019,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
if (strpos($key ?? '', '.') !== false) {
|
||||
$relations = explode('.', $key ?? '');
|
||||
$fieldName = array_pop($relations);
|
||||
/** @var static $relObj */
|
||||
$relObj = $this;
|
||||
$relation = null;
|
||||
foreach ($relations as $i => $relation) {
|
||||
@ -1029,6 +1026,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
// as the updater wouldn't know which object to write to (or create)
|
||||
if ($relObj->$relation() instanceof DataObject) {
|
||||
$parentObj = $relObj;
|
||||
/** @var static $relObj */
|
||||
$relObj = $relObj->$relation();
|
||||
// If the intermediate relationship objects haven't been created, then write them
|
||||
if ($i < sizeof($relations ?? []) - 1 && !$relObj->ID || (!$relObj->ID && $parentObj !== $this)) {
|
||||
@ -1073,7 +1071,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
* use the write() method.
|
||||
*
|
||||
* @param array $data A map of field name to data values to update.
|
||||
* @return DataObject $this
|
||||
* @return static $this
|
||||
*/
|
||||
public function castedUpdate($data)
|
||||
{
|
||||
@ -1097,7 +1095,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
* Caution: Does not delete the merged object.
|
||||
* Caution: Does now overwrite Created date on the original object.
|
||||
*
|
||||
* @param DataObject $rightObj
|
||||
* @param static $rightObj Object to merge in
|
||||
* @param string $priority left|right Determines who wins in case of a conflict (optional)
|
||||
* @param bool $includeRelations Merge any existing relations (optional)
|
||||
* @param bool $overwriteWithEmpty Overwrite existing left values with empty right values.
|
||||
@ -1151,7 +1149,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
if ($includeRelations) {
|
||||
if ($manyMany = $this->manyMany()) {
|
||||
foreach ($manyMany as $relationship => $class) {
|
||||
/** @var DataObject $leftComponents */
|
||||
$leftComponents = $leftObj->getManyManyComponents($relationship);
|
||||
$rightComponents = $rightObj->getManyManyComponents($relationship);
|
||||
if ($rightComponents && $rightComponents->exists()) {
|
||||
@ -1263,7 +1260,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
*
|
||||
* @param bool $recursive True if recursive
|
||||
* @param ArrayList $list Optional list to add items to
|
||||
* @return ArrayList list of objects
|
||||
* @return ArrayList<DataObject> list of objects
|
||||
*/
|
||||
public function findCascadeDeletes($recursive = true, $list = null)
|
||||
{
|
||||
@ -1303,7 +1300,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
* Called by the constructor when creating new records.
|
||||
*
|
||||
* @uses DataExtension::populateDefaults()
|
||||
* @return DataObject $this
|
||||
* @return static $this
|
||||
*/
|
||||
public function populateDefaults()
|
||||
{
|
||||
@ -1654,7 +1651,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
*
|
||||
* @param bool $recursive Recursively write components
|
||||
* @param array $skip List of DataObject references to skip
|
||||
* @return DataObject $this
|
||||
* @return static $this
|
||||
*/
|
||||
public function writeComponents($recursive = false, $skip = [])
|
||||
{
|
||||
@ -2339,7 +2336,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
* Generates a SearchContext to be used for building and processing
|
||||
* a generic search form for properties on this object.
|
||||
*
|
||||
* @return SearchContext
|
||||
* @return SearchContext<static>
|
||||
*/
|
||||
public function getDefaultSearchContext()
|
||||
{
|
||||
@ -3306,7 +3303,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
* @param string|array $limit A limit expression to be inserted into the LIMIT clause.
|
||||
* @param string $containerClass The container class to return the results in.
|
||||
*
|
||||
* @return DataList The objects matching the filter, in the class specified by $containerClass
|
||||
* @return DataList<static> The objects matching the filter, in the class specified by $containerClass
|
||||
*/
|
||||
public static function get(
|
||||
$callerClass = null,
|
||||
@ -3372,7 +3369,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
* @param boolean $cache Use caching
|
||||
* @param string|array|null $sort Passed to DataList::sort() so that DataList::first() returns the desired item
|
||||
*
|
||||
* @return DataObject|null The first item matching the query
|
||||
* @return static|null The first item matching the query
|
||||
*/
|
||||
public static function get_one($callerClass = null, $filter = "", $cache = true, $sort = "")
|
||||
{
|
||||
@ -3423,7 +3420,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
*
|
||||
* @param boolean $persistent When true will also clear persistent data stored in the Cache system.
|
||||
* When false will just clear session-local cached data
|
||||
* @return DataObject $this
|
||||
* @return static $this
|
||||
*/
|
||||
public function flushCache($persistent = true)
|
||||
{
|
||||
@ -3524,7 +3521,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
/**
|
||||
* Get the base class for this object
|
||||
*
|
||||
* @return string
|
||||
* @return class-string<DataObject>
|
||||
*/
|
||||
public function baseClass()
|
||||
{
|
||||
@ -4356,7 +4353,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
* @param bool $recursive True if recursive
|
||||
* @param ArrayList $list If specified, items will be added to this list. If not, a new
|
||||
* instance of ArrayList will be constructed and returned
|
||||
* @return ArrayList The list of related objects
|
||||
* @return ArrayList<DataObject> The list of related objects
|
||||
*/
|
||||
public function findRelatedObjects($source, $recursive = true, $list = null)
|
||||
{
|
||||
@ -4391,7 +4388,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
// Recurse if necessary
|
||||
if ($recursive) {
|
||||
foreach ($newItems as $item) {
|
||||
/** @var DataObject $item */
|
||||
$item->findRelatedObjects($source, true, $list);
|
||||
}
|
||||
}
|
||||
@ -4404,8 +4400,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
* Items already present in the list will be skipped.
|
||||
*
|
||||
* @param ArrayList $list Items to merge into
|
||||
* @param mixed $items List of new items to merge
|
||||
* @return ArrayList List of all newly added items that did not already exist in $list
|
||||
* @param iterable<DataObject>|DataObject|null $items List of new items to merge
|
||||
* @return ArrayList<DataObject> List of all newly added items that did not already exist in $list
|
||||
*/
|
||||
public function mergeRelatedObjects($list, $items)
|
||||
{
|
||||
@ -4417,7 +4413,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
$items = [$items];
|
||||
}
|
||||
|
||||
/** @var DataObject $item */
|
||||
foreach ($items as $item) {
|
||||
$this->mergeRelatedObject($list, $added, $item);
|
||||
}
|
||||
@ -4439,7 +4434,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
*/
|
||||
public function getUniqueKey(): string
|
||||
{
|
||||
/** @var UniqueKeyInterface $service */
|
||||
$service = Injector::inst()->get(UniqueKeyInterface::class);
|
||||
$keyComponents = $this->getUniqueKeyComponents();
|
||||
|
||||
|
@ -144,7 +144,7 @@ class DataObjectSchema
|
||||
*
|
||||
* @param string|object $class
|
||||
*
|
||||
* @return string
|
||||
* @return class-string<DataObject>
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function baseDataClass($class)
|
||||
@ -261,7 +261,7 @@ class DataObjectSchema
|
||||
*
|
||||
* @param string $table
|
||||
*
|
||||
* @return string|null The FQN of the class, or null if not found
|
||||
* @return class-string<DataObject>|null The FQN of the class, or null if not found
|
||||
*/
|
||||
public function tableClass($table)
|
||||
{
|
||||
@ -714,7 +714,7 @@ class DataObjectSchema
|
||||
* @param string $candidateClass
|
||||
* @param string $fieldName
|
||||
*
|
||||
* @return string
|
||||
* @return class-string<DataObject>|null
|
||||
*/
|
||||
public function classForField($candidateClass, $fieldName)
|
||||
{
|
||||
|
@ -1054,7 +1054,6 @@ class DataQuery
|
||||
}
|
||||
|
||||
// Join table with associated has_one
|
||||
/** @var DataObject $model */
|
||||
$foreignKey = $schema->getRemoteJoinField($localClass, $localField, $type, $polymorphic);
|
||||
$localIDColumn = $schema->sqlColumnForField($localClass, 'ID', $localPrefix);
|
||||
if ($polymorphic) {
|
||||
|
@ -21,6 +21,13 @@ use Traversable;
|
||||
*
|
||||
* Note that when this list represents a relation, adding items to or removing items from this list will NOT
|
||||
* affect the underlying relation in the database. This list is read-only.
|
||||
*
|
||||
* @template T of DataObject
|
||||
* @implements Relation<T>
|
||||
* @implements SS_List<T>
|
||||
* @implements Filterable<T>
|
||||
* @implements Sortable<T>
|
||||
* @implements Limitable<T>
|
||||
*/
|
||||
class EagerLoadedList extends ViewableData implements Relation, SS_List, Filterable, Sortable, Limitable
|
||||
{
|
||||
@ -28,11 +35,13 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
||||
|
||||
/**
|
||||
* List responsible for instantiating the actual DataObject objects from eager-loaded data
|
||||
* @var DataList<T>
|
||||
*/
|
||||
private DataList $dataList;
|
||||
|
||||
/**
|
||||
* Underlying DataObject class for this list
|
||||
* @var class-string<T>
|
||||
*/
|
||||
private string $dataClass;
|
||||
|
||||
@ -65,6 +74,9 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
||||
*/
|
||||
private array $manyManyComponent = [];
|
||||
|
||||
/**
|
||||
* @param class-string<T> $dataClass
|
||||
*/
|
||||
public function __construct(string $dataClass, string $dataListClass, int|array|null $foreignID = null, array $manyManyComponent = [])
|
||||
{
|
||||
if (!is_a($dataListClass, DataList::class, true)) {
|
||||
@ -144,6 +156,8 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
||||
|
||||
/**
|
||||
* Get the dataClass name for this list, ie the DataObject ClassName
|
||||
*
|
||||
* @return class-string<T>
|
||||
*/
|
||||
public function dataClass(): string
|
||||
{
|
||||
@ -179,6 +193,9 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
||||
throw new BadMethodCallException("Can't change the foreign ID for an EagerLoadedList");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Traversable<T>
|
||||
*/
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
$limitedRows = $this->getFinalisedRows();
|
||||
@ -354,6 +371,8 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
||||
|
||||
/**
|
||||
* Returns item stored in list with offset $key
|
||||
*
|
||||
* @return T|null
|
||||
*/
|
||||
public function offsetGet(mixed $key): ?DataObject
|
||||
{
|
||||
@ -493,6 +512,8 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
||||
|
||||
/**
|
||||
* Return a copy of this list which does not contain any items with any of these params
|
||||
*
|
||||
* @return static<T>
|
||||
*/
|
||||
public function excludeAny(...$args): static
|
||||
{
|
||||
@ -509,6 +530,7 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
||||
* Return a new instance of the list with an added filter
|
||||
*
|
||||
* @param array $filterArray
|
||||
* @return static<T>
|
||||
*/
|
||||
public function addFilter($filterArray): static
|
||||
{
|
||||
@ -522,6 +544,7 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
||||
*
|
||||
* The $list passed needs to contain the same dataclass as $this
|
||||
*
|
||||
* @return static<T>
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function subtract(DataList $list): static
|
||||
@ -577,7 +600,6 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
||||
if (is_array($value) && empty($value)) {
|
||||
throw new InvalidArgumentException("Cannot filter $column against an empty set");
|
||||
}
|
||||
/** @var SearchFilter $searchFilter */
|
||||
$searchFilter = $searchFilters[$column];
|
||||
$extractedValue = $this->extractValue($row, $this->standardiseColumn($searchFilter->getFullName()));
|
||||
$doesMatch = $searchFilter->matches($extractedValue);
|
||||
@ -612,6 +634,9 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayList<T>
|
||||
*/
|
||||
public function filterByCallback($callback): ArrayList
|
||||
{
|
||||
if (!is_callable($callback)) {
|
||||
@ -708,6 +733,8 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
||||
|
||||
/**
|
||||
* Shuffle the items in this list
|
||||
*
|
||||
* @return static<T>
|
||||
*/
|
||||
public function shuffle(): static
|
||||
{
|
||||
@ -862,6 +889,7 @@ class EagerLoadedList extends ViewableData implements Relation, SS_List, Filtera
|
||||
* At a minimum, $row['ID'] must be set. Unsaved records cannot be eager loaded.
|
||||
*
|
||||
* @param array $row
|
||||
* @return T
|
||||
*/
|
||||
public function createDataObject($row): DataObject
|
||||
{
|
||||
|
@ -11,6 +11,9 @@ namespace SilverStripe\ORM;
|
||||
* @see SS_List
|
||||
* @see Sortable
|
||||
* @see Limitable
|
||||
*
|
||||
* @template T
|
||||
* @extends SS_List<T>
|
||||
*/
|
||||
interface Filterable extends SS_List
|
||||
{
|
||||
@ -26,13 +29,14 @@ interface Filterable extends SS_List
|
||||
/**
|
||||
* Return a new instance of this list that only includes items with these characteristics
|
||||
*
|
||||
* @return Filterable
|
||||
* @example $list = $list->filter('Name', 'bob'); // only bob in the list
|
||||
* @example $list = $list->filter('Name', array('aziz', 'bob'); // aziz and bob in list
|
||||
* @example $list = $list->filter(array('Name'=>'bob, 'Age'=>21)); // bob with the age 21
|
||||
* @example $list = $list->filter(array('Name'=>'bob, 'Age'=>array(21, 43))); // bob with the Age 21 or 43
|
||||
* @example $list = $list->filter(array('Name'=>array('aziz','bob'), 'Age'=>array(21, 43)));
|
||||
* // aziz with the age 21 or 43 and bob with the Age 21 or 43
|
||||
*
|
||||
* @return static<T>
|
||||
*/
|
||||
public function filter();
|
||||
|
||||
@ -56,20 +60,21 @@ interface Filterable extends SS_List
|
||||
* // SQL: WHERE (("Name" IN ('bob', 'phil')) OR ("Age" IN ('21', '43'))
|
||||
*
|
||||
* @param string|array See {@link filter()}
|
||||
* @return static
|
||||
* @return static<T>
|
||||
*/
|
||||
public function filterAny();
|
||||
|
||||
/**
|
||||
* Return a new instance of this list that excludes any items with these characteristics
|
||||
*
|
||||
* @return Filterable
|
||||
* @example $list = $list->exclude('Name', 'bob'); // exclude bob from list
|
||||
* @example $list = $list->exclude('Name', array('aziz', 'bob'); // exclude aziz and bob from list
|
||||
* @example $list = $list->exclude(array('Name'=>'bob, 'Age'=>21)); // exclude bob that has Age 21
|
||||
* @example $list = $list->exclude(array('Name'=>'bob, 'Age'=>array(21, 43))); // exclude bob with Age 21 or 43
|
||||
* @example $list = $list->exclude(array('Name'=>array('bob','phil'), 'Age'=>array(21, 43)));
|
||||
* // bob age 21 or 43, phil age 21 or 43 would be excluded
|
||||
*
|
||||
* @return static<T>
|
||||
*/
|
||||
public function exclude();
|
||||
|
||||
@ -80,7 +85,7 @@ interface Filterable extends SS_List
|
||||
*
|
||||
* @example $list = $list->filterByCallback(function($item, $list) { return $item->Age == 9; })
|
||||
* @param callable $callback
|
||||
* @return Filterable
|
||||
* @return SS_List<T>
|
||||
*/
|
||||
public function filterByCallback($callback);
|
||||
|
||||
@ -88,7 +93,7 @@ interface Filterable extends SS_List
|
||||
* Return the first item with the given ID
|
||||
*
|
||||
* @param int $id
|
||||
* @return mixed
|
||||
* @return T|null
|
||||
*/
|
||||
public function byID($id);
|
||||
|
||||
@ -96,7 +101,7 @@ interface Filterable extends SS_List
|
||||
* Filter this list to only contain the given Primary IDs
|
||||
*
|
||||
* @param array $ids Array of integers
|
||||
* @return SS_List
|
||||
* @return static<T>
|
||||
*/
|
||||
public function byIDs($ids);
|
||||
}
|
||||
|
@ -7,6 +7,10 @@ use SilverStripe\View\ArrayData;
|
||||
/**
|
||||
* A list decorator that allows a list to be grouped into sub-lists by common
|
||||
* values of a field.
|
||||
*
|
||||
* @template TList
|
||||
* @template T
|
||||
* @extends ListDecorator<TList, T>
|
||||
*/
|
||||
class GroupedList extends ListDecorator
|
||||
{
|
||||
@ -40,7 +44,7 @@ class GroupedList extends ListDecorator
|
||||
*
|
||||
* @param string $index
|
||||
* @param string $children Name of the control under which children can be iterated on
|
||||
* @return ArrayList
|
||||
* @return ArrayList<ArrayData>
|
||||
*/
|
||||
public function GroupedBy($index, $children = 'Children')
|
||||
{
|
||||
|
@ -6,6 +6,9 @@ use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Subclass of {@link DataList} representing a has_many relation.
|
||||
*
|
||||
* @template T of DataObject
|
||||
* @extends RelationList<T>
|
||||
*/
|
||||
class HasManyList extends RelationList
|
||||
{
|
||||
@ -21,7 +24,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 +46,7 @@ class HasManyList extends RelationList
|
||||
|
||||
/**
|
||||
* @param null|int|array|string $id
|
||||
* @return array
|
||||
* @return array|null
|
||||
*/
|
||||
protected function foreignIDFilter($id = null)
|
||||
{
|
||||
|
@ -23,8 +23,8 @@ use SilverStripe\View\ViewableData;
|
||||
* obvious example of this is SiteTree.
|
||||
*
|
||||
* @property int $ParentID
|
||||
* @property DataObject|Hierarchy $owner
|
||||
* @method DataObject Parent()
|
||||
* @extends DataExtension<DataObject&static>
|
||||
*/
|
||||
class Hierarchy extends DataExtension
|
||||
{
|
||||
@ -119,7 +119,6 @@ class Hierarchy extends DataExtension
|
||||
public function validate(ValidationResult $validationResult)
|
||||
{
|
||||
// The object is new, won't be looping.
|
||||
/** @var DataObject|Hierarchy $owner */
|
||||
$owner = $this->owner;
|
||||
if (!$owner->ID) {
|
||||
return;
|
||||
@ -190,7 +189,7 @@ class Hierarchy extends DataExtension
|
||||
/**
|
||||
* Get the children for this DataObject filtered by canView()
|
||||
*
|
||||
* @return SS_List
|
||||
* @return SS_List<DataObject&static>
|
||||
*/
|
||||
public function Children()
|
||||
{
|
||||
@ -212,7 +211,7 @@ class Hierarchy extends DataExtension
|
||||
/**
|
||||
* Return all children, including those 'not in menus'.
|
||||
*
|
||||
* @return DataList
|
||||
* @return DataList<DataObject&static>
|
||||
*/
|
||||
public function AllChildren()
|
||||
{
|
||||
@ -226,7 +225,7 @@ class Hierarchy extends DataExtension
|
||||
* - Modified children will be marked as "ModifiedOnStage"
|
||||
* - Everything else has "SameOnStage" set, as an indicator that this information has been looked up.
|
||||
*
|
||||
* @return ArrayList
|
||||
* @return ArrayList<DataObject&static>
|
||||
*/
|
||||
public function AllChildrenIncludingDeleted()
|
||||
{
|
||||
@ -252,7 +251,7 @@ class Hierarchy extends DataExtension
|
||||
/**
|
||||
* Return all the children that this page had, including pages that were deleted from both stage & live.
|
||||
*
|
||||
* @return DataList
|
||||
* @return DataList<DataObject&static>
|
||||
* @throws Exception
|
||||
*/
|
||||
public function AllHistoricalChildren()
|
||||
@ -293,7 +292,6 @@ class Hierarchy extends DataExtension
|
||||
*/
|
||||
public function numChildren($cache = true)
|
||||
{
|
||||
|
||||
$baseClass = $this->owner->baseClass();
|
||||
$cacheType = 'numChildren';
|
||||
$id = $this->owner->ID;
|
||||
@ -355,7 +353,7 @@ class Hierarchy extends DataExtension
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var Versioned|DataObject $singleton */
|
||||
/** @var DataObject&static $dummyObject */
|
||||
$dummyObject = DataObject::singleton($baseClass);
|
||||
$baseTable = $dummyObject->baseTable();
|
||||
|
||||
@ -431,11 +429,10 @@ class Hierarchy extends DataExtension
|
||||
* @param bool $showAll Include all of the elements, even those not shown in the menus. Only applicable when
|
||||
* extension is applied to {@link SiteTree}.
|
||||
* @param bool $skipParentIDFilter Set to true to suppress the ParentID and ID where statements.
|
||||
* @return DataList
|
||||
* @return DataList<DataObject&static>
|
||||
*/
|
||||
public function stageChildren($showAll = false, $skipParentIDFilter = false)
|
||||
{
|
||||
/** @var DataObject|Hierarchy $owner */
|
||||
$owner = $this->owner;
|
||||
$hideFromHierarchy = $owner->config()->hide_from_hierarchy;
|
||||
$hideFromCMSTree = $owner->config()->hide_from_cms_tree;
|
||||
@ -477,7 +474,7 @@ class Hierarchy extends DataExtension
|
||||
* @param bool $showAll Include all of the elements, even those not shown in the menus. Only
|
||||
* applicable when extension is applied to {@link SiteTree}.
|
||||
* @param bool $onlyDeletedFromStage Only return items that have been deleted from stage
|
||||
* @return DataList
|
||||
* @return DataList<DataObject&static>
|
||||
* @throws Exception
|
||||
*/
|
||||
public function liveChildren($showAll = false, $onlyDeletedFromStage = false)
|
||||
@ -515,7 +512,7 @@ class Hierarchy extends DataExtension
|
||||
* is returned.
|
||||
*
|
||||
* @param string $filter
|
||||
* @return DataObject
|
||||
* @return DataObject&static
|
||||
*/
|
||||
public function getParent($filter = null)
|
||||
{
|
||||
@ -535,7 +532,7 @@ class Hierarchy extends DataExtension
|
||||
* Return all the parents of this class in a set ordered from the closest to furtherest parent.
|
||||
*
|
||||
* @param bool $includeSelf
|
||||
* @return ArrayList
|
||||
* @return ArrayList<DataObject&static>
|
||||
*/
|
||||
public function getAncestors($includeSelf = false)
|
||||
{
|
||||
|
@ -187,7 +187,7 @@ class MarkedSet
|
||||
* Get children from this node
|
||||
*
|
||||
* @param DataObject $node
|
||||
* @return SS_List
|
||||
* @return SS_List<DataObject>
|
||||
*/
|
||||
protected function getChildren(DataObject $node)
|
||||
{
|
||||
@ -453,7 +453,6 @@ class MarkedSet
|
||||
$nodeCountThreshold = $this->getNodeCountThreshold();
|
||||
|
||||
// Add root node, not-expanded by default
|
||||
/** @var DataObject|Hierarchy $rootNode */
|
||||
$rootNode = $this->rootNode;
|
||||
$this->clearMarks();
|
||||
$this->markUnexpanded($rootNode);
|
||||
@ -464,7 +463,6 @@ class MarkedSet
|
||||
$children = $this->markChildren($node);
|
||||
if ($nodeCountThreshold && sizeof($this->markedNodes ?? []) > $nodeCountThreshold) {
|
||||
// Undo marking children as opened since they're lazy loaded
|
||||
/** @var DataObject|Hierarchy $child */
|
||||
foreach ($children as $child) {
|
||||
$this->markClosed($child);
|
||||
}
|
||||
@ -542,7 +540,7 @@ class MarkedSet
|
||||
* Mark all children of the given node that match the marking filter.
|
||||
*
|
||||
* @param DataObject $node Parent node
|
||||
* @return array List of children marked by this operation
|
||||
* @return array<DataObject> List of children marked by this operation
|
||||
*/
|
||||
protected function markChildren(DataObject $node)
|
||||
{
|
||||
|
@ -11,6 +11,9 @@ namespace SilverStripe\ORM;
|
||||
* @see SS_List
|
||||
* @see Sortable
|
||||
* @see Filterable
|
||||
*
|
||||
* @template T
|
||||
* @implements SS_List<T>
|
||||
*/
|
||||
interface Limitable extends SS_List
|
||||
{
|
||||
@ -23,6 +26,7 @@ interface Limitable extends SS_List
|
||||
* If `$length` is null, then no limit is applied. If `$length` is 0, then an empty list is returned.
|
||||
*
|
||||
* @throws InvalidArgumentException if $length or offset are negative
|
||||
* @return static<T>
|
||||
*/
|
||||
public function limit(?int $length, int $offset = 0): Limitable;
|
||||
}
|
||||
|
@ -10,15 +10,24 @@ use Traversable;
|
||||
* A base class for decorators that wrap around a list to provide additional
|
||||
* functionality. It passes through list methods to the underlying list
|
||||
* implementation.
|
||||
*
|
||||
* @template TList of SS_List&Sortable&Filterable&Limitable
|
||||
* @template T
|
||||
* @implements SS_List<T>
|
||||
* @implements Sortable<T>
|
||||
* @implements Filterable<T>
|
||||
* @implements Limitable<T>
|
||||
*/
|
||||
abstract class ListDecorator extends ViewableData implements SS_List, Sortable, Filterable, Limitable
|
||||
{
|
||||
|
||||
/**
|
||||
* @var SS_List
|
||||
* @var TList<T>
|
||||
*/
|
||||
protected SS_List&Sortable&Filterable&Limitable $list;
|
||||
|
||||
/**
|
||||
* @param TList<T> $list
|
||||
*/
|
||||
public function __construct(SS_List&Sortable&Filterable&Limitable $list)
|
||||
{
|
||||
$this->setList($list);
|
||||
@ -26,6 +35,9 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TList<T>
|
||||
*/
|
||||
public function getList(): SS_List&Sortable&Filterable&Limitable
|
||||
{
|
||||
return $this->list;
|
||||
@ -37,7 +49,10 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
||||
* Useful for keeping a decorator/paginated list configuration intact while modifying
|
||||
* the underlying list.
|
||||
*
|
||||
* @return SS_List
|
||||
* @template TListA
|
||||
* @template TA
|
||||
* @param TListA<TA> $list
|
||||
* @return static<TListA, TA>
|
||||
*/
|
||||
public function setList(SS_List&Sortable&Filterable&Limitable $list): self
|
||||
{
|
||||
@ -51,6 +66,9 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
||||
return $this->list->offsetExists($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T
|
||||
*/
|
||||
public function offsetGet(mixed $key): mixed
|
||||
{
|
||||
return $this->list->offsetGet($key);
|
||||
@ -86,6 +104,9 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
||||
$this->list->remove($itemObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Traversable<T>
|
||||
*/
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
return $this->list->getIterator();
|
||||
@ -106,6 +127,9 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
||||
return $this->list->last();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function TotalItems()
|
||||
{
|
||||
return $this->list->count();
|
||||
@ -141,6 +165,9 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
||||
return $this->list->columnUnique($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TList<T>
|
||||
*/
|
||||
public function each($callback)
|
||||
{
|
||||
return $this->list->each($callback);
|
||||
@ -164,6 +191,8 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
||||
* @example $list->sort('Name DESC'); // DESC sorting
|
||||
* @example $list->sort('Name', 'ASC');
|
||||
* @example $list->sort(array('Name'=>'ASC,'Age'=>'DESC'));
|
||||
*
|
||||
* @return TList<T>
|
||||
*/
|
||||
public function sort()
|
||||
{
|
||||
@ -182,6 +211,8 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
||||
* @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
|
||||
*
|
||||
* @return TList<T>
|
||||
*/
|
||||
public function filter()
|
||||
{
|
||||
@ -208,7 +239,8 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
||||
* // SQL: WHERE (("Name" IN ('bob', 'phil')) OR ("Age" IN ('21', '43'))
|
||||
*
|
||||
* @param string|array See {@link filter()}
|
||||
* @return DataList
|
||||
*
|
||||
* @return TList<T>
|
||||
*/
|
||||
public function filterAny()
|
||||
{
|
||||
@ -222,7 +254,7 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
||||
*
|
||||
* @example $list = $list->filterByCallback(function($item, $list) { return $item->Age == 9; })
|
||||
* @param callable $callback
|
||||
* @return ArrayList (this may change in future implementations)
|
||||
* @return ArrayList<T>
|
||||
*/
|
||||
public function filterByCallback($callback)
|
||||
{
|
||||
@ -241,17 +273,14 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TList<T>
|
||||
*/
|
||||
public function limit(?int $length, int $offset = 0): SS_List&Sortable&Filterable&Limitable
|
||||
{
|
||||
return $this->list->limit($length, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first item with the given ID
|
||||
*
|
||||
* @param int $id
|
||||
* @return mixed
|
||||
*/
|
||||
public function byID($id)
|
||||
{
|
||||
return $this->list->byID($id);
|
||||
@ -261,7 +290,8 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
||||
* Filter this list to only contain the given Primary IDs
|
||||
*
|
||||
* @param array $ids Array of integers
|
||||
* @return SS_List
|
||||
*
|
||||
* @return TList<T>
|
||||
*/
|
||||
public function byIDs($ids)
|
||||
{
|
||||
@ -275,6 +305,8 @@ abstract class ListDecorator extends ViewableData implements SS_List, Sortable,
|
||||
* @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
|
||||
*
|
||||
* @return TList<T>
|
||||
*/
|
||||
public function exclude()
|
||||
{
|
||||
|
@ -9,9 +9,13 @@ use SilverStripe\ORM\Queries\SQLDelete;
|
||||
use SilverStripe\ORM\FieldType\DBComposite;
|
||||
use InvalidArgumentException;
|
||||
use Exception;
|
||||
use SilverStripe\ORM\FieldType\DBField;
|
||||
|
||||
/**
|
||||
* Subclass of {@link DataList} representing a many_many relation.
|
||||
*
|
||||
* @template T of DataObject
|
||||
* @extends RelationList<T>
|
||||
*/
|
||||
class ManyManyList extends RelationList
|
||||
{
|
||||
@ -50,7 +54,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.
|
||||
@ -120,12 +124,6 @@ class ManyManyList extends RelationList
|
||||
$this->dataQuery->addSelectFromTable($this->joinTable, $finalized);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a DataObject from the given SQL row.
|
||||
*
|
||||
* @param array $row
|
||||
* @return DataObject
|
||||
*/
|
||||
public function createDataObject($row)
|
||||
{
|
||||
// remove any composed fields
|
||||
@ -165,8 +163,6 @@ class ManyManyList extends RelationList
|
||||
* relationship for some foreign ID
|
||||
*
|
||||
* @param int|null|string|array $id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function foreignIDFilter($id = null)
|
||||
{
|
||||
@ -285,7 +281,6 @@ class ManyManyList extends RelationList
|
||||
];
|
||||
}
|
||||
|
||||
/** @var DBField[] $fieldObjects */
|
||||
$fieldObjects = [];
|
||||
if ($extraFields && $this->extraFields) {
|
||||
// Write extra field to manipluation in the same way
|
||||
@ -293,6 +288,7 @@ class ManyManyList extends RelationList
|
||||
foreach ($this->extraFields as $fieldName => $fieldSpec) {
|
||||
// Skip fields without an assignment
|
||||
if (array_key_exists($fieldName, $extraFields ?? [])) {
|
||||
/** @var DBField $fieldObject */
|
||||
$fieldObject = Injector::inst()->create($fieldSpec, $fieldName);
|
||||
$fieldObject->setValue($extraFields[$fieldName]);
|
||||
$fieldObject->writeToManipulation($manipulation[$this->joinTable]);
|
||||
@ -462,7 +458,6 @@ class ManyManyList extends RelationList
|
||||
],
|
||||
];
|
||||
|
||||
/** @var DBField[] $fieldObjects */
|
||||
$fieldObjects = [];
|
||||
// Write extra field to manipluation in the same way
|
||||
// that DataObject::prepareManipulationTable writes fields
|
||||
@ -470,6 +465,7 @@ class ManyManyList extends RelationList
|
||||
if (!array_key_exists($fieldName, $this->extraFields)) {
|
||||
throw new InvalidArgumentException("Field '$fieldName' is not defined in many_many_extraFields for this relationship");
|
||||
}
|
||||
/** @var DBField $fieldObject */
|
||||
$fieldObject = Injector::inst()->create($this->extraFields[$fieldName], $fieldName);
|
||||
// Make sure the field assignment is not an array unless the field allows non-scalar values
|
||||
if (is_array($value) && $fieldObject->scalarValueOnly()) {
|
||||
|
@ -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,15 +24,15 @@ 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.
|
||||
* @example new ManyManyThroughList('Banner', 'PageBanner', 'BannerID', 'PageID');
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @param array $extraFields Ignored for ManyManyThroughList
|
||||
* @param string $foreignClass 'from' class
|
||||
* @param string $parentClass Parent class (should be subclass of 'from')
|
||||
* @example new ManyManyThroughList('Banner', 'PageBanner', 'BannerID', 'PageID');
|
||||
*/
|
||||
public function __construct(
|
||||
$dataClass,
|
||||
@ -55,10 +58,6 @@ class ManyManyThroughList extends RelationList
|
||||
|
||||
/**
|
||||
* Don't apply foreign ID filter until getFinalisedQuery()
|
||||
*
|
||||
* @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)
|
||||
*/
|
||||
protected function foreignIDFilter($id = null)
|
||||
{
|
||||
@ -134,7 +133,6 @@ class ManyManyThroughList extends RelationList
|
||||
|
||||
// Rather than simple un-associating the record (as in has_many list)
|
||||
// Delete the actual mapping row as many_many deletions behave.
|
||||
/** @var DataObject $record */
|
||||
foreach ($records as $record) {
|
||||
$record->delete();
|
||||
}
|
||||
@ -144,6 +142,9 @@ class ManyManyThroughList extends RelationList
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function removeAll()
|
||||
{
|
||||
// Get the IDs of records in the current list
|
||||
@ -216,7 +217,6 @@ 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) {
|
||||
|
@ -9,6 +9,8 @@ use SilverStripe\ORM\Queries\SQLSelect;
|
||||
|
||||
/**
|
||||
* Injected into DataQuery to augment getFinalisedQuery() with a join table
|
||||
*
|
||||
* @template TJoin of DataObject
|
||||
*/
|
||||
class ManyManyThroughQueryManipulator implements DataQueryManipulator
|
||||
{
|
||||
@ -18,7 +20,7 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
|
||||
/**
|
||||
* DataObject that backs the joining table
|
||||
*
|
||||
* @var string
|
||||
* @var class-string<TJoin>
|
||||
*/
|
||||
protected $joinClass;
|
||||
|
||||
@ -53,6 +55,10 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
|
||||
/**
|
||||
* 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 string $foreignClass
|
||||
* @param string $parentClass
|
||||
*/
|
||||
public function __construct(string $joinClass, string $localKey, string $foreignKey, string $foreignClass, string $parentClass)
|
||||
{
|
||||
@ -68,7 +74,7 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @return class-string<TJoin>
|
||||
*/
|
||||
public function getJoinClass()
|
||||
{
|
||||
@ -76,7 +82,7 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $joinClass
|
||||
* @param class-string<TJoin> $joinClass
|
||||
* @return $this
|
||||
*/
|
||||
public function setJoinClass($joinClass)
|
||||
@ -152,7 +158,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)
|
||||
{
|
||||
@ -307,7 +313,7 @@ class ManyManyThroughQueryManipulator implements DataQueryManipulator
|
||||
|
||||
/**
|
||||
* @param string $parentClass
|
||||
* @return ManyManyThroughQueryManipulator
|
||||
* @return $this
|
||||
*/
|
||||
public function setParentClass($parentClass)
|
||||
{
|
||||
|
@ -13,10 +13,13 @@ use Traversable;
|
||||
|
||||
/**
|
||||
* A decorator that wraps around a data list in order to provide pagination.
|
||||
*
|
||||
* @template TList of SS_List
|
||||
* @template T
|
||||
* @extends ListDecorator<TList, T>
|
||||
*/
|
||||
class PaginatedList extends ListDecorator
|
||||
{
|
||||
|
||||
protected $request;
|
||||
protected $getVar = 'start';
|
||||
|
||||
@ -28,7 +31,7 @@ class PaginatedList extends ListDecorator
|
||||
/**
|
||||
* Constructs a new paginated list instance around a list.
|
||||
*
|
||||
* @param SS_List $list The list to paginate. The getRange method will
|
||||
* @param TList<T> $list The list to paginate. The getRange method will
|
||||
* be used to get the subset of objects to show.
|
||||
* @param array|ArrayAccess $request Either a map of request parameters or
|
||||
* request object that the pagination offset is read from.
|
||||
|
@ -10,6 +10,10 @@ use Traversable;
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
@ -30,7 +34,7 @@ class PolymorphicHasManyList extends HasManyList
|
||||
/**
|
||||
* Retrieve the name of the class this (has_many) relation is filtered by
|
||||
*
|
||||
* @return string
|
||||
* @return class-string<TForeign>
|
||||
*/
|
||||
public function getForeignClass()
|
||||
{
|
||||
@ -80,10 +84,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 (has_one) relation field. Used
|
||||
* to generate the ID, Class, and Relation 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)
|
||||
{
|
||||
@ -104,13 +108,6 @@ class PolymorphicHasManyList extends HasManyList
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the item to this relation.
|
||||
*
|
||||
* It does so by setting the relationFilters.
|
||||
*
|
||||
* @param DataObject|int $item The DataObject to be added, or its ID
|
||||
*/
|
||||
public function add($item)
|
||||
{
|
||||
if (is_numeric($item)) {
|
||||
@ -155,12 +152,6 @@ class PolymorphicHasManyList extends HasManyList
|
||||
$item->write();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function remove($item)
|
||||
{
|
||||
if (!($item instanceof $this->dataClass)) {
|
||||
|
@ -12,6 +12,12 @@ use SilverStripe\ORM\FieldType\DBField;
|
||||
* @method Relation relation($relationName)
|
||||
* @method Relation forForeignID($id)
|
||||
* @method string dataClass()
|
||||
*
|
||||
* @template T
|
||||
* @extends SS_List<T>
|
||||
* @extends Filterable<T>
|
||||
* @extends Sortable<T>
|
||||
* @extends Limitable<T>
|
||||
*/
|
||||
interface Relation extends SS_List, Filterable, Sortable, Limitable
|
||||
{
|
||||
@ -20,7 +26,7 @@ interface Relation extends SS_List, Filterable, Sortable, Limitable
|
||||
* Sets the ComponentSet to be the given ID list.
|
||||
* Records will be added and deleted as appropriate.
|
||||
*
|
||||
* @param array $idList List of IDs.
|
||||
* @param array<int> $idList List of IDs.
|
||||
*/
|
||||
public function setByIDList($idList);
|
||||
|
||||
@ -29,7 +35,7 @@ interface Relation extends SS_List, Filterable, Sortable, Limitable
|
||||
*
|
||||
* Does not return the IDs for unsaved DataObjects
|
||||
*
|
||||
* @return array
|
||||
* @return array<int>
|
||||
*/
|
||||
public function getIDList();
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -8,6 +8,10 @@ use IteratorAggregate;
|
||||
|
||||
/**
|
||||
* An interface that a class can implement to be treated as a list container.
|
||||
*
|
||||
* @template T
|
||||
* @extends ArrayAccess<array-key, T>
|
||||
* @extends IteratorAggregate<array-key, T>
|
||||
*/
|
||||
interface SS_List extends ArrayAccess, Countable, IteratorAggregate
|
||||
{
|
||||
@ -15,7 +19,7 @@ interface SS_List extends ArrayAccess, Countable, IteratorAggregate
|
||||
/**
|
||||
* Returns all the items in the list in an array.
|
||||
*
|
||||
* @return array
|
||||
* @return array<T>
|
||||
*/
|
||||
public function toArray();
|
||||
|
||||
@ -44,14 +48,14 @@ interface SS_List extends ArrayAccess, Countable, IteratorAggregate
|
||||
/**
|
||||
* Returns the first item in the list.
|
||||
*
|
||||
* @return mixed
|
||||
* @return T|null
|
||||
*/
|
||||
public function first();
|
||||
|
||||
/**
|
||||
* Returns the last item in the list.
|
||||
*
|
||||
* @return mixed
|
||||
* @return T|null
|
||||
*/
|
||||
public function last();
|
||||
|
||||
@ -71,7 +75,7 @@ interface SS_List extends ArrayAccess, Countable, IteratorAggregate
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
* @return T|null
|
||||
*/
|
||||
public function find($key, $value);
|
||||
|
||||
@ -87,7 +91,7 @@ interface SS_List extends ArrayAccess, Countable, IteratorAggregate
|
||||
* Walks the list using the specified callback
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return $this
|
||||
* @return static<T>
|
||||
*/
|
||||
public function each($callback);
|
||||
}
|
||||
|
@ -20,7 +20,8 @@ use Exception;
|
||||
* CAUTION: Will make all files in your /assets folder searchable by file name
|
||||
* unless "File" is excluded from FulltextSearchable::enable().
|
||||
*
|
||||
* @see http://doc.silverstripe.org/framework/en/tutorials/4-site-search
|
||||
* @template T of SiteTree|File
|
||||
* @extends DataExtension<T>
|
||||
*/
|
||||
class FulltextSearchable extends DataExtension
|
||||
{
|
||||
|
@ -42,6 +42,8 @@ use SilverStripe\ORM\DataQuery;
|
||||
* to include.
|
||||
*
|
||||
* @see http://doc.silverstripe.com/doku.php?id=searchcontext
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
class SearchContext
|
||||
{
|
||||
@ -51,7 +53,7 @@ class SearchContext
|
||||
* DataObject subclass to which search parameters relate to.
|
||||
* Also determines as which object each result is provided.
|
||||
*
|
||||
* @var string
|
||||
* @var class-string<T>
|
||||
*/
|
||||
protected $modelClass;
|
||||
|
||||
@ -84,7 +86,7 @@ class SearchContext
|
||||
* in the form of a $_REQUEST object.
|
||||
* CAUTION: All values should be treated as insecure client input.
|
||||
*
|
||||
* @param string $modelClass The base {@link DataObject} class that search properties related to.
|
||||
* @param class-string<T> $modelClass The base {@link DataObject} class that search properties related to.
|
||||
* Also used to generate a set of result objects based on this class.
|
||||
* @param FieldList $fields Optional. FormFields mapping to {@link DataObject::$db} properties
|
||||
* which are to be searched. Derived from modelclass using
|
||||
@ -144,7 +146,7 @@ class SearchContext
|
||||
* Falls back to {@link DataObject::$default_sort} if not provided.
|
||||
* @param int|array|null $limit
|
||||
* @param DataList $existingQuery
|
||||
* @return DataList
|
||||
* @return DataList<T>
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getQuery($searchParams, $sort = false, $limit = false, $existingQuery = null)
|
||||
@ -163,6 +165,7 @@ class SearchContext
|
||||
|
||||
/**
|
||||
* Perform a search on the passed DataList based on $this->searchParams.
|
||||
* @return DataList<T>
|
||||
*/
|
||||
private function search(DataList $query): DataList
|
||||
{
|
||||
@ -185,6 +188,7 @@ class SearchContext
|
||||
*
|
||||
* @param array|bool|string $sort Database column to sort on.
|
||||
* @param int|array|null $limit
|
||||
* @return DataList<T>
|
||||
*/
|
||||
private function prepareQuery($sort, $limit, ?DataList $existingQuery): DataList
|
||||
{
|
||||
@ -248,6 +252,7 @@ class SearchContext
|
||||
* Use the global general search for searching across multiple fields.
|
||||
*
|
||||
* @param string|array $searchPhrase
|
||||
* @return DataList<T>
|
||||
*/
|
||||
private function generalFieldSearch(DataList $query, array $searchableFields, $searchPhrase): DataList
|
||||
{
|
||||
@ -293,6 +298,7 @@ class SearchContext
|
||||
* Search against a single field
|
||||
*
|
||||
* @param string|array $searchPhrase
|
||||
* @return DataList<T>
|
||||
*/
|
||||
private function individualFieldSearch(DataList $query, array $searchableFields, string $searchField, $searchPhrase): DataList
|
||||
{
|
||||
@ -338,7 +344,7 @@ class SearchContext
|
||||
* @param array $searchParams
|
||||
* @param array|bool|string $sort
|
||||
* @param array|null|string $limit
|
||||
* @return DataList
|
||||
* @return DataList<T>
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getResults($searchParams, $sort = false, $limit = null)
|
||||
@ -365,7 +371,7 @@ class SearchContext
|
||||
* Accessor for the filter attached to a named field.
|
||||
*
|
||||
* @param string $name
|
||||
* @return SearchFilter
|
||||
* @return SearchFilter|null
|
||||
*/
|
||||
public function getFilter($name)
|
||||
{
|
||||
@ -389,7 +395,7 @@ class SearchContext
|
||||
/**
|
||||
* Overwrite the current search context filter map.
|
||||
*
|
||||
* @param array $filters
|
||||
* @param SearchFilter[] $filters
|
||||
*/
|
||||
public function setFilters($filters)
|
||||
{
|
||||
@ -486,7 +492,7 @@ class SearchContext
|
||||
* for each field. Returns an ArrayList of ArrayData, suitable for
|
||||
* rendering on a template.
|
||||
*
|
||||
* @return ArrayList
|
||||
* @return ArrayList<ArrayData>
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
|
@ -11,6 +11,9 @@ namespace SilverStripe\ORM;
|
||||
* @see SS_List
|
||||
* @see Filterable
|
||||
* @see Limitable
|
||||
*
|
||||
* @template T
|
||||
* @implements SS_List<T>
|
||||
*/
|
||||
interface Sortable extends SS_List
|
||||
{
|
||||
@ -27,11 +30,12 @@ interface Sortable extends SS_List
|
||||
* Return a new instance of this list that is sorted 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.
|
||||
*
|
||||
* @return static
|
||||
* @example $list = $list->sort('Name'); // default ASC sorting
|
||||
* @example $list = $list->sort('Name DESC'); // DESC sorting
|
||||
* @example $list = $list->sort('Name', 'ASC');
|
||||
* @example $list = $list->sort(array('Name'=>'ASC,'Age'=>'DESC'));
|
||||
*
|
||||
* @return static<T>
|
||||
*/
|
||||
public function sort();
|
||||
|
||||
@ -39,8 +43,9 @@ interface Sortable extends SS_List
|
||||
/**
|
||||
* Return a new instance of this list based on reversing the current sort.
|
||||
*
|
||||
* @return Sortable
|
||||
* @example $list = $list->reverse();
|
||||
*
|
||||
* @return static<T>
|
||||
*/
|
||||
public function reverse();
|
||||
}
|
||||
|
@ -17,6 +17,10 @@ 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
|
||||
* @extends ArrayList<T>
|
||||
* @implements Relation<T>
|
||||
*/
|
||||
class UnsavedRelationList extends ArrayList implements Relation
|
||||
{
|
||||
@ -38,7 +42,7 @@ class UnsavedRelationList extends ArrayList implements Relation
|
||||
/**
|
||||
* The DataObject class name that this relation is querying
|
||||
*
|
||||
* @var string
|
||||
* @var class-string<T>
|
||||
*/
|
||||
protected $dataClass;
|
||||
|
||||
@ -54,7 +58,7 @@ class UnsavedRelationList extends ArrayList implements Relation
|
||||
*
|
||||
* @param string $baseClass
|
||||
* @param string $relationName
|
||||
* @param string $dataClass The DataObject class used in the relation
|
||||
* @param class-string<T> $dataClass The DataObject class used in the relation
|
||||
*/
|
||||
public function __construct($baseClass, $relationName, $dataClass)
|
||||
{
|
||||
@ -112,7 +116,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()
|
||||
{
|
||||
@ -130,8 +134,6 @@ 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
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
@ -209,8 +211,6 @@ class UnsavedRelationList extends ArrayList implements Relation
|
||||
* Returns an array with both the keys and values set to the IDs of the records in this list.
|
||||
* Does not respect sort order. Use ->column("ID") to get an ID list with the current sort.
|
||||
* Does not return the IDs for unsaved DataObjects.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getIDList()
|
||||
{
|
||||
@ -230,11 +230,6 @@ class UnsavedRelationList extends ArrayList implements Relation
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first item in the list
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
$item = reset($this->items) ?: null;
|
||||
@ -247,11 +242,6 @@ class UnsavedRelationList extends ArrayList implements Relation
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last item in the list
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function last()
|
||||
{
|
||||
$item = end($this->items) ?: null;
|
||||
@ -291,7 +281,7 @@ 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)
|
||||
{
|
||||
|
@ -96,7 +96,6 @@ class BasicAuth
|
||||
|
||||
try {
|
||||
if ($request->getHeader('PHP_AUTH_USER') && $request->getHeader('PHP_AUTH_PW')) {
|
||||
/** @var MemberAuthenticator $authenticator */
|
||||
$authenticators = Security::singleton()->getApplicableAuthenticators(Authenticator::LOGIN);
|
||||
|
||||
foreach ($authenticators as $name => $authenticator) {
|
||||
|
@ -152,7 +152,6 @@ class DefaultAdminService
|
||||
$this->extend('beforeFindOrCreateAdmin', $email, $name);
|
||||
|
||||
// Find member
|
||||
/** @var Member $admin */
|
||||
$admin = Member::get()
|
||||
->filter('Email', $email)
|
||||
->first();
|
||||
|
@ -97,7 +97,6 @@ class Group extends DataObject
|
||||
$doSet = new ArrayList();
|
||||
|
||||
$children = Group::get()->filter("ParentID", $this->ID);
|
||||
/** @var Group $child */
|
||||
foreach ($children as $child) {
|
||||
$doSet->push($child);
|
||||
$doSet->merge($child->getAllChildren());
|
||||
@ -165,12 +164,10 @@ class Group extends DataObject
|
||||
$config->removeComponentsByType(GridFieldDeleteAction::class);
|
||||
$config->addComponent(GridFieldGroupDeleteAction::create($this->ID), GridFieldPageCount::class);
|
||||
|
||||
/** @var GridFieldAddExistingAutocompleter $autocompleter */
|
||||
$autocompleter = $config->getComponentByType(GridFieldAddExistingAutocompleter::class);
|
||||
$autocompleter
|
||||
->setResultsFormat('$Title ($Email)')
|
||||
->setSearchFields(['FirstName', 'Surname', 'Email']);
|
||||
/** @var GridFieldDetailForm $detailForm */
|
||||
$detailForm = $config->getComponentByType(GridFieldDetailForm::class);
|
||||
$detailForm
|
||||
->setItemEditFormCallback(function ($form) use ($group) {
|
||||
@ -307,7 +304,7 @@ class Group extends DataObject
|
||||
* See {@link DirectMembers()} for retrieving members without any inheritance.
|
||||
*
|
||||
* @param string $filter
|
||||
* @return ManyManyList
|
||||
* @return ManyManyList<Member>
|
||||
*/
|
||||
public function Members($filter = '')
|
||||
{
|
||||
@ -338,6 +335,7 @@ class Group extends DataObject
|
||||
|
||||
/**
|
||||
* Return only the members directly added to this group
|
||||
* @return ManyManyList<Member>
|
||||
*/
|
||||
public function DirectMembers()
|
||||
{
|
||||
@ -650,7 +648,7 @@ class Group extends DataObject
|
||||
* Returns all of the children for the CMS Tree.
|
||||
* Filters to only those groups that the current user can edit
|
||||
*
|
||||
* @return ArrayList
|
||||
* @return ArrayList<DataObject>
|
||||
*/
|
||||
public function AllChildrenIncludingDeleted()
|
||||
{
|
||||
|
@ -8,6 +8,9 @@ use SilverStripe\ORM\DataExtension;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\Core\Cache\MemberCacheFlusher;
|
||||
|
||||
/**
|
||||
* @extends DataExtension<Member|Group>
|
||||
*/
|
||||
class InheritedPermissionFlusher extends DataExtension implements Flushable
|
||||
{
|
||||
/**
|
||||
|
@ -417,7 +417,6 @@ class InheritedPermissions implements PermissionChecker, MemberCacheFlusher
|
||||
->execute();
|
||||
|
||||
foreach ($potentiallyInherited as $item) {
|
||||
/** @var DataObject|Hierarchy $item */
|
||||
if ($item['ParentID']) {
|
||||
if (!isset($groupedByParent[$item['ParentID']])) {
|
||||
$groupedByParent[$item['ParentID']] = [];
|
||||
|
@ -14,6 +14,8 @@ use SilverStripe\ORM\ManyManyList;
|
||||
* @method ManyManyList<Member> EditorMembers()
|
||||
* @method ManyManyList<Group> ViewerGroups()
|
||||
* @method ManyManyList<Member> ViewerMembers()
|
||||
*
|
||||
* @extends DataExtension<DataObject>
|
||||
*/
|
||||
class InheritedPermissionsExtension extends DataExtension
|
||||
{
|
||||
|
@ -81,7 +81,7 @@ class LoginAttempt extends DataObject
|
||||
* Get all login attempts for the given email address
|
||||
*
|
||||
* @param string $email
|
||||
* @return DataList|LoginAttempt[]
|
||||
* @return DataList<LoginAttempt>
|
||||
*/
|
||||
public static function getByEmail($email)
|
||||
{
|
||||
|
@ -34,7 +34,6 @@ abstract class LoginForm extends Form
|
||||
{
|
||||
$this->authenticatorClass = $class;
|
||||
|
||||
/** @var FieldList|null $fields */
|
||||
$fields = $this->Fields();
|
||||
if (!$fields) {
|
||||
return $this;
|
||||
|
@ -584,7 +584,6 @@ class Member extends DataObject
|
||||
*/
|
||||
public static function member_from_autologinhash($hash, $login = false)
|
||||
{
|
||||
/** @var Member $member */
|
||||
$member = static::get()->filter([
|
||||
'AutoLoginHash' => $hash,
|
||||
'AutoLoginExpired:GreaterThan' => DBDatetime::now()->getValue(),
|
||||
@ -610,7 +609,6 @@ class Member extends DataObject
|
||||
|
||||
// Exclude expired
|
||||
if (static::config()->get('temp_id_lifetime')) {
|
||||
/** @var DataList|Member[] $members */
|
||||
$members = $members->filter('TempIDExpired:GreaterThan', DBDatetime::now()->getValue());
|
||||
}
|
||||
|
||||
@ -657,7 +655,6 @@ class Member extends DataObject
|
||||
$label = $editingPassword
|
||||
? _t(__CLASS__ . '.EDIT_PASSWORD', 'New Password')
|
||||
: $this->fieldLabel('Password');
|
||||
/** @var ConfirmedPasswordField $password */
|
||||
$password = ConfirmedPasswordField::create(
|
||||
'Password',
|
||||
$label,
|
||||
@ -1176,7 +1173,7 @@ class Member extends DataObject
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ManyManyList|UnsavedRelationList
|
||||
* @return ManyManyList<Group>|UnsavedRelationList<Group>
|
||||
*/
|
||||
public function DirectGroups()
|
||||
{
|
||||
@ -1212,7 +1209,6 @@ class Member extends DataObject
|
||||
|
||||
$membersList = new ArrayList();
|
||||
// This is a bit ineffective, but follow the ORM style
|
||||
/** @var Group $group */
|
||||
foreach (Group::get()->byIDs($groupIDList) as $group) {
|
||||
$membersList->merge($group->Members());
|
||||
}
|
||||
@ -1332,7 +1328,6 @@ class Member extends DataObject
|
||||
$rootTabSet = $fields->fieldByName("Root");
|
||||
/** @var Tab $mainTab */
|
||||
$mainTab = $rootTabSet->fieldByName("Main");
|
||||
/** @var FieldList $mainFields */
|
||||
$mainFields = $mainTab->getChildren();
|
||||
|
||||
// Build change password field
|
||||
|
@ -66,7 +66,6 @@ class ChangePasswordHandler extends RequestHandler
|
||||
$request = $this->getRequest();
|
||||
|
||||
// Extract the member from the URL.
|
||||
/** @var Member $member */
|
||||
$member = null;
|
||||
if ($request->getVar('m') !== null) {
|
||||
$member = Member::get()->filter(['ID' => (int)$request->getVar('m')])->first();
|
||||
@ -153,7 +152,6 @@ class ChangePasswordHandler extends RequestHandler
|
||||
{
|
||||
// if there is a current member, they should be logged out
|
||||
if ($curMember = Security::getCurrentUser()) {
|
||||
/** @var LogoutHandler $handler */
|
||||
Injector::inst()->get(IdentityStore::class)->logOut();
|
||||
}
|
||||
|
||||
@ -275,7 +273,6 @@ class ChangePasswordHandler extends RequestHandler
|
||||
$member->write();
|
||||
|
||||
if ($member->canLogin()) {
|
||||
/** @var IdentityStore $identityStore */
|
||||
$identityStore = Injector::inst()->get(IdentityStore::class);
|
||||
$identityStore->logIn($member, false, $this->getRequest());
|
||||
}
|
||||
|
@ -145,7 +145,6 @@ class CookieAuthenticationHandler implements AuthenticationHandler
|
||||
}
|
||||
|
||||
// check if autologin token matches
|
||||
/** @var Member $member */
|
||||
$member = Member::get()->byID($uid);
|
||||
if (!$member) {
|
||||
return null;
|
||||
@ -153,7 +152,6 @@ class CookieAuthenticationHandler implements AuthenticationHandler
|
||||
|
||||
$hash = $member->encryptWithUserSettings($token);
|
||||
|
||||
/** @var RememberLoginHash $rememberLoginHash */
|
||||
$rememberLoginHash = RememberLoginHash::get()
|
||||
->filter([
|
||||
'MemberID' => $member->ID,
|
||||
|
@ -115,7 +115,6 @@ class LoginHandler extends RequestHandler
|
||||
|
||||
$this->extend('beforeLogin');
|
||||
// Successful login
|
||||
/** @var ValidationResult $result */
|
||||
if ($member = $this->checkLogin($data, $request, $result)) {
|
||||
$this->performLogin($member, $data, $request);
|
||||
// Allow operations on the member after successful login
|
||||
@ -241,7 +240,6 @@ class LoginHandler extends RequestHandler
|
||||
{
|
||||
/** IdentityStore */
|
||||
$rememberMe = (isset($data['Remember']) && Security::config()->get('autologin_enabled'));
|
||||
/** @var IdentityStore $identityStore */
|
||||
$identityStore = Injector::inst()->get(IdentityStore::class);
|
||||
$identityStore->logIn($member, $rememberMe, $request);
|
||||
|
||||
|
@ -165,7 +165,6 @@ class LostPasswordHandler extends RequestHandler
|
||||
return $dataValidation;
|
||||
}
|
||||
|
||||
/** @var Member $member */
|
||||
$member = $this->getMemberFromData($data);
|
||||
|
||||
// Allow vetoing forgot password requests
|
||||
@ -241,7 +240,6 @@ class LostPasswordHandler extends RequestHandler
|
||||
protected function sendEmail($member, $token)
|
||||
{
|
||||
try {
|
||||
/** @var Email $email */
|
||||
$email = Email::create()
|
||||
->setHTMLTemplate('SilverStripe\\Control\\Email\\ForgotPasswordEmail')
|
||||
->setData($member)
|
||||
|
@ -90,7 +90,6 @@ class MemberAuthenticator implements Authenticator
|
||||
if (!$member && $email) {
|
||||
// Find user by email
|
||||
$identifierField = Member::config()->get('unique_identifier_field');
|
||||
/** @var Member $member */
|
||||
$member = Member::get()
|
||||
->filter([$identifierField => $email])
|
||||
->first();
|
||||
|
@ -62,7 +62,6 @@ class SessionAuthenticationHandler implements AuthenticationHandler
|
||||
if (!$id) {
|
||||
return null;
|
||||
}
|
||||
/** @var Member $member */
|
||||
$member = DataObject::get_by_id(Member::class, $id);
|
||||
return $member;
|
||||
}
|
||||
@ -86,7 +85,6 @@ class SessionAuthenticationHandler implements AuthenticationHandler
|
||||
|
||||
// Activate sudo mode on login so the user doesn't have to reauthenticate for sudo
|
||||
// actions until the sudo mode timeout expires
|
||||
/** @var SudoModeServiceInterface $service */
|
||||
$service = Injector::inst()->get(SudoModeServiceInterface::class);
|
||||
$service->activate($session);
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ use SilverStripe\ORM\Queries\SQLSelect;
|
||||
/**
|
||||
* Represents a set of Groups attached to a member.
|
||||
* Handles the hierarchy logic.
|
||||
*
|
||||
* @extends ManyManyList<Group>
|
||||
*/
|
||||
class Member_GroupSet extends ManyManyList
|
||||
{
|
||||
|
@ -227,7 +227,6 @@ class PasswordValidator
|
||||
->where(['"MemberPassword"."MemberID"' => $member->ID])
|
||||
->sort('"Created" DESC, "ID" DESC')
|
||||
->limit($historicCount);
|
||||
/** @var MemberPassword $previousPassword */
|
||||
foreach ($previousPasswords as $previousPassword) {
|
||||
if ($previousPassword->checkPassword($password)) {
|
||||
$error = _t(
|
||||
|
@ -127,7 +127,6 @@ class PermissionCheckboxSetField extends FormField
|
||||
// Get all permissions from roles
|
||||
if ($record->Roles()->count()) {
|
||||
foreach ($record->Roles() as $role) {
|
||||
/** @var PermissionRole $role */
|
||||
foreach ($role->Codes() as $code) {
|
||||
if (!isset($inheritedCodes[$code->Code])) {
|
||||
$inheritedCodes[$code->Code] = [];
|
||||
|
@ -169,7 +169,6 @@ class RememberLoginHash extends DataObject
|
||||
if (static::config()->force_single_token) {
|
||||
RememberLoginHash::get()->filter('MemberID', $member->ID)->removeAll();
|
||||
}
|
||||
/** @var RememberLoginHash $rememberLoginHash */
|
||||
$rememberLoginHash = RememberLoginHash::create();
|
||||
do {
|
||||
$deviceID = $rememberLoginHash->getNewDeviceID();
|
||||
|
@ -38,7 +38,6 @@ class RequestAuthenticationHandler implements AuthenticationHandler
|
||||
|
||||
public function authenticateRequest(HTTPRequest $request)
|
||||
{
|
||||
/** @var AuthenticationHandler $handler */
|
||||
foreach ($this->getHandlers() as $name => $handler) {
|
||||
// in order to add cookies, etc
|
||||
$member = $handler->authenticateRequest($request);
|
||||
|
@ -253,7 +253,6 @@ class Security extends Controller implements TemplateGlobalProvider
|
||||
{
|
||||
$authenticators = $this->getAuthenticators();
|
||||
|
||||
/** @var Authenticator $authenticator */
|
||||
foreach ($authenticators as $name => $authenticator) {
|
||||
if (!($authenticator->supportedServices() & $service)) {
|
||||
unset($authenticators[$name]);
|
||||
@ -937,7 +936,6 @@ class Security extends Controller implements TemplateGlobalProvider
|
||||
{
|
||||
$handlers = [];
|
||||
$authenticators = $this->getApplicableAuthenticators(Authenticator::RESET_PASSWORD);
|
||||
/** @var Authenticator $authenticator */
|
||||
foreach ($authenticators as $authenticator) {
|
||||
$handlers[] = $authenticator->getLostPasswordHandler(
|
||||
Controller::join_links($this->Link(), 'lostpassword')
|
||||
@ -966,7 +964,6 @@ class Security extends Controller implements TemplateGlobalProvider
|
||||
*/
|
||||
public function changepassword()
|
||||
{
|
||||
/** @var array|Authenticator[] $authenticators */
|
||||
$authenticators = $this->getApplicableAuthenticators(Authenticator::CHANGE_PASSWORD);
|
||||
$handlers = [];
|
||||
foreach ($authenticators as $authenticator) {
|
||||
|
@ -47,8 +47,9 @@ class GenericTemplateGlobalProvider implements TemplateGlobalProvider
|
||||
* <% end_cached %>
|
||||
* </code>
|
||||
*
|
||||
* @param string $className
|
||||
* @return DataList
|
||||
* @template T of DataObject
|
||||
* @param class-string<T> $className
|
||||
* @return DataList<T>
|
||||
*/
|
||||
public static function getDataList($className)
|
||||
{
|
||||
|
@ -619,7 +619,6 @@ class ShortcodeParser
|
||||
$content = $this->getShortcodeReplacementText($tag);
|
||||
|
||||
if ($content) {
|
||||
/** @var HTMLValue $parsed */
|
||||
$parsed = HTMLValue::create($content);
|
||||
$body = $parsed->getBody();
|
||||
if ($body) {
|
||||
@ -658,7 +657,6 @@ class ShortcodeParser
|
||||
// use a proper DOM
|
||||
list($content, $tags) = $this->replaceElementTagsWithMarkers($content);
|
||||
|
||||
/** @var HTMLValue $htmlvalue */
|
||||
$htmlvalue = Injector::inst()->create(HTMLValue::class, $content);
|
||||
|
||||
// Now parse the result into a DOM
|
||||
|
@ -242,7 +242,7 @@ class EmbedShortcodeProvider implements ShortcodeHandler
|
||||
*
|
||||
* @param array $arguments List of embed arguments
|
||||
* @param array $exclude List of attribute names to exclude from the resulting list
|
||||
* @return ArrayList
|
||||
* @return ArrayList<ArrayData>
|
||||
*/
|
||||
private static function buildAttributeListFromArguments(array $arguments, array $exclude = []): ArrayList
|
||||
{
|
||||
|
@ -18,6 +18,7 @@ use SilverStripe\Core\Extensible;
|
||||
use SilverStripe\Core\Injector\Injectable;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\Dev\Debug;
|
||||
use SilverStripe\Dev\Deprecation;
|
||||
use SilverStripe\ORM\ArrayLib;
|
||||
use SilverStripe\ORM\FieldType\DBField;
|
||||
use SilverStripe\ORM\FieldType\DBHTMLText;
|
||||
@ -644,10 +645,13 @@ class ViewableData implements IteratorAggregate
|
||||
* This is useful so you can use a single record inside a <% control %> block in a template - and then use
|
||||
* to access individual fields on this object.
|
||||
*
|
||||
* @deprecated 5.2.0 Will be removed without equivalent functionality
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator(): Traversable
|
||||
{
|
||||
Deprecation::notice('5.2.0', 'Will be removed without equivalent functionality');
|
||||
return new ArrayIterator([$this]);
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,9 @@ use SilverStripe\Core\Manifest\ModuleManifest;
|
||||
* way to access instance methods which don't rely on instance
|
||||
* data (e.g. the custom SilverStripe static handling).
|
||||
*
|
||||
* @param string $className
|
||||
* @return mixed
|
||||
* @template T of object
|
||||
* @param class-string<T> $className
|
||||
* @return T|mixed
|
||||
*/
|
||||
function singleton($className)
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ class SSListContainsOnlyMatchingItemsTest extends SapphireTest
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayList|Member[]
|
||||
* @return ArrayList<Member>
|
||||
*/
|
||||
private function getListToMatch()
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ class SSListContainsOnlyTest extends SapphireTest
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayList|Member[]
|
||||
* @return ArrayList<Member>
|
||||
*/
|
||||
private function getListToMatch()
|
||||
{
|
||||
|
@ -77,7 +77,7 @@ class SSListContainsTest extends SapphireTest
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayList|Member[]
|
||||
* @return ArrayList<Member>
|
||||
*/
|
||||
private function getListToMatch()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user