Passed
Push — master ( 35e116...03a9f3 )
by Angel Fernando Quiroz
10:35 queued 19s
created

Version20250701130500::up()   B

Complexity

Conditions 11
Paths 72

Size

Total Lines 55
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 34
nc 72
nop 1
dl 0
loc 55
rs 7.3166
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\Migrations\Schema\V200;
8
9
use Chamilo\CoreBundle\Entity\Session;
10
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
11
use Doctrine\DBAL\Exception;
12
use Doctrine\DBAL\Schema\Schema;
13
14
class Version20250701130500 extends AbstractMigrationChamilo
15
{
16
    public function getDescription(): string
17
    {
18
        return 'Add access start and end dates to session_rel_user table and migrate dates from first course access';
19
    }
20
21
    /**
22
     * @inheritDoc
23
     */
24
    public function up(Schema $schema): void
25
    {
26
        $this->addSql("ALTER TABLE session_rel_user ADD access_start_date DATETIME DEFAULT NULL COMMENT '(DC2Type:datetime)'");
27
        $this->addSql("ALTER TABLE session_rel_user ADD access_end_date DATETIME DEFAULT NULL COMMENT '(DC2Type:datetime)'");
28
29
        $sessions = $this->getSessionWithNoDuration();
30
31
        foreach ($sessions as $session) {
32
            $sRUs = $this->getSessionRelUsers($session['id']);
33
34
            foreach ($sRUs as $sru) {
35
                $isCoach = $this->isCoach($session['id'], $sru['user_id']);
36
37
                $startDate = $isCoach && $session['coach_access_start_date']
38
                    ? $session['coach_access_start_date']
39
                    : $session['access_start_date'];
40
41
                $endDate = $isCoach && $session['coach_access_end_date']
42
                    ? $session['coach_access_end_date']
43
                    : $session['access_end_date'];
44
45
                $this->addSql(
46
                    'UPDATE session_rel_user SET access_start_date = :startDate, access_end_date = :endDate WHERE id = :id',
47
                    [
48
                        'startDate' => $startDate,
49
                        'endDate' => $endDate,
50
                        'id' => $sru['id'],
51
                    ]
52
                );
53
            }
54
        }
55
56
        $sessions = $this->getSessionWithDuration();
57
58
        foreach ($sessions as $session) {
59
            $sRUs = $this->getSessionRelUsers($session['id']);
60
            
61
            foreach ($sRUs as $sru) {
62
                $duration = (int) $session['duration'] + (int) $sru['duration'];
63
                
64
                $firstAccessToSession = $this->getFirstAccessToSession($session['id'], $sru['user_id']);
65
66
                $calculatedLastAccessToSession = $firstAccessToSession + $duration * 24 * 60 * 60;
67
68
                $startDate = $firstAccessToSession ?: null;
69
                $endDate = $firstAccessToSession ? $calculatedLastAccessToSession : null;
70
71
                $this->addSql(
72
                    'UPDATE session_rel_user
73
                        SET access_start_date = FROM_UNIXTIME(:startDate), access_end_date = FROM_UNIXTIME(:endDate)
74
                        WHERE id = :id',
75
                    [
76
                        'startDate' => $startDate,
77
                        'endDate' => $endDate,
78
                        'id' => $sru['id'],
79
                    ]
80
                );
81
            }
82
        }
83
    }
84
85
    /**
86
     * @throws Exception
87
     */
88
    private function getSessionWithNoDuration(): array
89
    {
90
        return $this->connection
91
            ->executeQuery(
92
                'SELECT
93
                    id,
94
                    display_start_date, display_end_date,
95
                    access_start_date, access_end_date,
96
                    coach_access_start_date, coach_access_end_date
97
                FROM session
98
                WHERE (duration IS NULL OR duration = 0)'
99
            )
100
            ->fetchAllAssociative()
101
        ;
102
    }
103
104
    /**
105
     * @throws Exception
106
     */
107
    private function getSessionRelUsers(int $sessionId): array
108
    {
109
        return $this->connection
110
            ->executeQuery(
111
                'SELECT id, user_id, duration FROM session_rel_user WHERE session_id = :sessionId',
112
                ['sessionId' => $sessionId]
113
            )
114
            ->fetchAllAssociative()
115
        ;
116
    }
117
118
    /**
119
     * @throws Exception
120
     */
121
    private function isCoach(int $sessionId, int $userId): bool
122
    {
123
        $sCRUs = $this->connection
124
            ->executeQuery(
125
                'SELECT COUNT(1) AS count_as_coach
126
                    FROM session_rel_course_rel_user
127
                    WHERE session_id = :sessionId
128
                        AND user_id = :userId
129
                        AND (status = :status_coach OR status = :status_general_coach)',
130
                [
131
                    'sessionId' => $sessionId,
132
                    'userId' => $userId,
133
                    'status_coach' => Session::COURSE_COACH,
134
                    'status_general_coach' => Session::GENERAL_COACH,
135
                ]
136
            )
137
            ->fetchAllAssociative()
138
        ;
139
140
        return $sCRUs[0]['count_as_coach'] > 0;
141
    }
142
143
    /**
144
     * @throws Exception
145
     */
146
    private function getSessionWithDuration(): array
147
    {
148
        return $this->connection
149
            ->executeQuery(
150
                'SELECT id, duration
151
                FROM session
152
                WHERE (duration IS NOT NULL AND duration > 0)'
153
            )
154
            ->fetchAllAssociative()
155
        ;
156
    }
157
158
    /**
159
     * @throws Exception
160
     */
161
    private function getFirstAccessToSession(int $sessionId, int $userId): int
162
    {
163
        $access = $this->connection
164
            ->executeQuery(
165
                'SELECT UNIX_TIMESTAMP(login_course_date) as tms
166
                    FROM track_e_course_access
167
                    WHERE session_id = :sessionId AND user_id = :userId
168
                    ORDER BY login_course_date ASC
169
                    LIMIT 1',
170
                [
171
                    'sessionId' => $sessionId,
172
                    'userId' => $userId,
173
                ]
174
            )
175
            ->fetchAllAssociative()
176
        ;
177
178
        if ($access) {
179
            return (int) $access[0]['tms'];
180
        }
181
182
        return 0;
183
    }
184
}