From f916dba5ee95be21b1b506ccc663fdaf2b3af234 Mon Sep 17 00:00:00 2001 From: Demian Katz <demian.katz@villanova.edu> Date: Wed, 10 Jul 2013 11:46:28 -0400 Subject: [PATCH] Created mechanism for combined handler drop-down. Resolves VUFIND-843. --- config/vufind/searchbox.ini | 25 ++++ module/VuFind/config/module.config.php | 2 +- .../VuFind/Controller/CombinedController.php | 34 +++++ .../src/VuFind/View/Helper/Root/SearchBox.php | 116 +++++++++++++++++- .../templates/search/searchbox.phtml | 11 +- .../templates/search/searchbox.phtml | 11 +- themes/root/theme.config.php | 6 +- 7 files changed, 190 insertions(+), 15 deletions(-) create mode 100644 config/vufind/searchbox.ini diff --git a/config/vufind/searchbox.ini b/config/vufind/searchbox.ini new file mode 100644 index 00000000000..365da2ad6e1 --- /dev/null +++ b/config/vufind/searchbox.ini @@ -0,0 +1,25 @@ +; This file controls VuFind's search box + +[General] +; Set this to true in order to use a combined search handler drop-down as specified +; in the [CombinedHandlers] section below. +combinedHandlers = false + +; This section controls the "combined handlers" drop-down. It must contain groups +; of settings with the following keys: +; +; type[] = "VuFind" for an internal search module or "External" for an external URL +; target[] = Search class ID for "VuFind" type, URL for "External" type +; label[] = Label for this value (subject to translation) +[CombinedHandlers] +type[] = VuFind +target[] = Solr +label[] = Catalog + +type[] = VuFind +target[] = Summon +label[] = Summon + +type[] = External +target[] = "http://www.google.com/search?q=" +label[] = Google diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index 1143b64b82c..846c537fbca 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -974,7 +974,7 @@ $staticRoutes = array( 'Browse/LCC', 'Browse/Region', 'Browse/Tag', 'Browse/Topic', 'Cart/doExport', 'Cart/Email', 'Cart/Export', 'Cart/Home', 'Cart/MyResearchBulk', 'Cart/Save', 'Collections/ByTitle', 'Collections/Home', - 'Combined/Home', 'Combined/Results', 'Confirm/Confirm', + 'Combined/Home', 'Combined/Results', 'Combined/SearchBox', 'Confirm/Confirm', 'Cover/Show', 'Cover/Unavailable', 'Error/Unavailable', 'Feedback/Email', 'Feedback/Home', 'Help/Home', 'Install/Done', 'Install/FixBasicConfig', 'Install/FixCache', diff --git a/module/VuFind/src/VuFind/Controller/CombinedController.php b/module/VuFind/src/VuFind/Controller/CombinedController.php index 502c4d05303..bade60b4624 100644 --- a/module/VuFind/src/VuFind/Controller/CombinedController.php +++ b/module/VuFind/src/VuFind/Controller/CombinedController.php @@ -137,4 +137,38 @@ class CombinedController extends AbstractSearch ) ); } + + /** + * Action to process the combined search box. + * + * @return mixed + */ + public function searchboxAction() + { + list($type, $target) = explode(':', $this->params()->fromQuery('type'), 2); + switch ($type) { + case 'VuFind': + list($searchClassId, $type) = explode('|', $target); + $params = $this->getRequest()->getQuery()->toArray(); + $params['type'] = $type; + + // Disable retained filters if we are switching classes! + $activeClass = $this->params()->fromQuery('activeSearchClassId'); + if ($activeClass != $searchClassId) { + unset($params['filter']); + } + unset($params['activeSearchClassId']); // don't need to pass this forward + + $route = $this->getServiceLocator() + ->get('VuFind\SearchOptionsPluginManager') + ->get($searchClassId)->getSearchAction(); + $options = array('query' => $params); + return $this->redirect()->toRoute($route, array(), $options); + case 'External': + $lookfor = $this->params()->fromQuery('lookfor'); + return $this->redirect()->toUrl($target . urlencode($lookfor)); + default: + throw new \Exception('Unexpected search type.'); + } + } } diff --git a/module/VuFind/src/VuFind/View/Helper/Root/SearchBox.php b/module/VuFind/src/VuFind/View/Helper/Root/SearchBox.php index 963de2aa61e..6d6d88887d9 100644 --- a/module/VuFind/src/VuFind/View/Helper/Root/SearchBox.php +++ b/module/VuFind/src/VuFind/View/Helper/Root/SearchBox.php @@ -26,6 +26,7 @@ * @link http://vufind.org/wiki/vufind2:developer_manual Wiki */ namespace VuFind\View\Helper\Root; +use VuFind\Search\Options\PluginManager as OptionsManager; /** * Search box view helper @@ -38,6 +39,43 @@ namespace VuFind\View\Helper\Root; */ class SearchBox extends \Zend\View\Helper\AbstractHelper { + /** + * Configuration for search box. + * + * @var array + */ + protected $config; + + /** + * Search options plugin manager + * + * @var OptionsManager + */ + protected $optionsManager; + + /** + * Constructor + * + * @param OptionsManager $optionsManager Search options plugin manager + * @param array $config Configuration for search box + */ + public function __construct(OptionsManager $optionsManager, $config = array()) + { + $this->optionsManager = $optionsManager; + $this->config = $config; + } + + /** + * Are combined handlers enabled? + * + * @return bool + */ + public function combinedHandlersActive() + { + return isset($this->config['General']['combinedHandlers']) + && $this->config['General']['combinedHandlers']; + } + /** * Get an array of filter information for use by the "retain filters" feature * of the search box. Returns an array of arrays with 'id' and 'value' keys used @@ -74,24 +112,92 @@ class SearchBox extends \Zend\View\Helper\AbstractHelper /** * Get an array of information on search handlers for use in generating a - * drop-down or hidden field. Returns an array of arrays with 'value', 'label' - * and 'selected' keys. + * drop-down or hidden field. Returns an array of arrays with 'value', 'label', + * 'indent' and 'selected' keys. * * @param string $activeSearchClass Active search class ID * @param string $activeHandler Active search handler - * @param \VuFind\Search\Base\Options $options Current search options * * @return array */ - public function getHandlers($activeSearchClass, $activeHandler, $options) + public function getHandlers($activeSearchClass, $activeHandler) + { + return $this->combinedHandlersActive() + ? $this->getCombinedHandlers($activeSearchClass, $activeHandler) + : $this->getBasicHandlers($activeSearchClass, $activeHandler); + } + + /** + * Support method for getHandlers() -- load basic settings. + * + * @param string $activeSearchClass Active search class ID + * @param string $activeHandler Active search handler + * + * @return array + */ + protected function getBasicHandlers($activeSearchClass, $activeHandler) { $handlers = array(); + $options = $this->optionsManager->get($activeSearchClass); foreach ($options->getBasicHandlers() as $searchVal => $searchDesc) { $handlers[] = array( - 'value' => $searchVal, 'label' => $searchDesc, + 'value' => $searchVal, 'label' => $searchDesc, 'indent' => false, 'selected' => ($activeHandler == $searchVal) ); } return $handlers; } + + /** + * Support method for getHandlers() -- load combined settings. + * + * @param string $activeSearchClass Active search class ID + * @param string $activeHandler Active search handler + * + * @return array + */ + protected function getCombinedHandlers($activeSearchClass, $activeHandler) + { + // Load and validate configuration: + $settings = isset($this->config['CombinedHandlers']) + ? $this->config['CombinedHandlers'] : array(); + if (empty($settings)) { + throw new \Exception('CombinedHandlers configuration missing.'); + } + $typeCount = count($settings['type']); + if ($typeCount != count($settings['target']) + || $typeCount != count($settings['label']) + ) { + throw new \Exception('CombinedHandlers configuration incomplete.'); + } + + // Build settings: + $handlers = array(); + for ($i = 0; $i < $typeCount; $i++) { + $type = $settings['type'][$i]; + $target = $settings['target'][$i]; + $label = $settings['label'][$i]; + + if ($type == 'VuFind') { + $options = $this->optionsManager->get($target); + $j = 0; + foreach ($options->getBasicHandlers() as $searchVal => $searchDesc) { + $j++; + $handlers[] = array( + 'value' => $type . ':' . $target . '|' . $searchVal, + 'label' => $j == 1 ? $label : $searchDesc, + 'indent' => $j == 1 ? false : true, + 'selected' => $target == $activeSearchClass + && $activeHandler == $searchVal + ); + } + } else if ($type == 'External') { + $handlers[] = array( + 'value' => $type . ':' . $target, 'label' => $label, + 'indent' => false, 'selected' => false + ); + } + } + return $handlers; + } } \ No newline at end of file diff --git a/themes/blueprint/templates/search/searchbox.phtml b/themes/blueprint/templates/search/searchbox.phtml index be08e4057a4..199232cf4a8 100644 --- a/themes/blueprint/templates/search/searchbox.phtml +++ b/themes/blueprint/templates/search/searchbox.phtml @@ -8,11 +8,10 @@ $options = $this->searchOptions($this->searchClassId); $handlers = $this->searchbox()->getHandlers( $this->searchClassId, - isset($this->searchIndex) ? $this->searchIndex : null, - $options + isset($this->searchIndex) ? $this->searchIndex : null ); $handlerCount = count($handlers); - $basicSearch = $options->getSearchAction(); + $basicSearch = $this->searchbox()->combinedHandlersActive() ? 'combined-searchbox' : $options->getSearchAction(); $searchHome = $options->getSearchHomeAction(); $advSearch = $options->getAdvancedSearchAction(); $lastSort = $options->getLastSort(); @@ -50,7 +49,7 @@ <? if ($handlerCount > 1): ?> <select id="searchForm_type" name="type" data-native-menu="false"> <? foreach ($handlers as $handler): ?> - <option value="<?=$this->escapeHtml($handler['value'])?>"<?=$handler['selected'] ? ' selected="selected"' : ''?>><?=$this->transEsc($handler['label'])?></option> + <option value="<?=$this->escapeHtml($handler['value'])?>"<?=$handler['selected'] ? ' selected="selected"' : ''?>><?=$handler['indent'] ? '-- ' : ''?><?=$this->transEsc($handler['label'])?></option> <? endforeach; ?> </select> <? elseif ($handlerCount == 1): ?> @@ -91,6 +90,10 @@ </div> <? endif; ?> <? + /* Show hidden field for active search class when in combined handler mode. */ + if ($this->searchbox()->combinedHandlersActive()) { + echo '<input type="hidden" name="activeSearchClassId" value="' . $this->escapeHtml($this->searchClassId) . '" />'; + } /* Load hidden limit preference from Session */ if (!empty($lastLimit)) { echo '<input type="hidden" name="limit" value="' . $this->escapeHtml($lastLimit) . '" />'; diff --git a/themes/jquerymobile/templates/search/searchbox.phtml b/themes/jquerymobile/templates/search/searchbox.phtml index efd8113dab8..875741a7b40 100644 --- a/themes/jquerymobile/templates/search/searchbox.phtml +++ b/themes/jquerymobile/templates/search/searchbox.phtml @@ -8,11 +8,10 @@ $options = $this->searchOptions($this->searchClassId); $handlers = $this->searchbox()->getHandlers( $this->searchClassId, - isset($this->searchIndex) ? $this->searchIndex : null, - $options + isset($this->searchIndex) ? $this->searchIndex : null ); $handlerCount = count($handlers); - $basicSearch = $options->getSearchAction(); + $basicSearch = $this->searchbox()->combinedHandlersActive() ? 'combined-searchbox' : $options->getSearchAction(); $lastSort = $options->getLastSort(); $lastLimit = $options->getLastLimit(); ?> @@ -26,7 +25,7 @@ <? if ($handlerCount > 1): ?> <select id="searchForm_type" name="type" data-native-menu="false"> <? foreach ($handlers as $handler): ?> - <option value="<?=$this->escapeHtml($handler['value'])?>"<?=$handler['selected'] ? ' selected="selected"' : ''?>><?=$this->transEsc($handler['label'])?></option> + <option value="<?=$this->escapeHtml($handler['value'])?>"<?=$handler['selected'] ? ' selected="selected"' : ''?>><?=$handler['indent'] ? '-- ' : ''?><?=$this->transEsc($handler['label'])?></option> <? endforeach; ?> </select> <? elseif ($handlerCount == 1): ?> @@ -36,6 +35,10 @@ <input type="submit" data-theme="b" name="submit" value="<?=$this->transEsc("Find")?>"/> </div> <? + /* Show hidden field for active search class when in combined handler mode. */ + if ($this->searchbox()->combinedHandlersActive()) { + echo '<input type="hidden" name="activeSearchClassId" value="' . $this->escapeHtml($this->searchClassId) . '" />'; + } /* Load hidden limit preference from Session */ if (!empty($lastLimit)) { echo '<input type="hidden" name="limit" value="' . $this->escapeHtml($lastLimit) . '" />'; diff --git a/themes/root/theme.config.php b/themes/root/theme.config.php index 101cfca5b49..8f705fdf906 100644 --- a/themes/root/theme.config.php +++ b/themes/root/theme.config.php @@ -104,7 +104,11 @@ return array( ); }, 'searchbox' => function ($sm) { - return new \VuFind\View\Helper\Root\SearchBox(); + $config = $sm->getServiceLocator()->get('VuFind\Config')->get('searchbox')->toArray(); + return new \VuFind\View\Helper\Root\SearchBox( + $sm->getServiceLocator()->get('VuFind\SearchOptionsPluginManager'), + $config + ); }, 'searchoptions' => function ($sm) { return new VuFind\View\Helper\Root\SearchOptions( -- GitLab