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
|
||||
{
|
||||
use SearchableDropdownTrait;
|
||||
|
||||
|
||||
// This needs to be defined on the class, not the trait, otherwise there is a PHP error
|
||||
protected $schemaComponent = 'SearchableDropdownField';
|
||||
|
||||
|
@ -265,6 +265,13 @@ trait SearchableDropdownTrait
|
||||
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
|
||||
*/
|
||||
@ -450,9 +457,16 @@ trait SearchableDropdownTrait
|
||||
|
||||
public function getSchemaStateDefaults(): array
|
||||
{
|
||||
$data = parent::getSchemaStateDefaults();
|
||||
$data = $this->updateDataForSchema($data);
|
||||
return $data;
|
||||
$state = [
|
||||
'name' => $this->getName(),
|
||||
'id' => $this->ID(),
|
||||
'value' => $this->getDefaultSchemaValue(),
|
||||
'message' => $this->getSchemaMessage(),
|
||||
'data' => [],
|
||||
];
|
||||
|
||||
$state = $this->updateDataForSchema($state);
|
||||
return $state;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -467,6 +481,14 @@ trait SearchableDropdownTrait
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function getDefaultSchemaValue()
|
||||
{
|
||||
if (!$this->getIsLazyLoaded() && $this->hasMethod('getDefaultValue')) {
|
||||
return $this->getDefaultValue();
|
||||
}
|
||||
return $this->Value();
|
||||
}
|
||||
|
||||
private function getOptionsForSearchRequest(string $term): array
|
||||
{
|
||||
if (!$this->sourceList) {
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace SilverStripe\Forms\Tests;
|
||||
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
use SilverStripe\Core\ClassInfo;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\Forms\FieldList;
|
||||
use SilverStripe\Forms\SearchableDropdownField;
|
||||
@ -217,4 +218,47 @@ class SearchableDropdownTraitTest extends SapphireTest
|
||||
$this->assertSame('My placeholder', $schema['placeholder']);
|
||||
$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