From dcccf05e39244dbd622832f902e948e37b1c832b Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Tue, 24 Sep 2013 12:27:21 -0400
Subject: [PATCH] Added OR/NOT support to TopFacets. - Progress on VUFIND-177 -
 Refactored TopFacets/SideFacets to share common base class

---
 .../src/VuFind/Recommend/AbstractFacets.php   | 146 ++++++++++++++++++
 .../src/VuFind/Recommend/SideFacets.php       | 101 +-----------
 .../VuFind/src/VuFind/Recommend/TopFacets.php |  57 +------
 .../templates/Recommend/TopFacets.phtml       |   6 +-
 4 files changed, 159 insertions(+), 151 deletions(-)
 create mode 100644 module/VuFind/src/VuFind/Recommend/AbstractFacets.php

diff --git a/module/VuFind/src/VuFind/Recommend/AbstractFacets.php b/module/VuFind/src/VuFind/Recommend/AbstractFacets.php
new file mode 100644
index 00000000000..d92802c6cc8
--- /dev/null
+++ b/module/VuFind/src/VuFind/Recommend/AbstractFacets.php
@@ -0,0 +1,146 @@
+<?php
+/**
+ * SideFacets Recommendations Module
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Villanova University 2010.
+ *
+ * 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  Recommendations
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/vufind2:recommendation_modules Wiki
+ */
+namespace VuFind\Recommend;
+use Zend\Config\Config;
+
+/**
+ * SideFacets Recommendations Module
+ *
+ * This class provides recommendations displaying facets beside search results
+ *
+ * @category VuFind2
+ * @package  Recommendations
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/vufind2:recommendation_modules Wiki
+ */
+abstract class AbstractFacets implements RecommendInterface
+{
+    /**
+     * Facets with "exclude" links enabled
+     *
+     * @var array
+     */
+    protected $excludableFacets = array();
+
+    /**
+     * Facets that are "ORed" instead of "ANDed."
+     *
+     * @var array
+     */
+    protected $orFacets = array();
+
+    /**
+     * Search results
+     *
+     * @var \VuFind\Search\Base\Results
+     */
+    protected $results;
+
+    /**
+     * Configuration loader
+     *
+     * @var \VuFind\Config\PluginManager
+     */
+    protected $configLoader;
+
+    /**
+     * Constructor
+     *
+     * @param \VuFind\Config\PluginManager $configLoader Configuration loader
+     */
+    public function __construct(\VuFind\Config\PluginManager $configLoader)
+    {
+        $this->configLoader = $configLoader;
+    }
+
+    /**
+     * process
+     *
+     * Called after the Search Results object has performed its main search.  This
+     * may be used to extract necessary information from the Search Results object
+     * or to perform completely unrelated processing.
+     *
+     * @param \VuFind\Search\Base\Results $results Search results object
+     *
+     * @return void
+     */
+    public function process($results)
+    {
+        $this->results = $results;
+    }
+
+    /**
+     * Is the specified field allowed to be excluded?
+     *
+     * @param string $field Field name
+     *
+     * @return bool
+     */
+    public function excludeAllowed($field)
+    {
+        return in_array($field, $this->excludableFacets);
+    }
+
+    /**
+     * Get results stored in the object.
+     *
+     * @return \VuFind\Search\Base\Results
+     */
+    public function getResults()
+    {
+        return $this->results;
+    }
+
+    /**
+     * Read boolean (OR/NOT) settings from the provided configuration
+     *
+     * @param Config $config    Configuration to read
+     * @param array  $allFacets All facets (to use when config = *)
+     * @param string $section   Configuration section containing settings
+     *
+     * @return void
+     */
+    protected function loadBooleanConfigs(Config $config, $allFacets,
+        $section = 'Results_Settings'
+    ) {
+        // Which facets are excludable?
+        if (isset($config->$section->exclude)) {
+            $this->excludableFacets = ($config->$section->exclude === '*')
+                ? $allFacets
+                : array_map('trim', explode(',', $config->$section->exclude));
+        }
+
+        // Which facets are ORed?
+        if (isset($config->Results_Settings->orFacets)) {
+            $this->orFacets = ($config->$section->orFacets === '*')
+                ? $allFacets
+                : array_map('trim', explode(',', $config->$section->orFacets));
+        }
+    }
+}
diff --git a/module/VuFind/src/VuFind/Recommend/SideFacets.php b/module/VuFind/src/VuFind/Recommend/SideFacets.php
index aa6c005ecb9..aab9733d8a8 100644
--- a/module/VuFind/src/VuFind/Recommend/SideFacets.php
+++ b/module/VuFind/src/VuFind/Recommend/SideFacets.php
@@ -39,7 +39,7 @@ use VuFind\Solr\Utils as SolrUtils;
  * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
  * @link     http://vufind.org/wiki/vufind2:recommendation_modules Wiki
  */
