From 30688e9c80cf4e3bdee0e274d4a330703c0675c4 Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Mon, 15 Dec 2014 13:53:59 -0500
Subject: [PATCH] More granular control over enabling recommendations.

---
 .../src/VuFind/Controller/AbstractSearch.php  |  29 ++++-
 .../VuFind/Controller/CombinedController.php  |   4 +-
 .../VuFind/src/VuFind/Search/Base/Params.php  | 103 ++++++++++--------
 .../src/VuFind/Search/Combined/Params.php     |   9 +-
 4 files changed, 91 insertions(+), 54 deletions(-)

diff --git a/module/VuFind/src/VuFind/Controller/AbstractSearch.php b/module/VuFind/src/VuFind/Controller/AbstractSearch.php
index 2ff10a6026e..ec5086544af 100644
--- a/module/VuFind/src/VuFind/Controller/AbstractSearch.php
+++ b/module/VuFind/src/VuFind/Controller/AbstractSearch.php
@@ -193,6 +193,30 @@ class AbstractSearch extends AbstractBase
         }
     }
 
+    /**
+     * Get active recommendation module settings
+     *
+     * @return array
+     */
+    protected function getActiveRecommendationSettings()
+    {
+        // Enable recommendations unless explicitly told to disable them:
+        $all = array('top', 'side', 'noresults');
+        $noRecommend = $this->params()->fromQuery('noRecommend', false);
+        if ($noRecommend === 1 || $noRecommend === '1'
+            || $noRecommend === 'true' || $noRecommend === true
+        ) {
+            return array();
+        } else if ($noRecommend === 0 || $noRecommend === '0'
+            || $noRecommend === 'false' || $noRecommend === false
+        ) {
+            return $all;
+        }
+        return array_diff(
+            $all, array_map('trim', explode(',', strtolower($noRecommend)))
+        );
+    }
+
     /**
      * Send search results to results view
      *
@@ -210,10 +234,7 @@ class AbstractSearch extends AbstractBase
 
         $results = $this->getResultsManager()->get($this->searchClassId);
         $params = $results->getParams();
-
-        // Enable recommendations unless explicitly told to disable them:
-        $noRecommend = $this->params()->fromQuery('noRecommend', false);
-        $params->recommendationsEnabled(!$noRecommend);
+        $params->recommendationsEnabled($this->getActiveRecommendationSettings());
 
         // Send both GET and POST variables to search class:
         $params->initFromRequest(
diff --git a/module/VuFind/src/VuFind/Controller/CombinedController.php b/module/VuFind/src/VuFind/Controller/CombinedController.php
index 25a866585a2..976985acd27 100644
--- a/module/VuFind/src/VuFind/Controller/CombinedController.php
+++ b/module/VuFind/src/VuFind/Controller/CombinedController.php
@@ -261,8 +261,8 @@ class CombinedController extends AbstractSearch
         $query = $this->getRequest()->getQuery();
         $query->limit = isset($settings['limit']) ? $settings['limit'] : null;
 
-        // Disable recommendations:
-        $query->noRecommend = 1;
+        // Disable top/side recommendations but leave noresults active:
+        $query->noRecommend = 'top,side';
     }
 }
 
diff --git a/module/VuFind/src/VuFind/Search/Base/Params.php b/module/VuFind/src/VuFind/Search/Base/Params.php
index a07ba1cb1f0..918ceb446ce 100644
--- a/module/VuFind/src/VuFind/Search/Base/Params.php
+++ b/module/VuFind/src/VuFind/Search/Base/Params.php
@@ -119,7 +119,7 @@ class Params implements ServiceLocatorAwareInterface
      *
      * @var bool
      */
