Passed
Push — 1.11.x ( bce6cd...c146d9 )
by Angel Fernando Quiroz
12:25
created

main/gradebook/lib/be/evaluation.class.php (2 issues)

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Entity\GradebookEvaluation;
5
use ChamiloSession as Session;
6
7
/**
8
 * Class Evaluation.
9
 */
10
class Evaluation implements GradebookItem
11
{
12
    public $studentList;
13
    /** @var GradebookEvaluation */
14
    public $entity;
15
    private $id;
16
    private $name;
17
    private $description;
18
    private $user_id;
19
    private $course_code;
20
    /** @var Category */
21
    private $category;
22
    private $created_at;
23
    private $weight;
24
    private $eval_max;
25
    private $visible;
26
    private $sessionId;
27
28
    /**
29
     * Construct.
30
     */
31
    public function __construct()
32
    {
33
    }
34
35
    /**
36
     * @return Category
37
     */
38
    public function getCategory()
39
    {
40
        return $this->category;
41
    }
42
43
    /**
44
     * @param Category $category
45
     */
46
    public function setCategory($category)
47
    {
48
        $this->category = $category;
49
    }
50
51
    /**
52
     * @return int
53
     */
54
    public function get_category_id()
55
    {
56
        return $this->category->get_id();
57
    }
58
59
    /**
60
     * @param int $category_id
61
     */
62
    public function set_category_id($category_id)
63
    {
64
        $categories = Category::load($category_id);
65
        if (isset($categories[0])) {
66
            $this->setCategory($categories[0]);
67
        }
68
    }
69
70
    /**
71
     * @return int
72
     */
73
    public function get_id()
74
    {
75
        return (int) $this->id;
76
    }
77
78
    /**
79
     * @return string
80
     */
81
    public function get_name()
82
    {
83
        return $this->name;
84
    }
85
86
    /**
87
     * @return string
88
     */
89
    public function get_description()
90
    {
91
        return $this->description;
92
    }
93
94
    public function get_user_id()
95
    {
96
        return $this->user_id;
97
    }
98
99
    public function get_course_code()
100
    {
101
        return $this->course_code;
102
    }
103
104
    /**
105
     * @return int
106
     */
107
    public function getSessionId()
108
    {
109
        return $this->sessionId;
110
    }
111
112
    /**
113
     * @param int $sessionId
114
     */
115
    public function setSessionId($sessionId)
116
    {
117
        $this->sessionId = (int) $sessionId;
118
    }
119
120
    public function set_session_id($sessionId)
121
    {
122
        $this->setSessionId($sessionId);
123
    }
124
125
    public function get_date()
126
    {
127
        return $this->created_at;
128
    }
129
130
    public function get_weight()
131
    {
132
        return $this->weight;
133
    }
134
135
    public function get_max()
136
    {
137
        return $this->eval_max;
138
    }
139
140
    public function get_type()
141
    {
142
        return $this->type;
143
    }
144
145
    public function is_visible()
146
    {
147
        return $this->visible;
148
    }
149
150
    public function get_locked()
151
    {
152
        return $this->locked;
153
    }
154
155
    public function is_locked()
156
    {
157
        return isset($this->locked) && 1 == $this->locked ? true : false;
158
    }
159
160
    public function set_id($id)
161
    {
162
        $this->id = (int) $id;
163
    }
164
165
    public function set_name($name)
166
    {
167
        $this->name = $name;
168
    }
169
170
    public function set_description($description)
171
    {
172
        $this->description = $description;
173
    }
174
175
    public function set_user_id($user_id)
176
    {
177
        $this->user_id = $user_id;
178
    }
179
180
    public function set_course_code($course_code)
181
    {
182
        $this->course_code = $course_code;
183
    }
184
185
    public function set_date($date)
186
    {
187
        $this->created_at = $date;
188
    }
189
190
    public function set_weight($weight)
191
    {
192
        $this->weight = $weight;
193
    }
194
195
    public function set_max($max)
196
    {
197
        $this->eval_max = $max;
198
    }
199
200
    public function set_visible($visible)
201
    {
202
        $this->visible = $visible;
203
    }
204
205
    public function set_type($type)
206
    {
207
        $this->type = $type;
208
    }
209
210
    public function set_locked($locked)
211
    {
212
        $this->locked = $locked;
213
    }
214
215
    /**
216
     * Retrieve evaluations and return them as an array of Evaluation objects.
217
     *
218
     * @param int    $id          evaluation id
219
     * @param int    $user_id     user id (evaluation owner)
220
     * @param string $course_code course code
221
     * @param int    $category_id parent category
222
     * @param int    $visible     visible
223
     *
224
     * @return array
225
     */
226
    public static function load(
227
        $id = null,
228
        $user_id = null,
229
        $course_code = null,
230
        $category_id = null,
231
        $visible = null,
232
        $locked = null
233
    ) {
234
        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
235
        $sql = 'SELECT * FROM '.$table;
236
        $paramcount = 0;
237
238
        if (isset($id)) {
239
            $sql .= ' WHERE id = '.intval($id);
240
            $paramcount++;
241
        }
242
243
        if (isset($user_id)) {
244
            if (0 != $paramcount) {
245
                $sql .= ' AND';
246
            } else {
247
                $sql .= ' WHERE';
248
            }
249
            $sql .= ' user_id = '.intval($user_id);
250
            $paramcount++;
251
        }
252
253
        if (isset($course_code) && $course_code != '-1') {
254
            if ($paramcount != 0) {
255
                $sql .= ' AND';
256
            } else {
257
                $sql .= ' WHERE';
258
            }
259
            $sql .= " course_code = '".Database::escape_string($course_code)."'";
260
            $paramcount++;
261
        }
262
263
        if (isset($category_id)) {
264
            if ($paramcount != 0) {
265
                $sql .= ' AND';
266
            } else {
267
                $sql .= ' WHERE';
268
            }
269
            $sql .= ' category_id = '.intval($category_id);
270
            $paramcount++;
271
        }
272
273
        if (isset($visible)) {
274
            if ($paramcount != 0) {
275
                $sql .= ' AND';
276
            } else {
277
                $sql .= ' WHERE';
278
            }
279
            $sql .= ' visible = '.intval($visible);
280
            $paramcount++;
281
        }
282
283
        if (isset($locked)) {
284
            if ($paramcount != 0) {
285
                $sql .= ' AND';
286
            } else {
287
                $sql .= ' WHERE';
288
            }
289
            $sql .= ' locked = '.intval($locked);
290
        }
291
292
        $result = Database::query($sql);
293
        $allEval = self::create_evaluation_objects_from_sql_result($result);
294
295
        return $allEval;
296
    }
297
298
    /**
299
     * Insert this evaluation into the database.
300
     */
301
    public function add()
302
    {
303
        if (isset($this->name) &&
304
            isset($this->user_id) &&
305
            isset($this->weight) &&
306
            isset($this->eval_max) &&
307
            isset($this->visible)
308
        ) {
309
            $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
310
311
            $sql = 'INSERT INTO '.$table
312
                .' (name, user_id, weight, max, visible';
313
            if (isset($this->description)) {
314
                $sql .= ',description';
315
            }
316
            if (isset($this->course_code)) {
317
                $sql .= ', course_code';
318
            }
319
            if (isset($this->category)) {
320
                $sql .= ', category_id';
321
            }
322
            $sql .= ', created_at';
323
            $sql .= ',type';
324
            $sql .= ") VALUES ('".Database::escape_string($this->get_name())."'"
325
                .','.intval($this->get_user_id())
326
                .','.api_float_val($this->get_weight())
327
                .','.intval($this->get_max())
328
                .','.intval($this->is_visible());
329
            if (isset($this->description)) {
330
                $sql .= ",'".Database::escape_string($this->get_description())."'";
331
            }
332
            if (isset($this->course_code)) {
333
                $sql .= ",'".Database::escape_string($this->get_course_code())."'";
334
            }
335
            if (isset($this->category)) {
336
                $sql .= ','.intval($this->get_category_id());
337
            }
338
            if (empty($this->type)) {
339
                $this->type = 'evaluation';
340
            }
341
            $sql .= ", '".api_get_utc_datetime()."'";
342
            $sql .= ',\''.Database::escape_string($this->type).'\'';
343
            $sql .= ")";
344
345
            Database::query($sql);
346
            $this->set_id(Database::insert_id());
347
        } else {
348
            return false;
349
            //die('Error in Evaluation add: required field empty');
350
        }
351
    }
352
353
    /**
354
     * @param int $id
355
     */
356
    public function addEvaluationLog($id)
357
    {
358
        if (!empty($id)) {
359
            $tbl_grade_evaluations = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
360
            $tbl_grade_linkeval_log = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG);
361
            $eval = new Evaluation();
362
            $dateobject = $eval->load($id, null, null, null, null);
363
            $arreval = get_object_vars($dateobject[0]);
364
            if (!empty($arreval['id'])) {
365
                $sql = 'SELECT weight from '.$tbl_grade_evaluations.'
366
                        WHERE id='.$arreval['id'];
367
                $rs = Database::query($sql);
368
                $row_old_weight = Database::fetch_array($rs, 'ASSOC');
369
                $current_date = api_get_utc_datetime();
370
                $params = [
371
                    'id_linkeval_log' => $arreval['id'],
372
                    'name' => $arreval['name'],
373
                    'description' => $arreval['description'],
374
                    'created_at' => $current_date,
375
                    'weight' => $row_old_weight['weight'],
376
                    'visible' => $arreval['visible'],
377
                    'type' => 'evaluation',
378
                    'user_id_log' => api_get_user_id(),
379
                ];
380
                Database::insert($tbl_grade_linkeval_log, $params);
381
            }
382
        }
383
    }
