Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.74% covered (success)
94.74%
36 / 38
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
HideFacetValueListener
94.74% covered (success)
94.74%
36 / 38
50.00% covered (danger)
50.00%
2 / 4
16.04
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 attach
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 onSearchPost
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
4.05
 processHideFacetValue
95.65% covered (success)
95.65%
22 / 23
0.00% covered (danger)
0.00%
0 / 1
10
1<?php
2
3/**
4 * Hide values of facet for displaying
5 *
6 * PHP version 8
7 *
8 * Copyright (C) The National Library of Finland 2014.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2,
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 *
23 * @category VuFind
24 * @package  Search
25 * @author   Frank Morgner <morgnerf@ub.uni-leipzig.de>
26 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
27 * @link     https://vufind.org Main Site
28 */
29
30namespace VuFind\Search\Base;
31
32use Laminas\EventManager\EventInterface;
33use Laminas\EventManager\SharedEventManagerInterface;
34use VuFindSearch\Backend\BackendInterface;
35use VuFindSearch\Service;
36
37use function is_callable;
38
39/**
40 * Hide single facet values from displaying.
41 *
42 * @category VuFind
43 * @package  Search
44 * @author   Frank Morgner <morgnerf@ub.uni-leipzig.de>
45 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
46 * @link     https://vufind.org Main Site
47 */
48class HideFacetValueListener
49{
50    /**
51     * Backend.
52     *
53     * @var BackendInterface
54     */
55    protected $backend;
56
57    /**
58     * List of facet values to show, indexed by facet field. All other facets are
59     * hidden.
60     *
61     * @var array
62     */
63    protected $showFacets = [];
64
65    /**
66     * List of facet values to hide, indexed by facet field.
67     *
68     * @var array
69     */
70    protected $hideFacets = [];
71
72    /**
73     * Constructor.
74     *
75     * @param BackendInterface $backend         Search backend
76     * @param array            $hideFacetValues Assoc. array of field
77     * name => values to exclude from display.
78     * @param array            $showFacetValues Assoc. array of field
79     * name => values to exclusively show in display.
80     */
81    public function __construct(
82        BackendInterface $backend,
83        array $hideFacetValues,
84        array $showFacetValues = []
85    ) {
86        $this->backend = $backend;
87        $this->hideFacets = $hideFacetValues;
88        $this->showFacets = $showFacetValues;
89    }
90
91    /**
92     * Attach listener to shared event manager.
93     *
94     * @param SharedEventManagerInterface $manager Shared event manager
95     *
96     * @return void
97     */
98    public function attach(
99        SharedEventManagerInterface $manager
100    ) {
101        $manager->attach(
102            Service::class,
103            Service::EVENT_POST,
104            [$this, 'onSearchPost']
105        );
106    }
107
108    /**
109     * Hide facet values from display
110     *
111     * @param EventInterface $event Event
112     *
113     * @return EventInterface
114     */
115    public function onSearchPost(EventInterface $event)
116    {
117        $command = $event->getParam('command');
118
119        if ($command->getTargetIdentifier() !== $this->backend->getIdentifier()) {
120            return $event;
121        }
122        $context = $command->getContext();
123        if ($context == 'search' || $context == 'retrieve') {
124            $this->processHideFacetValue($event);
125        }
126        return $event;
127    }
128
129    /**
130     * Process hide facet value
131     *
132     * @param EventInterface $event Event
133     *
134     * @return void
135     */
136    protected function processHideFacetValue($event)
137    {
138        $result = $event->getParam('command')->getResult();
139        if (!$result) {
140            return;
141        }
142        $facets = $result->getFacets();
143
144        // Count how many values have been filtered as we go:
145        $filteredFacetCounts = [];
146
147        foreach ($this->hideFacets as $facet => $values) {
148            foreach ((array)$values as $value) {
149                if (isset($facets[$facet][$value])) {
150                    unset($facets[$facet][$value]);
151                    $filteredFacetCounts[$facet] = ($filteredFacetCounts[$facet] ?? 0) + 1;
152                }
153            }
154        }
155        foreach ($this->showFacets as $facet => $values) {
156            if (isset($facets[$facet])) {
157                $valuesToHide = array_diff(
158                    array_keys($facets[$facet]),
159                    (array)$values
160                );
161                foreach ($valuesToHide as $valueToHide) {
162                    if (isset($facets[$facet][$valueToHide])) {
163                        unset($facets[$facet][$valueToHide]);
164                        $filteredFacetCounts[$facet] = ($filteredFacetCounts[$facet] ?? 0) + 1;
165                    }
166                }
167            }
168        }
169
170        // If the result object is capable of receiving filter counts, send the data:
171        if (is_callable([$result, 'setFilteredFacetCounts'])) {
172            $result->setFilteredFacetCounts($filteredFacetCounts);
173        }
174
175        $result->setFacets($facets);
176    }
177}