ckeditor5-1.0.x-dev/src/Plugin/Validation/Constraint/EnabledConfigurablePluginsConstraintValidator.php
src/Plugin/Validation/Constraint/EnabledConfigurablePluginsConstraintValidator.php
<?php
declare(strict_types = 1);
namespace Drupal\ckeditor5\Plugin\Validation\Constraint;
use Drupal\ckeditor5\Plugin\CKEditor5PluginConfigurableInterface;
use Drupal\ckeditor5\Plugin\CKEditor5PluginInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\editor\EditorInterface;
use Drupal\editor\Entity\Editor;
use Drupal\filter\Entity\FilterFormat;
use Drupal\filter\FilterFormatInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
/**
* Enabled configurable plugin settings validator.
*/
class EnabledConfigurablePluginsConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
use CKEditor5ConstraintValidatorTrait;
/**
* {@inheritdoc}
*/
public function validate($settings, Constraint $constraint) {
if (!$constraint instanceof EnabledConfigurablePluginsConstraint) {
throw new UnexpectedTypeException($constraint, __NAMESPACE__ . '\EnabledConfigurablePluginsConstraint');
}
$configurable_enabled_plugins = $this->getConfigurableEnabledPlugins();
try {
$plugin_settings = $this->context->getRoot()->get('settings.plugins')->getValue();
}
catch (\InvalidArgumentException $e) {
$plugin_settings = [];
}
foreach ($configurable_enabled_plugins as $id => $instance) {
$conditions = $instance->getPluginDefinition()['conditions'] ?? [];
if (isset($conditions['imageUploadStatus']) && $conditions['imageUploadStatus'] === TRUE) {
// This is the exception to the rule: this is a privileged plugin due to
// the Text Editor config entity's built-in image upload settings.
// @see \Drupal\editor\Entity\Editor::getImageUploadSettings()
// @see editor_image_upload_settings_form()
// @see \Drupal\ckeditor5\Plugin\CKEditor5Plugin\ImageUpload::settingsForm()
continue;
}
if (!isset($plugin_settings[$id]) || empty($plugin_settings[$id])) {
$this->context->buildViolation($constraint->message)
->setParameter('%plugin_label', $instance->getPluginDefinition()['label'])
->setParameter('%plugin_id', $id)
->atPath("plugins.$id")
->addViolation();
}
}
}
/**
* Gets all configurable CKEditor 5 plugin instances that are enabled.
*
* @return \Drupal\ckeditor5\Plugin\CKEditor5PluginConfigurableInterface[]
* An array of enabled configurable CKEditor 5 plugin instances.
*/
private function getConfigurableEnabledPlugins() : array {
// CKEditor5PluginManager::getEnabledDefinitions() needs to know the list of
// enabled filters. Therefore we must pass a text format config entity.
// @see \Drupal\ckeditor5\Plugin\CKEditor5PluginManager::isPluginDisabled()
if ($this->context->getRoot()->getDataDefinition()->getDataType() === 'ckeditor5_valid_pair__format_and_editor') {
$text_format = FilterFormat::create([
'filters' => $this->context->getRoot()->get('filters')->toArray(),
]);
}
else {
assert($this->context->getRoot()->getDataDefinition()->getDataType() === 'editor.editor.*');
$text_format = FilterFormat::load($this->context->getRoot()->get('format')->getValue());
}
assert($text_format instanceof FilterFormatInterface);
$text_editor = Editor::create([
'editor' => 'ckeditor5',
'settings' => $this->context->getRoot()->get('settings')->toArray(),
'image_upload' => $this->context->getRoot()->get('image_upload')->toArray(),
// Specify `filterFormat` to ensure that the generated Editor config
// entity object already has the $filterFormat property set, to prevent
// calls to Editor::hasAssociatedFilterFormat() and
// Editor::getFilterFormat() from loading the FilterFormat from storage.
// As far as this validation constraint validator is concerned, the
// concrete FilterFormat entity ID does not matter, all that matters is
// its filter configuration. Those exist in $text_format.
'filterFormat' => $text_format,
]);
assert($text_editor instanceof EditorInterface);
$enabled_plugins = array_intersect_key(
$this->pluginManager->getPlugins(),
$this->pluginManager->getEnabledDefinitions($text_editor)
);
$configurable_enabled_plugins = array_filter($enabled_plugins, function (CKEditor5PluginInterface $instance) : bool {
return $instance instanceof CKEditor5PluginConfigurableInterface;
});
return $configurable_enabled_plugins;
}
}
