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

main/inc/lib/link.lib.php (2 issues)

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CourseBundle\Entity\CLink;
6
7
/**
8
 * Function library for the links tool.
9
 *
10
 * This is a complete remake of the original link tool.
11
 * New features:
12
 * - Organize links into categories;
13
 * - favorites/bookmarks interface;
14
 * - move links up/down within a category;
15
 * - move categories up/down;
16
 * - expand/collapse all categories;
17
 * - add link to 'root' category => category-less link is always visible.
18
 *
19
 * @author Patrick Cool, complete remake (December 2003 - January 2004)
20
 * @author René Haentjens, CSV file import (October 2004)
21
 */
22
class Link extends Model
23
{
24
    public $table;
25
    public $is_course_model = true;
26
    public $columns = [
27
        'id',
28
        'c_id',
29
        'url',
30
        'title',
31
        'description',
32
        'category_id',
33
        'display_order',
34
        'on_homepage',
35
        'target',
36
        'session_id',
37
    ];
38
    public $required = ['url', 'title'];
39
    private $course;
40
41
    /**
42
     * Link constructor.
43
     */
44
    public function __construct()
45
    {
46
        $this->table = Database::get_course_table(TABLE_LINK);
47
    }
48
49
    /**
50
     * @param array $course
51
     */
52
    public function setCourse($course)
53
    {
54
        $this->course = $course;
55
    }
56
57
    /**
58
     * @return array
59
     */
60
    public function getCourse()
61
    {
62
        return !empty($this->course) ? $this->course : api_get_course_info();
63
    }
64
65
    /**
66
     * Organize the saving of a link, using the parent's save method and
67
     * updating the item_property table.
68
     *
69
     * @param array $params
70
     * @param bool  $show_query Whether to show the query in logs when
71
     *                          calling parent's save method
72
     *
73
     * @return bool True if link could be saved, false otherwise
74
     */
75
    public function save($params, $show_query = null)
76
    {
77
        $course_info = $this->getCourse();
78
        $courseId = $course_info['real_id'];
79
80
        $params['session_id'] = api_get_session_id();
81
        $params['category_id'] = isset($params['category_id']) ? $params['category_id'] : 0;
82
83
        $sql = "SELECT MAX(display_order)
84
                FROM  ".$this->table."
85
                WHERE
86
                    c_id = $courseId AND
87
                    category_id = '".intval($params['category_id'])."'";
88
        $result = Database:: query($sql);
89
        list($orderMax) = Database:: fetch_row($result);
90
        $order = $orderMax + 1;
91
        $params['display_order'] = $order;
92
93
        $id = parent::save($params, $show_query);
94
95
        if (!empty($id)) {
96
            // iid
97
            $sql = "UPDATE ".$this->table." SET id = iid WHERE iid = $id";
98
            Database::query($sql);
99
100
            api_item_property_update(
101
                $course_info,
102
                TOOL_LINK,
103
                $id,
104
                'LinkAdded',
105
                api_get_user_id()
106
            );
107
108
            api_set_default_visibility($id, TOOL_LINK, 0, $course_info);
109
        }
110
111
        return $id;
112
    }
113
114
    /**
115
     * Update a link in the database.
116
     *
117
     * @param int    $linkId    The ID of the link to update
118
     * @param string $linkUrl   The new URL to be saved
119
     * @param int    $courseId
120
     * @param int    $sessionId
121
     *
122
     * @return bool
123
     */
124
    public function updateLink(
125
        $linkId,
126
        $linkUrl,
127
        $courseId = null,
128
        $sessionId = null
129
    ) {
130
        $tblLink = Database::get_course_table(TABLE_LINK);
131
        $linkUrl = Database::escape_string($linkUrl);
132
        $linkId = intval($linkId);
133
        if (is_null($courseId)) {
134
            $courseId = api_get_course_int_id();
135
        }
136
        $courseId = intval($courseId);
137
        if (is_null($sessionId)) {
138
            $sessionId = api_get_session_id();
139
        }
140
        $sessionId = intval($sessionId);
141
        if ($linkUrl != '') {
142
            $sql = "UPDATE $tblLink SET
143
                    url = '$linkUrl'
144
                    WHERE id = $linkId AND c_id = $courseId AND session_id = $sessionId";
145
            $resLink = Database::query($sql);
146
147
            return $resLink;
148
        }
149
150
        return false;
151
    }
152
153
    /**
154
     * Used to add a link or a category.
155
     *
156
     * @param string $type , "link" or "category"
157
     *
158
     * @todo replace strings by constants
159
     *
160
     * @author Patrick Cool <[email protected]>, Ghent University
161
     *
162
     * @return bool True on success, false on failure
163
     */
164
    public static function addlinkcategory($type)
165
    {
166
        $ok = true;
167
        $_course = api_get_course_info();
168
        $course_id = $_course['real_id'];
169
        $session_id = api_get_session_id();
170
171
        if ($type === 'link') {
172
            $title = $_POST['title'];
173
            $urllink = $_POST['url'];
174
            $description = $_POST['description'];
175
            $selectcategory = $_POST['category_id'];
176
177
            $onhomepage = 0;
178
            if (isset($_POST['on_homepage'])) {
179
                $onhomepage = $_POST['on_homepage'];
180
            }
181
182
            $target = '_self'; // Default target.
183
            if (!empty($_POST['target'])) {
184
                $target = $_POST['target'];
185
            }
186
187
            $urllink = trim($urllink);
188
            $title = trim($title);
189
            $description = trim($description);
190
191
            // We ensure URL to be absolute.
192
            if (strpos($urllink, '://') === false) {
193
                $urllink = 'http://'.$urllink;
194
            }
195
196
            // If the title is empty, we use the URL as title.
197
            if ($title == '') {
198
                $title = $urllink;
199
            }
200
201
            // If the URL is invalid, an error occurs.
202
            if (!api_valid_url($urllink, true)) {
203
                // A check against an absolute URL
204
                Display::addFlash(Display::return_message(get_lang('GiveURL'), 'error'));
205
206
                return false;
207
            } else {
208
                // Looking for the largest order number for this category.
209
                $link = new Link();
210
                $params = [
211
                    'c_id' => $course_id,
212
                    'url' => $urllink,
213
                    'title' => $title,
214
                    'description' => $description,
215
                    'category_id' => $selectcategory,
216
                    'on_homepage' => $onhomepage,
217
                    'target' => $target,
218
                    'session_id' => $session_id,
219
                ];
220
                $link_id = $link->save($params);
221
222
                if ((api_get_setting('search_enabled') === 'true') &&
223
                    $link_id && extension_loaded('xapian')
224
                ) {
225
                    require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
226
227
                    $course_int_id = $_course['real_id'];
228
                    $courseCode = $_course['code'];
229
                    $specific_fields = get_specific_field_list();
230
                    $ic_slide = new IndexableChunk();
231
232
                    // Add all terms to db.
233
                    $all_specific_terms = '';
234
                    foreach ($specific_fields as $specific_field) {
235
                        if (isset($_REQUEST[$specific_field['code']])) {
236
                            $sterms = trim($_REQUEST[$specific_field['code']]);
237
                            if (!empty($sterms)) {
238
                                $all_specific_terms .= ' '.$sterms;
239
                                $sterms = explode(',', $sterms);
240
                                foreach ($sterms as $sterm) {
241
                                    $ic_slide->addTerm(
242
                                        trim($sterm),
243
                                        $specific_field['code']
244
                                    );
245
                                    add_specific_field_value(
246
                                        $specific_field['id'],
247
                                        $courseCode,
248
                                        TOOL_LINK,
249
                                        $link_id,
250
                                        $sterm
251
                                    );
252
                                }
253
                            }
254
                        }
255
                    }
256
257
                    // Build the chunk to index.
258
                    $ic_slide->addValue('title', $title);
259
                    $ic_slide->addCourseId($courseCode);
260
                    $ic_slide->addToolId(TOOL_LINK);
261
                    $xapian_data = [
262
                        SE_COURSE_ID => $courseCode,
263
                        SE_TOOL_ID => TOOL_LINK,
264
                        SE_DATA => [
265
                            'link_id' => (int) $link_id,
266
                        ],
267
                        SE_USER => (int) api_get_user_id(),
268
                    ];
269
                    $ic_slide->xapian_data = serialize($xapian_data);
270
                    $description = $all_specific_terms.' '.$description;
271
                    $ic_slide->addValue('content', $description);
272
273
                    // Add category name if set.
274
                    if (isset($selectcategory) && $selectcategory > 0) {
275
                        $table_link_category = Database::get_course_table(
276
                            TABLE_LINK_CATEGORY
277
                        );
278
                        $sql_cat = 'SELECT * FROM %s WHERE id=%d AND c_id = %d LIMIT 1';
279
                        $sql_cat = sprintf(
280
                            $sql_cat,
281
                            $table_link_category,
282
                            (int) $selectcategory,
283
                            $course_int_id
284
                        );
285
                        $result = Database:: query($sql_cat);
286
                        if (Database:: num_rows($result) == 1) {
287
                            $row = Database:: fetch_array($result);
288
                            $ic_slide->addValue(
289
                                'category',
290
                                $row['category_title']
291
                            );
292
                        }
293
                    }
294
295
                    $di = new ChamiloIndexer();
296
                    isset($_POST['language']) ? $lang = Database:: escape_string(
297
                        $_POST['language']
298
                    ) : $lang = 'english';
299
                    $di->connectDb(null, null, $lang);
300
                    $di->addChunk($ic_slide);
301
302
                    // Index and return search engine document id.
303
                    $did = $di->index();
304
                    if ($did) {
305
                        // Save it to db.
306
                        $tbl_se_ref = Database::get_main_table(
307
                            TABLE_MAIN_SEARCH_ENGINE_REF
308
                        );
309
                        $sql = 'INSERT INTO %s (id, course_code, tool_id, ref_id_high_level, search_did)
310
                                VALUES (NULL , \'%s\', \'%s\', %s, %s)';
311
                        $sql = sprintf(
312
                            $sql,
313
                            $tbl_se_ref,
314
                            $course_int_id,
315
                            $courseCode,
316
                            TOOL_LINK,
317
                            $link_id,
318
                            $did
319
                        );
320
                        Database:: query($sql);
321
                    }
322
                }
323
                Display::addFlash(Display::return_message(get_lang('LinkAdded')));
324
325
                return $link_id;
326
            }
327
        } elseif ($type === 'category') {
328
            $tbl_categories = Database::get_course_table(TABLE_LINK_CATEGORY);
329
330
            $category_title = trim($_POST['category_title']);
331
            $description = trim($_POST['description']);
332
333
            if (empty($category_title)) {
334
                echo Display::return_message(get_lang('GiveCategoryName'), 'error');
335
                $ok = false;
336
            } else {
337
                // Looking for the largest order number for this category.
338
                $result = Database:: query(
339
                    "SELECT MAX(display_order) FROM  $tbl_categories
340
                    WHERE c_id = $course_id "
341
                );
342
                list($orderMax) = Database:: fetch_row($result);
343
                $order = $orderMax + 1;
344
                $order = intval($order);
345
                $session_id = api_get_session_id();
346
347
                $params = [
348
                    'c_id' => $course_id,
349
                    'category_title' => $category_title,
350
                    'description' => $description,
351
                    'display_order' => $order,
352
                    'session_id' => $session_id,
353
                ];
354
                $linkId = Database::insert($tbl_categories, $params);
355
356
                if ($linkId) {
357
                    // iid
358
                    $sql = "UPDATE $tbl_categories SET id = iid WHERE iid = $linkId";
359
                    Database:: query($sql);
360
361
                    // add link_category visibility
362
                    // course ID is taken from context in api_set_default_visibility
363
                    //api_set_default_visibility($linkId, TOOL_LINK_CATEGORY);
364
                    api_item_property_update(
365
                        $_course,
366
                        TOOL_LINK_CATEGORY,
367
                        $linkId,
368
                        'LinkCategoryAdded',
369
                        api_get_user_id()
370
                    );
371
                    api_set_default_visibility($linkId, TOOL_LINK_CATEGORY);
372
                }
373
374
                Display::addFlash(Display::return_message(get_lang('CategoryAdded')));
375
376
                return $linkId;
377
            }
378
        }
379
380
        return $ok;
381
    }
382
383
    /**
384
     * Used to delete a link or a category.
385
     *
386
     * @author Patrick Cool <[email protected]>, Ghent University
387
     *
388
     * @param int    $id
389
     * @param string $type The type of item to delete
390
     *
391
     * @return bool
392
     */
393
    public static function deletelinkcategory($id, $type)
394
    {
395
        $courseInfo = api_get_course_info();
396
        $tbl_link = Database::get_course_table(TABLE_LINK);
397
        $tbl_categories = Database::get_course_table(TABLE_LINK_CATEGORY);
398
399
        $course_id = $courseInfo['real_id'];
400
        $id = intval($id);
401
402
        if (empty($id)) {
403
            return false;
404
        }
405
406
        $result = false;
407
        switch ($type) {
408
            case 'link':
409
                // -> Items are no longer physically deleted,
410
                // but the visibility is set to 2 (in item_property).
411
                // This will make a restore function possible for the platform administrator.
412
                $sql = "UPDATE $tbl_link SET on_homepage='0'
413
                        WHERE c_id = $course_id AND id='".$id."'";
414
                Database:: query($sql);
415
416
                api_item_property_update(
417
                    $courseInfo,
418
                    TOOL_LINK,
419
                    $id,
420
                    'delete',
421
                    api_get_user_id()
422
                );
423
                self::delete_link_from_search_engine(api_get_course_id(), $id);
424
                Skill::deleteSkillsFromItem($id, ITEM_TYPE_LINK);
425
                Display::addFlash(Display::return_message(get_lang('LinkDeleted')));
426
                $result = true;
427
                break;
428
            case 'category':
429
                // First we delete the category itself and afterwards all the links of this category.
430
                $sql = "DELETE FROM ".$tbl_categories."
431
                        WHERE c_id = $course_id AND id='".$id."'";
432
                Database:: query($sql);
433
434
                $sql = "DELETE FROM ".$tbl_link."
435
                        WHERE c_id = $course_id AND category_id='".$id."'";
436
                Database:: query($sql);
437
438
                api_item_property_update(
439
                    $courseInfo,
440
                    TOOL_LINK_CATEGORY,
441
                    $id,
442
                    'delete',
443
                    api_get_user_id()
444
                );
445
446
                Display::addFlash(Display::return_message(get_lang('CategoryDeleted')));
447
                $result = true;
448
                break;
449
        }
450
451
        return $result;
452
    }
453
454
    /**
455
     * Removes a link from search engine database.
456
     *
457
     * @param string $course_id Course code
458
     * @param int    $link_id   Document id to delete
459
     */
460
    public static function delete_link_from_search_engine($course_id, $link_id)
461
    {
462
        // Remove from search engine if enabled.
463
        if (api_get_setting('search_enabled') === 'true') {
464
            $tbl_se_ref = Database::get_main_table(
465
                TABLE_MAIN_SEARCH_ENGINE_REF
466
            );
467
            $sql = 'SELECT * FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
468
            $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_LINK, $link_id);
469
            $res = Database:: query($sql);
470
            if (Database:: num_rows($res) > 0) {
471
                $row = Database::fetch_array($res);
472
                $di = new ChamiloIndexer();
473
                $di->remove_document($row['search_did']);
474
            }
475
            $sql = 'DELETE FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
476
            $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_LINK, $link_id);
477
            Database:: query($sql);
478
479
            // Remove terms from db.
480
            require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
481
            delete_all_values_for_item($course_id, TOOL_DOCUMENT, $link_id);
482
        }
483
    }
