Issues (2037)

main/inc/lib/thematic.lib.php (9 issues)

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Provides functions for thematic option inside attendance tool.
6
 * It's also used like model to thematic_controller (MVC pattern)
7
 * Thematic class can be used to instanciate objects or as a library for thematic control.
8
 *
9
 * @author Christian Fasanando <[email protected]>
10
 * @author Julio Montoya <[email protected]> SQL fixes
11
 */
12
class Thematic
13
{
14
    private $session_id;
15
    private $thematic_id;
16
    private $thematic_title;
17
    private $thematic_content;
18
    private $thematic_plan_id;
19
    private $thematic_plan_title;
20
    private $thematic_plan_description;
21
    private $thematic_plan_description_type;
22
    private $thematic_advance_id;
23
    private $attendance_id;
24
    private $thematic_advance_content;
25
    private $start_date;
26
    private $duration;
27
    private $course_int_id;
28
29
    /**
30
     * Constructor.
31
     */
32
    public function __construct()
33
    {
34
        $this->course_int_id = api_get_course_int_id();
35
    }
36
37
    /**
38
     * Get the total number of thematic inside current course and current session.
39
     *
40
     * @see SortableTable#get_total_number_of_items()
41
     */
42
    public function get_number_of_thematics()
43
    {
44
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
45
        $condition_session = '';
46
        if (!api_get_session_id()) {
47
            $condition_session = api_get_session_condition(0);
48
        }
49
        $course_id = api_get_course_int_id();
50
        $sql = "SELECT COUNT(id) AS total_number_of_items
51
                FROM $tbl_thematic
52
                WHERE c_id = $course_id AND active = 1 $condition_session ";
53
        $res = Database::query($sql);
54
        $obj = Database::fetch_object($res);
55
56
        return $obj->total_number_of_items;
57
    }
58
59
    /**
60
     * Get the thematics to display on the current page (fill the sortable-table).
61
     *
62
     * @param   int     offset of first user to recover
63
     * @param   int     Number of users to get
64
     * @param   int     Column to sort on
65
     * @param   string  Order (ASC,DESC)
66
     *
67
     * @return array
68
     *
69
     * @see SortableTable#get_table_data($from)
70
     */
71
    public function get_thematic_data($from, $number_of_items, $column, $direction)
72
    {
73
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
74
        $condition_session = '';
75
        if (!api_get_session_id()) {
76
            $condition_session = api_get_session_condition(0);
77
        }
78
        $column = intval($column);
79
        $from = intval($from);
80
        $number_of_items = intval($number_of_items);
81
82
        if (!in_array($direction, ['ASC', 'DESC'])) {
83
            $direction = 'ASC';
84
        }
85
86
        $course_id = api_get_course_int_id();
87
88
        $sql = "SELECT id AS col0, title AS col1, display_order AS col2, session_id
89
                FROM $tbl_thematic
90
                WHERE c_id = $course_id AND active = 1 $condition_session
91
                ORDER BY col2
92
                LIMIT $from,$number_of_items ";
93
        $res = Database::query($sql);
94
95
        $thematics = [];
96
        $user_info = api_get_user_info(api_get_user_id());
97
        while ($thematic = Database::fetch_row($res)) {
98
            $session_star = '';
99
            if (api_get_session_id() == $thematic[3]) {
100
                $session_star = api_get_session_image(api_get_session_id(), $user_info['status']);
101
            }
102
            $thematic[1] = '<a href="index.php?'.api_get_cidreq().'&action=thematic_details&thematic_id='.$thematic[0].'">'.
103
                Security::remove_XSS($thematic[1], STUDENT).$session_star.'</a>';
104
            if (api_is_allowed_to_edit(null, true)) {
105
                $actions = '';
106
107
                if (api_get_session_id()) {
108
                    if (api_get_session_id() == $thematic[3]) {
109
                        $actions .= '<a href="index.php?'.api_get_cidreq().'&action=thematic_plan_list&thematic_id='.$thematic[0].'">'.
110
                            Display::return_icon('lesson_plan.png', get_lang('ThematicPlan'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
111
                        $actions .= '<a href="index.php?'.api_get_cidreq().'&action=thematic_advance_list&thematic_id='.$thematic[0].'">'.
112
                            Display::return_icon('lesson_plan_calendar.png', get_lang('ThematicAdvance'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
113
114
                        $actions .= '<a href="index.php?'.api_get_cidreq().'&action=thematic_edit&thematic_id='.$thematic[0].'">'.
115
                            Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL).'</a>';
116
                        $actions .= '<a onclick="javascript:if(!confirm(\''.get_lang('AreYouSureToDelete').'\')) return false;" href="index.php?'.api_get_cidreq().'&action=thematic_delete&thematic_id='.$thematic[0].'">'.
117
                            Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL).'</a>';
118
                    } else {
119
                        $actions .= Display::return_icon(
120
                            'lesson_plan_na.png',
121
                            get_lang('ThematicPlan'),
122
                            '',
123
                            ICON_SIZE_SMALL
124
                        ).'&nbsp;';
125
                        $actions .= Display::return_icon(
126
                            'lesson_plan_calendar_na.png',
127
                            get_lang('ThematicAdvance'),
128
                            '',
129
                            ICON_SIZE_SMALL
130
                        ).'&nbsp;';
131
                        $actions .= Display::return_icon('edit_na.png', get_lang('Edit'), '', ICON_SIZE_SMALL);
132
                        $actions .= Display::return_icon(
133
                            'delete_na.png',
134
                            get_lang('Delete'),
135
                            '',
136
                            ICON_SIZE_SMALL
137
                        ).'&nbsp;';
138
                        $actions .= Display::url(
139
                            Display::return_icon('cd.gif', get_lang('Copy')),
140
                            'index.php?'.api_get_cidreq().'&action=thematic_copy&thematic_id='.$thematic[0]
141
                        );
142
                    }
143
                } else {
144
                    $actions .= '<a href="index.php?'.api_get_cidreq().'&action=thematic_plan_list&thematic_id='.$thematic[0].'">'.
145
                        Display::return_icon('lesson_plan.png', get_lang('ThematicPlan'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
146
                    $actions .= '<a href="index.php?'.api_get_cidreq().'&action=thematic_advance_list&thematic_id='.$thematic[0].'">'.
147
                        Display::return_icon('lesson_plan_calendar.png', get_lang('ThematicAdvance'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
148
149
                    if ($thematic[2] > 1) {
150
                        $actions .= '<a href="'.api_get_self().'?action=moveup&'.api_get_cidreq().'&thematic_id='.$thematic[0].'">'.
151
                            Display::return_icon('up.png', get_lang('Up'), '', ICON_SIZE_SMALL).'</a>';
152
                    } else {
153
                        $actions .= Display::return_icon('up_na.png', '&nbsp;', '', ICON_SIZE_SMALL);
154
                    }
155
                    if ($thematic[2] < self::get_max_thematic_item()) {
0 ignored issues
show
Bug Best Practice introduced by
The method Thematic::get_max_thematic_item() is not static, but was called statically. ( Ignorable by Annotation )

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

155
                    if ($thematic[2] < self::/** @scrutinizer ignore-call */ get_max_thematic_item()) {
Loading history...
156
                        $actions .= '<a href="'.api_get_self().'?action=movedown&a'.api_get_cidreq().'&thematic_id='.$thematic[0].'">'.
157
                            Display::return_icon('down.png', get_lang('Down'), '', ICON_SIZE_SMALL).'</a>';
158
                    } else {
159
                        $actions .= Display::return_icon('down_na.png', '&nbsp;', '', ICON_SIZE_SMALL);
160
                    }
161
                    $actions .= '<a href="index.php?'.api_get_cidreq().'&action=thematic_edit&thematic_id='.$thematic[0].'">'.
162
                        Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL).'</a>';
163
                    $actions .= '<a onclick="javascript:if(!confirm(\''.get_lang('AreYouSureToDelete').'\')) return false;" href="index.php?'.api_get_cidreq().'&action=thematic_delete&thematic_id='.$thematic[0].'">'.
164
                        Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL).'</a>';
165
                }
166
                $thematics[] = [$thematic[0], $thematic[1], $actions];
167
            }
168
        }
169
170
        return $thematics;
171
    }
172
173
    /**
174
     * Get the maximum display order of the thematic item.
175
     *
176
     * @param bool $use_session
177
     *
178
     * @return int Maximum display order
179
     */
180
    public function get_max_thematic_item($use_session = true)
181
    {
182
        // Database table definition
183
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
184
        $session_id = api_get_session_id();
185
        if ($use_session) {
186
            $condition_session = api_get_session_condition($session_id);
187
        } else {
188
            $condition_session = '';
189
        }
190
        $course_id = api_get_course_int_id();
191
        $sql = "SELECT MAX(display_order)
192
                FROM $tbl_thematic
193
                WHERE c_id = $course_id AND active = 1 $condition_session";
194
        $rs = Database::query($sql);
195
        $row = Database::fetch_array($rs);
196
197
        return $row[0];
198
    }
199
200
    /**
201
     * Move a thematic.
202
     *
203
     * @param string $direction   (up, down)
204
     * @param int    $thematic_id
205
     */
206
    public function move_thematic($direction, $thematic_id)
207
    {
208
        // Database table definition
209
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
210
211
        // sort direction
212
        if ($direction == 'up') {
213
            $sortorder = 'DESC';
214
        } else {
215
            $sortorder = 'ASC';
216
        }
217
        $course_id = api_get_course_int_id();
218
        $session_id = api_get_session_id();
219
        $condition_session = api_get_session_condition($session_id);
220
221
        $sql = "SELECT id, display_order
222
                FROM $tbl_thematic
223
                WHERE c_id = $course_id AND active = 1 $condition_session
224
                ORDER BY display_order $sortorder";
225
        $res = Database::query($sql);
226
        $found = false;
227
228
        // Variable definition
229
        $current_id = 0;
230
        $next_id = 0;
231
        while ($row = Database::fetch_array($res)) {
232
            if ($found && empty($next_id)) {
233
                $next_id = intval($row['id']);
234
                $next_display_order = intval($row['display_order']);
235
            }
236
237
            if ($row['id'] == $thematic_id) {
238
                $current_id = intval($thematic_id);
239
                $current_display_order = intval($row['display_order']);
240
                $found = true;
241
            }
242
        }
243
244
        // get last done thematic advance before move thematic list
245
        $last_done_thematic_advance = $this->get_last_done_thematic_advance();
246
247
        if (!empty($next_display_order) && !empty($current_id)) {
248
            $sql = "UPDATE $tbl_thematic SET display_order = $next_display_order
249
                    WHERE c_id = $course_id AND id = $current_id ";
250
            Database::query($sql);
251
        }
252
        if (!empty($current_display_order) && !empty($next_id)) {
253
            $sql = "UPDATE $tbl_thematic SET
254
                    display_order = $current_display_order
255
                    WHERE c_id = $course_id AND id = $next_id ";
256
            Database::query($sql);
257
        }
258
259
        // update done advances with de current thematic list
260
        $this->update_done_thematic_advances($last_done_thematic_advance);
261
    }
262
263
    /**
264
     * Get thematic list.
265
     *
266
     * @param int    $thematic_id Thematic id (optional), get list by id
267
     * @param string $course_code
268
     * @param int    $session_id
269
     *
270
     * @return array Thematic data
271
     */
272
    public static function get_thematic_list(
273
        $thematic_id = null,
274
        $course_code = null,
275
        $session_id = null
276
    ) {
277
        // set current course and session
278
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
279
        $course_info = api_get_course_info($course_code);
280
        $course_id = $course_info['real_id'];
281
282
        if (isset($session_id)) {
283
            $session_id = intval($session_id);
284
        } else {
285
            $session_id = api_get_session_id();
286
        }
287
288
        $data = [];
289
        if (isset($thematic_id)) {
290
            $thematic_id = intval($thematic_id);
291
            $condition = " WHERE id = $thematic_id AND active = 1 ";
292
        } else {
293
            if (empty($session_id)) {
294
                $condition_session = api_get_session_condition(0);
295
            } else {
296
                $condition_session = api_get_session_condition($session_id, true, true);
297
            }
298
            $condition = " WHERE active = 1 $condition_session ";
299
        }
300
        $sql = "SELECT *
301
                FROM $tbl_thematic $condition AND c_id = $course_id
302
                ORDER BY display_order ";
303
304
        $res = Database::query($sql);
305
        if (Database::num_rows($res) > 0) {
306
            if (!empty($thematic_id)) {
307
                $data = Database::fetch_array($res, 'ASSOC');
308
            } else {
309
                while ($row = Database::fetch_array($res, 'ASSOC')) {
310
                    $data[$row['id']] = $row;
311
                }
312
            }
313
        } else {
314
            return false;
315
        }
316
317
        return $data;
318
    }
319
320
    /**
321
     * Insert or update a thematic.
322
     *
323
     * @return int last thematic id
324
     */
325
    public function thematic_save()
326
    {
327
        $_course = api_get_course_info();
328
        // definition database table
329
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
330
331
        // protect data
332
        $id = intval($this->thematic_id);
333
        $title = $this->thematic_title;
334
        $content = $this->thematic_content;
335
        $session_id = intval($this->session_id);
336
        $user_id = api_get_user_id();
337
338
        // get the maximum display order of all the glossary items
339
        $max_thematic_item = $this->get_max_thematic_item(false);
340
341
        if (empty($id)) {
342
            // insert
343
            $params = [
344
                'c_id' => $this->course_int_id,
345
                'title' => $title,
346
                'content' => $content,
347
                'active' => 1,
348
                'display_order' => intval($max_thematic_item) + 1,
349
                'session_id' => $session_id,
350
            ];
351
            $last_id = Database::insert($tbl_thematic, $params);
352
            if ($last_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $last_id of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
353
                $sql = "UPDATE $tbl_thematic SET id = iid WHERE iid = $last_id";
354
                Database::query($sql);
355
                api_item_property_update(
356
                    $_course,
357
                    'thematic',
358
                    $last_id,
359
                    "ThematicAdded",
360
                    $user_id
361
                );
362
            }
363
        } else {
364
            // Update
365
            $params = [
366
                'title' => $title,
367
                'content' => $content,
368
                'session_id' => $session_id,
369
            ];
370
371
            Database::update(
372
                $tbl_thematic,
373
                $params,
374
                ['id  = ? AND c_id = ?' => [$id, $this->course_int_id]]
375
            );
376
377
            $last_id = $id;
378
379
            // save inside item property table
380
            api_item_property_update(
381
                $_course,
382
                'thematic',
383
                $last_id,
384
                "ThematicUpdated",
385
                $user_id
386
            );
387
        }
388
389
        return $last_id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $last_id could also return false which is incompatible with the documented return type integer. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
390
    }
391
392
    /**
393
     * Delete logically (set active field to 0) a thematic.
394
     *
395
     * @param int|array One or many thematic ids
396
     *
397
     * @return int Affected rows
398
     */
399
    public function delete($thematic_id)
400
    {
401
        $_course = api_get_course_info();
402
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
403
        $affected_rows = 0;
404
        $user_id = api_get_user_id();
405
        $course_id = api_get_course_int_id();
406
407
        if (is_array($thematic_id)) {
408
            foreach ($thematic_id as $id) {
409
                $id = intval($id);
410
                $sql = "UPDATE $tbl_thematic SET active = 0
411
                        WHERE c_id = $course_id AND id = $id";
412
                $result = Database::query($sql);
413
                $affected_rows += Database::affected_rows($result);
414
                if (!empty($affected_rows)) {
415
                    // update row item property table
416
                    api_item_property_update(
417
                        $_course,
418
                        'thematic',
419
                        $id,
420
                        "ThematicDeleted",
421
                        $user_id
422
                    );
423
                }
424
            }
425
        } else {
426
            $thematic_id = intval($thematic_id);
427
            $sql = "UPDATE $tbl_thematic SET active = 0
428
                    WHERE c_id = $course_id AND id = $thematic_id";
429
            $result = Database::query($sql);
430
            $affected_rows = Database::affected_rows($result);
431
            if (!empty($affected_rows)) {
432
                // update row item property table
433
                api_item_property_update(
434
                    $_course,
435
                    'thematic',
436
                    $thematic_id,
437
                    "ThematicDeleted",
438
                    $user_id
439
                );
440
            }
441
        }
442
443
        return $affected_rows;
444
    }
445
446
    /**
447
     * @param int $thematic_id
448
     */
449
    public function copy($thematic_id)
450
    {
451
        $thematic = self::get_thematic_list($thematic_id, api_get_course_id(), 0);
452
        $thematic_copy = new Thematic();
453
        $thematic_copy->set_thematic_attributes(
454
            '',
455
            $thematic['title'].' - '.get_lang('Copy'),
456
            $thematic['content'],
457
            api_get_session_id()
458
        );
459
460
        $new_thematic_id = $thematic_copy->thematic_save();
461
        if (!empty($new_thematic_id)) {
462
            $thematic_advanced = self::get_thematic_advance_by_thematic_id($thematic_id);
0 ignored issues
show
Bug Best Practice introduced by
The method Thematic::get_thematic_advance_by_thematic_id() is not static, but was called statically. ( Ignorable by Annotation )

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

462
            /** @scrutinizer ignore-call */ 
463
            $thematic_advanced = self::get_thematic_advance_by_thematic_id($thematic_id);
Loading history...
463
            if (!empty($thematic_advanced)) {
464
                foreach ($thematic_advanced as $item) {
465
                    $thematic = new Thematic();
466
                    $thematic->set_thematic_advance_attributes(
467
                        0,
468
                        $new_thematic_id,
469
                        0,
470
                        $item['content'],
471
                        $item['start_date'],
472
                        $item['duration']
473
                    );
474
                    $thematic->thematic_advance_save();
475
                }
476
            }
477
            $thematic_plan = self::get_thematic_plan_data($thematic_id);
0 ignored issues
show
Bug Best Practice introduced by
The method Thematic::get_thematic_plan_data() is not static, but was called statically. ( Ignorable by Annotation )

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

477
            /** @scrutinizer ignore-call */ 
478
            $thematic_plan = self::get_thematic_plan_data($thematic_id);
Loading history...
478
            if (!empty($thematic_plan)) {
479
                foreach ($thematic_plan as $item) {
480
                    $thematic = new Thematic();
481
                    $thematic->set_thematic_plan_attributes(
482
                        $new_thematic_id,
483
                        $item['title'],
484
                        $item['description'],
485
                        $item['description_type']
486
                    );
487
                    $thematic->thematic_plan_save();
488
                }
489
            }
490
        }
491
    }
492
493
    /**
494
     * Get the total number of thematic advance inside current course.
495
     *
496
     * @see SortableTable#get_total_number_of_items()
497
     */
498
    public static function get_number_of_thematic_advances()
499
    {
500
        global $thematic_id;
501
        $table = Database::get_course_table(TABLE_THEMATIC_ADVANCE);
502
        $course_id = api_get_course_int_id();
503
        $thematic_id = (int) $thematic_id;
504
505
        $sql = "SELECT COUNT(id) AS total_number_of_items
506
                FROM $table
507
                WHERE c_id = $course_id AND thematic_id = $thematic_id ";
508
        $res = Database::query($sql);
509
        $obj = Database::fetch_object($res);
510
511
        return $obj->total_number_of_items;
512
    }
513
514
    /**
515
     * Get the thematic advances to display on the current page (fill the sortable-table).
516
     *
517
     * @param   int     offset of first user to recover
518
     * @param   int     Number of users to get
519
     * @param   int     Column to sort on
520
     * @param   string  Order (ASC,DESC)
521
     *
522
     * @return array
523
     *
524
     * @see SortableTable#get_table_data($from)
525
     */
526
    public static function get_thematic_advance_data($from, $number_of_items, $column, $direction)
527
    {
528
        global $thematic_id;
529
        $table = Database::get_course_table(TABLE_THEMATIC_ADVANCE);
530
        $column = intval($column);
531
        $from = intval($from);
532
        $number_of_items = intval($number_of_items);
533
        if (!in_array($direction, ['ASC', 'DESC'])) {
534
            $direction = 'ASC';
535
        }
536
        $data = [];
537
        $course_id = api_get_course_int_id();
538
        $thematic_id = (int) $thematic_id;
539
        if (api_is_allowed_to_edit(null, true)) {
540
            $sql = "SELECT id AS col0, start_date AS col1, duration AS col2, content AS col3
541
                    FROM $table
542
                    WHERE c_id = $course_id AND thematic_id = $thematic_id
543
                    ORDER BY col$column $direction
544
                    LIMIT $from,$number_of_items ";
545
546
            $list = api_get_item_property_by_tool(
547
                'thematic_advance',
548
                api_get_course_id(),
549
                api_get_session_id()
550
            );
551
552
            $elements = [];
553
            foreach ($list as $value) {
554
                $elements[] = $value['ref'];
555
            }
556
557
            $res = Database::query($sql);
558
            $i = 1;
559
            while ($thematic_advance = Database::fetch_row($res)) {
560
                if (in_array($thematic_advance[0], $elements)) {
561
                    $thematic_advance[1] = api_get_local_time($thematic_advance[1]);
562
                    $thematic_advance[1] = api_format_date($thematic_advance[1], DATE_TIME_FORMAT_LONG);
563
                    $actions = '';
564
                    $actions .= '<a href="index.php?'.api_get_cidreq().'&action=thematic_advance_edit&thematic_id='.$thematic_id.'&thematic_advance_id='.$thematic_advance[0].'">'.
565
                        Display::return_icon('edit.png', get_lang('Edit'), '', 22).'</a>';
566
                    $actions .= '<a onclick="javascript:if(!confirm(\''.get_lang('AreYouSureToDelete').'\')) return false;" href="index.php?'.api_get_cidreq().'&action=thematic_advance_delete&thematic_id='.$thematic_id.'&thematic_advance_id='.$thematic_advance[0].'">'.
567
                        Display::return_icon('delete.png', get_lang('Delete'), '', 22).'</a></center>';
568
                    $data[] = [$i, $thematic_advance[1], $thematic_advance[2], $thematic_advance[3], $actions];
569
                    $i++;
570
                }
571
            }
572
        }
573
574
        return $data;
575
    }
576
577
    /**
578
     * get thematic advance data by thematic id.
579
     *
580
     * @param int    $thematic_id
581
     * @param string $course_code Course code (optional)
582
     *
583
     * @return array data
584
     */
585
    public function get_thematic_advance_by_thematic_id($thematic_id, $course_code = null)
586
    {
587
        $course_info = api_get_course_info($course_code);
588
        $course_id = $course_info['real_id'];
589
590
        // set current course
591
        $table = Database::get_course_table(TABLE_THEMATIC_ADVANCE);
592
        $thematic_id = (int) $thematic_id;
593
        $data = [];
594
        $sql = "SELECT * FROM $table
595
                WHERE c_id = $course_id AND thematic_id = $thematic_id ";
596
597
        $elements = [];
598
        $list = api_get_item_property_by_tool(
599
            'thematic_advance',
600
            $course_info['code'],
601
            api_get_session_id()
602
        );
603
        foreach ($list as $value) {
604
            $elements[] = $value['ref'];
605
        }
606
607
        $res = Database::query($sql);
608
        if (Database::num_rows($res) > 0) {
609
            while ($row = Database::fetch_array($res, 'ASSOC')) {
610
                if (in_array($row['id'], $elements)) {
611
                    $data[] = $row;
612
                }
613
            }
614
        }
615
616
        return $data;
617
    }
618
619
    /**
620
     * @param array $data
621
     *
622
     * @return array
623
     */
624
    public function get_thematic_advance_div($data)
625
    {
626
        $return_array = [];
627
        $uinfo = api_get_user_info();
628
629
        foreach ($data as $thematic_id => $thematic_advance_data) {
630
            foreach ($thematic_advance_data as $key => $thematic_advance) {
631
                $session_star = '';
632
                if (api_is_allowed_to_edit(null, true)) {
633
                    if ($thematic_advance['session_id'] != 0) {
634
                        $session_star = api_get_session_image(api_get_session_id(), $uinfo['status']);
635
                    }
636
                }
637
                // DATE_TIME_FORMAT_LONG
638
                $thematic_advance_item = '<div><strong>'.
639
                    api_convert_and_format_date($thematic_advance['start_date'], DATE_TIME_FORMAT_LONG).
640
                    $session_star.'</strong></div>';
641
                $thematic_advance_item .= '<div>'.$thematic_advance['duration'].' '.get_lang('HourShort').'</div>';
642
                $thematic_advance_item .= '<div>'.Security::remove_XSS($thematic_advance['content'], STUDENT).'</div>';
643
                $return_array[$thematic_id][$thematic_advance['id']] = $thematic_advance_item;
644
            }
645
        }
646
647
        return $return_array;
648
    }
649
650
    /**
651
     * @param array $data
652
     *
653
     * @return array
654
     */
655
    public function get_thematic_plan_array($data)
656
    {
657
        $final_return = [];
658
        $uinfo = api_get_user_info();
659
660
        foreach ($data as $thematic_id => $thematic_plan_data) {
661
            $new_thematic_plan_data = [];
662
            foreach ($thematic_plan_data as $thematic_item) {
663
                $thematic_simple_list[] = $thematic_item['description_type'];
664
                $new_thematic_plan_data[$thematic_item['description_type']] = $thematic_item;
665
            }
666
667
            if (!empty($thematic_simple_list)) {
668
                foreach ($thematic_simple_list as $item) {
669
                    $default_thematic_plan_title[$item] = $new_thematic_plan_data[$item]['title'];
670
                }
671
            }
672
673
            $session_star = '';
674
            $return = [];
675
            if (!empty($default_thematic_plan_title)) {
676
                foreach ($default_thematic_plan_title as $id => $title) {
677
                    //avoid others
678
                    if ($title == 'Others' && empty($data[$thematic_id][$id]['description'])) {
679
                        continue;
680
                    }
681
                    if (!empty($data[$thematic_id][$id]['title']) &&
682
                        !empty($data[$thematic_id][$id]['description'])
683
                    ) {
684
                        if (api_is_allowed_to_edit(null, true)) {
685
                            if ($data[$thematic_id][$id]['session_id'] != 0) {
686
                                $session_star = api_get_session_image(api_get_session_id(), $uinfo['status']);
687
                            }
688
                        }
689
690
                        $return[$id]['title'] = Security::remove_XSS($data[$thematic_id][$id]['title'], STUDENT).$session_star;
691
                        $return[$id]['description'] = Security::remove_XSS($data[$thematic_id][$id]['description'], STUDENT);
692
                    }
693
                }
694
            }
695
            $final_return[$thematic_id] = $return;
696
        }
697
698
        return $final_return;
699
    }
700
701
    /**
702
     * Get thematic advance list.
703
     *
704
     * @param int    $thematic_advance_id Thematic advance id (optional), get data by thematic advance list
705
     * @param string $course_code         Course code (optional)
706
     * @param bool   $force_session_id    Force to have a session id
707
     * @param bool   $withLocalTime       Force start_date to local time
708
     *
709
     * @return array $data
710
     */
711
    public function get_thematic_advance_list(
712
        $thematic_advance_id = null,
713
        $course_code = null,
714
        $force_session_id = false,
715
        $withLocalTime = false
716
    ) {
717
        $course_info = api_get_course_info($course_code);
718
        $tbl_thematic_advance = Database::get_course_table(TABLE_THEMATIC_ADVANCE);
719
        $data = [];
720
        $condition = '';
721
        $thematic_advance_id = (int) $thematic_advance_id;
722
723
        if (!empty($thematic_advance_id)) {
724
            $condition = " AND a.id = $thematic_advance_id ";
725
        }
726
727
        $course_id = $course_info['real_id'];
728
729
        $sql = "SELECT * FROM $tbl_thematic_advance a
730
                WHERE c_id = $course_id $condition
731
                ORDER BY start_date ";
732
733
        $elements = [];
734
        if ($force_session_id) {
735
            $list = api_get_item_property_by_tool(
736
                'thematic_advance',
737
                $course_info['code'],
738
                api_get_session_id()
739
            );
740
            foreach ($list as $value) {
741
                $elements[$value['ref']] = $value;
742
            }
743
        }
744
745
        $res = Database::query($sql);
746
        if (Database::num_rows($res) > 0) {
747
            if (!empty($thematic_advance_id)) {
748
                $data = Database::fetch_array($res);
749
            } else {
750
                // group all data group by thematic id
751
                $tmp = [];
752
                while ($row = Database::fetch_array($res, 'ASSOC')) {
753
                    if ($withLocalTime == true) {
754
                        $row['start_date'] = api_get_local_time($row['start_date']);
755
                    }
756
                    $tmp[] = $row['thematic_id'];
757
                    if (in_array($row['thematic_id'], $tmp)) {
758
                        if ($force_session_id) {
759
                            if (in_array($row['id'], array_keys($elements))) {
760
                                $row['session_id'] = $elements[$row['id']]['session_id'];
761
                                $data[$row['thematic_id']][$row['id']] = $row;
762
                            }
763
                        } else {
764
                            $data[$row['thematic_id']][$row['id']] = $row;
765
                        }
766
                    }
767
                }
768
            }
769
        }
770
771
        return $data;
772
    }
773
774
    /**
775
     * insert or update a thematic advance.
776
     *
777
     * @todo problem
778
     *
779
     * @return int last thematic advance id
780
     */
781
    public function thematic_advance_save()
782
    {
783
        $_course = api_get_course_info();
784
        // definition database table
785
        $table = Database::get_course_table(TABLE_THEMATIC_ADVANCE);
786
787
        // protect data
788
        $id = intval($this->thematic_advance_id);
789
        $thematic_id = intval($this->thematic_id);
790
        $attendance_id = intval($this->attendance_id);
791
        $content = $this->thematic_advance_content;
792
        $start_date = $this->start_date;
793
        $duration = intval($this->duration);
794
        $user_id = api_get_user_id();
795
796
        $last_id = null;
797
        if (empty($id)) {
798
            // Insert
799
            $params = [
800
                'c_id' => $this->course_int_id,
801
                'thematic_id' => $thematic_id,
802
                'attendance_id' => $attendance_id,
803
                'content' => $content,
804
                'start_date' => api_get_utc_datetime($start_date),
805
                'duration' => $duration,
806
                'done_advance' => 0,
807
            ];
808
            $last_id = Database::insert($table, $params);
809
810
            if ($last_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $last_id of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
811
                $sql = "UPDATE $table SET id = iid WHERE iid = $last_id";
812
                Database::query($sql);
813
814
                api_item_property_update(
815
                    $_course,
816
                    'thematic_advance',
817
                    $last_id,
818
                    'ThematicAdvanceAdded',
819
                    $user_id
820
                );
821
            }
822
        } else {
823
            $params = [
824
                'thematic_id' => $thematic_id,
825
                'attendance_id' => $attendance_id,
826
                'content' => $content,
827
                'start_date' => api_get_utc_datetime($start_date),
828
                'duration' => $duration,
829
            ];
830
831
            Database::update(
832
                $table,
833
                $params,
834
                ['id = ? AND c_id = ?' => [$id, $this->course_int_id]]
835
            );
836
837
            api_item_property_update(
838
                $_course,
839
                'thematic_advance',
840
                $id,
841
                'ThematicAdvanceUpdated',
842
                $user_id
843
            );
844
        }
845
846
        return $last_id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $last_id could also return false which is incompatible with the documented return type integer. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
847
    }
848
849
    /**
850
     * delete  thematic advance.
851
     *
852
     * @param int $id Thematic advance id
853
     *
854
     * @return int Affected rows
855
     */
856
    public function thematic_advance_destroy($id)
857
    {
858
        $_course = api_get_course_info();
859
        $course_id = api_get_course_int_id();
860
861
        // definition database table
862
        $table = Database::get_course_table(TABLE_THEMATIC_ADVANCE);
863
864
        // protect data
865
        $id = intval($id);
866
        $user_id = api_get_user_id();
867
868
        $sql = "DELETE FROM $table
869
                WHERE c_id = $course_id AND id = $id ";
870
        $result = Database::query($sql);
871
        $affected_rows = Database::affected_rows($result);
872
        if ($affected_rows) {
873
            api_item_property_update(
874
                $_course,
875
                'thematic_advance',
876
                $id,
877
                'ThematicAdvanceDeleted',
878
                $user_id
879
            );
880
        }
881
882
        return $affected_rows;
883
    }
884
885
    /**
886
     * get thematic plan data.
887
     *
888
     * @param int Thematic id (optional), get data by thematic id
889
     * @param int Thematic plan description type (optional), get data by description type
890
     *
891
     * @return array Thematic plan data
892
     */
893
    public function get_thematic_plan_data($thematic_id = null, $description_type = null)
894
    {
895
        // definition database table
896
        $tbl_thematic_plan = Database::get_course_table(TABLE_THEMATIC_PLAN);
897
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
898
        $course_id = api_get_course_int_id();
899
900
        $data = [];
901
        $condition = '';
902
        if (isset($thematic_id)) {
903
            $thematic_id = intval($thematic_id);
904
            $condition .= " AND thematic_id = $thematic_id ";
905
        }
906
        if (isset($description_type)) {
907
            $description_type = intval($description_type);
908
            $condition .= " AND description_type = $description_type ";
909
        }
910
911
        $items_from_course = api_get_item_property_by_tool(
912
            'thematic_plan',
913
            api_get_course_id(),
914
            0
915
        );
916
        $items_from_session = api_get_item_property_by_tool(
917
            'thematic_plan',
918
            api_get_course_id(),
919
            api_get_session_id()
920
        );
921
922
        $thematic_plan_complete_list = [];
923
        $thematic_plan_id_list = [];
924
925
        if (!empty($items_from_course)) {
926
            foreach ($items_from_course as $item) {
927
                $thematic_plan_id_list[] = $item['ref'];
928
                $thematic_plan_complete_list[$item['ref']] = $item;
929
            }
930
        }
931
932
        if (!empty($items_from_session)) {
933
            foreach ($items_from_session as $item) {
934
                $thematic_plan_id_list[] = $item['ref'];
935
                $thematic_plan_complete_list[$item['ref']] = $item;
936
            }
937
        }
938
        if (!empty($thematic_plan_id_list)) {
939
            $sql = "SELECT
940
                        tp.id, thematic_id, tp.title, description, description_type, t.session_id
941
                    FROM $tbl_thematic_plan tp
942
                    INNER JOIN $tbl_thematic t
943
                    ON (t.id = tp.thematic_id AND t.c_id = tp.c_id)
944
                    WHERE
945
                        t.c_id = $course_id AND
946
                        tp.c_id = $course_id
947
                        $condition AND
948
                        tp.id IN (".implode(', ', $thematic_plan_id_list).") ";
949
950
            $rs = Database::query($sql);
951
952
            if (Database::num_rows($rs)) {
953
                if (!isset($thematic_id) && !isset($description_type)) {
954
                    // group all data group by thematic id
955
                    $tmp = [];
956
                    while ($row = Database::fetch_array($rs, 'ASSOC')) {
957
                        $tmp[] = $row['thematic_id'];
958
                        if (in_array($row['thematic_id'], $tmp)) {
959
                            $row['session_id'] = $thematic_plan_complete_list[$row['id']];
960
                            $data[$row['thematic_id']][$row['description_type']] = $row;
961
                        }
962
                    }
963
                } else {
964
                    while ($row = Database::fetch_array($rs, 'ASSOC')) {
965
                        $row['session_id'] = $thematic_plan_complete_list[$row['id']];
966
                        $data[] = $row;
967
                    }
968
                }
969
            }
970
        }
971
972
        return $data;
973
    }
974
975
    /**
976
     * insert or update a thematic plan.
977
     *
978
     * @return int affected rows
979
     */
980
    public function thematic_plan_save()
981
    {
982
        $_course = api_get_course_info();
983
        // definition database table
984
        $tbl_thematic_plan = Database::get_course_table(TABLE_THEMATIC_PLAN);
985
986
        // protect data
987
        $thematic_id = intval($this->thematic_id);
988
        $title = $this->thematic_plan_title;
989
        $description = $this->thematic_plan_description;
990
        $description_type = intval($this->thematic_plan_description_type);
991
        $user_id = api_get_user_id();
992
        $course_id = api_get_course_int_id();
993
        $list = api_get_item_property_by_tool(
994
            'thematic_plan',
995
            api_get_course_id(),
996
            api_get_session_id()
997
        );
998
999
        $elements_to_show = [];
1000
        foreach ($list as $value) {
1001
            $elements_to_show[] = $value['ref'];
1002
        }
1003
        $condition = '';
1004
        if (!empty($elements_to_show)) {
1005
            $condition = "AND id IN (".implode(',', $elements_to_show).") ";
1006
        }
1007
        // check thematic plan type already exists
1008
        $sql = "SELECT id FROM $tbl_thematic_plan
1009
                WHERE
1010
                    c_id = $course_id AND
1011
                    thematic_id = $thematic_id AND
1012
                    description_type = '$description_type'";
1013
        $rs = Database::query($sql);
1014
1015
        $affected_rows = 0;
1016
        if (Database::num_rows($rs) > 0) {
1017
            $row_thematic_plan = Database::fetch_array($rs);
1018
            $thematic_plan_id = $row_thematic_plan['id'];
1019
            $update = false;
1020
            if (in_array($thematic_plan_id, $elements_to_show)) {
1021
                $update = true;
1022
            }
1023
1024
            if ($update) {
1025
                // update
1026
                $params = [
1027
                    'title' => $title,
1028
                    'description' => $description,
1029
                ];
1030
                Database::update(
1031
                    $tbl_thematic_plan,
1032
                    $params,
1033
                    ['c_id = ? AND id = ?' => [$course_id, $thematic_plan_id]]
1034
                );
1035
1036
                api_item_property_update(
1037
                    $_course,
1038
                    'thematic_plan',
1039
                    $thematic_plan_id,
1040
                    'ThematicPlanUpdated',
1041
                    $user_id
1042
                );
1043
            } else {
1044
                // insert
1045
                $params = [
1046
                    'c_id' => $this->course_int_id,
1047
                    'thematic_id' => $thematic_id,
1048
                    'title' => $title,
1049
                    'description' => $description,
1050
                    'description_type' => $description_type,
1051
                ];
1052
                $last_id = Database::insert($tbl_thematic_plan, $params);
1053
                if ($last_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $last_id of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1054
                    $sql = "UPDATE $tbl_thematic_plan SET id = iid WHERE iid = $last_id";
1055
                    Database::query($sql);
1056
                    api_item_property_update(
1057
                        $_course,
1058
                        'thematic_plan',
1059
                        $last_id,
1060
                        'ThematicPlanAdded',
1061
                        $user_id
1062
                    );
1063
                }
1064
            }
1065
        } else {
1066
            // insert
1067
            $params = [
1068
                'c_id' => $this->course_int_id,
1069
                'thematic_id' => $thematic_id,
1070
                'title' => $title,
1071
                'description' => $description,
1072
                'description_type' => $description_type,
1073
            ];
1074
            $last_id = Database::insert($tbl_thematic_plan, $params);
1075
1076
            if ($last_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $last_id of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1077
                $sql = "UPDATE $tbl_thematic_plan SET id = iid WHERE iid = $last_id";
1078
                Database::query($sql);
1079
                api_item_property_update(
1080
                    $_course,
1081
                    'thematic_plan',
1082
                    $last_id,
1083
                    'ThematicPlanAdded',
1084
                    $user_id
1085
                );
1086
            }
1087
        }
1088
1089
        return $affected_rows;
1090
    }
1091
1092
    /**
1093
     * Delete a thematic plan description.
1094
     *
1095
     * @param int $thematic_id      Thematic id
1096
     * @param int $description_type Description type
1097
     *
1098
     * @return int Affected rows
1099
     */
1100
    public function thematic_plan_destroy($thematic_id, $description_type)
1101
    {
1102
        $_course = api_get_course_info();
1103
        // definition database table
1104
        $tbl_thematic_plan = Database::get_course_table(TABLE_THEMATIC_PLAN);
1105
1106
        // protect data
1107
        $thematic_id = intval($thematic_id);
1108
        $description_type = intval($description_type);
1109
        $user_id = api_get_user_id();
1110
        $course_info = api_get_course_info();
1111
        $course_id = $course_info['real_id'];
1112
1113
        // get thematic plan id
1114
        $thematic_plan_data = $this->get_thematic_plan_data($thematic_id, $description_type);
1115
        $thematic_plan_id = $thematic_plan_data[0]['id'];
1116
1117
        // delete
1118
        $sql = "DELETE FROM $tbl_thematic_plan
1119
                WHERE
1120
                    c_id = $course_id AND
1121
                    thematic_id = $thematic_id AND
1122
                    description_type = $description_type ";
1123
        $result = Database::query($sql);
1124
        $affected_rows = Database::affected_rows($result);
1125
        if ($affected_rows) {
1126
            api_item_property_update(
1127
                $_course,
1128
                'thematic_plan',
1129
                $thematic_plan_id,
1130
                'ThematicPlanDeleted',
1131
                $user_id
1132
            );
1133
        }
1134
1135
        return $affected_rows;
1136
    }
1137
1138
    /**
1139
     * Get next description type for a new thematic plan description (option 'others').
1140
     *
1141
     * @param int $thematic_id Thematic id
1142
     *
1143
     * @return int New Description type
1144
     */
1145
    public function get_next_description_type($thematic_id)
1146
    {
1147
        // definition database table
1148
        $tbl_thematic_plan = Database::get_course_table(TABLE_THEMATIC_PLAN);
1149
1150
        // protect data
1151
        $thematic_id = intval($thematic_id);
1152
        $course_id = api_get_course_int_id();
1153
1154
        $sql = "SELECT MAX(description_type) as max
1155
                FROM $tbl_thematic_plan
1156
                WHERE
1157
                    c_id = $course_id AND
1158
                    thematic_id = $thematic_id AND
1159
                    description_type >= ".ADD_THEMATIC_PLAN;
1160
        $rs = Database::query($sql);
1161
        $row = Database::fetch_array($rs);
1162
        $last_description_type = $row['max'];
1163
1164
        if (isset($last_description_type)) {
1165
            $next_description_type = $last_description_type + 1;
1166
        } else {
1167
            $next_description_type = ADD_THEMATIC_PLAN;
1168
        }
1169
1170
        return $next_description_type;
1171
    }
1172
1173
    /**
1174
     * update done thematic advances from thematic details interface.
1175
     *
1176
     * @param int $thematic_advance_id
1177
     *
1178
     * @return int Affected rows
1179
     */
1180
    public function update_done_thematic_advances($thematic_advance_id)
1181
    {
1182
        $_course = api_get_course_info();
1183
        $thematic_data = self::get_thematic_list(null, api_get_course_id());
1184
        $thematic_advance_data = $this->get_thematic_advance_list(
1185
            null,
1186
            api_get_course_id(),
1187
            true
1188
        );
1189
        $table = Database::get_course_table(TABLE_THEMATIC_ADVANCE);
1190
1191
        $affected_rows = 0;
1192
        $user_id = api_get_user_id();
1193
1194
        $all = [];
1195
        if (!empty($thematic_data)) {
1196
            foreach ($thematic_data as $thematic) {
1197
                if (!empty($thematic_advance_data[$thematic['id']])) {
1198
                    foreach ($thematic_advance_data[$thematic['id']] as $thematic_advance) {
1199
                        $all[] = $thematic_advance['id'];
1200
                    }
1201
                }
1202
            }
1203
        }
1204
        $error = null;
1205
        $a_thematic_advance_ids = [];
1206
        $course_id = api_get_course_int_id();
1207
        $sessionId = api_get_session_id();
1208
1209
        if (!empty($thematic_data)) {
1210
            foreach ($thematic_data as $thematic) {
1211
                $my_affected_rows = 0;
1212
                $thematic_id = $thematic['id'];
1213
                if (!empty($thematic_advance_data[$thematic['id']])) {
1214
                    foreach ($thematic_advance_data[$thematic['id']] as $thematic_advance) {
1215
                        $item_info = api_get_item_property_info(
1216
                            api_get_course_int_id(),
1217
                            'thematic_advance',
1218
                            $thematic_advance['id'],
1219
                            $sessionId
1220
                        );
1221
1222
                        if ($item_info['session_id'] == $sessionId) {
1223
                            $a_thematic_advance_ids[] = $thematic_advance['id'];
1224
                            // update done thematic for previous advances ((done_advance = 1))
1225
                            $upd = "UPDATE $table SET
1226
                                    done_advance = 1
1227
                                    WHERE c_id = $course_id AND id = ".$thematic_advance['id']." ";
1228
                            $result = Database::query($upd);
1229
                            $my_affected_rows = Database::affected_rows($result);
1230
                            $affected_rows += $my_affected_rows;
1231
                            //if ($my_affected_rows) {
1232
                            api_item_property_update(
1233
                                $_course,
1234
                                'thematic_advance',
1235
                                $thematic_advance['id'],
1236
                                "ThematicAdvanceDone",
1237
                                $user_id
1238
                            );
1239
                            //}
1240
                            if ($thematic_advance['id'] == $thematic_advance_id) {
1241
                                break 2;
1242
                            }
1243
                        }
1244
                    }
1245
                }
1246
            }
1247
        }
1248
1249
        // Update done thematic for others advances (done_advance = 0)
1250
        if (!empty($a_thematic_advance_ids) && count($a_thematic_advance_ids) > 0) {
1251
            $diff = array_diff($all, $a_thematic_advance_ids);
1252
            if (!empty($diff)) {
1253
                $upd = "UPDATE $table SET done_advance = 0
1254
                        WHERE c_id = $course_id AND id IN(".implode(',', $diff).") ";
1255
                Database::query($upd);
1256
            }
1257
1258
            // update item_property
1259
            $tbl_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1260
            $sql = "SELECT ref FROM $tbl_item_property
1261
                    WHERE
1262
                        c_id = $course_id AND
1263
                        tool='thematic_advance' AND
1264
                        lastedit_type='ThematicAdvanceDone' AND
1265
                        session_id = $sessionId ";
1266
            // get all thematic advance done
1267
            $rs_thematic_done = Database::query($sql);
1268
            if (Database::num_rows($rs_thematic_done) > 0) {
1269
                while ($row_thematic_done = Database::fetch_array($rs_thematic_done)) {
1270
                    $ref = $row_thematic_done['ref'];
1271
                    if (in_array($ref, $a_thematic_advance_ids)) {
1272
                        continue;
1273
                    }
1274
                    // update items
1275
                    $sql = "UPDATE $tbl_item_property SET
1276
                                lastedit_date='".api_get_utc_datetime()."',
1277
                                lastedit_type='ThematicAdvanceUpdated',
1278
                                lastedit_user_id = $user_id
1279
                            WHERE
1280
                                c_id = $course_id AND
1281
                                tool='thematic_advance' AND
1282
                                ref=$ref AND
1283
                                session_id = $sessionId  ";
1284
                    Database::query($sql);
1285
                }
1286
            }
1287
        }
1288
1289
        return $affected_rows;
1290
    }
1291
1292
    /**
1293
     * Get last done thematic advance from thematic details interface.
1294
     *
1295
     * @return int Last done thematic advance id
1296
     */
1297
    public function get_last_done_thematic_advance()
1298
    {
1299
        $thematic_data = self::get_thematic_list();
1300
        $thematic_advance_data = $this->get_thematic_advance_list(
1301
            null,
1302
            api_get_course_id(),
1303
            true
1304
        );
1305
1306
        $a_thematic_advance_ids = [];
1307
        $last_done_advance_id = 0;
1308
        if (!empty($thematic_data)) {
1309
            foreach ($thematic_data as $thematic) {
1310
                if (!empty($thematic_advance_data[$thematic['id']])) {
1311
                    foreach ($thematic_advance_data[$thematic['id']] as $thematic_advance) {
1312
                        if ($thematic_advance['done_advance'] == 1) {
1313
                            $a_thematic_advance_ids[] = $thematic_advance['id'];
1314
                        }
1315
                    }
1316
                }
1317
            }
1318
        }
1319
        if (!empty($a_thematic_advance_ids)) {
1320
            $last_done_advance_id = array_pop($a_thematic_advance_ids);
1321
            $last_done_advance_id = intval($last_done_advance_id);
1322
        }
1323
1324
        return $last_done_advance_id;
1325
    }
1326
1327
    /**
1328
     * Get next thematic advance not done from thematic details interface.
1329
     *
1330
     * @param   int Offset (if you want to get an item that is not directly the next)
1331
     *
1332
     * @return int next thematic advance not done
1333
     */
1334
    public function get_next_thematic_advance_not_done($offset = 1)
1335
    {
1336
        $thematic_data = self::get_thematic_list();
1337
        $thematic_advance_data = $this->get_thematic_advance_list();
1338
        $a_thematic_advance_ids = [];
1339
        $next_advance_not_done = 0;
1340
        if (!empty($thematic_data)) {
1341
            foreach ($thematic_data as $thematic) {
1342
                if (!empty($thematic_advance_data[$thematic['id']])) {
1343
                    foreach ($thematic_advance_data[$thematic['id']] as $thematic_advance) {
1344
                        if ($thematic_advance['done_advance'] == 0) {
1345
                            $a_thematic_advance_ids[] = $thematic_advance['id'];
1346
                        }
1347
                    }
1348
                }
1349
            }
1350
        }
1351
1352
        if (!empty($a_thematic_advance_ids)) {
1353
            for ($i = 0; $i < $offset; $i++) {
1354
                $next_advance_not_done = array_shift($a_thematic_advance_ids);
1355
            }
1356
            $next_advance_not_done = intval($next_advance_not_done);
1357
        }
1358
1359
        return $next_advance_not_done;
1360
    }
1361
1362
    /**
1363
     * Get total average of thematic advances.
1364
     *
1365
     * @param string $course_code (optional)
1366
     * @param int    $session_id  (optional)
1367
     *
1368
     * @return float Average of thematic advances
1369
     */
1370
    public function get_total_average_of_thematic_advances($course_code = null, $session_id = null)
1371
    {
1372
        if (empty($course_code)) {
1373
            $course_code = api_get_course_id();
1374
        }
1375
        if (api_get_session_id()) {
1376
            $thematic_data = self::get_thematic_list(null, $course_code);
1377
        } else {
1378
            $thematic_data = self::get_thematic_list(null, $course_code, 0);
1379
        }
1380
        $new_thematic_data = [];
1381
        if (!empty($thematic_data)) {
1382
            foreach ($thematic_data as $item) {
1383
                $new_thematic_data[] = $item;
1384
            }
1385
            $thematic_data = $new_thematic_data;
1386
        }
1387
1388
        $a_average_of_advances_by_thematic = [];
1389
        $total_average = 0;
1390
        if (!empty($thematic_data)) {
1391
            foreach ($thematic_data as $thematic) {
1392
                $thematic_id = $thematic['id'];
1393
                $a_average_of_advances_by_thematic[$thematic_id] = $this->get_average_of_advances_by_thematic(
1394
                    $thematic_id,
1395
                    $course_code
1396
                );
1397
            }
1398
        }
1399
1400
        // calculate total average
1401
        if (!empty($a_average_of_advances_by_thematic)) {
1402
            $count_tematics = count($thematic_data);
1403
            $score = array_sum($a_average_of_advances_by_thematic);
1404
            $total_average = round(($score * 100) / ($count_tematics * 100));
1405
        }
1406
1407
        return $total_average;
1408
    }
1409
1410
    /**
1411
     * Get average of advances by thematic.
1412
     *
1413
     * @param int Thematic id
1414
     * @param string $course_code
1415
     *
1416
     * @return float Average of thematic advances
1417
     */
1418
    public function get_average_of_advances_by_thematic($thematic_id, $course_code = null)
1419
    {
1420
        $thematic_advance_data = $this->get_thematic_advance_by_thematic_id($thematic_id, $course_code);
1421
        $average = 0;
1422
        if (!empty($thematic_advance_data)) {
1423
            // get all done advances by thematic
1424
            $advances = [];
1425
            $count_done_advances = 0;
1426
            foreach ($thematic_advance_data as $thematic_advance) {
1427
                if ($thematic_advance['done_advance'] == 1) {
1428
                    $count_done_advances++;
1429
                }
1430
                $advances[] = $thematic_advance['done_advance'];
1431
            }
1432
            // calculate average by thematic
1433
            $count_total_advances = count($advances);
1434
            $average = round(($count_done_advances * 100) / $count_total_advances);
1435
        }
1436
1437
        return $average;
1438
    }
1439
1440
    /**
1441
     * set attributes for fields of thematic table.
1442
     *
1443
     * @param    int        Thematic id
1444
     * @param    string    Thematic title
1445
     * @param    string    Thematic content
1446
     * @param    int        Session id
1447
     */
1448
    public function set_thematic_attributes($id = null, $title = '', $content = '', $session_id = 0)
1449
    {
1450
        $this->thematic_id = $id;
1451
        $this->thematic_title = $title;
1452
        $this->thematic_content = $content;
1453
        $this->session_id = $session_id;
1454
    }
1455
1456
    /**
1457
     * set attributes for fields of thematic_plan table.
1458
     *
1459
     * @param    int        Thematic id
1460
     * @param    string    Thematic plan title
1461
     * @param    string    Thematic plan description
1462
     * @param    int        Thematic plan description type
1463
     */
1464
    public function set_thematic_plan_attributes(
1465
        $thematic_id = 0,
1466
        $title = '',
1467
        $description = '',
1468
        $description_type = 0
1469
    ) {
1470
        $this->thematic_id = $thematic_id;
1471
        $this->thematic_plan_title = $title;
1472
        $this->thematic_plan_description = $description;
1473
        $this->thematic_plan_description_type = $description_type;
1474
    }
1475
1476
    /**
1477
     * set attributes for fields of thematic_advance table.
1478
     *
1479
     * @param int $id Thematic advance id
1480
     * @param    int        Thematic id
1481
     * @param    int        Attendance id
1482
     * @param    string    Content
1483
     * @param    string    Date and time
1484
     * @param    int        Duration in hours
1485
     */
1486
    public function set_thematic_advance_attributes(
1487
        $id = null,
1488
        $thematic_id = 0,
1489
        $attendance_id = 0,
1490
        $content = '',
1491
        $start_date = null,
1492
        $duration = 0
1493
    ) {
1494
        $this->thematic_advance_id = $id;
1495
        $this->thematic_id = $thematic_id;
1496
        $this->attendance_id = $attendance_id;
1497
        $this->thematic_advance_content = $content;
1498
        $this->start_date = $start_date;
1499
        $this->duration = $duration;
1500
    }
1501
1502
    /**
1503
     * set thematic id.
1504
     *
1505
     * @param    int     Thematic id
1506
     */
1507
    public function set_thematic_id($thematic_id)
1508
    {
1509
        $this->thematic_id = $thematic_id;
1510
    }
1511
1512
    /**
1513
     * get thematic id.
1514
     *
1515
     * @return int
1516
     */
1517
    public function get_thematic_id()
1518
    {
1519
        return $this->thematic_id;
1520
    }
1521
1522
    /**
1523
     * Get thematic plan titles by default.
1524
     *
1525
     * @return array
1526
     */
1527
    public function get_default_thematic_plan_title()
1528
    {
1529
        $default_thematic_plan_titles = [];
1530
        $default_thematic_plan_titles[1] = get_lang('Objectives');
1531
        $default_thematic_plan_titles[2] = get_lang('SkillToAcquire');
1532
        $default_thematic_plan_titles[3] = get_lang('Methodology');
1533
        $default_thematic_plan_titles[4] = get_lang('Infrastructure');
1534
        $default_thematic_plan_titles[5] = get_lang('Assessment');
1535
        $default_thematic_plan_titles[6] = get_lang('Others');
1536
1537
        return $default_thematic_plan_titles;
1538
    }
1539
1540
    /**
1541
     * Get thematic plan icons by default.
1542
     *
1543
     * @return array
1544
     */
1545
    public function get_default_thematic_plan_icon()
1546
    {
1547
        $default_thematic_plan_icon = [];
1548
        $default_thematic_plan_icon[1] = 'icons/32/objective.png';
1549
        $default_thematic_plan_icon[2] = 'icons/32/skills.png';
1550
        $default_thematic_plan_icon[3] = 'icons/32/strategy.png';
1551
        $default_thematic_plan_icon[4] = 'icons/32/laptop.png';
1552
        $default_thematic_plan_icon[5] = 'icons/32/assessment.png';
1553
        $default_thematic_plan_icon[6] = 'icons/32/wizard.png';
1554
1555
        return $default_thematic_plan_icon;
1556
    }
1557
1558
    /**
1559
     * Get questions by default for help.
1560
     *
1561
     * @return array
1562
     */
1563
    public function get_default_question()
1564
    {
1565
        $question = [];
1566
        $question[1] = get_lang('ObjectivesQuestions');
1567
        $question[2] = get_lang('SkillToAcquireQuestions');
1568
        $question[3] = get_lang('MethodologyQuestions');
1569
        $question[4] = get_lang('InfrastructureQuestions');
1570
        $question[5] = get_lang('AssessmentQuestions');
1571
1572
        return $question;
1573
    }
1574
}
1575