Completed
Push — master ( 441dc8...d4012c )
by Julito
09:56
created

Link::movecatlink()   B

Complexity

Conditions 11
Paths 80

Size

Total Lines 63
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 38
nc 80
nop 4
dl 0
loc 63
rs 7.3166
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CourseBundle\Entity\CLink;
5
6
/**
7
 * Function library for the links tool.
8
 *
9
 * This is a complete remake of the original link tool.
10
 * New features:
11
 * - Organize links into categories;
12
 * - favorites/bookmarks interface;
13
 * - move links up/down within a category;
14
 * - move categories up/down;
15
 * - expand/collapse all categories;
16
 * - add link to 'root' category => category-less link is always visible.
17
 *
18
 * @author Patrick Cool, complete remake (December 2003 - January 2004)
19
 * @author René Haentjens, CSV file import (October 2004)
20
 *
21
 * @package chamilo.link
22
 */
23
class Link extends Model
24
{
25
    public $table;
26
    public $is_course_model = true;
27
    public $columns = [
28
        'id',
29
        'c_id',
30
        'url',
31
        'title',
32
        'description',
33
        'category_id',
34
        'display_order',
35
        'on_homepage',
36
        'target',
37
        'session_id',
38
    ];
39
    public $required = ['url', 'title'];
40
    private $course;
41
42
    /**
43
     * Link constructor.
44
     */
45
    public function __construct()
46
    {
47
        $this->table = Database::get_course_table(TABLE_LINK);
48
    }
49
50
    /**
51
     * @param array $course
52
     */
53
    public function setCourse($course)
54
    {
55
        $this->course = $course;
56
    }
57
58
    /**
59
     * @return array
60
     */
61
    public function getCourse()
62
    {
63
        return !empty($this->course) ? $this->course : api_get_course_info();
64
    }
65
66
    /**
67
     * Organize the saving of a link, using the parent's save method and
68
     * updating the item_property table.
69
     *
70
     * @param array $params
71
     * @param bool  $show_query Whether to show the query in logs when
72
     *                          calling parent's save method
73
     *
74
     * @return bool True if link could be saved, false otherwise
75
     */
76
    public function save($params, $show_query = null)
77
    {
78
        $course_info = $this->getCourse();
79
        $courseId = $course_info['real_id'];
80
81
        $params['session_id'] = api_get_session_id();
82
        $params['category_id'] = isset($params['category_id']) ? $params['category_id'] : 0;
83
84
        $sql = "SELECT MAX(display_order)
85
                FROM  ".$this->table."
86
                WHERE
87
                    c_id = $courseId AND
88
                    category_id = '".intval($params['category_id'])."'";
89
        $result = Database:: query($sql);
90
        list($orderMax) = Database:: fetch_row($result);
91
        $order = $orderMax + 1;
92
        $params['display_order'] = $order;
93
94
        $id = parent::save($params, $show_query);
95
96
        if (!empty($id)) {
97
            // iid
98
            $sql = "UPDATE ".$this->table." SET id = iid WHERE iid = $id";
99
            Database::query($sql);
100
101
            api_item_property_update(
102
                $course_info,
103
                TOOL_LINK,
104
                $id,
105
                'LinkAdded',
106
                api_get_user_id()
107
            );
108
109
            api_set_default_visibility($id, TOOL_LINK);
110
        }
111
112
        return $id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $id also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
113
    }
114
115
    /**
116
     * Update a link in the database.
117
     *
118
     * @param int    $linkId    The ID of the link to update
119
     * @param string $linkUrl   The new URL to be saved
120
     * @param int    $courseId
121
     * @param int    $sessionId
122
     *
123
     * @return bool
124
     */
125
    public function updateLink(
126
        $linkId,
127
        $linkUrl,
128
        $courseId = null,
129
        $sessionId = null
130
    ) {
131
        $tblLink = Database::get_course_table(TABLE_LINK);
132
        $linkUrl = Database::escape_string($linkUrl);
133
        $linkId = intval($linkId);
134
        if (is_null($courseId)) {
135
            $courseId = api_get_course_int_id();
136
        }
137
        $courseId = intval($courseId);
138
        if (is_null($sessionId)) {
139
            $sessionId = api_get_session_id();
140
        }
141
        $sessionId = intval($sessionId);
142
        if ($linkUrl != '') {
143
            $sql = "UPDATE $tblLink SET 
144
                    url = '$linkUrl'
145
                    WHERE id = $linkId AND c_id = $courseId AND session_id = $sessionId";
146
            $resLink = Database::query($sql);
147
148
            return $resLink;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $resLink returns the type Doctrine\DBAL\Driver\Statement which is incompatible with the documented return type boolean.
Loading history...
149
        }
150
151
        return false;
152
    }
153
154
    /**
155
     * Used to add a link or a category.
156
     *
157
     * @param string $type , "link" or "category"
158
     *
159
     * @todo replace strings by constants
160
     *
161
     * @author Patrick Cool <[email protected]>, Ghent University
162
     *
163
     * @return bool True on success, false on failure
164
     */
165
    public static function addlinkcategory($type)
166
    {
167
        $ok = true;
168
        $_course = api_get_course_info();
169
        $course_id = $_course['real_id'];
170
        $session_id = api_get_session_id();
171
172
        if ($type == 'link') {
173
            $title = Security::remove_XSS(stripslashes($_POST['title']));
174
            $urllink = Security::remove_XSS($_POST['url']);
175
            $description = Security::remove_XSS($_POST['description']);
176
            $selectcategory = Security::remove_XSS($_POST['category_id']);
177
178
            $onhomepage = 0;
179
            if (isset($_POST['on_homepage'])) {
180
                $onhomepage = Security::remove_XSS($_POST['on_homepage']);
181
            }
182
183
            $target = '_self'; // Default target.
184
            if (!empty($_POST['target'])) {
185
                $target = Security::remove_XSS($_POST['target']);
186
            }
187
188
            $urllink = trim($urllink);
189
            $title = trim($title);
190
            $description = trim($description);
191
192
            // We ensure URL to be absolute.
193
            if (strpos($urllink, '://') === false) {
194
                $urllink = 'http://'.$urllink;
195
            }
196
197
            // If the title is empty, we use the URL as title.
198
            if ($title == '') {
199
                $title = $urllink;
200
            }
201
202
            // If the URL is invalid, an error occurs.
203
            if (!api_valid_url($urllink, true)) {
204
                // A check against an absolute URL
205
                Display::addFlash(Display::return_message(get_lang('GiveURL'), 'error'));
206
207
                return false;
208
            } else {
209
                // Looking for the largest order number for this category.
210
                $link = new Link();
211
                $params = [
212
                    'c_id' => $course_id,
213
                    'url' => $urllink,
214
                    'title' => $title,
215
                    'description' => $description,
216
                    'category_id' => $selectcategory,
217
                    'on_homepage' => $onhomepage,
218
                    'target' => $target,
219
                    'session_id' => $session_id,
220
                ];
221
                $link_id = $link->save($params);
222
223
                if ((api_get_setting('search_enabled') == 'true') &&
224
                    $link_id && extension_loaded('xapian')
225
                ) {
226
                    require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
227
228
                    $course_int_id = $_course['real_id'];
229
                    $courseCode = $_course['code'];
230
                    $specific_fields = get_specific_field_list();
231
                    $ic_slide = new IndexableChunk();
232
233
                    // Add all terms to db.
234
                    $all_specific_terms = '';
235
                    foreach ($specific_fields as $specific_field) {
236
                        if (isset($_REQUEST[$specific_field['code']])) {
237
                            $sterms = trim($_REQUEST[$specific_field['code']]);
238
                            if (!empty($sterms)) {
239
                                $all_specific_terms .= ' '.$sterms;
240
                                $sterms = explode(',', $sterms);
241
                                foreach ($sterms as $sterm) {
242
                                    $ic_slide->addTerm(
243
                                        trim($sterm),
244
                                        $specific_field['code']
245
                                    );
246
                                    add_specific_field_value(
247
                                        $specific_field['id'],
248
                                        $courseCode,
249
                                        TOOL_LINK,
250
                                        $link_id,
251
                                        $sterm
252
                                    );
253
                                }
254
                            }
255
                        }
256
                    }
257
258
                    // Build the chunk to index.
259
                    $ic_slide->addValue('title', $title);
260
                    $ic_slide->addCourseId($courseCode);
261
                    $ic_slide->addToolId(TOOL_LINK);
262
                    $xapian_data = [
263
                        SE_COURSE_ID => $courseCode,
264
                        SE_TOOL_ID => TOOL_LINK,
265
                        SE_DATA => [
266
                            'link_id' => (int) $link_id,
267
                        ],
268
                        SE_USER => (int) api_get_user_id(),
269
                    ];
270
                    $ic_slide->xapian_data = serialize($xapian_data);
271
                    $description = $all_specific_terms.' '.$description;
272
                    $ic_slide->addValue('content', $description);
273
274
                    // Add category name if set.
275
                    if (isset($selectcategory) && $selectcategory > 0) {
276
                        $table_link_category = Database::get_course_table(
277
                            TABLE_LINK_CATEGORY
278
                        );
279
                        $sql_cat = 'SELECT * FROM %s WHERE id=%d AND c_id = %d LIMIT 1';
280
                        $sql_cat = sprintf(
281
                            $sql_cat,
282
                            $table_link_category,
283
                            (int) $selectcategory,
284
                            $course_int_id
285
                        );
286
                        $result = Database:: query($sql_cat);
287
                        if (Database:: num_rows($result) == 1) {
288
                            $row = Database:: fetch_array($result);
289
                            $ic_slide->addValue(
290
                                'category',
291
                                $row['category_title']
292
                            );
293
                        }
294
                    }
295
296
                    $di = new ChamiloIndexer();
297
                    isset($_POST['language']) ? $lang = Database:: escape_string(
298
                        $_POST['language']
299
                    ) : $lang = 'english';
300
                    $di->connectDb(null, null, $lang);
301
                    $di->addChunk($ic_slide);
302
303
                    // Index and return search engine document id.
304
                    $did = $di->index();
305
                    if ($did) {
306
                        // Save it to db.
307
                        $tbl_se_ref = Database::get_main_table(
308
                            TABLE_MAIN_SEARCH_ENGINE_REF
309
                        );
310
                        $sql = 'INSERT INTO %s (id, course_code, tool_id, ref_id_high_level, search_did)
311
                                VALUES (NULL , \'%s\', \'%s\', %s, %s)';
312
                        $sql = sprintf(
313
                            $sql,
314
                            $tbl_se_ref,
315
                            $course_int_id,
316
                            $courseCode,
317
                            TOOL_LINK,
318
                            $link_id,
319
                            $did
320
                        );
321
                        Database:: query($sql);
322
                    }
323
                }
324
                Display::addFlash(Display::return_message(get_lang('LinkAdded')));
325
326
                return $link_id;
327
            }
328
        } elseif ($type == 'category') {
329
            $tbl_categories = Database::get_course_table(TABLE_LINK_CATEGORY);
330
331
            $category_title = trim($_POST['category_title']);
332
            $description = trim($_POST['description']);
333
334
            if (empty($category_title)) {
335
                echo Display::return_message(get_lang('GiveCategoryName'), 'error');
336
                $ok = false;
337
            } else {
338
                // Looking for the largest order number for this category.
339
                $result = Database:: query(
340
                    "SELECT MAX(display_order) FROM  $tbl_categories
341
                    WHERE c_id = $course_id "
342
                );
343
                list($orderMax) = Database:: fetch_row($result);
344
                $order = $orderMax + 1;
345
                $order = intval($order);
346
                $session_id = api_get_session_id();
347
348
                $params = [
349
                    'c_id' => $course_id,
350
                    'category_title' => $category_title,
351
                    'description' => $description,
352
                    'display_order' => $order,
353
                    'session_id' => $session_id,
354
                ];
355
                $linkId = Database::insert($tbl_categories, $params);
356
357
                if ($linkId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $linkId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
358
                    // iid
359
                    $sql = "UPDATE $tbl_categories SET id = iid WHERE iid = $linkId";
360
                    Database:: query($sql);
361
362
                    // add link_category visibility
363
                    // course ID is taken from context in api_set_default_visibility
364
                    //api_set_default_visibility($linkId, TOOL_LINK_CATEGORY);
365
                    api_item_property_update(
366
                        $_course,
367
                        TOOL_LINK_CATEGORY,
368
                        $linkId,
369
                        'LinkCategoryAdded',
370
                        api_get_user_id()
371
                    );
372
                    api_set_default_visibility($linkId, TOOL_LINK_CATEGORY);
373
                }
374
375
                Display::addFlash(Display::return_message(get_lang('CategoryAdded')));
376
377
                return $linkId;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $linkId also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
378
            }
379
        }
380
381
        return $ok;
382
    }
383
384
    /**
385
     * Used to delete a link or a category.
386
     *
387
     * @author Patrick Cool <[email protected]>, Ghent University
388
     *
389
     * @param int    $id
390
     * @param string $type The type of item to delete
391
     *
392
     * @return bool
393
     */
394
    public static function deletelinkcategory($id, $type)
395
    {
396
        $courseInfo = api_get_course_info();
397
        $tbl_link = Database::get_course_table(TABLE_LINK);
398
        $tbl_categories = Database::get_course_table(TABLE_LINK_CATEGORY);
399
400
        $course_id = $courseInfo['real_id'];
401
        $id = intval($id);
402
403
        if (empty($id)) {
404
            return false;
405
        }
406
407
        $result = false;
408
        switch ($type) {
409
            case 'link':
410
                // -> Items are no longer physically deleted,
411
                // but the visibility is set to 2 (in item_property).
412
                // This will make a restore function possible for the platform administrator.
413
                $sql = "UPDATE $tbl_link SET on_homepage='0'
414
                        WHERE c_id = $course_id AND id='".$id."'";
415
                Database:: query($sql);
416
417
                api_item_property_update(
418
                    $courseInfo,
419
                    TOOL_LINK,
420
                    $id,
421
                    'delete',
422
                    api_get_user_id()
423
                );
424
                self::delete_link_from_search_engine(api_get_course_id(), $id);
425
                Skill::deleteSkillsFromItem($id, ITEM_TYPE_LINK);
426
                Display::addFlash(Display::return_message(get_lang('LinkDeleted')));
427
                $result = true;
428
                break;
429
            case 'category':
430
                // First we delete the category itself and afterwards all the links of this category.
431
                $sql = "DELETE FROM ".$tbl_categories."
432
                        WHERE c_id = $course_id AND id='".$id."'";
433
                Database:: query($sql);
434
435
                $sql = "DELETE FROM ".$tbl_link."
436
                        WHERE c_id = $course_id AND category_id='".$id."'";
437
                Database:: query($sql);
438
439
                api_item_property_update(
440
                    $courseInfo,
441
                    TOOL_LINK_CATEGORY,
442
                    $id,
443
                    'delete',
444
                    api_get_user_id()
445
                );
446
447
                Display::addFlash(Display::return_message(get_lang('CategoryDeleted')));
448
                $result = true;
449
                break;
450
        }
451
452
        return $result;
453
    }
454
455
    /**
456
     * Removes a link from search engine database.
457
     *
458
     * @param string $course_id Course code
459
     * @param int    $link_id   Document id to delete
460
     */
461
    public static function delete_link_from_search_engine($course_id, $link_id)
462
    {
463
        // Remove from search engine if enabled.
464
        if (api_get_setting('search_enabled') === 'true') {
465
            $tbl_se_ref = Database::get_main_table(
466
                TABLE_MAIN_SEARCH_ENGINE_REF
467
            );
468
            $sql = 'SELECT * FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
469
            $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_LINK, $link_id);
470
            $res = Database:: query($sql);
471
            if (Database:: num_rows($res) > 0) {
472
                $row = Database::fetch_array($res);
473
                $di = new ChamiloIndexer();
474
                $di->remove_document($row['search_did']);
475
            }
476
            $sql = 'DELETE FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
477
            $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_LINK, $link_id);
478
            Database:: query($sql);
479
480
            // Remove terms from db.
481
            require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
482
            delete_all_values_for_item($course_id, TOOL_DOCUMENT, $link_id);
483
        }
484
    }
