From 1b51004e850bdf78ab29edfa6a1826f998241012 Mon Sep 17 00:00:00 2001
From: Frank Morgner <morgnerf@ub.uni-leipzig.de>
Date: Fri, 30 Sep 2016 09:13:50 +0200
Subject: [PATCH] refs #7624 implementation of AllowFacetValue in
 SideFacets.phtml in  finc View/Helper * enable only a whitelist of facet
 value to display * realized in View/Helper/Root for all instances *
 configuration facets.ini

---
 local/config/vufind/facets.ini                |   6 +
 .../src/finc/View/Helper/Root/Factory.php     |  15 +
 .../src/finc/View/Helper/Root/SideFacet.php   |  88 ++++
 .../finc/templates/Recommend/SideFacets.phtml | 486 +++++++++---------
 themes/finc/theme.config.php                  |   1 +
 5 files changed, 353 insertions(+), 243 deletions(-)
 create mode 100644 module/finc/src/finc/View/Helper/Root/SideFacet.php

diff --git a/local/config/vufind/facets.ini b/local/config/vufind/facets.ini
index d0822f9352c..bf59961a2fb 100644
--- a/local/config/vufind/facets.ini
+++ b/local/config/vufind/facets.ini
@@ -220,6 +220,12 @@ facet_limit      = 20
 [HideFacetValue]
 ;format[] = "Book"
 
+; Allow only a defined set of facets to be displayed to the user as a kind of
+; whitelist.
+; Use facet field names as keys and untranslated facet values as values.
+[AllowFacetValue]
+;format[] = "Book"
+
 ; Added for finc project
 ; Array of stricter facets hiding to diminsh displaying
 ; facet contents by starting searching.
diff --git a/module/finc/src/finc/View/Helper/Root/Factory.php b/module/finc/src/finc/View/Helper/Root/Factory.php
index 900f998198b..e01d306fb5e 100644
--- a/module/finc/src/finc/View/Helper/Root/Factory.php
+++ b/module/finc/src/finc/View/Helper/Root/Factory.php
@@ -132,4 +132,19 @@ class Factory
             isset($config->General) ? $config : null
         );
     }
+
+    /**
+     * Construct the SideFacet helper.
+     *
+     * @param ServiceManager $sm Service manager.
+     *
+     * @return SideFacet
+     */
+    public static function getSideFacet(ServiceManager $sm)
+    {
+        return new SideFacet(
+            $sm->getServiceLocator()->get('VuFind\Config')->get('facets')
+        );
+    }
+
 }
