/** * Process incoming parameters and display the page. * * @return void * @access public */ function launch() { global $interface; global $configArray; if (!$interface->get_template_vars('dualResultsEnabled')) { PEAR::raiseError(new PEAR_Error("Dual result view is not enabled.")); } // Initialise from the current search globals $searchObject = SearchObjectFactory::initSearchObject(); $searchObject->init(); // Set Interface Variables // Those we can construct BEFORE the search is executed $interface->setPageTitle('Search Results'); // Whether embedded openurl autocheck is enabled if (isset($configArray['OpenURL']['autocheck']) && $configArray['OpenURL']['autocheck']) { $interface->assign('openUrlAutoCheck', true); } // Set Proxy URL if (isset($configArray['EZproxy']['host'])) { $interface->assign('proxy', $configArray['EZproxy']['host']); } // Determine whether to display book previews if (isset($configArray['Content']['previews'])) { $interface->assignPreviews(); } $interface->assign("showContext", isset($configArray['Content']['showHierarchyTree']) ? $configArray['Content']['showHierarchyTree'] : false); // Process Search $result = $searchObject->processSearch(true, true); if (PEAR::isError($result)) { PEAR::raiseError($result->getMessage()); } // Some more variables // Those we can construct AFTER the search is executed, but we need // no matter whether there were any results $interface->assign('qtime', round($searchObject->getQuerySpeed(), 2)); $interface->assign('spellingSuggestions', $searchObject->getSpellingSuggestions()); $interface->assign('lookfor', $searchObject->displayQuery()); $interface->assign('searchType', $searchObject->getSearchType()); // Will assign null for an advanced search $interface->assign('searchIndex', $searchObject->getSearchIndex()); // Setup Display $interface->assign('sitepath', $configArray['Site']['path']); $interface->assign('more', $searchObject->renderSearchUrl()); $interface->assign('searchWithFilters', $searchObject->renderSearchUrl()); $searchWithoutLocalFilters = $searchObject->renderSearchUrl(false); $searchWithoutLocalFilters = str_replace('/Search/Results', '/Search/DualResults', $searchWithoutLocalFilters); $interface->assign('searchWithoutLocalFilters', $searchWithoutLocalFilters); if ($spatialDateRangeType = $searchObject->getSpatialDateRangeFilterType()) { $interface->assign('spatialDateRangeType', $spatialDateRangeType); } $interface->assign('pci_more', str_replace('/Search/Results', '/PCI/Search', $searchObject->renderSearchUrl())); if ($searchObject->getResultTotal() > 0) { // Assign interface variables $summary = $searchObject->getResultSummary(); $interface->assign('recordCount', $summary['resultTotal']); $interface->assign('recordStart', $summary['startRecord']); // We can't use the provided endRecord value (see note below about // setting limit), so we need to calculate it manually: $endRecord = $summary['startRecord'] + 9; if ($endRecord > $summary['resultTotal']) { $endRecord = $summary['resultTotal']; } $interface->assign('recordEnd', $endRecord); // Big one - our results; chop down to only the first ten for short // results, but note that we can't simply shorten the list by setting // the $searchObject's limit to 10, since this causes goofy behavior // in the ResultScroller below. $results = $searchObject->getResultRecordHTML(); if (count($results) > 10) { $results = array_slice($results, 0, 10); } $interface->assign('recordSet', $results); } // 'Finish' the search... complete timers and log search history. $searchObject->close(); $interface->assign('time', round($searchObject->getTotalSpeed(), 2)); // Show the save/unsave code on screen // The ID won't exist until after the search has been put in the search history // so this needs to occur after the close() on the searchObject $interface->assign('showSaved', true); $interface->assign('savedSearch', $searchObject->isSavedSearch()); $interface->assign('searchId', $searchObject->getSearchId()); // initialize the search result scroller for this search $scroller = new ResultScroller(); $scroller->init($searchObject, $result); // Done, display the page $interface->setTemplate('list-dual.tpl'); $interface->display('layout.tpl'); // Save the URL of this search to the session so we can return to it easily: $_SESSION['lastSearchURL'] = str_replace('/Search/Results', '/Search/DualResults', $searchObject->renderSearchUrl()); // Save the display query too, so we can use it e.g. in the breadcrumbs $_SESSION['lastSearchDisplayQuery'] = $searchObject->displayQuery(); }
/** * Initialize the record * * @param string $id Record ID * @param array $record Record data * * @return void */ protected function setRecord($id, $record) { global $interface; global $configArray; global $user; // Store ID of current record (this is needed to generate appropriate // links, and it is independent of which record driver gets used). $interface->assign('id', $_REQUEST['id']); $this->recordDriver = RecordDriverFactory::initRecordDriver($record); // Define Default Tab $defaultTab = isset($configArray['Site']['defaultRecordTab']) ? $configArray['Site']['defaultRecordTab'] : 'Holdings'; // Don't let bots crawl holdings if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/bot|crawl|slurp|spider/i', $_SERVER['HTTP_USER_AGENT'])) { $this->hasHoldings = false; $interface->assign('hasHoldings', false); $defaultTab = 'Description'; } else { if (isset($configArray['Site']['hideHoldingsTabWhenEmpty']) && $configArray['Site']['hideHoldingsTabWhenEmpty']) { $showHoldingsTab = $this->recordDriver->hasHoldings(); $interface->assign('hasHoldings', $showHoldingsTab); $defaultTab = !$showHoldingsTab && $defaultTab == "Holdings" ? "Description" : $defaultTab; } else { $interface->assign('hasHoldings', true); } } $tab = isset($_GET['action']) ? $_GET['action'] : $defaultTab; $interface->assign('tab', $tab); // Check if ajax tabs are active if (isset($configArray['Site']['ajaxRecordTabs']) && $configArray['Site']['ajaxRecordTabs']) { $interface->assign('dynamicTabs', true); } if ($this->recordDriver->hasRDF()) { $interface->assign('addHeader', '<link rel="alternate" type="application/rdf+xml" ' . 'title="RDF Representation" href="' . $configArray['Site']['url'] . '/Record/' . urlencode($_REQUEST['id']) . '/RDF" />' . "\n"); } $interface->assign('coreMetadata', $this->recordDriver->getCoreMetadata()); // Determine whether to display book previews if (isset($configArray['Content']['previews'])) { $interface->assignPreviews(); } // Determine whether comments or reviews are enabled if (isset($configArray['Site']['userComments']) && $configArray['Site']['userComments']) { $interface->assign('userCommentsEnabled', true); } // Ratings for libraries, comments for museums and archives if ($this->recordDriver->getSector() == 'lib') { $interface->assign('ratings', true); } if (isset($configArray['Site']['userComments']) && $configArray['Site']['userComments']) { // Get number of comments for this record include_once 'services/MyResearch/lib/Comments.php'; $comments = new Comments(); $commentCount = $comments->getCommentCount($_REQUEST['id']); $interface->assign(compact('commentCount')); $recordRating = $comments->getAverageRating($_REQUEST['id']); $interface->assign(compact('recordRating')); } // Determine whether to include script tag for syndetics plus if (isset($configArray['Syndetics']['plus']) && $configArray['Syndetics']['plus'] && isset($configArray['Syndetics']['plus_id'])) { $interface->assign('syndetics_plus_js', "http://plus.syndetics.com/widget.php?id=" . $configArray['Syndetics']['plus_id']); } // Set flags that control which tabs are displayed: if (isset($configArray['Content']['reviews'])) { $interface->assign('hasReviews', $this->recordDriver->hasReviews()); } if (isset($configArray['Content']['excerpts'])) { $interface->assign('hasExcerpt', $this->recordDriver->hasExcerpt()); } //Hierarchy Tree $interface->assign('hasHierarchyTree', $this->recordDriver->hasHierarchyTree()); $interface->assign('hasTOC', $this->recordDriver->hasTOC()); $interface->assign('hasMap', $this->recordDriver->hasMap()); $this->recordDriver->getTOC(); $interface->assign('extendedMetadata', $this->recordDriver->getExtendedMetadata()); // Assign the next/previous record data: $scroller = new ResultScroller(); $scrollData = $scroller->getScrollData($_REQUEST['id']); $interface->assign('previousRecord', $scrollData['previousRecord']); $interface->assign('nextRecord', $scrollData['nextRecord']); $interface->assign('currentRecordPosition', $scrollData['currentPosition']); $interface->assign('resultTotal', $scrollData['resultTotal']); // Retrieve User Search History $lastsearch = isset($_SESSION['lastSearchURL']) ? $_SESSION['lastSearchURL'] : false; $interface->assign('lastsearch', $lastsearch); if ($lastsearch) { // Retrieve active filters and assign them to searchbox template. // Since SearchObjects use $_REQUEST to init filters, we stash the current $_REQUEST // and fill it temporarily with URL parameters from last search. $query = parse_url($lastsearch, PHP_URL_QUERY); parse_str($query, $vars); $oldReq = $_REQUEST; $_REQUEST = $vars; $searchObject = SearchObjectFactory::initSearchObject(); $searchObject->init(); // This is needed for facet labels $searchObject->initRecommendations(); $filterList = $searchObject->getFilterList(); $filterListOthers = $searchObject->getFilterListOthers(); $checkboxFilters = $searchObject->getCheckboxFacets(); $filterUrlParams = $searchObject->getfilterUrlParams(); if (isset($vars['lookfor'])) { $interface->assign('lookfor', $vars['lookfor']); } $interface->assign('filterUrlParam', $filterUrlParams[0]); $interface->assign(compact('filterList')); $interface->assign(compact('filterListOthers')); $interface->assign('checkboxFilters', $checkboxFilters); if (isset($_SERVER['HTTP_REFERER'])) { // Set followup module & action for next search $parts = parse_url($_SERVER['HTTP_REFERER']); $pathParts = explode('/', $parts['path']); $refAction = array_pop($pathParts); $refModule = array_pop($pathParts); $interface->assign('followupSearchModule', $refModule); $interface->assign('followupSearchAction', $refAction); } $_REQUEST = $oldReq; } $interface->assign('lastsearchdisplayquery', isset($_SESSION['lastSearchDisplayQuery']) ? $_SESSION['lastSearchDisplayQuery'] : false); $interface->assign('searchId', isset($_SESSION['lastSearchID']) ? $_SESSION['lastSearchID'] : false); $interface->assign('searchType', isset($_SESSION['searchType']) ? $_SESSION['searchType'] : false); unset($_SESSION['lastSearchID']); unset($_SESSION['searchType']); // Send down text for inclusion in breadcrumbs $interface->assign('breadcrumbText', $this->recordDriver->getBreadcrumb()); // Send down OpenURL for COinS use: $interface->assign('openURL', $this->recordDriver->getOpenURL()); // Whether RSI is enabled if (isset($configArray['OpenURL']['use_rsi']) && $configArray['OpenURL']['use_rsi']) { $interface->assign('rsi', true); } // Whether embedded openurl autocheck is enabled if (isset($configArray['OpenURL']['autocheck']) && $configArray['OpenURL']['autocheck']) { $interface->assign('openUrlAutoCheck', true); } // Send down legal export formats (if any): $interface->assign('exportFormats', $this->recordDriver->getExportFormats()); if ($this->recordDriver->allowSocialMediaSharing()) { // Set AddThis User $interface->assign('addThis', isset($configArray['AddThis']['key']) ? $configArray['AddThis']['key'] : false); } // Set Proxy URL if (isset($configArray['EZproxy']['host'])) { $interface->assign('proxy', $configArray['EZproxy']['host']); } // Get Messages $this->infoMsg = isset($_GET['infoMsg']) ? $_GET['infoMsg'] : false; $this->errorMsg = isset($_GET['errorMsg']) ? $_GET['errorMsg'] : false; // Set bX flag $interface->assign('bXEnabled', isset($configArray['bX']['token']) ? true : false); // Get Record source driver $catalog = $this->catalog; $driver = is_callable(array($catalog, 'getSourceDriver')) ? $this->catalog->getSourceDriver($_REQUEST['id']) : ''; $interface->assign('driver', $driver); }
/** * Display search results * * @param object $searchObject Search Object * * @return void */ public function showResults($searchObject) { global $interface; global $configArray; // Set Proxy URL if (isset($configArray['EZproxy']['host'])) { $interface->assign('proxy', $configArray['EZproxy']['host']); } // Handle hierarchical facets (request level 0 only for initial display) $facetConfig = getExtraConfigArray('facets'); if (isset($facetConfig['SpecialFacets']['hierarchical'])) { foreach ($facetConfig['SpecialFacets']['hierarchical'] as $facet) { $searchObject->addFacetPrefix(array($facet => '0/')); } } // Build RSS Feed for Results (if requested) if ($searchObject->getView() == 'rss') { // Throw the XML to screen echo $searchObject->buildRSS(); // And we're done exit; } $accept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : ''; // Build JSON for Results (if requested) if ($searchObject->getView() == 'json' || stristr($accept, 'application/json')) { // Allow cross-origin requests header('Access-Control-Allow-Origin: *'); // Throw the JSON to screen echo $searchObject->buildJSON(); // And we're done exit; } // Build XML for Results (if requested) if ($searchObject->getView() == 'xml' || stristr($accept, 'text/xml')) { // Allow cross-origin requests header('Access-Control-Allow-Origin: *'); // Throw the XML to screen echo $searchObject->buildXML(); // And we're done exit; } // Determine whether to display book previews if (isset($configArray['Content']['previews'])) { $interface->assignPreviews(); } $interface->assign('showContext', isset($configArray['Content']['showHierarchyTree']) ? $configArray['Content']['showHierarchyTree'] : false); // TODO : Stats, move inside the search object // Setup Statistics Index Connection if ($configArray['Statistics']['enabled']) { $this->_solrStats = ConnectionManager::connectToIndex('SolrStats'); } // Set Interface Variables // Those we can construct BEFORE the search is executed $displayQuery = $searchObject->displayQuery(); $interface->setPageTitle(translate('Search Results') . (empty($displayQuery) ? '' : ' - ' . htmlspecialchars($displayQuery))); // Process Search $result = $searchObject->processSearch(true, true); if (PEAR::isError($result)) { PEAR::raiseError($result->getMessage()); } // Some more variables // Those we can construct AFTER the search is executed, but we need // no matter whether there were any results $interface->assign('qtime', round($searchObject->getQuerySpeed(), 2)); $interface->assign('spellingSuggestions', $searchObject->getSpellingSuggestions()); $interface->assign('isEmptySearch', $searchObject->isEmptySearch()); $interface->assign('lookfor', $displayQuery); $interface->assign('searchType', $searchObject->getSearchType()); // Will assign null for an advanced search $interface->assign('searchIndex', $searchObject->getSearchIndex()); $interface->assign('sortList', $searchObject->getSortList()); $interface->assign('viewList', $searchObject->getViewList()); $interface->assign('rssLink', $searchObject->getRSSUrl()); $interface->assign('limitList', $searchObject->getLimitList()); $interface->assign('searchWithoutFilters', $searchObject->renderSearchUrlWithoutFilters()); $interface->assign('searchWithFilters', $searchObject->renderSearchUrl()); if ($spatialDateRangeType = $searchObject->getSpatialDateRangeFilterType()) { $interface->assign('spatialDateRangeType', $spatialDateRangeType); } // We'll need recommendations no matter how many results we found: $interface->assign('topRecommendations', $searchObject->getRecommendationsTemplates('top')); $interface->assign('sideRecommendations', $searchObject->getRecommendationsTemplates('side')); $interface->assign('orFilters', $searchObject->getOrFilters()); // Whether RSI is enabled if (isset($configArray['OpenURL']['use_rsi']) && $configArray['OpenURL']['use_rsi']) { $interface->assign('rsi', true); } // Whether embedded openurl autocheck is enabled if (isset($configArray['OpenURL']['autocheck']) && $configArray['OpenURL']['autocheck']) { $interface->assign('openUrlAutoCheck', true); } // If no record found if ($searchObject->getResultTotal() < 1) { // Don't let bots crawl "no results" pages $this->disallowBots(); $interface->setTemplate('list-none.tpl'); $interface->assign('recordCount', 0); $interface->assign('removeAllFilters', $searchObject->renderSearchUrlWithoutFilters(array('prefiltered'))); // Set up special "no results" recommendations: $interface->assign('noResultsRecommendations', $searchObject->getRecommendationsTemplates('noresults')); // Was the empty result set due to an error? $error = $searchObject->getIndexError(); if ($error !== false) { // Solr 4 returns error as an array if (is_array($error)) { $error = $error['msg']; } // If it's a parse error or the user specified an invalid field, we // should display an appropriate message: if (stristr($error, 'org.apache.lucene.queryParser.ParseException') || stristr($error, 'org.apache.solr.search.SyntaxError') || preg_match('/^undefined field/', $error)) { $interface->assign('parseError', true); } else { // Unexpected error -- let's treat this as a fatal condition. PEAR::raiseError(new PEAR_Error('Unable to process query<br />Solr Returned: ' . $error)); } } // TODO : Stats, move inside the search object // Save no records found stat if ($this->_solrStats) { $this->_solrStats->saveNoHits($_GET['lookfor'], $_GET['type']); } } else { // TODO : Stats, move inside the search object // Save search stat if ($this->_solrStats) { $this->_solrStats->saveSearch($_GET['lookfor'], $_GET['type']); } // If the "jumpto" parameter is set, jump to the specified result index: $this->_processJumpto($result); // Assign interface variables $summary = $searchObject->getResultSummary(); $interface->assign('recordCount', $summary['resultTotal']); $interface->assign('recordStart', $summary['startRecord']); $interface->assign('recordEnd', $summary['endRecord']); // Big one - our results $interface->assign('recordSet', $searchObject->getResultRecordHTML()); // Setup Display //Get view & load template $currentView = $searchObject->getView(); $interface->assign('subpage', 'Search/list-' . $currentView . '.tpl'); $interface->setTemplate('list.tpl'); // Process Paging $link = $searchObject->renderLinkPageTemplate(); $options = array('totalItems' => $summary['resultTotal'], 'fileName' => $link, 'perPage' => $summary['perPage']); $pager = new VuFindPager($options); $interface->assign('pageLinks', $pager->getLinks()); } // 'Finish' the search... complete timers and log search history. $searchObject->close(); $interface->assign('time', round($searchObject->getTotalSpeed(), 2)); // Show the save/unsave code on screen // The ID won't exist until after the search has been put in the search // history so this needs to occur after the close() on the searchObject $interface->assign('showSaved', true); $interface->assign('savedSearch', $searchObject->isSavedSearch()); $interface->assign('searchId', $searchObject->getSearchId()); // Save the URL of this search to the session so we can return to it easily: $_SESSION['lastSearchURL'] = $searchObject->renderSearchUrl(); // Save the display query too, so we can use it e.g. in the breadcrumbs $_SESSION['lastSearchDisplayQuery'] = $displayQuery; // Also save the search ID and type so user can edit the advanced search $_SESSION['lastSearchID'] = $searchObject->getSearchID(); $_SESSION['searchType'] = $searchObject->getSearchType(); // initialize the search result scroller for this search $scroller = new ResultScroller(); $scroller->init($searchObject, $result); // Done, display the page $interface->display('layout.tpl'); }
/** * Process parameters and display the page. * * @return void * @access public */ public function launch() { global $interface; global $configArray; global $action; $this->disallowBots(); $enabledActions = array(); // Check if requested action is enabled and configured $searchSettings = getExtraConfigArray('searches'); if (isset($searchSettings['BrowseExtended'])) { foreach ($searchSettings['BrowseExtended'] as $key => $val) { if ((bool) $val) { $enabledActions[] = $key; } } } if (!in_array($action, $enabledActions)) { PEAR::raiseError("Browse action {$action} not enabled"); } if (!isset($searchSettings["BrowseExtended:{$action}"])) { PEAR::raiseError("Browse action {$action} not configured"); } $settings = $searchSettings["BrowseExtended:{$action}"]; $searchObject = SearchObjectFactory::initSearchObject('SolrBrowseExtended'); $searchObject->init($action); $result = $searchObject->processSearch(true, true); if (PEAR::isError($result)) { PEAR::raiseError($result->getMessage()); } $interface->assign('sideRecommendations', $searchObject->getRecommendationsTemplates('side')); $displayQuery = $searchObject->displayQuery(); $interface->assign('lookfor', $displayQuery); $interface->assign('paginateTitle', translate("browse_extended_{$action}")); $interface->setPageTitle(translate("browse_extended_{$action}")); $interface->assign('snippet', 'RecordDrivers/Index/result-browse-snippet-' . strtolower($action) . '.tpl'); $interface->assign('more', 'RecordDrivers/Index/result-browse-more-' . strtolower($action) . '.tpl'); $interface->assign('homeAction', $action); // If no record found if ($searchObject->getResultTotal() < 1) { $interface->setTemplate('../BrowseExtended/list-none.tpl'); } else { $summary = $searchObject->getResultSummary(); $interface->assign('recordCount', $summary['resultTotal']); $interface->assign('recordStart', $summary['startRecord']); $interface->assign('recordEnd', $summary['endRecord']); $interface->assign('recordSet', $searchObject->getResultRecordHTML()); $interface->setTemplate('../BrowseExtended/browse.tpl'); // Process Paging $link = $searchObject->renderLinkPageTemplate(); $options = array('totalItems' => $summary['resultTotal'], 'fileName' => $link, 'perPage' => $summary['perPage']); $pager = new VuFindPager($options); $interface->assign('pageLinks', $pager->getLinks()); } $_SESSION['lastSearchURL'] = $searchObject->renderSearchUrl(); $searchObject->close(); $scroller = new ResultScroller(); $scroller->init($searchObject, $result); $interface->assign('formAction', "Browse/{$action}"); // Done, display the page $interface->display('layout.tpl'); }