484
485
    /**
486
     * Get link info.
487
     *
488
     * @param int $id
489
     *
490
     * @return array link info
491
     */
492
    public static function getLinkInfo($id)
493
    {
494
        $tbl_link = Database::get_course_table(TABLE_LINK);
495
        $course_id = api_get_course_int_id();
496
497
        if (empty($id) || empty($course_id)) {
498
            return [];
499
        }
500
501
        $sql = "SELECT * FROM $tbl_link
502
                WHERE c_id = $course_id AND id='".(int) $id."' ";
503
        $result = Database::query($sql);
504
        $data = [];
505
        if (Database::num_rows($result)) {
506
            $data = Database::fetch_array($result);
507
        }
508
509
        return $data;
510
    }
511
512
    /**
513
     * @param int   $id
514
     * @param array $values
515
     */
516
    public static function editLink($id, $values = [])
517
    {
518
        $tbl_link = Database::get_course_table(TABLE_LINK);
519
        $_course = api_get_course_info();
520
        $course_id = $_course['real_id'];
521
        $id = (int) $id;
522
523
        $values['url'] = trim($values['url']);
524
        $values['title'] = trim($values['title']);
525
        $values['description'] = trim($values['description']);
526
        $values['target'] = empty($values['target']) ? '_self' : $values['target'];
527
        $values['on_homepage'] = isset($values['on_homepage']) ? $values['on_homepage'] : '';
528
529
        $categoryId = intval($values['category_id']);
530
531
        // We ensure URL to be absolute.
532
        if (strpos($values['url'], '://') === false) {
533
            $values['url'] = 'http://'.$_POST['url'];
534
        }
535
536
        // If the title is empty, we use the URL as title.
537
        if ($values['title'] == '') {
538
            $values['title'] = $values['url'];
539
        }
540
541
        // If the URL is invalid, an error occurs.
542
        if (!api_valid_url($values['url'], true)) {
543
            Display::addFlash(
544
                Display::return_message(get_lang('GiveURL'), 'error')
545
            );
546
547
            return false;
548
        }
549
550
        if (empty($id) || empty($course_id)) {
551
            return false;
552
        }
553
554
        // Finding the old category_id.
555
        $sql = "SELECT * FROM $tbl_link
556
                WHERE c_id = $course_id AND id='".$id."'";
557
        $result = Database:: query($sql);
558
        $row = Database:: fetch_array($result);
559
        $category_id = $row['category_id'];
560
561
        if ($category_id != $values['category_id']) {
562
            $sql = "SELECT MAX(display_order)
563
                    FROM $tbl_link
564
                    WHERE
565
                        c_id = $course_id AND
566
                        category_id='".intval($values['category_id'])."'";
567
            $result = Database:: query($sql);
568
            list($max_display_order) = Database:: fetch_row($result);
569
            $max_display_order++;
570
        } else {
571
            $max_display_order = $row['display_order'];
572
        }
573
        $params = [
574
            'url' => $values['url'],
575
            'title' => $values['title'],
576
            'description' => $values['description'],
577
            'category_id' => $values['category_id'],
578
            'display_order' => $max_display_order,
579
            'on_homepage' => $values['on_homepage'],
580
            'target' => $values['target'],
581
        ];
582
583
        Database::update(
584
            $tbl_link,
585
            $params,
586
            ['c_id = ? AND id = ?' => [$course_id, $id]]
587
        );
588
589
        // Update search enchine and its values table if enabled.
590
        if (api_get_setting('search_enabled') === 'true') {
591
            $course_int_id = api_get_course_int_id();
592
            $course_id = api_get_course_id();
593
            $link_title = Database:: escape_string($values['title']);
594
            $link_description = Database:: escape_string($values['description']);
595
596
            // Actually, it consists on delete terms from db,
597
            // insert new ones, create a new search engine document, and remove the old one.
598
            // Get search_did.
599
            $tbl_se_ref = Database::get_main_table(
600
                TABLE_MAIN_SEARCH_ENGINE_REF
601
            );
602
            $sql = 'SELECT * FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
603
            $sql = sprintf(
604
                $sql,
605
                $tbl_se_ref,
606
                $course_id,
607
                TOOL_LINK,
608
                $id
609
            );
610
            $res = Database:: query($sql);
611
612
            if (Database:: num_rows($res) > 0) {
613
                require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
614
615
                $se_ref = Database:: fetch_array($res);
616
                $specific_fields = get_specific_field_list();
617
                $ic_slide = new IndexableChunk();
618
619
                $all_specific_terms = '';
620
                foreach ($specific_fields as $specific_field) {
621
                    delete_all_specific_field_value(
622
                        $course_id,
623
                        $specific_field['id'],
624
                        TOOL_LINK,
625
                        $id
626
                    );
627
                    if (isset($_REQUEST[$specific_field['code']])) {
628
                        $sterms = trim(
629
                            $_REQUEST[$specific_field['code']]
630
                        );
631
                        if (!empty($sterms)) {
632
                            $all_specific_terms .= ' '.$sterms;
633
                            $sterms = explode(',', $sterms);
634
                            foreach ($sterms as $sterm) {
635
                                $ic_slide->addTerm(
636
                                    trim($sterm),
637
                                    $specific_field['code']
638
                                );
639
                                add_specific_field_value(
640
                                    $specific_field['id'],
641
                                    $course_id,
642
                                    TOOL_LINK,
643
                                    $id,
644
                                    $sterm
645
                                );
646
                            }
647
                        }
648
                    }
649
                }
650
651
                // Build the chunk to index.
652
                $ic_slide->addValue("title", $link_title);
653
                $ic_slide->addCourseId($course_id);
654
                $ic_slide->addToolId(TOOL_LINK);
655
                $xapian_data = [
656
                    SE_COURSE_ID => $course_id,
657
                    SE_TOOL_ID => TOOL_LINK,
658
                    SE_DATA => [
659
                        'link_id' => (int) $id,
660
                    ],
661
                    SE_USER => (int) api_get_user_id(),
662
                ];
663
                $ic_slide->xapian_data = serialize($xapian_data);
664
                $link_description = $all_specific_terms.' '.$link_description;
665
                $ic_slide->addValue('content', $link_description);
666
667
                // Add category name if set.
668
                if (isset($categoryId) && $categoryId > 0) {
669
                    $table_link_category = Database::get_course_table(
670
                        TABLE_LINK_CATEGORY
671
                    );
672
                    $sql_cat = 'SELECT * FROM %s WHERE id=%d and c_id = %d LIMIT 1';
673
                    $sql_cat = sprintf(
674
                        $sql_cat,
675
                        $table_link_category,
676
                        $categoryId,
677
                        $course_int_id
678
                    );
679
                    $result = Database:: query($sql_cat);
680
                    if (Database:: num_rows($result) == 1) {
681
                        $row = Database:: fetch_array($result);
682
                        $ic_slide->addValue(
683
                            'category',
684
                            $row['category_title']
685
                        );
686
                    }
687
                }
688
689
                $di = new ChamiloIndexer();
690
                isset($_POST['language']) ? $lang = Database:: escape_string($_POST['language']) : $lang = 'english';
691
                $di->connectDb(null, null, $lang);
692
                $di->remove_document($se_ref['search_did']);
693
                $di->addChunk($ic_slide);
694
695
                // Index and return search engine document id.
696
                $did = $di->index();
697
                if ($did) {
698
                    // Save it to db.
699
                    $sql = 'DELETE FROM %s
700
                            WHERE course_code=\'%s\'
701
                            AND tool_id=\'%s\'
702
                            AND ref_id_high_level=\'%s\'';
703
                    $sql = sprintf(
704
                        $sql,
705
                        $tbl_se_ref,
706
                        $course_id,
707
                        TOOL_LINK,
708
                        $id
709
                    );
710
                    Database:: query($sql);
711
                    $sql = 'INSERT INTO %s (c_id, id, course_code, tool_id, ref_id_high_level, search_did)
712
                            VALUES (NULL , \'%s\', \'%s\', %s, %s)';
713
                    $sql = sprintf(
714
                        $sql,
715
                        $tbl_se_ref,
716
                        $course_int_id,
717
                        $course_id,
718
                        TOOL_LINK,
719
                        $id,
720
                        $did
721
                    );
722
                    Database:: query($sql);
723
                }
724
            }
725
        }
726
727
        // "WHAT'S NEW" notification: update table last_toolEdit.
728
        api_item_property_update(
729
            $_course,
730
            TOOL_LINK,
731
            $id,
732
            'LinkUpdated',
733
            api_get_user_id()
734
        );
735
        Display::addFlash(Display::return_message(get_lang('LinkModded')));
736
    }
737
738
    /**
739
     * @param int   $id
740
     * @param array $values
741
     *
742
     * @return bool
743
     */
744
    public static function editCategory($id, $values)
745
    {
746
        $table = Database::get_course_table(TABLE_LINK_CATEGORY);
747
        $course_id = api_get_course_int_id();
748
        $id = intval($id);
749
750
        // This is used to put the modified info of the category-form into the database.
751
        $params = [
752
            'category_title' => $values['category_title'],
753
            'description' => $values['description'],
754
        ];
755
        Database::update(
756
            $table,
757
            $params,
758
            ['c_id = ? AND id = ?' => [$course_id, $id]]
759
        );
760
        Display::addFlash(Display::return_message(get_lang('CategoryModded')));
761
762
        return true;
763
    }
764
765
    /**
766
     * Changes the visibility of a link.
767
     *
768
     * @todo add the changing of the visibility of a course
769
     *
770
     * @author Patrick Cool <[email protected]>, Ghent University
771
     */
772
    public static function change_visibility_link($id, $scope)
773
    {
774
        $_course = api_get_course_info();
775
        $_user = api_get_user_info();
776
        if ($scope == TOOL_LINK) {
777
            api_item_property_update(
778
                $_course,
779
                TOOL_LINK,
780
                $id,
781
                $_GET['action'],
782
                $_user['user_id']
783
            );
784
            Display::addFlash(Display::return_message(get_lang('VisibilityChanged')));
785
        } elseif ($scope == TOOL_LINK_CATEGORY) {
786
            api_item_property_update(
787
                $_course,
788
                TOOL_LINK_CATEGORY,
789
                $id,
790
                $_GET['action'],
791
                $_user['user_id']
792
            );
793
            Display::addFlash(Display::return_message(get_lang('VisibilityChanged')));
794
        }
795
    }
796
797
    /**
798
     * Generate SQL to select all the links categories in the current course and
799
     * session.
800
     *
801
     * @param int  $courseId
802
     * @param int  $sessionId
803
     * @param bool $withBaseContent
804
     *
805
     * @return array
806
     */
807
    public static function getLinkCategories($courseId, $sessionId, $withBaseContent = true)
808
    {
809
        $tblLinkCategory = Database::get_course_table(TABLE_LINK_CATEGORY);
810
        $tblItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
811
        $courseId = intval($courseId);
812
        $courseInfo = api_get_course_info_by_id($courseId);
813
814
        // Condition for the session.
815
        $sessionCondition = api_get_session_condition(
816
            $sessionId,
817
            true,
818
            $withBaseContent,
819
            'linkcat.session_id'
820
        );
821
822
        // Getting links
823
        $sql = "SELECT *, linkcat.id
824
                FROM $tblLinkCategory linkcat
825
                WHERE
826
                    linkcat.c_id = $courseId
827
                    $sessionCondition
828
                ORDER BY linkcat.display_order DESC";
829
830
        $result = Database::query($sql);
831
        $categories = Database::store_result($result);
832
833
        $sql = "SELECT *, linkcat.id
834
                FROM $tblLinkCategory linkcat
835
                INNER JOIN $tblItemProperty ip
836
                ON (linkcat.id = ip.ref AND linkcat.c_id = ip.c_id)
837
                WHERE
838
                    ip.tool = '".TOOL_LINK_CATEGORY."' AND
839
                    (ip.visibility = '0' OR ip.visibility = '1')
840
                    $sessionCondition AND
841
                    linkcat.c_id = ".$courseId."
842
                ORDER BY linkcat.display_order DESC";
843
844
        $result = Database::query($sql);
845
846
        $categoryInItemProperty = [];
847
        if (Database::num_rows($result)) {
848
            while ($row = Database::fetch_array($result, 'ASSOC')) {
849
                $categoryInItemProperty[$row['id']] = $row;
850
            }
851
        }
852
853
        foreach ($categories as &$category) {
854
            if (!isset($categoryInItemProperty[$category['id']])) {
855
                api_item_property_update(
856
                    $courseInfo,
857
                    TOOL_LINK_CATEGORY,
858
                    $category['id'],
859
                    'LinkCategoryAdded',
860
                    api_get_user_id()
861
                );
862
            }
863
        }
864
865
        $sql = "SELECT DISTINCT linkcat.*, visibility
866
                FROM $tblLinkCategory linkcat
867
                INNER JOIN $tblItemProperty ip
868
                ON (linkcat.id = ip.ref AND linkcat.c_id = ip.c_id)
869
                WHERE
870
                    ip.tool = '".TOOL_LINK_CATEGORY."' AND
871
                    (ip.visibility = '0' OR ip.visibility = '1')
872
                    $sessionCondition AND
873
                    linkcat.c_id = ".$courseId."
874
                ORDER BY linkcat.display_order DESC
875
                ";
876
        $result = Database::query($sql);
877
878
        return Database::store_result($result, 'ASSOC');
879
    }
880
881
    /**
882
     * @param int $categoryId
883
     * @param $courseId
884
     * @param $sessionId
885
     * @param bool $withBaseContent
886
     *
887
     * @return array
888
     */
889
    public static function getLinksPerCategory(
890
        $categoryId,
891
        $courseId,
892
        $sessionId,
893
        $withBaseContent = true
894
    ) {
895
        $tbl_link = Database::get_course_table(TABLE_LINK);
896
        $TABLE_ITEM_PROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY);
897
        $courseId = (int) $courseId;
898
        $sessionId = (int) $sessionId;
899
        $categoryId = (int) $categoryId;
900
901
        // Condition for the session.
902
        $condition_session = api_get_session_condition(
903
            $sessionId,
904
            true,
905
            false,
906
            'ip.session_id'
907
        );
908
909
        if (!empty($sessionId)) {
910
            $conditionBaseSession = api_get_session_condition(
911
                0,
912
                true,
913
                $withBaseContent,
914
                'ip.session_id'
915
            );
916
            $condition = " AND
917
                (
918
                    (ip.visibility = '1' $conditionBaseSession) OR
919
920
                    (
921
                        (ip.visibility = '0' OR ip.visibility = '1')
922
                        $condition_session
923
                    )
924
                )
925
            ";
926
        } else {
927
            $condition = api_get_session_condition(
928
                0,
929
                true,
930
                false,
931
                'ip.session_id'
932
            );
933
            $condition .= " AND (ip.visibility = '0' OR ip.visibility = '1') $condition ";
934
        }
935
936
        $sql = "SELECT
937
                    link.id,
938
                    ip.session_id,
939
                    link.session_id link_session_id,
940
                    url,
941
                    category_id,
942
                    visibility,
943
                    description,
944
                    title,
945
                    target,
946
                    on_homepage
947
                FROM $tbl_link link
948
                INNER JOIN $TABLE_ITEM_PROPERTY ip
949
                ON (link.id = ip.ref AND link.c_id = ip.c_id)
950
                WHERE
951
                    ip.tool = '".TOOL_LINK."' AND
952
                    link.category_id = '".$categoryId."' AND
953
                    link.c_id = $courseId AND
954
                    ip.c_id = $courseId
955
                    $condition
956
                ORDER BY link.display_order ASC, ip.session_id DESC";
957
958
        $result = Database:: query($sql);
959
960
        return Database::store_result($result);
961
    }
