LearningCalendarPlugin   F
last analyzed

Complexity

Total Complexity 107

Size/Duplication

Total Lines 1138
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 485
c 0
b 0
f 0
dl 0
loc 1138
rs 2
wmc 107

39 Methods

Rating   Name   Duplication   Size   Complexity  
A getControlPointsToPlot() 0 9 2
A get_name() 0 3 1
A getEventTypeColorList() 0 9 2
A getGradebookEvaluationListToString() 0 10 2
A addControlPoint() 0 29 2
A getUserCalendar() 0 7 1
A getEvents() 0 19 2
A addUserToCalendar() 0 15 2
A copyCalendar() 0 29 4
B getCalendarsEventsByDate() 0 53 9
A getUsersPerCalendarCount() 0 9 1
A getUserEvents() 0 14 3
A getUserStatsPanel() 0 61 3
A getEventTypeList() 0 6 1
A getItemVisibility() 0 10 2
A uninstall() 0 27 4
B protectCalendar() 0 12 7
B getItemCountChecked() 0 70 9
A getAddUserToCalendarForm() 0 12 2
A __construct() 0 6 1
B getPersonalEvents() 0 44 6
A install() 0 73 1
A deleteAllCalendarFromUser() 0 9 1
A getCalendar() 0 7 1
A getUsersPerCalendar() 0 14 2
A getUserStats() 0 22 2
A getCalendarCount() 0 12 2
A create() 0 5 2
A getUserCalendarToString() 0 10 2
A getFirstCalendarDate() 0 19 2
A toogleDayType() 0 41 3
B getGradebookEvaluationList() 0 57 8
A getControlPoints() 0 10 1
A getCalendars() 0 52 4
A updateUserToCalendar() 0 13 2
A getForm() 0 6 1
A setJavaScript() 0 9 1
A deleteCalendar() 0 19 2
A toggleVisibility() 0 23 4

How to fix   Complexity   

Complex Class

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

1
<?php
2
3
/* For license terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Component\Utils\ActionIcon;
6
7
/**
8
 * Class LearningCalendarPlugin.
9
 */
