datafield-1.x-dev/src/Plugin/DataField/FieldWidget/HierarchicalSelectWidget.php
src/Plugin/DataField/FieldWidget/HierarchicalSelectWidget.php
<?php
namespace Drupal\datafield\Plugin\DataField\FieldWidget;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\Attribute\FieldWidget;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\datafield\Plugin\DataFieldWidgetInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Plugin implementation of the 'entity_reference' widget.
*/
#[FieldWidget(
id: 'hierarchical_select',
label: new TranslatableMarkup('Hierarchical select'),
field_types: ['entity_reference'],
)]
class HierarchicalSelectWidget implements DataFieldWidgetInterface, ContainerFactoryPluginInterface {
use StringTranslationTrait;
/**
* Constructs a EntityReferenceAutocompleteWidget object.
*
* @param string $plugin_id
* The plugin_id for the formatter.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param mixed $field_definition
* The definition of the field to which the formatter is associated.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
*/
public function __construct($plugin_id, $plugin_definition, $field_definition, protected EntityTypeManagerInterface $entityTypeManager) {
unset($plugin_id, $plugin_definition, $field_definition);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $configuration, $plugin_id, $plugin_definition) {
return new static(
$plugin_id,
$plugin_definition,
$configuration,
$container->get('entity_type.manager'),
);
}
/**
* {@inheritdoc}
*/
public function getFormElement(&$element, $item = NULL, $setting = []) {
$element['#type'] = 'hidden';
$hierarchical_select = [];
$default_value = $element["#default_value"] ?? '';
if (!empty($default_value)) {
$parents = $this->entityTypeManager->getStorage('taxonomy_term')
->loadAllParents($default_value);
if (!empty($parents)) {
$parentsTerms = array_keys($parents);
$parentsTerms = array_reverse($parentsTerms);
$element['#attributes']['data-parents'] = implode('-', $parentsTerms);
}
}
$element['#attributes']['data-vocabulary'] = $element['#field_settings']['target_bundles'];
$element['#attributes']['class'][] = 'hierarchical_select';
if (!empty($bundle = $element["#bundle"]) && empty($hierarchical_select[$bundle])) {
$element['#attached']['library'] = ['datafield/hierarchical_select'];
$hierarchical_select[$bundle] = $this->getTaxonomyParent($bundle);
$element['#attached']['drupalSettings']['datafieldHierarchicalSelect'][$bundle] = [$hierarchical_select[$bundle]];
$url = Url::fromRoute('datafield.hierarchical', ['vocabulary' => $bundle], ['absolute' => TRUE])
->toString();
$element['#attached']['drupalSettings']['datafieldHierarchicalAjax'][$bundle] = $url;
}
}
/**
* Get taxonomy by parent.
*
* @param mixed $vocabulary
* Taxnomy vocabulary.
* @param int $parent
* Parent term id.
*
* @return array
* List taxonomy by parent.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
private function getTaxonomyParent(mixed $vocabulary, int $parent = 0): array {
$tree = [];
$terms = $this->entityTypeManager->getStorage('taxonomy_term')->loadTree($vocabulary, $parent, 1, TRUE);
foreach ($terms as $term) {
$tree[$term->id()] = $term->getName();
}
return $tree;
}
}
