예제 #1
0
파일: Params.php 프로젝트: grharry/vufind
 /**
  * Build a string for onscreen display showing the
  *   query used in the search (not the filters).
  *
  * @return string user friendly version of 'query'
  */
 public function getDisplayQuery()
 {
     // For display purposes, undo the query manipulation performed above
     // in initBasicSearch():
     $q = parent::getDisplayQuery();
     return str_replace('\\"', '"', substr($q, 1, -1));
 }
예제 #2
0
 /**
  * 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) . " ]");
 }
예제 #3
0
파일: NewItems.php 프로젝트: tillk/vufind
 /**
  * Figure out which bib IDs to load from the ILS.
  *
  * @param \VuFind\ILS\Connection                     $catalog ILS connection
  * @param \VuFind\Search\Solr\Params                 $params  Solr parameters
  * @param string                                     $range   Range setting
  * @param string                                     $dept    Department setting
  * @param \Zend\Mvc\Controller\Plugin\FlashMessenger $flash   Flash messenger
  *
  * @return array
  */
 public function getBibIDsFromCatalog($catalog, $params, $range, $dept, $flash)
 {
     // The code always pulls in enough catalog results to get a fixed number
     // of pages worth of Solr results.  Note that if the Solr index is out of
     // sync with the ILS, we may see fewer results than expected.
     $resultPages = $this->getResultPages();
     $perPage = $params->getLimit();
     $newItems = $catalog->getNewItems(1, $perPage * $resultPages, $range, $dept);
     // Build a list of unique IDs
     $bibIDs = [];
     for ($i = 0; $i < count($newItems['results']); $i++) {
         $bibIDs[] = $newItems['results'][$i]['id'];
     }
     // Truncate the list if it is too long:
     $limit = $params->getQueryIDLimit();
     if (count($bibIDs) > $limit) {
         $bibIDs = array_slice($bibIDs, 0, $limit);
         $flash->setNamespace('info')->addMessage('too_many_new_items');
     }
     return $bibIDs;
 }
예제 #4
0
 /**
  * Set parameters based on a search object
  *
  * @param \Zend\StdLib\Parameters $request Parameter object representing user
  * request.
  *
  * @return void
  */
 public function initFromRequest($request)
 {
     parent::initFromRequest($request);
     // Force custom facet settings:
     $this->facetConfig = array();
     $this->addFacet('authorStr');
     $this->setFacetOffset(($this->getPage() - 1) * $this->getLimit());
     $this->setFacetLimit($this->getLimit() * 10);
     // Sorting - defaults to off with unlimited facets, so let's
     //           be explicit here for simplicity.
     if ($this->getSort() == 'author') {
         $this->setFacetSort('index');
     } else {
         $this->setFacetSort('count');
     }
 }
예제 #5
0
 /**
  * Add filters to the object based on values found in the request object.
  *
  * @param \Zend\StdLib\Parameters $request Parameter object representing user
  * request.
  *
  * @return void
  */
 protected function initFilters($request)
 {
     parent::initFilters($request);
     $this->initSpatialDateRangeFilter($request);
     $this->initNewItemsFilter($request);
 }
예제 #6
0
 /**
  * Process one instance of a spelling replacement and modify the return
  *   data structure with the details of what was done.
  *
  * @param string $term        The actually term we're replacing
  * @param string $targetTerm  The term above, or the token it is inside
  * @param bool   $inToken     Flag for whether the token or term is used
  * @param array  $details     The spelling suggestions
  * @param array  $returnArray Return data structure so far
  * @param Params $params      Params helper object
  *
  * @return array              $returnArray modified
  */
 protected function doSingleReplace($term, $targetTerm, $inToken, $details, $returnArray, Params $params)
 {
     $returnArray[$targetTerm]['freq'] = $details['freq'];
     foreach ($details['suggestions'] as $word => $freq) {
         // If the suggested word is part of a token
         if ($inToken) {
             // We need to make sure we replace the whole token
             $replacement = str_replace($term, $word, $targetTerm);
         } else {
             $replacement = $word;
         }
         //  Do we need to show the whole, modified query?
         if ($this->phrase) {
             $label = $params->getDisplayQueryWithReplacedTerm($targetTerm, $replacement);
         } else {
             $label = $replacement;
         }
         // Basic spelling suggestion data
         $returnArray[$targetTerm]['suggestions'][$label] = ['freq' => $freq, 'new_term' => $replacement];
         // Only generate expansions if enabled in config
         if ($this->expand) {
             // Parentheses differ for shingles
             if (strstr($targetTerm, " ") !== false) {
                 $replacement = "(({$targetTerm}) OR ({$replacement}))";
             } else {
                 $replacement = "({$targetTerm} OR {$replacement})";
             }
             $returnArray[$targetTerm]['suggestions'][$label]['expand_term'] = $replacement;
         }
     }
     return $returnArray;
 }
예제 #7
0
파일: Params.php 프로젝트: tillk/vufind
 /**
  * Pull the search parameters
  *
  * @param \Zend\StdLib\Parameters $request Parameter object representing user
  * request.
  *
  * @return void
  */
 public function initFromRequest($request)
 {
     if (null === $this->collectionID) {
         throw new \Exception('Collection ID missing');
     }
     if (null === $this->collectionField) {
         throw new \Exception('Collection field missing');
     }
     parent::initFromRequest($request);
     // We don't spellcheck this screen; it's not for free user input anyway
     $options = $this->getOptions();
     $options->spellcheckEnabled(false);
     // Prepare the search
     $safeId = addcslashes($this->collectionID, '"');
     $options->addHiddenFilter($this->collectionField . ':"' . $safeId . '"');
     $options->addHiddenFilter('!id:"' . $safeId . '"');
 }
예제 #8
0
 /**
  * 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('&amp;', '&', $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);
         }
     }
 }
예제 #9
0
파일: Params.php 프로젝트: htw-pk15/vufind
 /**
  * @override
  *
  * @param string $field Facet field name.
  *
  * @return string       Human-readable description of field.
  */
 public function getFacetLabel($field)
 {
     switch ($field) {
         case 'publishDate':
             return 'adv_search_year';
         default:
             return parent::getFacetLabel($field);
     }
 }