mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
ENH Various changes to support SiteTree form field scaffolding (#11327)
This commit is contained in:
parent
a8c322029d
commit
64a17e09d4
@ -17,16 +17,16 @@ class FormScaffolder
|
||||
use Injectable;
|
||||
|
||||
/**
|
||||
* @var DataObject $obj The object defining the fields to be scaffolded
|
||||
* The object defining the fields to be scaffolded
|
||||
* through its metadata like $db, $searchable_fields, etc.
|
||||
*/
|
||||
protected $obj;
|
||||
protected DataObject $obj;
|
||||
|
||||
/**
|
||||
* @var boolean $tabbed Return fields in a tabset, with all main fields in the path "Root.Main",
|
||||
* Return fields in a tabset, with all main fields in the path "Root.Main",
|
||||
* relation fields in "Root.<relationname>" (if {@link $includeRelations} is enabled).
|
||||
*/
|
||||
public $tabbed = false;
|
||||
public bool $tabbed = false;
|
||||
|
||||
/**
|
||||
* Only set up the "Root.Main" tab, but skip scaffolding actual FormFields.
|
||||
@ -35,16 +35,10 @@ class FormScaffolder
|
||||
public bool $mainTabOnly = false;
|
||||
|
||||
/**
|
||||
* @var boolean $ajaxSafe
|
||||
* @deprecated 5.3.0 Will be removed without equivalent functionality.
|
||||
* Array of field names to use as an allow list.
|
||||
* If left blank, all fields from {@link DataObject->db()} will be included unless explicitly ignored.
|
||||
*/
|
||||
public $ajaxSafe = false;
|
||||
|
||||
/**
|
||||
* @var array $restrictFields Numeric array of a field name whitelist.
|
||||
* If left blank, all fields from {@link DataObject->db()} will be included.
|
||||
*/
|
||||
public $restrictFields;
|
||||
public array $restrictFields = [];
|
||||
|
||||
/**
|
||||
* Numeric array of field names and has_one relations to explicitly not scaffold.
|
||||
@ -52,15 +46,15 @@ class FormScaffolder
|
||||
public array $ignoreFields = [];
|
||||
|
||||
/**
|
||||
* @var array $fieldClasses Optional mapping of fieldnames to subclasses of {@link FormField}.
|
||||
* Optional mapping of fieldnames to subclasses of {@link FormField}.
|
||||
* By default the scaffolder will determine the field instance by {@link DBField::scaffoldFormField()}.
|
||||
*/
|
||||
public $fieldClasses;
|
||||
public array $fieldClasses = [];
|
||||
|
||||
/**
|
||||
* @var boolean $includeRelations Include has_many and many_many relations
|
||||
* Include has_many and many_many relations
|
||||
*/
|
||||
public $includeRelations = false;
|
||||
public bool|array $includeRelations = false;
|
||||
|
||||
/**
|
||||
* Array of relation names to use as an allow list.
|
||||
@ -106,7 +100,7 @@ class FormScaffolder
|
||||
// Add logical fields directly specified in db config
|
||||
foreach ($this->obj->config()->get('db') as $fieldName => $fieldType) {
|
||||
// Skip fields that aren't in the allow list
|
||||
if ($this->restrictFields && !in_array($fieldName, $this->restrictFields ?? [])) {
|
||||
if (!empty($this->restrictFields) && !in_array($fieldName, $this->restrictFields)) {
|
||||
continue;
|
||||
}
|
||||
// Skip ignored fields
|
||||
@ -114,7 +108,7 @@ class FormScaffolder
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->fieldClasses && isset($this->fieldClasses[$fieldName])) {
|
||||
if (isset($this->fieldClasses[$fieldName])) {
|
||||
$fieldClass = $this->fieldClasses[$fieldName];
|
||||
$fieldObject = new $fieldClass($fieldName);
|
||||
} else {
|
||||
@ -138,7 +132,7 @@ class FormScaffolder
|
||||
// add has_one relation fields
|
||||
if ($this->obj->hasOne()) {
|
||||
foreach ($this->obj->hasOne() as $relationship => $component) {
|
||||
if ($this->restrictFields && !in_array($relationship, $this->restrictFields ?? [])) {
|
||||
if (!empty($this->restrictFields) && !in_array($relationship, $this->restrictFields)) {
|
||||
continue;
|
||||
}
|
||||
if (in_array($relationship, $this->ignoreFields)) {
|
||||
@ -147,7 +141,7 @@ class FormScaffolder
|
||||
$fieldName = $component === 'SilverStripe\\ORM\\DataObject'
|
||||
? $relationship // Polymorphic has_one field is composite, so don't refer to ID subfield
|
||||
: "{$relationship}ID";
|
||||
if ($this->fieldClasses && isset($this->fieldClasses[$fieldName])) {
|
||||
if (isset($this->fieldClasses[$fieldName])) {
|
||||
$fieldClass = $this->fieldClasses[$fieldName];
|
||||
$hasOneField = new $fieldClass($fieldName);
|
||||
} else {
|
||||
@ -305,7 +299,6 @@ class FormScaffolder
|
||||
'restrictFields' => $this->restrictFields,
|
||||
'ignoreFields' => $this->ignoreFields,
|
||||
'fieldClasses' => $this->fieldClasses,
|
||||
'ajaxSafe' => $this->ajaxSafe
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,6 @@ class Tab extends CompositeField
|
||||
// Assign name and title (not assigned by parent constructor)
|
||||
$this->setName($name);
|
||||
$this->setTitle($title);
|
||||
$this->setID(Convert::raw2htmlid($name));
|
||||
}
|
||||
|
||||
public function ID()
|
||||
@ -99,6 +98,16 @@ class Tab extends CompositeField
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
// Use raw properties instead of ID() and getName() here because we
|
||||
// only want to check the actual raw values of those properties.
|
||||
if (($this->id ?? '') === Convert::raw2htmlid($this->name)) {
|
||||
$this->setID(Convert::raw2htmlid($name));
|
||||
}
|
||||
return parent::setName($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get child fields
|
||||
*
|
||||
|
@ -295,7 +295,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
private static array $scaffold_cms_fields_settings = [
|
||||
'includeRelations' => true,
|
||||
'tabbed' => true,
|
||||
'ajaxSafe' => true,
|
||||
];
|
||||
|
||||
/**
|
||||
@ -2396,8 +2395,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
{
|
||||
$params = array_merge(
|
||||
[
|
||||
'fieldClasses' => false,
|
||||
'restrictFields' => false
|
||||
'fieldClasses' => [],
|
||||
'restrictFields' => []
|
||||
],
|
||||
(array)$_params
|
||||
);
|
||||
@ -2487,10 +2486,9 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
'includeRelations' => false,
|
||||
'restrictRelations' => [],
|
||||
'ignoreRelations' => [],
|
||||
'restrictFields' => false,
|
||||
'restrictFields' => [],
|
||||
'ignoreFields' => [],
|
||||
'fieldClasses' => false,
|
||||
'ajaxSafe' => false
|
||||
'fieldClasses' => [],
|
||||
],
|
||||
(array)$_params
|
||||
);
|
||||
@ -2504,7 +2502,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
$fs->restrictFields = $params['restrictFields'];
|
||||
$fs->ignoreFields = $params['ignoreFields'];
|
||||
$fs->fieldClasses = $params['fieldClasses'];
|
||||
$fs->ajaxSafe = $params['ajaxSafe'];
|
||||
|
||||
$this->extend('updateFormScaffolder', $fs, $this);
|
||||
|
||||
|
@ -42,4 +42,21 @@ class InheritedPermissionsExtension extends DataExtension
|
||||
'ViewerMembers',
|
||||
'EditorMembers',
|
||||
];
|
||||
|
||||
/**
|
||||
* These fields will need to be added manually, since SiteTree wants it in the special settings tab
|
||||
* and nothing else in code that uses these fields is scaffolded.
|
||||
*/
|
||||
private static array $scaffold_cms_fields_settings = [
|
||||
'ignoreFields' => [
|
||||
'CanViewType',
|
||||
'CanEditType',
|
||||
],
|
||||
'ignoreRelations' => [
|
||||
'ViewerGroups',
|
||||
'EditorGroups',
|
||||
'ViewerMembers',
|
||||
'EditorMembers',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
30
tests/php/Forms/TabTest.php
Normal file
30
tests/php/Forms/TabTest.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Forms\Tests;
|
||||
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\Forms\Tab;
|
||||
|
||||
class TabTest extends SapphireTest
|
||||
{
|
||||
protected $usesDatabase = false;
|
||||
|
||||
public function testNameAndID(): void
|
||||
{
|
||||
// ID is set on instantiation based on the name
|
||||
$tab = new Tab('MyName _-()!@#$');
|
||||
$this->assertSame('MyName _-()!@#$', $tab->getName());
|
||||
$this->assertSame('MyName_-', $tab->ID());
|
||||
|
||||
// Changing the name changes the ID
|
||||
$tab->setName('NewName');
|
||||
$this->assertSame('NewName', $tab->getName());
|
||||
$this->assertSame('NewName', $tab->ID());
|
||||
|
||||
// If ID is explicitly set, changing the name doesn't override it
|
||||
$tab->setID('Custom-ID');
|
||||
$tab->setName('AnotherName');
|
||||
$this->assertSame('AnotherName', $tab->getName());
|
||||
$this->assertSame('Custom-ID', $tab->ID());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user