mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
FIX Don't load data up front for lazy-loaded searchable dropdown (#11278)
This commit is contained in:
parent
9546450cf2
commit
1e0b9056f5
@ -9,7 +9,7 @@ use SilverStripe\ORM\DataList;
|
|||||||
class SearchableDropdownField extends DropdownField
|
class SearchableDropdownField extends DropdownField
|
||||||
{
|
{
|
||||||
use SearchableDropdownTrait;
|
use SearchableDropdownTrait;
|
||||||
|
|
||||||
// This needs to be defined on the class, not the trait, otherwise there is a PHP error
|
// This needs to be defined on the class, not the trait, otherwise there is a PHP error
|
||||||
protected $schemaComponent = 'SearchableDropdownField';
|
protected $schemaComponent = 'SearchableDropdownField';
|
||||||
|
|
||||||
|
@ -265,6 +265,13 @@ trait SearchableDropdownTrait
|
|||||||
return $this->getListMap($this->sourceList);
|
return $this->getListMap($this->sourceList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function Field($properties = [])
|
||||||
|
{
|
||||||
|
$context = $this;
|
||||||
|
$this->extend('onBeforeRender', $context, $properties);
|
||||||
|
return $context->customise($properties)->renderWith($context->getTemplates());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @param mixed $source
|
* @param mixed $source
|
||||||
*/
|
*/
|
||||||
@ -450,9 +457,16 @@ trait SearchableDropdownTrait
|
|||||||
|
|
||||||
public function getSchemaStateDefaults(): array
|
public function getSchemaStateDefaults(): array
|
||||||
{
|
{
|
||||||
$data = parent::getSchemaStateDefaults();
|
$state = [
|
||||||
$data = $this->updateDataForSchema($data);
|
'name' => $this->getName(),
|
||||||
return $data;
|
'id' => $this->ID(),
|
||||||
|
'value' => $this->getDefaultSchemaValue(),
|
||||||
|
'message' => $this->getSchemaMessage(),
|
||||||
|
'data' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
$state = $this->updateDataForSchema($state);
|
||||||
|
return $state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -467,6 +481,14 @@ trait SearchableDropdownTrait
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getDefaultSchemaValue()
|
||||||
|
{
|
||||||
|
if (!$this->getIsLazyLoaded() && $this->hasMethod('getDefaultValue')) {
|
||||||
|
return $this->getDefaultValue();
|
||||||
|
}
|
||||||
|
return $this->Value();
|
||||||
|
}
|
||||||
|
|
||||||
private function getOptionsForSearchRequest(string $term): array
|
private function getOptionsForSearchRequest(string $term): array
|
||||||
{
|
{
|
||||||
if (!$this->sourceList) {
|
if (!$this->sourceList) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace SilverStripe\Forms\Tests;
|
namespace SilverStripe\Forms\Tests;
|
||||||
|
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
|
use SilverStripe\Core\ClassInfo;
|
||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
use SilverStripe\Forms\SearchableDropdownField;
|
use SilverStripe\Forms\SearchableDropdownField;
|
||||||
@ -217,4 +218,47 @@ class SearchableDropdownTraitTest extends SapphireTest
|
|||||||
$this->assertSame('My placeholder', $schema['placeholder']);
|
$this->assertSame('My placeholder', $schema['placeholder']);
|
||||||
$this->assertFalse($schema['searchable']);
|
$this->assertFalse($schema['searchable']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function provideLazyLoadedDoesntCallGetSource()
|
||||||
|
{
|
||||||
|
$methodsToCall = [
|
||||||
|
'Field',
|
||||||
|
'getSchemaStateDefaults',
|
||||||
|
'getSchemaState',
|
||||||
|
'getSchemaDataDefaults',
|
||||||
|
'getSchemaData',
|
||||||
|
];
|
||||||
|
$classes = [
|
||||||
|
SearchableMultiDropdownField::class,
|
||||||
|
SearchableDropdownField::class,
|
||||||
|
];
|
||||||
|
$scenarios = [];
|
||||||
|
foreach ($classes as $class) {
|
||||||
|
foreach ($methodsToCall as $method) {
|
||||||
|
$scenarios[] = [
|
||||||
|
'fieldClass' => $class,
|
||||||
|
'methodToCall' => $method,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $scenarios;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideLazyLoadedDoesntCallGetSource
|
||||||
|
*/
|
||||||
|
public function testLazyLoadedDoesntCallGetSource(string $fieldClass, string $methodToCall)
|
||||||
|
{
|
||||||
|
// Some methods aren't shared between the two form fields.
|
||||||
|
if (!ClassInfo::hasMethod($fieldClass, $methodToCall)) {
|
||||||
|
$this->markTestSkipped("$fieldClass doesn't have method $methodToCall - skipping");
|
||||||
|
}
|
||||||
|
// We have to disable the constructor because it ends up calling a static method, and we can't call static methods on mocks.
|
||||||
|
$mockField = $this->getMockBuilder($fieldClass)->onlyMethods(['getSource'])->disableOriginalConstructor()->getMock();
|
||||||
|
$mockField->expects($this->never())->method('getSource');
|
||||||
|
$mockField->setIsLazyLoaded(true);
|
||||||
|
$mockField->setSource(Team::get());
|
||||||
|
$mockField->setForm(new Form());
|
||||||
|
$mockField->$methodToCall();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user