Completed
Push — master ( 7d9ab3...0334ca )
by Julito
08:48
created

Evaluation::setStudentList()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
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 $courseId;
27
    private $sessionId;
28
29
    /**
30
     * Construct.
31
     */
32
    public function __construct()
33
    {
34
    }
35
36
    /**
37
     * @return Category
38
     */
39
    public function getCategory()
40
    {
41
        return $this->category;
42
    }
43
44
    /**
45
     * @param Category $category
46
     */
47
    public function setCategory($category)
48
    {
49
        $this->category = $category;
50
    }
51
52
    /**
53
     * @return int
54
     */
55
    public function get_category_id()
56
    {
57
        return $this->category->get_id();
58
    }
59
60
    /**
61
     * @param int $category_id
62
     */
63
    public function set_category_id($category_id)
64
    {
65
        $categories = Category::load($category_id);
66
        if (isset($categories[0])) {
67
            $this->setCategory($categories[0]);
68
        }
69
    }
70
71
    /**
72
     * @return int
73
     */
74
    public function get_id()
75
    {
76
        return (int) $this->id;
77
    }
78
79
    /**
80
     * @return string
81
     */
82
    public function get_name()
83
    {
84
        return $this->name;
85
    }
86
87
    /**
88
     * @return string
89
     */
90
    public function get_description()
91
    {
92
        return $this->description;
93
    }
94
95
    public function get_user_id()
96
    {
97
        return $this->user_id;
98
    }
99
100
    public function get_course_code()
101
    {
102
        return $this->course_code;
103
    }
104
105
    /**
106
     * @return int
107
     */
108
    public function getSessionId()
109
    {
110
        return $this->sessionId;
111
    }
112
113
    /**
114
     * @param int $sessionId
115
     */
116
    public function setSessionId($sessionId)
117
    {
118
        $this->sessionId = (int) $sessionId;
119
    }
120
121
    public function get_date()
122
    {
123
        return $this->created_at;
124
    }
125
126
    public function get_weight()
127
    {
128
        return $this->weight;
129
    }
130
131
    public function get_max()
132
    {
133
        return $this->eval_max;
134
    }
135
136
    public function get_type()
137
    {
138
        return $this->type;
139
    }
140
141
    public function is_visible()
142
    {
143
        return $this->visible;
144
    }
145
146
    public function get_locked()
147
    {
148
        return $this->locked;
149
    }
150
151
    public function is_locked()
152
    {
153
        return isset($this->locked) && 1 == $this->locked ? true : false;
154
    }
155
156
    public function set_id($id)
157
    {
158
        $this->id = (int) $id;
159
    }
160
161
    public function set_name($name)
162
    {
163
        $this->name = $name;
164
    }
165
166
    public function set_description($description)
167
    {
168
        $this->description = $description;
169
    }
170
171
    public function set_user_id($user_id)
172
    {
173
        $this->user_id = $user_id;
174
    }
175
176
    public function getCourseId()
177
    {
178
        return $this->courseId;
179
    }
180
181
    public function set_course_code($course_code)
182
    {
183
        $this->course_code = $course_code;
184
    }
185
186
    public function set_date($date)
187
    {
188
        $this->created_at = $date;
189
    }
190
191
    public function set_weight($weight)
192
    {
193
        $this->weight = $weight;
194
    }
195
196
    public function set_max($max)
197
    {
198
        $this->eval_max = $max;
199
    }
200
201
    public function set_visible($visible)
202
    {
203
        $this->visible = $visible;
204
    }
205
206
    public function set_type($type)
207
    {
208
        $this->type = $type;
209
    }
210
211
    public function set_locked($locked)
212
    {
213
        $this->locked = $locked;
214
    }
215
216
    /**
217
     * Retrieve evaluations and return them as an array of Evaluation objects.
218
     *
219
     * @param int    $id          evaluation id
220
     * @param int    $user_id     user id (evaluation owner)
221
     * @param string $course_code course code
222
     * @param int    $category_id parent category
223
     * @param int    $visible     visible
224
     *
225
     * @return array
226
     */
