Passed
Push — master ( 2d9a22...0085e5 )
by Julito
10:53 queued 02:39
created

Positioning::isInitialExercise()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 4
eloc 4
nc 2
nop 3
dl 0
loc 8
rs 10
c 1
b 0
f 1
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, 'positioning.png');
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_array($result, 'ASSOC');
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 getInitialExercise($courseId, $sessionId)
159
    {
160
        return $this->getCourseExercise($courseId, $sessionId, true, false);
161
    }
162
163
    public function getFinalExercise($courseId, $sessionId)
164
    {
165
        return $this->getCourseExercise($courseId, $sessionId, false, true);
166
    }
167
168
    private function setOption($field, $exerciseId, $courseId, $sessionId)
169
    {
170
        if (!in_array($field, ['is_initial', 'is_final'], true)) {
171
            return false;
172
        }
173
174
        $data = $this->getPositionData($exerciseId, $courseId, $sessionId);
175
        $disableField = $field === 'is_initial' ? 'is_final' : 'is_initial';
176
        if ($data && isset($data['id'])) {
177
            $id = $data['id'];
178
            $sql = "UPDATE $this->table SET
179
                    $field = 1,
180
                    $disableField = 0
181
                    WHERE id = $id";
182
            Database::query($sql);
183
184
            $sql = "DELETE FROM $this->table
185
                    WHERE $field = 1 AND c_id = $courseId AND session_id = $sessionId AND id <> $id";
186
            Database::query($sql);
187
        } else {
188
            $params = [
189
                'exercise_id' => $exerciseId,
190
                'c_id' => $courseId,
191
                'session_id' => $sessionId,
192
                $field => 1,
193
                $disableField => 0,
194
            ];
195
            $id = Database::insert($this->table, $params);
196
197
            $sql = "DELETE FROM $this->table
198
                    WHERE $field = 1 AND c_id = $courseId AND session_id = $sessionId AND id <> $id";
199
            Database::query($sql);
200
        }
201
    }
202
203
    private function getCourseExercise($courseId, $sessionId, $isInitial, $isFinal)
204
    {
205
        $table = $this->table;
206
        $courseId = (int) $courseId;
207
        $sessionId = (int) $sessionId;
208
209
        $sql = "SELECT * FROM $table
210
                WHERE
211
                    c_id = $courseId AND
212
                    session_id = $sessionId
213
                    ";
214
215
        if ($isInitial) {
216
            $sql .= ' AND is_initial = 1 ';
217
        } else {
218
            $sql .= ' AND is_initial = 0 ';
219
        }
220
221
        if ($isFinal) {
222
            $sql .= ' AND is_final = 1 ';
223
        } else {
224
            $sql .= ' AND is_final = 0 ';
225
        }
226
227
        $result = Database::query($sql);
228
229
        if (Database::num_rows($result) > 0) {
230
            return Database::fetch_array($result, 'ASSOC');
231
        }
232
233
        return false;
234
    }
235
}
236