diff --git a/lang/en.yml b/lang/en.yml index b8575376..ea3ab5e6 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -18,6 +18,7 @@ en: INVALID_TYPECLASS_EMPTY: '"{class}": Allowed types cannot be empty' SilverStripe\LinkField\Models\EmailLink: EMAIL_FIELD: 'Email address' + LINKLABEL: 'Link to email address' PLURALNAME: 'Email Links' PLURALS: one: 'An Email Link' @@ -26,6 +27,7 @@ en: db_Email: Email SilverStripe\LinkField\Models\ExternalLink: EXTERNAL_URL_FIELD: 'External url' + LINKLABEL: 'Link to external URL' PLURALNAME: 'External Links' PLURALS: one: 'An External Link' @@ -36,6 +38,7 @@ en: CANNOT_VIEW_FILE: 'Cannot view file' FILE_DOES_NOT_EXIST: 'File does not exist' FILE_FIELD: File + LINKLABEL: 'Link to a file' MISSING_DEFAULT_TITLE: 'File missing' PLURALNAME: 'File Links' PLURALS: @@ -59,6 +62,7 @@ en: db_Version: Version has_one_Owner: Owner SilverStripe\LinkField\Models\PhoneLink: + LINKLABEL: 'Phone number' PHONE_FIELD: Phone PLURALNAME: 'Phone Links' PLURALS: @@ -70,6 +74,7 @@ en: ANCHOR_DESCRIPTION: 'Do not prepend "#". Anchor suggestions will be displayed once the linked page is attached.' ANCHOR_FIELD_TITLE: Anchor CANNOT_VIEW_PAGE: 'Cannot view page' + LINKLABEL: 'Page on this site' MISSING_DEFAULT_TITLE: 'Page missing' PAGE_DOES_NOT_EXIST: 'Page does not exist' PAGE_FIELD_TITLE: Page diff --git a/src/Form/Traits/AllowedLinkClassesTrait.php b/src/Form/Traits/AllowedLinkClassesTrait.php index f5911db8..417576ad 100644 --- a/src/Form/Traits/AllowedLinkClassesTrait.php +++ b/src/Form/Traits/AllowedLinkClassesTrait.php @@ -93,10 +93,14 @@ public function getTypesProps(): string } $typesList[$key] = [ 'key' => $key, - 'title' => $type->i18n_singular_name(), + 'title' => $type->getMenuTitle(), 'handlerName' => $type->LinkTypeHandlerName(), + 'priority' => $class::config()->get('menu_priority'), ]; } + uasort($typesList, function ($a, $b) { + return $a['priority'] - $b['priority']; + }); return json_encode($typesList); } @@ -121,7 +125,6 @@ private function genarateAllowedTypes(): array $result[$type] = $class; } } - return $result; } } diff --git a/src/Models/EmailLink.php b/src/Models/EmailLink.php index ba42a9c9..f02c7da3 100644 --- a/src/Models/EmailLink.php +++ b/src/Models/EmailLink.php @@ -18,6 +18,11 @@ class EmailLink extends Link 'Email' => 'Varchar(255)', ]; + /** + * Set the priority of this link type in the CMS menu + */ + private static int $menu_priority = 30; + public function getCMSFields(): FieldList { $this->beforeUpdateCMSFields(function (FieldList $fields) { @@ -38,4 +43,13 @@ public function getURL(): string { return $this->Email ? sprintf('mailto:%s', $this->Email) : ''; } + + /** + * The title that will be displayed in the dropdown + * for selecting the link type to create. + */ + public function getMenuTitle(): string + { + return _t(__CLASS__ . '.LINKLABEL', 'Link to email address'); + } } diff --git a/src/Models/ExternalLink.php b/src/Models/ExternalLink.php index 5a342088..9325aea7 100644 --- a/src/Models/ExternalLink.php +++ b/src/Models/ExternalLink.php @@ -17,6 +17,11 @@ class ExternalLink extends Link 'ExternalUrl' => 'Varchar', ]; + /** + * Set the priority of this link type in the CMS menu + */ + private static int $menu_priority = 20; + public function getCMSFields(): FieldList { $this->beforeUpdateCMSFields(function (FieldList $fields) { @@ -35,4 +40,13 @@ public function getURL(): string { return $this->ExternalUrl ?: ''; } + + /** + * The title that will be displayed in the dropdown + * for selecting the link type to create. + */ + public function getMenuTitle(): string + { + return _t(__CLASS__ . '.LINKLABEL', 'Link to external URL'); + } } diff --git a/src/Models/FileLink.php b/src/Models/FileLink.php index 3429e48f..fcb6caab 100644 --- a/src/Models/FileLink.php +++ b/src/Models/FileLink.php @@ -19,6 +19,11 @@ class FileLink extends Link 'File' => File::class, ]; + /** + * Set the priority of this link type in the CMS menu + */ + private static int $menu_priority = 10; + public function getCMSFields(): FieldList { $this->beforeUpdateCMSFields(function (FieldList $fields) { @@ -55,4 +60,13 @@ public function getDefaultTitle(): string return (string) $this->getDescription(); } + + /** + * The title that will be displayed in the dropdown + * for selecting the link type to create. + */ + public function getMenuTitle(): string + { + return _t(__CLASS__ . '.LINKLABEL', 'Link to a file'); + } } diff --git a/src/Models/Link.php b/src/Models/Link.php index ffebf426..19ac185e 100644 --- a/src/Models/Link.php +++ b/src/Models/Link.php @@ -57,6 +57,11 @@ class Link extends DataObject */ private ?string $linkType = null; + /** + * Set the priority of this link type in the CMS menu + */ + private static int $menu_priority = 100; + public function getDescription(): string { return ''; @@ -454,4 +459,15 @@ public function getShortCode(): string { return strtolower(rtrim(ClassInfo::shortName($this), 'Link')) ?? ''; } + + /** + * The title that will be displayed in the dropdown + * for selecting the link type to create. + * Subclasses should override this. + * It will use the singular_name by default. + */ + public function getMenuTitle(): string + { + return $this->i18n_singular_name(); + } } diff --git a/src/Models/PhoneLink.php b/src/Models/PhoneLink.php index a019ce5b..0cbcd4f2 100644 --- a/src/Models/PhoneLink.php +++ b/src/Models/PhoneLink.php @@ -15,6 +15,11 @@ class PhoneLink extends Link 'Phone' => 'Varchar(255)', ]; + /** + * Set the priority of this link type in the CMS menu + */ + private static int $menu_priority = 40; + public function getCMSFields(): FieldList { $this->beforeUpdateCMSFields(function (FieldList $fields) { @@ -33,4 +38,13 @@ public function getURL(): string { return $this->Phone ? sprintf('tel:%s', $this->Phone) : ''; } + + /** + * The title that will be displayed in the dropdown + * for selecting the link type to create. + */ + public function getMenuTitle(): string + { + return _t(__CLASS__ . '.LINKLABEL', 'Phone number'); + } } diff --git a/src/Models/SiteTreeLink.php b/src/Models/SiteTreeLink.php index 601ce168..2e128851 100644 --- a/src/Models/SiteTreeLink.php +++ b/src/Models/SiteTreeLink.php @@ -30,6 +30,11 @@ class SiteTreeLink extends Link 'Page' => SiteTree::class, ]; + /** + * Set the priority of this link type in the CMS menu + */ + private static int $menu_priority = 0; + public function getDescription(): string { $page = $this->Page(); @@ -131,4 +136,13 @@ public function getDefaultTitle(): string } return $page->Title; } + + /** + * The title that will be displayed in the dropdown + * for selecting the link type to create. + */ + public function getMenuTitle(): string + { + return _t(__CLASS__ . '.LINKLABEL', 'Page on this site'); + } } diff --git a/tests/php/Traits/AllowedLinkClassesTraitTest.php b/tests/php/Traits/AllowedLinkClassesTraitTest.php index abffd775..ed8b731d 100644 --- a/tests/php/Traits/AllowedLinkClassesTraitTest.php +++ b/tests/php/Traits/AllowedLinkClassesTraitTest.php @@ -5,6 +5,7 @@ use ArrayIterator; use InvalidArgumentException; use ReflectionMethod; +use SilverStripe\Core\Injector\Injector; use SilverStripe\Dev\SapphireTest; use SilverStripe\LinkField\Form\Traits\AllowedLinkClassesTrait; use SilverStripe\LinkField\Form\LinkField; @@ -105,6 +106,78 @@ public function provideTypesExceptionDataProvider() : array ]; } + public function sortedTypesDataProvider() : array + { + return [ + 'sort all allowed Link classes' => [ + 'enabled' => [ + SiteTreeLink::class, + ExternalLink::class, + FileLink::class, + EmailLink::class, + PhoneLink::class, + TestPhoneLink::class, + ], + 'expected' => [ + 'sitetree', + 'file', + 'external', + 'email', + 'phone', + 'testphone', + ], + 'reorder' => false, + ], + 'sort all allowed Link classes and move TestPhoneLink up ' => [ + 'enabled' => [ + SiteTreeLink::class, + ExternalLink::class, + FileLink::class, + EmailLink::class, + PhoneLink::class, + TestPhoneLink::class, + ], + 'expected' => [ + 'sitetree', + 'testphone', + 'file', + 'external', + 'email', + 'phone', + ], + 'reorder' => true, + ], + 'sort only particular allowed Link class and move TestPhoneLink up' => [ + 'enabled' => [ + SiteTreeLink::class, + TestPhoneLink::class, + EmailLink::class, + ], + 'expected' => [ + 'sitetree', + 'testphone', + 'email', + ], + 'reorder' => true, + ], + ]; + } + + /** + * @dataProvider sortedTypesDataProvider + */ + public function testGetTypesProps(array $enabled, array $expected, bool $reorder): void + { + if ($reorder) { + Injector::inst()->get(TestPhoneLink::class)->config()->set('menu_priority', 5); + } + + $linkField = LinkField::create('LinkField'); + $linkField->setAllowedTypes($enabled); + $json = json_decode($linkField->getTypesProps(), true); + $this->assertEquals(array_keys($json), $expected); + } + public function testGetTypesPropsCanCreate(): void { $linkField = LinkField::create('LinkField');