Passed
Push — master ( afe0a2...5330e2 )
by
unknown
11:37 queued 36s
created

Version20201210100011::up()   B

Complexity

Conditions 11
Paths 72

Size

Total Lines 55
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 34
nc 72
nop 1
dl 0
loc 55
rs 7.3166
c 0
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 Version20201210100011 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
    public function up(Schema $schema): void
22
    {
23
        $this->addSql("ALTER TABLE session_rel_user ADD access_start_date DATETIME DEFAULT NULL COMMENT '(DC2Type:datetime)'");
24
        $this->addSql("ALTER TABLE session_rel_user ADD access_end_date DATETIME DEFAULT NULL COMMENT '(DC2Type:datetime)'");
25
26
        $sessions = $this->getSessionWithNoDuration();
27
28
        foreach ($sessions as $session) {
29
            $sRUs = $this->getSessionRelUsers($session['id']);
30
31
            foreach ($sRUs as $sru) {
32
                $isCoach = $this->isCoach($session['id'], $sru['user_id']);
33
34
                $startDate = $isCoach && $session['coach_access_start_date']
35
                    ? $session['coach_access_start_date']
36
                    : $session['access_start_date'];
37
38
                $endDate = $isCoach && $session['coach_access_end_date']
39
                    ? $session['coach_access_end_date']
40
                    : $session['access_end_date'];
41
42
                $this->addSql(
43
                    'UPDATE session_rel_user SET access_start_date = :startDate, access_end_date = :endDate WHERE id = :id',
44
                    [
45
                        'startDate' => $startDate,
46
                        'endDate' => $endDate,
47
                        'id' => $sru['id'],
48
                    ]
49
                );
50
            }
51
        }
52
53
        $sessions = $this->getSessionWithDuration();
54
55
        foreach ($sessions as $session) {
56
            $sRUs = $this->getSessionRelUsers($session['id']);
57
58
            foreach ($sRUs as $sru) {
59
                $duration = (int) $session['duration'] + (int) $sru['duration'];
60
61
                $firstAccessToSession = $this->getFirstAccessToSession($session['id'], $sru['user_id']);
62
63
                $calculatedLastAccessToSession = $firstAccessToSession + $duration * 24 * 60 * 60;
64
65
                $startDate = $firstAccessToSession ?: null;
66
                $endDate = $firstAccessToSession ? $calculatedLastAccessToSession : null;
67
68
                $this->addSql(
69
                    'UPDATE session_rel_user
70
                        SET access_start_date = FROM_UNIXTIME(:startDate), access_end_date = FROM_UNIXTIME(:endDate)
71
                        WHERE id = :id',
72
                    [
73
                        'startDate' => $startDate,
74
                        'endDate' => $endDate,
75
                        'id' => $sru['id'],
76
                    ]
77
                );
78
            }
79
        }
80
    }
81
82
    /**
83
     * @throws Exception
84
     */
85
    private function getSessionWithNoDuration(): array
86
    {
87
        return $this->connection
88
            ->executeQuery(
89
                'SELECT
90
                    id,
91
                    display_start_date, display_end_date,
92
                    access_start_date, access_end_date,
93
                    coach_access_start_date, coach_access_end_date
94
                FROM session
95
                WHERE (duration IS NULL OR duration = 0)'
96
            )
97
            ->fetchAllAssociative()
98
        ;
99
    }
100
101
    /**
102
     * @throws Exception
103
     */
104
    private function getSessionRelUsers(int $sessionId): array
105
    {
106
        return $this->connection
107
            ->executeQuery(
108
                'SELECT id, user_id, duration FROM session_rel_user WHERE session_id = :sessionId',
109
                ['sessionId' => $sessionId]
110
            )
111
            ->fetchAllAssociative()
112
        ;
113
    }
114
115
    /**
116
     * @throws Exception
117
     */
118
    private function isCoach(int $sessionId, int $userId): bool
119
    {
120
        $sCRUs = $this->connection
121
            ->executeQuery(
122
                'SELECT COUNT(1) AS count_as_coach
123
                    FROM session_rel_course_rel_user
124
                    WHERE session_id = :sessionId
125
                        AND user_id = :userId
126
                        AND (status = :status_coach OR status = :status_general_coach)',
127
                [
128
                    'sessionId' => $sessionId,
129
                    'userId' => $userId,
130
                    'status_coach' => Session::COURSE_COACH,
131
                    'status_general_coach' => Session::GENERAL_COACH,
132
                ]
133
            )
134
            ->fetchAllAssociative()
135
        ;
136
137
        return $sCRUs[0]['count_as_coach'] > 0;
138
    }
139
140
    /**
141
     * @throws Exception
142
     */
143
    private function getSessionWithDuration(): array
144
    {
145
        return $this->connection
146
            ->executeQuery(
147
                'SELECT id, duration
148
                FROM session
149
                WHERE (duration IS NOT NULL AND duration > 0)'
150
            )
151
            ->fetchAllAssociative()
152
        ;
153
    }
154
155
    /**
156
     * @throws Exception
157
     */
158
    private function getFirstAccessToSession(int $sessionId, int $userId): int
159
    {
160
        $access = $this->connection
161
            ->executeQuery(
162
                'SELECT UNIX_TIMESTAMP(login_course_date) as tms
163
                    FROM track_e_course_access
164
                    WHERE session_id = :sessionId AND user_id = :userId
165
                    ORDER BY login_course_date ASC
166
                    LIMIT 1',
167
                [
168
                    'sessionId' => $sessionId,
169
                    'userId' => $userId,
170
                ]
171
            )
172
            ->fetchAllAssociative()
173
        ;
174
175
        if ($access) {
176
            return (int) $access[0]['tms'];
177
        }
178
179
        return 0;
180
    }
181
}
182