Passed
Push — master ( 6f8cb0...cccadf )
by Julito
09:47
created

survey_question   F

Complexity

Total Complexity 78

Size/Duplication

Total Lines 437
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 223
dl 0
loc 437
rs 2.16
c 0
b 0
f 0
wmc 78

10 Methods

Rating   Name   Duplication   Size   Complexity  
F createForm() 0 116 20
A save() 0 18 5
F preSave() 0 103 30
A addRemoveButtons() 0 22 2
A getForm() 0 3 1
A render() 0 3 1
A renderForm() 0 27 5
A setForm() 0 3 1
A addParentMenu() 0 43 2
B createQuestion() 0 26 11

How to fix   Complexity   

Complex Class

Complex classes like survey_question often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use survey_question, and based on these observations, apply Extract Interface, too.

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use ChamiloSession as Session;
5
6
/**
7
 * Class survey_question.
8
 */
9
class survey_question
10
{
11
    public $buttonList = [];
12
    /** @var FormValidator */
13
    private $form;
14
15
    /**
16
     * @param FormValidator $form
17
     * @param array         $surveyData
18
     */
19
    public function addParentMenu(FormValidator $form, $surveyData)
20
    {
21
        $surveyId = $surveyData['survey_id'];
22
        $questions = SurveyManager::get_questions($surveyId);
23
24
        $options = [];
25
        foreach ($questions as $question) {
26
            $options[$question['question_id']] = strip_tags($question['question']);
27
        }
28
        $form->addSelect(
29
            'parent_id',
30
            get_lang('Parent'),
31
            $options,
32
            ['id' => 'parent_id', 'placeholder' => get_lang('SelectAnOption')]
33
        );
34
        $url = api_get_path(WEB_AJAX_PATH).'survey.ajax.php?'.api_get_cidreq();
35
        $form->addHtml('
36
            <script>
37
                $(function() {                    
38
                    $("#parent_id").on("change", function() {
39
                        var questionId = $(this).val()
40
                        var params = {
41
                            "a": "load_question_options",
42
                            "survey_id": "'.$surveyId.'",
43
                            "question_id": questionId,
44
                        };    
45
                            
46
                          $.ajax({
47
                            type: "GET",
48
                            url: "'.$url.'",
49
                            data: params,
50
                            async: false,
51
                            success: function(data) {
52
                                $("#parent_options").html(data);
53
                            }
54
                        });        
55
                        console.log(); 
56
                    });
57
                });
58
            </script>
59
        ');
60
        $form->addHtml('<div id="parent_options"></div>');
61
        $form->addHidden('option_id', 0);
62
    }
63
64
    /**
65
     * @param string $type
66
     *
67
     * @return survey_question
68
     */
69
    public static function createQuestion($type)
70
    {
71
        switch ($type) {
72
            case 'comment':
73
                return new ch_comment();
74
            case 'dropdown':
75
                return new ch_dropdown();
76
            case 'multiplechoice':
77
                return new ch_multiplechoice();
78
            case 'multipleresponse':
79
                return new ch_multipleresponse();
80
            case 'open':
81
                return new ch_open();
82
            case 'pagebreak':
83
                return new ch_pagebreak();
84
            case 'percentage':
85
                return new ch_percentage();
86
            case 'personality':
87
                return new ch_personality();
88
            case 'score':
89
                return new ch_score();
90
            case 'yesno':
91
                return new ch_yesno();
92
            default:
93
                api_not_allowed(true);
94
                break;
95
        }
96
    }
97
98
    /**
99
     * Generic part of any survey question: the question field.
100
     *
101
     * @param array $surveyData
102
     * @param array $formData
103
     *
104
     * @return FormValidator
105
     */
106
    public function createForm($surveyData, $formData)
107
    {
108
        $action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : null;
109
        $questionId = isset($_GET['question_id']) ? (int) $_GET['question_id'] : null;
110
        $surveyId = isset($_GET['survey_id']) ? (int) $_GET['survey_id'] : null;
111
        $type = isset($_GET['type']) ? Security::remove_XSS($_GET['type']) : null;
112
113
        $toolName = Display::return_icon(
114
            SurveyManager::icon_question($type),
115
            get_lang(ucfirst($type)),
116
            ['align' => 'middle', 'height' => '22px']
117
        ).' ';
118
119
        if ($action == 'add') {
120
            $toolName .= get_lang('AddQuestion').': ';
121
        } elseif ($action == 'edit') {
122
            $toolName .= get_lang('EditQuestion').': ';
123
        }
124
125
        switch ($_GET['type']) {
126
            case 'yesno':
127
                $toolName .= get_lang('YesNo');
128
                break;
129
            case 'multiplechoice':
130
                $toolName .= get_lang('UniqueSelect');
131
                break;
132
            case 'multipleresponse':
133
                $toolName .= get_lang('MultipleResponse');
134
                break;
135
            default:
136
                $toolName .= get_lang(api_ucfirst($type));
137
        }
138
139
        $sharedQuestionId = isset($formData['shared_question_id']) ? $formData['shared_question_id'] : null;
140
141
        $url = api_get_self().'?action='.$action.'&type='.$type.'&survey_id='.$surveyId.'&question_id='.$questionId.'&'.api_get_cidreq();
142
        $form = new FormValidator('question_form', 'post', $url);
143
        $form->addHeader($toolName);
144
        $form->addHidden('survey_id', $surveyId);
145
        $form->addHidden('question_id', $questionId);
146
        $form->addHidden('shared_question_id', Security::remove_XSS($sharedQuestionId));
147
        $form->addHidden('type', $type);
148
149
        $config = [
150
            'ToolbarSet' => 'SurveyQuestion',
151
            'Width' => '100%',
152
            'Height' => '120',
153
        ];
154
        $form->addHtmlEditor(
155
            'question',
156
            get_lang('Question'),
157
            true,
158
            false,
159
            $config
160
        );
161
162
        if (api_get_configuration_value('allow_required_survey_questions') &&
163
            in_array($_GET['type'], ['yesno', 'multiplechoice'])) {
164
            $form->addCheckBox('is_required', get_lang('IsMandatory'), get_lang('Yes'));
165
        }
166
167
        // When survey type = 1??
168
        if ($surveyData['survey_type'] == 1) {
169
            $table_survey_question_group = Database::get_course_table(TABLE_SURVEY_QUESTION_GROUP);
170
            $sql = 'SELECT id,name FROM '.$table_survey_question_group.'
171
                    WHERE survey_id = '.(int) $_GET['survey_id'].'
172
                    ORDER BY name';
173
            $rs = Database::query($sql);
174
            $glist = null;
175
            while ($row = Database::fetch_array($rs, 'NUM')) {
176
                $glist .= '<option value="'.$row[0].'" >'.$row[1].'</option>';
177
            }
178
179
            $grouplist = $grouplist1 = $grouplist2 = $glist;
180
            if (!empty($formData['assigned'])) {
181
                $grouplist = str_replace(
182
                    '<option value="'.$formData['assigned'].'"',
183
                    '<option value="'.$formData['assigned'].'" selected',
184
                    $glist
185
                );
186
            }
187
188
            if (!empty($formData['assigned1'])) {
189
                $grouplist1 = str_replace(
190
                    '<option value="'.$formData['assigned1'].'"',
191
                    '<option value="'.$formData['assigned1'].'" selected',
192
                    $glist
193
                );
194
            }
195
196
            if (!empty($formData['assigned2'])) {
197
                $grouplist2 = str_replace(
198
                    '<option value="'.$formData['assigned2'].'"',
199
                    '<option value="'.$formData['assigned2'].'" selected',
200
                    $glist
201
                );
202
            }
203
204
            $this->html .= '	<tr><td colspan="">
0 ignored issues
show
Bug Best Practice introduced by
The property html does not exist on survey_question. Did you maybe forget to declare it?
Loading history...
205
			<fieldset style="border:1px solid black"><legend>'.get_lang('Condition').'</legend>
206
207
			<b>'.get_lang('Primary').'</b><br />
208
			'.'<input type="radio" name="choose" value="1" '.(($formData['choose'] == 1) ? 'checked' : '').
209
                '><select name="assigned">'.$grouplist.'</select><br />';
210
211
            $this->html .= '
212
			<b>'.get_lang('Secondary').'</b><br />
213
			'.'<input type="radio" name="choose" value="2" '.(($formData['choose'] == 2) ? 'checked' : '').
214
                '><select name="assigned1">'.$grouplist1.'</select> '.
215
                '<select name="assigned2">'.$grouplist2.'</select>'
216
                .'</fieldset><br />';
217
        }
218
219
        $this->setForm($form);
220
221
        return $form;
222
    }
223
224
    /**
225
     * Adds submit button.
226
     */
227
    public function renderForm()
228
    {
229
        if (isset($_GET['question_id']) && !empty($_GET['question_id'])) {
230
            /**
231
             * Check if survey has answers first before update it, this is because if you update it, the question
232
             * options will delete and re-insert in database loosing the iid and question_id to verify the correct answers.
233
             */
234
            $surveyId = isset($_GET['survey_id']) ? (int) $_GET['survey_id'] : 0;
235
            $answersChecker = SurveyUtil::checkIfSurveyHasAnswers($surveyId);
236
            if (!$answersChecker) {
237
                $this->buttonList[] = $this->getForm()->addButtonUpdate(get_lang('ModifyQuestionSurvey'), 'save', true);
238
            } else {
239
                $this->getForm()->addHtml('
240
                    <div class="form-group">
241
                        <label class="col-sm-2 control-label"></label>
242
                        <div class="col-sm-8">
243
                            <div class="alert alert-info">'.get_lang('YouCantNotEditThisQuestionBecauseAlreadyExistAnswers').'</div>
244
                        </div>
245
                        <div class="col-sm-2"></div>
246
                    </div>
247
                ');
248
            }
249
        } else {
250
            $this->buttonList[] = $this->getForm()->addButtonSave(get_lang('CreateQuestionSurvey'), 'save', true);
251
        }
252
253
        $this->getForm()->addGroup($this->buttonList, 'buttons');
254
    }
255
256
    /**
257
     * @return FormValidator
258
     */
259
    public function getForm()
260
    {
261
        return $this->form;
262
    }
263
264
    /**
265
     * @param FormValidator $form
266
     */
267
    public function setForm($form)
268
    {
269
        $this->form = $form;
270
    }
271
272
    /**
273
     * @param array $formData
274
     *
275
     * @return mixed
276
     */
277
    public function preSave($formData)
278
    {
279
        $counter = Session::read('answer_count');
280
        $answerList = Session::read('answer_list');
281
282
        if (empty($answerList)) {
283
            $answerList = isset($formData['answers']) ? $formData['answers'] : [];
284
            Session::write('answer_list', $answerList);
285
        }
286
287
        if (isset($_POST['answers'])) {
288
            $formData['answers'] = $_POST['answers'];
289
        }
290
291
        if (empty($counter)) {
292
            $counter = count($answerList) - 1;
293
            Session::write('answer_count', $counter);
294
        }
295
296
        // Moving an answer up
297
        if (isset($_POST['move_up']) && $_POST['move_up']) {
298
            foreach ($_POST['move_up'] as $key => &$value) {
299
                $id1 = $key;
300
                $content1 = $formData['answers'][$id1];
301
                $id2 = $key - 1;
302
                $content2 = $formData['answers'][$id2];
303
                $formData['answers'][$id1] = $content2;
304
                $formData['answers'][$id2] = $content1;
305
            }
306
        }
307
308
        // Moving an answer down
309
        if (isset($_POST['move_down']) && $_POST['move_down']) {
310
            foreach ($_POST['move_down'] as $key => &$value) {
311
                $id1 = $key;
312
                $content1 = $formData['answers'][$id1];
313
                $id2 = $key + 1;
314
                $content2 = $formData['answers'][$id2];
315
                $formData['answers'][$id1] = $content2;
316
                $formData['answers'][$id2] = $content1;
317
            }
318
        }
319
320
        /**
321
         * This solution is a little bit strange but I could not find a different solution.
322
         */
323
        if (isset($_POST['delete_answer'])) {
324
            $deleted = false;
325
            foreach ($_POST['delete_answer'] as $key => &$value) {
326
                $deleted = $key;
327
                $counter--;
328
                Session::write('answer_count', $counter);
329
            }
330
331
            foreach ($formData['answers'] as $key => &$value) {
332
                if ($key > $deleted) {
333
                    $formData['answers'][$key - 1] = $formData['answers'][$key];
334
                    unset($formData['answers'][$key]);
335
                }
336
            }
337
        }
338
339
        // Adding an answer
340
        if (isset($_POST['buttons']) && isset($_POST['buttons']['add_answer'])) {
341
            $counter++;
342
            Session::write('answer_count', $counter);
343
        }
344
345
        // Removing an answer
346
        if (isset($_POST['buttons']) && isset($_POST['buttons']['remove_answer'])) {
347
            $counter--;
348
            Session::write('answer_count', $counter);
349
            foreach ($formData['answers'] as $index => &$data) {
350
                if ($index > $counter) {
351
                    unset($formData['answers'][$index]);
352
                }
353
            }
354
        }
355
356
        if (!isset($_POST['delete_answer'])) {
357
            if (isset($formData['answers'])) {
358
                foreach ($formData['answers'] as $index => $data) {
359
                    if ($index > $counter) {
360
                        unset($formData['answers'][$index]);
361
                    }
362
                }
363
364
                for ($i = 0; $i <= $counter; $i++) {
365
                    if (!isset($formData['answers'][$i])) {
366
                        $formData['answers'][$i] = '';
367
                    }
368
                }
369
            }
370
        }
371
372
        $formData['answers'] = isset($formData['answers']) ? $formData['answers'] : [];
373
        Session::write('answer_list', $formData['answers']);
374
375
        if (!isset($formData['is_required']) && api_get_configuration_value('survey_mark_question_as_required')) {
376
            $formData['is_required'] = true;
377
        }
378
379
        return $formData;
380
    }
381
382
    /**
383
     * @param array $surveyData
384
     * @param array $formData
385
     *
386
     * @return mixed
387
     */
388
    public function save($surveyData, $formData)
389
    {
390
        // Saving a question
391
        if (isset($_POST['buttons']) && isset($_POST['buttons']['save'])) {
392
            Session::erase('answer_count');
393
            Session::erase('answer_list');
394
            $message = SurveyManager::save_question(
395
                $surveyData,
396
                $formData
397
            );
398
399
            if ($message == 'QuestionAdded' || $message == 'QuestionUpdated') {
400
                header('Location: '.api_get_path(WEB_CODE_PATH).'survey/survey.php?survey_id='.intval($_GET['survey_id']).'&message='.$message.'&'.api_get_cidreq());
401
                exit;
402
            }
403
        }
404
405
        return $formData;
406
    }
407
408
    /**
409
     * Adds two buttons. One to add an option, one to remove an option.
410
     *
411
     * @param array $data
412
     */
413
    public function addRemoveButtons($data)
414
    {
415
        $this->buttonList['remove_answer'] = $this->getForm()->createElement(
416
            'button',
417
            'remove_answer',
418
            get_lang('RemoveAnswer'),
419
            'minus',
420
            'default'
421
        );
422
423
        if (count($data['answers']) <= 2) {
424
            $this->buttonList['remove_answer']->updateAttributes(
425
                ['disabled' => 'disabled']
426
            );
427
        }
428
429
        $this->buttonList['add_answer'] = $this->getForm()->createElement(
430
            'button',
431
            'add_answer',
432
            get_lang('AddAnswer'),
433
            'plus',
434
            'default'
435
        );
436
    }
437
438
    /**
439
     * @param FormValidator $form
440
     * @param array         $questionData
441
     * @param array         $answers
442
     */
443
    public function render(FormValidator $form, $questionData = [], $answers = [])
0 ignored issues
show
Unused Code introduced by
The parameter $answers is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

443
    public function render(FormValidator $form, $questionData = [], /** @scrutinizer ignore-unused */ $answers = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $questionData is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

443
    public function render(FormValidator $form, /** @scrutinizer ignore-unused */ $questionData = [], $answers = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
444
    {
445
        return null;
446
    }
447
}
448