962
963
    /**
964
     * Displays all the links of a given category.
965
     *
966
     * @param int  $catid
967
     * @param int  $courseId
968
     * @param int  $session_id
969
     * @param bool $showActionLinks
970
     *
971
     * @return string
972
     *
973
     * @author Julio Montoya
974
     * @author Patrick Cool <[email protected]>, Ghent University
975
     */
976
    public static function showLinksPerCategory($catid, $courseId, $session_id, $showActionLinks = true)
977
    {
978
        global $token;
979
        $_user = api_get_user_info();
980
        $catid = (int) $catid;
981
982
        $links = self::getLinksPerCategory($catid, $courseId, $session_id);
983
        $content = '';
984
        $numberOfLinks = count($links);
985
986
        if (!empty($links)) {
987
            $content .= '<div class="link list-group">';
988
            $i = 1;
989
            $linksAdded = [];
990
            foreach ($links as $myrow) {
991
                $linkId = $myrow['id'];
992
                $linkUrl = Security::remove_XSS($myrow['url']);
993
994
                if (in_array($linkId, $linksAdded)) {
995
                    continue;
996
                }
997
998
                $linksAdded[] = $linkId;
999
                $categoryId = $myrow['category_id'];
1000
1001
                // Validation when belongs to a session.
1002
                $session_img = api_get_session_image($myrow['link_session_id'], $_user['status']);
1003
1004
                $toolbar = '';
1005
                $link_validator = '';
1006
                if (api_is_allowed_to_edit(null, true)) {
1007
                    $toolbar .= Display::toolbarButton(
1008
                        '',
1009
                        'javascript:void(0);',
1010
                        'check-circle-o',
1011
                        'default btn-sm',
1012
                        [
1013
                            'onclick' => "check_url('".$linkId."', '".addslashes($linkUrl)."');",
1014
                            'title' => get_lang('CheckURL'),
1015
                        ]
1016
                    );
1017
1018
                    $link_validator .= Display::span(
1019
                        '',
1020
                        [
1021
                        'id' => 'url_id_'.$linkId,
1022
                        'class' => 'check-link',
1023
                        ]
1024
                    );
1025
1026
                    if ($session_id == $myrow['link_session_id']) {
1027
                        $url = api_get_self().'?'.api_get_cidreq().'&action=editlink&id='.$linkId;
1028
                        $title = get_lang('Edit');
1029
                        $toolbar .= Display::toolbarButton(
1030
                            '',
1031
                            $url,
1032
                            'pencil',
1033
                            'default btn-sm',
1034
                            [
1035
                                'title' => $title,
1036
                            ]
1037
                        );
1038
                    }
1039
1040
                    $urlVisibility = api_get_self().'?'.api_get_cidreq().
1041
                            '&sec_token='.$token.
1042
                            '&id='.$linkId.
1043
                            '&scope=link&category_id='.$categoryId;
1044
1045
                    switch ($myrow['visibility']) {
1046
                        case '1':
1047
                            $urlVisibility .= '&action=invisible';
1048
                            $title = get_lang('MakeInvisible');
1049
                            $toolbar .= Display::toolbarButton(
1050
                                '',
1051
                                $urlVisibility,
1052
                                'eye',
1053
                                'default btn-sm',
1054
                                [
1055
                                    'title' => $title,
1056
                                ]
1057
                            );
1058
                            break;
1059
                        case '0':
1060
                            $urlVisibility .= '&action=visible';
1061
                            $title = get_lang('MakeVisible');
1062
                            $toolbar .= Display::toolbarButton(
1063
                                '',
1064
                                $urlVisibility,
1065
                                'eye-slash',
1066
                                'primary btn-sm',
1067
                                [
1068
                                    'title' => $title,
1069
                                ]
1070
                            );
1071
                            break;
1072
                    }
1073
1074
                    if ($session_id == $myrow['link_session_id']) {
1075
                        $moveLinkParams = [
1076
                            'id' => $linkId,
1077
                            'scope' => 'category',
1078
                            'category_id' => $categoryId,
1079
                            'action' => 'move_link_up',
1080
                        ];
1081
1082
                        $toolbar .= Display::toolbarButton(
1083
                            get_lang('MoveUp'),
1084
                            api_get_self().'?'.api_get_cidreq().'&'.http_build_query($moveLinkParams),
1085
                            'level-up',
1086
                            'default',
1087
                            ['class' => 'btn-sm '.($i === 1 ? 'disabled' : '')],
1088
                            false
1089
                        );
1090
1091
                        $moveLinkParams['action'] = 'move_link_down';
1092
                        $toolbar .= Display::toolbarButton(
1093
                            get_lang('MoveDown'),
1094
                            api_get_self().'?'.api_get_cidreq().'&'.http_build_query($moveLinkParams),
1095
                            'level-down',
1096
                            'default',
1097
                            ['class' => 'btn-sm '.($i === $numberOfLinks ? 'disabled' : '')],
1098
                            false
1099
                        );
1100
1101
                        $url = api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=deletelink&id='.$linkId.'&category_id='.$categoryId;
1102
                        $event = "javascript: if(!confirm('".get_lang('LinkDelconfirm')."'))return false;";
1103
                        $title = get_lang('Delete');
1104
1105
                        $toolbar .= Display::toolbarButton(
1106
                            '',
1107
                            $url,
1108
                            'trash',
1109
                            'default btn-sm',
1110
                            [
1111
                                'onclick' => $event,
1112
                                'title' => $title,
1113
                            ]
1114
                        );
1115
                    }
1116
                }
1117
1118
                $showLink = false;
1119
                $titleClass = '';
1120
                if ($myrow['visibility'] == '1') {
1121
                    $showLink = true;
1122
                } else {
1123
                    if (api_is_allowed_to_edit(null, true)) {
1124
                        $showLink = true;
1125
                        $titleClass = 'text-muted';
1126
                    }
1127
                }
1128
1129
                if ($showLink) {
1130
                    $iconLink = Display::return_icon(
1131
                        'url.png',
1132
                        get_lang('Link'),
1133
                        null,
1134
                        ICON_SIZE_SMALL
1135
                    );
1136
                    $url = api_get_path(WEB_CODE_PATH).'link/link_goto.php?'.api_get_cidreq().'&link_id='.$linkId;
1137
                    $content .= '<div class="list-group-item">';
1138
                    if ($showActionLinks) {
1139
                        $content .= '<div class="pull-right"><div class="btn-group">'.$toolbar.'</div></div>';
1140
                    }
1141
                    $content .= '<h4 class="list-group-item-heading">';
1142
                    $content .= $iconLink;
1143
                    $content .= Display::tag(
1144
                        'a',
1145
                        Security::remove_XSS($myrow['title']),
1146
                        [
1147
                            'href' => $url,
1148
                            'target' => Security::remove_XSS($myrow['target']),
1149
                            'class' => $titleClass,
1150
                        ]
1151
                    );
1152
                    $content .= $link_validator;
1153
                    $content .= $session_img;
1154
                    $content .= '</h4>';
1155
                    $content .= '<p class="list-group-item-text">'.Security::remove_XSS($myrow['description']).'</p>';
1156
                    $content .= '</div>';
1157
                }
1158
                $i++;
1159
            }
1160
            $content .= '</div>';
1161
        }
1162
1163
        return $content;
1164
    }
