mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
NEW Allow DataObject classes to define scaffolded relation formfields (#11269)
This commit is contained in:
parent
64ac096b46
commit
be0eab2bae
@ -37,7 +37,7 @@
|
|||||||
"psr/http-message": "^1",
|
"psr/http-message": "^1",
|
||||||
"sebastian/diff": "^4.0",
|
"sebastian/diff": "^4.0",
|
||||||
"silverstripe/config": "^2",
|
"silverstripe/config": "^2",
|
||||||
"silverstripe/assets": "^2.2",
|
"silverstripe/assets": "^2.3",
|
||||||
"silverstripe/vendor-plugin": "^2",
|
"silverstripe/vendor-plugin": "^2",
|
||||||
"sminnee/callbacklist": "^0.1.1",
|
"sminnee/callbacklist": "^0.1.1",
|
||||||
"symfony/cache": "^6.1",
|
"symfony/cache": "^6.1",
|
||||||
|
@ -138,27 +138,37 @@ class FormScaffolder
|
|||||||
&& ($this->includeRelations === true || isset($this->includeRelations['has_many']))
|
&& ($this->includeRelations === true || isset($this->includeRelations['has_many']))
|
||||||
) {
|
) {
|
||||||
foreach ($this->obj->hasMany() as $relationship => $component) {
|
foreach ($this->obj->hasMany() as $relationship => $component) {
|
||||||
if ($this->tabbed) {
|
$includeInOwnTab = true;
|
||||||
$fields->findOrMakeTab(
|
$fieldLabel = $this->obj->fieldLabel($relationship);
|
||||||
"Root.$relationship",
|
|
||||||
$this->obj->fieldLabel($relationship)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$fieldClass = (isset($this->fieldClasses[$relationship]))
|
$fieldClass = (isset($this->fieldClasses[$relationship]))
|
||||||
? $this->fieldClasses[$relationship]
|
? $this->fieldClasses[$relationship]
|
||||||
: 'SilverStripe\\Forms\\GridField\\GridField';
|
: null;
|
||||||
/** @var GridField $grid */
|
if ($fieldClass) {
|
||||||
$grid = Injector::inst()->create(
|
/** @var GridField */
|
||||||
$fieldClass,
|
$hasManyField = Injector::inst()->create(
|
||||||
$relationship,
|
$fieldClass,
|
||||||
$this->obj->fieldLabel($relationship),
|
$relationship,
|
||||||
$this->obj->$relationship(),
|
$fieldLabel,
|
||||||
GridFieldConfig_RelationEditor::create()
|
$this->obj->$relationship(),
|
||||||
);
|
GridFieldConfig_RelationEditor::create()
|
||||||
if ($this->tabbed) {
|
);
|
||||||
$fields->addFieldToTab("Root.$relationship", $grid);
|
|
||||||
} else {
|
} else {
|
||||||
$fields->push($grid);
|
/** @var DataObject */
|
||||||
|
$hasManySingleton = singleton($component);
|
||||||
|
$hasManyField = $hasManySingleton->scaffoldFormFieldForHasMany($relationship, $fieldLabel, $this->obj, $includeInOwnTab);
|
||||||
|
}
|
||||||
|
if ($this->tabbed) {
|
||||||
|
if ($includeInOwnTab) {
|
||||||
|
$fields->findOrMakeTab(
|
||||||
|
"Root.$relationship",
|
||||||
|
$fieldLabel
|
||||||
|
);
|
||||||
|
$fields->addFieldToTab("Root.$relationship", $hasManyField);
|
||||||
|
} else {
|
||||||
|
$fields->addFieldToTab('Root.Main', $hasManyField);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$fields->push($hasManyField);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,7 +197,7 @@ class FormScaffolder
|
|||||||
*
|
*
|
||||||
* @param FieldList $fields Reference to the @FieldList to add fields to.
|
* @param FieldList $fields Reference to the @FieldList to add fields to.
|
||||||
* @param string $relationship The relationship identifier.
|
* @param string $relationship The relationship identifier.
|
||||||
* @param mixed $overrideFieldClass Specify the field class to use here or leave as null to use default.
|
* @param string|null $overrideFieldClass Specify the field class to use here or leave as null to use default.
|
||||||
* @param bool $tabbed Whether this relationship has it's own tab or not.
|
* @param bool $tabbed Whether this relationship has it's own tab or not.
|
||||||
* @param DataObject $dataObject The @DataObject that has the relation.
|
* @param DataObject $dataObject The @DataObject that has the relation.
|
||||||
*/
|
*/
|
||||||
@ -198,28 +208,37 @@ class FormScaffolder
|
|||||||
$tabbed,
|
$tabbed,
|
||||||
DataObject $dataObject
|
DataObject $dataObject
|
||||||
) {
|
) {
|
||||||
if ($tabbed) {
|
$includeInOwnTab = true;
|
||||||
$fields->findOrMakeTab(
|
$fieldLabel = $dataObject->fieldLabel($relationship);
|
||||||
"Root.$relationship",
|
|
||||||
$dataObject->fieldLabel($relationship)
|
if ($overrideFieldClass) {
|
||||||
|
/** @var GridField */
|
||||||
|
$manyManyField = Injector::inst()->create(
|
||||||
|
$overrideFieldClass,
|
||||||
|
$relationship,
|
||||||
|
$fieldLabel,
|
||||||
|
$dataObject->$relationship(),
|
||||||
|
GridFieldConfig_RelationEditor::create()
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
$manyManyComponent = DataObject::getSchema()->manyManyComponent(get_class($dataObject), $relationship);
|
||||||
|
/** @var DataObject */
|
||||||
|
$manyManySingleton = singleton($manyManyComponent['childClass']);
|
||||||
|
$manyManyField = $manyManySingleton->scaffoldFormFieldForManyMany($relationship, $fieldLabel, $dataObject, $includeInOwnTab);
|
||||||
}
|
}
|
||||||
|
|
||||||
$fieldClass = $overrideFieldClass ?: GridField::class;
|
|
||||||
|
|
||||||
/** @var GridField $grid */
|
|
||||||
$grid = Injector::inst()->create(
|
|
||||||
$fieldClass,
|
|
||||||
$relationship,
|
|
||||||
$dataObject->fieldLabel($relationship),
|
|
||||||
$dataObject->$relationship(),
|
|
||||||
GridFieldConfig_RelationEditor::create()
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($tabbed) {
|
if ($tabbed) {
|
||||||
$fields->addFieldToTab("Root.$relationship", $grid);
|
if ($includeInOwnTab) {
|
||||||
|
$fields->findOrMakeTab(
|
||||||
|
"Root.$relationship",
|
||||||
|
$fieldLabel
|
||||||
|
);
|
||||||
|
$fields->addFieldToTab("Root.$relationship", $manyManyField);
|
||||||
|
} else {
|
||||||
|
$fields->addFieldToTab('Root.Main', $manyManyField);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$fields->push($grid);
|
$fields->push($manyManyField);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,10 @@ use SilverStripe\Forms\FormField;
|
|||||||
use SilverStripe\Forms\FormScaffolder;
|
use SilverStripe\Forms\FormScaffolder;
|
||||||
use SilverStripe\Forms\CompositeValidator;
|
use SilverStripe\Forms\CompositeValidator;
|
||||||
use SilverStripe\Forms\FieldsValidator;
|
use SilverStripe\Forms\FieldsValidator;
|
||||||
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
|
||||||
use SilverStripe\Forms\HiddenField;
|
use SilverStripe\Forms\HiddenField;
|
||||||
|
use SilverStripe\Forms\SearchableDropdownField;
|
||||||
use SilverStripe\i18n\i18n;
|
use SilverStripe\i18n\i18n;
|
||||||
use SilverStripe\i18n\i18nEntityProvider;
|
use SilverStripe\i18n\i18nEntityProvider;
|
||||||
use SilverStripe\ORM\Connect\MySQLSchemaManager;
|
use SilverStripe\ORM\Connect\MySQLSchemaManager;
|
||||||
@ -26,6 +29,7 @@ use SilverStripe\ORM\FieldType\DBComposite;
|
|||||||
use SilverStripe\ORM\FieldType\DBDatetime;
|
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||||
use SilverStripe\ORM\FieldType\DBEnum;
|
use SilverStripe\ORM\FieldType\DBEnum;
|
||||||
use SilverStripe\ORM\FieldType\DBField;
|
use SilverStripe\ORM\FieldType\DBField;
|
||||||
|
use SilverStripe\ORM\FieldType\DBForeignKey;
|
||||||
use SilverStripe\ORM\Filters\PartialMatchFilter;
|
use SilverStripe\ORM\Filters\PartialMatchFilter;
|
||||||
use SilverStripe\ORM\Filters\SearchFilter;
|
use SilverStripe\ORM\Filters\SearchFilter;
|
||||||
use SilverStripe\ORM\Queries\SQLDelete;
|
use SilverStripe\ORM\Queries\SQLDelete;
|
||||||
@ -2485,6 +2489,70 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
return $fs->getFieldList();
|
return $fs->getFieldList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scaffold a form field for selecting records of this model type in a has_one relation.
|
||||||
|
*
|
||||||
|
* @param string $fieldName The name we usually expect the field to have. This is often the has_one relation
|
||||||
|
* name with "ID" suffixed to it.
|
||||||
|
* @param string $relationName The name of the actual has_one relation, without "ID" suffixed to it.
|
||||||
|
* Some form fields such as UploadField use this instead of the usual field name.
|
||||||
|
*/
|
||||||
|
public function scaffoldFormFieldForHasOne(
|
||||||
|
string $fieldName,
|
||||||
|
?string $fieldTitle,
|
||||||
|
string $relationName,
|
||||||
|
DataObject $ownerRecord
|
||||||
|
): FormField {
|
||||||
|
$labelField = $this->hasField('Title') ? 'Title' : 'Name';
|
||||||
|
$list = DataList::create(static::class);
|
||||||
|
$threshold = DBForeignKey::config()->get('dropdown_field_threshold');
|
||||||
|
$overThreshold = $list->count() > $threshold;
|
||||||
|
$field = SearchableDropdownField::create($fieldName, $fieldTitle, $list, $labelField)
|
||||||
|
->setIsLazyLoaded($overThreshold)
|
||||||
|
->setLazyLoadLimit($threshold);
|
||||||
|
return $field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scaffold a form field for selecting records of this model type in a has_many relation.
|
||||||
|
*
|
||||||
|
* @param bool &$includeInTab Set this to true if the field should be in its own tab. False otherwise.
|
||||||
|
*/
|
||||||
|
public function scaffoldFormFieldForHasMany(
|
||||||
|
string $relationName,
|
||||||
|
?string $fieldTitle,
|
||||||
|
DataObject $ownerRecord,
|
||||||
|
bool &$includeInOwnTab
|
||||||
|
): FormField {
|
||||||
|
$includeInOwnTab = true;
|
||||||
|
return GridField::create(
|
||||||
|
$relationName,
|
||||||
|
$fieldTitle,
|
||||||
|
$ownerRecord->$relationName(),
|
||||||
|
GridFieldConfig_RelationEditor::create()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scaffold a form field for selecting records of this model type in a many_many relation.
|
||||||
|
*
|
||||||
|
* @param bool &$includeInTab Set this to true if the field should be in its own tab. False otherwise.
|
||||||
|
*/
|
||||||
|
public function scaffoldFormFieldForManyMany(
|
||||||
|
string $relationName,
|
||||||
|
?string $fieldTitle,
|
||||||
|
DataObject $ownerRecord,
|
||||||
|
bool &$includeInOwnTab
|
||||||
|
): FormField {
|
||||||
|
$includeInOwnTab = true;
|
||||||
|
return GridField::create(
|
||||||
|
$relationName,
|
||||||
|
$fieldTitle,
|
||||||
|
$ownerRecord->$relationName(),
|
||||||
|
GridFieldConfig_RelationEditor::create()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows user code to hook into DataObject::getCMSFields prior to updateCMSFields
|
* Allows user code to hook into DataObject::getCMSFields prior to updateCMSFields
|
||||||
* being called on extensions
|
* being called on extensions
|
||||||
|
@ -28,7 +28,8 @@ class DBForeignKey extends DBInt
|
|||||||
protected $object;
|
protected $object;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of related objects to show in a dropdown before it switches to using lazyloading
|
* Number of related objects to show in a scaffolded searchable dropdown field before it
|
||||||
|
* switches to using lazyloading.
|
||||||
* This will also be used as the lazy load limit
|
* This will also be used as the lazy load limit
|
||||||
*
|
*
|
||||||
* @config
|
* @config
|
||||||
@ -65,23 +66,7 @@ class DBForeignKey extends DBInt
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$hasOneSingleton = singleton($hasOneClass);
|
$hasOneSingleton = singleton($hasOneClass);
|
||||||
if ($hasOneSingleton instanceof File) {
|
$field = $hasOneSingleton->scaffoldFormFieldForHasOne($this->name, $title, $relationName, $this->object);
|
||||||
$field = Injector::inst()->create(FileHandleField::class, $relationName, $title);
|
|
||||||
if ($hasOneSingleton instanceof Image) {
|
|
||||||
$field->setAllowedFileCategories('image/supported');
|
|
||||||
}
|
|
||||||
if ($field->hasMethod('setAllowedMaxFileNumber')) {
|
|
||||||
$field->setAllowedMaxFileNumber(1);
|
|
||||||
}
|
|
||||||
return $field;
|
|
||||||
}
|
|
||||||
$labelField = $hasOneSingleton->hasField('Title') ? 'Title' : 'Name';
|
|
||||||
$list = DataList::create($hasOneClass);
|
|
||||||
$threshold = self::config()->get('dropdown_field_threshold');
|
|
||||||
$overThreshold = $list->count() > $threshold;
|
|
||||||
$field = SearchableDropdownField::create($this->name, $title, $list, $labelField)
|
|
||||||
->setIsLazyLoaded($overThreshold)
|
|
||||||
->setLazyLoadLimit($threshold);
|
|
||||||
return $field;
|
return $field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,12 +5,18 @@ namespace SilverStripe\Forms\Tests;
|
|||||||
use SilverStripe\Forms\HTMLEditor\HTMLEditorField;
|
use SilverStripe\Forms\HTMLEditor\HTMLEditorField;
|
||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Forms\CurrencyField;
|
||||||
|
use SilverStripe\Forms\DateField;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
use SilverStripe\Forms\Form;
|
use SilverStripe\Forms\Form;
|
||||||
use SilverStripe\Forms\Tests\FormScaffolderTest\Article;
|
use SilverStripe\Forms\Tests\FormScaffolderTest\Article;
|
||||||
use SilverStripe\Forms\Tests\FormScaffolderTest\ArticleExtension;
|
use SilverStripe\Forms\Tests\FormScaffolderTest\ArticleExtension;
|
||||||
use SilverStripe\Forms\Tests\FormScaffolderTest\Author;
|
use SilverStripe\Forms\Tests\FormScaffolderTest\Author;
|
||||||
|
use SilverStripe\Forms\Tests\FormScaffolderTest\Child;
|
||||||
|
use SilverStripe\Forms\Tests\FormScaffolderTest\ParentModel;
|
||||||
|
use SilverStripe\Forms\Tests\FormScaffolderTest\ParentChildJoin;
|
||||||
use SilverStripe\Forms\Tests\FormScaffolderTest\Tag;
|
use SilverStripe\Forms\Tests\FormScaffolderTest\Tag;
|
||||||
|
use SilverStripe\Forms\TimeField;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for DataObject FormField scaffolding
|
* Tests for DataObject FormField scaffolding
|
||||||
@ -30,9 +36,11 @@ class FormScaffolderTest extends SapphireTest
|
|||||||
Article::class,
|
Article::class,
|
||||||
Tag::class,
|
Tag::class,
|
||||||
Author::class,
|
Author::class,
|
||||||
|
ParentModel::class,
|
||||||
|
Child::class,
|
||||||
|
ParentChildJoin::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
public function testGetCMSFieldsSingleton()
|
public function testGetCMSFieldsSingleton()
|
||||||
{
|
{
|
||||||
$article = new Article;
|
$article = new Article;
|
||||||
@ -162,4 +170,47 @@ class FormScaffolderTest extends SapphireTest
|
|||||||
|
|
||||||
$this->assertFalse($fields->hasTabSet(), 'getFrontEndFields() doesnt produce a TabSet by default');
|
$this->assertFalse($fields->hasTabSet(), 'getFrontEndFields() doesnt produce a TabSet by default');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function provideScaffoldRelationFormFields()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[true],
|
||||||
|
[false],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideScaffoldRelationFormFields
|
||||||
|
*/
|
||||||
|
public function testScaffoldRelationFormFields(bool $includeInOwnTab)
|
||||||
|
{
|
||||||
|
$parent = $this->objFromFixture(ParentModel::class, 'parent1');
|
||||||
|
Child::$includeInOwnTab = $includeInOwnTab;
|
||||||
|
$fields = $parent->scaffoldFormFields(['includeRelations' => true, 'tabbed' => true]);
|
||||||
|
|
||||||
|
foreach (array_keys(ParentModel::config()->uninherited('has_one')) as $hasOneName) {
|
||||||
|
$scaffoldedFormField = $fields->dataFieldByName($hasOneName . 'ID');
|
||||||
|
if ($hasOneName === 'ChildPolymorphic') {
|
||||||
|
$this->assertNull($scaffoldedFormField, "$hasOneName should be null");
|
||||||
|
} else {
|
||||||
|
$this->assertInstanceOf(DateField::class, $scaffoldedFormField, "$hasOneName should be a DateField");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (array_keys(ParentModel::config()->uninherited('has_many')) as $hasManyName) {
|
||||||
|
$this->assertInstanceOf(CurrencyField::class, $fields->dataFieldByName($hasManyName), "$hasManyName should be a CurrencyField");
|
||||||
|
if ($includeInOwnTab) {
|
||||||
|
$this->assertNotNull($fields->findTab("Root.$hasManyName"));
|
||||||
|
} else {
|
||||||
|
$this->assertNull($fields->findTab("Root.$hasManyName"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (array_keys(ParentModel::config()->uninherited('many_many')) as $manyManyName) {
|
||||||
|
$this->assertInstanceOf(TimeField::class, $fields->dataFieldByName($manyManyName), "$manyManyName should be a TimeField");
|
||||||
|
if ($includeInOwnTab) {
|
||||||
|
$this->assertNotNull($fields->findTab("Root.$manyManyName"));
|
||||||
|
} else {
|
||||||
|
$this->assertNull($fields->findTab("Root.$manyManyName"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,3 +10,6 @@ SilverStripe\Forms\Tests\FormScaffolderTest\Author:
|
|||||||
author1:
|
author1:
|
||||||
FirstName: Author 1
|
FirstName: Author 1
|
||||||
Tags: =>SilverStripe\Forms\Tests\FormScaffolderTest\Article.article1
|
Tags: =>SilverStripe\Forms\Tests\FormScaffolderTest\Article.article1
|
||||||
|
SilverStripe\Forms\Tests\FormScaffolderTest\ParentModel:
|
||||||
|
parent1:
|
||||||
|
Title: Parent 1
|
||||||
|
57
tests/php/Forms/FormScaffolderTest/Child.php
Normal file
57
tests/php/Forms/FormScaffolderTest/Child.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Forms\Tests\FormScaffolderTest;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\Forms\CurrencyField;
|
||||||
|
use SilverStripe\Forms\DateField;
|
||||||
|
use SilverStripe\Forms\FormField;
|
||||||
|
use SilverStripe\Forms\TimeField;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
|
class Child extends DataObject implements TestOnly
|
||||||
|
{
|
||||||
|
private static $table_name = 'FormScaffolderTest_Child';
|
||||||
|
|
||||||
|
private static $db = [
|
||||||
|
'Title' => 'Varchar',
|
||||||
|
];
|
||||||
|
|
||||||
|
private static $has_one = [
|
||||||
|
'Parent' => ParentModel::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
public static bool $includeInOwnTab = true;
|
||||||
|
|
||||||
|
public function scaffoldFormFieldForHasOne(
|
||||||
|
string $fieldName,
|
||||||
|
?string $fieldTitle,
|
||||||
|
string $relationName,
|
||||||
|
DataObject $ownerRecord
|
||||||
|
): FormField {
|
||||||
|
// Intentionally return a field that is unlikely to be used by default in the future.
|
||||||
|
return DateField::create($fieldName, $fieldTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scaffoldFormFieldForHasMany(
|
||||||
|
string $relationName,
|
||||||
|
?string $fieldTitle,
|
||||||
|
DataObject $ownerRecord,
|
||||||
|
bool &$includeInOwnTab
|
||||||
|
): FormField {
|
||||||
|
$includeInOwnTab = static::$includeInOwnTab;
|
||||||
|
// Intentionally return a field that is unlikely to be used by default in the future.
|
||||||
|
return CurrencyField::create($relationName, $fieldTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scaffoldFormFieldForManyMany(
|
||||||
|
string $relationName,
|
||||||
|
?string $fieldTitle,
|
||||||
|
DataObject $ownerRecord,
|
||||||
|
bool &$includeInOwnTab
|
||||||
|
): FormField {
|
||||||
|
$includeInOwnTab = static::$includeInOwnTab;
|
||||||
|
// Intentionally return a field that is unlikely to be used by default in the future.
|
||||||
|
return TimeField::create($relationName, $fieldTitle);
|
||||||
|
}
|
||||||
|
}
|
20
tests/php/Forms/FormScaffolderTest/ParentChildJoin.php
Normal file
20
tests/php/Forms/FormScaffolderTest/ParentChildJoin.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Forms\Tests\FormScaffolderTest;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
|
class ParentChildJoin extends DataObject implements TestOnly
|
||||||
|
{
|
||||||
|
private static $table_name = 'FormScaffolderTest_ParentChildJoin';
|
||||||
|
|
||||||
|
private static $db = [
|
||||||
|
'Title' => 'Varchar',
|
||||||
|
];
|
||||||
|
|
||||||
|
private static $has_one = [
|
||||||
|
'Parent' => ParentModel::class,
|
||||||
|
'Child' => Child::class,
|
||||||
|
];
|
||||||
|
}
|
33
tests/php/Forms/FormScaffolderTest/ParentModel.php
Normal file
33
tests/php/Forms/FormScaffolderTest/ParentModel.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Forms\Tests\FormScaffolderTest;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
|
class ParentModel extends DataObject implements TestOnly
|
||||||
|
{
|
||||||
|
private static $table_name = 'FormScaffolderTest_ParentModel';
|
||||||
|
|
||||||
|
private static $db = [
|
||||||
|
'Title' => 'Varchar',
|
||||||
|
];
|
||||||
|
|
||||||
|
private static $has_one = [
|
||||||
|
'Child' => Child::class,
|
||||||
|
'ChildPolymorphic' => DataObject::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
private static $has_many = [
|
||||||
|
'ChildrenHasMany' => Child::class . '.Parent',
|
||||||
|
];
|
||||||
|
|
||||||
|
private static $many_many = [
|
||||||
|
'ChildrenManyMany' => Child::class,
|
||||||
|
'ChildrenManyManyThrough' => [
|
||||||
|
'through' => ParentChildJoin::class,
|
||||||
|
'from' => 'Parent',
|
||||||
|
'to' => 'Child',
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user