384
385
    /**
386
     * Update the properties of this evaluation in the database.
387
     */
388
    public function save()
389
    {
390
        $tbl_grade_evaluations = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
391
        $sql = 'UPDATE '.$tbl_grade_evaluations
392
            ." SET name = '".Database::escape_string($this->get_name())."'"
393
            .', description = ';
394
        if (isset($this->description)) {
395
            $sql .= "'".Database::escape_string($this->get_description())."'";
396
        } else {
397
            $sql .= 'null';
398
        }
399
        $sql .= ', user_id = '.intval($this->get_user_id())
400
            .', course_code = ';
401
        if (isset($this->course_code)) {
402
            $sql .= "'".Database::escape_string($this->get_course_code())."'";
403
        } else {
404
            $sql .= 'null';
405
        }
406
        $sql .= ', category_id = ';
407
        if (isset($this->category)) {
408
            $sql .= intval($this->get_category_id());
409
        } else {
410
            $sql .= 'null';
411
        }
412
        $sql .= ', weight = "'.Database::escape_string($this->get_weight()).'" '
413
            .', max = '.intval($this->get_max())
414
            .', visible = '.intval($this->is_visible())
415
            .' WHERE id = '.intval($this->id);
416
        //recorded history
417
418
        $eval_log = new Evaluation();
419
        $eval_log->addEvaluationLog($this->id);
420
        Database::query($sql);
421
    }