227
    public static function load(
228
        $id = null,
229
        $user_id = null,
230
        $course_code = null,
231
        $category_id = null,
232
        $visible = null,
233
        $locked = null
234
    ) {
235
        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
236
        $sql = 'SELECT * FROM '.$table;
237
        $paramcount = 0;
238
239
        if (isset($id)) {
240
            $sql .= ' WHERE id = '.intval($id);
241
            $paramcount++;
242
        }
243
244
        if (isset($user_id)) {
245
            if (0 != $paramcount) {
246
                $sql .= ' AND';
247
            } else {
248
                $sql .= ' WHERE';
249
            }
250
            $sql .= ' user_id = '.intval($user_id);
251
            $paramcount++;
252
        }
253
254
        if (isset($course_code) && '-1' != $course_code) {
255
            $courseInfo = api_get_course_info($course_code);
256
            if ($courseInfo) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $courseInfo of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
257
                if (0 != $paramcount) {
258
                    $sql .= ' AND';
259
                } else {
260
                    $sql .= ' WHERE';
261
                }
262
                $sql .= " c_id = '".$courseInfo['real_id']."'";
263
                $paramcount++;
264
            }
265
        }
266
267
        if (isset($category_id)) {
268
            if (0 != $paramcount) {
269
                $sql .= ' AND';
270
            } else {
271
                $sql .= ' WHERE';
272
            }
273
            $sql .= ' category_id = '.intval($category_id);
274
            $paramcount++;
275
        }
276
277
        if (isset($visible)) {
278
            if (0 != $paramcount) {
279
                $sql .= ' AND';
280
            } else {
281
                $sql .= ' WHERE';
282
            }
283
            $sql .= ' visible = '.intval($visible);
284
            $paramcount++;
285
        }
286
287
        if (isset($locked)) {
288
            if (0 != $paramcount) {
289
                $sql .= ' AND';
290
            } else {
291
                $sql .= ' WHERE';
292
            }
293
            $sql .= ' locked = '.intval($locked);
294
        }
295
296
        $result = Database::query($sql);
297
298
        return self::create_evaluation_objects_from_sql_result($result);
299
    }
300
301
    /**
302
     * Insert this evaluation into the database.
303
     */
304
    public function add()
305
    {
306
        if (isset($this->name) &&
307
            isset($this->user_id) &&
308
            isset($this->weight) &&
309
            isset($this->eval_max) &&
310
            isset($this->visible)
311
        ) {
312
            if (empty($this->type)) {
313
                $this->type = 'evaluation';
314
            }
315
            $em = Database::getManager();
316
317
            $evaluation = new GradebookEvaluation();
318
            $evaluation
319
                ->setDescription($this->description)
320
                ->setCourse(api_get_course_entity())
321
                ->setName($this->get_name())
322
                ->setCategoryId($this->get_category_id())
323
                ->setUserId($this->get_user_id())
324
                ->setWeight(api_float_val($this->get_weight()))
325
                ->setMax($this->get_max())
326
                ->setVisible($this->is_visible())
327
                ->setType($this->type)
328
            ;
329
            $em->persist($evaluation);
330
            $em->flush();
331
            $this->set_id($evaluation->getId());
332
        }
333
334
        return false;
335
    }
336
337
    /**
338
     * @param int $id
339
     */
340
    public function addEvaluationLog($id)
341
    {
342
        if (!empty($id)) {
343
            $tbl_grade_evaluations = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
344
            $tbl_grade_linkeval_log = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG);
345
            $eval = new Evaluation();
346
            $dateobject = $eval->load($id, null, null, null, null);
347
            $arreval = get_object_vars($dateobject[0]);
348
            if (!empty($arreval['id'])) {
349
                $sql = 'SELECT weight from '.$tbl_grade_evaluations.'
350
                        WHERE id='.$arreval['id'];
351
                $rs = Database::query($sql);
352
                $row_old_weight = Database::fetch_array($rs, 'ASSOC');
353
                $current_date = api_get_utc_datetime();
354
                $params = [
355
                    'id_linkeval_log' => $arreval['id'],
356
                    'name' => $arreval['name'],
357
                    'description' => $arreval['description'],
358
                    'created_at' => $current_date,
359
                    'weight' => $row_old_weight['weight'],
360
                    'visible' => $arreval['visible'],
361
                    'type' => 'evaluation',
362
                    'user_id_log' => api_get_user_id(),
363
                ];
364
                Database::insert($tbl_grade_linkeval_log, $params);
365
            }
366
        }
