CatForm   C
last analyzed

Complexity

Total Complexity 54

Size/Duplication

Total Lines 466
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 54
eloc 280
dl 0
loc 466
rs 6.4799
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A build_move_form() 0 25 4
A build_select_course_form() 0 20 2
A __construct() 0 29 6
A build_add_form() 0 26 2
B build_editing_form() 0 59 6
F build_basic_form() 0 263 34

How to fix   Complexity   

Complex Class

Complex classes like CatForm 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 CatForm, and based on these observations, apply Extract Interface, too.

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Class CatForm.
6
 *
7
 * @author Stijn Konings
8
 */
9
class CatForm extends FormValidator
10
{
11
    public const TYPE_ADD = 1;
12
    public const TYPE_EDIT = 2;
13
    public const TYPE_MOVE = 3;
14
    public const TYPE_SELECT_COURSE = 4;
15
    /** @var Category */
16
    private $category_object;
17
18
    /**
19
     * CatForm constructor.
20
     * Builds a form containing form items based on a given parameter.
21
     *
22
     * @param string $form_type       1=add, 2=edit,3=move,4=browse
23
     * @param string $category_object
24
     * @param string $form_name
25
     * @param string $method
26
     * @param null   $action
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $action is correct as it would always require null to be passed?
Loading history...
27
     */
28
    public function __construct(
29
        $form_type,
30
        $category_object,
31
        $form_name,
32
        $method = 'post',
33
        $action = null
34
    ) {
35
        parent::__construct($form_name, $method, $action);
36
        $this->form_type = $form_type;
37
        if (isset($category_object)) {
38
            $this->category_object = $category_object;
0 ignored issues
show
Documentation Bug introduced by
It seems like $category_object of type string is incompatible with the declared type Category of property $category_object.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
39
        }
40
41
        switch ($this->form_type) {
42
            case self::TYPE_EDIT:
43
                $this->build_editing_form();
44
                break;
45
            case self::TYPE_ADD:
46
                $this->build_add_form();
47
                break;
48
            case self::TYPE_MOVE:
49
                $this->build_move_form();
50
                break;
51
            case self::TYPE_SELECT_COURSE:
52
                $this->build_select_course_form();
53
                break;
54
        }
55
56
        $this->setDefaults();
57
    }
58
59
    /**
60
     * This function will build a move form that will allow the user to move a category to
61
     * a another.
62
     */
63
    protected function build_move_form()
64
    {
65
        $renderer = &$this->defaultRenderer();
66
        $renderer->setCustomElementTemplate('<span>{element}</span> ');
67
        $this->addElement(
68
            'static',
69
            null,
70
            null,
71
            '"'.$this->category_object->get_name().'" '
72
        );
73
        $this->addElement('static', null, null, get_lang('MoveTo').' : ');
74
        $select = $this->addElement('select', 'move_cat', null, null);
75
        $line = null;
76
        foreach ($this->category_object->get_target_categories() as $cat) {
77
            for ($i = 0; $i < $cat[2]; $i++) {
78
                $line .= '--';
79
            }
80
            if ($cat[0] != $this->category_object->get_parent_id()) {
81
                $select->addOption($line.' '.$cat[1], $cat[0]);
82
            } else {
83
                $select->addOption($line.' '.$cat[1], $cat[0], 'disabled');
84
            }
85
            $line = '';
86
        }
87
        $this->addElement('submit', null, get_lang('Ok'));
88
    }
89
90
    /**
91
     * This function builds an 'add category form, if parent id is 0, it will only
92
     * show courses.
93
     */
94
    protected function build_add_form()
95
    {
96
        // check if we are a root category
97
        // if so, you can only choose between courses
98
        if ('0' == $this->category_object->get_parent_id()) {
99
            $this->setDefaults(
100
                [
101
                    'select_course' => $this->category_object->get_course_code(),
102
                    'hid_user_id' => $this->category_object->get_user_id(),
103
                    'hid_parent_id' => $this->category_object->get_parent_id(),
104
                ]
105
            );
106
        } else {
107
            $this->setDefaults(
108
                [
109
                    'hid_user_id' => $this->category_object->get_user_id(),
110
                    'hid_parent_id' => $this->category_object->get_parent_id(),
111
                ]
112
            );
113
            $this->addElement(
114
                'hidden',
115
                'course_code',
116
                $this->category_object->get_course_code()
117
            );
118
        }
119
        $this->build_basic_form();
120
    }
121
122
    /**
123
     * Builds an form to edit a category.
124
     */
125
    protected function build_editing_form()
126
    {
127
        $skills = $this->category_object->getSkillsForSelect();
128
129
        $course_code = api_get_course_id();
130
        $session_id = api_get_session_id();
131
132
        $test_cats = Category::load(
133
            null,
134
            null,
135
            $course_code,
136
            null,
137
            null,
138
            $session_id,
139
            false
140
        );
141
142
        $links = null;
143
        if (isset($test_cats[0])) {
144
            $links = $test_cats[0]->get_links();
145
        }
146
        $grade_model_id = $this->category_object->get_grade_model_id();
147
148
        if (empty($links)) {
149
            $grade_model_id = 0;
150
        }
151
152
        $category_name = $this->category_object->get_name();
153
154
        // The main course category:
155
        if (isset($this->category_object) && 0 == $this->category_object->get_parent_id()) {
156
            if (empty($category_name)) {
157
                $category_name = $course_code;
158
            }
159
        }
160
161
        $this->setDefaults(
162
            [
163
                'name' => $category_name,
164
                'description' => $this->category_object->get_description(),
165
                'hid_user_id' => $this->category_object->get_user_id(),
166
                'hid_parent_id' => $this->category_object->get_parent_id(),
167
                'grade_model_id' => $grade_model_id,
168
                'skills' => $skills,
169
                'weight' => $this->category_object->get_weight(),
170
                'visible' => $this->category_object->is_visible(),
171
                'certif_min_score' => $this->category_object->getCertificateMinScore(),
172
                'generate_certificates' => $this->category_object->getGenerateCertificates(),
173
                'is_requirement' => $this->category_object->getIsRequirement(),
174
            ]
175
        );
176
177
        $this->addElement('hidden', 'hid_id', $this->category_object->get_id());
178
        $this->addElement(
179
            'hidden',
180
            'course_code',
181
            $this->category_object->get_course_code()
182
        );
183
        $this->build_basic_form();
184
    }
185
186
    /**
187
     * This function builds an 'select course' form in the add category process,
188
     * if parent id is 0, it will only show courses.
189
     */
190
    protected function build_select_course_form()
191
    {
192
        $select = $this->addElement(
193
            'select',
194
            'select_course',
195
            [get_lang('PickACourse'), 'test'],
196
            null
197
        );
198
        $courses = Category::get_all_courses(api_get_user_id());
199
        //only return courses that are not yet created by the teacher
200
        foreach ($courses as $row) {
201
            $select->addOption($row[1], $row[0]);
202
        }
203
        $this->setDefaults([
204
            'hid_user_id' => $this->category_object->get_user_id(),
205
            'hid_parent_id' => $this->category_object->get_parent_id(),
206
        ]);
207
        $this->addElement('hidden', 'hid_user_id');
208
        $this->addElement('hidden', 'hid_parent_id');
209
        $this->addElement('submit', null, get_lang('Ok'));
210
    }
211
212
    private function build_basic_form()
213
    {
214
        $this->addText(
215
            'name',
216
            get_lang('CategoryName'),
217
            true,
218
            ['maxlength' => '50']
219
        );
220
        $this->addRule('name', get_lang('ThisFieldIsRequired'), 'required');
221
222
        if (isset($this->category_object) &&
223
            $this->category_object->get_parent_id() == 0
224
        ) {
225
            // we can't change the root category
226
            $this->freeze('name');
227
        }
228
229
        $global_weight = api_get_setting('gradebook_default_weight');
230
231
        $value = 100;
232
        if (isset($global_weight)) {
233
            $value = $global_weight;
234
        }
235
236
        $this->addFloat(
237
            'weight',
238
            [
239
                get_lang('TotalWeight'),
240
                get_lang('TotalSumOfWeights'),
241
            ],
242
            true,
243
            ['value' => $value, 'maxlength' => '5']
244
        );
245
246
        $skillsDefaults = [];
247
248
        $allowSkillEdit = api_is_platform_admin() || api_is_drh();
249
        if (api_get_configuration_value('skills_teachers_can_assign_skills')) {
250
            $allowSkillEdit = $allowSkillEdit || api_is_allowed_to_edit();
251
        }
252
253
        if ($allowSkillEdit) {
254
            if (Skill::isToolAvailable()) {
255
                $skillSelect = $this->addElement(
256
                    'select_ajax',
257
                    'skills',
258
                    [
259
                        get_lang('Skills'),
260
                        get_lang('SkillsAchievedWhenAchievingThisGradebook'),
261
                    ],
262
                    null,
263
                    [
264
                        'id' => 'skills',
265
                        'multiple' => 'multiple',
266
                        'url' => api_get_path(WEB_AJAX_PATH).'skill.ajax.php?a=search_skills',
267
                    ]
268
                );
269
270
                // The magic should be here
271
                $skills = $this->category_object->get_skills();
272
                foreach ($skills as $skill) {
273
                    $skillsDefaults[] = $skill['id'];
274
                    $skillSelect->addOption($skill['name'], $skill['id']);
275
                }
276
            }
277
        }
278
279
        $defaultCertification = 0;
280
        if (!empty($this->category_object)) {
281
            $defaultCertification = $this->category_object->getCertificateMinScore();
282
        }
283
284
        if (isset($this->category_object) &&
285
            0 == $this->category_object->get_parent_id()
286
        ) {
287
            $model = ExerciseLib::getCourseScoreModel();
288
            if (empty($model)) {
289
                $this->addText(
290
                    'certif_min_score',
291
                    get_lang('CertificateMinScore'),
292
                    true,
293
                    ['maxlength' => '5']
294
                );
295
296
                if (true === api_get_configuration_value('gradebook_enable_subcategory_skills_independant_assignement')) {
297
                    // It allows the acquisition of competencies independently in the subcategories
298
                    $allowSkillsBySubCategory = $this->addCheckBox(
299
                        'allow_skills_by_subcategory',
300
                        [
301
                            null,
302
                            get_lang('ItAllowsTheAcquisitionOfSkillsBySubCategories'),
303
                        ],
304
                        get_lang('AllowsSkillsBySubCategories')
305
                    );
306
                    $allowSkillsBySubCategory->setChecked($this->category_object->getAllowSkillBySubCategory());
307
                }
308
            } else {
309
                $questionWeighting = $value;
310
                $defaultCertification = api_number_format($this->category_object->getCertificateMinScore(), 2);
311
                $select = $this->addSelect(
312
                    'certif_min_score',
313
                    get_lang('CertificateMinScore'),
314
                    [],
315
                    ['disable_js' => true]
316
                );
317
318
                foreach ($model['score_list'] as $item) {
319
                    $i = api_number_format($item['score_to_qualify'] / 100 * $questionWeighting, 2);
320
                    $model = ExerciseLib::getModelStyle($item, $i);
321
                    $attributes = ['class' => $item['css_class']];
322
                    if ($defaultCertification == $i) {
323
                        $attributes['selected'] = 'selected';
324
                    }
325
                    $select->addOption($model, $i, $attributes);
326
                }
327
                $select->updateSelectWithSelectedOption($this);
328
            }
329
330
            $this->addRule(
331
                'certif_min_score',
332
                get_lang('OnlyNumbers'),
333
                'numeric'
334
            );
335
            $this->addRule(
336
                'certif_min_score',
337
                get_lang('NegativeValue'),
338
                'compare',
339
                '>=',
340
                'server',
341
                false,
342
                false,
343
                0
344
            );
345
        } else {
346
            // It enables minimun score to get the skills independant assigment
347
            if (true === api_get_configuration_value('gradebook_enable_subcategory_skills_independant_assignement')) {
348
                $allowSkillsBySubCategory = $this->category_object->getAllowSkillBySubCategory($this->category_object->get_parent_id());
349
                if ($allowSkillsBySubCategory) {
350
                    $this->addText(
351
                        'certif_min_score',
352
                        get_lang('SkillMinScore'),
353
                        true,
354
                        ['maxlength' => '5']
355
                    );
356
                    $this->addRule(
357
                        'certif_min_score',
358
                        get_lang('OnlyNumbers'),
359
                        'numeric'
360
                    );
361
                    $this->addRule(
362
                        'certif_min_score',
363
                        get_lang('NegativeValue'),
364
                        'compare',
365
                        '>=',
366
                        'server',
367
                        false,
368
                        false,
369
                        0
370
                    );
371
                }
372
            }
373
            $this->addElement('checkbox', 'visible', null, get_lang('Visible'));
374
        }
375
376
        $this->addElement('hidden', 'hid_user_id');
377
        $this->addElement('hidden', 'hid_parent_id');
378
        $this->addElement(
379
            'textarea',
380
            'description',
381
            get_lang('Description')
382
        );
383
384
        if (isset($this->category_object) &&
385
            $this->category_object->get_parent_id() == 0 &&
386
            (api_is_platform_admin() || api_get_setting('teachers_can_change_grade_model_settings') == 'true')
387
        ) {
388
            // Getting grade models
389
            $obj = new GradeModel();
390
            $obj->fill_grade_model_select_in_form(
391
                $this,
392
                'grade_model_id',
393
                $this->category_object->get_grade_model_id()
394
            );
395
396
            // Freeze or not
397
            $course_code = api_get_course_id();
398
            $session_id = api_get_session_id();
399
            $test_cats = Category::load(
400
                null,
401
                null,
402
                $course_code,
403
                null,
404
                null,
405
                $session_id,
406
                false
407
            );
408
            $links = null;
409
            if (!empty($test_cats[0])) {
410
                $links = $test_cats[0]->get_links();
411
            }
412
413
            if (count($test_cats) > 1 || !empty($links)) {
414
                if ('true' == api_get_setting('gradebook_enable_grade_model')) {
415
                    $this->freeze('grade_model_id');
416
                }
417
            }
418
419
            $generateCertificatesParams = [];
420
            if ($this->category_object->getGenerateCertificates()) {
421
                $generateCertificatesParams['checked'] = 'checked';
422
            }
423
424
            $this->addElement(
425
                'checkbox',
426
                'generate_certificates',
427
                null,
428
                get_lang('GenerateCertificates'),
429
                $generateCertificatesParams
430
            );
431
        }
432
433
        //if (!empty($session_id)) {
434
        $isRequirementCheckbox = $this->addCheckBox(
435
                'is_requirement',
436
                [
437
                    null,
438
                    get_lang('ConsiderThisGradebookAsRequirementForASessionSequence'),
439
                ],
440
                get_lang('IsRequirement')
441
            );
442
        //}
443
444
        if ($this->category_object->getIsRequirement()) {
445
            $isRequirementCheckbox->setChecked(true);
446
        }
447
448
        $documentId = $this->category_object->getDocumentId();
449
        if (!empty($documentId)) {
450
            $documentData = DocumentManager::get_document_data_by_id($documentId, api_get_course_id());
451
452
            if (!empty($documentData)) {
453
                $this->addLabel(get_lang('Certificate'), $documentData['title']);
454
            }
455
        }
456
457
        if ($this->form_type == self::TYPE_ADD) {
458
            $this->addButtonCreate(get_lang('AddCategory'));
459
        } else {
460
            $this->addElement('hidden', 'editcat', intval($_GET['editcat']));
461
            $this->addButtonUpdate(get_lang('EditCategory'));
462
        }
463
464
        $setting = api_get_setting('tool_visible_by_default_at_creation');
465
        $visibility_default = 1;
466
        if (isset($setting['gradebook']) && $setting['gradebook'] == 'false') {
467
            $visibility_default = 0;
468
        }
469
470
        $this->setDefaults(
471
            [
472
                'visible' => $visibility_default,
473
                'skills' => $skillsDefaults,
474
                'certif_min_score' => (string) $defaultCertification,
475
            ]
476
        );
477
    }
478
}
479