485
486
    /**
487
     * Get link info.
488
     *
489
     * @param int $id
490
     *
491
     * @return array link info
492
     */
493
    public static function getLinkInfo($id)
494
    {
495
        $tbl_link = Database::get_course_table(TABLE_LINK);
496
        $course_id = api_get_course_int_id();
497
498
        if (empty($id) || empty($course_id)) {
499
            return [];
500
        }
501
502
        $sql = "SELECT * FROM $tbl_link
503
                WHERE c_id = $course_id AND id='".intval($id)."' ";
504
        $result = Database::query($sql);
505
        $data = [];
506
        if (Database::num_rows($result)) {
507
            $data = Database::fetch_array($result);
508
        }
509
510
        return $data;
511
    }
512
513
    /**
514
     * @param int   $id
515
     * @param array $values
516
     */
517
    public static function editLink($id, $values = [])
518
    {
519
        $tbl_link = Database::get_course_table(TABLE_LINK);
520
        $_course = api_get_course_info();
521
        $course_id = $_course['real_id'];
522
        $id = intval($id);
523
524
        $values['url'] = trim($values['url']);
525
        $values['title'] = trim($values['title']);
526
        $values['description'] = trim($values['description']);
527
        $values['target'] = empty($values['target']) ? '_self' : $values['target'];
528
        $values['on_homepage'] = isset($values['on_homepage']) ? $values['on_homepage'] : '';
529
530
        $categoryId = intval($values['category_id']);
531
532
        // We ensure URL to be absolute.
533
        if (strpos($values['url'], '://') === false) {
534
            $values['url'] = 'http://'.$_POST['url'];
535
        }
536
537
        // If the title is empty, we use the URL as title.
538
        if ($values['title'] == '') {
539
            $values['title'] = $values['url'];
540
        }
541
542
        // If the URL is invalid, an error occurs.
543
        if (!api_valid_url($values['url'], true)) {
544
            Display::addFlash(
545
                Display::return_message(get_lang('GiveURL'), 'error')
546
            );
547
548
            return false;
549
        }
550
551
        if (empty($id) || empty($course_id)) {
552
            return false;
553
        }
554
555
        // Finding the old category_id.
556
        $sql = "SELECT * FROM $tbl_link
557
                WHERE c_id = $course_id AND id='".$id."'";
558
        $result = Database:: query($sql);
559
        $row = Database:: fetch_array($result);
560
        $category_id = $row['category_id'];
561
562
        if ($category_id != $values['category_id']) {
563
            $sql = "SELECT MAX(display_order)
564
                    FROM $tbl_link 
565
                    WHERE
566
                        c_id = $course_id AND
567
                        category_id='".intval($values['category_id'])."'";
568
            $result = Database:: query($sql);
569
            list($max_display_order) = Database:: fetch_row($result);
570
            $max_display_order++;
571
        } else {
572
            $max_display_order = $row['display_order'];
573
        }
574
        $params = [
575
            'url' => $values['url'],
576
            'title' => $values['title'],
577
            'description' => $values['description'],
578
            'category_id' => $values['category_id'],
579
            'display_order' => $max_display_order,
580
            'on_homepage' => $values['on_homepage'],
581
            'target' => $values['target'],
582
            'category_id' => $values['category_id'],
583
        ];
584
585
        Database::update(
586
            $tbl_link,
587
            $params,
588
            ['c_id = ? AND id = ?' => [$course_id, $id]]
589
        );
590
591
        // Update search enchine and its values table if enabled.
592
        if (api_get_setting('search_enabled') == 'true') {
593
            $course_int_id = api_get_course_int_id();
594
            $course_id = api_get_course_id();
595
            $link_title = Database:: escape_string($values['title']);
596
            $link_description = Database:: escape_string($values['description']);
597
598
            // Actually, it consists on delete terms from db,
599
            // insert new ones, create a new search engine document, and remove the old one.
600
            // Get search_did.
601
            $tbl_se_ref = Database::get_main_table(
602
                TABLE_MAIN_SEARCH_ENGINE_REF
603
            );
604
            $sql = 'SELECT * FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
605
            $sql = sprintf(
606
                $sql,
607
                $tbl_se_ref,
608
                $course_id,
609
                TOOL_LINK,
610
                $id
611
            );
612
            $res = Database:: query($sql);
613
614
            if (Database:: num_rows($res) > 0) {
615
                require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
616
617
                $se_ref = Database:: fetch_array($res);
618
                $specific_fields = get_specific_field_list();
619
                $ic_slide = new IndexableChunk();
620
621
                $all_specific_terms = '';
622
                foreach ($specific_fields as $specific_field) {
623
                    delete_all_specific_field_value(
624
                        $course_id,
625
                        $specific_field['id'],
626
                        TOOL_LINK,
627
                        $id
628
                    );
629
                    if (isset($_REQUEST[$specific_field['code']])) {
630
                        $sterms = trim(
631
                            $_REQUEST[$specific_field['code']]
632
                        );
633
                        if (!empty($sterms)) {
634
                            $all_specific_terms .= ' '.$sterms;
635
                            $sterms = explode(',', $sterms);
636
                            foreach ($sterms as $sterm) {
637
                                $ic_slide->addTerm(
638
                                    trim($sterm),
639
                                    $specific_field['code']
640
                                );
641
                                add_specific_field_value(
642
                                    $specific_field['id'],
643
                                    $course_id,
644
                                    TOOL_LINK,
645
                                    $id,
646
                                    $sterm
647
                                );
648
                            }
649
                        }
650
                    }
651
                }
652
653
                // Build the chunk to index.
654
                $ic_slide->addValue("title", $link_title);
655
                $ic_slide->addCourseId($course_id);
656
                $ic_slide->addToolId(TOOL_LINK);
657
                $xapian_data = [
658
                    SE_COURSE_ID => $course_id,
659
                    SE_TOOL_ID => TOOL_LINK,
660
                    SE_DATA => [
661
                        'link_id' => (int) $id,
662
                    ],
663
                    SE_USER => (int) api_get_user_id(),
664
                ];
665
                $ic_slide->xapian_data = serialize($xapian_data);
666
                $link_description = $all_specific_terms.' '.$link_description;
667
                $ic_slide->addValue('content', $link_description);
668
669
                // Add category name if set.
670
                if (isset($categoryId) && $categoryId > 0) {
671
                    $table_link_category = Database::get_course_table(
672
                        TABLE_LINK_CATEGORY
673
                    );
674
                    $sql_cat = 'SELECT * FROM %s WHERE id=%d and c_id = %d LIMIT 1';
675
                    $sql_cat = sprintf(
676
                        $sql_cat,
677
                        $table_link_category,
678
                        $categoryId,
679
                        $course_int_id
680
                    );
681
                    $result = Database:: query($sql_cat);
682
                    if (Database:: num_rows($result) == 1) {
683
                        $row = Database:: fetch_array($result);
684
                        $ic_slide->addValue(
685
                            'category',
686
                            $row['category_title']
687
                        );
688
                    }
689
                }
690
691
                $di = new ChamiloIndexer();
692
                isset($_POST['language']) ? $lang = Database:: escape_string($_POST['language']) : $lang = 'english';
693
                $di->connectDb(null, null, $lang);
694
                $di->remove_document($se_ref['search_did']);
695
                $di->addChunk($ic_slide);
696
697
                // Index and return search engine document id.
698
                $did = $di->index();
699
                if ($did) {
700
                    // Save it to db.
701
                    $sql = 'DELETE FROM %s
702
                            WHERE course_code=\'%s\'
703
                            AND tool_id=\'%s\'
704
                            AND ref_id_high_level=\'%s\'';
705
                    $sql = sprintf(
706
                        $sql,
707
                        $tbl_se_ref,
708
                        $course_id,
709
                        TOOL_LINK,
710
                        $id
711
                    );
712
                    Database:: query($sql);
713
                    $sql = 'INSERT INTO %s (c_id, id, course_code, tool_id, ref_id_high_level, search_did)
714
                            VALUES (NULL , \'%s\', \'%s\', %s, %s)';
715
                    $sql = sprintf(
716
                        $sql,
717
                        $tbl_se_ref,
718
                        $course_int_id,
719
                        $course_id,
720
                        TOOL_LINK,
721
                        $id,
722
                        $did
723
                    );
724
                    Database:: query($sql);
725
                }
726
            }
727
        }
728
729
        // "WHAT'S NEW" notification: update table last_toolEdit.
730
        api_item_property_update(
731
            $_course,
732
            TOOL_LINK,
733
            $id,
734
            'LinkUpdated',
735
            api_get_user_id()
736
        );
737
        Display::addFlash(Display::return_message(get_lang('LinkModded')));
738
    }
739
740
    /**
741
     * @param int   $id
742
     * @param array $values
743
     *
744
     * @return bool
745
     */
746
    public static function editCategory($id, $values)
747
    {
748
        $table = Database::get_course_table(TABLE_LINK_CATEGORY);
749
        $course_id = api_get_course_int_id();
750
        $id = intval($id);
751
752
        // This is used to put the modified info of the category-form into the database.
753
        $params = [
754
            'category_title' => $values['category_title'],
755
            'description' => $values['description'],
756
        ];
757
        Database::update(
758
            $table,
759
            $params,
760
            ['c_id = ? AND id = ?' => [$course_id, $id]]
761
        );
762
        Display::addFlash(Display::return_message(get_lang('CategoryModded')));
763
764
        return true;
765
    }
766
767
    /**
768
     * Changes the visibility of a link.
769
     *
770
     * @todo add the changing of the visibility of a course
771
     *
772
     * @author Patrick Cool <[email protected]>, Ghent University
773
     */
774
    public static function change_visibility_link($id, $scope)
775
    {
776
        $_course = api_get_course_info();
777
        $_user = api_get_user_info();
778
        if ($scope == TOOL_LINK) {
779
            api_item_property_update(
780
                $_course,
781
                TOOL_LINK,
782
                $id,
783
                $_GET['action'],
784
                $_user['user_id']
785
            );
786
            Display::addFlash(Display::return_message(get_lang('VisibilityChanged')));
787
        } elseif ($scope == TOOL_LINK_CATEGORY) {
788
            api_item_property_update(
789
                $_course,
790
                TOOL_LINK_CATEGORY,
791
                $id,
792
                $_GET['action'],
793
                $_user['user_id']
794
            );
795
            Display::addFlash(Display::return_message(get_lang('VisibilityChanged')));
796
        }
797
    }
798
799
    /**
800
     * Generate SQL to select all the links categories in the current course and
801
     * session.
802
     *
803
     * @param int  $courseId
804
     * @param int  $sessionId
805
     * @param bool $withBaseContent
806
     *
807
     * @return array
808
     */
809
    public static function getLinkCategories($courseId, $sessionId, $withBaseContent = true)
810
    {
811
        $tblLinkCategory = Database::get_course_table(TABLE_LINK_CATEGORY);
812
        $tblItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
813
        $courseId = intval($courseId);
814
        $courseInfo = api_get_course_info_by_id($courseId);
815
816
        // Condition for the session.
817
        $sessionCondition = api_get_session_condition(
818
            $sessionId,
819
            true,
820
            $withBaseContent,
821
            'linkcat.session_id'
822
        );
823
824
        // Getting links
825
        $sql = "SELECT *, linkcat.id
826
                FROM $tblLinkCategory linkcat
827
                WHERE
828
                    linkcat.c_id = $courseId
829
                    $sessionCondition
830
                ORDER BY linkcat.display_order DESC";
831
832
        $result = Database::query($sql);
833
        $categories = Database::store_result($result);
834
835
        $sql = "SELECT *, linkcat.id
836
                FROM $tblLinkCategory linkcat
837
                INNER JOIN $tblItemProperty ip
838
                ON (linkcat.id = ip.ref AND linkcat.c_id = ip.c_id)
839
                WHERE
840
                    ip.tool = '".TOOL_LINK_CATEGORY."' AND
841
                    (ip.visibility = '0' OR ip.visibility = '1')
842
                    $sessionCondition AND
843
                    linkcat.c_id = ".$courseId."
844
                ORDER BY linkcat.display_order DESC";
845
846
        $result = Database::query($sql);
847
848
        $categoryInItemProperty = [];
849
        if (Database::num_rows($result)) {
850
            while ($row = Database::fetch_array($result, 'ASSOC')) {
851
                $categoryInItemProperty[$row['id']] = $row;
852
            }
853
        }
854
855
        foreach ($categories as &$category) {
856
            if (!isset($categoryInItemProperty[$category['id']])) {
857
                api_item_property_update(
858
                    $courseInfo,
859
                    TOOL_LINK_CATEGORY,
860
                    $category['id'],
861
                    'LinkCategoryAdded',
862
                    api_get_user_id()
863
                );
864
            }
865
        }
866
867
        $sql = "SELECT DISTINCT linkcat.*, visibility
868
                FROM $tblLinkCategory linkcat
869
                INNER JOIN $tblItemProperty ip
870
                ON (linkcat.id = ip.ref AND linkcat.c_id = ip.c_id)
871
                WHERE
872
                    ip.tool = '".TOOL_LINK_CATEGORY."' AND
873
                    (ip.visibility = '0' OR ip.visibility = '1')
874
                    $sessionCondition AND
875
                    linkcat.c_id = ".$courseId."
876
                ORDER BY linkcat.display_order DESC
877
                ";
878
        $result = Database::query($sql);
879
880
        return Database::store_result($result, 'ASSOC');
881
    }
882
883
    /**
884
     * @param int $categoryId
885
     * @param $courseId
886
     * @param $sessionId
887
     * @param bool $withBaseContent
888
     *
889
     * @return array
890
     */
891
    public static function getLinksPerCategory(
892
        $categoryId,
893
        $courseId,
894
        $sessionId,
895
        $withBaseContent = true
896
    ) {
897
        $tbl_link = Database::get_course_table(TABLE_LINK);
898
        $TABLE_ITEM_PROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY);
899
        $courseId = (int) $courseId;
900
        $sessionId = (int) $sessionId;
901
        $categoryId = (int) $categoryId;
902
903
        // Condition for the session.
904
        $condition_session = api_get_session_condition(
905
            $sessionId,
906
            true,
907
            false,
908
            'ip.session_id'
909
        );
910
911
        if (!empty($sessionId)) {
912
            $conditionBaseSession = api_get_session_condition(
913
                0,
914
                true,
915
                $withBaseContent,
916
                'ip.session_id'
917
            );
918
            $condition = " AND 
919
                (
920
                    (ip.visibility = '1' $conditionBaseSession) OR
921
                     
922
                    (
923
                        (ip.visibility = '0' OR ip.visibility = '1')
924
                        $condition_session
925
                    )
926
                )
927
            ";
928
        } else {
929
            $condition = api_get_session_condition(
930
                0,
931
                true,
932
                false,
933
                'ip.session_id'
934
            );
935
            $condition .= " AND (ip.visibility = '0' OR ip.visibility = '1') $condition ";
936
        }
937
938
        $sql = "SELECT 
939
                    link.id,
940
                    ip.session_id,
941
                    link.session_id link_session_id,
942
                    url,
943
                    category_id,
944
                    visibility,
945
                    description,
946
                    title,
947
                    target,
948
                    on_homepage
949
                FROM $tbl_link link
950
                INNER JOIN $TABLE_ITEM_PROPERTY ip
951
                ON (link.id = ip.ref AND link.c_id = ip.c_id)
952
                WHERE
953
                    ip.tool = '".TOOL_LINK."' AND
954
                    link.category_id = '".$categoryId."' AND
955
                    link.c_id = $courseId AND
956
                    ip.c_id = $courseId
957
                    $condition
958
                ORDER BY link.display_order ASC, ip.session_id DESC";
959
960
        $result = Database:: query($sql);
961
962
        return Database::store_result($result);
963
    }
