<?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')));
}
}
}
}