<?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\WeinanlieferungBundle\Cron; use Contao\Config; use Contao\CoreBundle\Monolog\ContaoContext; use Contao\CoreBundle\ServiceAnnotation\CronJob; use Contao\Date; use Contao\MemberModel; use Contao\StringUtil; use Contao\System; use Doctrine\DBAL\Connection; use NotificationCenter\Model\Notification; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungLageModel; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungLeseartModel; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungRebsorteModel; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungSlotsModel; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungStandortModel; /** * @CronJob("*\/10 * * * *") */ class SendSlotChangeNotificationJob { /** @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) { System::loadLanguageFile('default','de'); list($admin_name,$admin_email) = StringUtil::splitFriendlyEmail(Config::get('adminEmail')); $intNotificationsCount = 0; // Get locations $Locations = WeinanlieferungStandortModel::findBy('nc_enable','1'); if ($Locations !== null) { while ($Locations->next()) { $Location = $Locations->current(); $time = Date::floorToMinute(); // Get members $memberGroupIds = StringUtil::deserialize($Location->nc_notification_groups,true); $memberGroupSqlFragment = []; if (!count($memberGroupIds)) { continue; } foreach ($memberGroupIds as $memberGroupId) { $memberGroupSqlFragment[] = "`groups` LIKE '%\"$memberGroupId\"%'"; } $Members = MemberModel::findBy(array("(".implode(' OR ',$memberGroupSqlFragment).")","(start='' OR start<='$time') AND (stop='' OR stop>'" . ($time + 60) . "') AND disable=''"),null); // Do we have updateable items $Slots = $this->db->executeQuery("SELECT s.id, s.date, s.time, s.duration, s.behaelter, s.sorten, s.ernteart, s.lage, s.anmerkungen, s.nc_sent, s.buchbar_ab, s.buchbar_bis FROM tl_vr_wa_slot s WHERE s.pid = ? AND s.nc_sent < s.tstamp AND s.published='1' AND (buchbar_ab='' OR buchbar_ab<='$time') AND (buchbar_bis='' OR buchbar_bis>'" . ($time + 60) . "')",[$Location->id]); // Load groups and notification models if we have news to share if ($Members !== null && $Slots->rowCount() && ($Notification = Notification::findByPk($Location->nc_notification_slots)) !== null) { foreach ($Slots->iterateAssociative() as $Slot) { $arrSortenAvailable = []; $arrErnteartAvailable = []; $arrLageAvailable = []; $arrSortenBooked = []; $arrErnteartBooked = []; $arrLageBooked = []; $SlotModel = WeinanlieferungSlotsModel::findByPk($Slot['id']); if (isset($Slot['slot_sorten'])) { $SortenLeseart = StringUtil::deserialize($Slot['sorten'],true); foreach($SortenLeseart as $sorteLeseart) { $objSorte = WeinanlieferungRebsorteModel::findByPk($sorteLeseart['sorte']); $objLeseart = WeinanlieferungLeseartModel::findByPk($sorteLeseart['leseart']); $arrSortenAvailable[$objSorte->id.','.$objLeseart->id] = ($objSorte !== null ? $objSorte->title : '') . ' ' . ($objLeseart !== null ? $objLeseart->title : ''); } } if (isset($Slot['ernteart'])) { foreach (explode(',', $Slot['ernteart']) as $ernteart) { $arrErnteartAvailable[$ernteart] = $GLOBALS['TL_LANG']['REF']['wa_ernteart'][$ernteart] ?? $ernteart; } } if (isset($Slot['lage'])) { foreach (explode(',', $Slot['lage']) as $lage) { if (($Lage = WeinanlieferungLageModel::findByPk($lage)) !== null) { $arrLageAvailable[$Lage->id] = $Lage->title; } } } // Send notification to member foreach ($Members as $Member) { $Notification->send(array ( 'member_email' => $Member->email . ($Member->nc_news_additionalEmail ? ',' . $Member->nc_news_additionalEmail : ''), 'member_firstname' => $Member->firstname, 'member_lastname' => $Member->lastname, 'member_memberno' => $Member->memberno, 'slot_date' => Date::parse(Date::getNumericDateFormat(),$Slot['date']), 'slot_time' => Date::parse(Date::getNumericTimeFormat(),$Slot['time']), 'slot_standort' => $Location->title, 'slot_behaelter' => $Slot['behaelter'], 'slot_behaelterBuchbar' => $SlotModel !== null ? $SlotModel->getAvailableBehaelter() : '', 'slot_sorten' => implode(', ',$arrSortenAvailable), 'slot_ernteart' => implode(', ',$arrErnteartAvailable), 'slot_lage' => implode(', ',$arrLageAvailable), 'slot_anmerkungen' => $Slot['anmerkungen'], 'slot_ncsent' => $Slot['nc_sent'], 'slot_buchbar_ab' => Date::parse(Date::getNumericDatimFormat(),$Slot['buchbar_ab']), 'slot_buchbar_bis' => Date::parse(Date::getNumericDatimFormat(),$Slot['buchbar_bis']), 'admin_email' => $admin_email, ), $GLOBALS['TL_LANGUAGE']); $intNotificationsCount++; } $this->db->executeStatement("UPDATE tl_vr_wa_slot SET nc_sent = ? WHERE id = ?",[$time,$Slot['id']]); } } } // Flag news as sent if ($intNotificationsCount) { $this->logger->log(LogLevel::INFO, sprintf('WA notifications(%s) has been sent',$intNotificationsCount), array('contao' => new ContaoContext(__METHOD__, 'CRON'))); } } } }