diff --git a/config/vufind/Collection.ini b/config/vufind/Collection.ini new file mode 100644 index 0000000000000000000000000000000000000000..b3c833917500d04e0ed252e3ba4cbc2754a85c5a --- /dev/null +++ b/config/vufind/Collection.ini @@ -0,0 +1,10 @@ +; This file controls the Collection module (the page accessed by viewing a record +; which is a collection). + +; These settings control which fields are available to sort on in the Collection +; module. +[Sort] +title = sort_title +year = sort_year +year asc = "sort_year asc" +author = sort_author diff --git a/config/vufind/HierarchyDefault.ini b/config/vufind/HierarchyDefault.ini index c154ab0870a27babff877b48f733a97937d156a1..405be4cee64c6b5ce9352dc70ab69e8c65c3d968 100644 --- a/config/vufind/HierarchyDefault.ini +++ b/config/vufind/HierarchyDefault.ini @@ -1,3 +1,11 @@ +[Collections] +; What determines which records get linked to the Collection module instead of the +; Record module? Legal values: +; All - any record with is_hierarchy set +; Top - any record where is_hierarchy = hierarchy_top +; None - never link to the collection module +link_type = "Top" + [HierarchyTree] ; Are hierarchy trees visible? -- true or false (default false) show = true diff --git a/config/vufind/HierarchyFlat.ini b/config/vufind/HierarchyFlat.ini index fc5161132464a43a229c691594070b636ef9ae46..eb7b46355284df6e556d93d76dda479cfda1be10 100644 --- a/config/vufind/HierarchyFlat.ini +++ b/config/vufind/HierarchyFlat.ini @@ -1,3 +1,11 @@ +[Collections] +; What determines which records get linked to the Collection module instead of the +; Record module? Legal values: +; All - any record with is_hierarchy set +; Top - any record where is_hierarchy = hierarchy_top +; None - never link to the collection module +link_type = "Top" + [HierarchyTree] ; Are hierarchy trees visible? -- true or false (default false) show = false diff --git a/languages/en-gb.ini b/languages/en-gb.ini index 0ccbf7dcc253510757ee478cfb4a5d04b7ca2c10..ad18485e28aa3c2ef43a39646daabef3dc6fb884 100644 --- a/languages/en-gb.ini +++ b/languages/en-gb.ini @@ -83,6 +83,7 @@ Choose a Column to Begin Browsing = "Choose a Column to Begin Browsing" Choose a List = "Choose a List" Cite this = "Cite this" Code = Code +Collection Items = "Collection Items" Collections = Collections Comments = Comments Configuration = "Configuration" @@ -490,6 +491,7 @@ citation_multipage_abbrev = "pp." citation_singlepage_abbrev = "p." citation_volume_abbrev = "Vol." close = close +collection_empty = "No items to display." collection_view_record = "View Record" comment_error_load = "Error: Could Not Redraw Comment List" comment_error_save = "Error: Could Not Save Comment" diff --git a/languages/en.ini b/languages/en.ini index 6ec2bf358632a97b6b2b275b40eca77aeb94873f..165051a4df281ab18031463bf3f9c4f34ded9795 100644 --- a/languages/en.ini +++ b/languages/en.ini @@ -83,6 +83,7 @@ Choose a Column to Begin Browsing = "Choose a Column to Begin Browsing" Choose a List = "Choose a List" Cite this = "Cite this" Code = Code +Collection Items = "Collection Items" Collections = Collections Comments = Comments Configuration = "Configuration" @@ -490,6 +491,7 @@ citation_multipage_abbrev = "pp." citation_singlepage_abbrev = "p." citation_volume_abbrev = "Vol." close = close +collection_empty = "No items to display." collection_view_record = "View Record" comment_error_load = "Error: Could Not Redraw Comment List" comment_error_save = "Error: Could Not Save Comment" diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index a5bf1129687dfbd7f8b3fafc564844cdf923f411..8534f90b03bc93677fb617bb08f66ea64884742d 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -320,6 +320,12 @@ $config = array( 'recordtab_plugin_manager' => array( 'abstract_factories' => array('VuFind\RecordTab\PluginFactory'), 'factories' => array( + 'collectionlist' => function ($sm) { + $searchManager = $sm->getServiceLocator()->get('SearchManager'); + return new \VuFind\RecordTab\CollectionList( + $searchManager->setSearchClassId('SolrCollection')->getResults() + ); + }, 'holdingsils' => function ($sm) { // If VuFind is configured to suppress the holdings tab when the // ILS driver specifies no holdings, we need to pass in a connection diff --git a/module/VuFind/src/VuFind/Controller/CollectionController.php b/module/VuFind/src/VuFind/Controller/CollectionController.php index 3a977cbd7795eaa63f71e5d20d2bad16ea071494..14fff32568f5d8149a0655dd046e9977e214a5e5 100644 --- a/module/VuFind/src/VuFind/Controller/CollectionController.php +++ b/module/VuFind/src/VuFind/Controller/CollectionController.php @@ -57,7 +57,10 @@ class CollectionController extends AbstractRecord protected function getTabConfiguration() { // TODO: fill in - return array(); + return array( + 'VuFind\RecordDriver\AbstractBase' + => array('CollectionList' => 'CollectionList') + ); } /** diff --git a/module/VuFind/src/VuFind/Hierarchy/Driver/ConfigurationBased.php b/module/VuFind/src/VuFind/Hierarchy/Driver/ConfigurationBased.php index b7020e52a017ff75884c9e8cf44c91c3b69ea7d3..7261af65c2287770c1bfa8583c2cd4c70af3e8ae 100644 --- a/module/VuFind/src/VuFind/Hierarchy/Driver/ConfigurationBased.php +++ b/module/VuFind/src/VuFind/Hierarchy/Driver/ConfigurationBased.php @@ -124,4 +124,14 @@ class ConfigurationBased extends AbstractBase return isset($this->config->HierarchyTree) ? $this->config->HierarchyTree->toArray() : array(); } + /** + * Get Collection Link Type from the config file + * + * @return string + */ + public function getCollectionLinkType() + { + return isset($this->config->Collections->link_type) + ? ucwords(strtolower($this->config->Collections->link_type)) : 'All'; + } } \ No newline at end of file diff --git a/module/VuFind/src/VuFind/RecordTab/CollectionList.php b/module/VuFind/src/VuFind/RecordTab/CollectionList.php new file mode 100644 index 0000000000000000000000000000000000000000..045ba180ba0dbb6b5bb5534795885d55fd13a078 --- /dev/null +++ b/module/VuFind/src/VuFind/RecordTab/CollectionList.php @@ -0,0 +1,104 @@ +<?php +/** + * Collection list tab + * + * 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 RecordTabs + * @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/creating_a_session_handler Wiki + */ +namespace VuFind\RecordTab; + +/** + * Collection list tab + * + * @category VuFind2 + * @package RecordTabs + * @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/creating_a_session_handler Wiki + */ +class CollectionList extends AbstractBase +{ + /** + * Search results object + * + * @var \VuFind\Search\SolrCollection\Results + */ + protected $results; + + /** + * Flag indicating whether results have been processed yet + * + * @var bool + */ + protected $processed = false; + + /** + * Constructor + * + * @param \VuFind\Search\SolrCollection\Results $results Search object + */ + public function __construct(\VuFind\Search\SolrCollection\Results $results) + { + $this->results = $results; + } + + /** + * Get the on-screen description for this tab. + * + * @return string + */ + public function getDescription() + { + return 'Collection Items'; + } + + /** + * Get the processed search results. + * + * @return \VuFind\Search\SolrCollection\Results + */ + public function getResults() + { + if (!$this->processed) { + $params = new \Zend\Stdlib\Parameters( + $this->getRequest()->getQuery()->toArray() + + $this->getRequest()->getPost()->toArray() + ); + $this->results->getParams()->initFromRecordDriver( + $this->getRecordDriver(), $params + ); + $this->processed = true; + } + return $this->results; + } + + /** + * Get side recommendations. + * + * @return array + */ + public function getSideRecommendations() + { + return $this->getResults()->getRecommendations('side'); + } +} \ No newline at end of file diff --git a/module/VuFind/src/VuFind/Search/SolrCollection/Options.php b/module/VuFind/src/VuFind/Search/SolrCollection/Options.php new file mode 100644 index 0000000000000000000000000000000000000000..f5d25d712440a933148577a42127de1e93a66ca1 --- /dev/null +++ b/module/VuFind/src/VuFind/Search/SolrCollection/Options.php @@ -0,0 +1,67 @@ +<?php +/** + * Solr Collection aspect of the Search Multi-class (Options) + * + * 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 Search_SolrAuthor + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ +namespace VuFind\Search\SolrCollection; +use VuFind\Config\Reader as ConfigReader; + +/** + * Solr Collection Search Options + * + * @category VuFind2 + * @package Search_SolrAuthor + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ +class Options extends \VuFind\Search\Solr\Options +{ + /** + * Constructor + * + * @return void + */ + public function __construct() + { + parent::__construct(); + + // Load sort preferences (or defaults if none in .ini file): + $searchSettings = ConfigReader::getConfig('Collection'); + if (isset($searchSettings->Sorting)) { + $this->sortOptions = array(); + foreach ($searchSettings->Sorting as $key => $value) { + $this->sortOptions[$key] = $value; + } + } else { + $this->sortOptions = array( + 'title' => 'sort_title', + 'year' => 'sort_year', 'year asc' => 'sort_year asc', + 'author' => 'sort_author' + ); + } + $this->defaultSort = key($this->sortOptions); + } +} \ No newline at end of file diff --git a/module/VuFind/src/VuFind/Search/SolrCollection/Params.php b/module/VuFind/src/VuFind/Search/SolrCollection/Params.php new file mode 100644 index 0000000000000000000000000000000000000000..ec6787958bed59d1d51a9b59880a84449b6a49cc --- /dev/null +++ b/module/VuFind/src/VuFind/Search/SolrCollection/Params.php @@ -0,0 +1,124 @@ +<?php +/** + * Solr Collection aspect of the Search Multi-class (Params) + * + * 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 Search_SolrAuthor + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ +namespace VuFind\Search\SolrCollection; + +/** + * Solr Collection Search Options + * + * @category VuFind2 + * @package Search_SolrAuthor + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ +class Params extends \VuFind\Search\Solr\Params +{ + /** + * The field which defines somehting as being a collection + * this is usually either hierarchy_parent_id or + * hierarchy_top_id + * + * @var string + */ + protected $collectionField = null; + + /** + * The ID of the collection being searched + * + * @var string + */ + protected $collectionID = null; + + /** + * Pull the search parameters from the query and set up additional options using + * a record driver representing a collection. + * + * @param \VuFind\RecordDriver\AbstractBase $driver Record driver + * @param \Zend\StdLib\Parameters $request Parameter object + * representing user request. + * + * @return void + */ + public function initFromRecordDriver($driver, $request) + { + $this->collectionID = $driver->getUniqueID(); + if ($hierarchyDriver = $driver->getHierarchyDriver()) { + switch ($hierarchyDriver->getCollectionLinkType()) { + case 'All': + $this->collectionField = 'hierarchy_parent_id'; + break; + case 'Top': + $this->collectionField = 'hierarchy_top_id'; + break; + } + } + $this->initFromRequest($request); + } + + /** + * Pull the search parameters + * + * @param \Zend\StdLib\Parameters $request Parameter object representing user + * request. + * + * @return void + */ + public function initFromRequest($request) + { + if (null === $this->collectionID) { + throw new \Exception('Collection ID missing'); + } + if (null === $this->collectionField) { + throw new \Exception('Collection field missing'); + } + parent::initFromRequest($request); + + // We don't spellcheck this screen; it's not for free user input anyway + $options = $this->getOptions(); + $options->spellcheckEnabled(false); + + // Prepare the search + $options + ->addHiddenFilter($this->collectionField . ":" . $this->collectionID); + $options->addHiddenFilter("!id:" . $this->collectionID); + } + + /** + * Load all recommendation settings from the relevant ini file. Returns an + * associative array where the key is the location of the recommendations (top + * or side) and the value is the settings found in the file (which may be either + * a single string or an array of strings). + * + * @return array associative: location (top/side) => search settings + */ + protected function getRecommendationSettings() + { + // Disabled for now + return array(); + } +} \ No newline at end of file diff --git a/module/VuFind/src/VuFind/Search/SolrCollection/Results.php b/module/VuFind/src/VuFind/Search/SolrCollection/Results.php new file mode 100644 index 0000000000000000000000000000000000000000..f54f45e051a77e04831210d2972390f2f857cead --- /dev/null +++ b/module/VuFind/src/VuFind/Search/SolrCollection/Results.php @@ -0,0 +1,42 @@ +<?php +/** + * Solr Collection aspect of the Search Multi-class (Results) + * + * 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 Search_SolrAuthor + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ +namespace VuFind\Search\SolrCollection; + +/** + * Solr Collection Search Options + * + * @category VuFind2 + * @package Search_SolrAuthor + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ + +class Results extends \VuFind\Search\Solr\Results +{ +} \ No newline at end of file diff --git a/themes/blueprint/css/styles.css b/themes/blueprint/css/styles.css index 601dbb855e805240f07bf013f806454c3342b569..32fdf39f6e5d315891a411e1f48ae642f45596f0 100644 --- a/themes/blueprint/css/styles.css +++ b/themes/blueprint/css/styles.css @@ -1451,6 +1451,72 @@ tr:nth-child(even) td.gridMouseOver { display: none; } +/************************* COLLECTIONS PAGE ************************/ +.collectionDetails { + background-color: #FFF; + padding:20px 1em 1em 1em; + border: 2px solid #EEEEEE; + margin-top: -2px; + margin-bottom: 20px; +} + +.collectionDetails form { + border: 1px solid #EEEEEE; +} + +.collectionDetails .sortSelector { + border: 0px solid #FFF; + float: right; +} + +.collectionDetails li.result { + background-color: #EEEEEE; + margin-bottom: 0px; +} + +.collectionDetails li.result.alt { + background-color: #FFF; + margin-bottom: 0px; +} + +.collectionDetails .pagination span { + border: 1px solid #EEEEEE; + padding-left: 4px; + padding-right: 4px; +} + +.collectionDetails .paginationTop .pagination { + text-align: center; + margin-top: 5px; + margin-bottom: 8px; + padding-bottom: 0; + padding-top: 0; +} + +.collectionDetails .paginationTop .pagination span { + border: 1px solid #EEEEEE; + font-weight: bold; + padding-left: 4px; + padding-right: 4px; + margin-left: 3px; +} + +.collectionDetails .paginationTop .pagination a:hover { + border: 1px solid #EEEEEE; +} + +.collectionDetails .paginationTop .pagination a { + border: 1px solid #FFF; + padding-left: 4px; + padding-right: 4px; + margin-left: 3px; +} + +.collectionDetails .viewButtons { + float:right; + margin-right:10px; +} + /* Rss Recommendations */ div.suggestionHeader { min-height:30px; diff --git a/themes/blueprint/templates/RecordTab/collectionlist.phtml b/themes/blueprint/templates/RecordTab/collectionlist.phtml new file mode 100644 index 0000000000000000000000000000000000000000..b22e65a1fdb1eac0a3fec3fc65a749854150dc48 --- /dev/null +++ b/themes/blueprint/templates/RecordTab/collectionlist.phtml @@ -0,0 +1,31 @@ +<? + // Set page title. + $this->headTitle($this->translate('Collection Items') . ': ' . $this->driver->getBreadcrumb()); + + // Get search results + $results = $this->tab->getResults(); +?> +<? if (($recordTotal = $results->getResultTotal()) > 0): // only display these at very top if we have results ?> + <? foreach ($results->getRecommendations('top') as $current): ?> + <?=$this->recommend($current)?> + <? endforeach; ?> + <?=$this->transEsc("Showing")?> + <strong><?=$results->getStartRecord()?></strong> - <strong><?=$results->getEndRecord()?></strong> + <? if (!isset($this->skipTotalCount)): ?> + <?=$this->transEsc('of')?> <strong><?=$recordTotal?></strong> <?=$this->transEsc('Items')?> + <? endif; ?> + <?=$this->render('search/controls/sort.phtml', array('results' => $results))?> + <?=$this->render('search/controls/view.phtml', array('results' => $results))?> + <div class="paginationTop"> + <?=$this->paginationControl($results->getPaginator(), 'Sliding', 'search/pagination.phtml', array('results' => $results))?> + </div> + <div class="clearer"></div> + <form method="post" name="bulkActionForm" action="<?=$this->url('cart-home')?>"> + <?=$this->context($this)->renderInContext('search/bulk-action-buttons.phtml', array('results' => $results, 'idPrefix' => ''))?> + <?=$this->render('search/list-' . $results->getParams()->getView() . '.phtml', array('results' => $results))?> + <?=$this->context($this)->renderInContext('search/bulk-action-buttons.phtml', array('results' => $results, 'idPrefix' => 'bottom_'))?> + <?=$this->paginationControl($results->getPaginator(), 'Sliding', 'search/pagination.phtml', array('results' => $results))?> + </form> +<? else: ?> + <?=$this->transEsc('collection_empty')?> +<? endif; ?> diff --git a/themes/blueprint/templates/collection/view.phtml b/themes/blueprint/templates/collection/view.phtml index 4f0ea3f756474ccf1d11e6919e813790bca06e0f..28b4f3cc1e8748c2a3cf6cc94d36fbdd954ae939 100644 --- a/themes/blueprint/templates/collection/view.phtml +++ b/themes/blueprint/templates/collection/view.phtml @@ -50,7 +50,7 @@ <? endif; ?> - <div class="recordsubcontent"> + <div class="collectionDetails"> <?=isset($activeTabObj) ? $this->record($this->driver)->getTab($activeTabObj) : '' ?> </div> @@ -58,9 +58,11 @@ </div> <div class="<?=$this->layoutClass('sidebar')?>"> - <? foreach ($this->driver->getRelated() as $current): ?> - <?=$this->related($current)?> - <? endforeach; ?> + <? if (is_callable(array($activeTabObj, 'getSideRecommendations'))): ?> + <? foreach ($activeTabObj->getSideRecommendations() as $current): ?> + <?=$this->recommend($current)?> + <? endforeach; ?> + <? endif; ?> </div> <div class="clear"></div> diff --git a/themes/jquerymobile/templates/RecordTab/collectionlist.phtml b/themes/jquerymobile/templates/RecordTab/collectionlist.phtml new file mode 100644 index 0000000000000000000000000000000000000000..1cc8ffa7531bd0c67b1d858d654c5712a6e1e4c5 --- /dev/null +++ b/themes/jquerymobile/templates/RecordTab/collectionlist.phtml @@ -0,0 +1,18 @@ +<? + // Set page title. + $this->headTitle($this->translate('Collection Items') . ': ' . $this->driver->getBreadcrumb()); + + // Get search results + $results = $this->tab->getResults(); +?> +<? if (($recordTotal = $results->getResultTotal()) > 0): // only display these at very top if we have results ?> + <p> + <?=$this->transEsc("Showing")?> + <strong><?=$results->getStartRecord()?></strong> - <strong><?=$results->getEndRecord()?></strong> + <?=$this->transEsc('of')?> <strong><?=$recordTotal?></strong> <?=$this->transEsc('Items')?> + </p> + <?=$this->render('search/list-' . $results->getParams()->getView() . '.phtml', array('results' => $results))?> + <?=$this->paginationControl($results->getPaginator(), 'Sliding', 'search/pagination.phtml', array('results' => $results))?> +<? else: ?> + <?=$this->transEsc('collection_empty')?> +<? endif; ?> diff --git a/themes/jquerymobile/templates/collection/view.phtml b/themes/jquerymobile/templates/collection/view.phtml index 0a785bcfa63eadb195ef9bf698fa075ecc2d2732..fd920a320721bafa619e84cc105368847b9536ea 100644 --- a/themes/jquerymobile/templates/collection/view.phtml +++ b/themes/jquerymobile/templates/collection/view.phtml @@ -10,7 +10,7 @@ $tab = $activeTab ? $this->record($this->driver)->getTab($this->tabs[$activeTab]) : ''; ?> <div data-role="page" id="Record-view"> - <?=$this->mobileMenu()->header(array('searchLink' => $this->searchOptions($this->searchClassId)->getSearchHomeAction()))?> + <?=$this->mobileMenu()->header()?> <div class="record" data-role="content" data-record-id="<?=$this->escapeHtml($this->driver->getUniqueId())?>"> <?=$this->flashmessages()?> <? if ($this->activeTab == $this->defaultTab): ?>