Skip to content

Commit

Permalink
Merge branch '2' into 3
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/Models/ExternalLink.php
#	src/Models/FileLink.php
#	src/Models/SiteTreeLink.php
#	src/Type/Registry.php
  • Loading branch information
mfendeksilverstripe committed Aug 3, 2023
2 parents 469ad24 + e5e0532 commit f2bc62d
Show file tree
Hide file tree
Showing 14 changed files with 508 additions and 62 deletions.
4 changes: 4 additions & 0 deletions _config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ SilverStripe\Forms\TreeDropdownField:
SilverStripe\CMS\Forms\AnchorSelectorField:
extensions:
- SilverStripe\LinkField\Extensions\AjaxField

SilverStripe\LinkField\Form\FormFactory:
extensions:
- SilverStripe\LinkField\Extensions\FormFactoryExtension
55 changes: 55 additions & 0 deletions src/Extensions/FormFactoryExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace SilverStripe\LinkField\Extensions;

use SilverStripe\Control\RequestHandler;
use SilverStripe\Core\Extension;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\FormAction;
use SilverStripe\LinkField\Form\FormFactory;
use SilverStripe\LinkField\Models\Link;

/**
* Enhance the insert / edit link button label to match the model data state
*
* @method FormFactory getOwner()
*/
class FormFactoryExtension extends Extension
{
/**
* Extension point in @see FormFactory::getFormActions()
*
* @param FieldList $actions
* @param RequestHandler $controller
* @param string $name
* @param array $context
* @return void
*/
public function updateFormActions(FieldList $actions, RequestHandler $controller, string $name, array $context): void
{
if (!array_key_exists('LinkType', $context)) {
// We couldn't find any link model
return;
}

/** @var Link $linkType */
$linkType = $context['LinkType'];

if (!$linkType->exists()) {
// This is a new link, so we don't need to to any further customisation
return;
}

/** @var FormAction $insertAction */
$insertAction = $actions->fieldByName('action_insert');

if (!$insertAction) {
// We couldn't find the insert action
return;
}

// Update the title of the action to reflect the link model data state
$insertActionTitle = _t('Admin.EDIT_LINK', 'Edit link');
$insertAction->setTitle($insertActionTitle);
}
}
15 changes: 14 additions & 1 deletion src/Extensions/ModalController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
use SilverStripe\Admin\ModalController as OwnerController;
use SilverStripe\Control\HTTPResponse_Exception;
use SilverStripe\Core\Extension;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forms\Form;
use SilverStripe\LinkField\Form\FormFactory;
use SilverStripe\LinkField\Models\Link;
use SilverStripe\LinkField\Type\Registry;
use SilverStripe\ORM\DataObject;

/**
* Extensions to apply to ModalController so it knows how to handle the DynamicLink action.
Expand Down Expand Up @@ -69,10 +72,20 @@ private function getContext(): array
throw new HTTPResponse_Exception(sprintf('%s is not a valid link type', $type), 400);
}

$data = $this->getData();

// Hydrate current model in case data is available, so more options are available for CMS fields customsation
// This allows model-level form customisation
if ($data && array_key_exists('ID', $data) && $data['ID']) {
/** @var Link $type */
$type = Injector::inst()->create($type->ClassName, $data, DataObject::CREATE_HYDRATED);
}

return [
'LinkData' => $this->getData(),
'LinkData' => $data,
'LinkType' => $type,
'LinkTypeKey' => $linkTypeKey,
// TODO this is likely a legacy field, use form validator instead
'RequireLinkText' => false
];
}
Expand Down
16 changes: 14 additions & 2 deletions src/Form/FormFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use SilverStripe\Admin\Forms\LinkFormFactory;
use SilverStripe\Forms\HiddenField;
use SilverStripe\LinkField\Type\Type;
use SilverStripe\ORM\DataObject;

/**
* Create Form schema for the LinkField based on a key provided by the request.
Expand All @@ -21,7 +22,11 @@ protected function getFormFields($controller, $name, $context)
throw new LogicException(sprintf('%s: LinkType must be provided and must be an instance of Type', static::class));
}

$fields = $type->scaffoldLinkFields([]);
// Pass on any available link data
$linkData = array_key_exists('LinkData', $context)
? $context['LinkData']
: [];
$fields = $type->scaffoldLinkFields($linkData);
$fields->push(HiddenField::create('typeKey')->setValue($context['LinkTypeKey']));
$this->extend('updateFormFields', $fields, $controller, $name, $context);

Expand All @@ -30,6 +35,13 @@ protected function getFormFields($controller, $name, $context)

protected function getValidator($controller, $name, $context)
{
return null;
if (!array_key_exists('LinkType', $context)) {
return null;
}

/** @var DataObject|Type $type */
$type = $context['LinkType'];

return $type->getCMSCompositeValidator();
}
}
8 changes: 7 additions & 1 deletion src/Form/JsonField.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function setValue($value, $data = null)
return parent::setValue($value, $data);
}

