Skip to content

Commit

Permalink
NEW Allowed link types
Browse files Browse the repository at this point in the history
  • Loading branch information
Sabina Talipova committed Dec 12, 2023
1 parent 7f65d4f commit 5a2c284
Show file tree
Hide file tree
Showing 24 changed files with 330 additions and 406 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,41 @@ class ExternalLinkExtension extends Extension

```

The user can control and specify the links allowed for creation in each link field. The `setAllowedTypes` method only includes link types that have been provided as parameters.

```php
<?php
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\LinkField\ORM\DBLink;
use SilverStripe\LinkField\Models\Link;
use SilverStripe\LinkField\Form\LinkField;
use SilverStripe\LinkField\Form\MultiLinkField;
use SilverStripe\LinkField\Models\FileLink;
use SilverStripe\LinkField\Models\SiteTreeLink;

class Page extends SiteTree
{
...

public function getCMSFields()
{
$fields = parent::getCMSFields();

...

$fields->addFieldsToTab(
'Root.Main',
[
MultiLinkField::create('HasManyLinks')
->setAllowedTypes([ SiteTreeLink::class ]),
],
);

return $fields;
}
}
```

## Unversioned links

The `Link` model has the `Versioned` extension applied to it by default. If you wish for links to not be versioned, then remove the extension from the `Link` model in the projects `app/_config.php` file.
Expand Down
8 changes: 0 additions & 8 deletions _config/graphql.yml

This file was deleted.

20 changes: 0 additions & 20 deletions _config/types.yml

This file was deleted.

3 changes: 0 additions & 3 deletions _graphql/queries.yml

This file was deleted.

5 changes: 0 additions & 5 deletions _graphql/types.yml

This file was deleted.

2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions client/src/boot/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/* global document */
/* eslint-disable */
import registerComponents from './registerComponents';
import registerQueries from './registerQueries';

document.addEventListener('DOMContentLoaded', () => {
registerComponents();
registerQueries();
});
8 changes: 0 additions & 8 deletions client/src/boot/registerQueries.js

This file was deleted.

1 change: 0 additions & 1 deletion client/src/components/LinkField/LinkField.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ const mapDispatchToProps = (dispatch) => ({
});

export default compose(
injectGraphql('readLinkTypes'),
fieldHolder,
connect(null, mapDispatchToProps)
)(LinkField);
1 change: 1 addition & 0 deletions client/src/entwine/LinkField.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ jQuery.entwine('ss', ($) => {
value,
onChange: this.handleChange.bind(this),
isMulti: this.data('is-multi') ?? false,
types: this.data('types') ?? [],
};
},

Expand Down
48 changes: 0 additions & 48 deletions client/src/state/linkTypes/readLinkTypes.js

This file was deleted.

9 changes: 5 additions & 4 deletions src/Controllers/LinkFieldController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use SilverStripe\Forms\DefaultFormFactory;
use SilverStripe\Forms\Form;
use SilverStripe\LinkField\Models\Link;
use SilverStripe\LinkField\Type\Registry;
use SilverStripe\Security\SecurityToken;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\FormAction;
Expand All @@ -19,6 +18,8 @@
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forms\HiddenField;
use SilverStripe\LinkField\Form\LinkField;
use SilverStripe\LinkField\Services\LinkTypeService;
use SilverStripe\ORM\DataList;

class LinkFieldController extends LeftAndMain
Expand Down Expand Up @@ -74,7 +75,7 @@ public function linkForm(): Form
}
} else {
$typeKey = $this->typeKeyFromRequest();
$link = Registry::create()->byKey($typeKey);
$link = LinkTypeService::create()->byKey($typeKey);
if (!$link) {
$this->jsonError(404, _t('LinkField.INVALID_TYPEKEY', 'Invalid typeKey'));
}
Expand Down Expand Up @@ -175,7 +176,7 @@ public function save(array $data, Form $form): HTTPResponse
// Creating a new Link
$operation = 'create';
$typeKey = $this->typeKeyFromRequest();
$className = Registry::create()->list()[$typeKey] ?? '';
$className = LinkTypeService::create()->byKey($typeKey) ?? '';
if (!$className) {
$this->jsonError(404, _t('LinkField.INVALID_TYPEKEY', 'Invalid typeKey'));
}
Expand Down Expand Up @@ -240,7 +241,7 @@ private function createLinkForm(Link $link, string $operation): Form
$form = $formFactory->getForm($this, $name, ['Record' => $link]);

// Set where the form is submitted to
$typeKey = Registry::create()->keyByClassName($link->ClassName);
$typeKey = LinkTypeService::create()->keyByClassName($link->ClassName);
$form->setFormAction($this->Link("linkForm/$id?typeKey=$typeKey"));

// Add save action button
Expand Down
3 changes: 3 additions & 0 deletions src/Form/LinkField.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\LinkField\Models\Link;
use SilverStripe\LinkField\Form\Traits\AllowedLinkClassesTrait;

/**
* Allows CMS users to edit a Link object.
*/
class LinkField extends FormField
{
use AllowedLinkClassesTrait;

protected $schemaComponent = 'LinkField';

protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_CUSTOM;
Expand Down
3 changes: 3 additions & 0 deletions src/Form/MultiLinkField.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use LogicException;
use SilverStripe\Forms\FormField;
use SilverStripe\LinkField\Form\Traits\AllowedLinkClassesTrait;
use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\Relation;
Expand All @@ -16,6 +17,8 @@
*/
class MultiLinkField extends FormField
{
use AllowedLinkClassesTrait;

protected $schemaComponent = 'LinkField';

protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_CUSTOM;
Expand Down
104 changes: 104 additions & 0 deletions src/Form/Traits/AllowedLinkClassesTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php

namespace SilverStripe\LinkField\Form\Traits;

use SilverStripe\Core\Injector\Injector;
use SilverStripe\LinkField\Models\Link;
use SilverStripe\LinkField\Services\LinkTypeService;

/**
* Trait to manage which Link type can be added to LinkField form field.
* This trait is used in LinkField and MultiLinkField classes.
*/
trait AllowedLinkClassesTrait
{
private $allowed_types = [];

/**
* Set allowed types for LinkField
*/
public function setAllowedTypes(array $types): static
{
if (empty($types) || !$this->validateTypes($types)) {
$this->allowed_types = $this->genarateAllowedTypes();
} else {
$this->allowed_types = $this->genarateAllowedTypes($types);
}

return $this;
}

/**
* Get allowed types for LinkField
*/
public function getAllowedTypes(): array
{
return $this->allowed_types;
}

/**
* Validate types that they are subclasses of Link
*/
private function validateTypes(array $types): bool
{
$validClasses = [];
foreach ($types as $type) {
if (is_subclass_of($type, Link::class)) {
$validClasses[] = $type;
}
}

return count($validClasses) > 0;
}

/**
* The method returns an associational array converted to a JSON string,
* of available link types with additional parameters necessary
* for full-fledged work on the client side.
* @throws InvalidArgumentException
*/
public function getTypesProps(): string
{
$types = [];
$typeDefinitions = $this->genarateAllowedTypes();

foreach ($typeDefinitions as $key => $class) {
$types[$key] = Injector::inst()->get($class);
}

$typesList = [];

array_map(function (Link $type, string $key) use (&$typesList) {
$typesList[$key] = [
'key' => $key,
'title' => $type->LinkTypeTile(),
'handlerName' => $type->LinkTypeHandlerName(),
];
}, $types, array_keys($types));

return json_encode($typesList);
}

/**
* Generate allowed types with key => value pair
* Example: ['cms' => SiteTreeLink::class]
*/
private function genarateAllowedTypes(array $types = []): array
{
$typeDefinitions = !empty($types) ? $types : $this->getAllowedTypes();

if (empty($typeDefinitions)) {
return LinkTypeService::create()->generateAllLinkTypes();
}

$result = array();
foreach ($typeDefinitions as $class) {
if (is_subclass_of($class, Link::class)) {
$type = Injector::inst()->get($class)->getShortCode();
$result[$type] = $class;
}
}

return $result;
}
}
30 changes: 0 additions & 30 deletions src/GraphQL/LinkTypeResolver.php

This file was deleted.

Loading

0 comments on commit 5a2c284

Please sign in to comment.