Ejemplo n.º 1
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);
         }
     }
 }