From 55cc5abd2322cfbfcab49d5143f9bcd3467b4210 Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Wed, 25 Apr 2018 13:56:00 -0400
Subject: [PATCH] Facet caching improvements (#1165)

- Move facet caching logic out of controllers.
- Introduce a new plugin manager for facet caches.
- Standardize Summon facet cache logic to more closely match Solr; add HomePage support and fix broken functionality.
---
 config/vufind/Summon.ini                      |  14 ++
 module/VuFind/config/module.config.php        |   2 +
 .../VuFind/Controller/SearchController.php    | 118 +------------
 .../VuFind/Controller/SummonController.php    |  76 +--------
 .../src/VuFind/Search/Base/FacetCache.php     | 156 ++++++++++++++++++
 .../VuFind/Search/Base/FacetCacheFactory.php  |  78 +++++++++
 .../Search/FacetCache/PluginManager.php       |  72 ++++++++
 .../src/VuFind/Search/Solr/FacetCache.php     |  50 ++++++
 .../VuFind/Search/Solr/FacetCacheFactory.php  |  64 +++++++
 .../src/VuFind/Search/Summon/FacetCache.php   |  50 ++++++
 .../Search/Summon/FacetCacheFactory.php       |  54 ++++++
 .../src/VuFind/Search/Summon/Params.php       |  27 ++-
 12 files changed, 582 insertions(+), 179 deletions(-)
 create mode 100644 module/VuFind/src/VuFind/Search/Base/FacetCache.php
 create mode 100644 module/VuFind/src/VuFind/Search/Base/FacetCacheFactory.php
 create mode 100644 module/VuFind/src/VuFind/Search/FacetCache/PluginManager.php
 create mode 100644 module/VuFind/src/VuFind/Search/Solr/FacetCache.php
 create mode 100644 module/VuFind/src/VuFind/Search/Solr/FacetCacheFactory.php
 create mode 100644 module/VuFind/src/VuFind/Search/Summon/FacetCache.php
 create mode 100644 module/VuFind/src/VuFind/Search/Summon/FacetCacheFactory.php

diff --git a/config/vufind/Summon.ini b/config/vufind/Summon.ini
index fe5ffd8de07..325e3adbd4c 100644
--- a/config/vufind/Summon.ini
+++ b/config/vufind/Summon.ini
@@ -225,6 +225,20 @@ orFacets = *
 ; below, no facets will be translated.
 translated_facets[] = ContentType
 
+; These facets will be displayed on the Home Page.  If this section is omitted,
+; the [Advanced_Facets] section will be used instead.
+[HomePage_Facets]
+Language = "Language"
+ContentType = "Format"
+
+; These settings affect the way the [HomePage] facets are displayed
+; NOTE: To make changes take effect immediately, you may need to clear VuFind's
+; cache after changing this section.
+[HomePage_Facet_Settings]
+; how many values should we load for each facet?  depending on the column layout
+; of the homepage facet lists, we may not display all loaded values for every facet
+facet_limit = 100
+
 ; This section shows which search types will display in the basic search box at
 ; the top of Summon pages.  The name of each setting below corresponds with an
 ; index defined in the Summon API.  The value of each setting is the text to
diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php
index ba4d224d29f..84f123e8d96 100644
--- a/module/VuFind/config/module.config.php
+++ b/module/VuFind/config/module.config.php
@@ -337,6 +337,7 @@ $config = [
             'VuFind\Search\BackendManager' => 'VuFind\Search\BackendManagerFactory',
             'VuFind\Search\History' => 'VuFind\Search\HistoryFactory',
             'VuFind\Search\Memory' => 'VuFind\Search\MemoryFactory',
+            'VuFind\Search\FacetCache\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory',
             'VuFind\Search\Options\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory',
             'VuFind\Search\Params\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory',
             'VuFind\Search\Results\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory',
@@ -486,6 +487,7 @@ $config = [
             'related' => [ /* See VuFind\Related\PluginManager for defaults */ ],
             'resolver_driver' => [ /* See VuFind\Resolver\Driver\PluginManager for defaults */ ],
             'search_backend' => [ /* See VuFind\Search\BackendRegistry for defaults */ ],
+            'search_facetcache' => [ /* See VuFind\Search\FacetCache\PluginManager for defaults */ ],
             'search_options' => [ /* See VuFind\Search\Options\PluginManager for defaults */ ],
             'search_params' => [ /* See VuFind\Search\Params\PluginManager for defaults */ ],
             'search_results' => [ /* See VuFind\Search\Results\PluginManager for defaults */ ],
diff --git a/module/VuFind/src/VuFind/Controller/SearchController.php b/module/VuFind/src/VuFind/Controller/SearchController.php
index 27b89921974..8da9abd1427 100644
--- a/module/VuFind/src/VuFind/Controller/SearchController.php
+++ b/module/VuFind/src/VuFind/Controller/SearchController.php
@@ -51,9 +51,10 @@ class SearchController extends AbstractSearch
         $view = parent::advancedAction();
 
         // Set up facet information:
-        $view->facetList = $this->processAdvancedFacets(
-            $this->getAdvancedFacets(), $view->saved
-        );
+        $facets = $this->serviceLocator
+            ->get('VuFind\Search\FacetCache\PluginManager')->get('Solr')
+            ->getList('Advanced');
+        $view->facetList = $this->processAdvancedFacets($facets, $view->saved);
         $specialFacets = $this->parseSpecialFacetsSetting(
             $view->options->getSpecialAdvancedFacets()
         );
@@ -268,10 +269,12 @@ class SearchController extends AbstractSearch
      */
     public function homeAction()
     {
+        $facetCache = $this->serviceLocator
+            ->get('VuFind\Search\FacetCache\PluginManager')->get('Solr');
         return $this->createViewModel(
             [
-                'results' => $this->getResultsObjectWithHiddenFilters('Solr'),
-                'facetList' => $this->getHomePageFacets(),
+                'results' => $facetCache->getResults(),
+                'facetList' => $facetCache->getList('HomePage'),
                 'hierarchicalFacets' => $this->getHierarchicalFacets(),
                 'hierarchicalFacetSortOptions'
                     => $this->getHierarchicalFacetSortSettings()
@@ -516,111 +519,6 @@ class SearchController extends AbstractSearch
         return parent::resultsAction();
     }
 
-    /**
-     * Get active hidden filter settings.
-     *
-     * @return array
-     */
-    protected function getActiveHiddenFilters()
-    {
-        return $this->serviceLocator->get('VuFind\Search\SearchTabsHelper')
-            ->getHiddenFilters($this->searchClassId);
-    }
-
-    /**
-     * Create a results object with hidden filters pre-populated.
-     *
-     * @param string $backend ID of results object to create
-     * @param array  $filters Hidden filter settings (null for defaults)
-     *
-     * @return \VuFind\Search\Base\Results
-     */
-    protected function getResultsObjectWithHiddenFilters($backend, $filters = null)
-    {
-        if (null === $filters) {
-            $filters = $this->getActiveHiddenFilters();
-        }
-        $results = $this->getResultsManager()->get($backend);
-        $params = $results->getParams();
-        foreach ($filters as $key => $subFilters) {
-            foreach ($subFilters as $filter) {
-                $params->addHiddenFilter("$key:$filter");
-            }
-        }
-        return $results;
-    }
-
-    /**
-     * Return a Search Results object containing requested facet information.  This
-     * data may come from the cache.
-     *
-     * @param string $initMethod Name of params method to use to request facets
-     * @param string $cacheName  Cache key for facet data
-     *
-     * @return array
-     */
-    protected function getFacetResults($initMethod, $cacheName)
-    {
-        // Check if we have facet results cached, and build them if we don't.
-        $cache = $this->serviceLocator->get('VuFind\Cache\Manager')
-            ->getCache('object');
-        $language = $this->serviceLocator->get('Zend\Mvc\I18n\Translator')
-            ->getLocale();
-        $hiddenFilters = $this->getActiveHiddenFilters();
-        $hiddenFiltersHash = md5(json_encode($hiddenFilters));
-        $cacheName .= "List-$hiddenFiltersHash-$language";
-        if (!($list = $cache->getItem($cacheName))) {
-            // Use advanced facet settings to get summary facets on the front page;
-            // we may want to make this more flexible later.  Also keep in mind that
-            // the template is currently looking for certain hard-coded fields; this
-            // should also be made smarter.
-            $results = $this->getResultsObjectWithHiddenFilters(
-                'Solr', $hiddenFilters
-            );
-            $params = $results->getParams();
-            $params->$initMethod();
-
-            // Avoid a backend request if there are no facets configured by the given
-            // init method.
-            if (!empty($params->getFacetConfig())) {
-                // We only care about facet lists, so don't get any results (this
-                // helps prevent problems with serialized File_MARC objects in the
-                // cache):
-                $params->setLimit(0);
-                $list = $results->getFacetList();
-            } else {
-                $list = [];
-            }
-            $cache->setItem($cacheName, $list);
-        }
-
-        return $list;
-    }
-
-    /**
-     * Return a Search Results object containing advanced facet information.  This
-     * data may come from the cache.
-     *
-     * @return array
-     */
-    protected function getAdvancedFacets()
-    {
-        return $this->getFacetResults(
-            'initAdvancedFacets', 'solrSearchAdvancedFacets'
-        );
-    }
-
-    /**
-     * Return a Search Results object containing homepage facet information.  This
-     * data may come from the cache.
-     *
-     * @return array
-     */
-    protected function getHomePageFacets()
-    {
-        return $this->getFacetResults('initHomePageFacets', 'solrSearchHomeFacets');
-    }
-
     /**
      * Handle OpenSearch.
      *
diff --git a/module/VuFind/src/VuFind/Controller/SummonController.php b/module/VuFind/src/VuFind/Controller/SummonController.php
index d1d7e620edc..c08b9426086 100644
--- a/module/VuFind/src/VuFind/Controller/SummonController.php
+++ b/module/VuFind/src/VuFind/Controller/SummonController.php
@@ -105,9 +105,10 @@ class SummonController extends AbstractSearch
         $view = parent::advancedAction();
 
         // Set up facet information:
-        $view->facetList = $this->processAdvancedFacets(
-            $this->getAdvancedFacets(), $view->saved
-        );
+        $facets = $this->serviceLocator
+            ->get('VuFind\Search\FacetCache\PluginManager')->get('Summon')
+            ->getList('Advanced');
+        $view->facetList = $this->processAdvancedFacets($facets, $view->saved);
         $specialFacets = $this->parseSpecialFacetsSetting(
             $view->options->getSpecialAdvancedFacets()
         );
@@ -129,10 +130,12 @@ class SummonController extends AbstractSearch
      */
     public function homeAction()
     {
+        $facetCache = $this->serviceLocator
+            ->get('VuFind\Search\FacetCache\PluginManager')->get('Summon');
         return $this->createViewModel(
             [
-                'results' => $this->getResultsManager()->get('Summon'),
-                'facetList' => $this->getHomePageFacets(),
+                'results' => $facetCache->getResults(),
+                'facetList' => $facetCache->getList('HomePage'),
             ]
         );
     }
@@ -147,69 +150,6 @@ class SummonController extends AbstractSearch
         return $this->resultsAction();
     }
 
-    /**
-     * Return a Search Results object containing advanced facet information.  This
-     * data may come from the cache.
-     *
-     * @return array
-     */
-    protected function getAdvancedFacets()
-    {
-        // Check if we have facet results cached, and build them if we don't.
-        $cache = $this->serviceLocator->get('VuFind\Cache\Manager')
-            ->getCache('object');
-        $language = $this->serviceLocator->get('Zend\Mvc\I18n\Translator')
-            ->getLocale();
-        $cacheKey = 'summonSearchAdvancedFacetsList-' . $language;
-        if (!($list = $cache->getItem($cacheKey))) {
-            $config = $this->serviceLocator->get('VuFind\Config\PluginManager')
-                ->get('Summon');
-            $limit = isset($config->Advanced_Facet_Settings->facet_limit)
-                ? $config->Advanced_Facet_Settings->facet_limit : 100;
-            $results = $this->getResultsManager()->get('Summon');
-            $params = $results->getParams();
-            $facetsToShow = isset($config->Advanced_Facets)
-                 ? $config->Advanced_Facets
-                 : ['Language' => 'Language', 'ContentType' => 'Format'];
-            if (isset($config->Advanced_Facet_Settings->orFacets)) {
-                $orFields = array_map(
-                    'trim', explode(',', $config->Advanced_Facet_Settings->orFacets)
-                );
-            } else {
-                $orFields = [];
-            }
-            foreach ($facetsToShow as $facet => $label) {
-                $useOr = (isset($orFields[0]) && $orFields[0] == '*')
-                    || in_array($facet, $orFields);
-                $params->addFacet(
-                    $facet . ',or,1,' . $limit, $label, $useOr
-                );
-            }
-
-            // We only care about facet lists, so don't get any results:
-            $params->setLimit(0);
-
-            // force processing for cache
-            $list = $results->getFacetList();
-
-            $cache->setItem('summonSearchAdvancedFacetsList', $list);
-        }
-
-        return $list;
-    }
-
-    /**
-     * Return a Search Results object containing homepage facet information.  This
-     * data may come from the cache.
-     *
-     * @return array
-     */
-    protected function getHomePageFacets()
-    {
-        // For now, we'll use the same fields as the advanced search screen.
-        return $this->getAdvancedFacets();
-    }
-
     /**
      * Process the facets to be used as limits on the Advanced Search screen.
      *
diff --git a/module/VuFind/src/VuFind/Search/Base/FacetCache.php b/module/VuFind/src/VuFind/Search/Base/FacetCache.php
new file mode 100644
index 00000000000..740bb2f7734
--- /dev/null
+++ b/module/VuFind/src/VuFind/Search/Base/FacetCache.php
@@ -0,0 +1,156 @@
+<?php
+/**
+ * Abstract Base FacetCache.
+ *
+ * PHP version 7
+ *
+ * Copyright (C) Villanova University 2018.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category VuFind
+ * @package  Search_Base
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+namespace VuFind\Search\Base;
+
+use VuFind\Cache\Manager as CacheManager;
+
+/**
+ * Solr FacetCache Factory.
+ *
+ * @category VuFind
+ * @package  Search_Base
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+abstract class FacetCache
+{
+    /**
+     * Cache manager
+     *
+     * @var CacheManager
+     */
+    protected $cacheManager;
+
+    /**
+     * Currently selected language
+     *
+     * @var string
+     */
+    protected $language;
+
+    /**
+     * Search results object.
+     *
+     * @var Results
+     */
+    protected $results;
+
+    /**
+     * Constructor
+     *
+     * @param Results      $r        Search results object
+     * @param CacheManager $cm       Cache manager
+     * @param string       $language Active UI language
+     */
+    public function __construct(Results $r, CacheManager $cm, $language = 'en')
+    {
+        $this->results = $r;
+        $this->cacheManager = $cm;
+        $this->language = $language;
+    }
+
+    /**
+     * Get the namespace to use for caching facets.
+     *
+     * @return string
+     */
+    abstract protected function getCacheNamespace();
+
+    /**
+     * Get the cache key for the provided method.
+     *
+     * @return string
+     */
+    protected function getCacheKey()
+    {
+        $params = $this->results->getParams();
+        $settings = [$params->getFacetConfig(), $params->getHiddenFilters()];
+        return $this->language . md5(print_r($settings, true));
+    }
+
+    /**
+     * Perform the actual facet lookup.
+     *
+     * @param string $initMethod Name of params method to use to request facets
+     *
+     * @return array
+     */
+    protected function getFacetResults($initMethod)
+    {
+        // Check if we have facet results cached, and build them if we don't.
+        $cache = $this->cacheManager->getCache('object', $this->getCacheNamespace());
+        $params = $this->results->getParams();
+
+        // Note that we need to initialize the parameters BEFORE generating the
+        // cache key to ensure that the key is based on the proper settings.
+        $params->$initMethod();
+        $cacheKey = $this->getCacheKey();
+        if (!($list = $cache->getItem($cacheKey))) {
+            // Avoid a backend request if there are no facets configured by the given
+            // init method.
+            if (!empty($params->getFacetConfig())) {
+                // We only care about facet lists, so don't get any results (this
+                // improves performance):
+                $params->setLimit(0);
+                $list = $this->results->getFacetList();
+            } else {
+                $list = [];
+            }
+            $cache->setItem($cacheKey, $list);
+        }
+
+        return $list;
+    }
+
+    /**
+     * Return facet information. This data may come from the cache.
+     *
+     * @param string $context Context of list to retrieve ('Advanced' or 'HomePage')
+     *
+     * @return array
+     */
+    public function getList($context = 'Advanced')
+    {
+        if (!in_array($context, ['Advanced', 'HomePage'])) {
+            throw new \Exception('Invalid context: ' . $context);
+        }
+        // For now, all contexts are handled the same way.
+        return $this->getFacetResults('init' . $context . 'Facets');
+    }
+
+    /**
+     * Get results object used to retrieve facets.
+     *
+     * @return Results
+     */
+    public function getResults()
+    {
+        return $this->results;
+    }
+}
diff --git a/module/VuFind/src/VuFind/Search/Base/FacetCacheFactory.php b/module/VuFind/src/VuFind/Search/Base/FacetCacheFactory.php
new file mode 100644
index 00000000000..7d938da90c3
--- /dev/null
+++ b/module/VuFind/src/VuFind/Search/Base/FacetCacheFactory.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Abstract FacetCache Factory.
+ *
+ * PHP version 7
+ *
+ * Copyright (C) Villanova University 2018.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category VuFind
+ * @package  Search_Base
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+namespace VuFind\Search\Base;
+
+use Interop\Container\ContainerInterface;
+use Zend\ServiceManager\Factory\FactoryInterface;
+
+/**
+ * Abstract FacetCache Factory.
+ *
+ * @category VuFind
+ * @package  Search_Base
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+abstract class FacetCacheFactory implements FactoryInterface
+{
+    /**
+     * Create a results object with appropriate pre-populated values.
+     *
+     * @param ContainerInterface $container Service manager
+     *
+     * @return \VuFind\Search\Base\Results
+     */
+    abstract protected function getResults(ContainerInterface $container);
+
+    /**
+     * Create an object
+     *
+     * @param ContainerInterface $container     Service manager
+     * @param string             $requestedName Service being created
+     * @param null|array         $options       Extra options (optional)
+     *
+     * @return object
+     *
+     * @throws ServiceNotFoundException if unable to resolve the service.
+     * @throws ServiceNotCreatedException if an exception is raised when
+     * creating a service.
+     * @throws ContainerException if any other error occurs
+     */
+    public function __invoke(ContainerInterface $container, $requestedName,
+        array $options = null
+    ) {
+        if (!empty($options)) {
+            throw new \Exception('Unexpected options sent to factory.');
+        }
+        $results = $this->getResults($container);
+        $cacheManager = $container->get('VuFind\Cache\Manager');
+        $language = $container->get('Zend\Mvc\I18n\Translator')->getLocale();
+        return new $requestedName($results, $cacheManager, $language);
+    }
+}
diff --git a/module/VuFind/src/VuFind/Search/FacetCache/PluginManager.php b/module/VuFind/src/VuFind/Search/FacetCache/PluginManager.php
new file mode 100644
index 00000000000..e5b51980fd2
--- /dev/null
+++ b/module/VuFind/src/VuFind/Search/FacetCache/PluginManager.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Facet cache plugin manager
+ *
+ * PHP version 7
+ *
+ * Copyright (C) Villanova University 2018.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category VuFind
+ * @package  Search
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development:plugins:record_drivers Wiki
+ */
+namespace VuFind\Search\FacetCache;
+
+/**
+ * Facet cache plugin manager
+ *
+ * @category VuFind
+ * @package  Search
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development:plugins:record_drivers Wiki
+ */
+class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager
+{
+    /**
+     * Default plugin aliases.
+     *
+     * @var array
+     */
+    protected $aliases = [
+        'solr' => 'VuFind\Search\Solr\FacetCache',
+        'summon' => 'VuFind\Search\Summon\FacetCache',
+    ];
+
+    /**
+     * Default plugin factories.
+     *
+     * @var array
+     */
+    protected $factories = [
+        'VuFind\Search\Solr\FacetCache' => 'VuFind\Search\Solr\FacetCacheFactory',
+        'VuFind\Search\Summon\FacetCache' =>
+            'VuFind\Search\Summon\FacetCacheFactory',
+    ];
+
+    /**
+     * Return the name of the base class or interface that plug-ins must conform
+     * to.
+     *
+     * @return string
+     */
+    protected function getExpectedInterface()
+    {
+        return 'VuFind\Search\Base\FacetCache';
+    }
+}
diff --git a/module/VuFind/src/VuFind/Search/Solr/FacetCache.php b/module/VuFind/src/VuFind/Search/Solr/FacetCache.php
new file mode 100644
index 00000000000..c3aab4c420e
--- /dev/null
+++ b/module/VuFind/src/VuFind/Search/Solr/FacetCache.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Solr FacetCache.
+ *
+ * PHP version 7
+ *
+ * Copyright (C) Villanova University 2018.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category VuFind
+ * @package  Search_Solr
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+namespace VuFind\Search\Solr;
+
+/**
+ * Solr FacetCache.
+ *
+ * @category VuFind
+ * @package  Search_Solr
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+class FacetCache extends \VuFind\Search\Base\FacetCache
+{
+    /**
+     * Get the namespace to use for caching facets.
+     *
+     * @return string
+     */
+    protected function getCacheNamespace()
+    {
+        return 'solr-facets';
+    }
+}
diff --git a/module/VuFind/src/VuFind/Search/Solr/FacetCacheFactory.php b/module/VuFind/src/VuFind/Search/Solr/FacetCacheFactory.php
new file mode 100644
index 00000000000..7c1b065ee8b
--- /dev/null
+++ b/module/VuFind/src/VuFind/Search/Solr/FacetCacheFactory.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Solr FacetCache Factory.
+ *
+ * PHP version 7
+ *
+ * Copyright (C) Villanova University 2018.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category VuFind
+ * @package  Search_Solr
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+namespace VuFind\Search\Solr;
+
+use Interop\Container\ContainerInterface;
+
+/**
+ * Solr FacetCache Factory.
+ *
+ * @category VuFind
+ * @package  Search_Solr
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+class FacetCacheFactory extends \VuFind\Search\Base\FacetCacheFactory
+{
+    /**
+     * Create a results object with hidden filters pre-populated.
+     *
+     * @param ContainerInterface $container Service manager
+     *
+     * @return \VuFind\Search\Base\Results
+     */
+    protected function getResults(ContainerInterface $container)
+    {
+        $filters = $container->get('VuFind\Search\SearchTabsHelper')
+            ->getHiddenFilters('Solr');
+        $results = $container->get('VuFind\Search\Results\PluginManager')
+            ->get('Solr');
+        $params = $results->getParams();
+        foreach ($filters as $key => $subFilters) {
+            foreach ($subFilters as $filter) {
+                $params->addHiddenFilter("$key:$filter");
+            }
+        }
+        return $results;
+    }
+}
diff --git a/module/VuFind/src/VuFind/Search/Summon/FacetCache.php b/module/VuFind/src/VuFind/Search/Summon/FacetCache.php
new file mode 100644
index 00000000000..11bffd4c2e5
--- /dev/null
+++ b/module/VuFind/src/VuFind/Search/Summon/FacetCache.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Summon FacetCache.
+ *
+ * PHP version 7
+ *
+ * Copyright (C) Villanova University 2018.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category VuFind
+ * @package  Search_Summon
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+namespace VuFind\Search\Summon;
+
+/**
+ * Summon FacetCache.
+ *
+ * @category VuFind
+ * @package  Search_Summon
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+class FacetCache extends \VuFind\Search\Base\FacetCache
+{
+    /**
+     * Get the namespace to use for caching facets.
+     *
+     * @return string
+     */
+    protected function getCacheNamespace()
+    {
+        return 'summon-facets';
+    }
+}
diff --git a/module/VuFind/src/VuFind/Search/Summon/FacetCacheFactory.php b/module/VuFind/src/VuFind/Search/Summon/FacetCacheFactory.php
new file mode 100644
index 00000000000..2e0f10ceeb0
--- /dev/null
+++ b/module/VuFind/src/VuFind/Search/Summon/FacetCacheFactory.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Summon FacetCache Factory.
+ *
+ * PHP version 7
+ *
+ * Copyright (C) Villanova University 2018.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category VuFind
+ * @package  Search_Summon
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+namespace VuFind\Search\Summon;
+
+use Interop\Container\ContainerInterface;
+
+/**
+ * Summon FacetCache Factory.
+ *
+ * @category VuFind
+ * @package  Search_Summon
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+class FacetCacheFactory extends \VuFind\Search\Base\FacetCacheFactory
+{
+    /**
+     * Create a results object.
+     *
+     * @param ContainerInterface $container Service manager
+     *
+     * @return \VuFind\Search\Base\Results
+     */
+    protected function getResults(ContainerInterface $container)
+    {
+        return $container->get('VuFind\Search\Results\PluginManager')->get('Summon');
+    }
+}
diff --git a/module/VuFind/src/VuFind/Search/Summon/Params.php b/module/VuFind/src/VuFind/Search/Summon/Params.php
index 69cdcf0e5b2..0e197984c0d 100644
--- a/module/VuFind/src/VuFind/Search/Summon/Params.php
+++ b/module/VuFind/src/VuFind/Search/Summon/Params.php
@@ -377,7 +377,30 @@ class Params extends \VuFind\Search\Base\Params
      */
     public function initAdvancedFacets()
     {
-        $this->initFacetList('Advanced_Facets', 'Advanced_Facet_Settings', 'Summon');
+        $success = $this
+            ->initFacetList('Advanced_Facets', 'Advanced_Facet_Settings', 'Summon');
+        // If no configuration was found, set up defaults instead:
+        if (!$success) {
+            $defaults = ['Language' => 'Language', 'ContentType' => 'Format'];
+            foreach ($defaults as $key => $value) {
+                $this->addFacet($key, $value);
+            }
+        }
+    }
+
+    /**
+     * Initialize facet settings for the home page.
+     *
+     * @return void
+     */
+    public function initHomePageFacets()
+    {
+        // Load Advanced settings if HomePage settings are missing (legacy support):
+        $homeSuccess = $this
+            ->initFacetList('HomePage_Facets', 'HomePage_Facet_Settings', 'Summon');
+        if (!$homeSuccess) {
+            $this->initAdvancedFacets();
+        }
     }
 
     /**
@@ -406,9 +429,11 @@ class Params extends \VuFind\Search\Base\Params
         // Based on preference, change the order of initialization to make sure
         // that preferred facet labels come in last.
         if ($preferredSection == 'Advanced') {
+            $this->initHomePageFacets();
             $this->initBasicFacets();
             $this->initAdvancedFacets();
         } else {
+            $this->initHomePageFacets();
             $this->initAdvancedFacets();
             $this->initBasicFacets();
         }
-- 
GitLab