964
965
    /**
966
     * Displays all the links of a given category.
967
     *
968
     * @author Patrick Cool <[email protected]>, Ghent University
969
     * @author Julio Montoya
970
     *
971
     * @param $catid
972
     * @param int $courseId
973
     * @param int $session_id
974
     *
975
     * @return array
976
     */
977
    public static function showLinksPerCategory($catid, $courseId, $session_id)
978
    {
979
        global $token;
980
        $_user = api_get_user_info();
981
        $catid = intval($catid);
982
983
        $links = self::getLinksPerCategory($catid, $courseId, $session_id);
984
        $numberOfLinks = count($links);
985
        $listLink = [];
986
987
        if (!empty($links)) {
988
            $i = 1;
989
            $linksAdded = [];
990
            foreach ($links as $myrow) {
991
                $linkId = $myrow['id'];
992
                $linksAdded['id'] = $linkId;
993
                $categoryId = $myrow['category_id'];
994
                $linksAdded['category'] = $categoryId;
995
996
                // Validation when belongs to a session.
997
                $session_img = api_get_session_image(
998
                    $myrow['link_session_id'],
999
                    $_user['status']
1000
                );
1001
1002
                $toolbar = '';
1003
                $link_validator = '';
1004
                if (api_is_allowed_to_edit(null, true)) {
1005
                    $toolbar .= Display::toolbarButton(
1006
                        '',
1007
                        'javascript:void(0);',
1008
                        'check-circle',
1009
                        'secondary btn-sm',
1010
                        [
1011
                            'onclick' => "check_url('".$linkId."', '".addslashes($myrow['url'])."');",
1012
                            'title' => get_lang('CheckURL'),
1013
                        ]
1014
                    );
1015
1016
                    $link_validator .= Display::span(
1017
                        '',
1018
                        [
1019
                        'id' => 'url_id_'.$linkId,
1020
                        'class' => 'check-link',
1021
                        ]
1022
                    );
1023
1024
                    if ($session_id == $myrow['link_session_id']) {
1025
                        $url = api_get_self().'?'.api_get_cidreq().'&action=editlink&id='.$linkId;
1026
                        $title = get_lang('Edit');
1027
                        $toolbar .= Display::toolbarButton(
1028
                            '',
1029
                            $url,
1030
                            'pencil-alt',
1031
                            'secondary btn-sm',
1032
                            [
1033
                                'title' => $title,
1034
                            ]
1035
                        );
1036
                    }
1037
1038
                    $urlVisibility = api_get_self().'?'.api_get_cidreq().
1039
                            '&sec_token='.$token.
1040
                            '&id='.$linkId.
1041
                            '&scope=link&category_id='.$categoryId;
1042
1043
                    switch ($myrow['visibility']) {
1044
                        case '1':
1045
                            $urlVisibility .= '&action=invisible';
1046
                            $title = get_lang('MakeInvisible');
1047
                            $toolbar .= Display::toolbarButton(
1048
                                '',
1049
                                $urlVisibility,
1050
                                'eye',
1051
                                'secondary btn-sm',
1052
                                [
1053
                                    'title' => $title,
1054
                                ]
1055
                            );
1056
                            break;
1057
                        case '0':
1058
                            $urlVisibility .= '&action=visible';
1059
                            $title = get_lang('MakeVisible');
1060
                            $toolbar .= Display::toolbarButton(
1061
                                '',
1062
                                $urlVisibility,
1063
                                'eye-slash',
1064
                                'secondary btn-sm',
1065
                                [
1066
                                    'title' => $title,
1067
                                ]
1068
                            );
1069
                            break;
1070
                    }
1071
1072
                    if ($session_id == $myrow['link_session_id']) {
1073
                        $moveLinkParams = [
1074
                            'id' => $linkId,
1075
                            'scope' => 'category',
1076
                            'category_id' => $categoryId,
1077
                            'action' => 'move_link_up',
1078
                        ];
1079
1080
                        $toolbar .= Display::toolbarButton(
1081
                            get_lang('MoveUp'),
1082
                            api_get_self().'?'.api_get_cidreq().'&'.http_build_query($moveLinkParams),
1083
                            'level-up-alt',
1084
                            'secondary',
1085
                            ['class' => 'btn-sm '.($i === 1 ? 'disabled' : '')],
1086
                            false
1087
                        );
1088
1089
                        $moveLinkParams['action'] = 'move_link_down';
1090
                        $toolbar .= Display::toolbarButton(
1091
                            get_lang('MoveDown'),
1092
                            api_get_self().'?'.api_get_cidreq().'&'.http_build_query($moveLinkParams),
1093
                            'level-down-alt',
1094
                            'secondary',
1095
                            ['class' => 'btn-sm '.($i === $numberOfLinks ? 'disabled' : '')],
1096
                            false
1097
                        );
1098
1099
                        $url = api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=deletelink&id='.$linkId.'&category_id='.$categoryId;
1100
                        $event = "javascript: if(!confirm('".get_lang('LinkDelconfirm')."'))return false;";
1101
                        $title = get_lang('Delete');
1102
1103
                        $toolbar .= Display::toolbarButton(
1104
                            '',
1105
                            $url,
1106
                            'trash',
1107
                            'secondary btn-sm',
1108
                            [
1109
                                'onclick' => $event,
1110
                                'title' => $title,
1111
                            ]
1112
                        );
1113
                    }
1114
                }
1115
1116
                $showLink = true;
1117
                $urlLink = null;
1118
1119
                if ($myrow['visibility'] != '1') {
1120
                    $showLink = false;
1121
                }
1122
1123
                $linksAdded['visibility'] = $showLink;
1124
1125
                if ($showLink) {
1126
                    $urlLink = api_get_path(WEB_CODE_PATH).'link/link_goto.php?'.api_get_cidreq().'&link_id='.$linkId.'&link_url='.urlencode($myrow['url']);
1127
                }
1128
1129
                $i++;
1130
1131
                $linksAdded['title'] = Security::remove_XSS($myrow['title']);
1132
                $linksAdded['description'] = $myrow['description'];
1133
                $linksAdded['target'] = $myrow['target'];
1134
                $linksAdded['url'] = $urlLink;
1135
                $linksAdded['toolbar'] = $toolbar;
1136
                $linksAdded['session'] = $session_img;
1137
                $linksAdded['link_validator'] = $link_validator;
1138
1139
                $listLink[] = $linksAdded;
1140
            }
1141
        }
1142
1143
        return $listLink;
1144
    }
