Skip to content

Commit

Permalink
ENH Rename and move Title field
Browse files Browse the repository at this point in the history
  • Loading branch information
emteknetnz committed Feb 7, 2024
1 parent 533f9ed commit 506c81c
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 95 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,22 @@ class MyCustomLink extends Link

Custom links can have validation set using standard [model validation](https://docs.silverstripe.org/en/5/developer_guides/forms/validation/#model-validation).

## Migration form LinkField v3 to v4

The `Title` DB field has been renamed to `LinkText`

You can manually rename this column in your database with the following:

```php
// app/_config.php

use SilverStripe\ORM\DB;

// Only run this once
// This will rename the `Title` field to `LinkText` in all relevant tables
DB::get_conn()->getSchemaManager()->renameField('LinkField_Link', 'Title', 'LinkText');
```

## Migrating from Shae Dawson's Linkable module

https://github.com/sheadawson/silverstripe-linkable
Expand Down
6 changes: 3 additions & 3 deletions lang/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ en:
SINGULARNAME: 'File Link'
has_one_File: File
SilverStripe\LinkField\Models\Link:
LINK_FIELD_TITLE: Title
LINK_FIELD_TITLE_DESCRIPTION: 'If left blank, an appropriate default title will be used on the front-end'
LINK_TEXT_TITLE: 'Link text'
LINK_TEXT_TEXT_DESCRIPTION: 'If left blank, an appropriate default will be used on the front-end'
LINK_TYPE_TITLE: 'Link Type'
MISSING_DEFAULT_TITLE: 'No link provided'
OPEN_IN_NEW_TITLE: 'Open in new window?'
Expand All @@ -49,7 +49,7 @@ en:
other: '{count} Links'
SINGULARNAME: Link
db_OpenInNew: 'Open in new'
db_Title: Title
db_LinkText: 'Link text'
db_Version: Version
has_one_Owner: Owner
SilverStripe\LinkField\Models\PhoneLink:
Expand Down
2 changes: 1 addition & 1 deletion src/Form/Traits/AllowedLinkClassesTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public function getTypesProps(): string
$allowed = array_key_exists($key, $typeDefinitions) && $type->canCreate();
$typesList[$key] = [
'key' => $key,
'title' => $type->getMenuTitle(),
'linkText' => $type->getMenuTitle(),
'handlerName' => $type->LinkTypeHandlerName(),
'priority' => $class::config()->get('menu_priority'),
'icon' => $class::config()->get('icon'),
Expand Down
18 changes: 9 additions & 9 deletions src/Models/Link.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Link extends DataObject
private static $table_name = 'LinkField_Link';

private static array $db = [
'Title' => 'Varchar',
'LinkText' => 'Varchar',
'OpenInNew' => 'Boolean',
'Sort' => 'Int',
];
Expand Down Expand Up @@ -94,11 +94,11 @@ public function getCMSFields(): FieldList
$this->beforeUpdateCMSFields(function (FieldList $fields) {
$linkTypes = $this->getLinkTypes();

$titleField = $fields->dataFieldByName('Title');
$titleField->setTitle(_t(__CLASS__ . '.LINK_FIELD_TITLE', 'Title'));
$titleField->setDescription(_t(
self::class . '.LINK_FIELD_TITLE_DESCRIPTION',
'If left blank, an appropriate default title will be used on the front-end',
$linkTextField = $fields->dataFieldByName('LinkText');
$linkTextField->setTitle(_t(__CLASS__ . '.LINK_TEXT_TITLE', 'Link text'));
$linkTextField->setDescription(_t(
self::class . '.LINK_TEXT_TEXT_DESCRIPTION',
'If left blank, an appropriate default will be used on the front-end',
));

$fields->removeByName('Sort');
Expand All @@ -117,7 +117,7 @@ public function getCMSFields(): FieldList
$linkTypes
),
],
'Title'
'LinkText'
);

$linkTypeField->setEmptyString('-- select type --');
Expand Down Expand Up @@ -455,8 +455,8 @@ private function getLinkTypes(): array
public function getDisplayTitle(): string
{
// If we have a title, we can just bail out without any changes
if ($this->Title) {
return $this->Title;
if ($this->LinkText) {
return $this->LinkText;
}

$defaultLinkTitle = $this->getDefaultTitle();
Expand Down
6 changes: 3 additions & 3 deletions src/Models/SiteTreeLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,16 @@ public function getCMSFields(): FieldList
'QueryString',
]);

$titleField = $fields->dataFieldByName('Title');
$titleField?->setDescription(
$linkTextField = $fields->dataFieldByName('LinkText');
$linkTextField?->setDescription(
_t(
__CLASS__ . '.TITLE_DESCRIPTION',
'Auto generated from Page title if left blank',
),
);

$fields->insertAfter(
'Title',
'LinkText',
TreeDropdownField::create(
'PageID',
_t(__CLASS__ . '.PAGE_FIELD_TITLE', 'Page'),
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/LinkableMigrationTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class LinkableMigrationTask extends BuildTask
'ID' => 'ID',
'LastEdited' => 'LastEdited',
'Created' => 'Created',
'Title' => 'Title',
'Title' => 'LinkText',
'OpenInNewWindow' => 'OpenInNew',
];

Expand Down
42 changes: 21 additions & 21 deletions tests/php/Controllers/LinkFieldControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -548,18 +548,18 @@ public function provideLinkDelete(): array
* @dataProvider provideLinkSort
*/
public function testLinkSort(
array $newTitleOrder,
array $newLinkTextOrder,
string $fail,
int $expectedCode,
array $expectedTitles
array $expectedLinkTexts
): void {
TestPhoneLink::$fail = $fail;
$url = "/admin/linkfield/sort";
$newLinkIDs = [];
$links = TestPhoneLink::get();
foreach ($newTitleOrder as $num) {
foreach ($newLinkTextOrder as $num) {
foreach ($links as $link) {
if ($link->Title === "My phone link 0$num") {
if ($link->LinkText === "My phone link 0$num") {
$newLinkIDs[] = $link->ID;
}
}
Expand All @@ -575,60 +575,60 @@ public function testLinkSort(
$response = $this->post($url, null, $headers, null, $body);
$this->assertSame($expectedCode, $response->getStatusCode());
$this->assertSame(
$this->getExpectedTitles($expectedTitles),
TestPhoneLink::get()->filter(['OwnerRelation' => 'LinkList'])->column('Title')
$this->getExpectedLinkTexts($expectedLinkTexts),
TestPhoneLink::get()->filter(['OwnerRelation' => 'LinkList'])->column('LinkText')
);
}

public function provideLinkSort(): array
{
return [
'Success' => [
'newTitleOrder' => [4, 2, 3],
'newLinkTextOrder' => [4, 2, 3],
'fail' => '',
'expectedCode' => 204,
'expectedTitles' => [4, 2, 3],
'expectedLinkTexts' => [4, 2, 3],
],
'Emtpy data' => [
'newTitleOrder' => [],
'newLinkTextOrder' => [],
'fail' => '',
'expectedCode' => 400,
'expectedTitles' => [2, 3, 4],
'expectedLinkTexts' => [2, 3, 4],
],
'Fail can edit' => [
'newTitleOrder' => [4, 2, 3],
'newLinkTextOrder' => [4, 2, 3],
'fail' => 'can-edit',
'expectedCode' => 403,
'expectedTitles' => [2, 3, 4],
'expectedLinkTexts' => [2, 3, 4],
],
'Fail object data' => [
'newTitleOrder' => [],
'newLinkTextOrder' => [],
'fail' => 'object-data',
'expectedCode' => 400,
'expectedTitles' => [2, 3, 4],
'expectedLinkTexts' => [2, 3, 4],
],
'Fail csrf token' => [
'newTitleOrder' => [4, 2, 3],
'newLinkTextOrder' => [4, 2, 3],
'fail' => 'csrf-token',
'expectedCode' => 400,
'expectedTitles' => [2, 3, 4],
'expectedLinkTexts' => [2, 3, 4],
],
'Mismatched owner' => [
'newTitleOrder' => [4, 1, 2],
'newLinkTextOrder' => [4, 1, 2],
'fail' => '',
'expectedCode' => 400,
'expectedTitles' => [2, 3, 4],
'expectedLinkTexts' => [2, 3, 4],
],
'Mismatched owner relation' => [
'newTitleOrder' => [4, 5, 2],
'newLinkTextOrder' => [4, 5, 2],
'fail' => '',
'expectedCode' => 400,
'expectedTitles' => [2, 3, 4],
'expectedLinkTexts' => [2, 3, 4],
],
];
}

private function getExpectedTitles(array $expected): array
private function getExpectedLinkTexts(array $expected): array
{
return array_map(function ($num) {
return "My phone link 0$num";
Expand Down
10 changes: 5 additions & 5 deletions tests/php/Controllers/LinkFieldControllerTest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,30 @@ SilverStripe\LinkField\Tests\Models\LinkTest\LinkOwner:
TestLinkOwner02:
SilverStripe\LinkField\Tests\Controllers\LinkFieldControllerTest\TestPhoneLink:
TestPhoneLink01:
Title: My phone link 01
LinkText: My phone link 01
Phone: 0123456789
Sort: 1
# Link relation is manually joined in LinkFieldControllerTest::setup()
TestPhoneLink02:
Title: My phone link 02
LinkText: My phone link 02
Phone: 111222333
Sort: 1
Owner: =>SilverStripe\LinkField\Tests\Models\LinkTest\LinkOwner.TestLinkOwner02
OwnerRelation: LinkList
TestPhoneLink03:
Title: My phone link 03
LinkText: My phone link 03
Phone: 321321321
Sort: 2
Owner: =>SilverStripe\LinkField\Tests\Models\LinkTest\LinkOwner.TestLinkOwner02
OwnerRelation: LinkList
TestPhoneLink04:
Title: My phone link 04
LinkText: My phone link 04
Phone: 444444444
Sort: 3
Owner: =>SilverStripe\LinkField\Tests\Models\LinkTest\LinkOwner.TestLinkOwner02
OwnerRelation: LinkList
TestPhoneLink05:
Title: My phone link 05
LinkText: My phone link 05
Phone: 555555555
Sort: 1
Owner: =>SilverStripe\LinkField\Tests\Models\LinkTest\LinkOwner.TestLinkOwner02
Expand Down
52 changes: 26 additions & 26 deletions tests/php/Models/LinkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,24 +81,24 @@ public function testSiteTreeLinkTitleFallback(): void
/** @var SiteTreeLink $model */
$model = $this->objFromFixture(SiteTreeLink::class, 'page-link-1');

$this->assertEquals('PageLink1', $model->Title, 'We expect to get a default Link title');
$this->assertEquals('PageLink1', $model->LinkText, 'We expect to get a default Link title');

/** @var SiteTree $page */
$page = $this->objFromFixture(SiteTree::class, 'page-1');

$model->PageID = $page->ID;
$model->Title = null;
$model->LinkText = null;
$model->write();

// The actual Database Title field should still be null
$this->assertNull($model->getField('Title'));
$this->assertEquals(null, $model->Title, 'We expect that link does not have a title');
$this->assertNull($model->getField('LinkText'));
$this->assertEquals(null, $model->LinkText, 'We expect that link does not have a title');

$customTitle = 'My custom title';
$model->Title = $customTitle;
$model->LinkText = $customTitle;
$model->write();

$this->assertEquals($customTitle, $model->Title, 'We expect to get the custom title not page title');
$this->assertEquals($customTitle, $model->LinkText, 'We expect to get the custom title not page title');
}

/**
Expand Down Expand Up @@ -133,39 +133,25 @@ public function linkTypeProvider(): array
public function testGetVersionedState(): void
{
// Versioned Link
$link = Link::create(['Title' => 'abc']);
$link = Link::create(['LinkText' => 'abc']);
$this->assertTrue(Link::has_extension(Versioned::class));
$this->assertEquals('unsaved', $link->getVersionedState());
$link->write();
$this->assertEquals('draft', $link->getVersionedState());
$link->publishSingle();
$this->assertEquals('published', $link->getVersionedState());
$link->Title = 'def';
$link->LinkText = 'def';
$link->write();
$this->assertEquals('modified', $link->getVersionedState());
// Unversioned Link
Link::remove_extension(Versioned::class);
$link = Link::create(['Title' => '123']);
$link = Link::create(['LinkText' => '123']);
$this->assertEquals('unsaved', $link->getVersionedState());
$link->write();
$this->assertEquals('unversioned', $link->getVersionedState());
}

/**
* @param string $identifier
* @param string $class
* @param string $expected
* @return void
* @dataProvider linkUrlCasesDataProvider
*/
public function testGetUrl(string $identifier, string $class, string $expected): void
{
/** @var Link $link */
$link = $this->objFromFixture($class, $identifier);
$this->assertSame($expected, $link->getURL(), 'We expect specific URL value');
}

public function linkUrlCasesDataProvider(): array
public function provideGetUrl(): array
{
return [
'internal link / page only' => [
Expand Down Expand Up @@ -241,7 +227,21 @@ public function linkUrlCasesDataProvider(): array
];
}

function linkDefaultTitleDataProvider(): array
/**
* @param string $identifier
* @param string $class
* @param string $expected
* @return void
* @dataProvider provideGetUrl
*/
public function testGetUrl(string $identifier, string $class, string $expected): void
{
/** @var Link $link */
$link = $this->objFromFixture($class, $identifier);
$this->assertSame($expected, $link->getURL(), 'We expect specific URL value');
}

function provideDefaultLinkTitle(): array
{
return [
'page link' => [
Expand Down Expand Up @@ -303,7 +303,7 @@ function linkDefaultTitleDataProvider(): array
}

/**
* @dataProvider linkDefaultTitleDataProvider
* @dataProvider provideDefaultLinkTitle
*/
public function testDefaultLinkTitle(string $identifier, string $class, string $expected): void
{
Expand Down
Loading

0 comments on commit 506c81c

Please sign in to comment.