Passed
Pull Request — master (#5831)
by
unknown
09:59
created

ReinscriptionCheckCommand::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
nc 1
nop 3
dl 0
loc 9
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\Session;
10
use Chamilo\CoreBundle\Entity\SessionRelUser;
11
use Chamilo\CourseBundle\Entity\CLp;
12
use Chamilo\CourseBundle\Repository\CLpRepository;
13
use Chamilo\CoreBundle\Repository\SessionRepository;
14
use Chamilo\CourseBundle\Entity\CLpView;
15
use Doctrine\ORM\EntityManagerInterface;
16
use Symfony\Component\Console\Command\Command;
17
use Symfony\Component\Console\Input\InputInterface;
18
use Symfony\Component\Console\Output\OutputInterface;
19
use Symfony\Component\Console\Input\InputOption;
20
21
class ReinscriptionCheckCommand extends Command
22
{
23
    protected static $defaultName = 'app:reinscription-check';
24
25
    private CLpRepository $lpRepository;
26
    private SessionRepository $sessionRepository;
27
    private EntityManagerInterface $entityManager;
28
29
    public function __construct(
30
        CLpRepository $lpRepository,
31
        SessionRepository $sessionRepository,
32
        EntityManagerInterface $entityManager
33
    ) {
34
        parent::__construct();
35
        $this->lpRepository = $lpRepository;
36
        $this->sessionRepository = $sessionRepository;
37
        $this->entityManager = $entityManager;
38
    }
39
40
    protected function configure(): void
41
    {
42
        $this
43
            ->setDescription('Checks for users whose course completions have expired and reinscribe them into new sessions if needed.')
44
            ->addOption(
45
                'debug',
46
                null,
47
                InputOption::VALUE_NONE,
48
                'If set, debug messages will be shown.'
49
            );
50
    }
51
52
    protected function execute(InputInterface $input, OutputInterface $output): int
53
    {
54
        $debug = $input->getOption('debug');
55
56
        $expiredViews = $this->lpRepository->findExpiredViews(0);
57
58
        if ($debug) {
59
            $output->writeln(sprintf('Found %d expired views.', count($expiredViews)));
60
        }
61
62
        foreach ($expiredViews as $view) {
63
            $user = $view->getUser();
64
            $session = $view->getSession();
65
            $lp = $view->getLp();
66
67
            if ($debug) {
68
                $output->writeln(sprintf(
69
                    'User %d completed course %d associated with session %d, and its validity has expired.',
70
                    $user->getId(),
71
                    $lp->getIid(),
72
                    $session->getId()
73
                ));
74
            }
75
76
            // Check if the session is marked as the last repetition
77
            if ($session->getLastRepetition()) {
78
                if ($debug) {
79
                    $output->writeln('The session is marked as the last repetition. Skipping...');
80
                }
81
                continue;
82
            }
83
84
            // Find a valid child session
85
            $validChildSession = $this->sessionRepository->findValidChildSession($session);
86
87
            if ($validChildSession) {
88
                $this->enrollUserInSession($user, $validChildSession);
89
                if ($debug) {
90
                    $output->writeln(sprintf(
91
                        'User %d re-enrolled into the valid child session %d.',
92
                        $user->getId(),
93
                        $validChildSession->getId()
94
                    ));
95
                }
96
                continue;
97
            }
98
99
            // If no valid child session exists, check the parent session
100
            $validParentSession = $this->sessionRepository->findValidParentSession($session);
101
102
            if ($validParentSession) {
103
                $this->enrollUserInSession($user, $validParentSession);
104
                if ($debug) {
105
                    $output->writeln(sprintf(
106
                        'User %d re-enrolled into the valid parent session %d.',
107
                        $user->getId(),
108
                        $validParentSession->getId()
109
                    ));
110
                }
111
            } else {
112
                if ($debug) {
113
                    $output->writeln(sprintf(
114
                        'No valid child or parent session found for user %d.',
115
                        $user->getId()
116
                    ));
117
                }
118
            }
119
        }
120
121
        return Command::SUCCESS;
122
    }
123
124
    /**
125
     * Find users with expired completion based on "validity_in_days".
126
     */
127
    private function findExpiredCompletions($lp, $validityDays)
0 ignored issues
show
Unused Code introduced by
The method findExpiredCompletions() 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...
128
    {
129
        $now = new \DateTime();
130
        $expirationDate = (clone $now)->modify('-' . $validityDays . ' days');
131
132
        // Find users with 100% completion and whose last access date (start_time) is older than 'validity_in_days'
133
        return $this->entityManager->getRepository(CLpView::class)
134
            ->createQueryBuilder('v')
135
            ->innerJoin('Chamilo\CourseBundle\Entity\CLpItemView', 'iv', 'WITH', 'iv.view = v')
136
            ->where('v.lp = :lp')
137
            ->andWhere('v.progress = 100')
138
            ->andWhere('iv.startTime < :expirationDate')
139
            ->setParameter('lp', $lp)
140
            ->setParameter('expirationDate', $expirationDate->getTimestamp())
141
            ->getQuery()
142
            ->getResult();
143
    }
144
145
    /**
146
     * Enrolls a user into a session.
147
     */
148
    private function enrollUserInSession($user, $session): void
149
    {
150
        $existingSubscription = $this->findUserSubscriptionInSession($user, $session);
151
152
        if (!$existingSubscription) {
153
            $session->addUserInSession(Session::STUDENT, $user);
154
            $this->entityManager->persist($session);
155
            $this->entityManager->flush();
156
        }
157
    }
158
159
    private function findUserSubscriptionInSession($user, $session)
160
    {
161
        return $this->entityManager->getRepository(SessionRelUser::class)
162
            ->findOneBy([
163
                'user' => $user,
164
                'session' => $session,
165
            ]);
166
    }
167
}
168