1145
1146
    /**
1147
     * Displays the edit, delete and move icons.
1148
     *
1149
     * @param int   Category ID
1150
     * @param int $currentCategory
1151
     * @param int $countCategories
1152
     *
1153
     * @return string
1154
     *
1155
     * @author Patrick Cool <[email protected]>, Ghent University
1156
     */
1157
    public static function showCategoryAdminTools($category, $currentCategory, $countCategories)
1158
    {
1159
        $categoryId = $category['id'];
1160
        $token = null;
1161
        $urlEdit = api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=editcategory&id='.$categoryId.'&category_id='.$categoryId;
1162
        $tools = Display::toolbarButton(
1163
            null,
1164
            $urlEdit,
1165
            'pencil-alt',
1166
            null,
1167
            [
1168
                'title' => get_lang('Modify'),
1169
            ]);
1170
1171
        // DISPLAY MOVE UP COMMAND only if it is not the top link.
1172
        if ($currentCategory != 0) {
1173
            $url = api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=up&up='.$categoryId.'&category_id='.$categoryId;
1174
            $tools .= Display::toolbarButton(
1175
                null,
1176
                $url,
1177
                'level-up-alt',
1178
                'outline-secondary',
1179
                [
1180
                    'title' => get_lang("Up"),
1181
                ]
1182
                );
1183
        } else {
1184
            $tools .= Display::toolbarButton(
1185
                null,
1186
                null,
1187
                'level-up-alt',
1188
                'outline-secondary',
1189
                [
1190
                    'title' => get_lang("Up"),
1191
                    'class' => 'disabled',
1192
                ]
1193
            );
1194
        }
1195
1196
        // DISPLAY MOVE DOWN COMMAND only if it is not the bottom link.
1197
        if ($currentCategory < $countCategories - 1) {
1198
            $url = api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=down&down='.$categoryId.'&category_id='.$categoryId;
1199
            $tools .= Display::toolbarButton(
1200
                null,
1201
                $url,
1202
                'level-down-alt',
1203
                'outline-secondary',
1204
                [
1205
                    'title' => get_lang("Down"),
1206
                ]
1207
            );
1208
        } else {
1209
            $tools .= Display::toolbarButton(
1210
                null,
1211
                null,
1212
                'level-down-alt',
1213
                'outline-secondary',
1214
                [
1215
                    'title' => get_lang("Down"),
1216
                    'class' => 'disabled',
1217
                ]
1218
            );
1219
        }
1220
        $urlDelete = api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=deletecategory&id='.$categoryId."&category_id=$categoryId";
1221
        $tools .= Display::toolbarButton(
1222
            null,
1223
            $urlDelete,
1224
            'trash',
1225
            'outline-secondary',
1226
            [
1227
                'title' => get_lang("Delete"),
1228
                'onclick' => "javascript: if(!confirm('".get_lang('CategoryDelconfirm')."')) return false;",
1229
            ]
1230
        );
1231
1232
        return $tools;
1233
    }
