Пример #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->serviceManager->get('VuFind\\Config');
     $this->iniReader = new IniReader();
     $this->iniReader->setNestSeparator(chr(0));
     $hmac = $this->serviceManager->get('VuFind\\HMAC');
     $backend = $this->serviceManager->get('VuFind\\Search\\BackendManager')->get('Solr');
     $viewManager = $this->serviceManager->get('viewmanager');
     $viewModel = $viewManager->getViewModel();
     $renderer = $viewManager->getRenderer();
     $emailer = $this->serviceManager->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 = $this->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->warn('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->serviceManager->get('VuFind\\Translator')->addTranslationFile('ExtendedIni', null, $this::DEFAULT_PATH, $language)->setLocale($language);
         $limit = 50;
         // Prepare query
         $searchService = $this->serviceManager->get('VuFind\\Search');
         $searchObject = $s->getSearchObject();
         if ($searchObject->cl != 'Solr') {
             $this->err('Unsupported search class ' . $s->cl . ' for search ' . $s->id);
             continue;
         }
         $options = new Options($configLoader);
         $dateConverter = new DateConverter();
         $params = new Params($options, $configLoader, $dateConverter);
         $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->serviceManager);
         $filters = $this->processFilters($params->getFilterList());
         $params = ['records' => $newRecords, 'info' => ['baseUrl' => $viewBaseUrl, 'description' => $params->getDisplayQuery(), 'recordCount' => count($newRecords), '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->serviceManager->get('VuFind\\Mailer')->send($to, $from, $subject, $message);
         } catch (\Exception $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);
         }
     }
 }
Пример #2
0
 /**
  * Handler for database and journal browse actions.
  *
  * @param string $type Browse type
  *
  * @return mixed
  */
 protected function browse($type)
 {
     $config = $this->getServiceLocator()->get('VuFind\\Config')->get('browse');
     if (!isset($config['General'][$type]) || !$config['General'][$type]) {
         throw new \Exception("Browse action {$type} is disabled");
     }
     if (!isset($config[$type])) {
         throw new \Exception("Missing configuration for browse action: {$type}");
     }
     // Preserve last result view
     $configLoader = $this->getServiceLocator()->get('VuFind\\Config');
     $options = new Options($configLoader);
     $lastView = $options->getLastView();
     try {
         $config = $config[$type];
         $query = $this->getRequest()->getQuery();
         $query->set('view', 'condensed');
         if (!$query->get('limit')) {
             $query->set('limit', $config['resultLimit'] ?: 100);
         }
         if (!$query->get('sort')) {
             $query->set('sort', $config['sort'] ?: 'title');
         }
         if (!$query->get('type')) {
             $query->set('type', $config['type'] ?: 'Title');
         }
         $queryType = $query->get('type');
         $query->set('hiddenFilters', $config['filter']->toArray() ?: []);
         $query->set('recommendOverride', ['side' => ["SideFacets:Browse{$type}:CheckboxFacets:facets-browse"]]);
         $view = $this->forwardTo('Search', 'Results');
         $view->overrideTitle = "browse_extended_{$type}";
         $type = strtolower($type);
         $view->browse = $type;
         $view->defaultBrowseHandler = $config['type'];
         $view->results->getParams()->setBrowseHandler($queryType);
         // Update last search URL
         $view->results->getParams()->getOptions()->setBrowseAction("browse-{$type}");
         $this->getSearchMemory()->forgetSearch();
         $this->rememberSearch($view->results);
         $view->results->getParams()->getQuery()->setHandler($queryType);
         // Restore last result view
         $view->results->getOptions()->rememberLastView($lastView);
         return $view;
     } catch (\Exception $e) {
         $options->rememberLastView($lastView);
     }
 }