-class SideFacets implements RecommendInterface
+class SideFacets extends AbstractFacets
 {
     /**
      * Date facet configuration
@@ -55,20 +55,6 @@ class SideFacets implements RecommendInterface
      */
     protected $mainFacets = array();
 
-    /**
-     * Facets with "exclude" links enabled
-     *
-     * @var array
-     */
-    protected $excludableFacets = array();
-
-    /**
-     * Facets that are "ORed" instead of "ANDed."
-     *
-     * @var array
-     */
-    protected $orFacets = array();
-
     /**
      * Checkbox facet configuration
      *
@@ -76,30 +62,6 @@ class SideFacets implements RecommendInterface
      */
     protected $checkboxFacets = array();
 
-    /**
-     * Search results
-     *
-     * @var \VuFind\Search\Base\Results
-     */
-    protected $results;
-
-    /**
-     * Configuration loader
-     *
-     * @var \VuFind\Config\PluginManager
-     */
-    protected $configLoader;
-
-    /**
-     * Constructor
-     *
-     * @param \VuFind\Config\PluginManager $configLoader Configuration loader
-     */
-    public function __construct(\VuFind\Config\PluginManager $configLoader)
-    {
-        $this->configLoader = $configLoader;
-    }
-
     /**
      * setConfig
      *
@@ -124,27 +86,8 @@ class SideFacets implements RecommendInterface
         $this->mainFacets = isset($config->$mainSection) ?
             $config->$mainSection->toArray() : array();
 
-        // Which facets are excludable?
-        if (isset($config->Results_Settings->exclude)) {
-            if ($config->Results_Settings->exclude === '*') {
-                $this->excludableFacets = array_keys($this->mainFacets);
-            } else {
-                $this->excludableFacets = array_map(
-                    'trim', explode(',', $config->Results_Settings->exclude)
-                );
-            }
-        }
-
-        // Which facets are ORed?
-        if (isset($config->Results_Settings->orFacets)) {
-            if ($config->Results_Settings->orFacets === '*') {
-                $this->orFacets = array_keys($this->mainFacets);
-            } else {
-                $this->orFacets = array_map(
-                    'trim', explode(',', $config->Results_Settings->orFacets)
-                );
-            }
-        }
+        // Load boolean configurations:
+        $this->loadBooleanConfigs($config, array_keys($this->mainFacets));
 
         // Get a list of fields that should be displayed as date ranges rather than
         // standard facet lists.
@@ -190,22 +133,6 @@ class SideFacets implements RecommendInterface
         }
     }
 
-    /**
-     * process
-     *
-     * Called after the Search Results object has performed its main search.  This
-     * may be used to extract necessary information from the Search Results object
-     * or to perform completely unrelated processing.
-     *
-     * @param \VuFind\Search\Base\Results $results Search results object
-     *
-     * @return void
-     */
-    public function process($results)
-    {
-        $this->results = $results;
-    }
-
     /**
      * getFacetSet
      *
@@ -244,26 +171,4 @@ class SideFacets implements RecommendInterface
         }
         return $result;
     }
-
-    /**
-     * Is the specified field allowed to be excluded?
-     *
-     * @param string $field Field name
-     *
-     * @return bool
-     */
-    public function excludeAllowed($field)
-    {
-        return in_array($field, $this->excludableFacets);
-    }
-
-    /**
-     * Get results stored in the object.
-     *
-     * @return \VuFind\Search\Base\Results
-     */
-    public function getResults()
-    {
-        return $this->results;
-    }
 }
diff --git a/module/VuFind/src/VuFind/Recommend/TopFacets.php b/module/VuFind/src/VuFind/Recommend/TopFacets.php
index 0bfaf19bfb2..969cb820fdf 100644
--- a/module/VuFind/src/VuFind/Recommend/TopFacets.php
+++ b/module/VuFind/src/VuFind/Recommend/TopFacets.php
@@ -40,7 +40,7 @@ namespace VuFind\Recommend;
  * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
  * @link     http://vufind.org/wiki/vufind2:recommendation_modules Wiki
  */
