Passed
Push — master ( 241b61...cc68cc )
by Julito
09:18
created

Thematic::get_thematic_advance_list()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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

161
                    if ($thematic[2] < self::/** @scrutinizer ignore-call */ get_max_thematic_item()) {
Loading history...
162
                        $actions .= '<a href="'.api_get_self().'?action=movedown&a'.api_get_cidreq().'&thematic_id='.$thematic[0].'">'.
163
                            Display::return_icon('down.png', get_lang('down'), '', ICON_SIZE_SMALL).'</a>';
164
                    } else {
165
                        $actions .= Display::return_icon('down_na.png', '&nbsp;', '', ICON_SIZE_SMALL);
166
                    }
167
                    $actions .= '<a href="index.php?'.api_get_cidreq().'&action=thematic_edit&thematic_id='.$thematic[0].'">'.
168
                        Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL).'</a>';
169
                    $actions .= '<a onclick="javascript:if(!confirm(\''.get_lang('Are you sure you want to delete').'\')) return false;" href="index.php?'.api_get_cidreq().'&action=thematic_delete&thematic_id='.$thematic[0].'">'.
170
                        Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL).'</a>';
171
                }
172
                $thematics[] = [$thematic[0], $thematic[1], $actions];
173
            }
174
        }
175
176
        return $thematics;
177
    }
178
179
    /**
180
     * Get the maximum display order of the thematic item.
181
     *
182
     * @param bool $use_session
183
     *
184
     * @return int Maximum display order
185
     */
186
    public function get_max_thematic_item($use_session = true)
187
    {
188
        // Database table definition
189
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
190
        $session_id = api_get_session_id();
191
        if ($use_session) {
192
            $condition_session = api_get_session_condition($session_id);
193
        } else {
194
            $condition_session = '';
195
        }
196
        $course_id = api_get_course_int_id();
197
        $sql = "SELECT MAX(display_order)
198
                FROM $tbl_thematic
199
                WHERE c_id = $course_id AND active = 1 $condition_session";
200
        $rs = Database::query($sql);
201
        $row = Database::fetch_array($rs);
202
203
        return $row[0];
204
    }
205
206
    /**
207
     * Move a thematic.
208
     *
209
     * @param string $direction   (up, down)
210
     * @param int    $thematic_id
211
     */
212
    public function move_thematic($direction, $thematic_id)
213
    {
214
        // Database table definition
215
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
216
217
        // sort direction
218
        if ('up' == $direction) {
219
            $sortorder = 'DESC';
220
        } else {
221
            $sortorder = 'ASC';
222
        }
223
        $course_id = api_get_course_int_id();
224
        $session_id = api_get_session_id();
225
        $condition_session = api_get_session_condition($session_id);
226
227
        $sql = "SELECT id, display_order
228
                FROM $tbl_thematic
229
                WHERE c_id = $course_id AND active = 1 $condition_session
230
                ORDER BY display_order $sortorder";
231
        $res = Database::query($sql);
232
        $found = false;
233
234
        // Variable definition
235
        $current_id = 0;
236
        $next_id = 0;
237
        while ($row = Database::fetch_array($res)) {
238
            if ($found && empty($next_id)) {
239
                $next_id = intval($row['id']);
240
                $next_display_order = intval($row['display_order']);
241
            }
242
243
            if ($row['id'] == $thematic_id) {
244
                $current_id = intval($thematic_id);
245
                $current_display_order = intval($row['display_order']);
246
                $found = true;
247
            }
248
        }
249
250
        // get last done thematic advance before move thematic list
251
        $last_done_thematic_advance = $this->get_last_done_thematic_advance();
252
253
        if (!empty($next_display_order) && !empty($current_id)) {
254
            $sql = "UPDATE $tbl_thematic SET display_order = $next_display_order
255
                    WHERE c_id = $course_id AND id = $current_id ";
256
            Database::query($sql);
257
        }
258
        if (!empty($current_display_order) && !empty($next_id)) {
259
            $sql = "UPDATE $tbl_thematic SET
260
                    display_order = $current_display_order
261
                    WHERE c_id = $course_id AND id = $next_id ";
262
            Database::query($sql);
263
        }
264
265
        // update done advances with de current thematic list
266
        $this->update_done_thematic_advances($last_done_thematic_advance);
267
    }
268
269
    /**
270
     * Get thematic list.
271
     *
272
     * @param string $course_code
273
     * @param int    $session_id
274
     *
275
     * @return array Thematic data
276
     */
277
    public static function get_thematic_list($course_code = null, $session_id = null)
278
    {
279
        // set current course and session
280
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
281
        $course_info = api_get_course_info($course_code);
282
        $course_id = $course_info['real_id'];
283
284
        if (!empty($session_id)) {
285
            $session_id = (int) $session_id;
286
        } else {
287
            $session_id = api_get_session_id();
288
        }
289
290
        $data = [];
291
        if (empty($session_id)) {
292
            $condition_session = api_get_session_condition(0);
293
        } else {
294
            $condition_session = api_get_session_condition($session_id, true, true);
295
        }
296
        $condition = " WHERE active = 1 $condition_session ";
297
298
        $sql = "SELECT *
299
                FROM $tbl_thematic $condition AND c_id = $course_id
300
                ORDER BY display_order ";
301
302
        $res = Database::query($sql);
303
        if (Database::num_rows($res) > 0) {
304
            $repo = Container::getThematicRepository();
305
            while ($row = Database::fetch_array($res, 'ASSOC')) {
306
                $entity = $repo->find($row['iid']);
307
                $data[$row['iid']] = $entity;
308
            }
309
        }
310
311
        return $data;
312
    }
313
314
    /**
315
     * Insert or update a thematic.
316
     *
317
     * @return CThematic
318
     */
319
    public function thematic_save()
