Closed (fixed)
Project:
Facets
Version:
8.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Support request
Assigned:
Unassigned
Reporter:
Created:
5 Jul 2018 at 12:01 UTC
Updated:
3 Nov 2022 at 05:24 UTC
Jump to comment: Most recent
Hello,
I would like to know if this code could be valid for limiting the facet terms based on the depth level.
I've done a quick code to see if it is the proper way, could someone check it and tell me if it is the way to go?
It is working fine in the first try that I've made (not fully tested with bunch of cases).
Code is not complete and vocabulary is needed (probably we can get vocabulary from the facet source).
<?php
namespace Drupal\my_module\Plugin\facets\processor;
use Drupal\Core\Form\FormStateInterface;
use Drupal\facets\FacetInterface;
use Drupal\facets\Processor\BuildProcessorInterface;
use Drupal\facets\Processor\ProcessorPluginBase;
use Drupal\taxonomy\Entity\Vocabulary;
/**
* Processor that filters out results if they don't belong to a level of depth.
*
* @FacetsProcessor(
* id = "term_depth",
* label = @Translation("Show only terms for a given level of depth"),
* description = @Translation("Show only terms for a given level of depth"),
* stages = {
* "build" = 40
* }
* )
*/
class TermDepth extends ProcessorPluginBase implements BuildProcessorInterface {
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet) {
$processors = $facet->getProcessors();
$config = isset($processors[$this->getPluginId()]) ?
$processors[$this->getPluginId()] : NULL;
$min_level = 1;
$build['level'] = [
'#title' => $this->t('Level'),
'#type' => 'number',
'#min' => $min_level,
'#default_value' => !is_null($config) ? $config->getConfiguration()['level'] : $min_level,
'#description' => $this->t("Only show results for this level being 1 the root level."),
];
$options = [];
$vocabularies = Vocabulary::loadMultiple();
foreach ($vocabularies as $vid => $vocab) {
$options[$vid] = $vocab->label();
}
$build['bundle'] = [
'#type' => 'select',
'#title' => $this->t('Vocabulary'),
'#default_value' => !is_null($config) ? $config->getConfiguration()['bundle'] : NULL,
'#description' => $this->t("Choose vocabulary."),
'#options' => $options,
];
return $build;
}
/**
* {@inheritdoc}
*/
public function build(FacetInterface $facet, array $results) {
$processors = $facet->getProcessors();
$config = $processors[$this->getPluginId()];
$level = $config->getConfiguration()['level'];
$depth = $level - 1;
$vocabulary = $config->getConfiguration()['bundle'];
try {
/** @var \Drupal\taxonomy\TermInterface[] $market_tree_root_terms */
$terms = \Drupal::entityTypeManager()
->getStorage('taxonomy_term')
->loadTree($vocabulary, 0, $level, FALSE);
$valid_terms = [];
foreach ($terms as $term) {
if ($term->depth === $depth) {
$valid_terms[] = $term->tid;
}
}
/** @var \Drupal\facets\Result\ResultInterface $result */
$filtered_results = array_filter($results, function ($result) use ($valid_terms) {
return in_array($result->getRawValue(), $valid_terms);
});
$results = $filtered_results;
}
catch (\Exception $e) {
$results = [];
}
return $results;
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet) {
parent::validateConfigurationForm($form, $form_state, $facet);
}
}Thanks in advance.
Comments
Comment #2
rituraj.gupta commentedHi,
Above code is well written but if you have multiple vocab with depth then this will not work.
Comment #3
tuwebo commentedHi @rituraj.,gupta, thanks very much for the review, I appreciate it. We can close this support request, anyone feel free to open it if it is needed.
Comment #5
vlad.dancer@TuWebO, thank you for the shared solution!
Comment #6
sivamallareddy commented@TuWebO Thanks for the solution!! For me also it is working fine.