/**
/**
* @param DataObject|DataObjectInterface $record
* @return $this
*/
Expand All @@ -51,16 +51,22 @@ public function saveInto(DataObjectInterface $record)
if ($jsonDataObjectID && $jsonDataObject = $record->$fieldname) {
if ($value) {
$jsonDataObject = $jsonDataObject->setData($value);
$this->extend('onBeforeLinkEdit', $jsonDataObject, $record);
$jsonDataObject->write();
$this->extend('onAfterLinkEdit', $jsonDataObject, $record);
} else {
$this->extend('onBeforeLinkDelete', $jsonDataObject, $record);
$jsonDataObject->delete();
$record->{"{$fieldname}ID"} = 0;
$this->extend('onAfterLinkDelete', $jsonDataObject, $record);
}
} elseif ($value) {
$jsonDataObject = new $class();
$jsonDataObject = $jsonDataObject->setData($value);
$this->extend('onBeforeLinkCreate', $jsonDataObject, $record);
$jsonDataObject->write();
$record->{"{$fieldname}ID"} = $jsonDataObject->ID;
$this->extend('onAfterLinkCreate', $jsonDataObject, $record);
}
} elseif ((DataObject::getSchema()->databaseField(get_class($record), $fieldname))) {
$record->{$fieldname} = $value;
Expand Down
8 changes: 4 additions & 4 deletions src/Models/EmailLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ public function generateLinkDescription(array $data): string

public function getCMSFields(): FieldList
{
$fields = parent::getCMSFields();
$this->beforeUpdateCMSFields(static function (FieldList $fields) {
$fields->replaceField('Email', EmailField::create('Email'));
});

$fields->replaceField('Email', EmailField::create('Email'));

return $fields;
return parent::getCMSFields();
}

public function getURL(): string
Expand Down
6 changes: 4 additions & 2 deletions src/Models/FileLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
/**
* A link to a File track in asset-admin
*
* @property File $File
* @property int $FileID
* @method File File()
*/
class FileLink extends Link
{
Expand Down Expand Up @@ -38,6 +38,8 @@ public function LinkTypeHandlerName(): string

public function getURL(): string
{
return $this->File?->getURL() ?? '';
$file = $this->File();

return $file->exists() ? (string) $file->getURL() : '';
}
}
33 changes: 17 additions & 16 deletions src/Models/Link.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,23 +73,24 @@ public function scaffoldLinkFields(array $data): FieldList
*/
public function getCMSFields(): FieldList
{
$fields = parent::getCMSFields();
$linkTypes = $this->getLinkTypes();

if (static::class === self::class) {
// Add a link type selection field for generic links
$fields->addFieldsToTab(
'Root.Main',
[
$linkTypeField = DropdownField::create('LinkType', 'Link Type', $linkTypes),
],
'Title'
);

$linkTypeField->setEmptyString('-- select type --');
}
$this->beforeUpdateCMSFields(function (FieldList $fields) {
$linkTypes = $this->getLinkTypes();

if (static::class === self::class) {
// Add a link type selection field for generic links
$fields->addFieldsToTab(
'Root.Main',
[
$linkTypeField = DropdownField::create('LinkType', 'Link Type', $linkTypes),
],
'Title'
);

$linkTypeField->setEmptyString('-- select type --');
}
});

return $fields;
return parent::getCMSFields();
}

/**
Expand Down
74 changes: 47 additions & 27 deletions src/Models/SiteTreeLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@

use SilverStripe\CMS\Forms\AnchorSelectorField;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Control\Controller;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\TreeDropdownField;

/**
* A link to a Page in the CMS
*
* @property int $PageID
* @property string $Anchor
* @property string $QueryString
* @method SiteTree Page()
*/
class SiteTreeLink extends Link
Expand All @@ -20,6 +23,7 @@ class SiteTreeLink extends Link

private static array $db = [
'Anchor' => 'Varchar',
'QueryString' => 'Varchar',
];

private static array $has_one = [
Expand All @@ -46,42 +50,58 @@ public function generateLinkDescription(array $data): string

public function getCMSFields(): FieldList
{
$fields = parent::getCMSFields();
$this->beforeUpdateCMSFields(static function (FieldList $fields) {
// Remove scaffolded fields to we don't have field name conflicts which would prevent field customisation
$fields->removeByName([
'PageID',
'Anchor',
'QueryString',
]);

$titleField = $fields->dataFieldByName('Title');
$titleField?->setDescription('Auto generated from Page title if left blank');

$fields->insertAfter(
'Title',
TreeDropdownField::create(
'PageID',
'Page',
SiteTree::class,
'ID',
'TreeTitle'
)
);

$fields->insertAfter(
'PageID',
$queryStringField = TextField::create('QueryString')
);

$titleField = $fields->dataFieldByName('Title');
$titleField->setDescription('Auto generated from Page title if left blank');
$queryStringField->setDescription('Do not prepend "?". EG: "option1=value&option2=value2"');

$fields->insertAfter(
'Title',
TreeDropdownField::create(
'PageID',
'Page',
SiteTree::class,
'ID',
'TreeTitle'
)
);

$fields->insertAfter(
'PageID',
AnchorSelectorField::create('Anchor')
->setDescription('Do not prepend "#". EG: "option1=value&option2=value2"')
);

return $fields;
$fields->insertAfter(
'QueryString',
$anchorField = AnchorSelectorField::create('Anchor')
);

$anchorField->setDescription(
'Do not prepend "#". Anchor suggestions will be displayed once the linked page is attached.'
);
});

return parent::getCMSFields();
}

public function getURL(): string
{
$url = $this->Page() ? $this->Page()->Link() : '';
$page = $this->Page();
$url = $page->exists() ? $page->Link() : '';
$anchorSegment = $this->Anchor ? '#' . $this->Anchor : '';
$queryStringSegment = $this->QueryString ? '?' . $this->QueryString : '';

$this->extend('updateGetURLBeforeAnchor', $url);

if ($this->Anchor) {
$url .= '#' . $this->Anchor;
}

return $url;
return Controller::join_links($url, $anchorSegment, $queryStringSegment);
}

/**
Expand Down
Loading

0 comments on commit f2bc62d

Please sign in to comment.