367
    }
368
369
    /**
370
     * Update the properties of this evaluation in the database.
371
     */
372
    public function save()
373
    {
374
        $tbl_grade_evaluations = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
375
        $sql = 'UPDATE '.$tbl_grade_evaluations
376
            ." SET name = '".Database::escape_string($this->get_name())."'"
377
            .', description = ';
378
        if (isset($this->description)) {
379
            $sql .= "'".Database::escape_string($this->get_description())."'";
380
        } else {
381
            $sql .= 'null';
382
        }
383
        $sql .= ', user_id = '.intval($this->get_user_id())
384
            .', c_id = ';
385
        if (isset($this->courseId)) {
386
            $sql .= "'".Database::escape_string($this->getCourseId())."'";
387
        } else {
388
            $sql .= 'null';
389
        }
390
        $sql .= ', category_id = ';
391
        if (isset($this->category)) {
392
            $sql .= intval($this->get_category_id());
393
        } else {
394
            $sql .= 'null';
395
        }
396
        $sql .= ', weight = "'.Database::escape_string($this->get_weight()).'" '
397
            .', max = '.intval($this->get_max())
398
            .', visible = '.intval($this->is_visible())
399
            .' WHERE id = '.intval($this->id);
400
        //recorded history
401
402
        $eval_log = new Evaluation();
403
        $eval_log->addEvaluationLog($this->id);
404
        Database::query($sql);
405
    }
406
407
    /**
408
     * Delete this evaluation from the database.
409
     */
410
    public function delete()
411
    {
412
        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
413
        $sql = 'DELETE FROM '.$table.'
414
                WHERE id = '.$this->get_id();
415
        Database::query($sql);
416
    }
417
418
    /**
419
     * Check if an evaluation name (with the same parent category) already exists.
420
     *
421
     * @param string $name to check (if not given, the name property of this object will be checked)
422
     * @param $parent parent category
423
     *
424
     * @return bool
425
     */
426
    public function does_name_exist($name, $parent)
427
    {
428
        if (!isset($name)) {
429
            $name = $this->name;
430
            $parent = $this->category;
431
        }
432
        $tbl_grade_evaluations = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
433
        $sql = "SELECT count(id) AS number
434
                FROM $tbl_grade_evaluations
435
                WHERE name = '".Database::escape_string($name)."'";
436
437
        if (api_is_allowed_to_edit()) {
438
            $parent = Category::load($parent);
439
            $courseId = $parent[0]->getCourseId();
440
            if (isset($courseId) && !empty($courseId)) {
441
                $table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
442
                $sql .= ' AND user_id IN (
443
					 SELECT user_id FROM '.$table.'
444
					 WHERE
445
						c_id = '.$courseId.' AND
446
						status = '.COURSEMANAGER.'
447
					)';
448
            } else {
449
                $sql .= ' AND user_id = '.api_get_user_id();
450
            }
451
        } else {
452
            $sql .= ' AND user_id = '.api_get_user_id();
453
        }
454
455
        if (!isset($parent)) {
456
            $sql .= ' AND category_id is null';
457
        } else {
458
            $sql .= ' AND category_id = '.intval($parent);
459
        }
460
        $result = Database::query($sql);
461
        $number = Database::fetch_row($result);
462
463
        return 0 != $number[0];
464
    }
465
466
    /**
467
     * Are there any results for this evaluation yet ?
468
     * The 'max' property should not be changed then.
469
     *
470
     * @return bool
471
     */
472
    public function has_results()
473
    {
474
        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
475
        $sql = 'SELECT count(id) AS number
476
                FROM '.$table.'
477
                WHERE evaluation_id = '.intval($this->get_id());
478
        $result = Database::query($sql);
479
        $number = Database::fetch_row($result);
480
481
        return 0 != $number[0];
482
    }