-class TopFacets implements RecommendInterface
+class TopFacets extends AbstractFacets
 {
     /**
      * Facet configuration
@@ -56,30 +56,6 @@ class TopFacets implements RecommendInterface
      */
     protected $baseSettings;
 
-    /**
-     * Search results
-     *
-     * @var \VuFind\Search\Base\Results
-     */
-    protected $results;
-
-    /**
-     * Configuration loader
-     *
-     * @var \VuFind\Config\PluginManager
-     */
-    protected $configLoader;
-
-    /**
-     * Constructor
-     *
-     * @param \VuFind\Config\PluginManager $configLoader Configuration loader
-     */
-    public function __construct(\VuFind\Config\PluginManager $configLoader)
-    {
-        $this->configLoader = $configLoader;
-    }
-
     /**
      * setConfig
      *
@@ -109,6 +85,9 @@ class TopFacets implements RecommendInterface
             'rows' => $config->Results_Settings->top_rows,
             'cols' => $config->Results_Settings->top_cols
         );
+
+        // Load boolean configurations:
+        $this->loadBooleanConfigs($config, array_keys($this->facets));
     }
 
     /**
@@ -129,36 +108,10 @@ class TopFacets implements RecommendInterface
     {
         // Turn on top facets in the search results:
         foreach ($this->facets as $name => $desc) {
-            $params->addFacet($name, $desc);
+            $params->addFacet($name, $desc, in_array($name, $this->orFacets));
         }
     }
 
-    /**
-     * process
-     *
-     * Called after the Search Results object has performed its main search.  This
-     * may be used to extract necessary information from the Search Results object
-     * or to perform completely unrelated processing.
-     *
-     * @param \VuFind\Search\Base\Results $results Search results object
-     *
-     * @return void
-     */
-    public function process($results)
-    {
-        $this->results = $results;
-    }
-
-    /**
-     * Get results stored in the object.
-     *
-     * @return \VuFind\Search\Base\Results
-     */
-    public function getResults()
-    {
-        return $this->results;
-    }
-
     /**
      * Get facet information taken from the search.
      *
diff --git a/themes/blueprint/templates/Recommend/TopFacets.phtml b/themes/blueprint/templates/Recommend/TopFacets.phtml
index ac4154c9b0b..72d571f612c 100644
--- a/themes/blueprint/templates/Recommend/TopFacets.phtml
+++ b/themes/blueprint/templates/Recommend/TopFacets.phtml
@@ -4,6 +4,7 @@
 ?>
 <? if (isset($topFacetSet)): ?>
   <? foreach($topFacetSet as $title => $cluster): ?>
+    <? $allowExclude = $this->recommend->excludeAllowed($title); ?>
     <div class="authorbox">
       <strong><?=$this->transEsc($cluster['label'])?></strong><?=$this->transEsc("top_facet_suffix") ?>
       <? $iter=1;$corner=$topFacetSettings['rows']*$topFacetSettings['cols']; ?>
@@ -20,7 +21,10 @@
           <? if ($thisFacet['isApplied']): ?>
             <?=$this->escapeHtml($thisFacet['displayText'])?> <img src="<?=$this->imageLink('silk/tick.png')?>" alt="<?=$this->transEsc('Selected') ?>"/>
           <? else: ?>
-            <a href="<?=$this->currentPath().$this->recommend->getResults()->getUrlQuery()->addFacet($title, $thisFacet['value'])?>"><?=$this->escapeHtml($thisFacet['displayText'])?></a> (<?=$thisFacet['count'] ?>)
+            <a href="<?=$this->currentPath().$this->recommend->getResults()->getUrlQuery()->addFacet($title, $thisFacet['value'], $thisFacet['operator'])?>"><?=$this->escapeHtml($thisFacet['displayText'])?></a> (<?=$thisFacet['count'] ?>)
+            <? if ($allowExclude): ?>
+              <a href="<?=$this->currentPath().$results->getUrlQuery()->addFacet($title, $thisFacet['value'], 'NOT')?>"><?=$this->transEsc('exclude_facet')?></a>
+            <? endif; ?>
           <? endif; ?>
         </span>
         <? if (count($cluster['list']) > $corner && $iter == count($cluster['list'])): ?>
-- 
GitLab