/** * This test performs Solr searches using multifacets and checks whether they work * as expected (adding 'OR something' to filter query should increase count of returned records * in at least one case). */ public function testMultiFacetsSearch() { //configuration $solr = $this->getServiceManager()->get('VuFind\\Search\\BackendManager')->get('Solr'); $connector = $solr->getConnector(); $this->assertNotNull($connector); $config = $this->getServiceManager()->get('VuFind\\Config'); $this->assertNotNull($config); $options = new Options($config); $this->assertNotNull($options); $params = new Params($options, $config); $this->assertNotNull($params); $testedFields = array('institution', 'format'); //try each field foreach ($testedFields as $currentField) { $params->addFacet($currentField, $currentField); $paramBag = $params->getBackendParameters(); $this->assertTrue(is_array($paramBag->get('facet'))); $query = new Query("*:*"); $collection = $solr->search($query, 0, 0, $paramBag); $this->assertNotNull($collection); //get all possible filter values of current facet field $facets = $collection->getFacets()->getFieldFacets()->getArrayCopy(); $list = $facets[$currentField]; $list->rewind(); $allFilters = array(); while ($list->valid()) { $allFilters[] = $list->key(); $list->next(); } for ($i = 0; $i < count($allFilters); $i++) { for ($j = $i + 1; $j < count($allFilters); $j++) { //test all possible pairs of filters for current facet field $params = new Params($options, $config); $params->addFacet($currentField, $currentField); $params->setMultiselectFacets(array($currentField)); $params->addFilter($currentField . ':' . $allFilters[$i]); $paramBag = $params->getBackendParameters(); $collection = $solr->search($query, 0, 0, $paramBag); $this->assertNotNull($collection); $total1 = $collection->getTotal(); $params->addFilter($currentField . ':' . $allFilters[$j]); $paramBag = $params->getBackendParameters(); $collection = $solr->search($query, 0, 0, $paramBag); $this->assertNotNull($collection); $this->assertNotNull($collection); $total2 = $collection->getTotal(); if ($total2 > $total1) { //adding multifacet filter caused increasment of records in search results , we're done return; } } } } $this->fail("Multifacets test failed, multifacets has no effect on solr response." . " Tested fields: [ " . implode(", ", $testedFields) . " ]"); }
/** * @return ParamBag */ public function getSpellcheckBackendParameters() { $backendParams = parent::getBackendParameters(); $backendParams->remove("spellcheck"); //with SOLR 4.3 AND is no longer the default parameter $backendParams->add("q.op", "AND"); //we need this homegrown param to control the behaviour of InjectSwissbibSpellingListener //I don't see another possibilty yet $backendParams->add("swissbibspellcheck", "true"); //$backendParams = $this->addUserInstitutions($backendParams); return $backendParams; }
/** * Create search backend parameters for advanced features. * * @return ParamBag */ public function getBackendParameters() { $result = parent::getBackendParameters(); if ($this->debugQuery) { $result->add('debugQuery', 'true'); } // Restore original sort if we have geographic filters $sort = $this->normalizeSort($this->getSort()); $newSort = $result->get('sort'); if ($newSort && $newSort[0] != $sort) { $filters = $result->get('fq'); if (null !== $filters) { foreach ($filters as $filter) { if (strncmp($filter, '{!geofilt ', 10) == 0) { $newSort[0] = $this->normalizeSort($sort); $result->set('sort', $newSort); break; } } } } return $result; }
/** * Send scheduled alerts for a view. * * @return void */ protected function processViewAlerts() { $this->msg(" Sending scheduled alerts for view: {$this->localDir} " . "(base: {$this->scheduleBaseUrl})"); $iso8601 = 'Y-m-d\\TH:i:s\\Z'; $configLoader = $this->getServiceLocator()->get('VuFind\\Config'); $this->iniReader = new IniReader(); $this->iniReader->setNestSeparator(chr(0)); $hmac = $this->getServiceLocator()->get('VuFind\\HMAC'); $userTable = $this->getTable('User'); $backend = $this->getServiceLocator()->get('VuFind\\Search\\BackendManager')->get('Solr'); $viewManager = $this->getServiceLocator()->get('viewmanager'); $viewModel = $viewManager->getViewModel(); $renderer = $viewManager->getRenderer(); $emailer = $this->getServiceLocator()->get('VuFind\\Mailer'); $translator = $renderer->plugin('translate'); $urlHelper = $renderer->plugin('url'); $todayTime = new \DateTime(); $user = false; $institution = false; $institutionConfigs = false; $scheduled = $this->searchTable->getScheduledSearches($this->scheduleBaseUrl); $this->msg(sprintf(' Processing %d searches', count($scheduled))); foreach ($scheduled as $s) { $lastTime = new \DateTime($s->finna_last_executed); $schedule = $s->finna_schedule; if ($schedule == 1) { // Daily if ($todayTime->format('Y-m-d') == $lastTime->format('Y-m-d')) { $this->msg(' Bypassing search ' . $s->id . ': previous execution too recent (daily, ' . $lastTime->format($iso8601) . ')'); continue; } } else { if ($schedule == 2) { $diff = $todayTime->diff($lastTime); if ($diff->days < 6) { $this->msg(' Bypassing search ' . $s->id . ': previous execution too recent (weekly, ' . $lastTime->format($iso8601) . ')'); continue; } } else { $this->err('Search ' . $s->id . ': unknown schedule: ' . $s->schedule); continue; } } if ($user === false || $s->user_id != $user->id) { if (!($user = $userTable->getById($s->user_id))) { $this->err('Search ' . $s->id . ': user ' . $s->user_id . ' does not exist '); continue; } } if (!$user->email || trim($user->email) == '') { $this->err('User ' . $user->username . ' does not have an email address, bypassing alert ' . $s->id); continue; } $scheduleUrl = parse_url($s->finna_schedule_base_url); if (!isset($scheduleUrl['host'])) { $this->err('Could not resolve institution for search ' . $s->id . ' with schedule_base_url: ' . var_export($scheduleUrl, true)); continue; } // Set email language $language = $this->mainConfig->Site->language; if ($user->finna_language != '' && in_array($user->finna_language, array_keys($this->mainConfig->Languages->toArray()))) { $language = $user->finna_language; } $this->getServiceLocator()->get('VuFind\\Translator')->addTranslationFile('ExtendedIni', null, $this->defaultPath, $language)->setLocale($language); // Prepare query $searchObject = $s->getSearchObject(); $searchService = $this->getServiceLocator()->get('VuFind\\Search'); if ($searchObject->cl != 'Solr') { $this->err('Unsupported search class ' . $s->cl . ' for search ' . $s->id); continue; } $limit = 50; $options = new Options($configLoader); $params = new Params($options, $configLoader); $params->deminify($searchObject); $params->setLimit($limit); $params->setSort('first_indexed+desc'); $query = $params->getQuery(); $searchParams = $params->getBackendParameters(); $searchTime = gmdate($iso8601, time()); try { $collection = $searchService->search('Solr', $query, 0, $limit, $searchParams); $resultsTotal = $collection->getTotal(); if ($resultsTotal < 1) { $this->msg('No results found for search ' . $s->id); continue; } $records = $collection->getRecords(); } catch (\VuFindSearch\Backend\Exception\BackendException $e) { $this->err('Error processing search ' . $s->id . ': ' . $e->getMessage()); } $newestRecordDate = date($iso8601, strtotime($records[0]->getFirstIndexed())); $lastExecutionDate = $lastTime->format($iso8601); if ($newestRecordDate < $lastExecutionDate) { $this->msg('No new results for search ' . $s->id . ": {$newestRecordDate} < {$lastExecutionDate}"); continue; } // Collect records that have been indexed (for the first time) // after previous scheduled alert run $newRecords = []; foreach ($collection->getRecords() as $rec) { $recDate = date($iso8601, strtotime($rec->getFirstIndexed())); if ($recDate < $lastExecutionDate) { break; } $newRecords[] = $rec; } // Prepare email content $viewBaseUrl = $searchUrl = $s->finna_schedule_base_url; $searchUrl .= $urlHelper->__invoke($options->getSearchAction()); $urlQueryHelper = new UrlQueryHelper($params); $searchUrl .= str_replace('&', '&', $urlQueryHelper->getParams()); $secret = $s->getUnsubscribeSecret($hmac, $user); $unsubscribeUrl = $s->finna_schedule_base_url; $unsubscribeUrl .= $urlHelper->__invoke('myresearch-unsubscribe') . "?id={$s->id}&key={$secret}"; $params->setServiceLocator($this->getServiceLocator()); $filters = $this->processFilters($params->getFilterList()); $params = ['records' => $newRecords, 'info' => ['baseUrl' => $viewBaseUrl, 'description' => $params->getDisplayQuery(), 'recordCount' => count($records), 'url' => $searchUrl, 'unsubscribeUrl' => $unsubscribeUrl, 'filters' => $filters]]; $message = $renderer->render('Email/scheduled-alert.phtml', $params); $subject = $this->mainConfig->Site->title . ': ' . $translator->__invoke('Scheduled Alert Results'); $from = $this->mainConfig->Site->email; $to = $user->email; try { $this->getServiceLocator()->get('VuFind\\Mailer')->send($to, $from, $subject, $message); } catch (MailException $e) { $this->err("Failed to send message to {$user->email}: " . $e->getMessage()); continue; } if ($s->setLastExecuted($searchTime) === 0) { $this->msg('Error updating last_executed date for search ' . $s->id); } } }