1165
1166
    /**
1167
     * Displays the edit, delete and move icons.
1168
     *
1169
     * @param int   Category ID
1170
     * @param int $currentCategory
1171
     * @param int $countCategories
1172
     *
1173
     * @return string
1174
     *
1175
     * @author Patrick Cool <[email protected]>, Ghent University
1176
     */
1177
    public static function showCategoryAdminTools($category, $currentCategory, $countCategories)
1178
    {
1179
        $categoryId = $category['id'];
1180
        $token = null;
1181
        $tools = '<a href="'.api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=editcategory&id='.$categoryId.'&category_id='.$categoryId.'" title='.get_lang('Modify').'">'.
1182
            Display:: return_icon(
1183
                'edit.png',
1184
                get_lang('Modify'),
1185
                [],
1186
                ICON_SIZE_SMALL
1187
            ).'</a>';
1188
1189
        // DISPLAY MOVE UP COMMAND only if it is not the top link.
1190
        if ($currentCategory != 0) {
1191
            $tools .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=up&up='.$categoryId.'&category_id='.$categoryId.'" title="'.get_lang('Up').'">'.
1192
                Display:: return_icon(
1193
                    'up.png',
1194
                    get_lang('Up'),
1195
                    [],
1196
                    ICON_SIZE_SMALL
1197
                ).'</a>';
1198
        } else {
1199
            $tools .= Display:: return_icon(
1200
                'up_na.png',
1201
                get_lang('Up'),
1202
                [],
1203
                ICON_SIZE_SMALL
1204
            ).'</a>';
1205
        }
1206
1207
        // DISPLAY MOVE DOWN COMMAND only if it is not the bottom link.
1208
        if ($currentCategory < $countCategories - 1) {
1209
            $tools .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=down&down='.$categoryId.'&category_id='.$categoryId.'">'.
1210
                Display:: return_icon(
1211
                    'down.png',
1212
                    get_lang('Down'),
1213
                    [],
1214
                    ICON_SIZE_SMALL
1215
                ).'</a>';
1216
        } else {
1217
            $tools .= Display:: return_icon(
1218
                'down_na.png',
1219
                get_lang('Down'),
1220
                [],
1221
                ICON_SIZE_SMALL
1222
            ).'</a>';
1223
        }
1224
1225
        $tools .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=deletecategory&id='.$categoryId."&category_id=$categoryId\"
1226
            onclick=\"javascript: if(!confirm('".get_lang('CategoryDelconfirm')."')) return false;\">".
1227
            Display:: return_icon(
1228
                'delete.png',
1229
                get_lang('Delete'),
1230
                [],
1231
                ICON_SIZE_SMALL
1232
            ).'</a>';
1233
1234
        return $tools;
1235
    }
