Passed
Push — dependabot/npm_and_yarn/microm... ( f2f212...f35bf2 )
by
unknown
13:36 queued 05:58
created

SendCourseExpirationEmailsCommand   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 65
c 1
b 0
f 0
dl 0
loc 115
rs 10
wmc 13

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getAdministratorName() 0 7 1
A sendEmailToUser() 0 27 2
A __construct() 0 7 1
A configure() 0 6 1
B execute() 0 55 8
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Command;
8
9
use Chamilo\CoreBundle\Entity\Session;
10
use Chamilo\CoreBundle\Entity\User;
11
use Chamilo\CoreBundle\Settings\SettingsManager;
12
use DateTime;
13
use DateTimeZone;
14
use Doctrine\ORM\EntityManagerInterface;
15
use Symfony\Component\Console\Command\Command;
16
use Symfony\Component\Console\Input\InputInterface;
17
use Symfony\Component\Console\Input\InputOption;
18
use Symfony\Component\Console\Output\OutputInterface;
19
use Symfony\Component\Console\Style\SymfonyStyle;
20
use Symfony\Component\Mailer\MailerInterface;
21
use Symfony\Component\Mime\Email;
22
use Twig\Environment;
23
use UserManager;
24
25
class SendCourseExpirationEmailsCommand extends Command
26
{
27
    protected static $defaultName = 'app:send-course-expiration-emails';
28
29
    public function __construct(
30
        private readonly EntityManagerInterface $entityManager,
31
        private readonly SettingsManager $settingsManager,
32
        private readonly MailerInterface $mailer,
33
        private readonly Environment $twig
34
    ) {
35
        parent::__construct();
36
    }
37
38
    protected function configure(): void
39
    {
40
        $this
41
            ->setDescription('Send an email to users when their course is finished.')
42
            ->addOption('debug', null, InputOption::VALUE_NONE, 'Enable debug mode')
43
            ->setHelp('This command sends an email to users whose course session is expiring today.');
44
    }
45
46
    protected function execute(InputInterface $input, OutputInterface $output): int
47
    {
48
        $io = new SymfonyStyle($input, $output);
49
        $debug = $input->getOption('debug');
50
        $now = new DateTime('now', new DateTimeZone('UTC'));
51
        $endDate = $now->format('Y-m-d');
52
53
        if ($debug) {
54
            error_log('Debug mode activated');
55
            $io->note('Debug mode activated');
56
        }
57
58
        $isActive = 'true' === $this->settingsManager->getSetting('crons.cron_remind_course_expiration_activate');
59
60
        if (!$isActive) {
61
            if ($debug) {
62
                error_log('Cron job for course expiration emails is not active.');
63
                $io->note('Cron job for course expiration emails is not active.');
64
            }
65
            return Command::SUCCESS;
66
        }
67
68
        $sessionRepo = $this->entityManager->getRepository(Session::class);
69
        $sessions = $sessionRepo->createQueryBuilder('s')
70
            ->where('s.accessEndDate LIKE :date')
71
            ->setParameter('date', "$endDate%")
72
            ->getQuery()
73
            ->getResult();
74
75
        if (empty($sessions)) {
76
            $io->success("No sessions finishing today $endDate");
77
            return Command::SUCCESS;
78
        }
79
80
        $administrator = [
81
            'complete_name' => $this->getAdministratorName(),
82
            'email' => $this->settingsManager->getSetting('admin.administrator_email'),
83
        ];
84
85
        foreach ($sessions as $session) {
86
            $sessionUsers = $session->getUsers();
87
88
            if (empty($sessionUsers)) {
89
                $io->warning('No users to send mail for session: ' . $session->getTitle());
90
                continue;
91
            }
92
93
            foreach ($sessionUsers as $sessionUser) {
94
                $user = $sessionUser->getUser();
95
                $this->sendEmailToUser($user, $session, $administrator, $io, $debug);
96
            }
97
        }
98
99
        $io->success('Emails sent successfully for sessions expiring today.');
100
        return Command::SUCCESS;
101
    }
102
103
    private function getAdministratorName(): string
104
    {
105
        return api_get_person_name(
106
            $this->settingsManager->getSetting('admin.administrator_name'),
107
            $this->settingsManager->getSetting('admin.administrator_surname'),
108
            null,
109
            PERSON_NAME_EMAIL_ADDRESS
110
        );
111
    }
112
113
    private function sendEmailToUser(User $user, Session $session, array $administrator, SymfonyStyle $io, bool $debug): void
114
    {
115
        $siteName = $this->settingsManager->getSetting('platform.site_name');
116
117
        $subject = $this->twig->render('@ChamiloCore/Mailer/Legacy/cron_course_finished_subject.html.twig', [
118
            'session_name' => $session->getTitle(),
119
        ]);
120
121
        $body = $this->twig->render('@ChamiloCore/Mailer/Legacy/cron_course_finished_body.html.twig', [
122
            'complete_user_name' => UserManager::formatUserFullName($user),
123
            'session_name' => $session->getTitle(),
124
            'site_name' => $siteName,
125
        ]);
126
127
        $email = (new Email())
128
            ->from($administrator['email'])
129
            ->to($user->getEmail())
130
            ->subject($subject)
131
            ->html($body);
132
133
        $this->mailer->send($email);
134
135
        if ($debug) {
136
            error_log("Email sent to: " . UserManager::formatUserFullName($user) . " ({$user->getEmail()})");
137
            $io->note("Email sent to: " . UserManager::formatUserFullName($user) . " ({$user->getEmail()})");
138
            $io->note("Session: {$session->getTitle()}");
139
            $io->note("End date: {$session->getAccessEndDate()->format('Y-m-d h:i')}");
140
        }
141
    }
142
}
143