/** * Return Primo search parameters based on a user query and params. * * @param AbstractQuery $query User query * * @return ParamBag */ public function build(AbstractQuery $query) { // Send back results $params = new ParamBag(); $params->set('query', $this->abstractQueryToArray($query)); return $params; }
/** * Create search backend parameters for advanced features. * * @return ParamBag */ public function getBackendParameters() { $backendParams = new ParamBag(); // Sort $sort = $this->getSort(); $backendParams->set('sortKeys', empty($sort) ? 'relevance' : $sort); return $backendParams; }
/** * Test "merge with all" * * @return void */ public function testMergeWithAll() { $bag1 = new ParamBag(['a' => 1]); $bag2 = new ParamBag(['b' => 2]); $bag3 = new ParamBag(['c' => 3]); $bag3->mergeWithAll([$bag1, $bag2]); $this->assertEquals(['a' => [1], 'b' => [2], 'c' => [3]], $bag3->getArrayCopy()); }
/** * Return Summon search parameters based on a user query and params. * * @param AbstractQuery $query User query * * @return ParamBag */ public function build(AbstractQuery $query) { // Build base query $queryStr = $this->abstractQueryToString($query); // Send back results $params = new ParamBag(); $params->set('query', $queryStr); return $params; }
/** * Test the listener without setting an authorization service. * This should return an empty array. * * @return void */ public function testFilterTranslation() { $params = new ParamBag(['fq' => ['foo:value', 'baz:"foo:value"', 'foofoo:value', "foo\\:value", 'baz:value OR foo:value', '(foo:value)']]); $listener = new FilterFieldConversionListener(['foo' => 'bar', 'baz' => 'boo']); $backend = $this->getMockBuilder('VuFindSearch\\Backend\\Solr\\Backend')->disableOriginalConstructor()->getMock(); $event = new Event('pre', $backend, ['params' => $params]); $listener->onSearchPre($event); $fq = $params->get('fq'); $expected = ['bar:value', 'boo:"foo:value"', 'foofoo:value', "foo\\:value", 'boo:value OR bar:value', '(bar:value)']; $this->assertEquals($expected, $fq); }
/** * Create search backend parameters for advanced features. * * @return ParamBag */ public function getBackendParameters() { $backendParams = new ParamBag(); // The "relevance" sort option is a VuFind reserved word; we need to make // this null in order to achieve the desired effect with Primo: $sort = $this->getSort(); $finalSort = $sort == 'relevance' ? null : $sort; $backendParams->set('sort', $finalSort); $backendParams->set('filterList', $this->filterList); return $backendParams; }
/** * Return LibGuides search parameters based on a user query and params. * * @param AbstractQuery $query User query * * @return ParamBag */ public function build(AbstractQuery $query) { // Send back results $params = new ParamBag(); // Convert the query to an array, then flatten that to a string // (right now, we're ignoring a lot of data -- we may want to // revisit this and see if more detail can be utilized). $array = $this->abstractQueryToArray($query); if (isset($array[0]['lookfor'])) { $params->set('search', $array[0]['lookfor']); } return $params; }
/** * Return WorldCat search parameters based on a user query and params. * * @param AbstractQuery $query User query * * @return ParamBag */ public function build(AbstractQuery $query) { // Build base query $queryStr = $this->abstractQueryToString($query); // Exclude current library from results (if applicable) if (null !== $this->oclcCodeToExclude) { $queryStr .= ' not srw.li all "' . $this->oclcCodeToExclude . '"'; } // Send back results $params = new ParamBag(); $params->set('query', $queryStr); return $params; }
/** * Create search backend parameters for advanced features. * * @return ParamBag */ public function getBackendParameters() { $backendParams = new ParamBag(); // Sources $sources = $this->getSelectedShards(); if (!empty($sources)) { $allShards = $this->getOptions()->getShards(); foreach ($sources as $i => $current) { $sources[$i] = $allShards[$current]; } $backendParams->set('filter', 'pz:id=' . implode('|', $sources)); } return $backendParams; }
/** * Set up filters based on VuFind settings. * * @param ParamBag $params Parameter collection to update * * @return void */ public function createBackendFilterParameters(ParamBag $params) { // flag our non-Standard checkbox filters: $foundIncludeNewspapers = false; # includeNewspapers $foundIncludeWithoutFulltext = false; # includeWithoutFulltext $filterList = $this->getFilterList(); // Which filters should be applied to our query? if (!empty($filterList)) { // Loop through all filters and add appropriate values to request: foreach ($filterList as $filterArray) { foreach ($filterArray as $filt) { $safeValue = SummonQuery::escapeParam($filt['value']); if ($filt['field'] == 'holdingsOnly') { // Special case -- "holdings only" is a separate parameter from // other facets. $params->set('holdings', strtolower(trim($safeValue)) == 'true'); } else { if ($filt['field'] == 'excludeNewspapers') { // support a checkbox for excluding newspapers: // this is now the default behaviour. } else { if ($filt['field'] == 'includeNewspapers') { // explicitly include newspaper articles $foundIncludeNewspapers = true; } else { if ($range = SolrUtils::parseRange($filt['value'])) { // Special case -- range query (translate [x TO y] syntax): $from = SummonQuery::escapeParam($range['from']); $to = SummonQuery::escapeParam($range['to']); $params->add('rangeFilters', "PublicationDate,{$from}:{$to}"); } else { if ($filt['field'] == 'includeWithoutFulltext') { $foundIncludeWithoutFulltext = true; } else { // Standard case: $params->add('filters', "{$filt['field']},{$safeValue}"); } } } } } } } } // special cases (apply also when filter list is empty) // newspaper articles if (!$foundIncludeNewspapers) { // this actually means: do *not* show newspaper articles $params->add('filters', "ContentType,Newspaper Article,true"); } // combined facet "with holdings/with fulltext" if (!$foundIncludeWithoutFulltext) { $params->set('holdings', true); $params->add('filters', 'IsFullText,true'); } else { $params->set('holdings', false); } }
/** * Perform a search and return record collection. * * @param AbstractQuery $query Search query * @param integer $offset Search offset * @param integer $limit Search limit * @param ParamBag $params Search backend parameters * * @return RecordCollectionInterface */ public function search(AbstractQuery $query, $offset, $limit, ParamBag $params = null) { if (null === $params) { $params = new ParamBag(); } $params->mergeWith($this->getQueryBuilder()->build($query)); $response = $this->connector->search($params, $offset, $limit); $this->log('debug', print_r($response, true)); $collection = $this->createRecordCollection($response); $this->injectSourceIdentifier($collection); return $collection; }
/** * Returns browser usage statistics * * @param bool $version Include the version numbers in the list * @param int $listLength How many items to return * * @return array */ public function getBrowserStats($version, $listLength = 5) { $query = new Query('*:*'); $params = new ParamBag(); $params->add('fl', 'browser,browserVersion'); $params->add('group', 'true'); $params->add('group.field', 'session'); $start = 0; $limit = 1000; $hashes = []; do { $response = $this->solrBackend->search($query, $start, $limit, $params); $groups = $response->getGroups(); foreach ($groups['session']['groups'] as $group) { if ($version) { // Version specific $browser = $group['doclist']['docs'][0]['browser'] . ' ' . $group['doclist']['docs'][0]['browserVersion']; if (isset($hashes[$browser])) { $hashes[$browser]++; } elseif (count($hashes) < $limit) { $hashes[$browser] = 1; } } else { // Browser name if (isset($hashes[$group['doclist']['docs'][0]['browser']])) { $hashes[$group['doclist']['docs'][0]['browser']]++; } elseif (count($hashes) < $limit) { $hashes[$group['doclist']['docs'][0]['browser']] = 1; } } } $start += $limit; } while (count($groups['session']['groups']) > 0); $solrBrowsers = []; foreach ($hashes as $browser => $count) { $newBrowser = ['browserName' => $browser, 'count' => $count]; // Insert sort (limit to listLength) for ($i = 0; $i < $listLength - 1 && $i < count($solrBrowsers); $i++) { if ($count > $solrBrowsers[$i]['count']) { // Insert in order array_splice($solrBrowsers, $i, 0, [$newBrowser]); continue 2; // Skip the append after this loop } } if (count($solrBrowsers) < $listLength) { $solrBrowsers[] = $newBrowser; } } return $solrBrowsers; }
/** * Submit requests for more spelling suggestions. * * @param Spellcheck $spellcheck Aggregating spellcheck object * @param string $query Spellcheck query * * @return void */ protected function aggregateSpellcheck(Spellcheck $spellcheck, $query) { while (next($this->dictionaries) !== false) { $params = new ParamBag(); $params->set('spellcheck', 'true'); $params->set('spellcheck.dictionary', current($this->dictionaries)); $queryObj = new Query($query, 'AllFields'); try { $collection = $this->backend->search($queryObj, 0, 0, $params); $spellcheck->mergeWith($collection->getSpellcheck()); } catch (\Exception $ex) { if ($this->logger) { $this->logger->err("Exception thrown when aggregating spellcheck, ignoring.", array('exception' => $ex)); } } } }
/** * Set up expanders based on VuFind settings. * * @param ParamBag $params Parameter collection to update * * @return void */ public function createBackendExpanderParameters(ParamBag $params) { // Which filters should be applied to our query? if (!empty($this->expanders)) { // Loop through all filters and add appropriate values to request: $value = ''; foreach ($this->expanders as $expander) { $value = !empty($value) ? $value . ',' . $expander : $expander; } if (!empty($value)) { $params->add('expander', $value); } } }
/** * Test that loading a record overrides the shard settings. * * @return void */ public function testAllShardsUsedForRecordRetrieval() { $params = new ParamBag(['shards' => [self::$shards['b'], self::$shards['c']]]); $event = new Event('pre', $this->backend, ['params' => $params, 'context' => 'retrieve']); $this->listener->onSearchPre($event); $shards = $params->get('shards'); $this->assertEquals([implode(',', [self::$shards['a'], self::$shards['b'], self::$shards['c']])], $shards); }
/** * Execute a search. * * @param ParamBag $params Parameters * @param integer $offset Search offset * @param integer $limit Search limit * * @return string */ public function search(ParamBag $params, $offset, $limit) { $params->set('startRecord', $offset); $params->set('maximumRecords', $limit); $params->set('servicelevel', 'full'); $params->set('wskey', $this->wskey); $response = $this->call('POST', $params->getArrayCopy(), false); $xml = simplexml_load_string($response); $docs = isset($xml->records->record) ? $xml->records->record : []; $finalDocs = []; foreach ($docs as $doc) { $finalDocs[] = $doc->recordData->asXML(); } return ['docs' => $finalDocs, 'offset' => $offset, 'total' => isset($xml->numberOfRecords) ? (int) $xml->numberOfRecords : 0]; }
/** * Return SOLR search parameters based on a user query and params. * * @param AbstractQuery $query User query * * @return ParamBag */ public function build(AbstractQuery $query) { $params = new ParamBag(); // Add spelling query if applicable -- note that we mus set this up before // we process the main query in order to avoid unwanted extra syntax: if ($this->createSpellingQuery) { $params->set('spellcheck.q', $query->getAllTerms()); } if ($query instanceof QueryGroup) { $query = $this->reduceQueryGroup($query); } else { $query->setString($this->getLuceneHelper()->normalizeSearchString($query->getString())); } $string = $query->getString() ?: '*:*'; if ($handler = $this->getSearchHandler($query->getHandler(), $string)) { if (!$handler->hasExtendedDismax() && $this->getLuceneHelper()->containsAdvancedLuceneSyntax($string)) { $newString = $this->createAdvancedInnerSearchString($string, $handler); if ($handler->hasDismax()) { $oldString = $newString; $newString = $handler->createBoostQueryString($newString); // If a boost was added, we don't want to highlight based on // the boost query, so we should use the non-boosted version: if ($this->createHighlightingQuery && $oldString != $string) { $params->set('hl.q', $oldString); } if ($string == '*:*') { $params->set('hl.q', '*:*'); } } $string = $newString; } else { if ($handler->hasDismax()) { $params->set('qf', implode(' ', $handler->getDismaxFields())); $params->set('qt', $handler->getDismaxHandler()); foreach ($handler->getDismaxParams() as $param) { $params->add(reset($param), next($param)); } if ($handler->hasFilterQuery()) { $params->add('fq', $handler->getFilterQuery()); } } else { $string = $handler->createSimpleQueryString($string); } } } $params->set('q', $string); return $params; }
/** * Check if MetaLib databases are searchable. * * @return \Zend\Http\Response */ public function metalibLinksAjax() { $this->disableSessionWrites(); // avoid session write timing bug $config = $this->getServiceLocator()->get('VuFind\\Config')->get('MetaLib'); if (!isset($config->General->enabled) || !$config->General->enabled) { throw new \Exception('MetaLib is not enabled'); } $auth = $this->serviceLocator->get('ZfcRbac\\Service\\AuthorizationService'); $authorized = $auth->isGranted('finna.authorized'); $query = new Query(); $metalib = $this->getServiceLocator()->get('VuFind\\Search'); $results = []; $ids = $this->getRequest()->getQuery()->get('id'); foreach ($ids as $id) { $backendParams = new ParamBag(); $backendParams->add('irdInfo', [$id]); $result = $metalib->search('MetaLib', $query, false, false, $backendParams); $info = $result->getIRDInfo(); $status = null; if ($info && ($authorized || strcasecmp($info['access'], 'guest') == 0)) { $status = $info['searchable'] ? 'allowed' : 'nonsearchable'; } else { $status = 'denied'; } $results = ['id' => $id, 'status' => $status]; } return $this->output($results, self::STATUS_OK); }
/** * Set up filters based on VuFind settings. * * @param ParamBag $params Parameter collection to update * * @return void */ public function createBackendFilterParameters(ParamBag $params) { // Which filters should be applied to our query? $filterList = $this->getFilterList(); if (!empty($filterList)) { $orFacets = []; // Loop through all filters and add appropriate values to request: foreach ($filterList as $filterArray) { foreach ($filterArray as $filt) { $safeValue = SummonQuery::escapeParam($filt['value']); // Special case -- "holdings only" is a separate parameter from // other facets. if ($filt['field'] == 'holdingsOnly') { $params->set('holdings', strtolower(trim($safeValue)) == 'true'); } else { if ($filt['field'] == 'queryExpansion') { // Special case -- "query expansion" is a separate parameter // from other facets. $params->set('expand', strtolower(trim($safeValue)) == 'true'); } else { if ($filt['field'] == 'excludeNewspapers') { // Special case -- support a checkbox for excluding // newspapers: $params->add('filters', "ContentType,Newspaper Article,true"); } else { if ($range = SolrUtils::parseRange($filt['value'])) { // Special case -- range query (translate [x TO y] syntax): $from = SummonQuery::escapeParam($range['from']); $to = SummonQuery::escapeParam($range['to']); $params->add('rangeFilters', "{$filt['field']},{$from}:{$to}"); } else { if ($filt['operator'] == 'OR') { // Special case -- OR facets: $orFacets[$filt['field']] = isset($orFacets[$filt['field']]) ? $orFacets[$filt['field']] : []; $orFacets[$filt['field']][] = $safeValue; } else { // Standard case: $fq = "{$filt['field']},{$safeValue}"; if ($filt['operator'] == 'NOT') { $fq .= ',true'; } $params->add('filters', $fq); } } } } } } // Deal with OR facets: foreach ($orFacets as $field => $values) { $params->add('groupFilters', $field . ',or,' . implode(',', $values)); } } } }
/** * Execute a search. * * @param ParamBag $params Parameters * @param int $offset Search offset * @param int $limit Search limit * * @return array */ public function search(ParamBag $params, $offset, $limit) { $startrec = $offset + 1; $params->set('startrec', $startrec); $params->set('numrec', $limit); $params->set('prof', $this->prof); $params->set('pwd', $this->pwd); $response = $this->call('GET', $params->getArrayCopy(), false); $xml = simplexml_load_string($response); $finalDocs = []; foreach ($xml->SearchResults->records->rec as $doc) { $finalDocs[] = simplexml_load_string($doc->asXML()); } return ['docs' => $finalDocs, 'offset' => $offset, 'total' => (int) $xml->Hits]; }
/** * Apply query defaults, appends, invariants. * * @param ParamBag $params Parameters * @param array $defaults Query defaults * @param array $appends Query appends * @param array $invariants Query invariants * * @return void */ protected function apply(ParamBag $params, array $defaults, array $appends, array $invariants) { $final = $params->getArrayCopy(); $final = array_replace($defaults, $final); $final = array_merge_recursive($final, $appends); $final = array_replace($final, $invariants); $params->exchangeArray($final); }
/** * Retrieve a single document. * * @param string $id Document identifier * @param ParamBag $params Search backend parameters * * @return \VuFindSearch\Response\RecordCollectionInterface */ public function retrieve($id, ParamBag $params = null) { try { $authenticationToken = $this->getAuthenticationToken(); // check to see if the profile is overriden $overrideProfile = null !== $params ? $params->get('profile') : null; if (isset($overrideProfile)) { $this->profile = $overrideProfile; } $sessionToken = $this->getSessionToken(); $parts = explode(',', $id, 2); if (!isset($parts[1])) { throw new BackendException('Retrieval id is not in the correct format.'); } list($dbId, $an) = $parts; $hlTerms = null != $params ? $params->get('highlightterms') : null; $response = $this->client->retrieve($an, $dbId, $authenticationToken, $sessionToken, $hlTerms); } catch (\EbscoEdsApiException $e) { // if the auth or session token was invalid, try once more switch ($e->getApiErrorCode()) { case 104: case 108: case 109: try { // For error 104, retry auth token; for 108/9, retry sess token: if ($e->getApiErrorCode() == 104) { $authenticationToken = $this->getAuthenticationToken(true); } else { $sessionToken = $this->getSessionToken(true); } $response = $this->client->retrieve($an, $dbId, $authenticationToken, $sessionToken, $hlTerms); } catch (Exception $e) { throw new BackendException($e->getMessage(), $e->getCode(), $e); } break; default: throw $e; } } $collection = $this->createRecordCollection(['Records' => $response]); $this->injectSourceIdentifier($collection); return $collection; }
/** * Gathers data for the view of the AlphaBrowser and does some initialization * * @return \Zend\View\Model\ViewModel */ public function homeAction() { $config = $this->getConfig(); // Load browse types from config file, or use defaults if unavailable: if (isset($config->AlphaBrowse_Types) && !empty($config->AlphaBrowse_Types)) { $types = []; foreach ($config->AlphaBrowse_Types as $key => $value) { $types[$key] = $value; } } else { $types = ['topic' => 'By Topic', 'author' => 'By Author', 'title' => 'By Title', 'lcc' => 'By Call Number']; } // Load any extras from config file $extras = []; if (isset($config->AlphaBrowse_Extras)) { foreach ($config->AlphaBrowse_Extras as $key => $value) { $extras[$key] = $value; } } else { $extras = ['title' => 'author:format:publishDate', 'lcc' => 'title', 'dewey' => 'title']; } // Load remaining config parameters $rows_before = isset($config->AlphaBrowse->rows_before) && is_numeric($config->AlphaBrowse->rows_before) ? (int) $config->AlphaBrowse->rows_before : 0; $highlighting = isset($config->AlphaBrowse->highlighting) ? $config->AlphaBrowse->highlighting : false; $limit = isset($config->AlphaBrowse->page_size) && is_numeric($config->AlphaBrowse->page_size) ? (int) $config->AlphaBrowse->page_size : 20; // Connect to Solr: $db = $this->getServiceLocator()->get('VuFind\\Search\\BackendManager')->get('Solr'); // Process incoming parameters: $source = $this->params()->fromQuery('source', false); $from = $this->params()->fromQuery('from', false); $page = intval($this->params()->fromQuery('page', 0)); // Special case: highlighting is pointless if there's no user input: if (empty($from)) { $highlighting = false; } // Set up any extra parameters to pass $extraParams = new ParamBag(); if (isset($extras[$source])) { $extraParams->add('extras', $extras[$source]); } // Create view model: $view = $this->createViewModel(); // If required parameters are present, load results: if ($source && $from !== false) { // Load Solr data or die trying: $result = $db->alphabeticBrowse($source, $from, $page, $limit, $extraParams, 0 - $rows_before); // No results? Try the previous page just in case we've gone past // the end of the list.... if ($result['Browse']['totalCount'] == 0) { $page--; $result = $db->alphabeticBrowse($source, $from, $page, $limit, $extraParams, 0); if ($highlighting) { $view->highlight_end = true; } } // Only display next/previous page links when applicable: if ($result['Browse']['totalCount'] > $limit) { $view->nextpage = $page + 1; } if ($result['Browse']['offset'] + $result['Browse']['startRow'] > 1) { $view->prevpage = $page - 1; } $view->result = $result; } // set up highlighting: page 0 contains match location if ($highlighting && $page == 0) { $startRow = $result['Browse']['startRow']; // solr counts rows from 1; adjust to array position style $startRow_adj = $startRow - 1; $offset = $result['Browse']['offset']; $totalRows = $result['Browse']['totalCount']; $totalRows += $startRow + $offset > 0 ? $startRow_adj + $offset : 0; // normal case: somewhere in the middle of the browse list $highlight_row = $rows_before; // special case: match row is < rows_before (i.e. at beginning of list) if ($startRow_adj < $rows_before) { $highlight_row = $startRow_adj; } // special case: we've gone past the end // only the rows_before records will have been returned if ($startRow > $totalRows) { $view->highlight_end = true; } $view->highlight_row = $highlight_row; $view->match_type = $result['Browse']['matchType']; } $view->alphaBrowseTypes = $types; $view->from = $from; $view->source = $source; // Pass information about extra columns on to theme $view->extras = isset($extras[$source]) ? explode(':', $extras[$source]) : []; return $view; }
/** * Create search backend parameters for advanced features. * * @return ParamBag */ public function getBackendParameters() { $backendParams = new ParamBag(); // Spellcheck $backendParams->set('spellcheck', $this->getOptions()->spellcheckEnabled() ? 'true' : 'false'); // Facets $facets = $this->getFacetSettings(); if (!empty($facets)) { $backendParams->add('facet', 'true'); foreach ($facets as $key => $value) { // prefix keys with "facet" unless they already have a "f." prefix: $fullKey = substr($key, 0, 2) == 'f.' ? $key : "facet.{$key}"; $backendParams->add($fullKey, $value); } $backendParams->add('facet.mincount', 1); } // Filters $filters = $this->getFilterSettings(); foreach ($filters as $filter) { $backendParams->add('fq', $filter); } // Shards $allShards = $this->getOptions()->getShards(); $shards = $this->getSelectedShards(); if (empty($shards)) { $shards = array_keys($allShards); } // If we have selected shards, we need to format them: if (!empty($shards)) { $selectedShards = []; foreach ($shards as $current) { $selectedShards[$current] = $allShards[$current]; } $shards = $selectedShards; $backendParams->add('shards', implode(',', $selectedShards)); } // Sort $sort = $this->getSort(); if ($sort) { // If we have an empty search with relevance sort, see if there is // an override configured: if ($sort == 'relevance' && $this->getQuery()->getAllTerms() == '' && ($relOv = $this->getOptions()->getEmptySearchRelevanceOverride())) { $sort = $relOv; } $backendParams->add('sort', $this->normalizeSort($sort)); } // Highlighting -- on by default, but we should disable if necessary: if (!$this->getOptions()->highlightEnabled()) { $backendParams->add('hl', 'false'); } // Pivot facets for visual results if ($pf = $this->getPivotFacets()) { $backendParams->add('facet.pivot', $pf); } return $backendParams; }
/** * AggregateSpellcheck * * @param Spellcheck $spellcheck Spellcheck * @param string $query Query * * @return void */ protected function aggregateSpellcheck(Spellcheck $spellcheck, $query) { foreach ($this->dictionaries as $dictionary) { $params = new ParamBag(); $params->set('spellcheck', 'true'); $params->set('spellcheck.dictionary', $dictionary); $queryObj = new Query($query, 'AllFields'); $collection = $this->backend->search($queryObj, 0, 0, $params); $spellcheck->mergeWith($collection->getSpellcheck()); } }
/** * Test the listener if no permission controller exists * * @return void */ public function testOnCampusNoPermissionController() { $params = new ParamBag([]); $listener = new InjectOnCampusListener(); $event = new Event('pre', $this->backend, ['params' => $params]); $listener->onSearchPre($event); $onCampus = $params->get('onCampus'); $this->assertEquals([0 => false], $onCampus); }
/** * Create search backend parameters for advanced features. * * @return ParamBag */ public function getBackendParameters() { $backendParams = new ParamBag(); // Spellcheck $backendParams->set('spellcheck', $this->getOptions()->spellcheckEnabled() ? 'true' : 'false'); // Facets $facets = $this->getFacetSettings(); if (!empty($facets)) { $backendParams->add('facet', 'true'); if (isset($facets['indexSortedFacets'])) { foreach ($facets['indexSortedFacets'] as $field) { $backendParams->add("f.{$field}.facet.sort", 'index'); } unset($facets['indexSortedFacets']); } foreach ($facets as $key => $value) { if (substr($key, 0, strlen(self::PER_FIELD_PARAM)) === self::PER_FIELD_PARAM) { $backendParams->add($key, $value); } else { $backendParams->add("facet.{$key}", $value); } } $backendParams->add('facet.mincount', 1); } // Filters $filters = $this->getFilterSettings(); foreach ($filters as $filter) { $backendParams->add('fq', $filter); } // Shards $allShards = $this->getOptions()->getShards(); $shards = $this->getSelectedShards(); if (empty($shards)) { $shards = array_keys($allShards); } // If we have selected shards, we need to format them: if (!empty($shards)) { $selectedShards = []; foreach ($shards as $current) { $selectedShards[$current] = $allShards[$current]; } $shards = $selectedShards; $backendParams->add('shards', implode(',', $selectedShards)); } // Sort $sort = $this->getSort(); if ($sort) { // If we have an empty search with relevance sort, see if there is // an override configured: if ($sort == 'relevance' && $this->getQuery()->getAllTerms() == '' && ($relOv = $this->getOptions()->getEmptySearchRelevanceOverride())) { $sort = $relOv; } $backendParams->add('sort', $this->normalizeSort($sort)); } // Highlighting -- on by default, but we should disable if necessary: if (!$this->getOptions()->highlightEnabled()) { $backendParams->add('hl', 'false'); } // Pivot facets for visual results if ($pf = $this->getPivotFacets()) { $backendParams->add('facet.pivot', $pf); } if (!empty($this->boostFunctions)) { foreach ($this->boostFunctions as $func) { $backendParams->add('boost', $func); } } return $backendParams; }
/** * Retrieve a batch of documents. * * @param array $ids Array of document identifiers * @param ParamBag $params Search backend parameters * * @return RecordCollectionInterface */ public function retrieveBatch($ids, ParamBag $params = null) { $onCampus = null !== $params ? $params->get('onCampus') : [false]; $onCampus = $onCampus ? $onCampus[0] : false; // Load 100 records at a time; this is a good number to avoid memory // problems while still covering a lot of ground. $pageSize = 100; // Retrieve records a page at a time: $results = false; while (count($ids) > 0) { $currentPage = array_splice($ids, 0, $pageSize, []); try { $response = $this->connector->getRecords($currentPage, $this->connector->getInstitutionCode(), $onCampus); } catch (\Exception $e) { throw new BackendException($e->getMessage(), $e->getCode(), $e); } $next = $this->createRecordCollection($response); if (!$results) { $results = $next; } else { foreach ($next->getRecords() as $record) { $results->add($record); } } } $this->injectSourceIdentifier($results); return $results; }
/** * Create search backend parameters for advanced features. * * @return ParamBag */ public function getBackendParameters() { $backendParams = new ParamBag(); // Spellcheck $backendParams->set('spellcheck', $this->getOptions()->spellcheckEnabled() ? 'true' : 'false'); // Facets $facets = $this->getFacetSettings(); if (!empty($facets)) { $backendParams->add('facet', 'true'); foreach ($facets as $key => $value) { $backendParams->add("facet.{$key}", $value); } $backendParams->add('facet.mincount', 1); } // Filters $filters = $this->getFilterSettings(); foreach ($filters as $filter) { $backendParams->add('fq', $filter); } // Shards $allShards = $this->getOptions()->getShards(); $shards = $this->getSelectedShards(); if (empty($shards)) { $shards = array_keys($allShards); } // If we have selected shards, we need to format them: if (!empty($shards)) { $selectedShards = []; foreach ($shards as $current) { $selectedShards[$current] = $allShards[$current]; } $shards = $selectedShards; $backendParams->add('shards', implode(',', $selectedShards)); } // Sort $sort = $this->getSort(); if ($sort) { $backendParams->add('sort', $this->normalizeSort($sort)); } // Highlighting -- on by default, but we should disable if necessary: if (!$this->getOptions()->highlightEnabled()) { $backendParams->add('hl', 'false'); } // Pivot facets for visual results if ($pf = $this->getPivotFacets()) { $backendParams->add('facet.pivot', $pf); } return $backendParams; }
/** * Test the listener with preset fq-parameters * if the conditional filter is granted * * @return void */ public function testConditionalFilterWithFQ() { $params = new ParamBag(['fq' => ['fulltext:Vufind', 'field2:novalue']]); $listener = new InjectConditionalFilterListener(self::$searchConfig); $mockAuth = $this->getMockBuilder('ZfcRbac\\Service\\AuthorizationService')->disableOriginalConstructor()->getMock(); $mockAuth->expects($this->any())->method('isGranted')->with($this->equalTo('conditionalFilter.sample'))->will($this->returnValue(true)); $listener->setAuthorizationService($mockAuth); $event = new Event('pre', $this->backend, ['params' => $params]); $listener->onSearchPre($event); $fq = $params->get('fq'); $this->assertEquals([0 => 'fulltext:Vufind', 1 => 'field2:novalue', 2 => 'institution:"MyInst"'], $fq); }