<?php
namespace Diplix\KMGBundle\Console\Command;
use Diplix\Commons\DataHandlingBundle\Entity\SysLogEntry;
use Diplix\Commons\DataHandlingBundle\Repository\SysLogRepository;
use Diplix\KMGBundle\Entity\Order;
use Diplix\KMGBundle\Entity\OrderStatus;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Exception\CommandNotFoundException;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
/**
* Wrap all commands to be run with a single cron call in one command
*/
class CronCommand extends BaseCommand
{
public function __construct(
protected EntityManagerInterface $em,
protected LoggerInterface $log,
protected ParameterBagInterface $params,
?string $name = null)
{
parent::__construct($name);
}
protected function configure()
{
$this
->setName('kmg:cron')
;
}
protected function runCommand($commandName,$arguments = array(),OutputInterface $output)
{
try
{
$command = $this->getApplication()->find($commandName);
$cmdIn = new ArrayInput($arguments);
$command->run($cmdIn,$output);
return true;
}
catch (CommandNotFoundException $ex)
{
$output->writeln("<error>Command not found: ".$commandName."</error>");
return false;
}
}
protected function actuallyExecute(InputInterface $input, OutputInterface $output)
{
// $this->runCommand("tami:updatestatus",array(),$output);
$this->runCommand("notifications:send",[],$output);
$this->runCommand("telegram:updates",[],$output);
$this->runCommand("kmg:runallocator",[],$output);
$this->confirmRides($this->log);
}
protected function confirmRides(LoggerInterface $log)
{
$repo = $this->em->getRepository(Order::class);
$timeThreshold = (new \DateTime())->modify("- 120 minutes"); // fahrt schon mind. 2h alt
$oldThreshold = (new \DateTime())->modify("- 180 minutes"); // aber fahrten nicht älter als 3h
$qb = $repo
->createQueryBuilder('A')
->leftJoin('A.customer','C')
->andWhere('A.assignedTo is not null')
->andWhere('A.assignmentConfirmed = 1')
->andWhere('A.orderStatus = :status')->setParameter('status',OrderStatus::STATUS_VERMITTELT)
->andWhere('A.orderTime <= :time')->setParameter('time',$timeThreshold->format('Y-m-d H:i:s'))
->andWhere('A.orderTime >= :old')->setParameter('old',$oldThreshold->format('Y-m-d H:i:s'));
$orders = $qb->getQuery()->getResult();
$lmm = sprintf('%d Bestellungen im Status vermittelt werden aktualisiert',count($orders));
$log->info($lmm);
if (count($orders)>0)
{
SysLogRepository::logMessage($this->em->getConnection(),SysLogEntry::SYS_INFO,$lmm);
}
$stat = $this->em->getReference(OrderStatus::class, OrderStatus::STATUS_FINISHED);
/** @var Order $order */
foreach ($orders as $order)
{
$order->setOrderStatus($stat);
}
$this->em->flush();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
// todo: refactor so that only error messages get printed.
// todo: by that we can make use of the fact that console output can be automatically mailed to the admin
$output->writeln(date("[Y-m-d H:i]")." >> CRON START ");
// check for execution lock
$lockFile = $this->params->get('dx.temp_dir')."cron.lock";
$lastRunFile = $this->params->get('dx.temp_dir')."cron.lastrun";
if (file_exists($lockFile))
{
$lockinfo = file_get_contents($lockFile);
$output->writeln(sprintf("There is already a running instance of CronCommand (Lock: %s). Aborting.",$lockinfo));
return \Symfony\Component\Console\Command\Command::FAILURE;
}
try
{
$r = file_put_contents($lockFile,date("d.m.Y H:i.s"),LOCK_EX);
if ($r === false)
{
$output->writeln("Unable to aquire a lock. Aborting.");
return \Symfony\Component\Console\Command\Command::FAILURE;
}
// Run the actual commands
$this->actuallyExecute($input,$output);
file_put_contents($lastRunFile,date("U"));
}
finally
{
// remove lock
$r = unlink($lockFile);
if (!$r)
{
$output->writeln("Warning: Unable to remove lock.");
}
}
// ... and we're done
$output->writeln(date("[Y-m-d H:i]")." >> CRON END ");
return \Symfony\Component\Console\Command\Command::SUCCESS;
}
}