422
423
    /**
424
     * Delete this evaluation from the database.
425
     */
426
    public function delete()
427
    {
428
        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
429
        $sql = 'DELETE FROM '.$table.'
430
                WHERE id = '.$this->get_id();
431
        Database::query($sql);
432
    }
433
434
    /**
435
     * Check if an evaluation name (with the same parent category) already exists.
436
     *
437
     * @param string $name to check (if not given, the name property of this object will be checked)
438
     * @param $parent parent category
439
     *
440
     * @return bool
441
     */
442
    public function does_name_exist($name, $parent)
443
    {
444
        if (!isset($name)) {
445
            $name = $this->name;
446
            $parent = $this->category;
447
        }
448
        $tbl_grade_evaluations = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
449
        $sql = "SELECT count(id) AS number
450
                FROM $tbl_grade_evaluations
451
                WHERE name = '".Database::escape_string($name)."'";
452
453
        if (api_is_allowed_to_edit()) {
454
            $parent = Category::load($parent);
455
            $code = $parent[0]->get_course_code();
456
            $courseInfo = api_get_course_info($code);
457
            $courseId = $courseInfo['real_id'];
458
459
            if (isset($code) && $code != '0') {
460
                $main_course_user_table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
461
                $sql .= ' AND user_id IN (
462
                     SELECT user_id FROM '.$main_course_user_table.'
463
                     WHERE
464
                        c_id = '.$courseId.' AND
465
                        status = '.COURSEMANAGER.'
466
                    )';
467
            } else {
468
                $sql .= ' AND user_id = '.api_get_user_id();
469
            }
470
        } else {
471
            $sql .= ' AND user_id = '.api_get_user_id();
472
        }
