From 0c01fcf461c50af5fab464c196bbf35d4ca04090 Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Wed, 24 Jan 2024 16:39:06 +1300 Subject: [PATCH] ENH Hide the open in new window checkbox from phone and email links --- README.md | 4 +- src/Controllers/LinkFieldController.php | 4 +- src/Models/EmailLink.php | 1 + src/Models/Link.php | 9 ++++ src/Models/PhoneLink.php | 1 + .../Controllers/LinkFieldControllerTest.php | 8 +-- .../Traits/AllowedLinkClassesTraitTest.php | 53 ++++++++++++------- 7 files changed, 54 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index f7fbfbfd..3f28be08 100644 --- a/README.md +++ b/README.md @@ -106,10 +106,10 @@ class ExternalLinkExtension extends Extension $defaultLinkTitle = sprintf('External link: %s', $this->owner->ExternalUrl); } } - ``` ## Controlling what type of links can be created in a LinkField + By default, all `Link` subclasses can be created by a LinkField. This includes any custom `Link` subclasses defined in your projects or via third party module. Developers can control the link types allowed for individual `LinkField`. The `setAllowedTypes` method only allow link types that have been provided as parameters. @@ -141,6 +141,7 @@ Link::remove_extension(Versioned::class); ## Additional features The developer can customise the position of the link type in the menu by setting the `$menu_priority` value. The priority is in ascending order (i.e. a link with a higher priority value will be displayed lower in the list). + The developer can also set an icon that will correspond to a specific type of link by setting the value of the `$icon` configuration property. The value of this configuration corresponds to the css class of the icon to be used. ```yml @@ -148,6 +149,7 @@ SilverStripe\LinkField\Models\PhoneLink: icon: 'font-icon-menu-help' menu_priority: 1 ``` + The developer can also define these values for a new link type. ```php diff --git a/src/Controllers/LinkFieldController.php b/src/Controllers/LinkFieldController.php index 6b7d8873..86f10495 100644 --- a/src/Controllers/LinkFieldController.php +++ b/src/Controllers/LinkFieldController.php @@ -356,8 +356,8 @@ private function createLinkForm(Link $link, string $operation): Form // Add save action button $title = $id - ? _t(__CLASS__ . '.UPDATE_LINK', 'Update link') - : _t(__CLASS__ . '.CREATE_LINK', 'Create link'); + ? _t(__CLASS__ . '.UPDATE_LINK', 'Update link') + : _t(__CLASS__ . '.CREATE_LINK', 'Create link'); $actions = FieldList::create([ FormAction::create('save', $title) ->setSchemaData(['data' => ['buttonStyle' => 'primary']]), diff --git a/src/Models/EmailLink.php b/src/Models/EmailLink.php index a43eea3a..2b074161 100644 --- a/src/Models/EmailLink.php +++ b/src/Models/EmailLink.php @@ -32,6 +32,7 @@ public function getCMSFields(): FieldList 'Email', _t(__CLASS__ . '.EMAIL_FIELD', 'Email address'), )); + $fields->removeByName('OpenInNew'); }); return parent::getCMSFields(); } diff --git a/src/Models/Link.php b/src/Models/Link.php index cb8fc2db..4a0cfed6 100644 --- a/src/Models/Link.php +++ b/src/Models/Link.php @@ -123,6 +123,15 @@ public function getCMSFields(): FieldList $linkTypeField->setEmptyString('-- select type --'); } }); + $this->afterUpdateCMSFields(function (FieldList $fields) { + // Move the OpenInNew field to the bottom of the form if it hasn't been removed in + // a subclasses getCMSFields() method + $openInNewField = $fields->dataFieldByName('OpenInNew'); + if ($openInNewField) { + $fields->removeByName('OpenInNew'); + $fields->addFieldToTab('Root.Main', $openInNewField); + } + }); return parent::getCMSFields(); } diff --git a/src/Models/PhoneLink.php b/src/Models/PhoneLink.php index 26004255..0a72031b 100644 --- a/src/Models/PhoneLink.php +++ b/src/Models/PhoneLink.php @@ -27,6 +27,7 @@ public function getCMSFields(): FieldList $this->beforeUpdateCMSFields(function (FieldList $fields) { $linkField = $fields->dataFieldByName('Phone'); $linkField->setTitle(_t(__CLASS__ . '.PHONE_FIELD', 'Phone')); + $fields->removeByName('OpenInNew'); }); return parent::getCMSFields(); } diff --git a/tests/php/Controllers/LinkFieldControllerTest.php b/tests/php/Controllers/LinkFieldControllerTest.php index 9c97883e..18d55a96 100644 --- a/tests/php/Controllers/LinkFieldControllerTest.php +++ b/tests/php/Controllers/LinkFieldControllerTest.php @@ -85,10 +85,10 @@ public function testLinkFormGetSchema( . "&ownerRelation=$ownerRelation"; $this->assertSame($expectedAction, $formSchema['schema']['action']); // schema is nested and retains 'Root' and 'Main' tab hierarchy - $this->assertSame('Phone', $formSchema['schema']['fields'][0]['children'][0]['children'][2]['name']); + $this->assertSame('Phone', $formSchema['schema']['fields'][0]['children'][0]['children'][1]['name']); $this->assertSame('action_save', $formSchema['schema']['actions'][0]['name']); // state node is flattened, unlike schema node - $this->assertSame($expectedValue, $formSchema['state']['fields'][4]['value']); + $this->assertSame($expectedValue, $formSchema['state']['fields'][3]['value']); $this->assertFalse(array_key_exists('errors', $formSchema)); if ($idType === 'new-record') { $this->assertSame('OwnerID', $formSchema['state']['fields'][6]['name']); @@ -238,10 +238,10 @@ public function testLinkFormPost( . "&ownerRelation=$ownerRelation"; $this->assertSame($expectedUrl, $formSchema['schema']['action']); // schema is nested and retains 'Root' and 'Main' tab hierarchy - $this->assertSame('Phone', $formSchema['schema']['fields'][0]['children'][0]['children'][2]['name']); + $this->assertSame('Phone', $formSchema['schema']['fields'][0]['children'][0]['children'][1]['name']); $this->assertSame('action_save', $formSchema['schema']['actions'][0]['name']); // state node is flattened, unlike schema node - $this->assertSame('9876543210', $formSchema['state']['fields'][4]['value']); + $this->assertSame('9876543210', $formSchema['state']['fields'][3]['value']); if ($fail) { $this->assertSame($expectedMessage, $formSchema['errors'][0]['value']); // Phone was note updated on PhoneLink dataobject diff --git a/tests/php/Traits/AllowedLinkClassesTraitTest.php b/tests/php/Traits/AllowedLinkClassesTraitTest.php index 21345005..511a63f8 100644 --- a/tests/php/Traits/AllowedLinkClassesTraitTest.php +++ b/tests/php/Traits/AllowedLinkClassesTraitTest.php @@ -25,12 +25,12 @@ class AllowedLinkClassesTraitTest extends SapphireTest * Need to include only known Link subclasses. */ private $link_types = [ - SiteTreeLink::class, - ExternalLink::class, - FileLink::class, - EmailLink::class, - PhoneLink::class, - TestPhoneLink::class, + 'sitetree' => SiteTreeLink::class, + 'external' => ExternalLink::class, + 'file' => FileLink::class, + 'email' => EmailLink::class, + 'phone' => PhoneLink::class, + 'testphone' => TestPhoneLink::class, ]; public function setUp(): void @@ -58,20 +58,20 @@ public function allowedTypesDataProvider() : array return [ 'allow all Link classes' => [ 'enabled' => [ - SiteTreeLink::class, - ExternalLink::class, - FileLink::class, - EmailLink::class, - PhoneLink::class, - TestPhoneLink::class, + SiteTreeLink::class, + ExternalLink::class, + FileLink::class, + EmailLink::class, + PhoneLink::class, + TestPhoneLink::class, ], 'expected' => [ - SiteTreeLink::class, - ExternalLink::class, - FileLink::class, - EmailLink::class, - PhoneLink::class, - TestPhoneLink::class, + SiteTreeLink::class, + ExternalLink::class, + FileLink::class, + EmailLink::class, + PhoneLink::class, + TestPhoneLink::class, ], ], 'allow only SiteTreeLink class' => [ @@ -174,10 +174,11 @@ public function testGetSortedTypeProps(array $enabled, array $expected, bool $re 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); + $json = $this->removeCustomLinkTypes($json); $this->assertEquals(array_keys($json), $expected); } @@ -277,4 +278,18 @@ public function testGetTypesProps( $this->assertEquals($icon, $json[$key]['icon']); $this->assertEquals($allowed, $json[$key]['allowed']); } + + /** + * Remove any classes defined at the project level that interfere with running unit-tests locally + */ + private function removeCustomLinkTypes(array $json): array + { + $newJson = []; + foreach ($json as $key => $value) { + if (array_key_exists($key, $this->link_types)) { + $newJson[$key] = $value; + } + } + return $newJson; + } }