Passed
Pull Request — master (#6287)
by
unknown
08:55
created

Positioning::uninstall()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
class Positioning extends Plugin
6
{
7
    public $isCoursePlugin = true;
8
    public $table;
9
10
    /**
11
     * Class constructor.
12
     */
13
    protected function __construct()
14
    {
15
        parent::__construct(
16
            '1.0',
17
            'Julio Montoya',
18
            [
19
                'tool_enable' => 'boolean',
20
                'block_course_if_initial_exercise_not_attempted' => 'boolean',
21
                'average_percentage_to_unlock_final_exercise' => 'text',
22
            ]
23
        );
24
25
        $this->table = Database::get_main_table('plugin_positioning_exercise');
26
    }
27
28
    public static function create()
29
    {
30
        static $result = null;
31
32
        return $result ? $result : $result = new self();
33
    }
34
35
    public function install()
36
    {
37
        $table = $this->table;
38
39
        $sql = 'CREATE TABLE IF NOT EXISTS '.$table.' (
40
                id INT unsigned NOT NULL auto_increment PRIMARY KEY,
41
                exercise_id INT unsigned NOT NULL,
42
                c_id INT unsigned NOT NULL,
43
                session_id INT unsigned DEFAULT NULL,
44
                is_initial TINYINT(1) NOT NULL,
45
                is_final TINYINT(1) NOT NULL
46
                )';
47
        Database::query($sql);
48
49
        // Installing course settings
50
        $this->install_course_fields_in_all_courses(true);
51
    }
52
53
    public function uninstall()
54
    {
55
        $table = $this->table;
56
        Database::query("DROP TABLE IF EXISTS $table");
57
    }
58
59
    public function isInitialExercise($exerciseId, $courseId, $sessionId)
60
    {
61
        $data = $this->getPositionData($exerciseId, $courseId, $sessionId);
62
        if ($data && isset($data['is_initial']) && 1 === (int) $data['is_initial']) {
63
            return true;
64
        }
65
66
        return false;
67
    }
68
69
    public function getPositionData($exerciseId, $courseId, $sessionId)
70
    {
71
        $table = $this->table;
72
        $courseId = (int) $courseId;
73
        $sessionId = (int) $sessionId;
74
75
        $sql = "SELECT * FROM $table
76
                WHERE
77
                    exercise_id = $exerciseId AND
78
                    c_id = $courseId AND
79
                    session_id = $sessionId
80
                    ";
81
        $result = Database::query($sql);
82
83
        if (Database::num_rows($result) > 0) {
84
            return Database::fetch_assoc($result);
85
        }
86
87
        return false;
88
    }
89
90
    public function isFinalExercise($exerciseId, $courseId, $sessionId)
91
    {
92
        $data = $this->getPositionData($exerciseId, $courseId, $sessionId);
93
        if ($data && isset($data['is_final']) && 1 === (int) $data['is_final']) {
94
            return true;
95
        }
96
    }
97
98
    public function setInitialExercise($exerciseId, $courseId, $sessionId)
99
    {
100
        $this->setOption('is_initial', $exerciseId, $courseId, $sessionId);
101
    }
102
103
    public function setFinalExercise($exerciseId, $courseId, $sessionId)
104
    {
105
        $this->setOption('is_final', $exerciseId, $courseId, $sessionId);
106
    }
107
108
    public function blockFinalExercise($userId, $exerciseId, $courseId, $sessionId)
109
    {
110
        $initialData = $this->getInitialExercise($courseId, $sessionId);
111
112
        if (empty($initialData)) {
113
            return false;
114
        }
115
116
        if ($initialData && isset($initialData['exercise_id'])) {
117
            // If this is final exercise?
118
            $finalData = $this->getFinalExercise($courseId, $sessionId);
119
            if (!empty($finalData) && $finalData['exercise_id'] && $exerciseId == $finalData['exercise_id']) {
120
                $initialResults = Event::getExerciseResultsByUser(
121
                    $userId,
122
                    $initialData['exercise_id'],
123
                    $courseId,
124
                    $sessionId
125
                );
126
127
                if (empty($initialResults)) {
128
                    return true;
129
                }
130
131
                $averageToUnlock = (float) $this->get('average_percentage_to_unlock_final_exercise');
132
                if (empty($averageToUnlock)) {
133
                    return false;
134
                }
135
136
                // Check average
137
                $courseInfo = api_get_course_info_by_id($courseId);
138
                $userAverage = (float) Tracking::get_avg_student_progress(
139
                    $userId,
140
                    $courseInfo['code'],
141
                    [],
142
                    $sessionId
143
                );
144
145
                if ($userAverage >= $averageToUnlock) {
146
                    return false;
147
                }
148
149
                return true;
150
            } else {
151
                return false;
152
            }
153
        }
154
155
        return true;
156
    }
157
158
    public function shouldBlockUser(int $userId, int $courseId, ?int $sessionId): bool
159
    {
160
        if ($this->get('block_course_if_initial_exercise_not_attempted') !== 'true') {
161
            return false;
162
        }
163
164
        $initialData = $this->getInitialExercise($courseId, $sessionId);
165
166
        if (empty($initialData['exercise_id'])) {
167
            return false;
168
        }
169
170
        $results = \Event::getExerciseResultsByUser(
171
            $userId,
172
            (int) $initialData['exercise_id'],
173
            $courseId,
174
            $sessionId
175
        );
176
177
        return empty($results);
178
    }
179
180
    public function getInitialExercise($courseId, $sessionId)
181
    {
182
        return $this->getCourseExercise($courseId, $sessionId, true, false);
183
    }
184
185
    public function getFinalExercise($courseId, $sessionId)
186
    {
187
        return $this->getCourseExercise($courseId, $sessionId, false, true);
188
    }
189
190
    public function get_name()
191
    {
192
        return 'Positioning';
193
    }
194
195
    private function setOption($field, $exerciseId, $courseId, $sessionId)
196
    {
197
        if (!in_array($field, ['is_initial', 'is_final'], true)) {
198
            return false;
199
        }
200
201
        $data = $this->getPositionData($exerciseId, $courseId, $sessionId);
202
        $disableField = 'is_initial' === $field ? 'is_final' : 'is_initial';
203
        if ($data && isset($data['id'])) {
204
            $id = $data['id'];
205
            $sql = "UPDATE $this->table SET
206
                    $field = 1,
207
                    $disableField = 0
208
                    WHERE id = $id";
209
            Database::query($sql);
210
211
            $sql = "DELETE FROM $this->table
212
                    WHERE $field = 1 AND c_id = $courseId AND session_id = $sessionId AND id <> $id";
213
            Database::query($sql);
214
        } else {
215
            $params = [
216
                'exercise_id' => $exerciseId,
217
                'c_id' => $courseId,
218
                'session_id' => $sessionId,
219
                $field => 1,
220
                $disableField => 0,
221
            ];
222
            $id = Database::insert($this->table, $params);
223
224
            $sql = "DELETE FROM $this->table
225
                    WHERE $field = 1 AND c_id = $courseId AND session_id = $sessionId AND id <> $id";
226
            Database::query($sql);
227
        }
228
    }
229
230
    private function getCourseExercise($courseId, $sessionId, $isInitial, $isFinal)
231
    {
232
        $table = $this->table;
233
        $courseId = (int) $courseId;
234
        $sessionId = (int) $sessionId;
235
236
        $sql = "SELECT * FROM $table
237
                WHERE
238
                    c_id = $courseId AND
239
                    session_id = $sessionId
240
                    ";
241
242
        if ($isInitial) {
243
            $sql .= ' AND is_initial = 1 ';
244
        } else {
245
            $sql .= ' AND is_initial = 0 ';
246
        }
247
248
        if ($isFinal) {
249
            $sql .= ' AND is_final = 1 ';
250
        } else {
251
            $sql .= ' AND is_final = 0 ';
252
        }
253
254
        $result = Database::query($sql);
255
256
        if (Database::num_rows($result) > 0) {
257
            return Database::fetch_assoc($result);
258
        }
259
260
        return false;
261
    }
262
}
263