473
474
        if (!isset($parent)) {
475
            $sql .= ' AND category_id is null';
476
        } else {
477
            $sql .= ' AND category_id = '.intval($parent);
478
        }
479
        $result = Database::query($sql);
480
        $number = Database::fetch_row($result);
481
482
        return $number[0] != 0;
483
    }
484
485
    /**
486
     * Are there any results for this evaluation yet ?
487
     * The 'max' property should not be changed then.
488
     *
489
     * @return bool
490
     */
491
    public function has_results()
492
    {
493
        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
494
        $sql = 'SELECT count(id) AS number
495
                FROM '.$table.'
496
                WHERE evaluation_id = '.intval($this->get_id());
497
        $result = Database::query($sql);
498
        $number = Database::fetch_row($result);
499
500
        return 0 != $number[0];
501
    }
502
503
    /**
504
     * Delete all results for this evaluation.
505
     */
506
    public function delete_results()
507
    {
508
        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
509
        $sql = 'DELETE FROM '.$table.'
510
                WHERE evaluation_id = '.$this->get_id();
511
        Database::query($sql);
512
    }
513
514
    /**
515
     * Delete this evaluation and all underlying results.
516
     */
517
    public function delete_with_results()
518
    {
519
        $this->delete_results();
520
        $this->delete();
521
    }
522
523
    /**
524
     * Check if the given score is possible for this evaluation.
525
     */
526
    public function is_valid_score($score)
527
    {
528
        return is_numeric($score) && $score >= 0 && $score <= $this->eval_max;
529
    }
530
531
    /**
532
     * Calculate the score of this evaluation.
533
     *
534
     * @param int    $stud_id (default: all students who have results for this eval - then the average is returned)
535
     * @param string $type    (best, average, ranking)
536
     *
537
     * @return array (score, max) if student is given
538
     *               array (sum of scores, number of scores) otherwise
539
     *               or null if no scores available
540
     */
541
    public function calc_score($stud_id = null, $type = null)
542
    {
543
        $allowStats = api_get_configuration_value('allow_gradebook_stats');
544
545
        if ($allowStats) {
546
            $evaluation = $this->entity;
547
            if (!empty($evaluation)) {
548
                $weight = $evaluation->getMax();
549
                switch ($type) {
550
                    case 'best':
551
                        $bestResult = $evaluation->getBestScore();
552
                        $result = [$bestResult, $weight];
553
554
                        return $result;
555
                        break;
556
                    case 'average':
557
                        $count = count($evaluation->getUserScoreList());
558
                        if (empty($count)) {
559
                            $result = [0, $weight];
560
561
                            return $result;
562
                        }
563
564
                        $sumResult = array_sum($evaluation->getUserScoreList());
565
                        $result = [$sumResult / $count, $weight];
566
567
                        return $result;
568
                        break;
569
                    case 'ranking':
570
                        $ranking = AbstractLink::getCurrentUserRanking($stud_id, $evaluation->getUserScoreList());
571
572
                        return $ranking;
573
                        break;
574
                    default:
575
                        $weight = $evaluation->getMax();
576
                        if (!empty($stud_id)) {
577
                            $scoreList = $evaluation->getUserScoreList();
578
                            $result = [0, $weight];
579
                            if (isset($scoreList[$stud_id])) {
580
                                $result = [$scoreList[$stud_id], $weight];
581
                            }
582
583
                            return $result;
584
                        } else {
585
                            $studentCount = count($evaluation->getUserScoreList());
586
                            $sumResult = array_sum($evaluation->getUserScoreList());
587
                            $result = [$sumResult, $studentCount];
588
                        }
589
590
                        return $result;
591
                        break;
592
                }
593
            }
594
        }
595
596
        $useSession = true;
597
        if (isset($stud_id) && empty($type)) {
598
            $key = 'result_score_student_list_'.api_get_course_int_id().'_'.api_get_session_id().'_'.$this->id.'_'.$stud_id;
599
            $data = Session::read('calc_score');
600
            $results = isset($data[$key]) ? $data[$key] : null;
601
602
            if (false == $useSession) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
603
                $results = null;
604
            }
605
            $results = null;
606
            if (empty($results)) {
607
                $results = Result::load(null, $stud_id, $this->id);
608
                Session::write('calc_score', [$key => $results]);
609
            }
610
611
            $score = null;
612
            if (!empty($results)) {
613
                /** @var Result $res */
614
                foreach ($results as $res) {
615
                    $score = $res->get_score();
616
                }
617
            }
618
619
            return [$score, $this->get_max()];
620
        } else {
621
            $count = 0;
622
            $sum = 0;
623
            $bestResult = 0;
624
            $weight = 0;
625
            $sumResult = 0;
626
627
            $key = 'result_score_student_list_'.api_get_course_int_id().'_'.api_get_session_id().'_'.$this->id;
628
            $data = Session::read('calc_score');
629
            $allResults = isset($data[$key]) ? $data[$key] : null;
630
            if (false == $useSession) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
631
                $allResults = null;
632
            }
