From 3fa240535cf32c3a5c46aa011824589a532de310 Mon Sep 17 00:00:00 2001 From: Ere Maijala <ere.maijala@helsinki.fi> Date: Mon, 22 Dec 2014 13:57:31 -0500 Subject: [PATCH] Implemented support for simple container-child record links using the hierarchy fields. --- config/vufind/config.ini | 5 ++ config/vufind/searchspecs.yaml | 9 ++- languages/en.ini | 2 + languages/fi.ini | 2 + languages/sv.ini | 2 + .../src/VuFind/RecordDriver/Factory.php | 5 +- .../src/VuFind/RecordDriver/SolrDefault.php | 71 ++++++++++++++++++- .../VuFind/View/Helper/Root/RecordLink.php | 19 +++++ .../RecordDriver/SolrDefault/core.phtml | 12 +++- .../SolrDefault/result-list.phtml | 11 +-- .../RecordDriver/SolrDefault/core.phtml | 14 +++- .../SolrDefault/result-list.phtml | 5 +- .../RecordDriver/SolrDefault/core.phtml | 10 ++- 13 files changed, 151 insertions(+), 16 deletions(-) diff --git a/config/vufind/config.ini b/config/vufind/config.ini index 67bbc079cc8..13a82d190a4 100644 --- a/config/vufind/config.ini +++ b/config/vufind/config.ini @@ -1096,6 +1096,11 @@ search = true ; results can cause performance problems. If treeSearchLimit is -1 or not set, ; results will be unlimited. treeSearchLimit = 100 +; Whether hierarchy fields are used for linking between container records and their +; children (default = false). This is an alternative to the full collections support +; (see the [Collections] section), so only one of them should be enabled +; at a time e.g. unless custom record drivers are used. +;simpleContainerLinks = true ; This section will be used to configure the feedback module. ; Set "tab_enabled" to true in order to enable the feedback module. diff --git a/config/vufind/searchspecs.yaml b/config/vufind/searchspecs.yaml index d139ad91665..e44e42f5c55 100644 --- a/config/vufind/searchspecs.yaml +++ b/config/vufind/searchspecs.yaml @@ -56,8 +56,8 @@ # QueryFields: ... # # All the same settings as above, but for exact searches, i.e. search terms # # enclosed in quotes. Allows different fields or weights for exact -# # searches. See below for commented-out examples. -# +# # searches. See below for commented-out examples. +# # ...etc. # #----------------------------------------------------------------------------------- @@ -444,6 +444,11 @@ id: id: - [onephrase, ~] +ParentID: + QueryFields: + hierarchy_parent_id: + - [onephrase, ~] + # Fields for exact matches originating from alphabetic browse ids: QueryFields: diff --git a/languages/en.ini b/languages/en.ini index 191e30a4ba3..afcd5f34522 100644 --- a/languages/en.ini +++ b/languages/en.ini @@ -166,6 +166,8 @@ Checked Out = "Checked Out" Checked Out Items = "Checked Out Items" Checkedout = "Checked Out" Chicago Citation = "Chicago Style Citation" +child_record_count = "%%count%% records" +child_records = "Contents/pieces" Choose a Category to Begin Browsing = "Choose a Category to Begin Browsing" Choose a Column to Begin Browsing = "Choose a Column to Begin Browsing" Choose a List = "Choose a List" diff --git a/languages/fi.ini b/languages/fi.ini index ec85afeec15..932aa5f6477 100644 --- a/languages/fi.ini +++ b/languages/fi.ini @@ -161,6 +161,8 @@ Checked Out = "Lainattu" Checked Out Items = "Lainat" Checkedout = "Lainat" Chicago Citation = "Chicago-tyylinen lähdeviittaus" +child_record_count = "%%count%% tietuetta" +child_records = "Sisältö/kappaleet" Choose a Category to Begin Browsing = "Valitse kategoria aloittaaksesi selauksen" Choose a Column to Begin Browsing = "Valitse sarake aloittaaksesi selaamisen" Choose a List = "Valitse lista" diff --git a/languages/sv.ini b/languages/sv.ini index e816f7e7fde..0f56f95b07b 100644 --- a/languages/sv.ini +++ b/languages/sv.ini @@ -161,6 +161,8 @@ Checked Out = "Utlånad" Checked Out Items = "Utlånade exemplar" Checkedout = "Utlånade exemplar" Chicago Citation = "Chicago-stil citat" +child_record_count = "%%count%% poster" +child_records = "Innehåll/delar" Choose a Category to Begin Browsing = "Choose a Category to Begin Browsing" Choose a Column to Begin Browsing = "Välj en kolumn för att börja bläddra" Choose a List = "Välj en lista" diff --git a/module/VuFind/src/VuFind/RecordDriver/Factory.php b/module/VuFind/src/VuFind/RecordDriver/Factory.php index f16ffe51c4a..5cb0e78f792 100644 --- a/module/VuFind/src/VuFind/RecordDriver/Factory.php +++ b/module/VuFind/src/VuFind/RecordDriver/Factory.php @@ -141,11 +141,13 @@ class Factory */ public static function getSolrDefault(ServiceManager $sm) { - return new SolrDefault( + $driver = new SolrDefault( $sm->getServiceLocator()->get('VuFind\Config')->get('config'), null, $sm->getServiceLocator()->get('VuFind\Config')->get('searches') ); + $driver->attachSearchService($sm->getServiceLocator()->get('VuFind\Search')); + return $driver; } /** @@ -167,6 +169,7 @@ class Factory $sm->getServiceLocator()->get('VuFind\ILSHoldLogic'), $sm->getServiceLocator()->get('VuFind\ILSTitleHoldLogic') ); + $driver->attachSearchService($sm->getServiceLocator()->get('VuFind\Search')); return $driver; } diff --git a/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php b/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php index 65380c3da88..fa4a88e37fd 100644 --- a/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php +++ b/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php @@ -111,6 +111,20 @@ class SolrDefault extends AbstractBase */ protected $highlightDetails = array(); + /** + * Search results plugin manager + * + * @var \VuFindSearch\Service + */ + protected $searchService = null; + + /** + * Should we use hierarchy fields for simple container-child records linking? + * + * @var bool + */ + protected $containerLinking = false; + /** * Constructor * @@ -137,6 +151,12 @@ class SolrDefault extends AbstractBase $this->snippetCaptions[$key] = $value; } } + + // Container-contents linking + $this->containerLinking + = !isset($mainConfig->Hierarchy->simpleContainerLinks) + ? false : $mainConfig->Hierarchy->simpleContainerLinks; + parent::__construct($mainConfig, $recordConfig); } @@ -1307,8 +1327,7 @@ class SolrDefault extends AbstractBase } /** - * Get the absolute parent title(s) associated with this item - * (empty if none). + * Get the absolute parent title(s) associated with this item (empty if none). * * @return array */ @@ -1745,4 +1764,52 @@ class SolrDefault extends AbstractBase ? $this->fields['dedup_data'] : array(); } + + /** + * Attach a Search Results Plugin Manager connection and related logic to + * the driver + * + * @param \VuFindSearch\Service $service Search Service Manager + * + * @return void + */ + public function attachSearchService(\VuFindSearch\Service $service) + { + $this->searchService = $service; + } + + /** + * Get the number of child records belonging to this record + * + * @return int Number of records + */ + public function getChildRecordCount() + { + // Shortcut: if this record is not the top record, let's not find out the + // count. This assumes that contained records cannot contain more records. + if (!$this->containerLinking + || empty($this->fields['is_hierarchy_id']) + || null === $this->searchService + ) { + return 0; + } + + $safeId = addcslashes($this->fields['is_hierarchy_id'], '"'); + $query = new \VuFindSearch\Query\Query( + 'hierarchy_parent_id:"' . $safeId . '"' + ); + return $this->searchService->search('Solr', $query, 0, 0)->getTotal(); + } + + /** + * Get the container record id. + * + * @return string Container record id (empty string if none) + */ + public function getContainerRecordID() + { + return $this->containerLinking + && !empty($this->fields['hierarchy_parent_id']) + ? $this->fields['hierarchy_parent_id'][0] : ''; + } } diff --git a/module/VuFind/src/VuFind/View/Helper/Root/RecordLink.php b/module/VuFind/src/VuFind/View/Helper/Root/RecordLink.php index fe41b07847d..33b387834d2 100644 --- a/module/VuFind/src/VuFind/View/Helper/Root/RecordLink.php +++ b/module/VuFind/src/VuFind/View/Helper/Root/RecordLink.php @@ -218,4 +218,23 @@ class RecordLink extends \Zend\View\Helper\AbstractHelper $escapeHelper($truncateHelper($driver->getBreadcrumb(), 30)) . '</a>'; } + + /** + * Given a record driver, generate a URL to fetch all child records for it. + * + * @param \VuFind\RecordDriver\AbstractBase $driver Host Record. + * + * @return string + */ + public function getChildRecordSearchUrl($driver) + { + $urlHelper = $this->getView()->plugin('url'); + $url = $urlHelper('search-results') + . '?lookfor=' + . urlencode(addcslashes($driver->getUniqueID(), '"')) + . '&type=ParentID'; + // Make sure everything is properly HTML encoded: + $escaper = $this->getView()->plugin('escapehtml'); + return $escaper($url); + } } \ No newline at end of file diff --git a/themes/blueprint/templates/RecordDriver/SolrDefault/core.phtml b/themes/blueprint/templates/RecordDriver/SolrDefault/core.phtml index 8cffef3f4d1..950d451954c 100644 --- a/themes/blueprint/templates/RecordDriver/SolrDefault/core.phtml +++ b/themes/blueprint/templates/RecordDriver/SolrDefault/core.phtml @@ -13,9 +13,10 @@ <table cellpadding="2" cellspacing="0" border="0" class="citation" summary="<?=$this->transEsc('Bibliographic Details')?>"> <? $journalTitle = $this->driver->getContainerTitle(); if (!empty($journalTitle)): ?> <tr valign="top"> - <th><?=$this->transEsc('Journal Title')?>:</th> + <th><?=$this->transEsc('Published in')?>:</th> <td> - <a href="<?=$this->record($this->driver)->getLink('journaltitle', $journalTitle)?>"><?=$this->escapeHtml($journalTitle)?></a> + <? $containerID = $this->driver->getContainerRecordID(); ?> + <a href="<?=($containerID ? $this->recordLink()->getUrl("VuFind|$containerID") : $this->record($this->driver)->getLink('journaltitle', $journalTitle))?>"><?=$this->escapeHtml($journalTitle)?></a> <? $ref = $this->driver->getContainerReference(); if (!empty($ref)) { echo $this->escapeHtml($ref); } ?> </td> </tr> @@ -154,6 +155,13 @@ </tr> <? endif; ?> + <? $childRecordCount = $this->driver->tryMethod('getChildRecordCount'); if ($childRecordCount): ?> + <tr valign="top"> + <th><?=$this->transEsc('child_records')?>: </th> + <td><a href="<?=$this->recordLink()->getChildRecordSearchUrl($this->driver)?>"><?=$this->transEsc('child_record_count', array('%%count%%' => $childRecordCount))?></a></td> + </tr> + <? endif; ?> + <? $openUrl = $this->driver->openURLActive('record') ? $this->driver->getOpenURL() : false; // Account for replace_other_urls setting diff --git a/themes/blueprint/templates/RecordDriver/SolrDefault/result-list.phtml b/themes/blueprint/templates/RecordDriver/SolrDefault/result-list.phtml index 7a6126e06ad..2d472ca0611 100644 --- a/themes/blueprint/templates/RecordDriver/SolrDefault/result-list.phtml +++ b/themes/blueprint/templates/RecordDriver/SolrDefault/result-list.phtml @@ -38,7 +38,10 @@ <? $journalTitle = $this->driver->getContainerTitle(); $summDate = $this->driver->getPublicationDates(); ?> <? if (!empty($journalTitle)): ?> <?=!empty($summAuthor) ? '<br />' : ''?> - <?=/* TODO: handle highlighting more elegantly here */ $this->transEsc('Published in') . ' <a href="' . $this->record($this->driver)->getLink('journaltitle', str_replace(array('{{{{START_HILITE}}}}', '{{{{END_HILITE}}}}'), '', $journalTitle)) . '">' . $this->highlight($journalTitle) . '</a>';?> + <?=$this->transEsc('Published in')?> + <? $containerID = $this->driver->getContainerRecordID(); ?> + <? /* TODO: handle highlighting more elegantly here: */?> + <a href="<?=($containerID ? $this->recordLink()->getUrl("VuFind|$containerID") : $this->record($this->driver)->getLink('journaltitle', str_replace(array('{{{{START_HILITE}}}}', '{{{{END_HILITE}}}}'), '', $journalTitle)))?>"><?=$this->highlight($journalTitle) ?></a> <?=!empty($summDate) ? ' (' . $this->escapeHtml($summDate[0]) . ')' : ''?> <? elseif (!empty($summDate)): ?> <?=!empty($summAuthor) ? '<br />' : ''?> @@ -70,7 +73,7 @@ <? /* Display information on duplicate records if available */ $dedupData = $this->driver->getDedupData(); - if ($dedupData): ?> + if ($dedupData): ?> <div class="dedupInformation"> <? $i = 0; @@ -91,8 +94,8 @@ }?> </div> <? endif; ?> - - + + <div class="callnumAndLocation"> <? if ($this->driver->supportsAjaxStatus()): ?> <strong class="hideIfDetailed"><?=$this->transEsc('Call Number')?>:</strong> diff --git a/themes/bootstrap3/templates/RecordDriver/SolrDefault/core.phtml b/themes/bootstrap3/templates/RecordDriver/SolrDefault/core.phtml index e0f675a3b47..a855698b5cd 100644 --- a/themes/bootstrap3/templates/RecordDriver/SolrDefault/core.phtml +++ b/themes/bootstrap3/templates/RecordDriver/SolrDefault/core.phtml @@ -50,9 +50,10 @@ <table class="table table-striped" summary="<?=$this->transEsc('Bibliographic Details')?>"> <? $journalTitle = $this->driver->getContainerTitle(); if (!empty($journalTitle)): ?> <tr> - <th><?=$this->transEsc('Journal Title')?>:</th> + <th><?=$this->transEsc('Published in')?>:</th> <td> - <a href="<?=$this->record($this->driver)->getLink('journaltitle', $journalTitle)?>"><?=$this->escapeHtml($journalTitle)?></a> + <? $containerID = $this->driver->getContainerRecordID(); ?> + <a href="<?=($containerID ? $this->recordLink()->getUrl("VuFind|$containerID") : $this->record($this->driver)->getLink('journaltitle', $journalTitle))?>"><?=$this->escapeHtml($journalTitle)?></a> <? $ref = $this->driver->getContainerReference(); if (!empty($ref)) { echo $this->escapeHtml($ref); } ?> </td> </tr> @@ -192,6 +193,15 @@ </tr> <? endif; ?> + <? $childRecordCount = $this->driver->tryMethod('getChildRecordCount'); if ($childRecordCount): ?> + <tr> + <th><?=$this->transEsc('child_records')?>: </th> + <td> + <a href="<?=$this->recordLink()->getChildRecordSearchUrl($this->driver)?>"><?=$this->transEsc('child_record_count', array('%%count%%' => $childRecordCount))?></a> + </td> + </tr> + <? endif; ?> + <? $openUrl = $this->driver->openURLActive('record') ? $this->driver->getOpenURL() : false; // Account for replace_other_urls setting diff --git a/themes/bootstrap3/templates/RecordDriver/SolrDefault/result-list.phtml b/themes/bootstrap3/templates/RecordDriver/SolrDefault/result-list.phtml index 4e1a5afebbf..d40c7d21141 100644 --- a/themes/bootstrap3/templates/RecordDriver/SolrDefault/result-list.phtml +++ b/themes/bootstrap3/templates/RecordDriver/SolrDefault/result-list.phtml @@ -45,7 +45,10 @@ <? $journalTitle = $this->driver->getContainerTitle(); $summDate = $this->driver->getPublicationDates(); ?> <? if (!empty($journalTitle)): ?> <?=!empty($summAuthor) ? '<br />' : ''?> - <?=/* TODO: handle highlighting more elegantly here */ $this->transEsc('Published in') . ' <a href="' . $this->record($this->driver)->getLink('journaltitle', str_replace(array('{{{{START_HILITE}}}}', '{{{{END_HILITE}}}}'), '', $journalTitle)) . '">' . $this->highlight($journalTitle) . '</a>';?> + <?=$this->transEsc('Published in')?> + <? $containerID = $this->driver->getContainerRecordID(); ?> + <? /* TODO: handle highlighting more elegantly here: */?> + <a href="<?=($containerID ? $this->recordLink()->getUrl("VuFind|$containerID") : $this->record($this->driver)->getLink('journaltitle', str_replace(array('{{{{START_HILITE}}}}', '{{{{END_HILITE}}}}'), '', $journalTitle)))?>"><?=$this->highlight($journalTitle) ?></a> <?=!empty($summDate) ? ' (' . $this->escapeHtml($summDate[0]) . ')' : ''?> <? elseif (!empty($summDate)): ?> <?=!empty($summAuthor) ? '<br />' : ''?> diff --git a/themes/jquerymobile/templates/RecordDriver/SolrDefault/core.phtml b/themes/jquerymobile/templates/RecordDriver/SolrDefault/core.phtml index eb6f0d28506..1be519b07da 100644 --- a/themes/jquerymobile/templates/RecordDriver/SolrDefault/core.phtml +++ b/themes/jquerymobile/templates/RecordDriver/SolrDefault/core.phtml @@ -15,9 +15,10 @@ <dl class="biblio" title="<?=$this->transEsc('Bibliographic Details')?>"> <? $journalTitle = $this->driver->getContainerTitle(); if (!empty($journalTitle)): ?> - <dt><?=$this->transEsc('Journal Title')?>:</dt> + <dt><?=$this->transEsc('Published in')?>:</dt> <dd> - <a rel="external" href="<?=$this->record($this->driver)->getLink('journaltitle', $journalTitle)?>"><?=$this->escapeHtml($journalTitle)?></a> + <? $containerID = $this->driver->getContainerRecordID(); ?> + <a rel="external" href="<?=($containerID ? $this->recordLink()->getUrl("VuFind|$containerID") : $this->record($this->driver)->getLink('journaltitle', $journalTitle))?>"><?=$this->escapeHtml($journalTitle)?></a> <? $ref = $this->driver->getContainerReference(); if (!empty($ref)) { echo $this->escapeHtml($ref); } ?> </dd> <? endif; ?> @@ -125,6 +126,11 @@ </dd> <? endif; ?> + <? $childRecordCount = $this->driver->tryMethod('getChildRecordCount'); if ($childRecordCount): ?> + <dt><?=$this->transEsc('child_records')?>: </dt> + <dd><a rel="external" href="<?=$this->recordLink()->getChildRecordSearchUrl($this->driver)?>"><?=$this->transEsc('child_record_count', array('%%count%%' => $childRecordCount))?></a></dd> + <? endif; ?> + <? $openUrl = $this->driver->openURLActive('record') ? $this->driver->getOpenURL() : false; // Account for replace_other_urls setting -- GitLab