1236
1237
    /**
1238
     * move a link or a linkcategory up or down.
1239
     *
1240
     * @param   int Category ID
1241
     * @param   int Course ID
1242
     * @param   int Session ID
1243
     *
1244
     * @author Patrick Cool <[email protected]>, Ghent University
1245
     *
1246
     * @todo support sessions
1247
     */
1248
    public static function movecatlink($action, $catlinkid, $courseId = null, $sessionId = null)
1249
    {
1250
        $tbl_categories = Database::get_course_table(TABLE_LINK_CATEGORY);
1251
1252
        if (is_null($courseId)) {
1253
            $courseId = api_get_course_int_id();
1254
        }
1255
        $courseId = intval($courseId);
1256
        if (is_null($sessionId)) {
1257
            $sessionId = api_get_session_id();
1258
        }
1259
        $sessionId = intval($sessionId);
1260
        $thiscatlinkId = intval($catlinkid);
1261
1262
        if ($action === 'down') {
1263
            $sortDirection = 'DESC';
1264
        }
1265
1266
        if ($action === 'up') {
1267
            $sortDirection = 'ASC';
1268
        }
1269
1270
        $movetable = $tbl_categories;
1271
1272
        if (!empty($sortDirection)) {
1273
            if (!in_array(trim(strtoupper($sortDirection)), ['ASC', 'DESC'])) {
1274
                $sortDirection = 'ASC';
1275
            }
1276
1277
            $sql = "SELECT id, display_order FROM $movetable
1278
                    WHERE c_id = $courseId
1279
                    ORDER BY display_order $sortDirection";
1280
            $linkresult = Database:: query($sql);
1281
            $thislinkOrder = 1;
1282
            while ($sortrow = Database:: fetch_array($linkresult)) {
1283
                // STEP 2 : FOUND THE NEXT LINK ID AND ORDER, COMMIT SWAP
1284
                // This part seems unlogic, but it isn't . We first look for the current link with the querystring ID
1285
                // and we know the next iteration of the while loop is the next one. These should be swapped.
1286
                if (isset($thislinkFound) && $thislinkFound) {
1287
                    $nextlinkId = $sortrow['id'];
1288
                    $nextlinkOrder = $sortrow['display_order'];
1289
1290
                    Database:: query(
1291
                        "UPDATE ".$movetable."
1292
                        SET display_order = '$nextlinkOrder'
1293
                        WHERE c_id = $courseId  AND id =  '$thiscatlinkId'"
1294
                    );
1295
                    Database:: query(
1296
                        "UPDATE ".$movetable."
1297
                        SET display_order = '$thislinkOrder'
1298
                        WHERE c_id = $courseId  AND id =  '$nextlinkId'"
1299
                    );
1300
1301
                    break;
1302
                }
1303
                if ($sortrow['id'] == $thiscatlinkId) {
1304
                    $thislinkOrder = $sortrow['display_order'];
1305
                    $thislinkFound = true;
1306
                }
1307
            }
1308
        }
1309
1310
        Display::addFlash(Display::return_message(get_lang('LinkMoved')));
1311
    }