320
    {
321
        // definition database table
322
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
323
324
        // protect data
325
        $id = intval($this->thematic_id);
326
        $title = $this->thematic_title;
327
        $content = $this->thematic_content;
328
        $session_id = intval($this->session_id);
329
330
        // get the maximum display order of all the glossary items
331
        $max_thematic_item = $this->get_max_thematic_item(false);
332
333
        $repo = Container::getThematicRepository();
334
        $em = $repo->getEntityManager();
335
336
        if (empty($id)) {
337
            $thematic = new CThematic();
338
            $courseEntity = api_get_course_entity();
339
            $thematic
340
                ->setTitle($title)
341
                ->setContent($content)
342
                ->setActive(1)
343
                ->setCId($this->course_int_id)
344
                ->setDisplayOrder($max_thematic_item + 1)
345
                ->setSessionId($session_id)
346
                ->setParent($courseEntity)
347
                ->addCourseLink($courseEntity, api_get_session_entity())
348
            ;
349
350
            $em->persist($thematic);
351
            $em->flush();
352
353
            // insert
354
            /*$params = [
355
                'c_id' => $this->course_int_id,
356
                'active' => 1,
357
                'display_order' => intval($max_thematic_item) + 1,
358
                'session_id' => $session_id,
359
            ];*/
360
            $last_id = $thematic->getIid();
361
            if ($last_id) {
362
                /*api_item_property_update(
363
                    $_course,
364
                    'thematic',
365
                    $last_id,
366
                    'ThematicAdded',
367
                    $user_id
368
                );*/
369
            }
370
        } else {
371
            $thematic = $repo->find($id);
372
            if ($thematic) {
0 ignored issues
show
introduced by
$thematic is of type Chamilo\CoreBundle\Entity\ResourceInterface, thus it always evaluated to true.
Loading history...
373
                $thematic
374
                    ->setTitle($title)
0 ignored issues
show
Bug introduced by
The method setTitle() does not exist on Chamilo\CoreBundle\Entity\ResourceInterface. It seems like you code against a sub-type of Chamilo\CoreBundle\Entity\ResourceInterface such as Chamilo\CoreBundle\Entity\Course or Chamilo\CourseBundle\Entity\CLink or Chamilo\CourseBundle\Entity\CNotebook or Chamilo\CourseBundle\Entity\CAnnouncement or Chamilo\CourseBundle\Entity\CThematicPlan or Chamilo\CourseBundle\Entity\CQuiz or Chamilo\CourseBundle\Entity\CCourseDescription or Chamilo\CourseBundle\Entity\CGroupCategory or Chamilo\CourseBundle\Entity\CDocument or Chamilo\CourseBundle\Entity\CThematic or Chamilo\CourseBundle\Entity\CQuizQuestionCategory or Chamilo\CourseBundle\Entity\CStudentPublication or Chamilo\CourseBundle\Entity\CCalendarEvent. ( Ignorable by Annotation )

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

374
                    ->/** @scrutinizer ignore-call */ 
375
                      setTitle($title)
Loading history...
375
                    ->setContent($content)
376
                ;
377
378
                $em->persist($thematic);
379
                $em->flush();
380
            }
381
382
            // Update
383
            /*$params = [
384
                'title' => $title,
385
                'content' => $content,
386
                'session_id' => $session_id,
387
            ];
388
389
            Database::update(
390
                $tbl_thematic,
391
                $params,
392
                ['id  = ? AND c_id = ?' => [$id, $this->course_int_id]]
393
            );
394
395
            $last_id = $id;
396
397
            // save inside item property table
398
            api_item_property_update(
399
                $_course,
400
                'thematic',
401
                $last_id,
402
                'ThematicUpdated',
403
                $user_id
404
            );*/
405
        }
406
407
        return $thematic;
408
    }
409
410
    /**
411
     * Delete logically (set active field to 0) a thematic.
412
     *
413
     * @param int|array One or many thematic ids
414
     *
415
     * @return int Affected rows
416
     */
417
    public function delete($thematic_id)
418
    {
419
        $_course = api_get_course_info();
420
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
421
        $affected_rows = 0;
422
        $user_id = api_get_user_id();
423
        $course_id = api_get_course_int_id();
424
425
        if (is_array($thematic_id)) {
426
            foreach ($thematic_id as $id) {
427
                $id = intval($id);
428
                $sql = "UPDATE $tbl_thematic SET active = 0
429
                        WHERE c_id = $course_id AND id = $id";
430
                $result = Database::query($sql);
431
                $affected_rows += Database::affected_rows($result);
432
                if (!empty($affected_rows)) {
433
                    // update row item property table
434
                    /*api_item_property_update(
435
                        $_course,
436
                        'thematic',
437
                        $id,
438
                        'ThematicDeleted',
439
                        $user_id
440
                    );*/
441
                }
442
            }
443
        } else {
444
            $thematic_id = intval($thematic_id);
445
            $sql = "UPDATE $tbl_thematic SET active = 0
446
                    WHERE c_id = $course_id AND id = $thematic_id";
447
            $result = Database::query($sql);
448
            $affected_rows = Database::affected_rows($result);
449
            if (!empty($affected_rows)) {
450
                // update row item property table
451
                /*api_item_property_update(
452
                    $_course,
453
                    'thematic',
454
                    $thematic_id,
455
                    'ThematicDeleted',
456
                    $user_id
457
                );*/
458
            }
459
        }
460
461
        return $affected_rows;
462
    }
463
464
    /**
465
     * @param int $thematicId
466
     */
467
    public function copy($thematicId)
468
    {
469
        $repo = Container::getThematicRepository();
470
        /** @var CThematic $thematic */
471
        $thematic = $repo->find($thematicId);
472
        if (null === $thematic) {
473
            return false;
474
        }
475
476
        $thematicManager = new Thematic();
477
        $thematicManager->set_thematic_attributes(
478
            '',
479
            $thematic->getTitle().' - '.get_lang('Copy'),
480
            $thematic->getContent(),
481
            api_get_session_id()
482
        );
483
        $new_thematic_id = $thematicManager->thematic_save();
484
485
        if (!empty($new_thematic_id)) {
486
            $thematic_advanced = $thematic->getAdvances();
487
            if (!empty($thematic_advanced)) {
488
                foreach ($thematic_advanced as $item) {
489
                    $thematic = new Thematic();
490
                    $thematic->set_thematic_advance_attributes(
491
                        0,
492
                        $new_thematic_id,
493
                        0,
494
                        $item->getContent(),
495
                        $item->getStartDate()->format('Y-m-d H:i:s'),
496
                        $item->getDuration()
497
                    );
498
                    $thematic->thematic_advance_save();
499
                }
500
            }
501
            $thematic_plan = $thematic->getPlans();
0 ignored issues
show
Bug introduced by
The method getPlans() does not exist on Thematic. ( Ignorable by Annotation )

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

501
            /** @scrutinizer ignore-call */ 
502
            $thematic_plan = $thematic->getPlans();

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

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

Loading history...
502
            if (!empty($thematic_plan)) {
503
                foreach ($thematic_plan as $item) {
504
                    $thematic = new Thematic();
505
                    $thematic->set_thematic_plan_attributes(
506
                        $new_thematic_id,
507
                        $item->getTitle(),
508
                        $item->getDescription(),
509
                        $item->getDescriptionType()
510
                    );
511
                    $thematic->thematic_plan_save();
512
                }
513
            }
514
        }
515
    }
