From 2ef21cd3cff909048c4e4b9e655582ea1d71694b Mon Sep 17 00:00:00 2001
From: Frank Morgner <morgnerf@ub.uni-leipzig.de>
Date: Thu, 18 Jun 2015 15:36:52 -0400
Subject: [PATCH] New listener to hide specific facet values from display

---
 config/vufind/facets.ini                      |   5 +
 .../Factory/AbstractSolrBackendFactory.php    |  31 ++++
 .../Search/Solr/HideFacetValueListener.php    | 132 ++++++++++++++++++
 .../Backend/Solr/Response/Json/NamedList.php  |  10 ++
 4 files changed, 178 insertions(+)
 create mode 100644 module/VuFind/src/VuFind/Search/Solr/HideFacetValueListener.php

diff --git a/config/vufind/facets.ini b/config/vufind/facets.ini
index 42e38222625..1e6faae1822 100644
--- a/config/vufind/facets.ini
+++ b/config/vufind/facets.ini
@@ -170,3 +170,8 @@ visual_facets = "callnumber-first,topic_facet"
 ; If you rename a facet field, you can map the old value to a new value in this
 ; section to ensure that legacy URLs continue to function.
 [LegacyFields]
+
+; Prevent specific facet values from being displayed to the user.
+; Use facet field names as keys and untranslated facet values as values.
+[HideFacetValue]
+;format[] = "Book"
diff --git a/module/VuFind/src/VuFind/Search/Factory/AbstractSolrBackendFactory.php b/module/VuFind/src/VuFind/Search/Factory/AbstractSolrBackendFactory.php
index 99d0379b341..8ef71f225c7 100644
--- a/module/VuFind/src/VuFind/Search/Factory/AbstractSolrBackendFactory.php
+++ b/module/VuFind/src/VuFind/Search/Factory/AbstractSolrBackendFactory.php
@@ -29,6 +29,7 @@
 namespace VuFind\Search\Factory;
 
 use VuFind\Search\Solr\FilterFieldConversionListener;
+use VuFind\Search\Solr\HideFacetValueListener;
 use VuFind\Search\Solr\InjectHighlightingListener;
 use VuFind\Search\Solr\InjectConditionalFilterListener;
 use VuFind\Search\Solr\InjectSpellingListener;
@@ -175,6 +176,7 @@ abstract class AbstractSolrBackendFactory implements FactoryInterface
         // Load configurations:
         $config = $this->config->get('config');
         $search = $this->config->get($this->searchConfig);
+        $facet = $this->config->get($this->facetConfig);
 
         // Highlighting
         $this->getInjectHighlightingListener($backend, $search)->attach($events);
@@ -231,6 +233,11 @@ abstract class AbstractSolrBackendFactory implements FactoryInterface
             $filterFieldConversionListener->attach($events);
         }
 
+        // Attach hide facet value listener:
+        if ($hfvListener = $this->getHideFacetValueListener($backend, $facet)) {
+            $hfvListener->attach($events);
+        }
+
         // Attach error listeners for Solr 3.x and Solr 4.x (for backward
         // compatibility with VuFind 1.x instances).
         $legacyErrorListener = new LegacyErrorListener($backend);
@@ -385,6 +392,30 @@ abstract class AbstractSolrBackendFactory implements FactoryInterface
         );
     }
 
