src/CoreBundle/Command/SendCourseExpirationEmailsCommand.php
<?php
/* For licensing terms, see /license.txt */
declare(strict_types=1);
namespace Chamilo\CoreBundle\Command;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Settings\SettingsManager;
use DateTime;
use DateTimeZone;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Twig\Environment;
use UserManager;
class SendCourseExpirationEmailsCommand extends Command
{
/**
* @var string
*/
protected static $defaultName = 'app:send-course-expiration-emails';
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly SettingsManager $settingsManager,
private readonly MailerInterface $mailer,
private readonly Environment $twig
) {
parent::__construct();
}
protected function configure(): void
{
$this
->setDescription('Send an email to users when their course is finished.')
->addOption('debug', null, InputOption::VALUE_NONE, 'Enable debug mode')
->setHelp('This command sends an email to users whose course session is expiring today.')
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$debug = $input->getOption('debug');
$now = new DateTime('now', new DateTimeZone('UTC'));
$endDate = $now->format('Y-m-d');
if ($debug) {
error_log('Debug mode activated');
$io->note('Debug mode activated');
}
$isActive = 'true' === $this->settingsManager->getSetting('crons.cron_remind_course_expiration_activate');
if (!$isActive) {
if ($debug) {
error_log('Cron job for course expiration emails is not active.');
$io->note('Cron job for course expiration emails is not active.');
}
return Command::SUCCESS;
}
$sessionRepo = $this->entityManager->getRepository(Session::class);
$sessions = $sessionRepo->createQueryBuilder('s')
->where('s.accessEndDate LIKE :date')
->setParameter('date', "$endDate%")
->getQuery()
->getResult()
;
if (empty($sessions)) {
$io->success("No sessions finishing today $endDate");
return Command::SUCCESS;
}
$administrator = [
'complete_name' => $this->getAdministratorName(),
'email' => $this->settingsManager->getSetting('admin.administrator_email'),
];
foreach ($sessions as $session) {
$sessionUsers = $session->getUsers();
if (empty($sessionUsers)) {
$io->warning('No users to send mail for session: '.$session->getTitle());
continue;
}
foreach ($sessionUsers as $sessionUser) {
$user = $sessionUser->getUser();
$this->sendEmailToUser($user, $session, $administrator, $io, $debug);
}
}
$io->success('Emails sent successfully for sessions expiring today.');
return Command::SUCCESS;
}
private function getAdministratorName(): string
{
return api_get_person_name(
$this->settingsManager->getSetting('admin.administrator_name'),
$this->settingsManager->getSetting('admin.administrator_surname'),
null,
PERSON_NAME_EMAIL_ADDRESS
);
}
private function sendEmailToUser(User $user, Session $session, array $administrator, SymfonyStyle $io, bool $debug): void
{
$siteName = $this->settingsManager->getSetting('platform.site_name');
$subject = $this->twig->render('@ChamiloCore/Mailer/Legacy/cron_course_finished_subject.html.twig', [
'session_name' => $session->getTitle(),
]);
$body = $this->twig->render('@ChamiloCore/Mailer/Legacy/cron_course_finished_body.html.twig', [
'complete_user_name' => UserManager::formatUserFullName($user),
'session_name' => $session->getTitle(),
'site_name' => $siteName,
]);
$email = (new Email())
->from($administrator['email'])
->to($user->getEmail())
->subject($subject)
->html($body)
;
$this->mailer->send($email);
if ($debug) {
error_log('Email sent to: '.UserManager::formatUserFullName($user)." ({$user->getEmail()})");
$io->note('Email sent to: '.UserManager::formatUserFullName($user)." ({$user->getEmail()})");
$io->note("Session: {$session->getTitle()}");
$io->note("End date: {$session->getAccessEndDate()->format('Y-m-d h:i')}");
}
}
}