516
517
    /**
518
     * Get the total number of thematic advance inside current course.
519
     *
520
     * @see SortableTable#get_total_number_of_items()
521
     */
522
    public static function get_number_of_thematic_advances()
523
    {
524
        global $thematic_id;
525
        $table = Database::get_course_table(TABLE_THEMATIC_ADVANCE);
526
        $course_id = api_get_course_int_id();
527
        $thematic_id = (int) $thematic_id;
528
529
        $sql = "SELECT COUNT(id) AS total_number_of_items
530
                FROM $table
531
                WHERE c_id = $course_id AND thematic_id = $thematic_id ";
532
        $res = Database::query($sql);
533
        $obj = Database::fetch_object($res);
534
535
        return $obj->total_number_of_items;
536
    }
537
538
    /**
539
     * Get the thematic advances to display on the current page (fill the sortable-table).
540
     *
541
     * @param   int     offset of first user to recover
542
     * @param   int     Number of users to get
543
     * @param   int     Column to sort on
544
     * @param   string  Order (ASC,DESC)
545
     *
546
     * @return array
547
     *
548
     * @see SortableTable#get_table_data($from)
549
     */
550
    public static function get_thematic_advance_data($from, $number_of_items, $column, $direction, $params = [])
551
    {
552
        $table = Database::get_course_table(TABLE_THEMATIC_ADVANCE);
553
        $column = (int) $column;
554
        $from = (int) $from;
555
        $number_of_items = (int) $number_of_items;
556
        if (!in_array($direction, ['ASC', 'DESC'])) {
557
            $direction = 'ASC';
558
        }
559
        $data = [];
560
        $course_id = api_get_course_int_id();
561
        $thematic_id = (int) $params['thematic_id'];
562
        if (api_is_allowed_to_edit(null, true)) {
563
            $sql = "SELECT id AS col0, start_date AS col1, duration AS col2, content AS col3
564
                    FROM $table
565
                    WHERE c_id = $course_id AND thematic_id = $thematic_id
566
                    ORDER BY col$column $direction
567
                    LIMIT $from,$number_of_items ";
568
569
            /*$list = api_get_item_property_by_tool(
570
                'thematic_advance',
571
                api_get_course_id(),
572
                api_get_session_id()
573
            );*/
574
575
            /*$elements = [];
576
            foreach ($list as $value) {
577
                $elements[] = $value['ref'];
578
            }*/
579
580
            $res = Database::query($sql);
581
            $i = 1;
582
            while ($thematic_advance = Database::fetch_row($res)) {
583
                //if (in_array($thematic_advance[0], $elements)) {
584
                $thematic_advance[1] = api_get_local_time($thematic_advance[1]);
585
                $thematic_advance[1] = api_format_date($thematic_advance[1], DATE_TIME_FORMAT_LONG);
586
                $actions = '';
587
                $actions .= '<a href="index.php?'.api_get_cidreq().'&action=thematic_advance_edit&thematic_id='.$thematic_id.'&thematic_advance_id='.$thematic_advance[0].'">'.
588
                        Display::return_icon('edit.png', get_lang('Edit'), '', 22).'</a>';
589
                $actions .= '<a onclick="javascript:if(!confirm(\''.get_lang('Are you sure you want to delete').'\')) return false;" href="index.php?'.api_get_cidreq().'&action=thematic_advance_delete&thematic_id='.$thematic_id.'&thematic_advance_id='.$thematic_advance[0].'">'.
590
                        Display::return_icon('delete.png', get_lang('Delete'), '', 22).'</a></center>';
591
                $data[] = [$i, $thematic_advance[1], $thematic_advance[2], $thematic_advance[3], $actions];
592
                $i++;
593
                // }
594
            }
595
        }
596
597
        return $data;
598
    }
599
600
    /**
601
     * get thematic advance data by thematic id.
602
     *
603
     * @param int    $thematic_id
604
     * @param string $course_code Course code (optional)
605
     *
606
     * @return array data
607
     */
608
    public function get_thematic_advance_by_thematic_id($thematic_id, $course_code = null)
609
    {
610
        $course_info = api_get_course_info($course_code);
611
        $course_id = $course_info['real_id'];
612
613
        $repo = Container::getThematicAdvanceRepository();
614
615
        $courseEntity = api_get_course_entity($course_id);
616
        $sessionEntity = api_get_session_entity(api_get_session_id());
617
618
        $qb = $repo->getResourcesByCourse($courseEntity, $sessionEntity);
619
620
        $qb->andWhere($qb->expr()->eq('resource.thematic', $thematic_id));
621
622
        return $qb->getQuery()->getResult();
623
    }
624
625
    public function getThematicAdvance($id): ?CThematicAdvance
626
    {
627
        $repo = Container::getThematicAdvanceRepository();
628
629
        return $repo->find($id);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $repo->find($id) returns the type Chamilo\CoreBundle\Entity\ResourceInterface which includes types incompatible with the type-hinted return Chamilo\CourseBundle\Entity\CThematicAdvance|null.
Loading history...
630
    }
631
632
    /**
633
     * Get thematic advance list.
634
     *
635
     * @param string $course_code         Course code (optional)
636
     * @param bool   $force_session_id    Force to have a session id
637
     * @param bool   $withLocalTime       Force start_date to local time
638
     *
639
     * @return CThematicAdvance[]
640
     */
641
    public function get_thematic_advance_list($course_code = null, $force_session_id = false, $withLocalTime = false)
642
    {
643
        $course_info = api_get_course_info($course_code);
644
        $course_id = $course_info['real_id'];
645
        $repo = Container::getThematicAdvanceRepository();
646
647
        $courseEntity = api_get_course_entity($course_id);
648
        $sessionEntity = null;
649
        if ($force_session_id) {
650
            $sessionEntity = api_get_session_entity(api_get_session_id());
651
            /*$list = api_get_item_property_by_tool(
652
                'thematic_advance',
653
                $course_info['code'],
654
                api_get_session_id()
655
            );
656
            foreach ($list as $value) {
657
                $elements[$value['ref']] = $value;
658
            }*/
659
        }
660
661
        $qb = $repo->getResourcesByCourse($courseEntity, $sessionEntity);
662
        $qb->orderBy('resource.startDate', 'DESC');
663
664
        return $qb->getQuery()->getResult();
665
    }
