/** * Support function to display spelling suggestions. * * @param string $msg HTML to display at the top of * the spelling section. * @param \VuFind\Search\Base\Results $results Results object * @param \Zend\View\Renderer\PhpRenderer $view View renderer object * * @return string */ public function renderSpellingSuggestions($msg, $results, $view) { $spellingSuggestions = $results->getSpellingSuggestions(); if (empty($spellingSuggestions)) { return ''; } $html = '<div class="' . $this->getContainerClass() . '">'; $html .= $msg; foreach ($spellingSuggestions as $term => $details) { $html .= '<br/>' . $view->escapeHtml($term) . ' » '; $i = 0; foreach ($details['suggestions'] as $word => $data) { if ($i++ > 0) { $html .= ', '; } $html .= '<a href="' . $results->getUrlQuery()->replaceTerm($term, $data['new_term']) . '">' . $view->escapeHtml($word) . '</a>'; if (isset($data['expand_term']) && !empty($data['expand_term'])) { $url = $results->getUrlQuery()->replaceTerm($term, $data['expand_term']); $html .= $this->renderExpandLink($url, $view); } } } $html .= '</div>'; return $html; }
/** * Sort and extend facet list * * @param Results $results VuFind\Search\Solr\Results * @param String $field Facet group ID, e.g. 'navSubidsbb' * @param Array $list Contained items of the facet group * @param String $searchRoute E.g. 'search-results' * @param Array $routeParams RouteParams * * @return Array */ public function __invoke(Results $results, $field, array $list, $searchRoute, array $routeParams = []) { $facets = []; // Avoid limit on URL $urlHelper = $this->getView()->plugin('url'); $baseRoute = $urlHelper($searchRoute, $routeParams); foreach ($list as $facetItem) { $facetItem['url'] = $baseRoute . $results->getUrlQuery()->addFacet($field, $facetItem['value']); $facets[$facetItem['displayText']] = $facetItem; } return array_values($facets); }
/** * Get search parameters * * @return string of params */ public function getSearchParams() { // Get search parameters and return them minus the leading ?: $str = substr($this->searchObject->getUrlQuery()->getParams(false), 1); // Pass through hidden filters: $options = $this->searchObject->getOptions(); if (is_callable([$options, 'getHiddenFilters'])) { foreach ($options->getHiddenFilters() as $hf) { $str .= '&' . urlencode('hf[]') . '=' . urlencode($hf); } } return $str; }
/** * Turns facet information into an alphabetical list. * * @param \VuFind\Search\Base\Results $results Search result object * @param string $field Facet field to sort * @param array $list Facet value list extract from * the search result object's getFacetList method * @param array $searchRoute Route to use to generate * search URLs for individual facet values * * @return array Associative URL => description array sorted by description */ public function __invoke($results, $field, $list, $searchRoute) { $facets = []; // avoid limit on URL $results->getParams()->setLimit($results->getOptions()->getDefaultLimit()); $urlHelper = $this->getView()->plugin('url'); foreach ($list as $value) { $url = $urlHelper($searchRoute) . $results->getUrlQuery()->addFacet($field, $value['value']); $facets[$url] = $value['displayText']; } natcasesort($facets); return $facets; }
/** * Represent the current search results as a feed. * * @param \VuFind\Search\Base\Results $results Search results to convert to * feed * @param string $currentPath Base path to display in feed * (leave null to load dynamically using currentpath view helper) * * @return Feed */ public function __invoke($results, $currentPath = null) { $this->registerExtension(); // Determine base URL if not already provided: if (is_null($currentPath)) { $currentPath = $this->getView()->plugin('currentpath')->__invoke(); } $serverUrl = $this->getView()->plugin('serverurl'); $baseUrl = $serverUrl($currentPath); // Create the parent feed $feed = new Feed(); $feed->setTitle($this->translate('Results for') . ' ' . $results->getParams()->getDisplayQuery()); $feed->setLink($baseUrl . $results->getUrlQuery()->setViewParam(null, false)); $feed->setFeedLink($baseUrl . $results->getUrlQuery()->getParams(false), $results->getParams()->getView()); $feed->setDescription($this->translate('Showing') . ' ' . $results->getStartRecord() . '-' . $results->getEndRecord() . ' ' . $this->translate('of') . ' ' . $results->getResultTotal()); $params = $results->getParams(); // add atom links for easier paging $feed->addOpensearchLink($baseUrl . $results->getUrlQuery()->setPage(1, false), 'first', $params->getView()); if ($params->getPage() > 1) { $feed->addOpensearchLink($baseUrl . $results->getUrlQuery()->setPage($params->getPage() - 1, false), 'previous', $params->getView()); } $lastPage = ceil($results->getResultTotal() / $params->getLimit()); if ($params->getPage() < $lastPage) { $feed->addOpensearchLink($baseUrl . $results->getUrlQuery()->setPage($params->getPage() + 1, false), 'next', $params->getView()); } $feed->addOpensearchLink($baseUrl . $results->getUrlQuery()->setPage($lastPage, false), 'last', $params->getView()); // add opensearch fields $feed->setOpensearchTotalResults($results->getResultTotal()); $feed->setOpensearchItemsPerPage($params->getLimit()); $feed->setOpensearchStartIndex($results->getStartRecord() - 1); $feed->setOpensearchSearchTerms($params->getQuery()->getString()); $records = $results->getResults(); foreach ($records as $current) { $this->addEntry($feed, $current); } return $feed; }
/** * Get the URL for this query without filters. * * @return string */ public function getFilterlessUrl() { return $this->results->getUrlQuery()->removeAllFilters(); }
/** * Add a search into the search table (history) * * @param \VuFind\Search\Results\PluginManager $manager Search manager * @param \VuFind\Search\Base\Results $newSearch Search to save * @param string $sessionId Current session ID * @param array $searchHistory Existing saved * searches (for deduplication purposes) * * @return void */ public function saveSearch(\VuFind\Search\Results\PluginManager $manager, $newSearch, $sessionId, $searchHistory = []) { // Duplicate elimination $newUrl = $newSearch->getUrlQuery()->getParams(); foreach ($searchHistory as $oldSearch) { // Deminify the old search (note that if we have a resource, we need // to grab the contents -- this is necessary for PostgreSQL compatibility // although MySQL returns a plain string). $minSO = $oldSearch->getSearchObject(); $dupSearch = $minSO->deminify($manager); // See if the classes and urls match $oldUrl = $dupSearch->getUrlQuery()->getParams(); if (get_class($dupSearch) == get_class($newSearch) && $oldUrl == $newUrl) { // Is the older search saved? if ($oldSearch->saved) { // Return existing saved row instead of creating a new one: $newSearch->updateSaveStatus($oldSearch); return; } else { // Delete the old search since we'll be creating a new, more // current version below: $oldSearch->delete(); } } } // If we got this far, we didn't find a saved duplicate, so we should // save the new search: $data = ['session_id' => $sessionId, 'created' => date('Y-m-d'), 'search_object' => serialize(new minSO($newSearch))]; $this->insert($data); $row = $this->getRowById($this->getLastInsertValue()); // Chicken and egg... We didn't know the id before insert $newSearch->updateSaveStatus($row); $row->search_object = serialize(new minSO($newSearch)); $row->save(); }
/** * 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) { $filters = $results->getParams()->getFilters(); foreach ($filters as $key => $value) { if ($key == $this->geoField) { $match = array(); if (preg_match('/Intersects\\(([0-9 \\-\\.]+)\\)/', $value[0], $match)) { $this->selectedCoordinates = explode(' ', $match[1]); } else { if (preg_match($this->polygonMatch, $value[0], $match)) { $this->selectedCoordinates = [$match[1], $match[2], $match[3], $match[4]]; } } $this->searchParams = $results->getUrlQuery()->removeFacet($this->geoField, $value[0], false); } } if ($this->searchParams == null) { $this->searchParams = $results->getUrlQuery()->getParams(false); } }
/** * Build a hidden filter query fragment from the given filters * * @param Results $results Search results * @param array $filters Filters * * @return string Query parameters */ protected function buildUrlHiddenFilters(Results $results, $filters) { // Set up results object for URL building: $params = $results->getParams(); foreach ($filters as $filter) { $params->addHiddenFilter($filter); } $urlParams = $results->getUrlQuery()->getParams(false); return $urlParams !== '?' ? $urlParams : ''; }
/** * 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) { if ($this->selectedDateRange == null) { return; } $this->searchParams = $results->getUrlQuery()->removeFacet($this->selectedDateRange, false); $curr_date = date('Ym', strtotime('now')); $s1 = date('Ym', strtotime('last year')); $e1 = date('Ym', strtotime('last year december')); $s2 = date('Ym', strtotime('this year january')); $e2 = $curr_date; $ranges = array_merge(range($e2, $s2), range($e1, $s1)); foreach ($ranges as $date) { $range = $this->createRange($date, $e2); $label = $this->createLabel($date); $this->dateRanges[$label] = array('filter' => $this->createFilter($range), 'selected' => $this->selectedDateRange == $range); } }
/** * Add a search into the search table (history) * * @param \VuFind\Search\Results\PluginManager $manager Search manager * @param \VuFind\Search\Base\Results $newSearch Search to save * @param string $sessionId Current session ID * @param array $searchHistory Existing saved * searches (for deduplication purposes) * * @return void */ public function saveSearch(\VuFind\Search\Results\PluginManager $manager, $newSearch, $sessionId, $searchHistory = []) { // Duplicate elimination $newUrl = $newSearch->getUrlQuery()->getParams(); foreach ($searchHistory as $oldSearch) { // Deminify the old search: $dupSearch = $oldSearch->getSearchObject()->deminify($manager); // See if the classes and urls match $oldUrl = $dupSearch->getUrlQuery()->getParams(); if (get_class($dupSearch) == get_class($newSearch) && $oldUrl == $newUrl) { // Is the older search saved? if ($oldSearch->saved) { // Return existing saved row instead of creating a new one: $newSearch->updateSaveStatus($oldSearch); return; } else { // Delete the old search since we'll be creating a new, more // current version below: $oldSearch->delete(); } } } // If we got this far, we didn't find a saved duplicate, so we should // save the new search: $this->insert(['created' => date('Y-m-d')]); $row = $this->getRowById($this->getLastInsertValue()); // Chicken and egg... We didn't know the id before insert $newSearch->updateSaveStatus($row); // Don't set session ID until this stage, because we don't want to risk // ever having a row that's associated with a session but which has no // search object data attached to it; this could cause problems! $row->session_id = $sessionId; $row->search_object = serialize(new minSO($newSearch)); $row->save(); }
/** * Get search parameters * * @return string of params */ public function getSearchParams() { // Get search parameters and return them minus the leading ?: return substr($this->searchObject->getUrlQuery()->getParams(false), 1); }
/** * Update the remembered "last search" in the session. * * @param \VuFind\Search\Base\Results $search Search object to remember. * * @return void */ protected function rememberSearch($search) { $baseUrl = $this->getController()->url()->fromRoute($search->getOptions()->getSearchAction()); $this->getController()->getSearchMemory()->rememberSearch($baseUrl . $search->getUrlQuery()->getParams(false)); }
/** * Represent the current search results as a feed. * * @param \VuFind\Search\Base\Results $results Search results to convert to * feed * @param string $currentPath Base path to display in feed * (leave null to load dynamically using currentpath view helper) * * @return Feed */ public function __invoke($results, $currentPath = null) { $this->registerExtension(); // Determine base URL if not already provided: if (is_null($currentPath)) { $currentPath = $this->getView()->plugin('currentpath')->__invoke(); } $serverUrl = $this->getView()->plugin('serverurl'); $baseUrl = $serverUrl($currentPath); // Create the parent feed $feed = new Feed(); $translator = $this->getTranslator(); $feed->setTitle($translator('Results for') . ' ' . $results->getParams()->getDisplayQuery()); $feed->setLink($baseUrl . $results->getUrlQuery()->setViewParam(null, false)); $feed->setFeedLink($baseUrl . $results->getUrlQuery()->getParams(false), $results->getParams()->getView()); $records = $results->getResults(); $feed->setDescription($translator('Displaying the top') . ' ' . count($records) . ' ' . $translator('search results of') . ' ' . $results->getResultTotal() . ' ' . $translator('found')); foreach ($records as $current) { $this->addEntry($feed, $current); } return $feed; }
/** * Add a search into the search table (history) * * @param \VuFind\Search\Results\PluginManager $manager Search manager * @param \VuFind\Search\Base\Results $newSearch Search to save * @param string $sessionId Current session ID * @param array $searchHistory Existing saved * searches (for deduplication purposes) * * @return void */ public function saveSearch(\VuFind\Search\Results\PluginManager $manager, $newSearch, $sessionId, $searchHistory = []) { // Resolve search hash of current search $hash = null; // Duplicate elimination foreach ($searchHistory as $oldSearch) { // Deminify the old search (note that if we have a resource, we need // to grab the contents -- this is necessary for PostgreSQL compatibility // although MySQL returns a plain string). $minSO = $oldSearch->getSearchObject(); $dupSearch = $minSO->deminify($manager); // See if the classes and urls match $oldUrl = $dupSearch->getUrlQuery()->getParams(); $newUrl = $newSearch->getUrlQuery()->getParams(); if (get_class($dupSearch) == get_class($newSearch) && $oldUrl == $newUrl) { $hash = $oldSearch->finna_search_id; break; } } parent::saveSearch($manager, $newSearch, $sessionId, $searchHistory); // Augment row updated by parent with search hash $row = $this->select(['id' => $newSearch->getSearchId()])->current(); if (empty($row)) { return false; } $row['finna_search_object'] = serialize(new fminSO($newSearch)); if (!$hash) { $hash = md5(md5($row->search_object) . md5($row->finna_search_object)); } $row->finna_search_id = $hash; $row->save(); $newSearch->setSearchHash($row->finna_search_id); }
/** * Store the URL of the provided search (if appropriate). * * @param \VuFind\Search\Base\Results $results Search results object * * @return void */ protected function rememberSearch($results) { if ($this->rememberSearch) { $searchUrl = $this->url()->fromRoute($results->getOptions()->getSearchAction()) . $results->getUrlQuery()->getParams(false); $this->getSearchMemory()->rememberSearch($searchUrl); } }
/** * Store the URL of the provided search (if appropriate). * * @param \VuFind\Search\Base\Results $results Search results object * * @return void */ protected function rememberSearch($results) { // Only save search URL if the property tells us to... if ($this->rememberSearch) { $searchUrl = $this->url()->fromRoute($results->getOptions()->getSearchAction()) . $results->getUrlQuery()->getParams(false); $this->getSearchMemory()->rememberSearch($searchUrl); } // Always save search parameters, since these are namespaced by search // class ID. $this->getSearchMemory()->rememberParams($results->getParams()); }
/** * 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) { $reorder_coords = []; $filters = $results->getParams()->getFilters(); foreach ($filters as $key => $value) { if ($key == $this->geoField) { $match = []; if (preg_match('/Intersects\\(ENVELOPE\\((.*), (.*), (.*), (.*)\\)\\)/', $value[0], $match)) { array_push($this->bboxSearchCoords, (double) $match[1], (double) $match[2], (double) $match[3], (double) $match[4]); // Need to reorder coords from WENS to WSEN array_push($reorder_coords, (double) $match[1], (double) $match[4], (double) $match[2], (double) $match[3]); $this->selectedCoordinates = $reorder_coords; } $this->searchParams = $results->getUrlQuery()->removeFacet($this->geoField, $value[0], false); } } if ($this->searchParams == null) { $this->searchParams = $results->getUrlQuery()->getParams(false); } $this->searchFilters = $results->getParams()->getBackendParameters(); $this->searchQuery = $results->getParams()->getQuery(); }