Passed
Push — 1.11.x ( 659998...c58798 )
by Angel Fernando Quiroz
10:01
created

RemedialCoursePlugin::getRemedialCourseList()   F

Complexity

Conditions 25
Paths 291

Size

Total Lines 131
Code Lines 74

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 25
eloc 74
c 3
b 0
f 0
nc 291
nop 4
dl 0
loc 131
rs 2.1958

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
/**
6
 * Class RemedialCoursePlugin.
7
 */
8
class RemedialCoursePlugin extends Plugin
9
{
10
    const SETTING_ENABLED = 'enabled';
11
    const EXTRAFIELD_REMEDIAL_VARIABLE = 'remedialcourselist';
12
13
    /**
14
     * RemedialCoursePlugin constructor.
15
     */
16
    protected function __construct()
17
    {
18
        $settings = [
19
            self::SETTING_ENABLED => 'boolean',
20
        ];
21
        parent::__construct(
22
            '1.0',
23
            'Carlos Alvarado',
24
            $settings
25
        );
26
    }
27
28
    /**
29
     * Create a new instance of RemedialCoursePlugin.
30
     */
31
    public static function create(): RemedialCoursePlugin
32
    {
33
        static $result = null;
34
35
        return $result ?: $result = new self();
36
    }
37
38
    /**
39
     * Perform the plugin installation.
40
     */
41
    public function install()
42
    {
43
        $this->saveRemedialField();
44
        $this->saveAdvanceRemedialField();
45
    }
46
47
    /**
48
     * Save the arrangement for remedialcourselist, it is adjusted internally so that the values
49
     * match the necessary ones.
50
     */
51
    public function saveRemedialField()
52
    {
53
        $extraField = new ExtraField('exercise');
54
        $remedialcourselist = $extraField->get_handler_field_info_by_field_variable(self::EXTRAFIELD_REMEDIAL_VARIABLE);
55
        if (false === $remedialcourselist) {
56
            $extraField->save([
57
                'field_type' => ExtraField::FIELD_TYPE_SELECT_MULTIPLE,
58
                'variable' => self::EXTRAFIELD_REMEDIAL_VARIABLE,
59
                'display_text' => 'remedialCourseList',
60
                'default_value' => 1,
61
                'field_order' => 0,
62
                'visible_to_self' => 1,
63
                'visible_to_others' => 0,
64
                'changeable' => 1,
65
                'filter' => 0,
66
            ]);
67
        }
68
    }
69
70
    /**
71
     * Save the arrangement for remedialadvancecourselist, it is adjusted internally so that the values
72
     * match the necessary ones.
73
     */
74
    public function saveAdvanceRemedialField()
75
    {
76
        $extraField = new ExtraField('exercise');
77
        $advancedcourselist = $extraField->get_handler_field_info_by_field_variable('advancedcourselist');
78
        if (false === $advancedcourselist) {
79
            $extraField->save([
80
                'field_type' => ExtraField::FIELD_TYPE_SELECT_MULTIPLE,
81
                'variable' => 'advancedcourselist',
82
                'display_text' => 'advancedCourseList',
83
                'default_value' => 1,
84
                'field_order' => 0,
85
                'visible_to_self' => 1,
86
                'visible_to_others' => 0,
87
                'changeable' => 1,
88
                'filter' => 0,
89
            ]);
90
        }
91
    }
92
93
    /**
94
     * Set default_value to 0.
95
     */
96
    public function uninstall()
97
    {
98
    }
99
100
    public function get_name(): string
101
    {
102
        return 'remedial_course';
103
    }
104
105
    public function getRemedialCourseList(
106
        Exercise $objExercise,
107
        int $userId = 0,
108
        int $sessionId = 0,
109
        bool $review = false
110
    ): ?string {
111
        if ('true' !== $this->get(self::SETTING_ENABLED)) {
112
            return null;
113
        }
114
115
        $field = new ExtraField('exercise');
116
        $remedialField = $field->get_handler_field_info_by_field_variable(self::EXTRAFIELD_REMEDIAL_VARIABLE);
117
118
        if (empty($remedialField)) {
119
            return null;
120
        }
121
122
        $extraFieldValue = new ExtraFieldValue('exercise');
123
        $remedialExcerciseField = $extraFieldValue->get_values_by_handler_and_field_variable(
124
            $objExercise->iId,
125
            self::EXTRAFIELD_REMEDIAL_VARIABLE
126
        );
127
        $remedialCourseIds = explode(';', $remedialExcerciseField['value']);
128
129
        if (empty($remedialExcerciseField['value']) || count($remedialCourseIds) == 0) {
130
            return null;
131
        }
132
133
        $questionExcluded = [
134
            FREE_ANSWER,
135
            ORAL_EXPRESSION,
136
            ANNOTATION,
137
        ];
138
139
        $userId = empty($userId) ? api_get_user_id() : $userId;
140
141
        $exerciseStatInfo = Event::getExerciseResultsByUser(
142
            $userId,
143
            $objExercise->iId,
144
            $objExercise->course_id,
145
            $sessionId
146
        );
147
        $bestAttempt = Event::get_best_attempt_exercise_results_per_user(
148
            $userId,
149
            $objExercise->iId,
150
            $objExercise->course_id,
151
            $sessionId
152
        );
153
154
        foreach ($exerciseStatInfo as $attempt) {
155
            if (!isset($bestAttempt['exe_result']) || $attempt['exe_result'] >= $bestAttempt['exe_result']) {
156
                $bestAttempt = $attempt;
157
            }
158
159
            if (!isset($attempt['question_list'])) {
160
                continue;
161
            }
162
163
            foreach ($attempt['question_list'] as $questionId => $answer) {
164
                $question = Question::read($questionId, api_get_course_info_by_id($attempt['c_id']));
165
                $questionOpen = in_array($question->type, $questionExcluded) && !$review;
166
167
                if (!$questionOpen) {
168
                    continue;
169
                }
170
171
                $score = $attempt['exe_result'];
172
                $comments = Event::get_comments($objExercise->iId, $questionId);
173
174
                if (empty($comments) || $score == 0) {
175
                    return null;
176
                }
177
            }
178
        }
179
180
        if (empty($bestAttempt)) {
181
            return null;
182
        }
183
184
        $bestAttempt['exe_result'] = (int) $bestAttempt['exe_result'];
185
186
        $isPassedPercentage = ExerciseLib::isPassPercentageAttemptPassed(
187
            $objExercise,
188
            $bestAttempt['exe_result'],
189
            $bestAttempt['exe_weighting']
190
        );
191
192
        if ($isPassedPercentage) {
193
            return null;
194
        }
195
196
        $hasAttempts = count($exerciseStatInfo) < $objExercise->selectAttempts();
197
198
        $doSubscriptionToRemedial = !$hasAttempts || $objExercise->isBlockedByPercentage($bestAttempt);
199
200
        if (!$doSubscriptionToRemedial) {
201
            return null;
202
        }
203
204
        $courses = [];
205
        $isInASession = !empty($sessionId);
206
207
        foreach ($remedialCourseIds as $courseId) {
208
            $courseData = api_get_course_info_by_id($courseId);
209
210
            if (empty($courseData)) {
211
                continue;
212
            }
213
214
            if ($isInASession) {
215
                $courseExistsInSession = SessionManager::sessionHasCourse($sessionId, $courseData['code']);
216
217
                if ($courseExistsInSession) {
218
                    SessionManager::subscribe_users_to_session_course([$userId], $sessionId, $courseData['code']);
219
                    $courses[] = $courseData['title'];
220
                }
221
            } else {
222
                $isSubscribed = CourseManager::is_user_subscribed_in_course($userId, $courseData['code']);
223
224
                if (!$isSubscribed) {
225
                    CourseManager::subscribeUser($userId, $courseData['code']);
226
                    $courses[] = $courseData['title'];
227
                }
228
            }
229
        }
230
231
        if (empty($courses)) {
232
            return null;
233
        }
234
235
        return sprintf($this->get_lang('SubscriptionToXRemedialCourses'), implode(' - ', $courses));
236
    }
237
}
238