1312
1313
    /**
1314
     * This function checks if the url is a vimeo link.
1315
     *
1316
     * @author Julio Montoya
1317
     *
1318
     * @version 1.0
1319
     */
1320
    public static function isVimeoLink($url)
1321
    {
1322
        $isLink = strrpos($url, 'vimeo.com');
1323
1324
        return $isLink;
1325
    }
1326
1327
    /**
1328
     * Get vimeo id from URL.
1329
     *
1330
     * @param string $url
1331
     *
1332
     * @return bool|mixed
1333
     */
1334
    public static function getVimeoLinkId($url)
1335
    {
1336
        $possibleUrls = [
1337
            'http://www.vimeo.com/',
1338
            'http://vimeo.com/',
1339
            'https://www.vimeo.com/',
1340
            'https://vimeo.com/',
1341
        ];
1342
        $url = str_replace($possibleUrls, '', $url);
1343
1344
        if (is_numeric($url)) {
1345
            return $url;
1346
        }
1347
1348
        return false;
1349
    }
1350
1351
    /**
1352
     * This function checks if the url is a youtube link.
1353
     *
1354
     * @author Jorge Frisancho
1355
     * @author Julio Montoya - Fixing code
1356
     *
1357
     * @version 1.0
1358
     */
1359
    public static function is_youtube_link($url)
1360
    {
1361
        $is_youtube_link = strrpos($url, 'youtube') || strrpos(
1362
            $url,
1363
            'youtu.be'
1364
        );
1365
1366
        return $is_youtube_link;
1367
    }
1368
1369
    /**
1370
     * This function checks if the url is a PDF File link.
1371
     *
1372
     * @author Jorge Frisancho
1373
     * @author Alex Aragón - Fixing code
1374
     *
1375
     * @version 1.0
1376
     */
1377
    public static function isPdfLink($url)
1378
    {
1379
        $isPdfLink = strrpos(strtolower($url), '.pdf');
1380
1381
        return $isPdfLink;
1382
    }
1383
1384
    /**
1385
     * Get youtube id from an URL.
1386
     *
1387
     * @param string $url
1388
     *
1389
     * @return string
1390
     */
1391
    public static function get_youtube_video_id($url)
1392
    {
1393
        // This is the length of YouTube's video IDs
1394
        $len = 11;
1395
1396
        // The ID string starts after "v=", which is usually right after
1397
        // "youtube.com/watch?" in the URL
1398
        $pos = strpos($url, "v=");
1399
        $id = '';
1400
1401
        //If false try other options
1402
        if ($pos === false) {
1403
            $url_parsed = parse_url($url);
1404
1405
            //Youtube shortener
1406
            //http://youtu.be/ID
1407
            $pos = strpos($url, "youtu.be");
1408
1409
            if ($pos == false) {
1410
                $id = '';
1411
            } else {
1412
                return substr($url_parsed['path'], 1);
1413
            }
1414
1415
            //if empty try the youtube.com/embed/ID
1416
            if (empty($id)) {
1417
                $pos = strpos($url, "embed");
1418
                if ($pos === false) {
1419
                    return '';
1420
                } else {
1421
                    return substr($url_parsed['path'], 7);
1422
                }
1423
            }
1424
        } else {
1425
            // Offset the start location to match the beginning of the ID string
1426
            $pos += 2;
1427
            // Get the ID string and return it
1428
            $id = substr($url, $pos, $len);
1429
1430
            return $id;
1431
        }
1432
    }
1433
1434
    /**
1435
     * @param int    $course_id
1436
     * @param int    $session_id
1437
     * @param int    $categoryId
1438
     * @param string $show
1439
     * @param null   $token
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $token is correct as it would always require null to be passed?
Loading history...
1440
     * @param bool   $showActionLinks
1441
     * @param bool   $forceOpenCategories
1442
     *
1443
     * @return string
1444
     */
