Fixes and some refactoring for max nesting level handling in

nested gridfields.
This commit is contained in:
Niklas Forsdahl 2024-04-24 09:19:32 +03:00
parent cfcf8d2e8e
commit 847ce07ab0
2 changed files with 27 additions and 13 deletions

View File

@ -16,7 +16,6 @@ use SilverStripe\Forms\GridField\GridField_DataManipulator;
use SilverStripe\Forms\GridField\GridField_HTMLProvider; use SilverStripe\Forms\GridField\GridField_HTMLProvider;
use SilverStripe\Forms\GridField\GridField_SaveHandler; use SilverStripe\Forms\GridField\GridField_SaveHandler;
use SilverStripe\Forms\GridField\GridField_URLHandler; use SilverStripe\Forms\GridField\GridField_URLHandler;
use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
use SilverStripe\Forms\GridField\GridFieldStateAware; use SilverStripe\Forms\GridField\GridFieldStateAware;
use SilverStripe\ORM\DataList; use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
@ -45,7 +44,12 @@ class GridFieldNestedForm extends AbstractGridFieldComponent implements
'handleNestedItem' 'handleNestedItem'
]; ];
private static $max_nesting_level = 10; /**
* The default max nesting level. Nesting further than this will throw an exception.
*
* @var boolean
*/
private static $default_max_nesting_level = 10;
/** /**
* @var string * @var string
@ -153,20 +157,29 @@ class GridFieldNestedForm extends AbstractGridFieldComponent implements
return $this; return $this;
} }
/**
* Get the max nesting level allowed for this grid field.
* @return int
*/
public function getMaxNestingLevel() public function getMaxNestingLevel()
{ {
return $this->maxNestingLevel ?: $this->config()->max_nesting_level; return $this->maxNestingLevel ?: static::config()->get('default_max_nesting_level');
} }
protected function getNestingLevel($gridField) /**
* Check if we are currently at the max nesting level allowed.
* @return bool
*/
protected function atMaxNestingLevel(GridField $gridField): bool
{ {
$level = 0; $level = 0;
$c = $gridField->getForm()->getController(); $controller = $gridField->getForm()->getController();
while ($c && $c instanceof GridFieldDetailForm_ItemRequest) { $maxLevel = $this->getMaxNestingLevel();
$c = $c->getController(); while ($level < $maxLevel && $controller && $controller instanceof GridFieldNestedFormItemRequest) {
$controller = $controller->getController();
$level++; $level++;
} }
return $level; return $level >= $maxLevel;
} }
public function getColumnMetadata($gridField, $columnName) public function getColumnMetadata($gridField, $columnName)
@ -193,8 +206,7 @@ class GridFieldNestedForm extends AbstractGridFieldComponent implements
public function getColumnContent($gridField, $record, $columnName) public function getColumnContent($gridField, $record, $columnName)
{ {
$nestingLevel = $this->getNestingLevel($gridField); if ($this->atMaxNestingLevel($gridField)) {
if ($nestingLevel >= $this->getMaxNestingLevel()) {
return ''; return '';
} }
$gridField->addExtraClass('has-nested'); $gridField->addExtraClass('has-nested');
@ -328,8 +340,7 @@ class GridFieldNestedForm extends AbstractGridFieldComponent implements
public function handleNestedItem(GridField $gridField, $request = null, $record = null) public function handleNestedItem(GridField $gridField, $request = null, $record = null)
{ {
$nestingLevel = $this->getNestingLevel($gridField); if ($this->atMaxNestingLevel($gridField)) {
if ($nestingLevel >= $this->getMaxNestingLevel()) {
throw new Exception('Max nesting level reached'); throw new Exception('Max nesting level reached');
} }
if (!$record && $request) { if (!$record && $request) {

View File

@ -72,7 +72,10 @@ class GridFieldNestedFormItemRequest extends GridFieldDetailForm_ItemRequest
} }
if ($this->record->hasExtension(Hierarchy::class)) { if ($this->record->hasExtension(Hierarchy::class)) {
$config->addComponent(new GridFieldNestedForm(), GridFieldOrderableRows::class); $config->addComponent($nestedForm = new GridFieldNestedForm(), GridFieldOrderableRows::class);
// use max nesting level from parent component
$nestedForm->setMaxNestingLevel($this->component->getMaxNestingLevel());
/** @var GridFieldOrderableRows */ /** @var GridFieldOrderableRows */
$orderableRows = $config->getComponentByType(GridFieldOrderableRows::class); $orderableRows = $config->getComponentByType(GridFieldOrderableRows::class);
if ($orderableRows) { if ($orderableRows) {