Skip to content

Commit

Permalink
API Provide a way to register link forms dynamically for ModalController
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli committed Nov 25, 2024
1 parent 64c9c5a commit 3ac554d
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 42 deletions.
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/src/containers/InsertLinkModal/InsertLinkModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const createInsertLinkModal = (sectionConfigKey, formName) => {

// get the schemaUrl to use as a key for overrides
const schemaUrl = `${sectionConfig.form[formName].schemaUrl}${requireTextFieldUrl}`
.replace(/:pageid/, ownProps.currentPageID);
.replace(/:pageid/, ownProps.currentPageID || 0);

return {
sectionConfig,
Expand Down
24 changes: 12 additions & 12 deletions code/FormSchemaController.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public function setFormSchema(FormSchema $schema): static
}

/**
* Gets a JSON schema representing the current edit form.
* Gets a JSON schema representing a form.
*/
public function schema(HTTPRequest $request): HTTPResponse
{
Expand Down Expand Up @@ -103,16 +103,6 @@ public function schema(HTTPRequest $request): HTTPResponse
return $this->getSchemaResponse($schemaID, $form);
}

/**
* Check if the current request has a X-Formschema-Request header set.
* Used by conditional logic that responds to validation results
*/
protected function getSchemaRequested(): bool
{
$parts = $this->getRequest()->getHeader(static::SCHEMA_HEADER);
return !empty($parts);
}

/**
* Generate schema for the given form based on the X-Formschema-Request header value
*
Expand All @@ -121,7 +111,7 @@ protected function getSchemaRequested(): bool
* @param ValidationResult $errors Required for 'error' response
* @param array $extraData Any extra data to be merged with the schema response
*/
protected function getSchemaResponse(string $schemaID, ?Form $form = null, ValidationResult $errors = null, array $extraData = []): HTTPResponse
public function getSchemaResponse(string $schemaID, ?Form $form = null, ValidationResult $errors = null, array $extraData = []): HTTPResponse
{
$parts = $this->getRequest()->getHeader(static::SCHEMA_HEADER);
$data = $this
Expand All @@ -137,6 +127,16 @@ protected function getSchemaResponse(string $schemaID, ?Form $form = null, Valid
return $response;
}

/**
* Check if the current request has a X-Formschema-Request header set.
* Used by conditional logic that responds to validation results
*/
protected function getSchemaRequested(): bool
{
$parts = $this->getRequest()->getHeader(static::SCHEMA_HEADER);
return !empty($parts);
}

private function prepareTinyMce(): void
{
// Set the members html editor config
Expand Down
11 changes: 3 additions & 8 deletions code/LeftAndMain.php
Original file line number Diff line number Diff line change
Expand Up @@ -310,14 +310,9 @@ public function getClientConfig(): array
// Add WYSIWYG link form schema before extensions are applied
$this->beforeExtending('updateClientConfig', function (array &$clientConfig): void {
$modalController = ModalController::singleton();
$clientConfig['form'] = [
'EditorExternalLink' => [
'schemaUrl' => $modalController->Link('schema/EditorExternalLink'),
],
'EditorEmailLink' => [
'schemaUrl' => $modalController->Link('schema/EditorEmailLink'),
],
];
foreach (array_keys(ModalController::config()->get('link_modal_form_factories')) as $name) {
$clientConfig['form'][$name]['schemaUrl'] = $modalController->Link('linkModalFormSchema/' . $name . '/:pageid');
}
});
return parent::getClientConfig();
}
Expand Down
82 changes: 62 additions & 20 deletions code/ModalController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

namespace SilverStripe\Admin;

use LogicException;
use SilverStripe\Admin\Forms\EditorEmailLinkFormFactory;
use SilverStripe\Admin\Forms\EditorExternalLinkFormFactory;
use SilverStripe\Admin\Forms\LinkFormFactory;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forms\Form;

/**
Expand All @@ -13,40 +18,77 @@ class ModalController extends FormSchemaController
{
private static ?string $url_segment = 'modals';

private static $allowed_actions = [
'EditorExternalLink',
'EditorEmailLink',
private static string $required_permission_codes = 'CMS_ACCESS';

private static array $allowed_actions = [
'linkModalForm',
'linkModalFormSchema',
];

private static string $required_permission_codes = 'CMS_ACCESS';
private static array $url_handlers = [
'linkModalForm/$ModalName/$ItemID' => 'linkModalForm',
'GET linkModalFormSchema/$ModalName/$ItemID' => 'linkModalFormSchema',
];

/**
* Associative array of modal form names to form factory classes.
* Used primarily to register modal form factories for use in the WYSIWYG link plugin.
* Form factories must subclass LinkFormFactory
*/
private static array $link_modal_form_factories = [
'EditorExternalLink' => EditorExternalLinkFormFactory::class,
'EditorEmailLink' => EditorEmailLinkFormFactory::class,
];

/**
* Builds and returns the external link form
* Get a link modal form built from a factory.
* Intended to be used in conjunction with linkModalFormSchema()
*/
public function EditorExternalLink(): Form
public function linkModalForm(HTTPRequest $request): Form
{
$modalName = $request->param('ModalName');
$itemID = $request->param('ItemID');
if ($modalName === null || $itemID === null) {
$this->jsonError(400, 'Missing request params');
}
$modalForms = static::config()->get('link_modal_form_factories');
if (!array_key_exists($modalName, $modalForms)) {
$this->httpError(400);
}
// Show link text field if requested
$showLinkText = $this->getRequest()->getVar('requireLinkText');
$factory = EditorExternalLinkFormFactory::singleton();
return $factory->getForm(
$class = $modalForms[$modalName];
if (!is_a($class, LinkFormFactory::class, true)) {
throw new LogicException("Factory for '$modalName' must be a subclass of " . LinkFormFactory::class);
}

// Build the form
/** @var LinkFormFactory $factory */
$factory = Injector::inst()->get($class);
$form = $factory->getForm(
$this,
__FUNCTION__,
[ 'RequireLinkText' => isset($showLinkText) ]
'linkModalForm/'.$modalName,
[
'RequireLinkText' => isset($showLinkText),
'ItemID' => $itemID,
]
);
// Set url handler that handles ItemID param correctly
$form->setRequestHandler(
LeftAndMainFormRequestHandler::create($form, [$itemID])
);
return $form;
}

/**
* Builds and returns the external link form
* Gets a JSON schema representing a link modal form.
* Links to this must include the ID of the current record or 0
* e.g ModalController::singleton()->Link('linkModalFormSchema/myModalForm/:pageid')
*/
public function EditorEmailLink(): Form
public function linkModalFormSchema(HTTPRequest $request): HTTPResponse
{
// Show link text field if requested
$showLinkText = $this->getRequest()->getVar('requireLinkText');
$factory = EditorEmailLinkFormFactory::singleton();
return $factory->getForm(
$this,
__FUNCTION__,
[ 'RequireLinkText' => isset($showLinkText) ]
);
$form = $this->linkModalForm($request);
$schemaID = $request->getURL();
return $this->getSchemaResponse($schemaID, $form);
}
}

0 comments on commit 3ac554d

Please sign in to comment.