1445
    public static function listLinksAndCategories(
1446
        $course_id,
1447
        $session_id,
1448
        $categoryId,
1449
        $show = 'none',
1450
        $token = null,
1451
        $showActionLinks = true,
1452
        $forceOpenCategories = false
1453
    ) {
1454
        $categoryId = (int) $categoryId;
1455
        $content = '';
1456
        $categories = self::getLinkCategories($course_id, $session_id);
1457
        $countCategories = count($categories);
1458
        $linksPerCategory = self::showLinksPerCategory(0, $course_id, $session_id, $showActionLinks);
1459
1460
        if ($showActionLinks) {
1461
            /*	Action Links */
1462
            $content = '<div class="actions">';
1463
            if (api_is_allowed_to_edit(null, true)) {
1464
                $content .= '<a href="'.api_get_self().'?'.api_get_cidreq(
1465
                    ).'&action=addlink&category_id='.$categoryId.'">'.
1466
                    Display::return_icon('new_link.png', get_lang('LinkAdd'), '', ICON_SIZE_MEDIUM).'</a>';
1467
                $content .= '<a href="'.api_get_self().'?'.api_get_cidreq(
1468
                    ).'&action=addcategory&category_id='.$categoryId.'">'.
1469
                    Display::return_icon('new_folder.png', get_lang('CategoryAdd'), '', ICON_SIZE_MEDIUM).'</a>';
1470
            }
1471
1472
            if (!empty($countCategories)) {
1473
                $content .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=list&show=none">';
1474
                $content .= Display::return_icon(
1475
                        'forum_listview.png',
1476
                        get_lang('FlatView'),
1477
                        '',
1478
                        ICON_SIZE_MEDIUM
1479
                    ).' </a>';
1480
1481
                $content .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=list&show=all">';
1482
                $content .= Display::return_icon(
1483
                        'forum_nestedview.png',
1484
                        get_lang('NestedView'),
1485
                        '',
1486
                        ICON_SIZE_MEDIUM
1487
                    ).'</a>';
1488
            }
1489
1490
            $content .= Display::url(
1491
                Display::return_icon('pdf.png', get_lang('ExportToPdf'), '', ICON_SIZE_MEDIUM),
1492
                api_get_self().'?'.api_get_cidreq().'&action=export'
1493
            );
1494
            $content .= '</div>';
1495
        }
1496
1497
        if (empty($countCategories)) {
1498
            $content .= $linksPerCategory;
1499
        } else {
1500
            if (!empty($linksPerCategory)) {
1501
                $content .= Display::panel($linksPerCategory, get_lang('NoCategory'));
1502
            }
1503
        }
1504
1505
        $counter = 0;
1506
        foreach ($categories as $myrow) {
1507
            // Student don't see invisible categories.
1508
            if (!api_is_allowed_to_edit(null, true)) {
1509
                if ($myrow['visibility'] == 0) {
1510
                    continue;
1511
                }
1512
            }
1513
1514
            // Validation when belongs to a session
1515
            $showChildren = $categoryId == $myrow['id'] || $show === 'all';
1516
            if ($forceOpenCategories) {
1517
                $showChildren = true;
1518
            }
1519
1520
            $strVisibility = '';
1521
            $visibilityClass = null;
1522
            if ($myrow['visibility'] == '1') {
1523
                $strVisibility = '<a href="link.php?'.api_get_cidreq().'&sec_token='.$token.'&action=invisible&id='.$myrow['id'].'&scope='.TOOL_LINK_CATEGORY.'" title="'.get_lang('Hide').'">'.
1524
                    Display::return_icon('visible.png', get_lang('Hide'), [], ICON_SIZE_SMALL).'</a>';
1525
            } elseif ($myrow['visibility'] == '0') {
1526
                $visibilityClass = 'text-muted';
1527
                $strVisibility = ' <a href="link.php?'.api_get_cidreq().'&sec_token='.$token.'&action=visible&id='.$myrow['id'].'&scope='.TOOL_LINK_CATEGORY.'" title="'.get_lang('Show').'">'.
1528
                    Display::return_icon('invisible.png', get_lang('Show'), [], ICON_SIZE_SMALL).'</a>';
1529
            }
1530
1531
            $header = '';
1532
            if ($showChildren) {
1533
                $header .= '<a class="'.$visibilityClass.'" href="'.api_get_self().'?'.api_get_cidreq().'&category_id=">';
1534
                $header .= Display::return_icon('forum_nestedview.png');
1535
            } else {
1536
                $header .= '<a class="'.$visibilityClass.'" href="'.api_get_self().'?'.api_get_cidreq().'&category_id='.$myrow['id'].'">';
1537
                $header .= Display::return_icon('forum_listview.png');
1538
            }
1539
            $header .= Security::remove_XSS($myrow['category_title']).'</a>';
1540
1541
            if ($showActionLinks) {
1542
                if (api_is_allowed_to_edit(null, true)) {
1543
                    if ($session_id == $myrow['session_id']) {
1544
                        $header .= $strVisibility;
1545
                        $header .= self::showCategoryAdminTools($myrow, $counter, count($categories));
1546
                    } else {
1547
                        $header .= get_lang('EditionNotAvailableFromSession');
1548
                    }
1549
                }
1550
            }
1551
1552
            $childrenContent = '';
1553
            if ($showChildren) {
1554
                $childrenContent = self::showLinksPerCategory(
1555
                    $myrow['id'],
1556
                    api_get_course_int_id(),
1557
                    api_get_session_id()
1558
                );
1559
            }
1560
1561
            $content .= Display::panel(Security::remove_XSS($myrow['description']).$childrenContent, $header);
1562
            $counter++;
1563
        }
1564
1565
        return $content;
1566
    }
1567
1568
    /**
1569
     * @param int    $linkId
1570
     * @param string $action
1571
     * @param null   $token
1572
     *
1573
     * @return FormValidator
1574
     */
1575
    public static function getLinkForm($linkId, $action, $token = null)
1576
    {
1577
        $course_id = api_get_course_int_id();
1578
        $session_id = api_get_session_id();
1579
        $linkInfo = self::getLinkInfo($linkId);
1580
        $categoryId = isset($linkInfo['category_id']) ? $linkInfo['category_id'] : '';
1581
        $lpId = isset($_GET['lp_id']) ? Security::remove_XSS($_GET['lp_id']) : null;
1582
1583
        $form = new FormValidator(
1584
            'link',
1585
            'post',
1586
            api_get_self().'?action='.$action.
1587
            '&category_id='.$categoryId.
1588
            '&'.api_get_cidreq().
1589
            '&id='.$linkId.
1590
            '&sec_token='.$token
1591
        );
1592
1593
        if ($action === 'addlink') {
1594
            $form->addHeader(get_lang('LinkAdd'));
1595
        } else {
1596
            $form->addHeader(get_lang('LinkMod'));
1597
        }
1598
1599
        $target_link = '_blank';
1600
        $title = '';
1601
        $category = '';
1602
        $onhomepage = '';
1603
        $description = '';
1604
        if (!empty($linkInfo)) {
1605
            $urllink = $linkInfo['url'];
1606
            $title = $linkInfo['title'];
1607
            $description = $linkInfo['description'];
1608
            $category = $linkInfo['category_id'];
1609
            if ($linkInfo['on_homepage'] != 0) {
1610
                $onhomepage = 1;
1611
            }
1612
            $target_link = $linkInfo['target'];
1613
        }
1614
1615
        $form->addHidden('id', $linkId);
1616
        $form->addText('url', 'URL');
1617
        $form->addRule('url', get_lang('GiveURL'), 'url');
1618
        $form->addText('title', get_lang('LinkName'));
1619
        $form->addTextarea('description', get_lang('Description'));
1620
1621
        $resultcategories = self::getLinkCategories($course_id, $session_id);
1622
        $options = ['0' => '--'];
1623
        if (!empty($resultcategories)) {
1624
            foreach ($resultcategories as $myrow) {
1625
                $options[$myrow['id']] = $myrow['category_title'];
1626
            }
1627
        }
1628
1629
        $form->addSelect('category_id', get_lang('Category'), $options);
1630
        $form->addCheckBox('on_homepage', null, get_lang('OnHomepage'));
1631
1632
        $targets = [
1633
            '_self' => get_lang('LinkOpenSelf'),
1634
            '_blank' => get_lang('LinkOpenBlank'),
1635
            '_parent' => get_lang('LinkOpenParent'),
1636
            '_top' => get_lang('LinkOpenTop'),
1637
        ];
1638
1639
        $form->addSelect(
1640
            'target',
1641
            [
1642
                get_lang('LinkTarget'),
1643
                get_lang('AddTargetOfLinkOnHomepage'),
1644
            ],
1645
            $targets
1646
        );
1647
1648
        $defaults = [
1649
            'url' => empty($urllink) ? 'http://' : str_replace('&amp;', '&', Security::remove_XSS($urllink)),
1650
            'title' => Security::remove_XSS($title),
1651
            'category_id' => $category,
1652
            'on_homepage' => $onhomepage,
1653
            'description' => Security::remove_XSS($description),
1654
            'target' => $target_link,
1655
        ];
1656
1657
        if (api_get_setting('search_enabled') === 'true') {
1658
            require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
1659
            $specific_fields = get_specific_field_list();
1660
            $form->addCheckBox('index_document', get_lang('SearchFeatureDoIndexLink'), get_lang('Yes'));
1661
1662
            foreach ($specific_fields as $specific_field) {
1663
                $default_values = '';
1664
                if ($action === 'editlink') {
1665
                    $filter = [
1666
                        'field_id' => $specific_field['id'],
1667
                        'ref_id' => intval($_GET['id']),
1668
                        'tool_id' => '\''.TOOL_LINK.'\'',
1669
                    ];
1670
                    $values = get_specific_field_values_list($filter, ['value']);
1671
                    if (!empty($values)) {
1672
                        $arr_str_values = [];
1673
                        foreach ($values as $value) {
1674
                            $arr_str_values[] = $value['value'];
1675
                        }
1676
                        $default_values = implode(', ', $arr_str_values);
1677
                    }
1678
                }
1679
                $form->addText($specific_field['name'], $specific_field['code']);
1680
                $defaults[$specific_field['name']] = $default_values;
1681
            }
1682
        }
1683
1684
        $skillList = Skill::addSkillsToForm($form, ITEM_TYPE_LINK, $linkId);
1685
        $form->addHidden('lp_id', $lpId);
1686
        $form->addButtonSave(get_lang('SaveLink'), 'submitLink');
1687
        $defaults['skills'] = array_keys($skillList);
1688
        $form->setDefaults($defaults);
1689
1690
        return $form;
1691
    }
