作者:bbeckma
项目:NDL-VuFind
/**
* 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;
}
作者:bbeckma
项目:NDL-VuFind
/**
* 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;
}
作者:grharr
项目:vufin
/**
* 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());
}
作者:grharr
项目:vufin
/**
* 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;
}
作者:till
项目:vufin
/**
* 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);
}
作者:till
项目:vufin
/**
* 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;
}
作者:CUSA
项目:vufin
/**
* 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);
}
}
作者:till
项目:vufin
/**
* 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;
}
作者:bbeckma
项目:NDL-VuFind
/**
* 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;
}
作者:paulusov
项目:VuFind-2.
/**
* 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));
}
}
}
}
作者:bbeckma
项目:NDL-VuFind
/**
* 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);
}
}
}
作者:bbeckma
项目:NDL-VuFind
/**
* 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);
}
作者:grharr
项目:vufin
/**
* 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];
}
作者:paulusov
项目:VuFind-2.
/**
* 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;
}
作者:bbeckma
项目:NDL-VuFind
/**
* 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);
}
作者:datavoyage
项目:vufin
/**
* 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));
}
}
}
}
作者:bbeckma
项目:NDL-VuFind
/**
* 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];
}
作者:till
项目:vufin
/**
* 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);
}
作者:steenlibrar
项目:vufin
/**
* 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;
}
作者:till
项目:vufin
/**
* 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;
}