483
484
    /**
485
     * Delete all results for this evaluation.
486
     */
487
    public function delete_results()
488
    {
489
        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
490
        $sql = 'DELETE FROM '.$table.'
491
                WHERE evaluation_id = '.$this->get_id();
492
        Database::query($sql);
493
    }
494
495
    /**
496
     * Delete this evaluation and all underlying results.
497
     */
498
    public function delete_with_results()
499
    {
500
        $this->delete_results();
501
        $this->delete();
502
    }
503
504
    /**
505
     * Check if the given score is possible for this evaluation.
506
     */
507
    public function is_valid_score($score)
508
    {
509
        return is_numeric($score) && $score >= 0 && $score <= $this->eval_max;
510
    }
511
512
    /**
513
     * Calculate the score of this evaluation.
514
     *
515
     * @param int    $stud_id (default: all students who have results for this eval - then the average is returned)
516
     * @param string $type    (best, average, ranking)
517
     *
518
     * @return array (score, max) if student is given
519
     *               array (sum of scores, number of scores) otherwise
520
     *               or null if no scores available
521
     */
522
    public function calc_score($stud_id = null, $type = null)
523
    {
524
        $allowStats = api_get_configuration_value('allow_gradebook_stats');
525
        if ($allowStats) {
526
            $evaluation = $this->entity;
527
            if (!empty($evaluation)) {
528
                $weight = $evaluation->getMax();
529
                switch ($type) {
530
                    case 'best':
531
                        $bestResult = $evaluation->getBestScore();
0 ignored issues
show
Bug introduced by
The method getBestScore() does not exist on Chamilo\CoreBundle\Entity\GradebookEvaluation. ( Ignorable by Annotation )

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

531
                        /** @scrutinizer ignore-call */ 
532
                        $bestResult = $evaluation->getBestScore();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
532
                        $result = [$bestResult, $weight];
533
534
                        return $result;
535
                        break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
536
                    case 'average':
537
                        $count = count($evaluation->getUserScoreList());
0 ignored issues
show
Bug introduced by
The method getUserScoreList() does not exist on Chamilo\CoreBundle\Entity\GradebookEvaluation. ( Ignorable by Annotation )

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

537
                        $count = count($evaluation->/** @scrutinizer ignore-call */ getUserScoreList());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
538
                        if (empty($count)) {
539
                            $result = [0, $weight];
540
541
                            return $result;
542
                        }
543
544
                        $sumResult = array_sum($evaluation->getUserScoreList());
545
                        $result = [$sumResult / $count, $weight];
546
547
                        return $result;
548
                        break;
549
                    case 'ranking':
550
                        $ranking = AbstractLink::getCurrentUserRanking($stud_id, $evaluation->getUserScoreList());
551
552
                        return $ranking;
553
                        break;
554
                    default:
555
                        $weight = $evaluation->getMax();
556
                        if (!empty($stud_id)) {
557
                            $scoreList = $evaluation->getUserScoreList();
558
                            $result = [0, $weight];
559
                            if (isset($scoreList[$stud_id])) {
560
                                $result = [$scoreList[$stud_id], $weight];
561
                            }
562
563
                            return $result;
564
                        } else {
565
                            $studentCount = count($evaluation->getUserScoreList());
566
                            $sumResult = array_sum($evaluation->getUserScoreList());
567
                            $result = [$sumResult, $studentCount];
568
                        }
569
570
                        return $result;
571
                        break;
572
                }
573
            }
574
        }
575
576
        $useSession = true;
577
        if (isset($stud_id) && empty($type)) {
578
            $key = 'result_score_student_list_'.api_get_course_int_id().'_'.api_get_session_id().'_'.$this->id.'_'.$stud_id;
579
            $data = Session::read('calc_score');
580
            $results = isset($data[$key]) ? $data[$key] : null;
581
582
            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...
583
                $results = null;
584
            }
585
            $results = null;
586
            if (empty($results)) {
587
                $results = Result::load(null, $stud_id, $this->id);
588
                Session::write('calc_score', [$key => $results]);
589
            }
590
591
            $score = 0;
592
            /** @var Result $res */
593
            foreach ($results as $res) {
594
                $score = $res->get_score();
595
            }
596
597
            return [$score, $this->get_max()];
598
        } else {
599
            $count = 0;
600
            $sum = 0;
601
            $bestResult = 0;
602
            $weight = 0;
603
            $sumResult = 0;
604
605
            $key = 'result_score_student_list_'.api_get_course_int_id().'_'.api_get_session_id().'_'.$this->id;
606
            $data = Session::read('calc_score');
607
            $allResults = isset($data[$key]) ? $data[$key] : null;
608
            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...
609
                $allResults = null;
610
            }