1692
1693
    /**
1694
     * @param int    $id
1695
     * @param string $action
1696
     *
1697
     * @return FormValidator
1698
     */
1699
    public static function getCategoryForm($id, $action)
1700
    {
1701
        $id = (int) $id;
1702
        $action = Security::remove_XSS($action);
1703
1704
        $form = new FormValidator(
1705
            'category',
1706
            'post',
1707
            api_get_self().'?action='.$action.'&'.api_get_cidreq()
1708
        );
1709
1710
        $defaults = [];
1711
        if ($action == 'addcategory') {
1712
            $form->addHeader(get_lang('CategoryAdd'));
1713
            $my_cat_title = get_lang('CategoryAdd');
1714
        } else {
1715
            $form->addHeader(get_lang('CategoryMod'));
1716
            $my_cat_title = get_lang('CategoryMod');
1717
            $defaults = self::getCategory($id);
1718
        }
1719
        $form->addHidden('id', $id);
1720
        $form->addText('category_title', get_lang('CategoryName'));
1721
        $form->addTextarea('description', get_lang('Description'));
1722
        $form->addButtonSave($my_cat_title, 'submitCategory');
1723
        $form->setDefaults($defaults);
1724
1725
        return $form;
1726
    }
1727
1728
    /**
1729
     * @param int $id
1730
     *
1731
     * @return array
1732
     */
1733
    public static function getCategory($id)
1734
    {
1735
        $table = Database::get_course_table(TABLE_LINK_CATEGORY);
1736
        $id = (int) $id;
1737
        $courseId = api_get_course_int_id();
1738
1739
        if (empty($id) || empty($courseId)) {
1740
            return [];
1741
        }
1742
        $sql = "SELECT * FROM $table
1743
                WHERE id = $id AND c_id = $courseId";
1744
        $result = Database::query($sql);
1745
        $category = Database::fetch_array($result, 'ASSOC');
1746
1747
        return $category;
1748
    }
1749
1750
    /**
1751
     * Move a link up in its category.
1752
     *
1753
     * @param int $id
1754
     *
1755
     * @return bool
1756
     */
1757
    public static function moveLinkUp($id)
1758
    {
1759
        return self::moveLinkDisplayOrder($id, 'ASC');
1760
    }
1761
1762
    /**
1763
     * Move a link down in its category.
1764
     *
1765
     * @param int $id
1766
     *
1767
     * @return bool
1768
     */
1769
    public static function moveLinkDown($id)
1770
    {
1771
        return self::moveLinkDisplayOrder($id, 'DESC');
1772
    }
1773
1774
    /**
1775
     * @param string $url
1776
     *
1777
     * @return bool
1778
     */
1779
    public static function checkUrl($url)
1780
    {
1781
        // Check if curl is available.
1782
        if (!in_array('curl', get_loaded_extensions())) {
1783
            return false;
1784
        }
1785
1786
        // set URL and other appropriate options
1787
        $defaults = [
1788
            CURLOPT_URL => $url,
1789
            CURLOPT_FOLLOWLOCATION => true, // follow redirects accept youtube.com
1790
            CURLOPT_HEADER => 0,
1791
            CURLOPT_RETURNTRANSFER => true,
1792
            CURLOPT_TIMEOUT => 4,
1793
        ];
1794
1795
        $proxySettings = api_get_configuration_value('proxy_settings');
1796
1797
        if (!empty($proxySettings) &&
1798
            isset($proxySettings['curl_setopt_array'])
1799
        ) {
1800
            $defaults[CURLOPT_PROXY] = $proxySettings['curl_setopt_array']['CURLOPT_PROXY'];
1801
            $defaults[CURLOPT_PROXYPORT] = $proxySettings['curl_setopt_array']['CURLOPT_PROXYPORT'];
1802
        }
1803
1804
        // Create a new cURL resource
1805
        $ch = curl_init();
1806
        curl_setopt_array($ch, $defaults);
1807
1808
        // grab URL and pass it to the browser
1809
        ob_start();
1810
        $result = curl_exec($ch);
1811
        ob_get_clean();
1812
1813
        // close cURL resource, and free up system resources
1814
        curl_close($ch);
1815
1816
        return $result;
1817
    }
1818
1819
    /**
1820
     * Move a link inside its category (display_order field).
1821
     *
1822
     * @param int    $id        The link ID
1823
     * @param string $direction The direction to sort the links
1824
     *
1825
     * @return bool
1826
     */
1827
    private static function moveLinkDisplayOrder($id, $direction)
1828
    {
1829
        $em = Database::getManager();
1830
        /** @var CLink $link */
1831
        $link = $em->find('ChamiloCourseBundle:CLink', $id);
1832
1833
        if (!$link) {
0 ignored issues
show
$link is of type Chamilo\CourseBundle\Entity\CLink, thus it always evaluated to true.
Loading history...
1834
            return false;
1835
        }
1836
1837
        $compareLinks = $em
1838
            ->getRepository('ChamiloCourseBundle:CLink')
1839
            ->findBy(
1840
                [
1841
                    'cId' => $link->getCId(),
1842
                    'categoryId' => $link->getCategoryId(),
1843
                ],
1844
                ['displayOrder' => $direction]
1845
            );
1846
1847
        /** @var CLink $prevLink */
1848
        $prevLink = null;
1849
1850
        /** @var CLink $compareLink */
1851
        foreach ($compareLinks as $compareLink) {
1852
            if ($compareLink->getId() !== $link->getId()) {
1853
                $prevLink = $compareLink;
1854
1855
                continue;
1856
            }
1857
1858
            if (!$prevLink) {
1859
                return false;
1860
            }
1861
1862
            $newPrevLinkDisplayOrder = $link->getDisplayOrder();
1863
            $newLinkDisplayOrder = $prevLink->getDisplayOrder();
1864
1865
            $link->setDisplayOrder($newLinkDisplayOrder);
1866
            $prevLink->setDisplayOrder($newPrevLinkDisplayOrder);
1867
1868
            $em->merge($prevLink);
1869
            $em->merge($link);
1870
            break;
1871
        }
1872
1873
        $em->flush();
1874
1875
        return true;
1876
    }
1877
}
1878