1234
1235
    /**
1236
     * move a link or a linkcategory up or down.
1237
     *
1238
     * @param   int Category ID
1239
     * @param   int Course ID
1240
     * @param   int Session ID
1241
     *
1242
     * @author Patrick Cool <[email protected]>, Ghent University
1243
     *
1244
     * @todo support sessions
1245
     */
1246
    public static function movecatlink($action, $catlinkid, $courseId = null, $sessionId = null)
1247
    {
1248
        $tbl_categories = Database::get_course_table(TABLE_LINK_CATEGORY);
1249
1250
        if (is_null($courseId)) {
1251
            $courseId = api_get_course_int_id();
1252
        }
1253
        $courseId = intval($courseId);
1254
        if (is_null($sessionId)) {
1255
            $sessionId = api_get_session_id();
1256
        }
1257
        $sessionId = intval($sessionId);
1258
        $thiscatlinkId = intval($catlinkid);
1259
1260
        if ($action == 'down') {
1261
            $sortDirection = 'DESC';
1262
        }
1263
1264
        if ($action == 'up') {
1265
            $sortDirection = 'ASC';
1266
        }
1267
1268
        $movetable = $tbl_categories;
1269
1270
        if (!empty($sortDirection)) {
1271
            if (!in_array(trim(strtoupper($sortDirection)), ['ASC', 'DESC'])) {
1272
                $sortDirection = 'ASC';
1273
            }
1274
1275
            $sql = "SELECT id, display_order FROM $movetable
1276
                    WHERE c_id = $courseId
1277
                    ORDER BY display_order $sortDirection";
1278
            $linkresult = Database:: query($sql);
1279
            $thislinkOrder = 1;
1280
            while ($sortrow = Database:: fetch_array($linkresult)) {
1281
                // STEP 2 : FOUND THE NEXT LINK ID AND ORDER, COMMIT SWAP
1282
                // This part seems unlogic, but it isn't . We first look for the current link with the querystring ID
1283
                // and we know the next iteration of the while loop is the next one. These should be swapped.
1284
                if (isset($thislinkFound) && $thislinkFound) {
1285
                    $nextlinkId = $sortrow['id'];
1286
                    $nextlinkOrder = $sortrow['display_order'];
1287
1288
                    Database:: query(
1289
                        "UPDATE ".$movetable."
1290
                        SET display_order = '$nextlinkOrder'
1291
                        WHERE c_id = $courseId  AND id =  '$thiscatlinkId'"
1292
                    );
1293
                    Database:: query(
1294
                        "UPDATE ".$movetable."
1295
                        SET display_order = '$thislinkOrder'
1296
                        WHERE c_id = $courseId  AND id =  '$nextlinkId'"
1297
                    );
1298
1299
                    break;
1300
                }
1301
                if ($sortrow['id'] == $thiscatlinkId) {
1302
                    $thislinkOrder = $sortrow['display_order'];
1303
                    $thislinkFound = true;
1304
                }
1305
            }
1306
        }
1307
1308
        Display::addFlash(Display::return_message(get_lang('LinkMoved')));
1309
    }