633
634
            if (empty($allResults)) {
635
                $allResults = Result::load(null, null, $this->id);
636
                Session::write($key, $allResults);
637
            }
638
639
            $students = [];
640
            /** @var Result $res */
641
            foreach ($allResults as $res) {
642
                $score = $res->get_score();
643
                if (!empty($score) || '0' == $score) {
644
                    $count++;
645
                    $sum += $score / $this->get_max();
646
                    $sumResult += $score;
647
                    if ($score > $bestResult) {
648
                        $bestResult = $score;
649
                    }
650
                    $weight = $this->get_max();
651
                }
652
                $students[$res->get_user_id()] = $score;
653
            }
654
655
            if (empty($count)) {
656
                return [null, null];
657
            }
658
659
            switch ($type) {
660
                case 'best':
661
                    return [$bestResult, $weight];
662
                    break;
663
                case 'average':
664
                    return [$sumResult / $count, $weight];
665
                    break;
666
                case 'ranking':
667
                    $students = [];
668
                    /** @var Result $res */
669
                    foreach ($allResults as $res) {
670
                        $score = $res->get_score();
671
                        $students[$res->get_user_id()] = $score;
672
                    }
673
674
                    return AbstractLink::getCurrentUserRanking($stud_id, $students);
675
                    break;
676
                default:
677
                    return [$sum, $count];
678
                    break;
679
            }
680
        }
681
    }
682
683
    /**
684
     * Generate an array of possible categories where this evaluation can be moved to.
685
     * Notice: its own parent will be included in the list: it's up to the frontend
686
     * to disable this element.
687
     *
688
     * @return array 2-dimensional array - every element contains 3 subelements (id, name, level)
689
     */
690
    public function get_target_categories()
691
    {
692
        // - course independent evaluation
693
        //   -> movable to root or other course independent categories
694
        // - evaluation inside a course
695
        //   -> movable to root, independent categories or categories inside the course
696
        $user = api_is_platform_admin() ? null : api_get_user_id();
697
        $targets = [];
698
        $level = 0;
699
        $root = [0, get_lang('RootCat'), $level];
700
        $targets[] = $root;
701
702
        if (isset($this->course_code) && !empty($this->course_code)) {
703
            $crscats = Category::load(null, null, $this->course_code, 0);
704
            foreach ($crscats as $cat) {
705
                $targets[] = [$cat->get_id(), $cat->get_name(), $level + 1];
706
                $targets = $this->addTargetSubcategories(
707
                    $targets,
708
                    $level + 1,
709
                    $cat->get_id()
710
                );
711
            }
712
        }
713
714
        $indcats = Category::load(null, $user, 0, 0);
715
        foreach ($indcats as $cat) {
716
            $targets[] = [$cat->get_id(), $cat->get_name(), $level + 1];
717
            $targets = $this->addTargetSubcategories(
718
                $targets,
719
                $level + 1,
720
                $cat->get_id()
721
            );
722
        }
723
724
        return $targets;
725
    }