611
612
            if (empty($allResults)) {
613
                $allResults = Result::load(null, null, $this->id);
614
                Session::write($key, $allResults);
615
            }
616
617
            $students = [];
618
            /** @var Result $res */
619
            foreach ($allResults as $res) {
620
                $score = $res->get_score();
621
                if (!empty($score) || '0' == $score) {
622
                    $count++;
623
                    $sum += $score / $this->get_max();
624
                    $sumResult += $score;
625
                    if ($score > $bestResult) {
626
                        $bestResult = $score;
627
                    }
628
                    $weight = $this->get_max();
629
                }
630
                $students[$res->get_user_id()] = $score;
631
            }
632
633
            if (empty($count)) {
634
                return [null, null];
635
            }
636
637
            switch ($type) {
638
                case 'best':
639
                    return [$bestResult, $weight];
640
                    break;
641
                case 'average':
642
                    return [$sumResult / $count, $weight];
643
                    break;
644
                case 'ranking':
645
                    $students = [];
646
                    /** @var Result $res */
647
                    foreach ($allResults as $res) {
648
                        $score = $res->get_score();
649
                        $students[$res->get_user_id()] = $score;
650
                    }
651
652
                    return AbstractLink::getCurrentUserRanking($stud_id, $students);
653
                    break;
654
                default:
655
                    return [$sum, $count];
656
                    break;
657
            }
658
        }
659
    }
660
661
    /**
662
     * Generate an array of possible categories where this evaluation can be moved to.
663
     * Notice: its own parent will be included in the list: it's up to the frontend
664
     * to disable this element.
665
     *
666
     * @return array 2-dimensional array - every element contains 3 subelements (id, name, level)
667
     */
668
    public function get_target_categories()
669
    {
670
        // - course independent evaluation
671
        //   -> movable to root or other course independent categories
672
        // - evaluation inside a course
673
        //   -> movable to root, independent categories or categories inside the course
674
        $user = api_is_platform_admin() ? null : api_get_user_id();
675
        $targets = [];
676
        $level = 0;
677
        $root = [0, get_lang('Main folder'), $level];
678
        $targets[] = $root;
679
680
        if (isset($this->courseId) && !empty($this->courseId)) {
681
            $crscats = Category::load(null, null, $this->course_code, 0);
682
            foreach ($crscats as $cat) {
683
                $targets[] = [$cat->get_id(), $cat->get_name(), $level + 1];
684
                $targets = $this->addTargetSubcategories($targets, $level + 1, $cat->get_id());
685
            }
686
        }
687
688
        $indcats = Category::load(null, $user, 0, 0);
689
        foreach ($indcats as $cat) {
690
            $targets[] = [$cat->get_id(), $cat->get_name(), $level + 1];
691
            $targets = $this->addTargetSubcategories(
692
                $targets,
693
                $level + 1,
694
                $cat->get_id()
695
            );
696
        }
697
698
        return $targets;
699
    }
700
701
    /**
702
     * Move this evaluation to the given category.
703
     * If this evaluation moves from inside a course to outside,
704
     * its course code is also changed.
705
     */
706
    public function move_to_cat($cat)
707
    {
708
        $this->set_category_id($cat->get_id());
709
        if ($this->get_course_code() != $cat->get_course_code()) {
710
            $this->set_course_code($cat->get_course_code());
711
        }
712
        $this->save();
713
    }
714
715
    /**
716
     * Retrieve evaluations where a student has results for
717
     * and return them as an array of Evaluation objects.
718
     *
719
     * @param int $cat_id  parent category (use 'null' to retrieve them in all categories)
720
     * @param int $stud_id student id
721
     *
722
     * @return array
723
     */