1310
1311
    /**
1312
     * CSV file import functions.
1313
     *
1314
     * @author René Haentjens , Ghent University
1315
     *
1316
     * @param string $catname
1317
     *
1318
     * @return int
1319
     */
1320
    public static function get_cat($catname)
1321
    {
1322
        // Get category id (existing or make new).
1323
        $tbl_categories = Database::get_course_table(TABLE_LINK_CATEGORY);
1324
        $course_id = api_get_course_int_id();
1325
1326
        $result = Database:: query(
1327
            "SELECT id FROM ".$tbl_categories."
1328
            WHERE c_id = $course_id AND category_title='".Database::escape_string($catname)."'"
1329
        );
1330
        if (Database:: num_rows($result) >= 1 && ($row = Database:: fetch_array($result))) {
1331
            return $row['id']; // Several categories with same name: take the first.
1332
        }
1333
1334
        $result = Database:: query(
1335
            "SELECT MAX(display_order) FROM ".$tbl_categories." WHERE c_id = $course_id "
1336
        );
1337
        list($max_order) = Database:: fetch_row($result);
1338
1339
        $params = [
1340
            'c_id' => $course_id,
1341
            'category_title' => $catname,
1342
            'description' => '',
1343
            'display_order' => $max_order + 1,
1344
        ];
1345
        $id = Database::insert($tbl_categories, $params);
1346
1347
        return $id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $id could also return false which is incompatible with the documented return type integer. Did you maybe forget to handle an error condition?

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

Loading history...
1348
    }
1349
1350
    /**
1351
     * CSV file import functions.
1352
     *
1353
     * @author René Haentjens , Ghent University
1354
     *
1355
     * @param string $url
1356
     * @param string $title
1357
     * @param string $description
1358
     * @param string $on_homepage
1359
     * @param string $hidden
1360
     */
1361
    public static function put_link($url, $cat, $title, $description, $on_homepage, $hidden)
1362
    {
1363
        $_course = api_get_course_info();
1364
        $_user = api_get_user_info();
1365
1366
        $tbl_link = Database::get_course_table(TABLE_LINK);
1367
        $course_id = api_get_course_int_id();
1368
1369
        $urleq = "url='".Database:: escape_string($url)."'";
1370
        $cateq = "category_id=".intval($cat);
1371
1372
        $result = Database:: query(
1373
            "
1374
            SELECT id FROM $tbl_link
1375
            WHERE c_id = $course_id AND ".$urleq.' AND '.$cateq
1376
        );
1377
1378
        if (Database:: num_rows($result) >= 1 && ($row = Database:: fetch_array($result))) {
1379
            $sql = "UPDATE $tbl_link SET 
1380
                        title = '".Database:: escape_string($title)."', 
1381
                        description = '".Database:: escape_string($description)."'
1382
                    WHERE c_id = $course_id AND  id='".Database:: escape_string($row['id'])."'";
1383
            Database:: query($sql);
1384
1385
            $ipu = 'LinkUpdated';
1386
            $rv = 1; // 1 = upd
1387
        } else {
1388
            // Add new link
1389
            $result = Database:: query(
1390
                "SELECT MAX(display_order) FROM  $tbl_link
1391
                WHERE c_id = $course_id AND category_id='".intval($cat)."'"
1392
            );
1393
            list($max_order) = Database:: fetch_row($result);
1394
1395
            Database:: query(
1396
                "INSERT INTO $tbl_link (c_id, url, title, description, category_id, display_order, on_homepage)
1397
                VALUES (".api_get_course_int_id().",
1398
                '".Database:: escape_string($url)."',
1399
                '".Database:: escape_string($title)."',
1400
                '".Database:: escape_string($description)."',
1401
                '".intval($cat)."','".(intval($max_order) + 1)."',
1402
                '".intval($on_homepage).
1403
                "')"
1404
            );
1405
1406
            $id = Database:: insert_id();
1407
            $ipu = 'LinkAdded';
1408
            $rv = 2; // 2 = new
1409
        }
1410
1411
        api_item_property_update(
1412
            $_course,
1413
            TOOL_LINK,
1414
            $id,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $id does not seem to be defined for all execution paths leading up to this point.
Loading history...
1415
            $ipu,
1416
            $_user['user_id']
1417
        );
1418
1419
        if ($hidden && $ipu == 'LinkAdded') {
1420
            api_item_property_update(
1421
                $_course,
1422
                TOOL_LINK,
1423
                $id,
1424
                'invisible',
1425
                $_user['user_id']
1426
            );
1427
        }
1428
1429
        return $rv;
1430
    }
1431
1432
    /**
1433
     * This function checks if the url is a vimeo link.
1434
     *
1435
     * @author Julio Montoya
1436
     *
1437
     * @version 1.0
1438
     */
1439
    public static function isVimeoLink($url)
1440
    {
1441
        $isLink = strrpos($url, 'vimeo.com');
1442
1443
        return $isLink;
1444
    }
1445
1446
    /**
1447
     * Get vimeo id from URL.
1448
     *
1449
     * @param string $url
1450
     *
1451
     * @return bool|mixed
1452
     */
1453
    public static function getVimeoLinkId($url)
1454
    {
1455
        $possibleUrls = [
1456
            'http://www.vimeo.com/',
1457
            'http://vimeo.com/',
1458
            'https://www.vimeo.com/',
1459
            'https://vimeo.com/',
1460
        ];
1461
        $url = str_replace($possibleUrls, '', $url);
1462
1463
        if (is_numeric($url)) {
1464
            return $url;
1465
        }
1466
1467
        return false;
1468
    }
1469
1470
    /**
1471
     * This function checks if the url is a youtube link.
1472
     *
1473
     * @author Jorge Frisancho
1474
     * @author Julio Montoya - Fixing code
1475
     *
1476
     * @version 1.0
1477
     */
1478
    public static function is_youtube_link($url)
1479
    {
1480
        $is_youtube_link = strrpos($url, 'youtube') || strrpos(
1481
            $url,
1482
            'youtu.be'
1483
        );
1484
1485
        return $is_youtube_link;
1486
    }
1487
1488
    /**
1489
     * This function checks if the url is a PDF File link.
1490
     *
1491
     * @author Jorge Frisancho
1492
     * @author Alex Aragón - Fixing code
1493
     *
1494
     * @version 1.0
1495
     */
1496
    public static function isPdfLink($url)
1497
    {
1498
        $isPdfLink = strrpos(strtolower($url), '.pdf');
1499
1500
        return $isPdfLink;
1501
    }
1502
1503
    /**
1504
     * Get youtube id from an URL.
1505
     *
1506
     * @param string $url
1507
     *
1508
     * @return string
1509
     */
1510
    public static function get_youtube_video_id($url)
1511
    {
1512
        // This is the length of YouTube's video IDs
1513
        $len = 11;
1514
1515
        // The ID string starts after "v=", which is usually right after
1516
        // "youtube.com/watch?" in the URL
1517
        $pos = strpos($url, "v=");
1518
        $id = '';
1519
1520
        //If false try other options
1521
        if ($pos === false) {
1522
            $url_parsed = parse_url($url);
1523
1524
            //Youtube shortener
1525
            //http://youtu.be/ID
1526
            $pos = strpos($url, "youtu.be");
1527
1528
            if ($pos == false) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $pos of type integer to the boolean false. If you are specifically checking for 0, consider using something more explicit like === 0 instead.
Loading history...
1529
                $id = '';
1530
            } else {
1531
                return substr($url_parsed['path'], 1);
1532
            }
1533
1534
            //if empty try the youtube.com/embed/ID
1535
            if (empty($id)) {
1536
                $pos = strpos($url, "embed");
1537
                if ($pos === false) {
1538
                    return '';
1539
                } else {
1540
                    return substr($url_parsed['path'], 7);
1541
                }
1542
            }
1543
        } else {
1544
            // Offset the start location to match the beginning of the ID string
1545
            $pos += 2;
1546
            // Get the ID string and return it
1547
            $id = substr($url, $pos, $len);
1548
1549
            return $id;
1550
        }
1551
    }
