View source
<?php
namespace Drupal\webform\Plugin;
use Drupal\Component\Plugin\FallbackPluginManagerInterface;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Extension\ThemeHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\CategorizingPluginManagerTrait;
use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\Core\Render\ElementInfoManagerInterface;
use Drupal\webform\Utility\WebformElementHelper;
use Drupal\webform\WebformSubmissionForm;
class WebformElementManager extends DefaultPluginManager implements FallbackPluginManagerInterface, WebformElementManagerInterface {
use CategorizingPluginManagerTrait;
protected $themeHandler;
protected $configFactory;
protected $elementInfo;
protected $instances = [];
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, ConfigFactoryInterface $config_factory, ElementInfoManagerInterface $element_info) {
parent::__construct('Plugin/WebformElement', $namespaces, $module_handler, 'Drupal\\webform\\Plugin\\WebformElementInterface', 'Drupal\\webform\\Annotation\\WebformElement');
$this->configFactory = $config_factory;
$this->elementInfo = $element_info;
$this->themeHandler = $theme_handler;
$this
->alterInfo('webform_element_info');
$this
->setCacheBackend($cache_backend, 'webform_element_plugins');
}
protected function alterDefinitions(&$definitions) {
$this->themeHandler
->reset();
foreach ($definitions as $element_key => $element_definition) {
if (!$this->elementInfo
->getInfo($element_key)) {
unset($definitions[$element_key]);
continue;
}
foreach ($element_definition['dependencies'] as $dependency) {
if (!$this->moduleHandler
->moduleExists($dependency)) {
unset($definitions[$element_key]);
continue;
}
}
}
parent::alterDefinitions($definitions);
}
public function getFallbackPluginId($plugin_id, array $configuration = []) {
return 'webform_element';
}
public function createInstance($plugin_id, array $configuration = []) {
if (empty($configuration)) {
if (!isset($this->instances[$plugin_id])) {
$this->instances[$plugin_id] = parent::createInstance($plugin_id, $configuration);
}
return $this->instances[$plugin_id];
}
else {
return parent::createInstance($plugin_id, $configuration);
}
}
public function getInstances() {
$plugin_definitions = $this
->getDefinitions();
$plugin_definitions = $this
->getSortedDefinitions($plugin_definitions);
$plugin_definitions = $this
->removeExcludeDefinitions($plugin_definitions);
foreach ($plugin_definitions as $plugin_id => $plugin_definition) {
$this
->createInstance($plugin_id);
}
return $this->instances;
}
public function initializeElement(array &$element) {
$element_plugin = $this
->getElementInstance($element);
$element_plugin
->initialize($element);
}
public function buildElement(array &$element, array $form, FormStateInterface $form_state) {
$form_object = $form_state
->getFormObject();
$webform_submission = $form_object instanceof WebformSubmissionForm ? $form_object
->getEntity() : NULL;
$webform = $webform_submission ? $webform_submission
->getWebform() : NULL;
$element_plugin = $this
->getElementInstance($element, $webform_submission ?: $webform);
$element_plugin
->prepare($element, $webform_submission);
$element_plugin
->finalize($element, $webform_submission);
$element_plugin
->setDefaultValue($element);
$hooks = [
'webform_element',
];
if (!empty($element['#type'])) {
$hooks[] = 'webform_element_' . $element['#type'];
}
$context = [
'form' => $form,
];
$this->moduleHandler
->alter($hooks, $element, $form_state, $context);
if ($webform_submission) {
$webform
->invokeHandlers('alterElement', $element, $form_state, $context);
}
}
public function processElement(array &$element) {
$element_plugin = $this
->getElementInstance($element);
$element_plugin
->initialize($element);
$element_plugin
->prepare($element);
$element_plugin
->finalize($element);
$element_plugin
->setDefaultValue($element);
return $element;
}
public function processElements(array &$elements) {
foreach ($elements as $key => &$element) {
if (!WebformElementHelper::isElement($element, $key)) {
continue;
}
$this
->processElement($element);
$this
->processElements($element);
}
}
public function invokeMethod($method, array &$element, &$context1 = NULL, &$context2 = NULL) {
if (!isset($element['#type'])) {
return NULL;
}
$plugin_id = $this
->getElementPluginId($element);
$webform_element = $this
->createInstance($plugin_id);
return $webform_element
->{$method}($element, $context1, $context2);
}
public function getElementPluginId(array $element) {
if (isset($element['#webform_plugin_id']) && $this
->hasDefinition($element['#webform_plugin_id'])) {
return $element['#webform_plugin_id'];
}
elseif (isset($element['#type']) && $this
->hasDefinition($element['#type'])) {
return $element['#type'];
}
elseif (isset($element['#markup'])) {
return 'webform_markup';
}
return $this
->getFallbackPluginId(NULL);
}
public function getElementInstance(array $element, EntityInterface $entity = NULL) {
$plugin_id = $this
->getElementPluginId($element);
$element_plugin = $this
->createInstance($plugin_id, $element);
if ($entity) {
$element_plugin
->setEntities($entity);
}
else {
$element_plugin
->resetEntities();
}
return $element_plugin;
}
public function getSortedDefinitions(array $definitions = NULL, $sort_by = 'label') {
$definitions = isset($definitions) ? $definitions : $this
->getDefinitions();
switch ($sort_by) {
case 'category':
uasort($definitions, function ($a, $b) use ($sort_by) {
return strnatcasecmp($a['category'] . '-' . $a[$sort_by], $b['category'] . '-' . $b[$sort_by]);
});
break;
default:
uasort($definitions, function ($a, $b) use ($sort_by) {
return strnatcasecmp($a[$sort_by], $b[$sort_by]);
});
break;
}
return $definitions;
}
public function getGroupedDefinitions(array $definitions = NULL, $label_key = 'label') {
$definitions = $this
->getSortedDefinitions(isset($definitions) ? $definitions : $this
->getDefinitions(), $label_key);
$basic_category = (string) $this
->t('Basic elements');
$advanced_category = (string) $this
->t('Advanced elements');
$other_category = (string) $this
->t('Other elements');
$grouped_definitions = [
$basic_category => [],
$advanced_category => [],
];
foreach ($definitions as $id => $definition) {
$grouped_definitions[(string) $definition['category']][$id] = $definition;
}
if (isset($grouped_definitions[''])) {
$no_category = $grouped_definitions[''];
unset($grouped_definitions['']);
$grouped_definitions += [
$other_category => $no_category,
];
}
return $grouped_definitions;
}
public function removeExcludeDefinitions(array $definitions) {
$definitions = isset($definitions) ? $definitions : $this
->getDefinitions();
$excluded = $this->configFactory
->get('webform.settings')
->get('element.excluded_elements');
return $excluded ? array_diff_key($definitions, $excluded) : $definitions;
}
public function getTranslatableProperties() {
$properties = [];
$webform_elements = $this
->getInstances();
foreach ($webform_elements as $webform_element) {
$translatable_properties = $webform_element
->getTranslatableProperties();
$properties += array_combine($translatable_properties, $translatable_properties);
}
ksort($properties);
return $properties;
}
public function getAllProperties() {
$properties = [];
$webform_elements = $this
->getInstances();
foreach ($webform_elements as $webform_element) {
$default_properties = array_keys($webform_element
->getDefaultProperties());
$properties += array_combine($default_properties, $default_properties);
}
ksort($properties);
return $properties;
}
public function isExcluded($type) {
return $this->configFactory
->get('webform.settings')
->get('element.excluded_elements.' . $type) ? TRUE : FALSE;
}
}