+    /**
+    * Get a hide facet value listener for the backend
+    *
+    * @param BackendInterface $backend Search backend
+    * @param Config           $facet   Configuration of facets
+    *
+    * @return mixed null|HideFacetValueListener
+    */
+    protected function getHideFacetValueListener(
+        BackendInterface $backend,
+        Config $facet
+    ) {
+        if (!isset($facet->HideFacetValue)
+            || ($facet->HideFacetValue->count()) == 0
+        ) {
+            return null;
+        }
+        return new HideFacetValueListener(
+            $backend,
+            $facet->HideFacetValue->toArray()
+        );
+    }
+
+
     /**
      * Get a hierarchical facet listener for the backend
      *
diff --git a/module/VuFind/src/VuFind/Search/Solr/HideFacetValueListener.php b/module/VuFind/src/VuFind/Search/Solr/HideFacetValueListener.php
new file mode 100644
index 00000000000..9c7672839af
--- /dev/null
+++ b/module/VuFind/src/VuFind/Search/Solr/HideFacetValueListener.php
@@ -0,0 +1,132 @@
+<?php
+/**
+ * Hide values of facet for displaying
+ *
+ * PHP version 5
+ *
+ * Copyright (C) The National Library of Finland 2014.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @category VuFind2
+ * @package  Search
+ * @author   Frank Morgner <morgnerf@ub.uni-leipzig.de>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org   Main Site
+ */
+namespace VuFind\Search\Solr;
+
+use VuFindSearch\Backend\BackendInterface;
+use Zend\EventManager\SharedEventManagerInterface;
+use Zend\EventManager\EventInterface;
+
+/**
+ * Hide single facet values from displaying.
+ *
+ * @category VuFind2
+ * @package  Search
+ * @author   Frank Morgner <morgnerf@ub.uni-leipzig.de>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org   Main Site
+ */
+class HideFacetValueListener
+{
+    /**
+     * Backend.
+     *
+     * @var BackendInterface
+     */
+    protected $backend;
+
+    /**
+     * List of facets to hide.
+     *
+     * @var array
+     */
+    protected $hideFacets = [];
+
+    /**
+     * Constructor.
+     *
+     * @param BackendInterface $backend         Search backend
+     * @param array            $hideFacetValues Facet config file id
+     */
+    public function __construct(
+        BackendInterface $backend,
+        array $hideFacetValues
+    ) {
+        $this->backend = $backend;
+        $this->hideFacets = $hideFacetValues;
+    }
+
+    /**
+     * Attach listener to shared event manager.
+     *
+     * @param SharedEventManagerInterface $manager Shared event manager
+     *
+     * @return void
+     */
+    public function attach(
+        SharedEventManagerInterface $manager
+    ) {
+        $manager->attach('VuFind\Search', 'post', [$this, 'onSearchPost']);
+    }
+
+    /**
+     * Hide facet values from display
+     *
+     * @param EventInterface $event Event
+     *
+     * @return EventInterface
+     */
+    public function onSearchPost(EventInterface $event)
+    {
+        $backend = $event->getParam('backend');
+
+        if ($backend != $this->backend->getIdentifier()) {
+            return $event;
+        }
+        $context = $event->getParam('context');
+        if ($context == 'search' || $context == 'retrieve') {
+            $this->processHideFacetValue($event);
+        }
+        return $event;
+    }
+
+    /**
+     * Process hide facet value
+     *
+     * @param EventInterface $event Event
+     *
+     * @return void
+     */
+    protected function processHideFacetValue($event)
+    {
+        $result = $event->getTarget();
+        $facets = $result->getFacets()->getFieldFacets();
+
+        foreach ($this->hideFacets as $facet => $value) {
+            if (isset($facets[$facet])) {
+                foreach ((array)$value as $config_value) {
+                    foreach ($facets[$facet] as $facet_value => $count) {
+                        if ($facet_value == $config_value) {
+                            $facets[$facet]->remove();
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Response/Json/NamedList.php b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Response/Json/NamedList.php
index 4b7b966a8b7..2e231544630 100644
--- a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Response/Json/NamedList.php
+++ b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Response/Json/NamedList.php
@@ -149,4 +149,14 @@ class NamedList implements Countable, Iterator
         reset($this->list);
         $this->current = current($this->list);
     }
+
+    /**
+     * Remove element from list.
+     *
+     * @return void
+     */
+    public function remove()
+    {
+        unset($this->list[key($this->list)]);
+    }
 }
\ No newline at end of file
-- 
GitLab