1552
1553
    /**
1554
     * @param int    $course_id
1555
     * @param int    $session_id
1556
     * @param int    $categoryId
1557
     * @param string $show
1558
     * @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...
1559
     */
1560
    public static function listLinksAndCategories(
1561
        $course_id,
1562
        $session_id,
1563
        $categoryId,
1564
        $show = 'none',
1565
        $token = null
1566
    ) {
1567
        $tbl_link = Database::get_course_table(TABLE_LINK);
1568
        $tblCIP = Database::get_course_table(TABLE_ITEM_PROPERTY);
1569
        $categoryId = intval($categoryId);
1570
1571
        /*	Action Links */
1572
        echo '<div class="actions">';
1573
        if (api_is_allowed_to_edit(null, true)) {
1574
            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=addlink&category_id='.$categoryId.'">'.
1575
                Display::return_icon('new_link.png', get_lang('LinkAdd'), '', ICON_SIZE_MEDIUM).'</a>';
1576
            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=addcategory&category_id='.$categoryId.'">'.
1577
                Display::return_icon('new_folder.png', get_lang('CategoryAdd'), '', ICON_SIZE_MEDIUM).'</a>';
1578
        }
1579
1580
        $categories = self::getLinkCategories($course_id, $session_id);
1581
        $countCategories = count($categories);
1582
        if (!empty($countCategories)) {
1583
            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=list&show=none">';
1584
            echo Display::return_icon('forum_listview.png', get_lang('FlatView'), '', ICON_SIZE_MEDIUM).' </a>';
1585
1586
            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=list&show=all">';
1587
            echo Display::return_icon('forum_nestedview.png', get_lang('NestedView'), '', ICON_SIZE_MEDIUM).'</a>';
1588
        }
1589
        echo '</div>';
1590
1591
        $counter = 0;
1592
        $category = [];
1593
        $listCategory = [];
1594
1595
        $list['not_category'] = self::showLinksPerCategory(0, $course_id, $session_id);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$list was never initialized. Although not strictly required by PHP, it is generally a good practice to add $list = array(); before regardless.
Loading history...
1596
1597
        foreach ($categories as $myrow) {
1598
            // Student don't see invisible categories.
1599
            if (!api_is_allowed_to_edit(null, true)) {
1600
                if ($myrow['visibility'] == 0) {
1601
                    continue;
1602
                }
1603
            }
1604
1605
            // Validation when belongs to a session
1606
            $showChildren = $categoryId == $myrow['id'] || $show == 'all';
1607
            $category['id'] = $myrow['id'];
1608
            $category['description'] = Security::remove_XSS($myrow['description']);
1609
1610
            $strVisibility = '';
1611
            $visibilityClass = null;
1612
1613
            if ($myrow['visibility'] == '1') {
1614
                $url = 'link.php?'.api_get_cidreq().'&sec_token='.$token.'&action=invisible&id='.$myrow['id'].'&scope='.TOOL_LINK_CATEGORY;
1615
                $title = get_lang('Hide');
1616
                $strVisibility = Display::toolbarButton(null, $url, 'eye', null, ['title' => $title]);
1617
            } elseif ($myrow['visibility'] == '0') {
1618
                $visibilityClass = 'text-muted';
1619
                $url = 'link.php?'.api_get_cidreq().'&sec_token='.$token.'&action=visible&id='.$myrow['id'].'&scope='.TOOL_LINK_CATEGORY;
1620
                $title = get_lang('Show');
1621
                $strVisibility = Display::toolbarButton(null, $url, 'eye-slash', null, ['title' => $title]);
1622
            }
1623
1624
            if ($showChildren) {
1625
                $category['visibility'] = $visibilityClass;
1626
                $category['url'] = api_get_self().'?'.api_get_cidreq().'&category_id=';
1627
            } else {
1628
                $category['visibility'] = $visibilityClass;
1629
                $category['url'] = api_get_self().'?'.api_get_cidreq().'&category_id='.$myrow['id'];
1630
            }
1631
1632
            $category['title'] = Security::remove_XSS($myrow['category_title']);
1633
1634
            $iconTools = '';
1635
1636
            if (api_is_allowed_to_edit(null, true)) {
1637
                if ($session_id == $myrow['session_id']) {
1638
                    $iconTools .= $strVisibility;
1639
                    $iconTools .= self::showCategoryAdminTools($myrow, $counter, count($categories));
1640
                } else {
1641
                    $iconTools .= get_lang('EditionNotAvailableFromSession');
1642
                }
1643
            }
1644
1645
            $category['tools'] = $iconTools;
1646
1647
            $childrenContent = '';
1648
            if ($showChildren) {
1649
                $childrenContent = self::showLinksPerCategory(
1650
                    $myrow['id'],
1651
                    api_get_course_int_id(),
1652
                    api_get_session_id()
1653
                );
1654
            }
1655
            $category['children'] = $childrenContent;
1656
            $listCategory[] = $category;
1657
        }
1658
        $list['in_category'] = $listCategory;
1659
1660
        $tpl = new Template(null);
1661
        $tpl->assign('list_not_category', $list['not_category']);
1662
        $tpl->assign('list_in_category', $list['in_category']);
1663
        $courseInfoLayout = $tpl->get_template("link/index.html.twig");
1664
        $content = $tpl->fetch($courseInfoLayout);
1665
1666
        echo $content;
1667
    }
1668
1669
    /**
1670
     * @param int    $linkId
1671
     * @param string $action
1672
     * @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...
1673
     *
1674
     * @return FormValidator
1675
     */
1676
    public static function getLinkForm($linkId, $action, $token = null)
1677
    {
1678
        $course_id = api_get_course_int_id();
1679
        $session_id = api_get_session_id();
1680
        $linkInfo = self::getLinkInfo($linkId);
1681
        $categoryId = isset($linkInfo['category_id']) ? $linkInfo['category_id'] : '';
1682
        $lpId = isset($_GET['lp_id']) ? Security::remove_XSS($_GET['lp_id']) : null;
1683
1684
        $form = new FormValidator(
1685
            'link',
1686
            'post',
1687
            api_get_self().'?action='.$action.
1688
            '&category_id='.$categoryId.
1689
            '&'.api_get_cidreq().
1690
            '&id='.$linkId.
1691
            '&sec_token='.$token
1692
        );
1693
1694
        if ($action == 'addlink') {
1695
            $form->addHeader(get_lang('LinkAdd'));
1696
        } else {
1697
            $form->addHeader(get_lang('LinkMod'));
1698
        }
1699
1700
        $target_link = '_blank';
1701
        $title = '';
1702
        $category = '';
1703
        $onhomepage = '';
1704
        $description = '';
1705
1706
        if (!empty($linkInfo)) {
1707
            $urllink = $linkInfo['url'];
1708
            $title = $linkInfo['title'];
1709
            $description = $linkInfo['description'];
1710
            $category = $linkInfo['category_id'];
1711
            if ($linkInfo['on_homepage'] != 0) {
1712
                $onhomepage = 1;
1713
            }
1714
            $target_link = $linkInfo['target'];
1715
        }
1716
1717
        $form->addHidden('id', $linkId);
1718
        $form->addText('url', 'URL');
1719
        $form->addRule('url', get_lang('GiveURL'), 'url');
1720
        $form->addText('title', get_lang('LinkName'));
1721
        $form->addHtmlEditor('description', get_lang('Description'), true, false, ['ToolbarSet' => 'Profile', 'Width' => '100%', 'Height' => '130']);
1722
1723
        $resultcategories = self::getLinkCategories($course_id, $session_id);
1724
        $options = ['0' => '--'];
1725
        if (!empty($resultcategories)) {
1726
            foreach ($resultcategories as $myrow) {
1727
                $options[$myrow['id']] = $myrow['category_title'];
1728
            }
1729
        }
1730
1731
        $form->addSelect('category_id', get_lang('Category'), $options);
1732
        $form->addCheckBox('on_homepage', null, get_lang('OnHomepage'));
1733
1734
        $targets = [
1735
            '_self' => get_lang('LinkOpenSelf'),
1736
            '_blank' => get_lang('LinkOpenBlank'),
1737
            '_parent' => get_lang('LinkOpenParent'),
1738
            '_top' => get_lang('LinkOpenTop'),
1739
        ];
1740
1741
        $form->addSelect(
1742
            'target',
1743
            [
1744
                get_lang('LinkTarget'),
1745
                get_lang('AddTargetOfLinkOnHomepage'),
1746
            ],
1747
            $targets
1748
        );
1749
1750
        $defaults = [
1751
            'url' => empty($urllink) ? 'http://' : Security::remove_XSS($urllink),
1752
            'title' => Security::remove_XSS($title),
1753
            'category_id' => $category,
1754
            'on_homepage' => $onhomepage,
1755
            'description' => $description,
1756
            'target' => $target_link,
1757
        ];
1758
1759
        if (api_get_setting('search_enabled') == 'true') {
1760
            require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
1761
            $specific_fields = get_specific_field_list();
1762
            $form->addCheckBox('index_document', get_lang('SearchFeatureDoIndexLink'), get_lang('Yes'));
1763
1764
            foreach ($specific_fields as $specific_field) {
1765
                $default_values = '';
1766
                if ($action == 'editlink') {
1767
                    $filter = [
1768
                        'field_id' => $specific_field['id'],
1769
                        'ref_id' => intval($_GET['id']),
1770
                        'tool_id' => '\''.TOOL_LINK.'\'',
1771
                    ];
1772
                    $values = get_specific_field_values_list($filter, ['value']);
1773
                    if (!empty($values)) {
1774
                        $arr_str_values = [];
1775
                        foreach ($values as $value) {
1776
                            $arr_str_values[] = $value['value'];
1777
                        }
1778
                        $default_values = implode(', ', $arr_str_values);
1779
                    }
1780
                }
1781
                $form->addText($specific_field['name'], $specific_field['code']);
1782
                $defaults[$specific_field['name']] = $default_values;
1783
            }
1784
        }
1785
1786
        $skillList = Skill::addSkillsToForm($form, ITEM_TYPE_LINK, $linkId);
1787
        $form->addHidden('lp_id', $lpId);
1788
        $form->addButtonSave(get_lang('SaveLink'), 'submitLink');
1789
        $defaults['skills'] = array_keys($skillList);
1790
        $form->setDefaults($defaults);
1791
1792
        return $form;
1793
    }
