From a684c8ca03badc0a6462581aca23c68a1e45d5f7 Mon Sep 17 00:00:00 2001 From: Guy Sartorelli <36352093+GuySartorelli@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:20:00 +1200 Subject: [PATCH] ENH Auto-scaffold Member and Group with appropriate form fields (#11285) --- src/Security/Group.php | 32 +++++++++++++++++++++++++++ src/Security/Member.php | 48 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/src/Security/Group.php b/src/Security/Group.php index 87200903cdc..a8a3a5c5f11 100755 --- a/src/Security/Group.php +++ b/src/Security/Group.php @@ -8,6 +8,7 @@ use SilverStripe\Forms\DropdownField; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; +use SilverStripe\Forms\FormField; use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridFieldAddExistingAutocompleter; use SilverStripe\Forms\GridField\GridFieldButtonRow; @@ -27,6 +28,8 @@ use SilverStripe\Forms\TabSet; use SilverStripe\Forms\TextareaField; use SilverStripe\Forms\TextField; +use SilverStripe\Forms\TreeDropdownField; +use SilverStripe\Forms\TreeMultiselectField; use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataQuery; @@ -297,6 +300,35 @@ public function fieldLabels($includerelations = true) return $labels; } + public function scaffoldFormFieldForHasOne( + string $fieldName, + ?string $fieldTitle, + string $relationName, + DataObject $ownerRecord + ): FormField { + return TreeDropdownField::create($fieldName, $fieldTitle, static::class); + } + + public function scaffoldFormFieldForHasMany( + string $relationName, + ?string $fieldTitle, + DataObject $ownerRecord, + bool &$includeInOwnTab + ): FormField { + $includeInOwnTab = false; + return TreeMultiselectField::create($relationName, $fieldTitle, static::class); + } + + public function scaffoldFormFieldForManyMany( + string $relationName, + ?string $fieldTitle, + DataObject $ownerRecord, + bool &$includeInOwnTab + ): FormField { + $includeInOwnTab = false; + return TreeMultiselectField::create($relationName, $fieldTitle, static::class); + } + /** * Get many-many relation to {@link Member}, * including all members which are "inherited" from children groups of this record. diff --git a/src/Security/Member.php b/src/Security/Member.php index 51686f99e67..ad241beac8e 100644 --- a/src/Security/Member.php +++ b/src/Security/Member.php @@ -40,6 +40,10 @@ use Symfony\Component\Mime\Exception\RfcComplianceException; use Closure; use RuntimeException; +use SilverStripe\Forms\FormField; +use SilverStripe\Forms\SearchableDropdownField; +use SilverStripe\Forms\SearchableMultiDropdownField; +use SilverStripe\ORM\FieldType\DBForeignKey; /** * The member class which represents the users of the system @@ -1442,6 +1446,50 @@ public function fieldLabels($includerelations = true) return $labels; } + public function scaffoldFormFieldForHasOne( + string $fieldName, + ?string $fieldTitle, + string $relationName, + DataObject $ownerRecord + ): FormField { + $field = parent::scaffoldFormFieldForHasOne($fieldName, $fieldTitle, $relationName, $ownerRecord); + if ($field instanceof SearchableDropdownField) { + $field->setUseSearchContext(true); + } + return $field; + } + + public function scaffoldFormFieldForHasMany( + string $relationName, + ?string $fieldTitle, + DataObject $ownerRecord, + bool &$includeInOwnTab + ): FormField { + $includeInOwnTab = false; + return $this->scaffoldFormFieldForManyRelation($relationName, $fieldTitle); + } + + public function scaffoldFormFieldForManyMany( + string $relationName, + ?string $fieldTitle, + DataObject $ownerRecord, + bool &$includeInOwnTab + ): FormField { + $includeInOwnTab = false; + return $this->scaffoldFormFieldForManyRelation($relationName, $fieldTitle); + } + + private function scaffoldFormFieldForManyRelation(string $relationName, ?string $fieldTitle): FormField + { + $list = static::get(); + $field = SearchableMultiDropdownField::create($relationName, $fieldTitle, $list); + // Use the same lazyload threshold has_one relations use + $threshold = DBForeignKey::config()->get('dropdown_field_threshold'); + $overThreshold = $list->count() > $threshold; + $field->setIsLazyLoaded($overThreshold)->setLazyLoadLimit($threshold); + return $field; + } + /** * Users can view their own record. * Otherwise they'll need ADMIN or CMS_ACCESS_SecurityAdmin permissions.