For the case where we have one depth and the user can also choose parents without children. Like the following example:
-- region 1
- countery 1
- country 2
-- region 2
- country 3
- country 4
-- region 3
that the user can select all countries. Also, because region 3 does not have any children, he can choose it. For Drupal 10 I wrote this code:
<?php
namespace Drupal\select2_custom_widget\Plugin\Field\FieldWidget;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\select2\Plugin\Field\FieldWidget\Select2EntityReferenceWidget;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a 'Select2 OptGroup two levels' widget.
*
* @FieldWidget(
* id = "select2_optgroup_two_levels",
* label = @Translation("Select2 OptGroup two levels"),
* field_types = {
* "entity_reference",
* },
* multiple_values = TRUE
* )
*/
class Select2OptGroupTwoLevels extends Select2EntityReferenceWidget implements ContainerFactoryPluginInterface {
/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* {@inheritdoc}
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): Select2EntityReferenceWidget {
return new static(
$plugin_id,
$plugin_definition,
$configuration['field_definition'],
$configuration['settings'],
$configuration['third_party_settings'],
$container->get('entity_type.manager')
);
}
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state): array {
$element = parent::formElement($items, $delta, $element, $form, $form_state);
$element['#options'] = $this->getOptGroupOptions($items);
return $element;
}
/**
* Constructs the optgroup options for the select element.
*
* @param \Drupal\Core\Field\FieldItemListInterface $items
* The field items.
*
* @return array
* The optgroup options.
*/
private function getOptGroupOptions(FieldItemListInterface $items): array {
$field_definition = $items->getFieldDefinition();
$handler_settings = $field_definition->getSetting('handler_settings');
$target_bundles = $handler_settings['target_bundles'] ?? [];
$parents_with_children = $this->getParentsWithChildren($target_bundles);
$result = [];
$current_parent_name = '';
foreach ($target_bundles as $bundle_name => $bundle_info) {
$terms = $this->entityTypeManager->getStorage('taxonomy_term')->loadTree($bundle_name);
foreach ($terms as $term) {
if ($term->depth === 0) {
$current_parent_name = $term->name;
if (!isset($parents_with_children[$term->tid])) {
$result[$term->tid] = $term->name;
} else {
$result[$current_parent_name] = $result[$current_parent_name] ?? [];
}
} elseif ($term->depth === 1) {
$result[$current_parent_name][$term->tid] = $term->name;
}
}
}
return $result;
}
/**
* Identifies parents that have children.
*
* @param array $target_bundles
* The target bundles.
*
* @return array
* An array of parents with children.
*/
private function getParentsWithChildren(array $target_bundles): array {
$parents_with_children = [];
foreach ($target_bundles as $bundle_name => $bundle_info) {
$terms = $this->entityTypeManager->getStorage('taxonomy_term')->loadTree($bundle_name);
foreach ($terms as $term) {
if ($term->depth === 1) {
$parents_with_children[$term->parents[0]] = true;
}
}
}
return $parents_with_children;
}
}
Hello, I installed the prerequisites with this composer require laminas/laminas-feed, but still the error You have requested a non-existent service "feed.bridge.reader". I take Please be more specific, what did you do? Do we have to change the codes?
Hello, I installed the prerequisites with this composer require laminas/laminas-feed, but still the error You have requested a non-existent service "feed.bridge.reader". I take Please be more specific, what did you do? Do we have to change the codes?