726
727
    /**
728
     * Move this evaluation to the given category.
729
     * If this evaluation moves from inside a course to outside,
730
     * its course code is also changed.
731
     */
732
    public function move_to_cat($cat)
733
    {
734
        $this->set_category_id($cat->get_id());
735
        if ($this->get_course_code() != $cat->get_course_code()) {
736
            $this->set_course_code($cat->get_course_code());
737
        }
738
        $this->save();
739
    }
740
741
    /**
742
     * Retrieve evaluations where a student has results for
743
     * and return them as an array of Evaluation objects.
744
     *
745
     * @param int $cat_id  parent category (use 'null' to retrieve them in all categories)
746
     * @param int $stud_id student id
747
     *
748
     * @return array
749
     */
750
    public static function get_evaluations_with_result_for_student($cat_id, $stud_id)
751
    {
752
        $tbl_grade_evaluations = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
753
        $tbl_grade_results = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
754
755
        $sql = 'SELECT * FROM '.$tbl_grade_evaluations.'
756
                WHERE id IN (
757
                    SELECT evaluation_id FROM '.$tbl_grade_results.'
758
                    WHERE user_id = '.intval($stud_id).' AND score IS NOT NULL
759
                )';
760
        if (!api_is_allowed_to_edit()) {
761
            $sql .= ' AND visible = 1';
762
        }
763
        if (isset($cat_id)) {
764
            $sql .= ' AND category_id = '.intval($cat_id);
765
        } else {
766
            $sql .= ' AND category_id >= 0';
767
        }
768
769
        $result = Database::query($sql);
770
        $alleval = self::create_evaluation_objects_from_sql_result($result);
771
772
        return $alleval;
773
    }
774
775
    /**
776
     * Get a list of students that do not have a result record for this evaluation.
777
     *
778
     * @param string $first_letter_user
779
     *
780
     * @return array
781
     */
782
    public function get_not_subscribed_students($first_letter_user = '')
783
    {
784
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
785
        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
786
787
        $sql = "SELECT user_id,lastname,firstname,username
788
                FROM $tbl_user
789
                WHERE
790
                    lastname LIKE '".Database::escape_string($first_letter_user)."%' AND
791
                    status = ".STUDENT." AND user_id NOT IN (
792
                        SELECT user_id FROM $table
793
                        WHERE evaluation_id = ".$this->get_id()."
794
                    )
795
                ORDER BY lastname";
796
797
        $result = Database::query($sql);
798
        $users = Database::store_result($result);
799
800
        return $users;
801
    }
802
803
    /**
804
     * Find evaluations by name.
805
     *
806
     * @param string $name_mask search string
807
     *
808
     * @return array evaluation objects matching the search criterium
809
     *
810
     * @todo can be written more efficiently using a new (but very complex) sql query
811
     */
812
    public function findEvaluations($name_mask, $selectcat)
813
    {
814
        $rootcat = Category::load($selectcat);
815
        $evals = $rootcat[0]->get_evaluations(
816
            (api_is_allowed_to_create_course() ? null : api_get_user_id()),
817
            true
818
        );
819
        $foundevals = [];
820
        foreach ($evals as $eval) {
821
            if (!(api_strpos(api_strtolower($eval->get_name()), api_strtolower($name_mask)) === false)) {
822
                $foundevals[] = $eval;
823
            }
824
        }
825
826
        return $foundevals;
827
    }
828
829
    public function get_item_type()
830
    {
831
        return 'E';
832
    }
833
834
    public function get_icon_name()
835
    {
836
        return $this->has_results() ? 'evalnotempty' : 'evalempty';
837
    }
838
839
    /**
840
     * Locks an evaluation, only one who can unlock it is the platform administrator.
841
     *
842
     * @param int locked 1 or unlocked 0
843
     */
844
    public function lock($locked)
845
    {
846
        $table_evaluation = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
847
        $sql = "UPDATE $table_evaluation
848
                SET locked = '".intval($locked)."'
849
                WHERE id='".$this->get_id()."'";
850
        Database::query($sql);
851
    }