-    protected $recommendationEnabled = false;
+    protected $recommendationEnabled = array();
 
     /**
      * Main facet configuration
@@ -670,13 +670,17 @@ class Params implements ServiceLocatorAwareInterface
      */
     public function getRecommendations($location = 'top')
     {
-        if (!$this->recommendationsEnabled()) {
-            return array();
-        }
-        if (is_null($location)) {
-            return $this->recommend;
+        $enabled = $this->recommendationsEnabled();
+        if (null === $location) {
+            $active = array();
+            foreach ($enabled as $current) {
+                if (isset($this->recommend[$current])) {
+                    $active[$current] = $this->recommend[$current];
+                }
+            }
+            return $active;
         }
-        return isset($this->recommend[$location])
+        return in_array($location, $enabled) && isset($this->recommend[$location])
             ? $this->recommend[$location] : array();
     }
 
@@ -685,14 +689,19 @@ class Params implements ServiceLocatorAwareInterface
      * off recommendations when retrieving results in a context other than standard
      * display of results.
      *
-     * @param bool $bool True to enable, false to disable (null to leave unchanged)
+     * @param bool|array $new New setting (true to enable all, false to disable all,
+     * array to set which areas are active, null to leave unchanged)
      *
-     * @return bool      Current state of recommendations
+     * @return array          Current active recommendation areas
      */
-    public function recommendationsEnabled($bool = null)
+    public function recommendationsEnabled($new = null)
     {
-        if (!is_null($bool)) {
-            $this->recommendationEnabled = $bool;
+        if (true === $new) {
+            $this->recommendationEnabled = array('top', 'side', 'noresults');
+        } else if (false === $new) {
+            $this->recommendationEnabled = array();
+        } else if (null !== $new) {
+            $this->recommendationEnabled = $new;
         }
         return $this->recommendationEnabled;
     }
@@ -708,7 +717,8 @@ class Params implements ServiceLocatorAwareInterface
     protected function getRecommendationSettings()
     {
         // Bypass settings if recommendations are disabled.
-        if (!$this->recommendationsEnabled()) {
+        $enabled = $this->recommendationsEnabled();
+        if (empty($enabled)) {
             return array();
         }
 
@@ -724,38 +734,45 @@ class Params implements ServiceLocatorAwareInterface
         // Load a type-specific recommendations setting if possible, or the default
         // otherwise:
         $recommend = array();
-        if (!is_null($handler)
-            && isset($searchSettings->TopRecommendations->$handler)
-        ) {
-            $recommend['top'] = $searchSettings->TopRecommendations
-                ->$handler->toArray();
-        } else {
-            $recommend['top']
-                = isset($searchSettings->General->default_top_recommend)
-                ? $searchSettings->General->default_top_recommend->toArray()
-                : false;
+
+        if (in_array('top', $enabled)) {
+            if (null !== $handler
+                && isset($searchSettings->TopRecommendations->$handler)
+            ) {
+                $recommend['top'] = $searchSettings->TopRecommendations
+                    ->$handler->toArray();
+            } else {
+                $recommend['top']
+                    = isset($searchSettings->General->default_top_recommend)
+                    ? $searchSettings->General->default_top_recommend->toArray()
+                    : false;
+            }
         }
-        if (!is_null($handler)
-            && isset($searchSettings->SideRecommendations->$handler)
-        ) {
-            $recommend['side'] = $searchSettings->SideRecommendations
-                ->$handler->toArray();
-        } else {
-            $recommend['side']
-                = isset($searchSettings->General->default_side_recommend)
-                ? $searchSettings->General->default_side_recommend->toArray()
-                : false;
+        if (in_array('side', $enabled)) {
+            if (null !== $handler
+                && isset($searchSettings->SideRecommendations->$handler)
+            ) {
+                $recommend['side'] = $searchSettings->SideRecommendations
+                    ->$handler->toArray();
+            } else {
+                $recommend['side']
+                    = isset($searchSettings->General->default_side_recommend)
+                    ? $searchSettings->General->default_side_recommend->toArray()
+                    : false;
+            }
         }
-        if (!is_null($handler)
-            && isset($searchSettings->NoResultsRecommendations->$handler)
-        ) {
-            $recommend['noresults'] = $searchSettings->NoResultsRecommendations
-                ->$handler->toArray();
-        } else {
-            $recommend['noresults']
-                = isset($searchSettings->General->default_noresults_recommend)
-                ? $searchSettings->General->default_noresults_recommend->toArray()
-                : false;
+        if (in_array('noresults', $enabled)) {
+            if (null !== $handler
+                && isset($searchSettings->NoResultsRecommendations->$handler)
+            ) {
+                $recommend['noresults'] = $searchSettings->NoResultsRecommendations
+                    ->$handler->toArray();
+            } else {
+                $recommend['noresults']
+                    = isset($searchSettings->General->default_noresults_recommend)
+                    ? $searchSettings->General->default_noresults_recommend->toArray()
+                    : false;
+            }
         }
 
         return $recommend;
diff --git a/module/VuFind/src/VuFind/Search/Combined/Params.php b/module/VuFind/src/VuFind/Search/Combined/Params.php
index 3601b726aa9..450f0f14888 100644
--- a/module/VuFind/src/VuFind/Search/Combined/Params.php
+++ b/module/VuFind/src/VuFind/Search/Combined/Params.php
@@ -48,15 +48,14 @@ class Params extends \VuFind\Search\Solr\Params
      */
     protected function getRecommendationSettings()
     {
-        // Bypass settings if recommendations are disabled.
-        if (!$this->recommendationsEnabled()) {
-            return array();
-        }
+        $enabled = $this->recommendationsEnabled();
         $recommend = array();
         $config = $this->getServiceLocator()->get('VuFind\Config')
             ->get('combined');
         foreach (array('top', 'bottom') as $location) {
-            if (isset($config->RecommendationModules->$location)) {
+            if (in_array($location, $enabled)
+                && isset($config->RecommendationModules->$location)
+            ) {
                 $recommend[$location]
                     = $config->RecommendationModules->$location->toArray();
             }
-- 
GitLab