diff --git a/module/finc/src/finc/View/Helper/Root/SideFacet.php b/module/finc/src/finc/View/Helper/Root/SideFacet.php
new file mode 100644
index 00000000000..058a10c0cca
--- /dev/null
+++ b/module/finc/src/finc/View/Helper/Root/SideFacet.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Side facet view helper
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Villanova University 2010.
+ * Copyright (C) Leipzig University Library 2016.
+ *
+ * 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 VuFind
+ * @package  View_Helpers
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @author   Frank Morgner <morgnerf@ub.uni-leipzig.de>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+namespace finc\View\Helper\Root;
+
+/**
+ * Permissions view helper
+ *
+ * @category VuFind
+ * @package  View_Helpers
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @author   Frank Morgner <morgnerf@ub.uni-leipzig.de>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+class SideFacet extends \Zend\View\Helper\AbstractHelper
+{
+    /**
+     * VuFind configuration
+     *
+     * @var \Zend\Config\Config
+     */
+    protected $config;
+
+    /**
+     * Constructor
+     *
+     * @param \Zend\Config\Config $config VuFind configuration
+     * @access public
+     */
+    public function __construct($config = null)
+    {
+        $this->config = $config;
+    }
+
+    /**
+     * Checks whether the user is logged in.
+     *
+     * @param array $sideFacets List of side facets
+     *
+     * @return array            Filtered side facets
+     * @access public
+     */
+    public function displayAllowedFacetValues($sideFacets)
+    {
+        if (!isset($this->config->AllowFacetValue) ||
+            count($this->config->AllowFacetValue) == 0
+        ) {
+            return $sideFacets;
+        }
+        foreach ($this->config->AllowFacetValue as $label => $values) {
+            if (isset($sideFacets[$label])) {
+                foreach ($sideFacets[$label]['list'] as $key => &$item) {
+                    if (!in_array($item['value'], $values->toArray())) {
+                        unset($sideFacets[$label]['list'][$key]);
+                    }
+                }
+            }
+        }
+        return $sideFacets;
+    }
+}
diff --git a/themes/finc/templates/Recommend/SideFacets.phtml b/themes/finc/templates/Recommend/SideFacets.phtml
index fc2e1406a2c..33a58dd6a74 100644
--- a/themes/finc/templates/Recommend/SideFacets.phtml
+++ b/themes/finc/templates/Recommend/SideFacets.phtml
@@ -1,244 +1,244 @@
-<!-- recommend - SIDEFACETS.phtml -->
-<? $results = $this->recommend->getResults(); ?>
-<? if ($results->getResultTotal() > 0): ?>
-  <h4><?= $this->transEsc(isset($this->overrideSideFacetCaption) ? $this->overrideSideFacetCaption : 'Narrow Search') ?></h4>
-<? endif; ?>
-<? $checkboxFilters = $results->getParams()->getCheckboxFacets();
-if (count($checkboxFilters) > 0): ?>
-  <?
-  $html = '';
-  $shown = 0;
-  foreach ($checkboxFilters as $current) {
-    $html .= '<label class="checkbox';
-    if ($results->getResultTotal() < 1 && !$current['selected'] && !$current['alwaysVisible']) {
-      $html .= ' hide';
-    } else {
-      $shown++;
-    }
-    $html .= '"><input type="checkbox" name="filter[]" value="' . $this->escapeHtmlAttr($current['filter']) . '"
-      ' . ($current['selected'] ? 'checked="checked"' : '') . ' id="' . $this->escapeHtmlAttr(str_replace(' ', '', $current['desc'])) . '"
-      onclick="document.location.href=\'' . ($current['selected'] ? $results->getUrlQuery()->removeFilter($current['filter']) : $results->getUrlQuery()->addFilter($current['filter'])) . '\';" />' . $this->transEsc($current['desc']) . '</label>';
-  }
-  ?>
-  <div class="checkboxFilter<? if ($shown == 0): ?> hide<? endif; ?>"><?= $html ?></div>
-<? endif; ?>
-<? $extraFilters = isset($this->extraSideFacetFilters) ? $this->extraSideFacetFilters : array(); ?>
-<? $collapsedFacets = $this->recommend->getCollapsedFacets() ?>
-<? $hierarchicalFacetSortOptions = $this->recommend->getHierarchicalFacetSortOptions() ?>
-<? $hierarchicalFacets = $this->recommend->getHierarchicalFacets() ?>
-<? $filterList = array_merge($results->getParams()->getFilterList(true), $extraFilters);
-if (!empty($filterList)): ?>
-  <div class="filters">
-    <div class="title"><?= $this->transEsc('Remove Filters') ?></div>
-    <ul class="side-nav" role="navigation">
-      <? foreach ($filterList as $field => $filters): ?>
-        <? foreach ($filters as $i => $filter): ?>
-          <?
-          $index = isset($filter['field']) ? array_search($filter['field'], $collapsedFacets) : false;
-          if ($index !== false) {
-            unset($collapsedFacets[$index]); // Open if we have a match
-          }
-          if (isset($filter['specialType']) && $filter['specialType'] == 'keyword') {
-            $removeLink = $this->currentPath() . $results->getUrlQuery()->replaceTerm($filter['value'], '');
-          } else {
-            $removeLink = $this->currentPath() . $results->getUrlQuery()->removeFacet($filter['field'], $filter['value'], true, $filter['operator']);
-          }
-          if ($filter['displayText'] == '[* TO *]') {
-            $filter['displayText'] = $this->translate('filter_wildcard');
-          }
-          ?>
-          <li>
-            <a class="active" href="<?= $removeLink ?>">
-              <span class="pull-right"><i class="fa fa-times"></i></span>
-              <? if ($filter['operator'] == 'NOT') echo $this->transEsc('NOT') . ' ';
-              if ($filter['operator'] == 'OR' && $i > 0) echo $this->transEsc('OR') . ' '; ?><?= $this->transEsc($field) ?>: <?= $this->escapeHtml($filter['displayText']) ?>
-            </a>
-          </li>
-        <? endforeach; ?>
-      <? endforeach; ?>
-    </ul>
-  </div>
-<? endif; ?>
-<?= isset($this->sideFacetExtraControls) ? $this->sideFacetExtraControls : '' ?>
-<? $sideFacetSet = $this->recommend->getFacetSet();
-$rangeFacets = $this->recommend->getAllRangeFacets(); ?>
-<? if (!empty($sideFacetSet) && $results->getResultTotal() > 0): ?>
-  <? foreach ($sideFacetSet as $title => $cluster): ?>
-    <? $allowExclude = $this->recommend->excludeAllowed($title); ?>
-    <? $facets_before_more = $this->recommend->getShowMoreSetting($title); ?>
-    <ul class="accordion" id="side-panel-<?= $this->escapeHtmlAttr($title) ?>" data-accordion>
-      <li class="accordion-navigation <? if (!in_array($title, $collapsedFacets)): ?> active<? endif ?>">
-        <a href="#side-collapse-<?= $this->escapeHtmlAttr($title) ?>" class="title"><?= $this->transEsc($cluster['label']) ?></a>
-        <div id="side-collapse-<?= $this->escapeHtmlAttr($title) ?>" class="content <? if (!in_array($title, $collapsedFacets)): ?>active<? endif ?>">
-          <? if (isset($rangeFacets[$title])): ?>
-          <ul class="date-range-slider">
-            <li>
-              <form name="<?= $this->escapeHtmlAttr($title) ?>Filter" id="<?= $this->escapeHtmlAttr($title) ?>Filter">
-                <?= $results->getUrlQuery()->asHiddenFields(array('page' => "/./", 'filter' => "/^{$title}:.*/")) ?>
-                <input type="hidden" name="<?= $this->escapeHtmlAttr($rangeFacets[$title]['type']) ?>range[]" value="<?= $this->escapeHtmlAttr($title) ?>"/>
-                <div class="row">
-                  <? $extraInputAttribs = ($rangeFacets[$title]['type'] == 'date') ? 'maxlength="4" ' : ''; ?>
-                  <div class="medium-6 columns">
-                    <label for="<?= $this->escapeHtmlAttr($title) ?>from">
-                      <?= $this->transEsc('date_from') ?>:
-                    </label>
-                    <input type="text" name="<?= $this->escapeHtmlAttr($title) ?>from" id="<?= $this->escapeHtmlAttr($title) ?>from"
-                           value="<?= isset($rangeFacets[$title]['values'][0]) ? $this->escapeHtmlAttr($rangeFacets[$title]['values'][0]) : '' ?>" <?= $extraInputAttribs ?>/>
-                  </div>
-                  <div class="medium-6 columns">
-                    <label for="<?= $this->escapeHtmlAttr($title) ?>to">
-                      <?= $this->transEsc('date_to') ?>:
-                    </label>
-                    <input type="text" name="<?= $this->escapeHtmlAttr($title) ?>to" id="<?= $this->escapeHtmlAttr($title) ?>to"
-                           value="<?= isset($rangeFacets[$title]['values'][1]) ? $this->escapeHtmlAttr($rangeFacets[$title]['values'][1]) : '' ?>" <?= $extraInputAttribs ?>/>
-                  </div>
-                </div>
-                <? if ($rangeFacets[$title]['type'] == 'date'): ?>
-                  <div class="slider-container"><input type="text" class="hide" id="<?= $this->escapeHtmlAttr($title) ?><?= $this->escapeHtml($rangeFacets[$title]['type']) ?>Slider"/></div>
-                <? endif; ?>
-                <input class="button tiny" type="submit" value="<?= $this->transEsc('Set') ?>"/>
-              </form>
-              <? /* NO closing UL and LI here! - is closed below */ ?>
-              <? /* ADAPT RANGE SLIDER JS HERE AND REMOVE BootstrapSlider JS and CSS when FNDTN6 is out - FIXME CK */ ?>
-              <? if ($rangeFacets[$title]['type'] == 'date'): ?>
-                <? $this->headScript()->appendFile('vendor/bootstrap-slider.js'); ?>
-                <? $this->headLink()->appendStylesheet('vendor/bootstrap-slider.css'); ?>
-                <?
-                $min = !empty($rangeFacets[$title]['values'][0]) ? min($rangeFacets[$title]['values'][0], 1400) : 1400;
-                $future = date('Y', time() + 31536000);
-                $max = !empty($rangeFacets[$title]['values'][1]) ? max($future, $rangeFacets[$title]['values'][1]) : $future;
-                $low = !empty($rangeFacets[$title]['values'][0]) ? $rangeFacets[$title]['values'][0] : $min;
-                $high = !empty($rangeFacets[$title]['values'][1]) ? $rangeFacets[$title]['values'][1] : $max;
-                $reversed = $this->layout()->rtl ? 'true' : 'false';
-                $script = <<<JS
-$(document).ready(function() {
-  var fillTexts = function() {
-  var v = {$this->escapeHtmlAttr($title)}dateSlider.getValue();
-  $('#{$this->escapeHtmlAttr($title)}from').val(v[0]);
-  $('#{$this->escapeHtmlAttr($title)}to').val(v[1]);
-  };
-  var {$this->escapeHtmlAttr($title)}dateSlider = $('#{$this->escapeHtmlAttr($title)}dateSlider')
-  .slider({
-     'min':{$min},
-     'max':{$max},
-     'handle':"square",
-     'tooltip':"hide",
-    'value':[{$low},{$high}],
-    'reversed': {$reversed}
-  })
-  .on('slide', fillTexts)
-  .data('slider');
-});
-
-$('#{$this->escapeHtmlAttr($title)}from, #{$this->escapeHtmlAttr($title)}to').change(function () {
-  var from = Number($('#{$this->escapeHtmlAttr($title)}from').val());
-  var to   = Number($('#{$this->escapeHtmlAttr($title)}to').val());
-  if (from <= 0) {
-    from = {$min};
-  }
-  if (to <= 0) {
-    to = {$max};
-  }
-  $('#{$this->escapeHtmlAttr($title)}dateSlider').slider('setValue', [from, to], true);
-});
-JS;
-                ?>
-                <?= $this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $script, 'SET'); ?>
-              <? endif; ?>
-              <? else: ?>
-              <? if (in_array($title, $hierarchicalFacets)): ?>
-              <? $this->headScript()->appendFile('vendor/jsTree/jstree.min.js'); ?>
-              <? $this->headScript()->appendFile('facets.js'); ?>
-              <? $sort = isset($hierarchicalFacetSortOptions[$title]) ? $hierarchicalFacetSortOptions[$title] : ''; ?>
-              <? if (!in_array($title, $collapsedFacets)): ?>
-                <?
-                $script = <<<JS
-$(document).ready(function() {
-  initFacetTree($('#facet_{$this->escapeHtml($title)}'), true);
-});
-<? /* Verify necessity of the following JS - fixme CK */ ?>
-JS;
-                ?>
-                <?= $this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $script, 'SET'); ?>
-              <? else: ?>
-                <?
-                $script = <<<JS
-$('#side-collapse-{$this->escapeHtmlAttr($title)}').on('show.fndtn.accordion', function() {
-  initFacetTree($('#facet_{$this->escapeHtml($title)}'), true);
-});
-JS;
-                ?>
-                <?= $this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $script, 'SET'); ?>
-              <? endif; ?>
-            <li id="facet_<?= $this->escapeHtml($title) ?>" class="jstree-facet"
-                data-facet="<?= $this->escapeHtmlAttr($title) ?>"
-                data-path="<?= $this->currentPath() ?>"
-                data-exclude="<?= $allowExclude ?>"
-                data-operator="<?= $this->recommend->getFacetOperator($title) ?>"
-                data-exclude-title="<?= $this->transEsc('exclude_facet') ?>"
-                data-sort="<?= isset($hierarchicalFacetSortOptions[$title]) ? $hierarchicalFacetSortOptions[$title] : '' ?>">
-            </li>
-            <noscript>
-              <? endif; ?>
-              <ul class="side-nav" role="navigation">
-                <? foreach ($cluster['list'] as $i => $thisFacet): ?>
-                  <?
-                  if (strlen($thisFacet['displayText']) == 0) {
-                    $thisFacet['displayText'] = "-";
-                  }
-                  ?>
-                  <? $moreClass = 'narrowGroupHidden-' . $this->escapeHtmlAttr($title) . ' hide'; ?>
-                  <? if ($i == $facets_before_more): ?>
-                    <li id="more-narrowGroupHidden-<?= $this->escapeHtmlAttr($title) ?>">
-                      <a href="javascript:moreFacets('narrowGroupHidden-<?=$this->escapeHtmlAttr($title) ?>')"><?= $this->transEsc('more') ?>&nbsp;...</a>
-                    </li>
-                  <? endif; ?>
-                  <? if ($thisFacet['isApplied']): ?>
-                    <li class="<? if ($i >= $facets_before_more): ?> <?= $moreClass ?> <? endif ?>">
-                      <a class="active <? if ($thisFacet['operator'] == 'OR'): ?> facetOR applied<? endif ?>" href="<?= $this->currentPath() . $results->getUrlQuery()->removeFacet($title, $thisFacet['value'], true, $thisFacet['operator']) ?>" >
-                        <? if ($thisFacet['operator'] == 'OR'): ?>
-                          <i class="fa fa-check-square-o"></i>
-                        <? else: ?>
-                          <span class="pull-right"><i class="fa fa-check"></i></span>
-                        <? endif; ?>
-                        <?= $this->escapeHtml($thisFacet['displayText']) ?>
-                      </a>
-                    </li>
-                  <? else: ?>
-                    <? $addURL = $this->currentPath() . $results->getUrlQuery()->addFacet($title, $thisFacet['value'], $thisFacet['operator']); ?>
-                    <? if ($allowExclude): ?>
-                      <li class="facet<?= $thisFacet['operator'] ?><? if ($i >= $facets_before_more): ?> <?= $moreClass ?><? endif ?>">
-                    <? else: ?>
-                      <li class="<? if ($i >= $facets_before_more): ?> <?= $moreClass ?><? endif ?>">
-                        <a href="<?= $addURL ?>" class="facet<?= $thisFacet['operator'] ?>">
-                        <? endif; ?>
-                          <span class="label pull-right">
-                            <?= $this->localizedNumber($thisFacet['count']) ?>
-                            <? if ($allowExclude): ?>
-                              <a href="<?= $this->currentPath() . $results->getUrlQuery()->addFacet($title, $thisFacet['value'], 'NOT') ?>" title="<?= $this->transEsc('exclude_facet') ?>"><i class="fa fa-minus-circle"></i></a>
-                            <? endif; ?>
-                          </span>
-                    <? if ($allowExclude): ?>
-                    <a href="<?= $addURL ?>">
-                  <? endif; ?>
-                    <? if ($thisFacet['operator'] == 'OR'): ?>
-                      <i class="fa fa-square-o"></i>
-                    <? endif; ?>
-                    <?= $this->escapeHtml($thisFacet['displayText']) ?>
-                    <? /* No <? if ($allowExclude): ?> here! - CK */ ?>
-                    </a>
-                    </li>
-                  <? endif; ?>
-                <? endforeach; ?>
-                <? if ($i >= $facets_before_more): ?><li class="<?= $moreClass ?>"><a href="javascript:lessFacets('narrowGroupHidden-<?=$this->escapeHtmlAttr($title) ?>')"><?= $this->transEsc('less') ?>&nbsp;...</a></li><? endif; ?>
-                <? endif; ?>
-              </ul>
-              <? if (in_array($title, $hierarchicalFacets)): ?>
-            </noscript>
-            <? endif; ?>
-        </div>
-      </li>
-    </ul>
-  <? endforeach; ?>
-<? endif; ?>
+<!-- recommend - SIDEFACETS.phtml -->
+<? $results = $this->recommend->getResults(); ?>
+<? if ($results->getResultTotal() > 0): ?>
+  <h4><?= $this->transEsc(isset($this->overrideSideFacetCaption) ? $this->overrideSideFacetCaption : 'Narrow Search') ?></h4>
+<? endif; ?>
+<? $checkboxFilters = $results->getParams()->getCheckboxFacets();
+if (count($checkboxFilters) > 0): ?>
+  <?
+  $html = '';
+  $shown = 0;
+  foreach ($checkboxFilters as $current) {
+    $html .= '<label class="checkbox';
+    if ($results->getResultTotal() < 1 && !$current['selected'] && !$current['alwaysVisible']) {
+      $html .= ' hide';
+    } else {
+      $shown++;
+    }
+    $html .= '"><input type="checkbox" name="filter[]" value="' . $this->escapeHtmlAttr($current['filter']) . '"
+      ' . ($current['selected'] ? 'checked="checked"' : '') . ' id="' . $this->escapeHtmlAttr(str_replace(' ', '', $current['desc'])) . '"
+      onclick="document.location.href=\'' . ($current['selected'] ? $results->getUrlQuery()->removeFilter($current['filter']) : $results->getUrlQuery()->addFilter($current['filter'])) . '\';" />' . $this->transEsc($current['desc']) . '</label>';
+  }
+  ?>
+  <div class="checkboxFilter<? if ($shown == 0): ?> hide<? endif; ?>"><?= $html ?></div>
+<? endif; ?>
+<? $extraFilters = isset($this->extraSideFacetFilters) ? $this->extraSideFacetFilters : array(); ?>
+<? $collapsedFacets = $this->recommend->getCollapsedFacets() ?>
+<? $hierarchicalFacetSortOptions = $this->recommend->getHierarchicalFacetSortOptions() ?>
+<? $hierarchicalFacets = $this->recommend->getHierarchicalFacets() ?>
+<? $filterList = array_merge($results->getParams()->getFilterList(true), $extraFilters);
+if (!empty($filterList)): ?>
+  <div class="filters">
+    <div class="title"><?= $this->transEsc('Remove Filters') ?></div>
+    <ul class="side-nav" role="navigation">
+      <? foreach ($filterList as $field => $filters): ?>
+        <? foreach ($filters as $i => $filter): ?>
+          <?
+          $index = isset($filter['field']) ? array_search($filter['field'], $collapsedFacets) : false;
+          if ($index !== false) {
+            unset($collapsedFacets[$index]); // Open if we have a match
+          }
+          if (isset($filter['specialType']) && $filter['specialType'] == 'keyword') {
+            $removeLink = $this->currentPath() . $results->getUrlQuery()->replaceTerm($filter['value'], '');
+          } else {
+            $removeLink = $this->currentPath() . $results->getUrlQuery()->removeFacet($filter['field'], $filter['value'], true, $filter['operator']);
+          }
+          if ($filter['displayText'] == '[* TO *]') {
+            $filter['displayText'] = $this->translate('filter_wildcard');
+          }
+          ?>
+          <li>
+            <a class="active" href="<?= $removeLink ?>">
+              <span class="pull-right"><i class="fa fa-times"></i></span>
+              <? if ($filter['operator'] == 'NOT') echo $this->transEsc('NOT') . ' ';
+              if ($filter['operator'] == 'OR' && $i > 0) echo $this->transEsc('OR') . ' '; ?><?= $this->transEsc($field) ?>: <?= $this->escapeHtml($filter['displayText']) ?>
+            </a>
+          </li>
+        <? endforeach; ?>
+      <? endforeach; ?>
+    </ul>
+  </div>
+<? endif; ?>
+<?= isset($this->sideFacetExtraControls) ? $this->sideFacetExtraControls : '' ?>
+<? $sideFacetSet = $this->sidefacet()->displayAllowedFacetValues($this->recommend->getFacetSet());
+$rangeFacets = $this->recommend->getAllRangeFacets(); ?>
+<? if (!empty($sideFacetSet) && $results->getResultTotal() > 0): ?>
+  <? foreach ($sideFacetSet as $title => $cluster): ?>
+    <? $allowExclude = $this->recommend->excludeAllowed($title); ?>
+    <? $facets_before_more = $this->recommend->getShowMoreSetting($title); ?>
+    <ul class="accordion" id="side-panel-<?= $this->escapeHtmlAttr($title) ?>" data-accordion>
+      <li class="accordion-navigation <? if (!in_array($title, $collapsedFacets)): ?> active<? endif ?>">
+        <a href="#side-collapse-<?= $this->escapeHtmlAttr($title) ?>" class="title"><?= $this->transEsc($cluster['label']) ?></a>
+        <div id="side-collapse-<?= $this->escapeHtmlAttr($title) ?>" class="content <? if (!in_array($title, $collapsedFacets)): ?>active<? endif ?>">
+          <? if (isset($rangeFacets[$title])): ?>
+          <ul class="date-range-slider">
+            <li>
+              <form name="<?= $this->escapeHtmlAttr($title) ?>Filter" id="<?= $this->escapeHtmlAttr($title) ?>Filter">
+                <?= $results->getUrlQuery()->asHiddenFields(array('page' => "/./", 'filter' => "/^{$title}:.*/")) ?>
+                <input type="hidden" name="<?= $this->escapeHtmlAttr($rangeFacets[$title]['type']) ?>range[]" value="<?= $this->escapeHtmlAttr($title) ?>"/>
+                <div class="row">
+                  <? $extraInputAttribs = ($rangeFacets[$title]['type'] == 'date') ? 'maxlength="4" ' : ''; ?>
+                  <div class="medium-6 columns">
+                    <label for="<?= $this->escapeHtmlAttr($title) ?>from">
+                      <?= $this->transEsc('date_from') ?>:
+                    </label>
+                    <input type="text" name="<?= $this->escapeHtmlAttr($title) ?>from" id="<?= $this->escapeHtmlAttr($title) ?>from"
+                           value="<?= isset($rangeFacets[$title]['values'][0]) ? $this->escapeHtmlAttr($rangeFacets[$title]['values'][0]) : '' ?>" <?= $extraInputAttribs ?>/>
+                  </div>
+                  <div class="medium-6 columns">
+                    <label for="<?= $this->escapeHtmlAttr($title) ?>to">
+                      <?= $this->transEsc('date_to') ?>:
+                    </label>
+                    <input type="text" name="<?= $this->escapeHtmlAttr($title) ?>to" id="<?= $this->escapeHtmlAttr($title) ?>to"
+                           value="<?= isset($rangeFacets[$title]['values'][1]) ? $this->escapeHtmlAttr($rangeFacets[$title]['values'][1]) : '' ?>" <?= $extraInputAttribs ?>/>
+                  </div>
+                </div>
+                <? if ($rangeFacets[$title]['type'] == 'date'): ?>
+                  <div class="slider-container"><input type="text" class="hide" id="<?= $this->escapeHtmlAttr($title) ?><?= $this->escapeHtml($rangeFacets[$title]['type']) ?>Slider"/></div>
+                <? endif; ?>
+                <input class="button tiny" type="submit" value="<?= $this->transEsc('Set') ?>"/>
+              </form>
+              <? /* NO closing UL and LI here! - is closed below */ ?>
+              <? /* ADAPT RANGE SLIDER JS HERE AND REMOVE BootstrapSlider JS and CSS when FNDTN6 is out - FIXME CK */ ?>
+              <? if ($rangeFacets[$title]['type'] == 'date'): ?>
+                <? $this->headScript()->appendFile('vendor/bootstrap-slider.js'); ?>
+                <? $this->headLink()->appendStylesheet('vendor/bootstrap-slider.css'); ?>
+                <?
+                $min = !empty($rangeFacets[$title]['values'][0]) ? min($rangeFacets[$title]['values'][0], 1400) : 1400;
+                $future = date('Y', time() + 31536000);
+                $max = !empty($rangeFacets[$title]['values'][1]) ? max($future, $rangeFacets[$title]['values'][1]) : $future;
+                $low = !empty($rangeFacets[$title]['values'][0]) ? $rangeFacets[$title]['values'][0] : $min;
+                $high = !empty($rangeFacets[$title]['values'][1]) ? $rangeFacets[$title]['values'][1] : $max;
+                $reversed = $this->layout()->rtl ? 'true' : 'false';
+                $script = <<<JS
+$(document).ready(function() {
+  var fillTexts = function() {
+  var v = {$this->escapeHtmlAttr($title)}dateSlider.getValue();
+  $('#{$this->escapeHtmlAttr($title)}from').val(v[0]);
+  $('#{$this->escapeHtmlAttr($title)}to').val(v[1]);
+  };
+  var {$this->escapeHtmlAttr($title)}dateSlider = $('#{$this->escapeHtmlAttr($title)}dateSlider')
+  .slider({
+     'min':{$min},
+     'max':{$max},
+     'handle':"square",
+     'tooltip':"hide",
+    'value':[{$low},{$high}],
+    'reversed': {$reversed}
+  })
+  .on('slide', fillTexts)
+  .data('slider');
+});
+
+$('#{$this->escapeHtmlAttr($title)}from, #{$this->escapeHtmlAttr($title)}to').change(function () {
+  var from = Number($('#{$this->escapeHtmlAttr($title)}from').val());
+  var to   = Number($('#{$this->escapeHtmlAttr($title)}to').val());
+  if (from <= 0) {
+    from = {$min};
+  }
+  if (to <= 0) {
+    to = {$max};
+  }
+  $('#{$this->escapeHtmlAttr($title)}dateSlider').slider('setValue', [from, to], true);
+});
+JS;
+                ?>
+                <?= $this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $script, 'SET'); ?>
+              <? endif; ?>
+              <? else: ?>
+              <? if (in_array($title, $hierarchicalFacets)): ?>
+              <? $this->headScript()->appendFile('vendor/jsTree/jstree.min.js'); ?>
+              <? $this->headScript()->appendFile('facets.js'); ?>
+              <? $sort = isset($hierarchicalFacetSortOptions[$title]) ? $hierarchicalFacetSortOptions[$title] : ''; ?>
+              <? if (!in_array($title, $collapsedFacets)): ?>
+                <?
+                $script = <<<JS
+$(document).ready(function() {
+  initFacetTree($('#facet_{$this->escapeHtml($title)}'), true);
+});
+<? /* Verify necessity of the following JS - fixme CK */ ?>
+JS;
+                ?>
+                <?= $this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $script, 'SET'); ?>
+              <? else: ?>
+                <?
+                $script = <<<JS
+$('#side-collapse-{$this->escapeHtmlAttr($title)}').on('show.fndtn.accordion', function() {
+  initFacetTree($('#facet_{$this->escapeHtml($title)}'), true);
+});
+JS;
+                ?>
+                <?= $this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $script, 'SET'); ?>
+              <? endif; ?>
+            <li id="facet_<?= $this->escapeHtml($title) ?>" class="jstree-facet"
+                data-facet="<?= $this->escapeHtmlAttr($title) ?>"
+                data-path="<?= $this->currentPath() ?>"
+                data-exclude="<?= $allowExclude ?>"
+                data-operator="<?= $this->recommend->getFacetOperator($title) ?>"
+                data-exclude-title="<?= $this->transEsc('exclude_facet') ?>"
+                data-sort="<?= isset($hierarchicalFacetSortOptions[$title]) ? $hierarchicalFacetSortOptions[$title] : '' ?>">
+            </li>
+            <noscript>
+              <? endif; ?>
+              <ul class="side-nav" role="navigation">
+                <? foreach ($cluster['list'] as $i => $thisFacet): ?>
+                  <?
+                  if (strlen($thisFacet['displayText']) == 0) {
+                    $thisFacet['displayText'] = "-";
+                  }
+                  ?>
+                  <? $moreClass = 'narrowGroupHidden-' . $this->escapeHtmlAttr($title) . ' hide'; ?>
+                  <? if ($i == $facets_before_more): ?>
+                    <li id="more-narrowGroupHidden-<?= $this->escapeHtmlAttr($title) ?>">
+                      <a href="javascript:moreFacets('narrowGroupHidden-<?=$this->escapeHtmlAttr($title) ?>')"><?= $this->transEsc('more') ?>&nbsp;...</a>
+                    </li>
+                  <? endif; ?>
+                  <? if ($thisFacet['isApplied']): ?>
+                    <li class="<? if ($i >= $facets_before_more): ?> <?= $moreClass ?> <? endif ?>">
+                      <a class="active <? if ($thisFacet['operator'] == 'OR'): ?> facetOR applied<? endif ?>" href="<?= $this->currentPath() . $results->getUrlQuery()->removeFacet($title, $thisFacet['value'], true, $thisFacet['operator']) ?>" >
+                        <? if ($thisFacet['operator'] == 'OR'): ?>
+                          <i class="fa fa-check-square-o"></i>
+                        <? else: ?>
+                          <span class="pull-right"><i class="fa fa-check"></i></span>
+                        <? endif; ?>
+                        <?= $this->escapeHtml($thisFacet['displayText']) ?>
+                      </a>
+                    </li>
+                  <? else: ?>
+                    <? $addURL = $this->currentPath() . $results->getUrlQuery()->addFacet($title, $thisFacet['value'], $thisFacet['operator']); ?>
+                    <? if ($allowExclude): ?>
+                      <li class="facet<?= $thisFacet['operator'] ?><? if ($i >= $facets_before_more): ?> <?= $moreClass ?><? endif ?>">
+                    <? else: ?>
+                      <li class="<? if ($i >= $facets_before_more): ?> <?= $moreClass ?><? endif ?>">
+                        <a href="<?= $addURL ?>" class="facet<?= $thisFacet['operator'] ?>">
+                        <? endif; ?>
+                          <span class="label pull-right">
+                            <?= $this->localizedNumber($thisFacet['count']) ?>
+                            <? if ($allowExclude): ?>
+                              <a href="<?= $this->currentPath() . $results->getUrlQuery()->addFacet($title, $thisFacet['value'], 'NOT') ?>" title="<?= $this->transEsc('exclude_facet') ?>"><i class="fa fa-minus-circle"></i></a>
+                            <? endif; ?>
+                          </span>
+                    <? if ($allowExclude): ?>
+                    <a href="<?= $addURL ?>">
+                  <? endif; ?>
+                    <? if ($thisFacet['operator'] == 'OR'): ?>
+                      <i class="fa fa-square-o"></i>
+                    <? endif; ?>
+                    <?= $this->escapeHtml($thisFacet['displayText']) ?>
+                    <? /* No <? if ($allowExclude): ?> here! - CK */ ?>
+                    </a>
+                    </li>
+                  <? endif; ?>
+                <? endforeach; ?>
+                <? if ($i >= $facets_before_more): ?><li class="<?= $moreClass ?>"><a href="javascript:lessFacets('narrowGroupHidden-<?=$this->escapeHtmlAttr($title) ?>')"><?= $this->transEsc('less') ?>&nbsp;...</a></li><? endif; ?>
+                <? endif; ?>
+              </ul>
+              <? if (in_array($title, $hierarchicalFacets)): ?>
+            </noscript>
+            <? endif; ?>
+        </div>
+      </li>
+    </ul>
+  <? endforeach; ?>
+<? endif; ?>
 <!-- recommend - SIDEFACETS.phtml - END -->
\ No newline at end of file
diff --git a/themes/finc/theme.config.php b/themes/finc/theme.config.php
index a7213dfc37d..36bac408616 100644
--- a/themes/finc/theme.config.php
+++ b/themes/finc/theme.config.php
@@ -17,6 +17,7 @@ return array(
             'citation' => 'finc\View\Helper\Root\Factory::getCitation',
             'openurl' => 'finc\View\Helper\Root\Factory::getOpenUrl',
             'branchinfo' => 'finc\View\Helper\Root\Factory::getBranchInfo',
+            'sidefacet' => 'finc\View\Helper\Root\Factory::getSideFacet'
         ),
         'invokables' => array(
             'resultfeed' => 'finc\View\Helper\Root\ResultFeed'
-- 
GitLab