1794
1795
    /**
1796
     * @param int    $id
1797
     * @param string $action
1798
     *
1799
     * @return FormValidator
1800
     */
1801
    public static function getCategoryForm($id, $action)
1802
    {
1803
        $id = (int) $id;
1804
        $action = Security::remove_XSS($action);
1805
1806
        $form = new FormValidator(
1807
            'category',
1808
            'post',
1809
            api_get_self().'?action='.$action.'&'.api_get_cidreq()
1810
        );
1811
1812
        $defaults = [];
1813
        if ($action == 'addcategory') {
1814
            $form->addHeader(get_lang('CategoryAdd'));
1815
            $my_cat_title = get_lang('CategoryAdd');
1816
        } else {
1817
            $form->addHeader(get_lang('CategoryMod'));
1818
            $my_cat_title = get_lang('CategoryMod');
1819
            $defaults = self::getCategory($id);
1820
        }
1821
        $form->addHidden('id', $id);
1822
        $form->addText('category_title', get_lang('CategoryName'));
1823
        $form->addHtmlEditor('description', get_lang('Description'), true, false, ['ToolbarSet' => 'Profile', 'Width' => '100%', 'Height' => '130']);
1824
        $form->addButtonSave($my_cat_title, 'submitCategory');
1825
        $form->setDefaults($defaults);
1826
1827
        return $form;
1828
    }
1829
1830
    /**
1831
     * @param int $id
1832
     *
1833
     * @return array
1834
     */
1835
    public static function getCategory($id)
1836
    {
1837
        $table = Database::get_course_table(TABLE_LINK_CATEGORY);
1838
        $id = (int) $id;
1839
        $courseId = api_get_course_int_id();
1840
1841
        if (empty($id) || empty($courseId)) {
1842
            return [];
1843
        }
1844
        $sql = "SELECT * FROM $table 
1845
                WHERE id = $id AND c_id = $courseId";
1846
        $result = Database::query($sql);
1847
        $category = Database::fetch_array($result, 'ASSOC');
1848
1849
        return $category;
1850
    }
1851
1852
    /**
1853
     * Move a link up in its category.
1854
     *
1855
     * @param int $id
1856
     *
1857
     * @return bool
1858
     */
1859
    public static function moveLinkUp($id)
1860
    {
1861
        return self::moveLinkDisplayOrder($id, 'ASC');
1862
    }
1863
1864
    /**
1865
     * Move a link down in its category.
1866
     *
1867
     * @param int $id
1868
     *
1869
     * @return bool
1870
     */
1871
    public static function moveLinkDown($id)
1872
    {
1873
        return self::moveLinkDisplayOrder($id, 'DESC');
1874
    }
1875
1876
    /**
1877
     * @param string $url
1878
     *
1879
     * @return bool
1880
     */
1881
    public static function checkUrl($url)
1882
    {
1883
        // Check if curl is available.
1884
        if (!in_array('curl', get_loaded_extensions())) {
1885
            return false;
1886
        }
1887
1888
        // set URL and other appropriate options
1889
        $defaults = [
1890
            CURLOPT_URL => $url,
1891
            CURLOPT_FOLLOWLOCATION => true, // follow redirects accept youtube.com
1892
            CURLOPT_HEADER => 0,
1893
            CURLOPT_RETURNTRANSFER => true,
1894
            CURLOPT_TIMEOUT => 4,
1895
        ];
1896
1897
        $proxySettings = api_get_configuration_value('proxy_settings');
1898
1899
        if (!empty($proxySettings) &&
1900
            isset($proxySettings['curl_setopt_array'])
1901
        ) {
1902
            $defaults[CURLOPT_PROXY] = $proxySettings['curl_setopt_array']['CURLOPT_PROXY'];
1903
            $defaults[CURLOPT_PROXYPORT] = $proxySettings['curl_setopt_array']['CURLOPT_PROXYPORT'];
1904
        }
1905
1906
        // Create a new cURL resource
1907
        $ch = curl_init();
1908
        curl_setopt_array($ch, $defaults);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_setopt_array() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

1908
        curl_setopt_array(/** @scrutinizer ignore-type */ $ch, $defaults);
Loading history...
1909
1910
        // grab URL and pass it to the browser
1911
        ob_start();
1912
        $result = curl_exec($ch);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

1912
        $result = curl_exec(/** @scrutinizer ignore-type */ $ch);
Loading history...
1913
        ob_get_clean();
1914
1915
        // close cURL resource, and free up system resources
1916
        curl_close($ch);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_close() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

1916
        curl_close(/** @scrutinizer ignore-type */ $ch);
Loading history...
1917
1918
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result also could return the type string which is incompatible with the documented return type boolean.
Loading history...
1919
    }
1920
1921
    /**
1922
     * Move a link inside its category (display_order field).
1923
     *
1924
     * @param int    $id        The link ID
1925
     * @param string $direction The direction to sort the links
1926
     *
1927
     * @return bool
1928
     */
1929
    private static function moveLinkDisplayOrder($id, $direction)
1930
    {
1931
        $em = Database::getManager();
1932
        /** @var CLink $link */
1933
        $link = $em->find('ChamiloCourseBundle:CLink', $id);
1934
1935
        if (!$link) {
0 ignored issues
show
introduced by
$link is of type Chamilo\CourseBundle\Entity\CLink, thus it always evaluated to true.
Loading history...
1936
            return false;
1937
        }
1938
1939
        $compareLinks = $em
1940
            ->getRepository('ChamiloCourseBundle:CLink')
1941
            ->findBy(
1942
                [
1943
                    'cId' => $link->getCId(),
1944
                    'categoryId' => $link->getCategoryId(),
1945
                ],
1946
                ['displayOrder' => $direction]
1947
            );
1948
1949
        /** @var CLink $prevLink */
1950
        $prevLink = null;
1951
1952
        /** @var CLink $compareLink */
1953
        foreach ($compareLinks as $compareLink) {
1954
            if ($compareLink->getId() !== $link->getId()) {
1955
                $prevLink = $compareLink;
1956
1957
                continue;
1958
            }
1959
1960
            if (!$prevLink) {
1961
                return false;
1962
            }
1963
1964
            $newPrevLinkDisplayOrder = $link->getDisplayOrder();
1965
            $newLinkDisplayOrder = $prevLink->getDisplayOrder();
1966
1967
            $link->setDisplayOrder($newLinkDisplayOrder);
1968
            $prevLink->setDisplayOrder($newPrevLinkDisplayOrder);
1969
1970
            $em->merge($prevLink);
1971
            $em->merge($link);
1972
            break;
1973
        }
1974
1975
        $em->flush();
1976
1977
        return true;
1978
    }
1979
}
1980