Thanks! Merged.
Hi Rahul. I've added you as a maintainer to this project. Thank you for your efforts to improve this module!
nikita_tt β created an issue.
Finally! Congratulations!
nikita_tt β created an issue.
<?php
namespace Drupal\customer_portal\Plugin\facets\processor;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\facets\FacetInterface;
use Drupal\facets\Plugin\facets\processor\HierarchyProcessor;
use Drupal\facets\Result\Result;
use Drupal\taxonomy\Entity\Term;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* The hierarchy processor transforms the result in a tree.
*
* This processor must be run before the URL processor.
*
* @FacetsProcessor(
* id = "child_hierarchy_processor",
* label = @Translation("Build hierarchy tree only with children terms"),
* description = @Translation("Build the tree for facets that use hierarchy."),
* stages = {
* "build" = 100,
* },
* locked = false,
* default_enabled = false,
* )
*/
class ChildHierarchyProcessor extends HierarchyProcessor implements ContainerFactoryPluginInterface {
/**
* The current route match.
*
* @var \Drupal\Core\Routing\RouteMatchInterface
*/
protected $routeMatch;
/**
* Constructs a new object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The current route match.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->routeMatch = $route_match;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('current_route_match')
);
}
/**
* An array of all entity ids in the active resultset which are a child.
*
* @var string[]
*/
protected $childIds = [];
/**
* {@inheritdoc}
*/
public function build(FacetInterface $facet, array $results) {
// Handle hierarchy.
if ($results) {
$keyed_results = [];
foreach ($results as $result) {
$keyed_results[$result->getRawValue()] = $result;
}
$hierarchy = $facet->getHierarchyInstance();
$facet->addCacheableDependency($hierarchy);
$parent_groups = $hierarchy->getChildIds(array_keys($keyed_results));
$keyed_results = $this->buildAdvancedHierarchicalTree($keyed_results, $parent_groups, $facet);
// Remove children from primary level.
foreach (array_unique($this->childIds) as $child_id) {
unset($keyed_results[$child_id]);
}
// Display only children of the current taxonomy term.
if ($current_term_id = $this->getCurrentTermId($facet, $results, $keyed_results)) {
if (array_key_exists($current_term_id, $keyed_results)) {
$keyed_results = $keyed_results[$current_term_id]->getChildren();
// Set facet name.
$this->prepareFacetName($facet, $current_term_id);
}
// If the term is not in the list of top level terms then this most
// likely means this term in the deepest level of tree that can be
// displayed using this facet widget.
// So at first, it is needed to check if any of the parents of the
// current term is in the list of options. And if so then remove all
// options ("all" because the current term is at the bottom of hierarchy
// and it cannot have any options).
else {
$parent_term_ids = $hierarchy->getParentIds($current_term_id);
if (array_intersect($parent_term_ids, array_keys($keyed_results))) {
$deepest_possible_level = TRUE;
}
}
}
$results = !empty($deepest_possible_level) ? [] : array_values($keyed_results);
}
return $results;
}
/**
* Prepares facet name.
*
* @param \Drupal\facets\FacetInterface $facet
* Facet instance.
* @param null|string $term_id
* Term ID.
* @param array $other_data
* Something else.
*/
protected function prepareFacetName($facet, $term_id = NULL, array $other_data = []) {
if ($facet->get('show_title') === TRUE && ($term = Term::load($term_id))) {
$facet->set('name', $term->label());
}
}
/**
* Find the term ID that is the parent of options that must be shown.
*
* @param \Drupal\facets\FacetInterface $facet
* Facet instance.
* @param \Drupal\facets\Result\Result[] $results
* Facet results.
* @param \Drupal\facets\Result\Result[] $keyed_results
* Processed results.
*
* @return string|null
* Taxonomy term ID.
*/
protected function getCurrentTermId(FacetInterface $facet, array $results, array $keyed_results) {
$current_term_id = NULL;
if ($this->routeMatch->getRouteName() === 'entity.taxonomy_term.canonical') {
$current_term_id = $this->routeMatch->getRawParameter('taxonomy_term');
}
return $current_term_id;
}
/**
* Builds a hierarchical structure for results.
*
* When given an array of results and an array which defines the hierarchical
* structure, this will build the results structure and set all childs.
*
* @param \Drupal\facets\Result\ResultInterface[] $keyed_results
* An array of results keyed by id.
* @param array $parent_groups
* An array of 'child id arrays' keyed by their parent id.
*
* @return \Drupal\facets\Result\ResultInterface[]
* An array of results structured hierarchically.
*/
protected function buildAdvancedHierarchicalTree(array $keyed_results, array $parent_groups, $facet): array {
$processors = $facet->getProcessorsByStage('build');
if (isset($processors['translate_entity'])) {
/** @var \Drupal\facets\Plugin\facets\processor\TranslateEntityProcessor $translate_entity_processor */
$translate_entity_processor = $processors['translate_entity'];
}
foreach ($keyed_results as &$result) {
$current_id = $result->getRawValue();
if (isset($parent_groups[$current_id]) && $parent_groups[$current_id]) {
$child_ids = $parent_groups[$current_id];
$child_keyed_results = [];
foreach ($child_ids as $child_id) {
if (isset($keyed_results[$child_id])) {
$child_keyed_results[$child_id] = $keyed_results[$child_id];
}
else {
$child_keyed_results[$child_id] = new Result($facet, $child_id, $child_id, 0);
}
}
// Set active status for child options that have been just created.
$facet->setResults($child_keyed_results);
// Display entity labels instead of entity IDs.
if (!empty($translate_entity_processor)) {
$child_keyed_results = $translate_entity_processor->build($facet, $child_keyed_results);
}
$result->setChildren($child_keyed_results);
$this->childIds = array_merge($this->childIds, $child_ids);
}
}
return $keyed_results;
}
}
@paulrad Thank you for the patch! Wouldn't it be better to have this code in a separate sub-module? What do you think?
More details are here: https://www.drupal.org/project/country/issues/3196869#comment-15377861 π Autocomplete field widget error in case of BaseField Postponed: needs info
Hi. As I remember there was a problem if the field was a base field (defined in the entity class) of the custom entity type.
Steps to reproduce:
1. Create a custom entity type. It can be generated via drush or drupal console.
2. Add the country field to this custom entity type. (baseFieldDefinitions
method)
$fields['residence_country'] = BaseFieldDefinition::create('country')
->setLabel(t('Country of residence'))
->setRevisionable(TRUE)
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE)
->setRequired(TRUE);
3. Go to the entity create/edit form and try to add a value to the Country field. You will see the error.
Note: I'm not sure whether the issue is still relevant or not.
Confirm it works. Thanks!
Corrected. Thank you!
Thanks again, @srilakshmier, for the patch! The new dev branch has been created and patched, and the new release (2.0.0) has been published.
I've used the commit message proposed in this ticket for adding credits for @srilakshmier but I'm not sure if it worked correctly.
Thanks! The lowest supported Drupal version was changed to 9.5 because of PHP8 requirements.
See
https://www.drupal.org/docs/getting-started/system-requirements/php-requ... β
nikita_tt β made their first commit to this issueβs fork.
Thanks, @srilakshmier, for the patch!
Can someone advise what way should I choose for applying this patch? I'm in doubt because the current latest version of the module (8.x-1.7) supports 8 AND 10 versions of Drupal but this new hook is available only for 9.2.x and higher.
Should I change the required Drupal version for the latest module version and create a new release only for D10?
nikita_tt β created an issue.
I agree with #10. This patch does not make any sense.
Thank you! The new tag has been added.
nikita_tt β created an issue.
Merged. Sorry for the delay.
nikita_tt β made their first commit to this issueβs fork.
#434 works on 8.8.1
Thank you very much!