Update VuFind® to 9.1, changes in the search subsystem
At the State and University Library we are currently in the process of updating our discovery systems from VuFind 8
to VuFind 9. One area that has changed from 8 to 9 is the VuFindSearch
module, namely how an
event-based listener interacts with it.
Today I updated the PruneSolrfieldfacetlistener
, a listener that prunes (removes) field facet values
from a facetted search response. We use this listener in our Katalogplus as well in our KatalogHamburg to facet over locations (field collection_details in the
K10Plus Zentral search index) and display only
locations relevant to the user. We do this by removing all facet values that do not match predefined criteria.
This listener stops working with VuFind 9 for the following reasons:
-
Commit #f269dd121 changed the
VuFindSearch
service such that the search command is no longer the target of the event, but an event parameter. -
Commit #8dc8ec42e6 standardize
the representation of a Solr response such that a call to the
getFacets()
method returns an associative with an entry for each facet. In VuFind 8 the call returned aFacets
object with agetFieldFacets()
method.
Addressing theses changes was no rocket science, the PruneSolrfieldfacetlistener
is working again.
namespace SUBHH\VuFind\Shared;
-use VuFindSearch\Backend\Solr\Response\Json\RecordCollection;
-use VuFindSearch\Backend\Solr\Response\Json\Facets; // @phan-suppress-current-line PhanUnreferencedUseNormal
use VuFindSearch\Service;
+use VuFindSearch\ParamBag;
+use VuFindSearch\Command\CommandInterface;
+use VuFindSearch\Backend\Solr\Response\Json\RecordCollection;
use Laminas\EventManager\EventInterface;
use Laminas\EventManager\SharedEventManagerInterface;
@@ -51,28 +52,24 @@ final class PruneSolrFieldFacetListener
$events->attach('VuFindSearch', Service::EVENT_POST, [$this, 'onSearchPost']);
}
+ /** @param EventInterface<Service, ParamBag> $event */
public function onSearchPost (EventInterface $event) : void
{
- $response = $event->getTarget();
- if ($response instanceof RecordCollection) {
-
- /** @var Facets */
- $facets = $response->getFacets();
- $fieldfacets = $facets->getFieldFacets(); // @phan-suppress-current-line PhanNonClassMethodCall
- if (isset($fieldfacets[$this->field])) {
- $facet = $fieldfacets[$this->field];
- $facet->rewind();
-
- $remove = array();
- while ($facet->valid())
namespace SUBHH\VuFind\Shared;
-use VuFindSearch\Backend\Solr\Response\Json\RecordCollection;
-use VuFindSearch\Backend\Solr\Response\Json\Facets; // @phan-suppress-current-line PhanUnreferencedUseNormal
use VuFindSearch\Service;
+use VuFindSearch\ParamBag;
+use VuFindSearch\Command\CommandInterface;
+use VuFindSearch\Backend\Solr\Response\Json\RecordCollection;
use Laminas\EventManager\EventInterface;
use Laminas\EventManager\SharedEventManagerInterface;
@@ -51,27 +52,23 @@ final class PruneSolrFieldFacetListener
$events->attach('VuFindSearch', Service::EVENT_POST, [$this, 'onSearchPost']);
}
+ /** @param EventInterface<Service, ParamBag> $event */
public function onSearchPost (EventInterface $event) : void
{
- $response = $event->getTarget();
- if ($response instanceof RecordCollection) {
-
- /** @var Facets */
- $facets = $response->getFacets();
- $fieldfacets = $facets->getFieldFacets(); // @phan-suppress-current-line PhanNonClassMethodCall
- if (isset($fieldfacets[$this->field])) {
- $facet = $fieldfacets[$this->field];
- $facet->rewind();
-
- $remove = array();
- while ($facet->valid()) {
- $value = $facet->key();
- if ($this->filter->accept($value) === false) {
- $remove[] = $value;
- }
- $facet->next();
+ $command = $event->getParam('command');
+ if ($command instanceof CommandInterface) {
+ $response = $command->getResult();
+ if ($response instanceof RecordCollection) {
+ $facets = $response->getFacets();
+ if (array_key_exists($this->field, $facets)) {
+ $facets[$this->field] = array_filter($facets[$this->field], array($this, 'filter'), ARRAY_FILTER_USE_KEY);
}
- $facet->removeKeys($remove);
+ $response->setFacets($facets);
}
}
}
+
+ private function filter (mixed $key) : bool
+ {
+ return $this->filter->accept($key);
+ }
}