Passed
Pull Request — master (#5831)
by
unknown
07:50
created

SessionRepetitionCommand::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 5
nc 1
nop 4
dl 0
loc 11
rs 10
c 1
b 0
f 0
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\AccessUrl;
10
use Chamilo\CoreBundle\Entity\Session;
11
use Chamilo\CoreBundle\Repository\SessionRepository;
12
use Doctrine\ORM\EntityManagerInterface;
13
use Symfony\Component\Console\Command\Command;
14
use Symfony\Component\Console\Input\InputInterface;
15
use Symfony\Component\Console\Output\OutputInterface;
16
use Symfony\Component\Console\Input\InputOption;
17
use Symfony\Component\Mailer\MailerInterface;
18
use Symfony\Component\Mime\Email;
19
use Symfony\Contracts\Translation\TranslatorInterface;
20
21
class SessionRepetitionCommand extends Command
22
{
23
    protected static $defaultName = 'app:session-repetition';
24
25
    private SessionRepository $sessionRepository;
26
    private EntityManagerInterface $entityManager;
27
    private MailerInterface $mailer;
28
    private TranslatorInterface $translator;
29
30
    public function __construct(
31
        SessionRepository $sessionRepository,
32
        EntityManagerInterface $entityManager,
33
        MailerInterface $mailer,
34
        TranslatorInterface $translator
35
    ) {
36
        parent::__construct();
37
        $this->sessionRepository = $sessionRepository;
38
        $this->entityManager = $entityManager;
39
        $this->mailer = $mailer;
40
        $this->translator = $translator;
41
    }
42
43
    protected function configure(): void
44
    {
45
        $this
46
            ->setDescription('Automatically duplicates sessions that meet the repetition criteria.')
47
            ->addOption('debug', null, InputOption::VALUE_NONE, 'Enable debug mode');
48
    }
49
50
    protected function execute(InputInterface $input, OutputInterface $output): int
51
    {
52
        $debug = $input->getOption('debug');
53
54
        // Find sessions that meet the repetition criteria
55
        $sessions = $this->sessionRepository->findSessionsWithoutChildAndReadyForRepetition();
56
57
        if ($debug) {
58
            $output->writeln(sprintf('Found %d session(s) ready for repetition.', count($sessions)));
59
        }
60
61
        foreach ($sessions as $session) {
62
            if ($debug) {
63
                $output->writeln(sprintf('Processing session: %d', $session->getId()));
64
            }
65
66
            // Duplicate session
67
            $newSession = $this->duplicateSession($session, $debug, $output);
68
69
            // Notify general coach of the new session
70
            $this->notifyGeneralCoach($newSession, $debug, $output);
71
72
            $output->writeln('Created new session: ' . $newSession->getId() . ' from session: ' . $session->getId());
73
        }
74
75
        return Command::SUCCESS;
76
    }
77
78
    /**
79
     * Duplicates a session and creates a new session with adjusted dates.
80
     */
81
    private function duplicateSession(Session $session, bool $debug, OutputInterface $output): Session
82
    {
83
        // Calculate new session dates based on the duration of the original session
84
        $duration = $session->getAccessEndDate()->diff($session->getAccessStartDate());
85
        $newStartDate = (clone $session->getAccessEndDate())->modify('+1 day');
86
        $newEndDate = (clone $newStartDate)->add($duration);
87
88
        if ($debug) {
89
            $output->writeln(sprintf(
90
                'Duplicating session %d. New start date: %s, New end date: %s',
91
                $session->getId(),
92
                $newStartDate->format('Y-m-d H:i:s'),
93
                $newEndDate->format('Y-m-d H:i:s')
94
            ));
95
        }
96
97
        // Create a new session with the same details as the original session
98
        $newSession = new Session();
99
        $newSession
100
            ->setTitle($session->getTitle() . ' (Repetition ' . $session->getId() . ' - ' . time() . ')')
101
            ->setAccessStartDate($newStartDate)
102
            ->setAccessEndDate($newEndDate)
103
            ->setDisplayStartDate($newStartDate)
104
            ->setDisplayEndDate($newEndDate)
105
            ->setCoachAccessStartDate($newStartDate)
106
            ->setCoachAccessEndDate($newEndDate)
107
            ->setVisibility($session->getVisibility())
108
            ->setDuration($session->getDuration())
109
            ->setDescription($session->getDescription() ?? '')
110
            ->setShowDescription($session->getShowDescription() ?? false)
111
            ->setCategory($session->getCategory())
112
            ->setPromotion($session->getPromotion())
113
            ->setDaysToReinscription($session->getDaysToReinscription())
114
            ->setDaysToNewRepetition($session->getDaysToNewRepetition())
115
            ->setParentId($session->getId())
116
            ->setLastRepetition(false);
117
118
        // Copy the AccessUrls from the original session
119
        foreach ($session->getUrls() as $accessUrl) {
120
            $newSession->addAccessUrl($accessUrl->getUrl());
121
        }
122
123
        // Copy the courses from the original session
124
        foreach ($session->getCourses() as $course) {
125
            $newSession->addCourse($course);
126
        }
127
128
        // Copy the general coaches from the original session
129
        foreach ($session->getGeneralCoaches() as $coach) {
130
            $newSession->addGeneralCoach($coach);
131
        }
132
133
        // Save the new session
134
        $this->entityManager->persist($newSession);
135
        $this->entityManager->flush();
136
137
        if ($debug) {
138
            $output->writeln(sprintf('New session %d created successfully.', $newSession->getId()));
139
        }
140
141
        return $newSession;
142
    }
143
144
    /**
145
     * Retrieves or creates a default AccessUrl for sessions.
146
     */
147
    private function getDefaultAccessUrl()
0 ignored issues
show
Unused Code introduced by
The method getDefaultAccessUrl() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
148
    {
149
        return $this->entityManager->getRepository(AccessUrl::class)->findOneBy([]);
150
    }
151
152
153
    /**
154
     * Notifies the general coach of the session about the new repetition.
155
     */
156
    private function notifyGeneralCoach(Session $newSession, bool $debug, OutputInterface $output): void
157
    {
158
        $generalCoach = $newSession->getGeneralCoaches()->first();
159
        if ($generalCoach) {
160
            $message = sprintf(
161
                'A new repetition of the session "%s" has been created. Please review the details: %s',
162
                $newSession->getTitle(),
163
                $this->generateSessionSummaryLink($newSession)
164
            );
165
166
            if ($debug) {
167
                $output->writeln(sprintf('Notifying coach (ID: %d) for session %d', $generalCoach->getId(), $newSession->getId()));
168
            }
169
170
            // Send message to the general coach
171
            $this->sendMessage($generalCoach->getEmail(), $message);
172
173
            if ($debug) {
174
                $output->writeln('Notification sent.');
175
            }
176
        } else {
177
            if ($debug) {
178
                $output->writeln('No general coach found for session ' . $newSession->getId());
179
            }
180
        }
181
    }
182
183
    /**
184
     * Sends an email message to a user.
185
     */
186
    private function sendMessage(string $recipientEmail, string $message): void
187
    {
188
        $subject = $this->translator->trans('New Session Repetition Created');
189
190
        $email = (new Email())
191
            ->from('[email protected]')
192
            ->to($recipientEmail)
193
            ->subject($subject)
194
            ->html('<p>' . $message . '</p>');
195
196
        $this->mailer->send($email);
197
    }
198
199
    /**
200
     * Generates a link to the session summary page.
201
     */
202
    private function generateSessionSummaryLink(Session $session): string
203
    {
204
        return '/main/session/resume_session.php?id_session=' . $session->getId();
205
    }
206
}
207