- ๐จ๐ฆCanada Shiraz Dindar Sooke, BC
For me,
#7 sets the default facet value in the facet field, but the results are not actually filtered accordingly.
#2 works for me. However, since then a new argument ($urlGenerator) was added to the url_processor constructor (the one we are extending), so I had to add it here as well, as follows:
<?php namespace Drupal\my_module\Plugin\facets\url_processor; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\facets\Plugin\facets\url_processor\QueryString; use Drupal\facets\Utility\FacetsUrlGenerator; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; /** * Query string URL processor. * * @FacetsUrlProcessor( * id = "my_query_string", * label = @Translation("My Query string"), * description = @Translation("Add description") * ) */ class MyQueryString extends QueryString { /** * A string of how to represent the facet in the url. * * @var string */ protected $urlAlias; /** * The event dispatcher. * * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface */ protected $eventDispatcher; /** * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request, EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $eventDispatcher, FacetsUrlGenerator $urlGenerator) { $this->alterRequest($request); parent::__construct($configuration, $plugin_id, $plugin_definition, $request, $entity_type_manager, $eventDispatcher, $urlGenerator); } /** * @param \Symfony\Component\HttpFoundation\Request $request */ private function alterRequest(Request $request): void { $query = $request->query; $facet_new_parameters = []; if ($facet_parameters = $query->get('f')) { $article_type_filter_exists = FALSE; foreach ($facet_parameters as $parameter) { $sepator = ':'; $explosion = explode($sepator, $parameter); $facet_type = array_shift($explosion); if ($facet_type === 'article_type') { $article_type_filter_exists = TRUE; } } if (!$article_type_filter_exists) { $facet_new_parameters = array_merge($facet_parameters, ['article_type:10372']); } } else { $facet_new_parameters = ['article_type:10372']; } if (!empty($facet_new_parameters)) { $query->set('f', $facet_new_parameters); } } }
That said, I agree with #9 -- this should be something that we can set in the facet config.
Thanks all!
- ๐ท๐ดRomania reszli Tรขrgu Mureศ
$query->get('f') will not work anymore since it's not a scalar value but an array
I used $query->all()['f'] ?? [] insteadproblem with this approach is that you can't even intentionally reset the filter to "any" since then the value is not in the URL and it will force the default
- ๐ฌ๐ทGreece vensires
Based on the previous comments of this thread, I was able to build the following URL processor.
In my case, I wanted that the values from user fields became the default values for facets when entering the page. In some other views though, the default query_string plugin is what I needed. Read the inline comments if you intend to use it. Might require some refactoring for your case.
namespace Drupal\mymodule\Plugin\facets\url_processor; use Drupal\Core\Cache\UnchangingCacheableDependencyTrait; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\facets\Plugin\facets\url_processor\QueryString; use Drupal\facets\Utility\FacetsUrlGenerator; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; /** * Query string URL processor. * * @FacetsUrlProcessor( * id = "mymodule_query_string", * label = @Translation("My module query string"), * description = @Translation("Extends the original query string with predefined values") * ) */ class MymoduleQueryString extends QueryString { use UnchangingCacheableDependencyTrait; /** * {@inheritdoc} * * Since we are operating on the construct function and this gets called for * every facet on every page, we have to tamper the query object and then * restore it; otherwise facets without default values don't seem to work. */ public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request, EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $eventDispatcher, FacetsUrlGenerator $urlGenerator) { // Keep a clone of the original query to restore it later. $query = clone $request->query; /** @var \Drupal\facets\Entity\Facet $facet */ $facet = $configuration['facet']; if ($facet->getFacetSourceConfig()->getUrlProcessorName() === $plugin_id) { $this->alterRequest($request); } parent::__construct($configuration, $plugin_id, $plugin_definition, $request, $entity_type_manager, $eventDispatcher, $urlGenerator); if ($facet->getFacetSourceConfig()->getUrlProcessorName() === $plugin_id) { // Restore the original query. $request->query = $query; } } /** * Alter the request object used by facets. * * When this function gets called, the default constructor has not yet been * called; thus we have to take all the variables we need as arguments instead * of relying on $this. * * @param \Symfony\Component\HttpFoundation\Request $request * The current request object. */ protected function alterRequest(Request $request) { // For this static variable to have any performance improvements, you must // have big_pipe module turned off. Otherwise, you would require another way // of caching due to different requests; maybe using a computed field on the // user entity is a possible solution. static $facet_parameters = []; /** @var \Drupal\user\UserInterface $account */ $account = \Drupal::entityTypeManager()->getStorage('user')->load(\Drupal::currentUser()->id()); $query = &$request->query; // Allow "?disable_defaults=1" for a "Clear defaults" button to be able to // work at this point. if ($query->getInt('disable_defaults', 0)) { return; } if (empty($facet_parameters)) { $original_query_parameters = $query->all()['f'] ?? []; if (empty($original_query_parameters)) { $facet_parameters = []; // Get user fields... if ($account->hasField('field_name_1') && !$account->get('field_name_1')->isEmpty()) { foreach ($account->get('field_name_1')->getValue() as $values) { $facet_parameters[] = 'facet_alias1:' . $values['target_id']; } } if ($account->hasField('field_name_2') && !$account->get('field_name_2')->isEmpty()) { foreach ($account->get('field_name_2')->getValue() as $values) { $facet_parameters[] = 'facet_alias2:' . $values['target_id']; } } } } if (!empty($facet_parameters)) { $query->set('f', $facet_parameters); } } }
- ๐ง๐ชBelgium ludo.r Brussels
It seems, my custom URL processor is being called event when the facet source is set to use the default one.
Anyone encountered this issue?