View source
<?php
namespace Drupal\webform_shs\Element;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\Select;
class ShsTermSelect extends Select {
protected static $options = NULL;
public function getInfo() {
return [
'#vocabulary' => '',
'#force_deepest' => FALSE,
'#force_deepest_error' => '',
'#cache_options' => FALSE,
'#depth_labels' => [],
'#addNewLabel' => '',
] + parent::getInfo();
}
public static function processSelect(&$element, FormStateInterface $form_state, &$complete_form) {
self::setOptions($element);
$element = parent::processSelect($element, $form_state, $complete_form);
$element['#type'] = 'select';
$route = \Drupal::routeMatch()
->getRouteObject();
if (\Drupal::service('router.admin_context')
->isAdminRoute($route)) {
return $element;
}
$settings = [
'required' => $element['#required'],
'multiple' => $element['#webform_multiple'],
'anyLabel' => $element['#empty_option'] ?? t('- None -'),
'anyValue' => '_none',
'force_deepest' => $element['#force_deepest'],
'cache_options' => $element['#cache_options'],
'#depth_labels' => [],
'addNewLabel' => $element['#addNewLabel'] ?: t('Add another item'),
];
$widget_defaults = \Drupal::service('shs.widget_defaults');
$bundle = $element['#vocabulary'];
$cardinality = $element['#multiple'] ? -1 : 1;
$parents = $widget_defaults
->getInitialParentDefaults($settings['anyValue'], $cardinality);
if (!is_null($element['#value'])) {
$parents = $widget_defaults
->getParentDefaults($element['#value'], $settings['anyValue'], 'taxonomy_term', $cardinality);
}
$settings_shs = [
'settings' => $settings,
'labels' => $element['#depth_labels'],
'bundle' => $bundle,
'baseUrl' => 'shs-term-data',
'cardinality' => $cardinality,
'parents' => $parents,
'defaultValue' => $element['#value'] ?? NULL,
];
$hooks = [
'shs_js_settings',
sprintf('shs_%s_js_settings', $element['#webform_key']),
];
\Drupal::moduleHandler()
->alter($hooks, $settings_shs, $bundle, $element['#webform_key']);
$element['#shs'] = $settings_shs;
$element['#shs']['classes'] = shs_get_class_definitions($element['#webform_key']);
$element['#attributes']['class'][] = 'shs-enabled';
$element['#attributes']['data-shs-selector'] = $element['#webform_key'];
$element['#attached']['library'][] = 'shs/shs.form';
$element['#attached']['drupalSettings']['shs'] = [
$element['#webform_key'] => $element['#shs'],
];
$element['#element_validate'][] = [
self::class,
'validateForceDeepest',
];
return $element;
}
public static function validateForceDeepest(array &$element, FormStateInterface $form_state) {
if (empty($element['#force_deepest'])) {
return;
}
if (!empty($element['#force_deepest_error'])) {
$message = $element['#force_deepest_error'];
}
else {
$message = t('You need to select a term from the deepest level in field @name.', [
'@name' => $element['#title'],
]);
}
$value = $form_state
->getValue($element['#name']);
if (!is_array($value)) {
$value = [
$value,
];
}
foreach ($value as $element_value) {
if ($element['#shs']['settings']['anyValue'] === $element_value) {
if (!$element['#required']) {
continue;
}
elseif (count($element['#options']) > 1) {
$form_state
->setError($element, $message);
return;
}
}
elseif (shs_term_has_children($element_value)) {
$form_state
->setError($element, $message);
return;
}
}
}
public static function setOptions(array &$element) {
if (!empty($element['#options'])) {
return;
}
if (!\Drupal::moduleHandler()
->moduleExists('taxonomy') || empty($element['#vocabulary'])) {
$element['#options'] = [];
return;
}
$element['#options'] = static::getOptions($element);
}
protected static function getOptions(array $element) {
return self::buildOptions($element['#vocabulary'], !empty($element['#cache_options']));
}
public static function getOptionsCacheId($vid) {
return 'webform_shs:options:' . $vid;
}
public static function invalidateOptionsCache($vid) {
$cid = self::getOptionsCacheId($vid);
\Drupal::cache()
->invalidate($cid);
}
public static function buildOptions($vid, $cache_options = FALSE) {
if ($cache_options) {
$options = self::buildCachedTermOptions($vid);
}
else {
$options = self::buildTermOptions($vid);
}
return $options;
}
protected static function buildCachedTermOptions($vid) {
$cid = self::getOptionsCacheId($vid);
if ($cache = \Drupal::cache()
->get($cid)) {
$options = $cache->data;
}
else {
$options = self::buildTermOptions($vid);
\Drupal::cache()
->set($cid, $options, Cache::PERMANENT);
}
return $options;
}
protected static function buildTermOptions($vid) {
$options = [];
$taxonomy_storage = \Drupal::entityTypeManager()
->getStorage('taxonomy_term');
$terms = $taxonomy_storage
->loadTree($vid);
foreach ($terms as $item) {
$options[$item->tid] = $item->name;
}
return $options;
}
}