724
    public static function get_evaluations_with_result_for_student($cat_id = null, $stud_id)
725
    {
726
        $tbl_grade_evaluations = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
727
        $tbl_grade_results = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
728
729
        $sql = 'SELECT * FROM '.$tbl_grade_evaluations.'
730
                WHERE id IN (
731
                    SELECT evaluation_id FROM '.$tbl_grade_results.'
732
                    WHERE user_id = '.intval($stud_id).' AND score IS NOT NULL
733
                )';
734
        if (!api_is_allowed_to_edit()) {
735
            $sql .= ' AND visible = 1';
736
        }
737
        if (isset($cat_id)) {
738
            $sql .= ' AND category_id = '.intval($cat_id);
739
        } else {
740
            $sql .= ' AND category_id >= 0';
741
        }
742
743
        $result = Database::query($sql);
744
        $alleval = self::create_evaluation_objects_from_sql_result($result);
745
746
        return $alleval;
747
    }
748
749
    /**
750
     * Get a list of students that do not have a result record for this evaluation.
751
     *
752
     * @param string $first_letter_user
753
     *
754
     * @return array
755
     */
756
    public function get_not_subscribed_students($first_letter_user = '')
757
    {
758
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
759
        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
760
761
        $sql = "SELECT user_id,lastname,firstname,username
762
                FROM $tbl_user
763
                WHERE
764
                    lastname LIKE '".Database::escape_string($first_letter_user)."%' AND
765
                    status = ".STUDENT." AND user_id NOT IN (
766
                        SELECT user_id FROM $table
767
                        WHERE evaluation_id = ".$this->get_id()."
768
                    )
769
                ORDER BY lastname";
770
771
        $result = Database::query($sql);
772
        $users = Database::store_result($result);
773
774
        return $users;
775
    }
776
777
    /**
778
     * Find evaluations by name.
779
     *
780
     * @param string $name_mask search string
781
     *
782
     * @return array evaluation objects matching the search criterium
783
     *
784
     * @todo can be written more efficiently using a new (but very complex) sql query
785
     */
786
    public function findEvaluations($name_mask, $selectcat)
787
    {
788
        $rootcat = Category::load($selectcat);
789
        $evals = $rootcat[0]->get_evaluations(
790
            (api_is_allowed_to_create_course() ? null : api_get_user_id()),
791
            true
792
        );
793
        $foundevals = [];
794
        foreach ($evals as $eval) {
795
            if (!(false === api_strpos(api_strtolower($eval->get_name()), api_strtolower($name_mask)))) {
796
                $foundevals[] = $eval;
797
            }
798
        }
799
800
        return $foundevals;
801
    }
802
803
    public function get_item_type()
804
    {
805
        return 'E';
806
    }
807
808
    public function get_icon_name()
809
    {
810
        return $this->has_results() ? 'evalnotempty' : 'evalempty';
811
    }
812
813
    /**
814
     * Locks an evaluation, only one who can unlock it is the platform administrator.
815
     *
816
     * @param int locked 1 or unlocked 0
817
     */
818
    public function lock($locked)
819
    {
820
        $table_evaluation = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
821
        $sql = "UPDATE $table_evaluation
822
                SET locked = '".intval($locked)."'
823
                WHERE id='".$this->get_id()."'";
824
        Database::query($sql);
825
    }
826
827
    public function check_lock_permissions()
828
    {
829
        if (api_is_platform_admin()) {
830
            return true;
831
        } else {
832
            if ($this->is_locked()) {
833
                api_not_allowed();
834
            }
835
        }
836
    }
837
838
    public function delete_linked_data()
839
    {
840
    }
841
842
    /**
843
     * @return mixed
844
     */
845
    public function getStudentList()
846
    {
847
        return $this->studentList;
848
    }
849
850
    /**
851
     * @param $list
852
     */
853
    public function setStudentList($list)
854
    {
855
        $this->studentList = $list;
856
    }
857
858
    /**
859
     * @param int $evaluationId
860
     */