852
853
    public function check_lock_permissions()
854
    {
855
        if (api_is_platform_admin()) {
856
            return true;
857
        } else {
858
            if ($this->is_locked()) {
859
                api_not_allowed();
860
            }
861
        }
862
    }
863
864
    public function delete_linked_data()
865
    {
866
    }
867
868
    /**
869
     * @return mixed
870
     */
871
    public function getStudentList()
872
    {
873
        return $this->studentList;
874
    }
875
876
    /**
877
     * @param $list
878
     */
879
    public function setStudentList($list)
880
    {
881
        $this->studentList = $list;
882
    }
883
884
    /**
885
     * @param int $evaluationId
886
     */
887
    public static function generateStats($evaluationId)
888
    {
889
        $allowStats = api_get_configuration_value('allow_gradebook_stats');
890
        if ($allowStats) {
891
            $evaluation = self::load($evaluationId);
892
893
            $results = Result::load(null, null, $evaluationId);
894
            $sumResult = 0;
895
            $bestResult = 0;
896
            $average = 0;
897
            $scoreList = [];
898
899
            if (!empty($results)) {
900
                /** @var Result $result */
901
                foreach ($results as $result) {
902
                    $score = $result->get_score();
903
                    $scoreList[$result->get_user_id()] = $score;
904
                    $sumResult += $score;
905
                    if ($score > $bestResult) {
906
                        $bestResult = $score;
907
                    }
908
                }
909
                $average = $sumResult / count($results);
910
            }
911
912
            /** @var Evaluation $evaluation */
913
            $evaluation = $evaluation[0];
914
            $evaluation = $evaluation->entity;
915
            $evaluation
916
                ->setBestScore($bestResult)
917
                ->setAverageScore($average)
918
                ->setUserScoreList($scoreList)
919
            ;
920
921
            $em = Database::getManager();
922
            $em->persist($evaluation);
923
            $em->flush();
924
        }
925
    }
926
927
    /**
928
     * @param array $result
929
     *
930
     * @return array
931
     */
932
    private static function create_evaluation_objects_from_sql_result($result)
933
    {
934
        $alleval = [];
935
        $allow = api_get_configuration_value('allow_gradebook_stats');
936
        if ($allow) {
937
            $em = Database::getManager();
938
            $repo = $em->getRepository('ChamiloCoreBundle:GradebookEvaluation');
939
        }
940
941
        if (Database::num_rows($result)) {
942
            while ($data = Database::fetch_array($result)) {
943
                $eval = new Evaluation();
944
                $eval->set_id($data['id']);
945
                $eval->set_name($data['name']);
946
                $eval->set_description($data['description']);
947
                $eval->set_user_id($data['user_id']);
948
                $eval->set_course_code($data['course_code']);
949
                $eval->set_category_id($data['category_id']);
950
                $eval->set_date(api_get_local_time($data['created_at']));
951
                $eval->set_weight($data['weight']);
952
                $eval->set_max($data['max']);
953
                $eval->set_visible($data['visible']);
954
                $eval->set_type($data['type']);
955
                $eval->set_locked($data['locked']);
956
                $eval->setSessionId(api_get_session_id());
957
958
                if ($allow) {
959
                    $eval->entity = $repo->find($data['id']);
960
                }
961
962
                $alleval[] = $eval;
963
            }
964
        }
965
966
        return $alleval;
967
    }
968
969
    /**
970
     * Internal function used by get_target_categories().
971
     *
972
     * @param array $targets
973
     * @param int   $level
974
     * @param int   $categoryId
975
     *
976
     * @return array
977
     */
978
    private function addTargetSubcategories($targets, $level, $categoryId)
979
    {
980
        $subcats = Category::load(null, null, null, $categoryId);
981
        foreach ($subcats as $cat) {
982
            $targets[] = [$cat->get_id(), $cat->get_name(), $level + 1];
983
            $targets = $this->addTargetSubcategories(
984
                $targets,
985
                $level + 1,
986
                $cat->get_id()
987
            );
988
        }
989
990
        return $targets;
991
    }
992
}
993