<?php declare(strict_types=1); /* * This file is part of newsmailer bundle for Contao. * * (c) Benjamin Roth * * @license LGPL-3.0-or-later */ namespace vonRotenberg\NewsmailerBundle\Cron; use Contao\Config; use Contao\ContentModel; use Contao\Controller; use Contao\CoreBundle\Monolog\ContaoContext; use Contao\CoreBundle\ServiceAnnotation\CronJob; use Contao\Date; use Contao\MemberGroupModel; use Contao\MemberModel; use Contao\NewsArchiveModel; use Contao\StringUtil; use Doctrine\DBAL\Connection; use NotificationCenter\Model\Notification; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; /** * @CronJob("minutely") */ class SendNewsNotificationJob { /** @var LoggerInterface */ private $logger; /** @var Connection */ private $db; public function __construct(Connection $db, LoggerInterface $logger) { $this->logger = $logger; $this->db = $db; } public function __invoke(string $scope) { list($admin_name,$admin_email) = StringUtil::splitFriendlyEmail(Config::get('adminEmail')); // Get archives with notifications enabled $Archives = NewsArchiveModel::findBy('nc_enable','1'); if ($Archives !== null) { list($admin_name,$admin_email) = StringUtil::splitFriendlyEmail(Config::get('adminEmail')); while ($Archives->next()) { $Archive = $Archives->current(); $arrGroupIds = StringUtil::deserialize($Archive->nc_notification_groups,true); $time = Date::floorToMinute(); // Do we have new news items $News = $this->db->executeQuery("SELECT id, alias, headline, `date`, teaser FROM tl_news WHERE pid = ? AND nc_sent != '1' AND date <='$time' AND (start='' OR start<='$time') AND (stop='' OR stop>'" . ($time + 60) . "') AND published='1' ORDER BY `date` DESC, `time` DESC",[$Archive->id]); $arrNewsIds = array(); // Load groups and notification models if we have news to share if ($News->rowCount() && ($Notification = Notification::findByPk($Archive->nc_notification)) !== null && ($Groups = MemberGroupModel::findMultipleByIds($arrGroupIds)) !== null) { while ($Groups->next()) { // Skip disabled groups if ($Groups->disable) { continue; } // Get group members $Members = MemberModel::findBy(array("`groups` LIKE '%\"".$Groups->id."\"%'","(start='' OR start<='$time') AND (stop='' OR stop>'" . ($time + 60) . "') AND disable=''"),null); // Send notification to each member if ($Members !== null) { $arrNews = array(); $arrNewsPlain = array(); foreach ($News->iterateAssociative() as $item) { $strText = ''; $objContentElement = ContentModel::findPublishedByPidAndTable($item['id'], 'tl_news'); if ($objContentElement !== null) { while ($objContentElement->next()) { $strText .= Controller::getContentElement($objContentElement->current()); } } $arrRow = array( 'date' => date('d.m.Y',$item['date']), 'headline' => $item['headline'], 'teaser' => $item['teaser'] ? StringUtil::substr(strip_tags(str_ireplace(array('<br />','<br>','<br/>','</p>','<p>'),' ',$item['teaser'])),128) : '', 'text_plain' => $strText ? strip_tags(str_ireplace(array('<br />','<br>','<br/>','</p>','<p>'),' ',$strText)) : ($item['teaser'] ? strip_tags(str_ireplace(array('<br />','<br>','<br/>','</p>','<p>'),' ',$item['teaser'])) : ''), 'text_html' => $strText ?: $item['teaser'] ); if (($objJumpTo = $Archive->getRelated('jumpTo')) !== null) { // $arrRow['url'] = $objJumpTo->getAbsoluteUrl(sprintf((Config::get('useAutoItem') ? '/%s' : '/items/%s'),$item['alias'])).'?ltoken=%%_TOKEN_%%'; $arrRow['url'] = $objJumpTo->getAbsoluteUrl(sprintf((Config::get('useAutoItem') ? '/%s' : '/items/%s'),$item['alias'])); } $arrNews[] = $arrRow; $arrNewsPlain[] = date('d.m.Y',$item['date']).' - '.$item['headline']; $arrNewsHtml[] = '<div style="margin-bottom: 15px;"><h3>'.$arrRow['date'].' '.$arrRow['headline'].'</h3><p>'.$arrRow['teaser'].'</p>'. ($arrRow['url'] ? '<p><a href="'.$arrRow['url'].'">» Ganze Nachricht lesen...</a></p>' : '') .'</div>'; $arrNewsFullPlain[] = date('d.m.Y',$item['date']).' - '.$item['headline'] . "\n" . $arrRow['text_plain']; $arrNewsFullHtml[] = '<div style="margin-bottom: 15px;"><h3>'.$arrRow['date'].' '.$arrRow['headline'].'</h3>' . $arrRow['text_html'] . ($arrRow['url'] ? '<p><a href="'.$arrRow['url'].'">» Ganze Nachricht lesen...</a></p>' : '') .'</div>'; $arrNewsIds[] = $item['id']; } while ($Members->next()) { if (!$Members->nc_news_subscribe) { continue; } //$strToken = \TokenLogin::getOrRenewUserToken($Members->current()); $strToken = ''; $Notification->send(array ( 'member_email' => $Members->email.($Members->nc_news_additionalEmail ? ','.$Members->nc_news_additionalEmail : ''), 'member_firstname' => $Members->firstname, 'member_lastname' => $Members->lastname, 'news_topics' => implode("\n",$arrNewsPlain), 'news_topics_html' => "<ul>\n<li>".str_replace('%%_TOKEN_%%',$strToken,implode("</li>\n<li>",$arrNewsHtml))."</li>\n</ul>", 'news_full' => implode("\n",$arrNewsFullPlain), 'news_full_html' => implode("",$arrNewsFullHtml), 'member_login_token' => $strToken, 'admin_email' => $admin_email, ), $GLOBALS['TL_LANGUAGE']); } } } // Flag news as sent if (count($arrNewsIds)) { $strNewsIds = implode(',',$arrNewsIds); $this->db->executeStatement("UPDATE tl_news SET nc_sent = '1' WHERE id IN ($strNewsIds)"); } $this->logger->log(LogLevel::INFO, 'News notifications has been sent', array('contao' => new ContaoContext(__METHOD__, 'CRON'))); } } } } }