function CKEditor5::validateConfigurationForm
Same name in other branches
- 9 core/modules/ckeditor5/src/Plugin/Editor/CKEditor5.php \Drupal\ckeditor5\Plugin\Editor\CKEditor5::validateConfigurationForm()
- 10 core/modules/ckeditor5/src/Plugin/Editor/CKEditor5.php \Drupal\ckeditor5\Plugin\Editor\CKEditor5::validateConfigurationForm()
Overrides EditorBase::validateConfigurationForm
File
-
core/
modules/ ckeditor5/ src/ Plugin/ Editor/ CKEditor5.php, line 570
Class
- CKEditor5
- Defines a CKEditor 5-based text editor for Drupal.
Namespace
Drupal\ckeditor5\Plugin\EditorCode
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
$json = $form_state->getValue([
'toolbar',
'items',
]);
$toolbar_items = Json::decode($json);
// This basic validation must live in the form logic because it can only
// occur in a form context.
if (!$toolbar_items) {
$form_state->setErrorByName('toolbar][items', $this->t('Invalid toolbar value.'));
return;
}
// Construct a Text Editor config entity with the submitted values for
// validation. Do this on a clone: do not manipulate form state.
$submitted_editor = clone $form_state->get('editor');
$settings = $submitted_editor->getSettings();
// Update settings first to match the submitted toolbar items. This is
// necessary for ::shouldHaveVisiblePluginSettingsForm() to work.
$settings['toolbar']['items'] = $toolbar_items;
$submitted_editor->setSettings($settings);
$eventual_editor_and_format_for_plugin_settings_visibility = $this->getEventualEditorWithPrimedFilterFormat($form_state, $submitted_editor);
$settings['plugins'] = [];
$default_configurations = [];
foreach ($this->ckeditor5PluginManager
->getDefinitions() as $plugin_id => $definition) {
if (!$definition->isConfigurable()) {
continue;
}
// Create a fresh instance of this CKEditor 5 plugin, not tied to a text
// editor configuration entity.
$plugin = $this->ckeditor5PluginManager
->getPlugin($plugin_id, NULL);
// If this plugin is configurable but it has empty default configuration,
// that means the configuration must be stored out of band.
// @see \Drupal\ckeditor5\Plugin\CKEditor5Plugin\Image
// @see editor_image_upload_settings_form()
$default_configuration = $plugin->defaultConfiguration();
$configuration_stored_out_of_band = empty($default_configuration);
// If this plugin is configurable but has not yet had user interaction,
// the default configuration will still be active and may trigger
// validation errors. Do not trigger those validation errors until the
// form is actually saved, to allow the user to first configure other
// CKEditor 5 functionality.
$default_configurations[$plugin_id] = $default_configuration;
if ($form_state->hasValue([
'plugins',
$plugin_id,
])) {
$subform = $form['plugins'][$plugin_id];
$subform_state = SubformState::createForSubform($subform, $form, $form_state);
$plugin->validateConfigurationForm($subform, $subform_state);
$plugin->submitConfigurationForm($subform, $subform_state);
// If the configuration is stored out of band, ::submitConfigurationForm
// will already have stored it. If it is not stored out of band,
// populate $settings, to populate $submitted_editor.
if (!$configuration_stored_out_of_band) {
$settings['plugins'][$plugin_id] = $plugin->getConfiguration();
}
}
elseif ($this->shouldHaveVisiblePluginSettingsForm($definition, $eventual_editor_and_format_for_plugin_settings_visibility)) {
if (!$configuration_stored_out_of_band) {
$settings['plugins'][$plugin_id] = $default_configuration;
}
}
}
// All plugin settings have been collected, including defaults that depend
// on visibility. Store the collected settings, throw away the interim state
// that allowed determining which defaults to add.
// Create a new clone, because the plugins whose data is being stored
// out-of-band may have modified the Text Editor config entity in the form
// state.
// @see \Drupal\editor\EditorInterface::setImageUploadSettings()
// @see \Drupal\ckeditor5\Plugin\CKEditor5Plugin\Image::submitConfigurationForm()
unset($eventual_editor_and_format_for_plugin_settings_visibility);
$submitted_editor = clone $form_state->get('editor');
$submitted_editor->setSettings($settings);
// Validate the text editor + text format pair.
// Note that the eventual pair is computed and validated, not the received
// pair: if the filter_html filter is in use, the CKEditor 5 configuration
// dictates the filter_html's filter plugin's "allowed_html" setting.
// @see ckeditor5_form_filter_format_form_alter()
// @see ::getGeneratedAllowedHtmlValue()
$eventual_editor_and_format = $this->getEventualEditorWithPrimedFilterFormat($form_state, $submitted_editor);
$violations = CKEditor5::validatePair($eventual_editor_and_format, $eventual_editor_and_format->getFilterFormat());
foreach ($violations as $violation) {
$property_path_parts = explode('.', $violation->getPropertyPath());
// Special case: AJAX updates that do not submit the form (that cannot
// result in configuration being saved).
if (in_array('editor_form_filter_admin_format_editor_configure', $form_state->getSubmitHandlers(), TRUE)) {
// Ensure that plugins' validation constraints do not immediately
// trigger a validation error: the user may choose to configure other
// CKEditor 5 aspects first.
if ($property_path_parts[0] === 'settings' && $property_path_parts[1] === 'plugins') {
$plugin_id = $property_path_parts[2];
// This CKEditor 5 plugin settings form was just added: the user has
// not yet had a chance to configure it.
if (!$form_state->hasValue([
'plugins',
$plugin_id,
])) {
continue;
}
// This CKEditor 5 plugin settings form was added recently, the user
// is triggering AJAX rebuilds of the configuration UI because they're
// configuring other functionality first. Only require these to be
// valid at form submission time.
if ($form_state->getValue([
'plugins',
$plugin_id,
]) === $default_configurations[$plugin_id]) {
continue;
}
}
}
$form_item_name = static::mapPairViolationPropertyPathsToFormNames($violation->getPropertyPath(), $form);
// When adding a toolbar item, it is possible that not all conditions for
// using it have been met yet. FormBuilder refuses to rebuild forms when a
// validation error is present. But to meet the condition for the toolbar
// item, configuration must be set in a vertical tab that must still
// appear. Work-around: reduce the validation error to a warning message.
// @see \Drupal\ckeditor5\Plugin\Validation\Constraint\ToolbarItemConditionsMetConstraintValidator
if ($form_state->isRedirectDisabled() && $form_item_name === 'editor][settings][toolbar][items') {
$this->messenger()
->addWarning($violation->getMessage());
continue;
}
$form_state->getCompleteFormState()
->setErrorByName($form_item_name, $violation->getMessage());
}
// Pass it on to ::submitConfigurationForm().
$form_state->get('editor')
->setSettings($settings);
// Provide the validated eventual pair in form state to
// ::getGeneratedAllowedHtmlValue(), to update filter_html's
// "allowed_html".
$form_state->set('ckeditor5_validated_pair', $eventual_editor_and_format);
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.