10
class LearningCalendarPlugin extends Plugin
11
{
12
    const EVENT_TYPE_TAKEN = 1;
13
    const EVENT_TYPE_EXAM = 2;
14
    const EVENT_TYPE_FREE = 3;
15
16
    /**
17
     * Class constructor.
18
     */
19
    protected function __construct()
20
    {
21
        $version = '0.1';
22
        $author = 'Julio Montoya';
23
        parent::__construct($version, $author, ['enabled' => 'boolean']);
24
        $this->setHasPersonalEvents(true);
25
    }
26
27
    /**
28
     * Event definition.
29
     *
30
     * @return array
31
     */
32
    public function getEventTypeList()
33
    {
34
        return [
35
            self::EVENT_TYPE_TAKEN => ['color' => 'red', 'name' => self::get_lang('EventTypeTaken')],
36
            self::EVENT_TYPE_EXAM => ['color' => 'yellow', 'name' => self::get_lang('EventTypeExam')],
37
            self::EVENT_TYPE_FREE => ['color' => 'green', 'name' => self::get_lang('EventTypeFree')],
38
        ];
39
    }
40
41
    /**
42
     * @return array
43
     */
44
    public function getEventTypeColorList()
45
    {
46
        $list = $this->getEventTypeList();
47
        $newList = [];
48
        foreach ($list as $eventId => $event) {
49
            $newList[$eventId] = $event['color'];
50
        }
51
52
        return $newList;
53
    }
54
55
    /**
56
     * Get the class instance.
57
     *
58
     * @return $this
59
     */
60
    public static function create()
61
    {
62
        static $result = null;
63
64
        return $result ?: $result = new self();
65
    }
66
67
    /**
68
     * Get the plugin directory name.
69
     */
70
    public function get_name()
71
    {
72
        return 'LearningCalendar';
73
    }
74
75
    /**
76
     * Install the plugin. Setup the database.
77
     */
78
    public function install()
79
    {
80
        $sql = "
81
            CREATE TABLE IF NOT EXISTS learning_calendar(
82
              id int not null AUTO_INCREMENT primary key,
83
              title varchar(255) not null default '',
84
              description longtext default null,
85
              total_hours int not null default 0,
86
              minutes_per_day int not null default 0,
87
              disabled int default 0,
88
              author_id int(11) not null
89
            )
90
        ";
91
        Database::query($sql);
92
93
        $sql = "
94
            CREATE TABLE IF NOT EXISTS learning_calendar_events(
95
              id int not null AUTO_INCREMENT primary key,
96
              title varchar(255) default '',
97
              calendar_id int not null,
98
              start_date date not null,
99
              end_date date not null,
100
              type int not null
101
            )
102
        ";
103
        Database::query($sql);
104
105
        $sql = '
106
            CREATE TABLE IF NOT EXISTS learning_calendar_user(
107
              id int not null AUTO_INCREMENT primary key,
108
              user_id int(11) not null,
109
              calendar_id int not null
110
            )
111
        ';
112
        Database::query($sql);
113
114
        $sql = '
115
            CREATE TABLE IF NOT EXISTS learning_calendar_control_point(
116
              id int not null AUTO_INCREMENT primary key,
117
              user_id int(11) not null,
118
              control_date date not null,
119
              control_value int not null,
120
              created_at datetime not null,
121
              updated_at datetime not null
122
            )
123
        ';
124
        Database::query($sql);
125
126
        $extraField = new ExtraField('lp_item');
127
        $params = [
128
            'display_text' => $this->get_lang('Learning calendarOneDayMarker'),
129
            'variable' => 'calendar',
130
            'visible_to_self' => 1,
131
            'changeable' => 1,
132
            'visible_to_others' => 1,
133
            'value_type' => ExtraField::FIELD_TYPE_CHECKBOX,
134
        ];
135
136
        $extraField->save($params);
137
138
        $extraField = new ExtraField('course');
139
        $params = [
140
            'display_text' => $this->get_lang('Course duration (h)'),
141
            'variable' => 'course_hours_duration',
142
            'visible_to_self' => 1,
143
            'changeable' => 1,
144
            'visible_to_others' => 1,
145
            'value_type' => ExtraField::FIELD_TYPE_TEXT,
146
        ];
147
148
        $extraField->save($params);
149
150
        return true;
151
    }
152
153
    /**
154
     * Uninstall the plugin.
155
     */
156
    public function uninstall()
157
    {
158
        $tables = [
159
            'learning_calendar',
160
            'learning_calendar_events',
161
            'learning_calendar_user',
162
        ];
163
164
        foreach ($tables as $table) {
165
            $sql = "DROP TABLE IF EXISTS $table";
166
            Database::query($sql);
167
        }
168
169
        $extraField = new ExtraField('lp_item');
170
        $fieldInfo = $extraField->get_handler_field_info_by_field_variable('calendar');
171
172
        if ($fieldInfo) {
173
            $extraField->delete($fieldInfo['id']);
174
        }
175
176
        $extraField = new ExtraField('course');
177
        $fieldInfo = $extraField->get_handler_field_info_by_field_variable('course_hours_duration');
178
        if ($fieldInfo) {
179
            $extraField->delete($fieldInfo['id']);
180
        }
181
182
        return true;
183
    }
184
185
    /**
186
     * @param int    $from
187
     * @param int    $numberOfItems
188
     * @param int    $column
189
     * @param string $direction
190
     *
191
     * @return array
192
     */
193
    public function getCalendars(
194
        $from,
195
        $numberOfItems,
196
        $column,
197
        $direction = 'DESC'
198
    ) {
199
        $column = (int) $column;
200
        $from = (int) $from;
201
        $numberOfItems = (int) $numberOfItems;
202
        $direction = strtoupper($direction);
203
204
        if (!in_array($direction, ['ASC', 'DESC'])) {
205
            $direction = 'DESC';
206
        }
207
208
        if (api_is_platform_admin()) {
209
            $sql = 'SELECT * FROM learning_calendar';
210
        } else {
211
            $userId = api_get_user_id();
212
            $sql = "SELECT * FROM learning_calendar WHERE author_id = $userId";
213
        }
214
215
        $sql .= " LIMIT $from, $numberOfItems ";
216
217
        $result = Database::query($sql);
218
        $list = [];
219
        $link = api_get_path(WEB_PLUGIN_PATH).'LearningCalendar/start.php';
220
        while ($row = Database::fetch_array($result)) {
221
            $id = $row['id'];
222
            $row['title'] = Display::url(
223
                $row['title'],
224
                api_get_path(WEB_PLUGIN_PATH).'LearningCalendar/calendar.php?id='.$id
225
            );
226
            $actions = Display::url(
227
                Display::getMdiIcon(ActionIcon::EDIT, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Edit')),
228
                $link.'?action=edit&id='.$id
229
            );
230
231
            $actions .= Display::url(
232
                Display::getMdiIcon(ActionIcon::COPY_CONTENT, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Copy')),
233
                $link.'?action=copy&id='.$id
234
            );
235
236
            $actions .= Display::url(
237
                Display::getMdiIcon(ActionIcon::DELETE, 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Delete')),
238
                $link.'?action=delete&id='.$id
239
            );
240
            $row['actions'] = $actions;
241
            $list[] = $row;
242
        }
243
244
        return $list;
245
    }
246
247
    /**
248
     * @param array $calendarInfo
249
     * @param int   $start
250
     * @param int   $end
251
     * @param int   $type
252
     * @param bool  $getCount
253
     *
254
     * @return array
255
     */
256
    public function getCalendarsEventsByDate($calendarInfo, $start, $end, $type = 0, $getCount = false)
257
    {
258
        if (empty($calendarInfo)) {
259
            if ($getCount) {
260
                return 0;
261
            }
262
263
            return [];
264
        }
265
266
        $calendarId = (int) $calendarInfo['id'];
267
        $start = (int) $start;
268
        $end = (int) $end;
269
270
        $startCondition = '';
271
        $endCondition = '';
272
        $typeCondition = '';
273
274
        if (0 !== $start) {
275
            $start = api_get_utc_datetime($start);
276
            $startCondition = "AND start_date >= '".$start."'";
277
        }
278
        if (0 !== $end) {
279
            $end = api_get_utc_datetime($end);
280
            $endCondition = "AND (end_date <= '".$end."' OR end_date IS NULL)";
281
        }
282
283
        if (!empty($type)) {
284
            $type = (int) $type;
285
            $typeCondition = " AND type = $type ";
286
        }
287
288
        $select = '*';
289
        if ($getCount) {
290
            $select = 'count(id) count ';
291
        }
292
293
        $sql = "SELECT $select FROM learning_calendar_events
294
                WHERE calendar_id = $calendarId $startCondition $endCondition $typeCondition";
295
        $result = Database::query($sql);
296
297
        if ($getCount) {
298
            $row = Database::fetch_assoc($result);
299
300
            return $row['count'];
301
        }
302
303
        $list = [];
304
        while ($row = Database::fetch_assoc($result)) {
305
            $list[] = $row;
306
        }
307
308
        return ['calendar' => $calendarInfo, 'events' => $list];
309
    }
310
311
    /**
312
     * @param array $calendarInfo
313
     *
314
     * @return array
315
     */
316
    public function getFirstCalendarDate($calendarInfo)
317
    {
318
        if (empty($calendarInfo)) {
319
            return [];
320
        }
321
322
        $calendarId = (int) $calendarInfo['id'];
323
324
        /*if (!empty($type)) {
325
            $type = (int) $type;
326
            $typeCondition = " AND type = $type ";
327
        }*/
328
329
        $sql = "SELECT start_date FROM learning_calendar_events
330
                WHERE calendar_id = $calendarId ORDER BY start_date LIMIT 1";
331
        $result = Database::query($sql);
332
        $row = Database::fetch_assoc($result);
333
334
        return $row['start_date'];
335
    }
336
337
    /**
338
     * @return int
339
     */
340
    public function getCalendarCount()
341
    {
342
        if (api_is_platform_admin()) {
343
            $sql = 'select count(*) as count FROM learning_calendar';
344
        } else {
345
            $userId = api_get_user_id();
346
            $sql = "select count(*) as count FROM learning_calendar WHERE author_id = $userId";
347
        }
348
        $result = Database::query($sql);
349
        $result = Database::fetch_array($result);
350
351
        return (int) $result['count'];
352
    }
353
354
    /**
355
     * @param int $calendarId
356
     *
357
     * @return array
358
     */
359
    public function getUsersPerCalendar($calendarId)
360
    {
361
        $calendarId = (int) $calendarId;
362
        $sql = "SELECT * FROM learning_calendar_user
363
                WHERE calendar_id = $calendarId";
364
        $result = Database::query($sql);
365
        $list = [];
366
        while ($row = Database::fetch_assoc($result)) {
367
            $userInfo = api_get_user_info($row['user_id']);
368
            $userInfo['exam'] = 'exam';
369
            $list[] = $userInfo;
370
        }
371
372
        return $list;
373
    }
374
375
    /**
376
     * @param int $calendarId
377
     *
378
     * @return int
379
     */
380
    public function getUsersPerCalendarCount($calendarId)
381
    {
382
        $calendarId = (int) $calendarId;
383
        $sql = "SELECT count(id) as count FROM learning_calendar_user
384
                WHERE calendar_id = $calendarId";
385
        $result = Database::query($sql);
386
        $row = Database::fetch_assoc($result);
387
388
        return (int) $row['count'];
389
    }
390
391
    /**
392
     * @param int $id
393
     */
394
    public function toggleVisibility($id)
395
    {
396
        $extraField = new ExtraField('lp_item');
397
        $fieldInfo = $extraField->get_handler_field_info_by_field_variable('calendar');
398
        if ($fieldInfo) {
399
            $itemInfo = $this->getItemVisibility($id);
400
            if (empty($itemInfo)) {
401
                $extraField = new ExtraFieldValue('lp_item');
402
                $value = 1;
403
                $params = [
404
                    'field_id' => $fieldInfo['id'],
405
                    'value' => $value,
406
                    'item_id' => $id,
407
                ];
408
                $extraField->save($params);
409
            } else {
410
                $newValue = 1 === (int) $itemInfo['value'] ? 0 : 1;
411
                $extraField = new ExtraFieldValue('lp_item');
412
                $params = [
413
                    'id' => $itemInfo['id'],
414
                    'value' => $newValue,
415
                ];
416
                $extraField->update($params);
417
            }
418
        }
419
    }
420
421
    /**
422
     * @param int $id
423
     *
424
     * @return array
425
     */
426
    public function getItemVisibility($id)
427
    {
428
        $extraField = new ExtraFieldValue('lp_item');
429
        $values = $extraField->get_values_by_handler_and_field_variable($id, 'calendar');
430
431
        if (empty($values)) {
432
            return [];
433
        }
434
435
        return $values;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $values also could return the type boolean which is incompatible with the documented return type array.
Loading history...
436
    }
437
438
    /**
439
     * @param int $calendarId
440
     *
441
     * @return array|mixed
442
     */
443
    public function getCalendar($calendarId)
444
    {
445
        $calendarId = (int) $calendarId;
446
        $sql = "SELECT * FROM learning_calendar WHERE id = $calendarId";
447
        $result = Database::query($sql);
448
449
        return Database::fetch_assoc($result);
450
    }
451
452
    /**
453
     * @param int $userId
454
     *
455
     * @return array|mixed
456
     */
457
    public function getUserCalendar($userId)
458
    {
459
        $userId = (int) $userId;
460
        $sql = "SELECT * FROM learning_calendar_user WHERE user_id = $userId";
461
        $result = Database::query($sql);
462
463
        return Database::fetch_assoc($result);
464
    }
465
466
    /**
467
     * @param int  $userId
468
     * @param int  $start
469
     * @param int  $end
470
     * @param int  $type
471
     * @param bool $getCount
472
     *
473
     * @return array|int
474
     */
475
    public function getUserEvents($userId, $start, $end, $type = 0, $getCount = false)
476
    {
477
        $calendarRelUser = $this->getUserCalendar($userId);
478
        if (!empty($calendarRelUser)) {
479
            $calendar = $this->getCalendar($calendarRelUser['calendar_id']);
480
481
            return $this->getCalendarsEventsByDate($calendar, $start, $end, $type, $getCount);
482
        }
483
484
        if ($getCount) {
485
            return 0;
486
        }
487
488
        return [];
489
    }
490
491
    /**
492
     * @param int $userId
493
     *
494
     * @return mixed|string
495
     */
496
    public function getUserCalendarToString($userId)
497
    {
498
        $calendar = $this->getUserCalendar($userId);
499
        if ($calendar) {
500
            $calendarInfo = $this->getCalendar($calendar['calendar_id']);
501
502
            return $calendarInfo['title'];
503
        }
504
505
        return '';
506
    }
507
508
    /**
509
     * @param int $calendarId
510
     * @param int $userId
511
     *
512
     * @return bool
513
     */
514
    public function addUserToCalendar($calendarId, $userId)
515
    {
516
        $calendar = $this->getUserCalendar($userId);
517
        if (empty($calendar)) {
518
            $params = [
519
                'calendar_id' => $calendarId,
520
                'user_id' => $userId,
521
            ];
522
523
            Database::insert('learning_calendar_user', $params);
524
525
            return true;
526
        }
527
528
        return false;
529
    }
530
531
    /**
532
     * @param int $calendarId
533
     * @param int $userId
534
     *
535
     * @return bool
536
     */
537
    public function updateUserToCalendar($calendarId, $userId)
538
    {
539
        $calendar = $this->getUserCalendar($userId);
540
        if (!empty($calendar)) {
541
            $params = [
542
                'calendar_id' => $calendarId,
543
                'user_id' => $userId,
544
            ];
545
546
            Database::update('learning_calendar_user', $params, ['id = ?' => $calendar['id']]);
547
        }
548
549
        return true;
550
    }
551
552
    /**
553
     * @param int $calendarId
554
     * @param int $userId
555
     *
556
     * @return bool
557
     */
558
    public function deleteAllCalendarFromUser($calendarId, $userId)
559
    {
560
        $calendarId = (int) $calendarId;
561
        $userId = (int) $userId;
562
        $sql = "DELETE FROM learning_calendar_user
563
                WHERE user_id = $userId AND calendar_id = $calendarId";
564
        Database::query($sql);
565
566
        return true;
567
    }
568
569
    /*public static function getUserCalendar($calendarId, $userId)
570
    {
571
        $params = [
572
            'calendar_id' => $calendarId,
573
            'user_id' => $calendarId,
574
        ];
575
576
        Database::insert('learning_calendar_user', $params);
577
578
        return true;
579
    }*/
580
581
    public function getForm(FormValidator &$form)
582
    {
583
        $form->addText('title', get_lang('Title'));
584
        $form->addText('total_hours', get_lang('Total hours'));
585
        $form->addText('minutes_per_day', get_lang('Minutes per day'));
586
        $form->addHtmlEditor('description', get_lang('Description'), false);
587
    }
588
589
    /**
590
     * @param Agenda $agenda
591
     * @param int    $start
592
     * @param int    $end
593
     *
594
     * @return array
595
     */
596
    public function getPersonalEvents($agenda, $start, $end)
597
    {
598
        $userId = api_get_user_id();
599
        $events = $this->getUserEvents($userId, $start, $end);
600
601
        if (empty($events)) {
602
            return [];
603
        }
604
605
        $calendarInfo = $events['calendar'];
606
        $events = $events['events'];
607
608
        $list = [];
609
        $typeList = $this->getEventTypeColorList();
610
        foreach ($events as $row) {
611
            $event = [];
612
            $event['id'] = 'personal_'.$row['id'];
613
            $event['title'] = $calendarInfo['title'];
614
            $event['className'] = 'personal';
615
            $color = isset($typeList[$row['type']]) ? $typeList[$row['type']] : $typeList[self::EVENT_TYPE_FREE];
616
            $event['borderColor'] = $color;
617
            $event['backgroundColor'] = $color;
618
            $event['editable'] = false;
619
            $event['sent_to'] = get_lang('Me');
620
            $event['type'] = 'personal';
621
622
            if (!empty($row['start_date'])) {
623
                $event['start'] = $agenda->formatEventDate($row['start_date']);
624
                $event['start_date_localtime'] = api_get_local_time($row['start_date']);
625
            }
626
627
            if (!empty($row['end_date'])) {
628
                $event['end'] = $agenda->formatEventDate($row['end_date']);
629
                $event['end_date_localtime'] = api_get_local_time($row['end_date']);
630
            }
631
632
            $event['description'] = 'plugin';
633
            $event['allDay'] = 1;
634
            $event['parent_event_id'] = 0;
635
            $event['has_children'] = 0;
636
            $list[] = $event;
637
        }
638
639
        return $list;
640
    }
641
642
    /**
643
     * @param int   $userId
644
     * @param array $coursesAndSessions
645
     *
646
     * @return string
647
     */
648
    public function getGradebookEvaluationListToString($userId, $coursesAndSessions)
649
    {
650
        $list = $this->getGradebookEvaluationList($userId, $coursesAndSessions);
651
652
        $html = '';
653
        if (!empty($list)) {
654
            $html = implode('&nbsp;', array_column($list, 'title'));
655
        }
656
657
        return $html;
658
    }
659
660
    /**
661
     * @param int   $userId
662
     * @param array $coursesAndSessions
663
     *
664
     * @return array
665
     */
666
    public function getGradebookEvaluationList($userId, $coursesAndSessions)
667
    {
668
        $userId = (int) $userId;
669
670
        if (empty($coursesAndSessions)) {
671
            return 0;
672
        }
673
674
        $courseSessionConditionToString = '';
675
        foreach ($coursesAndSessions as $sessionId => $courseList) {
676
            if (isset($courseList['course_list'])) {
677
                $courseList = array_keys($courseList['course_list']);
678
            }
679
            if (empty($courseList)) {
680
                continue;
681
            }
682
            //$courseListToString = implode("','", $courseList);
683
            /*if (empty($sessionId)) {
684
                $courseAndSessionCondition[] =
685
                    " c.id IN ('$courseListToString') ";
686
            } else {
687
                $courseAndSessionCondition[] = "
688
                    (
689
                        c.id IN ('$courseListToString')
690
                    )";
691
            }*/
692
            $courseSessionConditionToString = " AND c.id IN ('".implode("','", $courseList)."') ";
693
        }
694
695
        if (empty($courseSessionConditionToString)) {
696
            return 0;
697
        }
698
699
        $tableEvaluation = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
700
        $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
701
        $tableResult = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
702
        $sql = "SELECT DISTINCT e.title, e.id
703
                FROM $tableEvaluation e
704
                INNER JOIN $tableCourse c
705
                ON (course_code = c.code)
706
                INNER JOIN $tableResult r
707
                ON (r.evaluation_id = e.id)
708
                WHERE
709
                  e.type = 'evaluation' AND
710
                  r.score >= 2 AND
711
                  r.user_id = $userId
712
                  $courseSessionConditionToString
713
        ";
714
        $result = Database::query($sql);
715
        $list = [];
716
        if (Database::num_rows($result)) {
717
            while ($row = Database::fetch_assoc($result)) {
718
                $list[$row['id']] = $row;
719
            }
720
        }
721
722
        return $list;
723
    }
724
725
    /**
726
     * @param int   $userId
727
     * @param array $coursesAndSessions
728
     *
729
     * @return int
730
     */
731
    public function getItemCountChecked($userId, $coursesAndSessions)
732
    {
733
        $userId = (int) $userId;
734
735
        if (empty($coursesAndSessions)) {
736
            return 0;
737
        }
738
739
        $tableItem = Database::get_course_table(TABLE_LP_ITEM);
740
        $tableLp = Database::get_course_table(TABLE_LP_MAIN);
741
        $tableLpItemView = Database::get_course_table(TABLE_LP_ITEM_VIEW);
742
        $tableLpView = Database::get_course_table(TABLE_LP_VIEW);
743
        $extraField = new ExtraField('lp_item');
744
        $fieldInfo = $extraField->get_handler_field_info_by_field_variable('calendar');
745
746
        if (empty($fieldInfo)) {
747
            return 0;
748
        }
749
750
        $courseAndSessionCondition = [];
751
        foreach ($coursesAndSessions as $sessionId => $courseList) {
752
            if (isset($courseList['course_list'])) {
753
                $courseList = array_keys($courseList['course_list']);
754
            }
755
            if (empty($courseList)) {
756
                continue;
757
            }
758
            $courseListToString = implode("','", $courseList);
759
            if (empty($sessionId)) {
760
                $courseAndSessionCondition[] =
761
                    " ((l.session_id = 0 OR l.session_id is NULL) AND i.c_id IN ('$courseListToString'))";
762
            } else {
763
                $courseAndSessionCondition[] = "
764
                    (
765
                        ((l.session_id = 0 OR l.session_id is NULL) OR l.session_id = $sessionId) AND
766
                        i.c_id IN ('$courseListToString')
767
                    )";
768
            }
769
        }
770
771
        if (empty($courseAndSessionCondition)) {
772
            return 0;
773
        }
774
775
        $courseSessionConditionToString = 'AND ('.implode(' OR ', $courseAndSessionCondition).') ';
776
        $sql = "SELECT count(*) as count
777
                FROM $tableItem i INNER JOIN $tableLp l
778
                ON (i.c_id = l.c_id AND i.lp_id = l.iid)
779
                INNER JOIN $tableLpItemView iv
780
                ON (iv.c_id = l.c_id AND i.iid = iv.lp_item_id)
781
                INNER JOIN $tableLpView v
782
                ON (v.c_id = l.c_id AND v.lp_id = l.iid AND iv.lp_view_id = v.iid)
783
                INNER JOIN extra_field_values e
784
                ON (e.item_id = i.iid AND value = 1 AND field_id = ".$fieldInfo['id'].")
785
                WHERE
786
                    v.user_id = $userId AND
787
                    status = 'completed'
788
                    $courseSessionConditionToString
789
                GROUP BY iv.view_count
790
               ";
791
792
        $result = Database::query($sql);
793
794
        if (Database::num_rows($result)) {
795
            $row = Database::fetch_assoc($result);
796
797
            return $row['count'];
798
        }
799
800
        return 0;
801
    }
802
803
    public function setJavaScript()
804
    {
805
        global $htmlHeadXtra;
806
807
        $htmlHeadXtra[] = api_get_js('jqplot/jquery.jqplot.js');
808
        $htmlHeadXtra[] = api_get_js('jqplot/plugins/jqplot.dateAxisRenderer.js');
809
        $htmlHeadXtra[] = api_get_js('jqplot/plugins/jqplot.canvasOverlay.js');
810
        $htmlHeadXtra[] = api_get_js('jqplot/plugins/jqplot.pointLabels.js');
811
        $htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/jqplot/jquery.jqplot.css');
812
    }
813
814
    /**
815
     * @param int   $userId
816
     * @param array $courseAndSessionList
817
     *
818
     * @return string
819
     */
820
    public function getUserStatsPanel($userId, $courseAndSessionList)
821
    {
822
        // @todo use translation
823
        // get events from this year to today
824
        $stats = $this->getUserStats($userId, $courseAndSessionList);
825
        $html = $this->get_lang('Number of days accumulated in calendar').$stats['user_event_count'];
0 ignored issues
show
Bug introduced by
Are you sure $stats['user_event_count'] of type array|integer can be used in concatenation? ( Ignorable by Annotation )

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

825
        $html = $this->get_lang('Number of days accumulated in calendar')./** @scrutinizer ignore-type */ $stats['user_event_count'];
Loading history...
826
        if (!empty($courseAndSessionList)) {
827
            $html .= '<br />';
828
            $html .= $this->get_lang('NumberDaysAccumulatedInLp').$stats['completed'];
829
            $html .= '<br />';
830
            $html .= $this->get_lang('NumberDaysInRetard').' '.($stats['completed'] - $stats['user_event_count']);
831
        }
832
833
        $controlList = $this->getControlPointsToPlot($userId);
834
835
        if (!empty($controlList)) {
836
            $listToString = json_encode($controlList);
837
            $date = $this->get_lang('Date');
838
            $controlPoint = $this->get_lang('NumberOfDays');
839
840
            $html .= '<div id="control_point_chart"></div>';
841
            $html .= '<script>
842
                $(document).ready(function(){
843
                    var cosPoints = '.$listToString.';
844
                    var plot1 = $.jqplot(\'control_point_chart\', [cosPoints], {
845
                        //animate: !$.jqplot.use_excanvas,
846
                        series:[{
847
                            showMarker:true,
848
                            pointLabels: { show:true },
849
                        }],
850
                        axes:{
851
                            xaxis:{
852
                                label: "'.$date.'",
853
                                renderer: $.jqplot.DateAxisRenderer,
854
                                tickOptions:{formatString: "%Y-%m-%d"},
855
                                tickInterval: \'30 day\',
856
                            },
857
                            yaxis:{
858
                                label: "'.$controlPoint.'",
859
                                max: 20,
860
                                min: -20,
861
                            }
862
                        },
863
                        canvasOverlay: {
864
                            show: true,
865
                            objects: [{
866
                                horizontalLine: {
867
                                    name: \'0 mark\',
868
                                    y: 0,
869
                                    lineWidth: 2,
870
                                    color: \'rgb(f, f, f)\',
871
                                    shadow: false
872
                                }
873
                            }]
874
                        },
875
                  });
876
                });
877
            </script>';
878
        }
879
880
        return Display::panel($html, $this->get_lang('Learning calendar'));
881
    }
882
883
    /**
884
     * @param int   $userId
885
     * @param array $courseAndSessionList
886
     *
887
     * @return array
888
     */
889
    public function getUserStats($userId, $courseAndSessionList)
890
    {
891
        // Get events from this year to today
892
        $takenCount = $this->getUserEvents(
893
            $userId,
894
            strtotime(date('Y-01-01')),
895
            time(),
896
            self::EVENT_TYPE_TAKEN,
897
            true
898
        );
899
900
        $completed = 0;
901
        $diff = 0;
902
        if (!empty($courseAndSessionList)) {
903
            $completed = $this->getItemCountChecked($userId, $courseAndSessionList);
904
            $diff = $takenCount - $completed;
905
        }
906
907
        return [
908
            'user_event_count' => $takenCount,
909
            'completed' => $completed,
910
            'diff' => $diff,
911
        ];
912
    }
913
914
    /**
915
     * @param int $calendarId
916
     *
917
     * @return bool
918
     */
919
    public function copyCalendar($calendarId)
920
    {
921
        $item = $this->getCalendar($calendarId);
922
        $this->protectCalendar($item);
923
        $item['author_id'] = api_get_user_id();
924
925
        if (empty($item)) {
926
            return false;
927
        }
928
929
        $calendarId = (int) $calendarId;
930
931
        unset($item['id']);
932
        //$item['title'] = $item['title'];
933
934
        $newCalendarId = Database::insert('learning_calendar', $item);
935
        if (!empty($newCalendarId)) {
936
            $sql = "SELECT * FROM learning_calendar_events WHERE calendar_id = $calendarId";
937
            $result = Database::query($sql);
938
            while ($row = Database::fetch_assoc($result)) {
939
                unset($row['id']);
940
                $row['calendar_id'] = $newCalendarId;
941
                Database::insert('learning_calendar_events', $row);
942
            }
943
944
            return true;
945
        }
946
947
        return false;
948
    }
949
950
    /**
951
     * @param int $calendarId
952
     *
953
     * @return bool
954
     */
955
    public function deleteCalendar($calendarId)
956
    {
957
        $item = $this->getCalendar($calendarId);
958
        $this->protectCalendar($item);
959
960
        if (empty($item)) {
961
            return false;
962
        }
963
964
        $calendarId = (int) $calendarId;
965
966
        $sql = "DELETE FROM learning_calendar WHERE id = $calendarId";
967
        Database::query($sql);
968
969
        // Delete events
970
        $sql = "DELETE FROM learning_calendar_events WHERE calendar_id = $calendarId";
971
        Database::query($sql);
972
973
        return true;
974
    }
975
976
    /**
977
     * @param int    $calendarId
978
     * @param string $startDate
979
     */
980
    public function toogleDayType($calendarId, $startDate)
981
    {
982
        $startDate = Database::escape_string($startDate);
983
        $calendarId = (int) $calendarId;
984
985
        $eventTypeList = $this->getEventTypeColorList();
986
        // Remove the free type to loop correctly when toogle days.
987
        unset($eventTypeList[self::EVENT_TYPE_FREE]);
988
989
        $sql = "SELECT * FROM learning_calendar_events
990
                WHERE start_date = '$startDate' AND calendar_id = $calendarId ";
991
        $result = Database::query($sql);
992
993
        if (Database::num_rows($result)) {
994
            $row = Database::fetch_assoc($result);
995
            $currentType = $row['type'];
996
            $currentType++;
997
            if ($currentType > count($eventTypeList)) {
998
                Database::delete(
999
                    'learning_calendar_events',
1000
                    [' calendar_id = ? AND start_date = ?' => [$calendarId, $startDate]]
1001
                );
1002
            } else {
1003
                $params = [
1004
                    'type' => $currentType,
1005
                ];
1006
                Database::update(
1007
                    'learning_calendar_events',
1008
                    $params,
1009
                    [' calendar_id = ? AND start_date = ?' => [$calendarId, $startDate]]
1010
                );
1011
            }
1012
        } else {
1013
            $params = [
1014
                'title' => '',
1015
                'calendar_id' => $calendarId,
1016
                'start_date' => $startDate,
1017
                'end_date' => $startDate,
1018
                'type' => self::EVENT_TYPE_TAKEN,
1019
            ];
1020
            Database::insert('learning_calendar_events', $params);
1021
        }
1022
    }
1023
1024
    /**
1025
     * @param int $calendarId
1026
     *
1027
     * @return array
1028
     */
1029
    public function getEvents($calendarId)
1030
    {
1031
        $calendarId = (int) $calendarId;
1032
        $eventTypeList = $this->getEventTypeColorList();
1033
1034
        $sql = "SELECT * FROM learning_calendar_events
1035
                WHERE calendar_id = $calendarId ";
1036
        $result = Database::query($sql);
1037
1038
        $list = [];
1039
        while ($row = Database::fetch_assoc($result)) {
1040
            $list[] = [
1041
                'start_date' => $row['start_date'],
1042
                'end_date' => $row['start_date'],
1043
                'color' => $eventTypeList[$row['type']],
1044
            ];
1045
        }
1046
1047
        return $list;
1048
    }
1049
1050
    public function protectCalendar(array $calendarInfo)
1051
    {
1052
        $allow = api_is_platform_admin() || api_is_teacher();
1053
1054
        if (!$allow) {
1055
            api_not_allowed(true);
1056
        }
1057
1058
        if (!empty($calendarInfo)) {
1059
            if (!api_is_platform_admin() && api_is_teacher()) {
1060
                if ($calendarInfo['author_id'] != api_get_user_id()) {
1061
                    api_not_allowed(true);
1062
                }
1063
            }
1064
        }
1065
    }
1066
1067
    /**
1068
     * @param int $userId
1069
     *
1070
     * @return array
1071
     */
1072
    public function getControlPoints($userId)
1073
    {
1074
        $userId = (int) $userId;
1075
        $sql = "SELECT control_date, control_value
1076
                FROM learning_calendar_control_point
1077
                WHERE user_id = $userId
1078
                ORDER BY control_date";
1079
        $result = Database::query($sql);
1080
1081
        return Database::store_result($result, 'ASSOC');
1082
    }
1083
1084
    /**
1085
     * @param int $userId
1086
     *
1087
     * @return array
1088
     */
1089
    public function getControlPointsToPlot($userId)
1090
    {
1091
        $list = $this->getControlPoints($userId);
1092
        $points = [];
1093
        foreach ($list as $item) {
1094
            $points[] = [$item['control_date'], $item['control_value']];
1095
        }
1096
1097
        return $points;
1098
    }
1099
1100
    /**
1101
     * @param int $userId
1102
     * @param int $value
1103
     */
1104
    public function addControlPoint($userId, $value)
1105
    {
1106
        $userId = (int) $userId;
1107
        $value = (int) $value;
1108
        $local = api_get_local_time();
1109
        $date = substr($local, 0, 10);
1110
1111
        $sql = "SELECT id
1112
                FROM learning_calendar_control_point
1113
                WHERE user_id = $userId AND control_date = '$date'";
1114
        $result = Database::query($sql);
1115
1116
        if (Database::num_rows($result)) {
1117
            $params = [
1118
                'control_value' => $value,
1119
                'updated_at' => api_get_utc_datetime(),
1120
            ];
1121
            $data = Database::fetch_array($result);
1122
            $id = $data['id'];
1123
            Database::update('learning_calendar_control_point', $params, ['id = ?' => $id]);
1124
        } else {
1125
            $params = [
1126
                'user_id' => $userId,
1127
                'control_date' => $date,
1128
                'control_value' => $value,
1129
                'created_at' => api_get_utc_datetime(),
1130
                'updated_at' => api_get_utc_datetime(),
1131
            ];
1132
            Database::insert('learning_calendar_control_point', $params);
1133
        }
1134
    }
1135
1136
    public function getAddUserToCalendarForm(FormValidator &$form)
1137
    {
1138
        $calendars = $this->getCalendars(0, 1000, '');
1139
1140
        if (empty($calendars)) {
1141
            echo Display::return_message(get_lang('No data available'), 'warning');
1142
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1143
        }
1144
        $calendars = array_column($calendars, 'title', 'id');
1145
        $calendars = array_map('strip_tags', $calendars);
1146
1147
        $form->addSelect('calendar_id', get_lang('Calendar'), $calendars, ['disable_js' => true]);
1148
    }
1149
}
1150