861
    public static function generateStats($evaluationId)
862
    {
863
        $allowStats = api_get_configuration_value('allow_gradebook_stats');
864
        if ($allowStats) {
865
            $evaluation = self::load($evaluationId);
866
867
            $results = Result::load(null, null, $evaluationId);
868
            $sumResult = 0;
869
            $bestResult = 0;
870
            $average = 0;
871
            $scoreList = [];
872
873
            if (!empty($results)) {
874
                /** @var Result $result */
875
                foreach ($results as $result) {
876
                    $score = $result->get_score();
877
                    $scoreList[$result->get_user_id()] = $score;
878
                    $sumResult += $score;
879
                    if ($score > $bestResult) {
880
                        $bestResult = $score;
881
                    }
882
                }
883
                $average = $sumResult / count($results);
884
            }
885
886
            /** @var Evaluation $evaluation */
887
            $evaluation = $evaluation[0];
888
            $evaluation = $evaluation->entity;
889
            $evaluation
890
                ->setBestScore($bestResult)
0 ignored issues
show
Bug introduced by
The method setBestScore() does not exist on Chamilo\CoreBundle\Entity\GradebookEvaluation. ( Ignorable by Annotation )

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

890
                ->/** @scrutinizer ignore-call */ 
891
                  setBestScore($bestResult)

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
891
                ->setAverageScore($average)
892
                ->setUserScoreList($scoreList)
893
            ;
894
895
            $em = Database::getManager();
896
            $em->persist($evaluation);
897
            $em->flush();
898
        }
899
    }
900
901
    /**
902
     * @param int $courseId
903
     *
904
     * @return Evaluation
905
     */
906
    public function setCourseId($courseId)
907
    {
908
        $this->courseId = $courseId;
909
910
        return $this;
911
    }
912
913
    /**
914
     * @param array $result
915
     *
916
     * @return array
917
     */
918
    private static function create_evaluation_objects_from_sql_result($result)
919
    {
920
        $alleval = [];
921
        $allow = api_get_configuration_value('allow_gradebook_stats');
922
        if ($allow) {
923
            $em = Database::getManager();
924
            $repo = $em->getRepository('ChamiloCoreBundle:GradebookEvaluation');
925
        }
926
927
        if (Database::num_rows($result)) {
928
            while ($data = Database::fetch_array($result)) {
929
                $eval = new Evaluation();
930
                $eval->set_id($data['id']);
931
                $eval->set_name($data['name']);
932
                $eval->set_description($data['description']);
933
                $eval->set_user_id($data['user_id']);
934
                $eval->setCourseId($data['c_id']);
935
                $courseInfo = api_get_course_info_by_id($data['c_id']);
936
                $eval->set_course_code($courseInfo['code']);
937
                $eval->set_category_id($data['category_id']);
938
                $eval->set_date(api_get_local_time($data['created_at']));
939
                $eval->set_weight($data['weight']);
940
                $eval->set_max($data['max']);
941
                $eval->set_visible($data['visible']);
942
                $eval->set_type($data['type']);
943
                $eval->set_locked($data['locked']);
944
                $eval->setSessionId(api_get_session_id());
945
946
                if ($allow) {
947
                    $eval->entity = $repo->find($data['id']);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $repo does not seem to be defined for all execution paths leading up to this point.
Loading history...
948
                }
949
950
                $alleval[] = $eval;
951
            }
952
        }
953
954
        return $alleval;
955
    }
956
957
    /**
958
     * Internal function used by get_target_categories().
959
     *
960
     * @param array $targets
961
     * @param int   $level
962
     * @param int   $categoryId
963
     *
964
     * @return array
965
     */
966
    private function addTargetSubcategories($targets, $level, $categoryId)
967
    {
968
        $subcats = Category::load(null, null, null, $categoryId);
969
        foreach ($subcats as $cat) {
970
            $targets[] = [$cat->get_id(), $cat->get_name(), $level + 1];
971
            $targets = $this->addTargetSubcategories(
972
                $targets,
973
                $level + 1,
974
                $cat->get_id()
975
            );
976
        }
977
978
        return $targets;
979
    }
980
}
981