666
667
    /**
668
     * insert or update a thematic advance.
669
     *
670
     * @todo problem
671
     *
672
     * @return int last thematic advance id
673
     */
674
    public function thematic_advance_save()
675
    {
676
        $id = (int) $this->thematic_advance_id;
677
        $thematic_id = intval($this->thematic_id);
678
        $attendance_id = intval($this->attendance_id);
679
        $content = $this->thematic_advance_content;
680
        $start_date = $this->start_date;
681
        $duration = intval($this->duration);
682
        $repo = Container::getThematicAdvanceRepository();
683
        $em = $repo->getEntityManager();
684
685
        /** @var CThematicAdvance $advance */
686
        $advance = $repo->find($id);
687
688
        $repoThematic = Container::getThematicRepository();
689
        $thematic = $repoThematic->find($thematic_id);
690
        $attendanceRepo = Container::getAttendanceRepository();
691
        $attendance = $attendanceRepo->find($attendance_id);
692
693
        $last_id = null;
694
        if (null === $advance) {
695
            $advance = new CThematicAdvance();
696
            $advance
697
                ->setCId($this->course_int_id)
698
                ->setContent($content)
699
                //->setThematic($thematic)
700
                //->setAttendance($attendance)
701
                ->setStartDate(api_get_utc_datetime($start_date, true, true))
702
                ->setDuration($duration)
703
            ;
704
705
            if ($thematic) {
0 ignored issues
show
introduced by
$thematic is of type Chamilo\CoreBundle\Entity\ResourceInterface, thus it always evaluated to true.
Loading history...
706
                $advance->setThematic($thematic);
707
            }
708
709
            if ($attendance) {
0 ignored issues
show
introduced by
$attendance is of type Chamilo\CoreBundle\Entity\ResourceInterface, thus it always evaluated to true.
Loading history...
710
                $advance->setAttendance($attendance);
711
            }
712
713
            $courseEntity = api_get_course_entity();
714
            $advance
715
                ->setParent($courseEntity)
716
                ->addCourseLink($courseEntity, api_get_session_entity())
717
            ;
718
            $em->persist($advance);
719
            $em->flush();
720
721
            $last_id = $advance->getIid();
722
        } else {
723
            $advance
724
                ->setCId($this->course_int_id)
725
                ->setContent($content)
726
                ->setStartDate(api_get_utc_datetime($start_date, true, true))
727
                ->setDuration($duration)
728
            ;
729
730
            if ($thematic) {
0 ignored issues
show
introduced by
$thematic is of type Chamilo\CoreBundle\Entity\ResourceInterface, thus it always evaluated to true.
Loading history...
731
                $advance->setThematic($thematic);
732
            }
733
734
            if ($attendance) {
0 ignored issues
show
introduced by
$attendance is of type Chamilo\CoreBundle\Entity\ResourceInterface, thus it always evaluated to true.
Loading history...
735
                $advance->setAttendance($attendance);
736
            }
737
            $em->persist($advance);
738
            $em->flush();
739
        }
740
741
        return $last_id;
742
    }
743
744
    /**
745
     * delete  thematic advance.
746
     *
747
     * @param int $id Thematic advance id
748
     *
749
     * @return int Affected rows
750
     */
751
    public function thematic_advance_destroy($id)
