/** * Expose parent method since we need to use it from SearchTabs. * * @param array $a Array of parameters to turn into a GET string * @param bool $escape Should we escape the string for use in the view? * * @return string */ public function buildQueryString($a, $escape = true) { return parent::buildQueryString($a, $escape); }
/** * 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); } } }
/** * Get an array of URL parameters. * * @return array */ public function getParamArray() { $params = parent::getParamArray(); $filter = $this->params->getSpatialDateRangeFilter(); if ($filter && isset($filter['type']) && isset($filter['query'])) { $field = $this->params->getSpatialDateRangeField() . '_type'; $params[$field] = $filter['type']; } if ($set = $this->params->getMetaLibSearchSet()) { $params['set'] = $set; } return $params; }
/** * Get an array of URL parameters. * * @return array */ public function getParamArray() { $params = parent::getParamArray(); $filter = $this->params->getSpatialDateRangeFilter(); if ($filter && isset($filter['type'])) { $field = $this->params->getSpatialDateRangeField() . '_type'; $params[$field] = $filter['type']; } return $params; }