752
    {
753
        $repo = Container::getThematicAdvanceRepository();
754
        $advance = $repo->find($id);
755
756
        if ($advance) {
0 ignored issues
show
introduced by
$advance is of type Chamilo\CoreBundle\Entity\ResourceInterface, thus it always evaluated to true.
Loading history...
757
            $repo->getEntityManager()->remove($advance);
758
            $repo->getEntityManager()->flush();
759
        }
760
761
        return true;
762
763
        $_course = api_get_course_info();
0 ignored issues
show
Unused Code introduced by
$_course = api_get_course_info() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
764
        $course_id = api_get_course_int_id();
765
766
        // definition database table
767
        $table = Database::get_course_table(TABLE_THEMATIC_ADVANCE);
768
769
        // protect data
770
        $id = intval($id);
771
        $user_id = api_get_user_id();
772
773
        $sql = "DELETE FROM $table
774
                WHERE c_id = $course_id AND id = $id ";
775
        $result = Database::query($sql);
776
        $affected_rows = Database::affected_rows($result);
777
778
        if ($affected_rows) {
779
            api_item_property_update(
0 ignored issues
show
Bug introduced by
The function api_item_property_update was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

779
            /** @scrutinizer ignore-call */ 
780
            api_item_property_update(
Loading history...
780
                $_course,
781
                'thematic_advance',
782
                $id,
783
                'ThematicAdvanceDeleted',
784
                $user_id
785
            );
786
        }
787
788
        return $affected_rows;
789
    }
790
791
    /**
792
     * get thematic plan data.
793
     *
794
     * @param int Thematic id (optional), get data by thematic id
795
     * @param int Thematic plan description type (optional), get data by description type
796
     *
797
     * @deprecated
798
     *
799
     * @return array Thematic plan data
800
     */
801
    public function get_thematic_plan_data($thematic_id = null, $description_type = null)
802
    {
803
        // definition database table
804
        $tbl_thematic_plan = Database::get_course_table(TABLE_THEMATIC_PLAN);
805
        $tbl_thematic = Database::get_course_table(TABLE_THEMATIC);
806
        $course_id = api_get_course_int_id();
807
808
        $repo = Container::getThematicPlanRepository();
809
810
        $courseEntity = api_get_course_entity();
811
        $sessionEntity = api_get_session_entity(api_get_session_id());
812
813
        $qb = $repo->getResourcesByCourse($courseEntity, $sessionEntity);
814
815
        $result = $qb->getQuery()->getResult();
816
        //var_dump(count($result));
817
818
        $data = [];
819
        $condition = '';
820
        //var_dump($thematic_id, $description_type);
821
        if (!empty($thematic_id)) {
822
            $qb->andWhere($qb->expr()->eq('resource.thematic', $thematic_id));
823
824
            //$thematic_id = intval($thematic_id);
825
            //$condition .= " AND thematic_id = $thematic_id ";
826
        }
827
        if (!empty($description_type)) {
828
            $qb->andWhere($qb->expr()->eq('resource.descriptionType', $description_type));
829
            //$condition .= " AND description_type = $description_type ";
830
        }
831
832
        return $qb->getQuery()->getResult();
833
834
        /*$items_from_course = api_get_item_property_by_tool(
835
            'thematic_plan',
836
            api_get_course_id(),
837
            0
838
        );
839
        $items_from_session = api_get_item_property_by_tool(
840
            'thematic_plan',
841
            api_get_course_id(),
842
            api_get_session_id()
843
        );*/
844
845
        $thematic_plan_complete_list = [];
0 ignored issues
show
Unused Code introduced by
$thematic_plan_complete_list = array() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
846
        $thematic_plan_id_list = [];
847
848
        /*if (!empty($items_from_course)) {
849
            foreach ($items_from_course as $item) {
850
                $thematic_plan_id_list[] = $item['ref'];
851
                $thematic_plan_complete_list[$item['ref']] = $item;
852
            }
853
        }
854
855
        if (!empty($items_from_session)) {
856
            foreach ($items_from_session as $item) {
857
                $thematic_plan_id_list[] = $item['ref'];
858
                $thematic_plan_complete_list[$item['ref']] = $item;
859
            }
860
        }*/
861
862
        if (!empty($thematic_plan_id_list)) {
863
            $sql = "SELECT
864
                        tp.id, thematic_id, tp.title, description, description_type, t.session_id
865
                    FROM $tbl_thematic_plan tp
866
                    INNER JOIN $tbl_thematic t
867
                    ON (t.id = tp.thematic_id AND t.c_id = tp.c_id)
868
                    WHERE
869
                        t.c_id = $course_id AND
870
                        tp.c_id = $course_id
871
                        $condition AND
872
                        tp.id IN (".implode(', ', $thematic_plan_id_list).') ';
873
874
            $rs = Database::query($sql);
875
876
            if (Database::num_rows($rs)) {
877
                if (!isset($thematic_id) && !isset($description_type)) {
878
                    // group all data group by thematic id
879
                    $tmp = [];
880
                    while ($row = Database::fetch_array($rs, 'ASSOC')) {
881
                        $tmp[] = $row['thematic_id'];
882
                        if (in_array($row['thematic_id'], $tmp)) {
883
                            $row['session_id'] = $thematic_plan_complete_list[$row['id']];
884
                            $data[$row['thematic_id']][$row['description_type']] = $row;
885
                        }
886
                    }
887
                } else {
888
                    while ($row = Database::fetch_array($rs, 'ASSOC')) {
889
                        $row['session_id'] = $thematic_plan_complete_list[$row['id']];
890
                        $data[] = $row;
891
                    }
892
                }
893
            }
894
        }
895
896
        return $data;
897
    }
898
899
    /**
900
     * insert or update a thematic plan.
901
     *
902
     * @return int affected rows
903
     */
904
    public function thematic_plan_save()
905
    {
906
        $_course = api_get_course_info();
907
        // definition database table
908
        $tbl_thematic_plan = Database::get_course_table(TABLE_THEMATIC_PLAN);
909
910
        // protect data
911
        $thematic_id = intval($this->thematic_id);
912
        $title = $this->thematic_plan_title;
913
        $description = $this->thematic_plan_description;
914
        $description_type = intval($this->thematic_plan_description_type);
915
        $user_id = api_get_user_id();
916
        $course_id = api_get_course_int_id();
917
918
        /*$list = api_get_item_property_by_tool(
919
            'thematic_plan',
920
            api_get_course_id(),
921
            api_get_session_id()
922
        );
923
924
        $elements_to_show = [];
925
        foreach ($list as $value) {
926
            $elements_to_show[] = $value['ref'];
927
        }
928
        $condition = '';
929
        if (!empty($elements_to_show)) {
930
            $condition = 'AND id IN ('.implode(',', $elements_to_show).') ';
931
        }*/
932
933
        $repo = Container::getThematicPlanRepository();
934
935
        $criteria = [
936
            'cId' => $course_id,
937
            'thematic' => $thematic_id,
938
            'descriptionType' => $description_type,
939
        ];
940
        $em = $repo->getEntityManager();
941
        /** @var CThematicPlan $plan */
942
        $plan = $repo->findOneBy($criteria);
943
944
        // check thematic plan type already exists
945
        /*$sql = "SELECT id FROM $tbl_thematic_plan
946
                WHERE
947
                    c_id = $course_id AND
948
                    thematic_id = $thematic_id AND
949
                    description_type = '$description_type'";
950
        $rs = Database::query($sql);*/
951
        if ($plan) {
0 ignored issues
show
introduced by
$plan is of type Chamilo\CourseBundle\Entity\CThematicPlan, thus it always evaluated to true.
Loading history...
952
            $plan
953
                ->setTitle($title)
954
                ->setDescription($description)
955
            ;
956
            $em->persist($plan);
957
            $em->flush();
958
959
        // update
960
            /*$params = [
961
                'title' => $title,
962
                'description' => $description,
963
            ];
964
            Database::update(
965
                $tbl_thematic_plan,
966
                $params,
967
                ['c_id = ? AND id = ?' => [$course_id, $thematic_plan_id]]
968
            );
969
970
            api_item_property_update(
971
                $_course,
972
                'thematic_plan',
973
                $thematic_plan_id,
974
                'ThematicPlanUpdated',
975
                $user_id
976
            );*/
977
        } else {
978
            $thematic = Container::getThematicRepository()->find($thematic_id);
979
            $course = api_get_course_entity();
980
            $plan = new CThematicPlan();
981
            $plan
982
                ->setTitle($title)
983
                ->setDescription($description)
984
                ->setCId($this->course_int_id)
985
                ->setThematic($thematic)
986
                ->setDescriptionType($description_type)
987
                ->setParent($course)
988
                ->addCourseLink($course, api_get_session_entity())
989
            ;
990
991
            $em->persist($plan);
992
            $em->flush();
993
994
            if ($plan && $plan->getIid()) {
995
                /*
996
                api_item_property_update(
997
                    $_course,
998
                    'thematic_plan',
999
                    $last_id,
1000
                    'ThematicPlanAdded',
1001
                    $user_id
1002
                );*/
1003
            }
1004
        }
1005
1006
        return true;
1007
    }
1008
1009
    /**
1010
     * Delete a thematic plan description.
1011
     *
1012
     * @param int $thematic_id Thematic id
1013
     *
1014
     * @return int Affected rows
1015
     */
1016
    public function thematic_plan_destroy($thematic_id, $descriptionType)
1017
    {
1018
        $repo = Container::getThematicRepository();
1019
1020
        /** @var CThematic $thematic */
1021
        $thematic = $repo->find($thematic_id);
1022
1023
        foreach ($thematic->getPlans() as $plan) {
1024
            if ($descriptionType == $plan->getDescriptionType()) {
1025
                $thematic->getPlans()->removeElement($plan);
1026
            }
1027
        }
1028
        $repo->getEntityManager()->persist($thematic);
1029
        $repo->getEntityManager()->flush();
1030
1031
        return false;
1032
1033
        $_course = api_get_course_info();
0 ignored issues
show
Unused Code introduced by
$_course = api_get_course_info() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1034
        // definition database table
1035
        $tbl_thematic_plan = Database::get_course_table(TABLE_THEMATIC_PLAN);
1036
1037
        // protect data
1038
        $thematic_id = intval($thematic_id);
1039
        $description_type = intval($description_type);
1040
        $user_id = api_get_user_id();
1041
        $course_info = api_get_course_info();
1042
        $course_id = $course_info['real_id'];
1043
1044
        // get thematic plan id
1045
        $thematic_plan_data = $this->get_thematic_plan_data($thematic_id, $description_type);
1046
        $thematic_plan_id = $thematic_plan_data[0]['id'];
1047
1048
        // delete
1049
        $sql = "DELETE FROM $tbl_thematic_plan
1050
                WHERE
1051
                    c_id = $course_id AND
1052
                    thematic_id = $thematic_id AND
1053
                    description_type = $description_type ";
1054
        $result = Database::query($sql);
1055
        $affected_rows = Database::affected_rows($result);
1056
        if ($affected_rows) {
1057
            /*api_item_property_update(
1058
                $_course,
1059
                'thematic_plan',
1060
                $thematic_plan_id,
1061
                'ThematicPlanDeleted',
1062
                $user_id
1063
            );*/
1064
        }
1065
1066
        return $affected_rows;
1067
    }
1068
1069
    /**
1070
     * Get next description type for a new thematic plan description (option 'others').
1071
     *
1072
     * @param int $thematic_id Thematic id
1073
     *
1074
     * @return int New Description type
1075
     */
1076
    public function get_next_description_type($thematic_id)
1077
    {
1078
        // definition database table
1079
        $tbl_thematic_plan = Database::get_course_table(TABLE_THEMATIC_PLAN);
1080
1081
        // protect data
1082
        $thematic_id = intval($thematic_id);
1083
        $course_id = api_get_course_int_id();
1084
1085
        $sql = "SELECT MAX(description_type) as max
1086
                FROM $tbl_thematic_plan
1087
                WHERE
1088
                    c_id = $course_id AND
1089
                    thematic_id = $thematic_id AND
1090
                    description_type >= ".ADD_THEMATIC_PLAN;
1091
        $rs = Database::query($sql);
1092
        $row = Database::fetch_array($rs);
1093
        $last_description_type = $row['max'];
1094
1095
        if (isset($last_description_type)) {
1096
            $next_description_type = $last_description_type + 1;
1097
        } else {
1098
            $next_description_type = ADD_THEMATIC_PLAN;
1099
        }
1100
1101
        return $next_description_type;
1102
    }
1103
1104
    /**
1105
     * update done thematic advances from thematic details interface.
1106
     *
1107
     * @return int Affected rows
1108
     */
1109
    public function update_done_thematic_advances($advanceId)
1110
    {
1111
        $repo = Container::getThematicRepository();
1112
        $em = $repo->getEntityManager();
1113
1114
        $list = self::get_thematic_list(api_get_course_id());
1115
        $ordered = [];
1116
1117
        foreach ($list as $thematic) {
1118
            $done = true;
1119
            foreach ($thematic->getAdvances() as $advance) {
1120
                $ordered[] = $advance;
1121
                /*if ($advanceId === $advance->getIid()) {
1122
                    $done = false;
1123
                }*/
1124
                $advance->setDoneAdvance($done);
1125
            }
1126
        }
1127
1128
        $done = true;
1129
        foreach ($ordered as $advance) {
1130
            if ($advanceId === $advance->getIid()) {
1131
                $done = false;
1132
                $advance->setDoneAdvance(true);
1133
                $em->persist($advance);
1134
                continue;
1135
            }
1136
1137
            $advance->setDoneAdvance($done);
1138
            $em->persist($advance);
1139
        }
1140
1141
        $em->flush();
1142
1143
        return true;
1144
1145
        $_course = api_get_course_info();
0 ignored issues
show
Unused Code introduced by
$_course = api_get_course_info() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1146
        $thematic_data = self::get_thematic_list(api_get_course_id());
1147
        $table = Database::get_course_table(TABLE_THEMATIC_ADVANCE);
1148
1149
        $affected_rows = 0;
1150
        $user_id = api_get_user_id();
1151
1152
        /*$all = [];
1153
        if (!empty($thematic_data)) {
1154
            foreach ($thematic_data as $thematic) {
1155
                $thematic_id = $thematic['id'];
1156
                if (!empty($thematic_advance_data[$thematic['id']])) {
1157
                    foreach ($thematic_advance_data[$thematic['id']] as $thematic_advance) {
1158
                        $all[] = $thematic_advance['id'];
1159
                    }
1160
                }
1161
            }
1162
        }*/
1163
        $error = null;
1164
        $a_thematic_advance_ids = [];
1165
        $course_id = api_get_course_int_id();
1166
        $sessionId = api_get_session_id();
1167
1168
        /*if (!empty($thematic_data)) {
1169
            foreach ($thematic_data as $thematic) {
1170
                $my_affected_rows = 0;
1171
                $thematic_id = $thematic['id'];
1172
                if (!empty($thematic_advance_data[$thematic['id']])) {
1173
                    foreach ($thematic_advance_data[$thematic['id']] as $thematic_advance) {
1174
                        $item_info = api_get_item_property_info(
1175
                            api_get_course_int_id(),
1176
                            'thematic_advance',
1177
                            $thematic_advance['id'],
1178
                            $sessionId
1179
                        );
1180
1181
                        if ($item_info['session_id'] == $sessionId) {
1182
                            $a_thematic_advance_ids[] = $thematic_advance['id'];
1183
                            // update done thematic for previous advances ((done_advance = 1))
1184
                            $upd = "UPDATE $table SET
1185
                                    done_advance = 1
1186
                                    WHERE c_id = $course_id AND id = ".$thematic_advance['id'].' ';
1187
                            $result = Database::query($upd);
1188
                            $my_affected_rows = Database::affected_rows($result);
1189
                            $affected_rows += $my_affected_rows;
1190
                            //if ($my_affected_rows) {
1191
                            api_item_property_update(
1192
                                $_course,
1193
                                'thematic_advance',
1194
                                $thematic_advance['id'],
1195
                                'ThematicAdvanceDone',
1196
                                $user_id
1197
                            );
1198
                            //}
1199
                            if ($thematic_advance['id'] == $thematic_advance_id) {
1200
                                break 2;
1201
                            }
1202
                        }
1203
                    }
1204
                }
1205
            }
1206
        }*/
1207
1208
        // Update done thematic for others advances (done_advance = 0)
1209
        if (!empty($a_thematic_advance_ids) && count($a_thematic_advance_ids) > 0) {
1210
            $diff = array_diff($all, $a_thematic_advance_ids);
1211
            if (!empty($diff)) {
1212
                $upd = "UPDATE $table SET done_advance = 0
1213
                        WHERE c_id = $course_id AND id IN(".implode(',', $diff).') ';
1214
                Database::query($upd);
1215
            }
1216
1217
            // update item_property
1218
            $tbl_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
1219
            $sql = "SELECT ref FROM $tbl_item_property
1220
                    WHERE
1221
                        c_id = $course_id AND
1222
                        tool='thematic_advance' AND
1223
                        lastedit_type='ThematicAdvanceDone' AND
1224
                        session_id = $sessionId ";
1225
            // get all thematic advance done
1226
            $rs_thematic_done = Database::query($sql);
1227
            if (Database::num_rows($rs_thematic_done) > 0) {
1228
                while ($row_thematic_done = Database::fetch_array($rs_thematic_done)) {
1229
                    $ref = $row_thematic_done['ref'];
1230
                    if (in_array($ref, $a_thematic_advance_ids)) {
1231
                        continue;
1232
                    }
1233
                    // update items
1234
                    $sql = "UPDATE $tbl_item_property SET
1235
                                lastedit_date='".api_get_utc_datetime()."',
1236
                                lastedit_type='ThematicAdvanceUpdated',
1237
                                lastedit_user_id = $user_id
1238
                            WHERE
1239
                                c_id = $course_id AND
1240
                                tool='thematic_advance' AND
1241
                                ref=$ref AND
1242
                                session_id = $sessionId  ";
1243
                    Database::query($sql);
1244
                }
1245
            }
1246
        }
1247
1248
        return $affected_rows;
1249
    }
1250
1251
    /**
1252
     * Get last done thematic advance from thematic details interface.
1253
     *
1254
     * @return int Last done thematic advance id
1255
     */
1256
    public function get_last_done_thematic_advance()
1257
    {
1258
        $thematic_data = self::get_thematic_list();
1259
1260
        $a_thematic_advance_ids = [];
1261
        $last_done_advance_id = 0;
1262
        if (!empty($thematic_data)) {
1263
            /** @var CThematic $thematic */
1264
            foreach ($thematic_data as $thematic) {
1265
                $id = $thematic->getIid();
1266
                if ($thematic->getAdvances()->count()) {
1267
                    foreach ($thematic->getAdvances() as $thematic_advance) {
1268
                        if (1 == $thematic_advance->getDoneAdvance()) {
1269
                            $a_thematic_advance_ids[] = $thematic_advance->getIid();
1270
                        }
1271
                    }
1272
                }
1273
            }
1274
        }
1275
        if (!empty($a_thematic_advance_ids)) {
1276
            $last_done_advance_id = array_pop($a_thematic_advance_ids);
1277
            $last_done_advance_id = intval($last_done_advance_id);
1278
        }
1279
1280
        return $last_done_advance_id;
1281
    }
1282
1283
    /**
1284
     * Get next thematic advance not done from thematic details interface.
1285
     *
1286
     * @param   int Offset (if you want to get an item that is not directly the next)
1287
     *
1288
     * @return int next thematic advance not done
1289
     */
1290
    public function get_next_thematic_advance_not_done($offset = 1)
1291
    {
1292
        $thematic_data = self::get_thematic_list();
1293
        $thematic_advance_data = $this->get_thematic_advance_list();
1294
        $a_thematic_advance_ids = [];
1295
        $next_advance_not_done = 0;
1296
        if (!empty($thematic_data)) {
1297
            foreach ($thematic_data as $thematic) {
1298
                if (!empty($thematic_advance_data[$thematic['id']])) {
1299
                    foreach ($thematic_advance_data[$thematic['id']] as $thematic_advance) {
1300
                        if (0 == $thematic_advance['done_advance']) {
1301
                            $a_thematic_advance_ids[] = $thematic_advance['id'];
1302
                        }
1303
                    }
1304
                }
1305
            }
1306
        }
1307
1308
        if (!empty($a_thematic_advance_ids)) {
1309
            for ($i = 0; $i < $offset; $i++) {
1310
                $next_advance_not_done = array_shift($a_thematic_advance_ids);
1311
            }
1312
            $next_advance_not_done = intval($next_advance_not_done);
1313
        }
1314
1315
        return $next_advance_not_done;
1316
    }
1317
1318
    /**
1319
     * Get total average of thematic advances.
1320
     *
1321
     * @param string $course_code (optional)
1322
     * @param int    $session_id  (optional)
1323
     *
1324
     * @return float Average of thematic advances
1325
     */
1326
    public function get_total_average_of_thematic_advances($course_code = null, $session_id = null)
1327
    {
1328
        if (empty($course_code)) {
1329
            $course_code = api_get_course_id();
1330
        }
1331
        if (api_get_session_id()) {
1332
            $thematic_data = self::get_thematic_list($course_code);
1333
        } else {
1334
            $thematic_data = self::get_thematic_list($course_code, 0);
1335
        }
1336
1337
        $a_average_of_advances_by_thematic = [];
1338
        $total_average = 0;
1339
        if (!empty($thematic_data)) {
1340
            /** @var CThematic $thematic */
1341
            foreach ($thematic_data as $thematic) {
1342
                $thematic_id = $thematic->getIid();
1343
                $a_average_of_advances_by_thematic[$thematic_id] = $this->get_average_of_advances_by_thematic(
1344
                    $thematic,
1345
                    $course_code
1346
                );
1347
            }
1348
        }
1349
1350
        // calculate total average
1351
        if (!empty($a_average_of_advances_by_thematic)) {
1352
            $count_tematics = count($thematic_data);
1353
            $score = array_sum($a_average_of_advances_by_thematic);
1354
            $total_average = round(($score * 100) / ($count_tematics * 100));
1355
        }
1356
1357
        return $total_average;
1358
    }
1359
1360
    /**
1361
     * Get average of advances by thematic.
1362
     *
1363
     * @param CThematic $thematic
1364
     * @param string    $course_code
1365
     *
1366
     * @return float Average of thematic advances
1367
     */
1368
    public function get_average_of_advances_by_thematic($thematic, $course_code = null)
1369
    {
1370
        $advances = $thematic->getAdvances();
1371
        $average = 0;
1372
        if ($advances->count()) {
1373
            // get all done advances by thematic
1374
            $count = 0;
1375
            /** @var CThematicAdvance $thematic_advance */
1376
            foreach ($advances as $thematic_advance) {
1377
                if ($thematic_advance->getDoneAdvance()) {
1378
                    $count++;
1379
                }
1380
            }
1381
1382
            // calculate average by thematic
1383
            $average = round(($count * 100) / count($advances));
1384
        }
1385
1386
        return $average;
1387
    }
1388
1389
    /**
1390
     * set attributes for fields of thematic table.
1391
     *
1392
     * @param    int        Thematic id
1393
     * @param    string    Thematic title
1394
     * @param    string    Thematic content
1395
     * @param    int        Session id
1396
     */
1397
    public function set_thematic_attributes($id = null, $title = '', $content = '', $session_id = 0)
1398
    {
1399
        $this->thematic_id = $id;
1400
        $this->thematic_title = $title;
1401
        $this->thematic_content = $content;
1402
        $this->session_id = $session_id;
1403
    }
1404
1405
    /**
1406
     * set attributes for fields of thematic_plan table.
1407
     *
1408
     * @param    int        Thematic id
1409
     * @param    string    Thematic plan title
1410
     * @param    string    Thematic plan description
1411
     * @param    int        Thematic plan description type
1412
     */
1413
    public function set_thematic_plan_attributes(
1414
        $thematic_id = 0,
1415
        $title = '',
1416
        $description = '',
1417
        $description_type = 0
1418
    ) {
1419
        $this->thematic_id = $thematic_id;
1420
        $this->thematic_plan_title = $title;
1421
        $this->thematic_plan_description = $description;
1422
        $this->thematic_plan_description_type = $description_type;
1423
    }
1424
1425
    /**
1426
     * set attributes for fields of thematic_advance table.
1427
     *
1428
     * @param int $id Thematic advance id
1429
     * @param    int        Thematic id
1430
     * @param    int        Attendance id
1431
     * @param    string    Content
1432
     * @param    string    Date and time
1433
     * @param    int        Duration in hours
1434
     */
1435
    public function set_thematic_advance_attributes(
1436
        $id = null,
1437
        $thematic_id = 0,
1438
        $attendance_id = 0,
1439
        $content = '',
1440
        $start_date = null,
1441
        $duration = 0
1442
    ) {
1443
        $this->thematic_advance_id = $id;
1444
        $this->thematic_id = $thematic_id;
1445
        $this->attendance_id = $attendance_id;
1446
        $this->thematic_advance_content = $content;
1447
        $this->start_date = $start_date;
1448
        $this->duration = $duration;
1449
    }
1450
1451
    /**
1452
     * set thematic id.
1453
     *
1454
     * @param    int     Thematic id
1455
     */
1456
    public function set_thematic_id($thematic_id)
1457
    {
1458
        $this->thematic_id = $thematic_id;
1459
    }
1460
1461
    /**
1462
     * get thematic id.
1463
     *
1464
     * @return int
1465
     */
1466
    public function get_thematic_id()
1467
    {
1468
        return $this->thematic_id;
1469
    }
1470
1471
    /**
1472
     * Get thematic plan titles by default.
1473
     *
1474
     * @return array
1475
     */
1476
    public function get_default_thematic_plan_title()
1477
    {
1478
        $default_thematic_plan_titles = [];
1479
        $default_thematic_plan_titles[1] = get_lang('Objectives');
1480
        $default_thematic_plan_titles[2] = get_lang('Skills to acquire');
1481
        $default_thematic_plan_titles[3] = get_lang('Methodology');
1482
        $default_thematic_plan_titles[4] = get_lang('Infrastructure');
1483
        $default_thematic_plan_titles[5] = get_lang('Assessment');
1484
        $default_thematic_plan_titles[6] = get_lang('Others');
1485
1486
        return $default_thematic_plan_titles;
1487
    }
1488
1489
    /**
1490
     * Get thematic plan icons by default.
1491
     *
1492
     * @return array
1493
     */
1494
    public function get_default_thematic_plan_icon()
1495
    {
1496
        $default_thematic_plan_icon = [];
1497
        $default_thematic_plan_icon[1] = 'icons/32/objective.png';
1498
        $default_thematic_plan_icon[2] = 'icons/32/skills.png';
1499
        $default_thematic_plan_icon[3] = 'icons/32/strategy.png';
1500
        $default_thematic_plan_icon[4] = 'icons/32/laptop.png';
1501
        $default_thematic_plan_icon[5] = 'icons/32/assessment.png';
1502
        $default_thematic_plan_icon[6] = 'icons/32/wizard.png';
1503
1504
        return $default_thematic_plan_icon;
1505
    }
1506
1507
    /**
1508
     * Get questions by default for help.
1509
     *
1510
     * @return array
1511
     */
1512
    public function get_default_question()
1513
    {
1514
        $question = [];
1515
        $question[1] = get_lang('What should the end results be when the learner has completed the course? What are the activities performed during the course?');
1516
        $question[2] = get_lang('Skills to acquireQuestions');
1517
        $question[3] = get_lang('What methods and activities help achieve the objectives of the course?  What would the schedule be?');
1518
        $question[4] = get_lang('What infrastructure is necessary to achieve the goals of this topic normally?');
1519
        $question[5] = get_lang('How will learners be assessed? Are there strategies to develop in order to master the topic?');
1520
1521
        return $question;
1522
    }
1523
}
1524