Completed
Push — master ( 27e209...a08afa )
by Julito
186:04 queued 150:53
created

Link   F

Complexity

Total Complexity 180

Size/Duplication

Total Lines 1958
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1958
rs 0.6314
c 0
b 0
f 0
wmc 180

32 Methods

Rating   Name   Duplication   Size   Complexity  
B updateLink() 0 27 4
A change_visibility_link() 0 22 3
A getLinksPerCategory() 0 72 2
B get_cat() 0 28 3
F editLink() 0 222 20
F addlinkcategory() 0 216 22
A editCategory() 0 19 1
A __construct() 0 3 1
A setCourse() 0 3 1
B getLinkCategories() 0 73 5
A getLinkInfo() 0 17 4
B deletelinkcategory() 0 59 4
A getCourse() 0 3 2
C movecatlink() 0 63 11
B save() 0 37 3
A delete_link_from_search_engine() 0 22 3
D getLinkForm() 0 115 14
A showCategoryAdminTools() 0 58 3
A moveLinkDown() 0 3 1
F listLinksAndCategories() 0 97 15
B getCategoryForm() 0 24 2
A moveLinkUp() 0 3 1
A is_youtube_link() 0 7 2
C import_link() 0 66 14
B put_link() 0 69 5
B get_youtube_video_id() 0 39 5
A getVimeoLinkId() 0 14 2
D showLinksPerCategory() 0 188 14
B moveLinkDisplayOrder() 0 49 5
A isVimeoLink() 0 5 1
A getCategory() 0 15 3
B checkUrl() 0 38 4

How to fix   Complexity   

Complex Class

Complex classes like Link often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Link, and based on these observations, apply Extract Interface, too.

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
 * @package chamilo.link
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
     * @param array $params
69
     * @param boolean $show_query Whether to show the query in logs when
70
     * calling parent's save method
71
     *
72
     * @return bool True if link could be saved, false otherwise
73
     */
74
    public function save($params, $show_query = null)
75
    {
76
        $course_info = $this->getCourse();
77
        $courseId = $course_info['real_id'];
78
79
        $params['session_id'] = api_get_session_id();
80
        $params['category_id'] = isset($params['category_id']) ? $params['category_id'] : 0;
81
82
        $sql = "SELECT MAX(display_order)
83
                FROM  ".$this->table."
84
                WHERE
85
                    c_id = $courseId AND
86
                    category_id = '".intval($params['category_id'])."'";
87
        $result = Database:: query($sql);
88
        list($orderMax) = Database:: fetch_row($result);
89
        $order = $orderMax + 1;
90
        $params['display_order'] = $order;
91
92
        $id = parent::save($params, $show_query);
93
94
        if (!empty($id)) {
95
            // iid
96
            $sql = "UPDATE ".$this->table." SET id = iid WHERE iid = $id";
97
            Database::query($sql);
98
99
            api_item_property_update(
100
                $course_info,
101
                TOOL_LINK,
102
                $id,
103
                'LinkAdded',
104
                api_get_user_id()
105
            );
106
107
            api_set_default_visibility($id, TOOL_LINK);
108
        }
109
110
        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...
111
    }
112
113
    /**
114
     * Update a link in the database
115
     * @param int $linkId The ID of the link to update
116
     * @param string $linkUrl The new URL to be saved
117
     * @param int   $courseId
118
     * @param int   $sessionId
119
     * @return bool
120
     */
121
    public function updateLink(
122
        $linkId,
123
        $linkUrl,
124
        $courseId = null,
125
        $sessionId = null
126
    ) {
127
        $tblLink = Database::get_course_table(TABLE_LINK);
128
        $linkUrl = Database::escape_string($linkUrl);
129
        $linkId = intval($linkId);
130
        if (is_null($courseId)) {
131
            $courseId = api_get_course_int_id();
132
        }
133
        $courseId = intval($courseId);
134
        if (is_null($sessionId)) {
135
            $sessionId = api_get_session_id();
136
        }
137
        $sessionId = intval($sessionId);
138
        if ($linkUrl != '') {
139
            $sql = "UPDATE $tblLink SET 
140
                    url = '$linkUrl'
141
                    WHERE id = $linkId AND c_id = $courseId AND session_id = $sessionId";
142
            $resLink = Database::query($sql);
143
144
            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...
145
        }
146
147
        return false;
148
    }
149
150
    /**
151
     * Used to add a link or a category
152
     * @param string $type , "link" or "category"
153
     * @todo replace strings by constants
154
     * @author Patrick Cool <[email protected]>, Ghent University
155
     * @return bool True on success, false on failure
156
     */
157
    public static function addlinkcategory($type)
158
    {
159
        $ok = true;
160
        $_course = api_get_course_info();
161
        $course_id = $_course['real_id'];
162
        $session_id = api_get_session_id();
163
164
        if ($type == 'link') {
165
            $title = Security::remove_XSS(stripslashes($_POST['title']));
166
            $urllink = Security::remove_XSS($_POST['url']);
167
            $description = Security::remove_XSS($_POST['description']);
168
            $selectcategory = Security::remove_XSS($_POST['category_id']);
169
170
            if (!isset($_POST['on_homepage'])) {
171
                $onhomepage = 0;
172
            } else {
173
                $onhomepage = Security::remove_XSS($_POST['on_homepage']);
174
            }
175
176
            if (empty($_POST['target'])) {
177
                $target = '_self'; // Default target.
178
            } else {
179
                $target = Security::remove_XSS($_POST['target']);
180
            }
181
182
            $urllink = trim($urllink);
183
            $title = trim($title);
184
            $description = trim($description);
185
186
            // We ensure URL to be absolute.
187
            if (strpos($urllink, '://') === false) {
188
                $urllink = 'http://'.$urllink;
189
            }
190
191
            // If the title is empty, we use the URL as title.
192
            if ($title == '') {
193
                $title = $urllink;
194
            }
195
196
            // If the URL is invalid, an error occurs.
197
            if (!api_valid_url($urllink, true)) {
198
                // A check against an absolute URL
199
                Display::addFlash(Display::return_message(get_lang('GiveURL'), 'error'));
200
201
                return false;
202
            } else {
203
                // Looking for the largest order number for this category.
204
205
                $link = new Link();
206
                $params = [
207
                    'c_id' => $course_id,
208
                    'url' => $urllink,
209
                    'title' => $title,
210
                    'description' => $description,
211
                    'category_id' => $selectcategory,
212
                    'on_homepage' => $onhomepage,
213
                    'target' => $target,
214
                    'session_id' => $session_id,
215
                ];
216
                $link_id = $link->save($params);
217
218
                if ((api_get_setting('search_enabled') == 'true') &&
219
                    $link_id && extension_loaded('xapian')
220
                ) {
221
                    require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
222
223
                    $course_int_id = $_course['real_id'];
224
                    $courseCode = $_course['code'];
225
                    $specific_fields = get_specific_field_list();
226
                    $ic_slide = new IndexableChunk();
227
228
                    // Add all terms to db.
229
                    $all_specific_terms = '';
230
                    foreach ($specific_fields as $specific_field) {
231
                        if (isset($_REQUEST[$specific_field['code']])) {
232
                            $sterms = trim($_REQUEST[$specific_field['code']]);
233
                            if (!empty($sterms)) {
234
                                $all_specific_terms .= ' '.$sterms;
235
                                $sterms = explode(',', $sterms);
236
                                foreach ($sterms as $sterm) {
237
                                    $ic_slide->addTerm(
238
                                        trim($sterm),
239
                                        $specific_field['code']
240
                                    );
241
                                    add_specific_field_value(
242
                                        $specific_field['id'],
243
                                        $courseCode,
244
                                        TOOL_LINK,
245
                                        $link_id,
246
                                        $sterm
247
                                    );
248
                                }
249
                            }
250
                        }
251
                    }
252
253
                    // Build the chunk to index.
254
                    $ic_slide->addValue('title', $title);
255
                    $ic_slide->addCourseId($courseCode);
256
                    $ic_slide->addToolId(TOOL_LINK);
257
                    $xapian_data = [
258
                        SE_COURSE_ID => $courseCode,
259
                        SE_TOOL_ID => TOOL_LINK,
260
                        SE_DATA => [
261
                            'link_id' => (int) $link_id
262
                        ],
263
                        SE_USER => (int) api_get_user_id(),
264
                    ];
265
                    $ic_slide->xapian_data = serialize($xapian_data);
266
                    $description = $all_specific_terms.' '.$description;
267
                    $ic_slide->addValue('content', $description);
268
269
                    // Add category name if set.
270
                    if (isset($selectcategory) && $selectcategory > 0) {
271
                        $table_link_category = Database::get_course_table(
272
                            TABLE_LINK_CATEGORY
273
                        );
274
                        $sql_cat = 'SELECT * FROM %s WHERE id=%d AND c_id = %d LIMIT 1';
275
                        $sql_cat = sprintf(
276
                            $sql_cat,
277
                            $table_link_category,
278
                            (int) $selectcategory,
279
                            $course_int_id
280
                        );
281
                        $result = Database:: query($sql_cat);
282
                        if (Database:: num_rows($result) == 1) {
283
                            $row = Database:: fetch_array($result);
284
                            $ic_slide->addValue(
285
                                'category',
286
                                $row['category_title']
287
                            );
288
                        }
289
                    }
290
291
                    $di = new ChamiloIndexer();
292
                    isset($_POST['language']) ? $lang = Database:: escape_string(
293
                        $_POST['language']
294
                    ) : $lang = 'english';
295
                    $di->connectDb(null, null, $lang);
296
                    $di->addChunk($ic_slide);
297
298
                    // Index and return search engine document id.
299
                    $did = $di->index();
300
                    if ($did) {
301
                        // Save it to db.
302
                        $tbl_se_ref = Database::get_main_table(
303
                            TABLE_MAIN_SEARCH_ENGINE_REF
304
                        );
305
                        $sql = 'INSERT INTO %s (id, course_code, tool_id, ref_id_high_level, search_did)
306
                                VALUES (NULL , \'%s\', \'%s\', %s, %s)';
307
                        $sql = sprintf(
308
                            $sql,
309
                            $tbl_se_ref,
310
                            $course_int_id,
311
                            $courseCode,
312
                            TOOL_LINK,
313
                            $link_id,
314
                            $did
315
                        );
316
                        Database:: query($sql);
317
                    }
318
                }
319
                Display::addFlash(Display::return_message(get_lang('LinkAdded')));
320
            }
321
        } elseif ($type == 'category') {
322
            $tbl_categories = Database::get_course_table(TABLE_LINK_CATEGORY);
323
324
            $category_title = trim($_POST['category_title']);
325
            $description = trim($_POST['description']);
326
327
            if (empty($category_title)) {
328
                echo Display::return_message(get_lang('GiveCategoryName'), 'error');
329
                $ok = false;
330
            } else {
331
                // Looking for the largest order number for this category.
332
                $result = Database:: query(
333
                    "SELECT MAX(display_order) FROM  $tbl_categories
334
                    WHERE c_id = $course_id "
335
                );
336
                list($orderMax) = Database:: fetch_row($result);
337
                $order = $orderMax + 1;
338
                $order = intval($order);
339
                $session_id = api_get_session_id();
340
341
                $params = [
342
                    'c_id' => $course_id,
343
                    'category_title' => $category_title,
344
                    'description' => $description,
345
                    'display_order' => $order,
346
                    'session_id' => $session_id
347
                ];
348
                $linkId = Database::insert($tbl_categories, $params);
349
350
                if ($linkId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $linkId of type integer|false 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...
351
                    // iid
352
                    $sql = "UPDATE $tbl_categories SET id = iid WHERE iid = $linkId";
353
                    Database:: query($sql);
354
355
                    // add link_category visibility
356
                    // course ID is taken from context in api_set_default_visibility
357
                    //api_set_default_visibility($linkId, TOOL_LINK_CATEGORY);
358
                    api_item_property_update(
359
                        $_course,
360
                        TOOL_LINK_CATEGORY,
361
                        $linkId,
362
                        'LinkCategoryAdded',
363
                        api_get_user_id()
364
                    );
365
                    api_set_default_visibility($linkId, TOOL_LINK_CATEGORY);
366
                }
367
368
                Display::addFlash(Display::return_message(get_lang('CategoryAdded')));
369
            }
370
        }
371
372
        return $ok;
373
    }
374
375
    /**
376
     * Used to delete a link or a category
377
     * @author Patrick Cool <[email protected]>, Ghent University
378
     * @param int $id
379
     * @param string $type The type of item to delete
380
     * @return bool
381
     */
382
    public static function deletelinkcategory($id, $type)
383
    {
384
        $courseInfo = api_get_course_info();
385
        $tbl_link = Database::get_course_table(TABLE_LINK);
386
        $tbl_categories = Database::get_course_table(TABLE_LINK_CATEGORY);
387
388
        $course_id = $courseInfo['real_id'];
389
        $id = intval($id);
390
391
        if (empty($id)) {
392
            return false;
393
        }
394
395
        $result = false;
396
397
        switch ($type) {
398
            case 'link':
399
                // -> Items are no longer physically deleted,
400
                // but the visibility is set to 2 (in item_property).
401
                // This will make a restore function possible for the platform administrator.
402
                $sql = "UPDATE $tbl_link SET on_homepage='0'
403
                        WHERE c_id = $course_id AND id='".$id."'";
404
                Database:: query($sql);
405
406
                api_item_property_update(
407
                    $courseInfo,
408
                    TOOL_LINK,
409
                    $id,
410
                    'delete',
411
                    api_get_user_id()
412
                );
413
                self::delete_link_from_search_engine(api_get_course_id(), $id);
414
                Display::addFlash(Display::return_message(get_lang('LinkDeleted')));
415
                $result = true;
416
                break;
417
            case 'category':
418
                // First we delete the category itself and afterwards all the links of this category.
419
                $sql = "DELETE FROM ".$tbl_categories."
420
                        WHERE c_id = $course_id AND id='".$id."'";
421
                Database:: query($sql);
422
423
                $sql = "DELETE FROM ".$tbl_link."
424
                        WHERE c_id = $course_id AND category_id='".$id."'";
425
                Database:: query($sql);
426
427
                api_item_property_update(
428
                    $courseInfo,
429
                    TOOL_LINK_CATEGORY,
430
                    $id,
431
                    'delete',
432
                    api_get_user_id()
433
                );
434
435
                Display::addFlash(Display::return_message(get_lang('CategoryDeleted')));
436
                $result = true;
437
                break;
438
        }
439
440
        return $result;
441
    }
442
443
    /**
444
     * Removes a link from search engine database
445
     * @param string $course_id Course code
446
     * @param int $link_id Document id to delete
447
     * @return void
448
     */
449
    public static function delete_link_from_search_engine($course_id, $link_id)
450
    {
451
        // Remove from search engine if enabled.
452
        if (api_get_setting('search_enabled') === 'true') {
453
            $tbl_se_ref = Database::get_main_table(
454
                TABLE_MAIN_SEARCH_ENGINE_REF
455
            );
456
            $sql = 'SELECT * FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
457
            $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_LINK, $link_id);
458
            $res = Database:: query($sql);
459
            if (Database:: num_rows($res) > 0) {
460
                $row = Database::fetch_array($res);
461
                $di = new ChamiloIndexer();
462
                $di->remove_document($row['search_did']);
463
            }
464
            $sql = 'DELETE FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
465
            $sql = sprintf($sql, $tbl_se_ref, $course_id, TOOL_LINK, $link_id);
466
            Database:: query($sql);
467
468
            // Remove terms from db.
469
            require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
470
            delete_all_values_for_item($course_id, TOOL_DOCUMENT, $link_id);
471
        }
472
    }
473
474
    /**
475
     *
476
     * Get link info
477
     * @param int $id
478
     * @return array link info
479
     *
480
     **/
481
    public static function getLinkInfo($id)
482
    {
483
        $tbl_link = Database::get_course_table(TABLE_LINK);
484
        $course_id = api_get_course_int_id();
485
486
        if (empty($id) || empty($course_id)) {
487
            return [];
488
        }
489
490
        $sql = "SELECT * FROM $tbl_link
491
                WHERE c_id = $course_id AND id='".intval($id)."' ";
492
        $result = Database::query($sql);
493
        $data = [];
494
        if (Database::num_rows($result)) {
495
            $data = Database::fetch_array($result);
496
        }
497
        return $data;
498
    }
499
500
    /**
501
     * @param int $id
502
     * @param array $values
503
     */
504
    public static function editLink($id, $values = [])
505
    {
506
        $tbl_link = Database::get_course_table(TABLE_LINK);
507
        $_course = api_get_course_info();
508
        $course_id = $_course['real_id'];
509
        $id = intval($id);
510
511
        $values['url'] = trim($values['url']);
512
        $values['title'] = trim($values['title']);
513
        $values['description'] = trim($values['description']);
514
        $values['target'] = empty($values['target']) ? '_self' : $values['target'];
515
        $values['on_homepage'] = isset($values['on_homepage']) ? $values['on_homepage'] : '';
516
517
        $categoryId = intval($values['category_id']);
518
519
        // We ensure URL to be absolute.
520
        if (strpos($values['url'], '://') === false) {
521
            $values['url'] = 'http://'.$_POST['url'];
522
        }
523
524
        // If the title is empty, we use the URL as title.
525
        if ($values['title'] == '') {
526
            $values['title'] = $values['url'];
527
        }
528
529
        // If the URL is invalid, an error occurs.
530
        if (!api_valid_url($values['url'], true)) {
531
            Display::addFlash(
532
                Display::return_message(get_lang('GiveURL'), 'error')
533
            );
534
535
            return false;
536
        }
537
538
        if (empty($id) || empty($course_id)) {
539
            return false;
540
        }
541
542
        // Finding the old category_id.
543
        $sql = "SELECT * FROM $tbl_link
544
                WHERE c_id = $course_id AND id='".$id."'";
545
        $result = Database:: query($sql);
546
        $row = Database:: fetch_array($result);
547
        $category_id = $row['category_id'];
548
549
        if ($category_id != $values['category_id']) {
550
            $sql = "SELECT MAX(display_order)
551
                    FROM $tbl_link 
552
                    WHERE
553
                        c_id = $course_id AND
554
                        category_id='".intval($values['category_id'])."'";
555
            $result = Database:: query($sql);
556
            list($max_display_order) = Database:: fetch_row($result);
557
            $max_display_order++;
558
        } else {
559
            $max_display_order = $row['display_order'];
560
        }
561
        $params = [
562
            'url' => $values['url'],
563
            'title' => $values['title'],
564
            'description' => $values['description'],
565
            'category_id' => $values['category_id'],
566
            'display_order' => $max_display_order,
567
            'on_homepage' => $values['on_homepage'],
568
            'target' => $values['target'],
569
            'category_id' => $values['category_id']
570
        ];
571
572
        Database::update(
573
            $tbl_link,
574
            $params,
575
            ['c_id = ? AND id = ?' => [$course_id, $id]]
576
        );
577
578
        // Update search enchine and its values table if enabled.
579
        if (api_get_setting('search_enabled') == 'true') {
580
            $course_int_id = api_get_course_int_id();
581
            $course_id = api_get_course_id();
582
            $link_title = Database:: escape_string($values['title']);
583
            $link_description = Database:: escape_string($values['description']);
584
585
            // Actually, it consists on delete terms from db,
586
            // insert new ones, create a new search engine document, and remove the old one.
587
            // Get search_did.
588
            $tbl_se_ref = Database::get_main_table(
589
                TABLE_MAIN_SEARCH_ENGINE_REF
590
            );
591
            $sql = 'SELECT * FROM %s WHERE course_code=\'%s\' AND tool_id=\'%s\' AND ref_id_high_level=%s LIMIT 1';
592
            $sql = sprintf(
593
                $sql,
594
                $tbl_se_ref,
595
                $course_id,
596
                TOOL_LINK,
597
                $id
598
            );
599
            $res = Database:: query($sql);
600
601
            if (Database:: num_rows($res) > 0) {
602
                require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
603
604
                $se_ref = Database:: fetch_array($res);
605
                $specific_fields = get_specific_field_list();
606
                $ic_slide = new IndexableChunk();
607
608
                $all_specific_terms = '';
609
                foreach ($specific_fields as $specific_field) {
610
                    delete_all_specific_field_value(
611
                        $course_id,
612
                        $specific_field['id'],
613
                        TOOL_LINK,
614
                        $id
615
                    );
616
                    if (isset($_REQUEST[$specific_field['code']])) {
617
                        $sterms = trim(
618
                            $_REQUEST[$specific_field['code']]
619
                        );
620
                        if (!empty($sterms)) {
621
                            $all_specific_terms .= ' '.$sterms;
622
                            $sterms = explode(',', $sterms);
623
                            foreach ($sterms as $sterm) {
624
                                $ic_slide->addTerm(
625
                                    trim($sterm),
626
                                    $specific_field['code']
627
                                );
628
                                add_specific_field_value(
629
                                    $specific_field['id'],
630
                                    $course_id,
631
                                    TOOL_LINK,
632
                                    $id,
633
                                    $sterm
634
                                );
635
                            }
636
                        }
637
                    }
638
                }
639
640
                // Build the chunk to index.
641
                $ic_slide->addValue("title", $link_title);
642
                $ic_slide->addCourseId($course_id);
643
                $ic_slide->addToolId(TOOL_LINK);
644
                $xapian_data = [
645
                    SE_COURSE_ID => $course_id,
646
                    SE_TOOL_ID => TOOL_LINK,
647
                    SE_DATA => [
648
                        'link_id' => (int) $id
649
                    ],
650
                    SE_USER => (int) api_get_user_id(),
651
652
                ];
653
                $ic_slide->xapian_data = serialize($xapian_data);
654
                $link_description = $all_specific_terms.' '.$link_description;
655
                $ic_slide->addValue('content', $link_description);
656
657
                // Add category name if set.
658
                if (isset($categoryId) && $categoryId > 0) {
659
                    $table_link_category = Database::get_course_table(
660
                        TABLE_LINK_CATEGORY
661
                    );
662
                    $sql_cat = 'SELECT * FROM %s WHERE id=%d and c_id = %d LIMIT 1';
663
                    $sql_cat = sprintf(
664
                        $sql_cat,
665
                        $table_link_category,
666
                        $categoryId,
667
                        $course_int_id
668
                    );
669
                    $result = Database:: query($sql_cat);
670
                    if (Database:: num_rows($result) == 1) {
671
                        $row = Database:: fetch_array($result);
672
                        $ic_slide->addValue(
673
                            'category',
674
                            $row['category_title']
675
                        );
676
                    }
677
                }
678
679
                $di = new ChamiloIndexer();
680
                isset($_POST['language']) ? $lang = Database:: escape_string($_POST['language']) : $lang = 'english';
681
                $di->connectDb(null, null, $lang);
682
                $di->remove_document($se_ref['search_did']);
683
                $di->addChunk($ic_slide);
684
685
                // Index and return search engine document id.
686
                $did = $di->index();
687
                if ($did) {
688
                    // Save it to db.
689
                    $sql = 'DELETE FROM %s
690
                            WHERE course_code=\'%s\'
691
                            AND tool_id=\'%s\'
692
                            AND ref_id_high_level=\'%s\'';
693
                    $sql = sprintf(
694
                        $sql,
695
                        $tbl_se_ref,
696
                        $course_id,
697
                        TOOL_LINK,
698
                        $id
699
                    );
700
                    Database:: query($sql);
701
                    $sql = 'INSERT INTO %s (c_id, id, course_code, tool_id, ref_id_high_level, search_did)
702
                            VALUES (NULL , \'%s\', \'%s\', %s, %s)';
703
                    $sql = sprintf(
704
                        $sql,
705
                        $tbl_se_ref,
706
                        $course_int_id,
707
                        $course_id,
708
                        TOOL_LINK,
709
                        $id,
710
                        $did
711
                    );
712
                    Database:: query($sql);
713
                }
714
            }
715
        }
716
717
        // "WHAT'S NEW" notification: update table last_toolEdit.
718
        api_item_property_update(
719
            $_course,
720
            TOOL_LINK,
721
            $id,
722
            'LinkUpdated',
723
            api_get_user_id()
724
        );
725
        Display::addFlash(Display::return_message(get_lang('LinkModded')));
726
    }
727
728
    /**
729
     * @param int $id
730
     * @param array $values
731
     * @return bool
732
     */
733
    public static function editCategory($id, $values)
734
    {
735
        $table = Database::get_course_table(TABLE_LINK_CATEGORY);
736
        $course_id = api_get_course_int_id();
737
        $id = intval($id);
738
739
        // This is used to put the modified info of the category-form into the database.
740
        $params = [
741
            'category_title' => $values['category_title'],
742
            'description' => $values['description']
743
        ];
744
        Database::update(
745
            $table,
746
            $params,
747
            ['c_id = ? AND id = ?' => [$course_id, $id]]
748
        );
749
        Display::addFlash(Display::return_message(get_lang('CategoryModded')));
750
751
        return true;
752
    }
753
754
    /**
755
     * Changes the visibility of a link
756
     * @todo add the changing of the visibility of a course
757
     * @author Patrick Cool <[email protected]>, Ghent University
758
     */
759
    public static function change_visibility_link($id, $scope)
760
    {
761
        $_course = api_get_course_info();
762
        $_user = api_get_user_info();
763
        if ($scope == TOOL_LINK) {
764
            api_item_property_update(
765
                $_course,
766
                TOOL_LINK,
767
                $id,
768
                $_GET['action'],
769
                $_user['user_id']
770
            );
771
            Display::addFlash(Display::return_message(get_lang('VisibilityChanged')));
772
        } elseif ($scope == TOOL_LINK_CATEGORY) {
773
            api_item_property_update(
774
                $_course,
775
                TOOL_LINK_CATEGORY,
776
                $id,
777
                $_GET['action'],
778
                $_user['user_id']
779
            );
780
            Display::addFlash(Display::return_message(get_lang('VisibilityChanged')));
781
        }
782
    }
783
784
    /**
785
     * Generate SQL to select all the links categories in the current course and
786
     * session
787
     * @param   int $courseId
788
     * @param   int $sessionId
789
     * @param   bool $withBaseContent
790
     *
791
     * @return array
792
     */
793
    public static function getLinkCategories($courseId, $sessionId, $withBaseContent = true)
794
    {
795
        $tblLinkCategory = Database::get_course_table(TABLE_LINK_CATEGORY);
796
        $tblItemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
797
        $courseId = intval($courseId);
798
        $courseInfo = api_get_course_info_by_id($courseId);
799
800
        // Condition for the session.
801
        $sessionCondition = api_get_session_condition(
802
            $sessionId,
803
            true,
804
            $withBaseContent,
805
            'linkcat.session_id'
806
        );
807
808
        // Getting links
809
        $sql = "SELECT *, linkcat.id
810
                FROM $tblLinkCategory linkcat
811
                WHERE
812
                    linkcat.c_id = $courseId
813
                    $sessionCondition
814
                ORDER BY linkcat.display_order DESC";
815
816
        $result = Database::query($sql);
817
        $categories = Database::store_result($result);
818
819
        $sql = "SELECT *, linkcat.id
820
                FROM $tblLinkCategory linkcat
821
                INNER JOIN $tblItemProperty ip
822
                ON (linkcat.id = ip.ref AND linkcat.c_id = ip.c_id)
823
                WHERE
824
                    ip.tool = '".TOOL_LINK_CATEGORY."' AND
825
                    (ip.visibility = '0' OR ip.visibility = '1')
826
                    $sessionCondition AND
827
                    linkcat.c_id = ".$courseId."
828
                ORDER BY linkcat.display_order DESC";
829
830
        $result = Database::query($sql);
831
832
        $categoryInItemProperty = [];
833
        if (Database::num_rows($result)) {
834
            while ($row = Database::fetch_array($result, 'ASSOC')) {
835
                $categoryInItemProperty[$row['id']] = $row;
836
            }
837
        }
838
839
        foreach ($categories as & $category) {
840
            if (!isset($categoryInItemProperty[$category['id']])) {
841
                api_item_property_update(
842
                    $courseInfo,
843
                    TOOL_LINK_CATEGORY,
844
                    $category['id'],
845
                    'LinkCategoryAdded',
846
                    api_get_user_id()
847
                );
848
                //api_set_default_visibility($category['id'], TOOL_LINK_CATEGORY);
849
            }
850
        }
851
852
        $sql = "SELECT DISTINCT linkcat.*, visibility
853
                FROM $tblLinkCategory linkcat
854
                INNER JOIN $tblItemProperty ip
855
                ON (linkcat.id = ip.ref AND linkcat.c_id = ip.c_id)
856
                WHERE
857
                    ip.tool = '".TOOL_LINK_CATEGORY."' AND
858
                    (ip.visibility = '0' OR ip.visibility = '1')
859
                    $sessionCondition AND
860
                    linkcat.c_id = ".$courseId."
861
                ORDER BY linkcat.display_order DESC
862
                ";
863
        $result = Database::query($sql);
864
865
        return Database::store_result($result, 'ASSOC');
866
    }
867
868
    /**
869
     * @param integer $categoryId
870
     * @param $courseId
871
     * @param $sessionId
872
     * @param bool $withBaseContent
873
     *
874
     * @return array
875
     */
876
    public static function getLinksPerCategory(
877
        $categoryId,
878
        $courseId,
879
        $sessionId,
880
        $withBaseContent = true
881
    ) {
882
        $tbl_link = Database::get_course_table(TABLE_LINK);
883
        $TABLE_ITEM_PROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY);
884
        $courseId = (int) $courseId;
885
        $sessionId = (int) $sessionId;
886
        $categoryId = (int) $categoryId;
887
888
        // Condition for the session.
889
        $condition_session = api_get_session_condition(
890
            $sessionId,
891
            true,
892
            false,
893
            'ip.session_id'
894
        );
895
896
        if (!empty($sessionId)) {
897
            $conditionBaseSession = api_get_session_condition(
898
                0,
899
                true,
900
                $withBaseContent,
901
                'ip.session_id'
902
            );
903
            $condition = " AND 
904
                (
905
                    (ip.visibility = '1' $conditionBaseSession) OR
906
                     
907
                    (
908
                        (ip.visibility = '0' OR ip.visibility = '1')
909
                        $condition_session
910
                    )
911
                )
912
            ";
913
        } else {
914
            $condition = api_get_session_condition(
915
                0,
916
                true,
917
                false,
918
                'ip.session_id'
919
            );
920
            $condition .= " AND (ip.visibility = '0' OR ip.visibility = '1') $condition ";
921
        }
922
923
        $sql = "SELECT 
924
                    link.id,
925
                    ip.session_id,
926
                    link.session_id link_session_id,
927
                    url,
928
                    category_id,
929
                    visibility,
930
                    description,
931
                    title,
932
                    target,
933
                    on_homepage
934
                FROM $tbl_link link
935
                INNER JOIN $TABLE_ITEM_PROPERTY ip
936
                ON (link.id = ip.ref AND link.c_id = ip.c_id)
937
                WHERE
938
                    ip.tool = '".TOOL_LINK."' AND
939
                    link.category_id = '" . $categoryId."' AND
940
                    link.c_id = $courseId AND
941
                    ip.c_id = $courseId
942
                    $condition
943
                ORDER BY link.display_order ASC, ip.session_id DESC";
944
945
        $result = Database:: query($sql);
946
947
        return Database::store_result($result);
948
    }
949
950
    /**
951
     * Displays all the links of a given category.
952
     * @author Patrick Cool <[email protected]>, Ghent University
953
     * @author Julio Montoya
954
     *
955
     * @param $catid
956
     * @param integer $courseId
957
     * @param integer $session_id
958
     * @return string
959
     */
960
    public static function showLinksPerCategory($catid, $courseId, $session_id)
961
    {
962
        global $token;
963
        $_user = api_get_user_info();
964
        $catid = intval($catid);
965
966
        $links = self::getLinksPerCategory($catid, $courseId, $session_id);
967
        $content = '';
968
        $numberOfLinks = count($links);
969
970
        if (!empty($links)) {
971
            $content .= '<div class="link list-group">';
972
            $i = 1;
973
            $linksAdded = [];
974
            foreach ($links as $myrow) {
975
                $linkId = $myrow['id'];
976
977
                if (in_array($linkId, $linksAdded)) {
978
                    continue;
979
                }
980
981
                $linksAdded[] = $linkId;
982
                $categoryId = $myrow['category_id'];
983
984
                // Validation when belongs to a session.
985
                $session_img = api_get_session_image(
986
                    $myrow['link_session_id'],
987
                    $_user['status']
988
                );
989
990
                $toolbar = '';
991
                $link_validator = '';
992
                if (api_is_allowed_to_edit(null, true)) {
993
                    $toolbar .= Display::toolbarButton(
994
                        '',
995
                        'javascript:void(0);',
996
                        'check-circle-o',
997
                        'default btn-sm',
998
                        [
999
                            'onclick' => "check_url('".$linkId."', '".addslashes($myrow['url'])."');",
1000
                            'title' => get_lang('CheckURL')
1001
                        ]
1002
                    );
1003
1004
                    $link_validator .= Display::span(
1005
                        '',
1006
                        [
1007
                        'id' => 'url_id_'.$linkId,
1008
                        'class' => 'check-link'
1009
                        ]
1010
                    );
1011
1012
                    if ($session_id == $myrow['link_session_id']) {
1013
                        $url = api_get_self().'?'.api_get_cidreq().'&action=editlink&id='.$linkId;
1014
                        $title = get_lang('Edit');
1015
                        $toolbar .= Display::toolbarButton(
1016
                            '',
1017
                            $url,
1018
                            'pencil',
1019
                            'default btn-sm',
1020
                            [
1021
                                'title' => $title
1022
                            ]
1023
                        );
1024
                    }
1025
1026
                    $urlVisibility = api_get_self().'?'.api_get_cidreq().
1027
                            '&sec_token='.$token.
1028
                            '&id='.$linkId.
1029
                            '&scope=link&category_id='.$categoryId;
1030
1031
                    switch ($myrow['visibility']) {
1032
                        case '1':
1033
                            $urlVisibility .= '&action=invisible';
1034
                            $title = get_lang('MakeInvisible');
1035
                            $toolbar .= Display::toolbarButton(
1036
                                '',
1037
                                $urlVisibility,
1038
                                'eye',
1039
                                'default btn-sm',
1040
                                [
1041
                                    'title' => $title
1042
                                ]
1043
                            );
1044
                            break;
1045
                        case '0':
1046
                            $urlVisibility .= '&action=visible';
1047
                            $title = get_lang('MakeVisible');
1048
                            $toolbar .= Display::toolbarButton(
1049
                                '',
1050
                                $urlVisibility,
1051
                                'eye-slash',
1052
                                'primary btn-sm',
1053
                                [
1054
                                    'title' => $title
1055
                                ]
1056
                            );
1057
                            break;
1058
                    }
1059
1060
                    if ($session_id == $myrow['link_session_id']) {
1061
                        $moveLinkParams = [
1062
                            'id' => $linkId,
1063
                            'scope' => 'category',
1064
                            'category_id' => $categoryId,
1065
                            'action' => 'move_link_up'
1066
                        ];
1067
1068
                        $toolbar .= Display::toolbarButton(
1069
                            get_lang('MoveUp'),
1070
                            api_get_self().'?'.api_get_cidreq().'&'.http_build_query($moveLinkParams),
1071
                            'level-up',
1072
                            'default',
1073
                            ['class' => 'btn-sm '.($i === 1 ? 'disabled' : '')],
1074
                            false
1075
                        );
1076
1077
                        $moveLinkParams['action'] = 'move_link_down';
1078
                        $toolbar .= Display::toolbarButton(
1079
                            get_lang('MoveDown'),
1080
                            api_get_self().'?'.api_get_cidreq().'&'.http_build_query($moveLinkParams),
1081
                            'level-down',
1082
                            'default',
1083
                            ['class' => 'btn-sm '.($i === $numberOfLinks ? 'disabled' : '')],
1084
                            false
1085
                        );
1086
1087
                        $url .= api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=deletelink&id='.$linkId.'&category_id='.$categoryId;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $url does not seem to be defined for all execution paths leading up to this point.
Loading history...
1088
                        $event = "javascript: if(!confirm('".get_lang('LinkDelconfirm')."'))return false;";
1089
                        $title = get_lang('Delete');
1090
1091
                        $toolbar .= Display::toolbarButton(
1092
                            '',
1093
                            $url,
1094
                            'trash',
1095
                            'default btn-sm',
1096
                            [
1097
                                'onclick' => $event,
1098
                                'title' => $title
1099
                            ]
1100
                        );
1101
                    }
1102
                }
1103
1104
                $showLink = false;
1105
                $titleClass = '';
1106
                if ($myrow['visibility'] == '1') {
1107
                    $showLink = true;
1108
                } else {
1109
                    if (api_is_allowed_to_edit(null, true)) {
1110
                        $showLink = true;
1111
                        $titleClass = 'text-muted';
1112
                    }
1113
                }
1114
1115
                if ($showLink) {
1116
                    $iconLink = Display::return_icon(
1117
                        'url.png',
1118
                        get_lang('Link'),
1119
                        null,
1120
                        ICON_SIZE_SMALL
1121
                    );
1122
                    $url = api_get_path(WEB_CODE_PATH).'link/link_goto.php?'.api_get_cidreq().'&link_id='.$linkId.'&link_url='.urlencode($myrow['url']);
1123
                    $content .= '<div class="list-group-item">';
1124
                    $content .= '<div class="pull-right"><div class="btn-group">'.$toolbar.'</div></div>';
1125
                    $content .= '<h4 class="list-group-item-heading">';
1126
                    $content .= $iconLink;
1127
                    $content .= Display::tag(
1128
                        'a',
1129
                        Security::remove_XSS($myrow['title']),
1130
                        [
1131
                            'href' => $url,
1132
                            'target' => $myrow['target'],
1133
                            'class' => $titleClass
1134
                        ]
1135
                    );
1136
                    $content .= $link_validator;
1137
                    $content .= $session_img;
1138
                    $content .= '</h4>';
1139
                    $content .= '<p class="list-group-item-text">'.$myrow['description'].'</p>';
1140
                    $content .= '</div>';
1141
                }
1142
                $i++;
1143
            }
1144
            $content .= '</div>';
1145
        }
1146
1147
        return $content;
1148
    }
1149
1150
    /**
1151
     * Displays the edit, delete and move icons
1152
     * @param int   Category ID
1153
     * @param integer $currentCategory
1154
     * @param integer $countCategories
1155
     * @return string
1156
     *
1157
     * @author Patrick Cool <[email protected]>, Ghent University
1158
     */
1159
    public static function showCategoryAdminTools($category, $currentCategory, $countCategories)
1160
    {
1161
        $categoryId = $category['id'];
1162
        $token = null;
1163
        $tools = '<a href="'.api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=editcategory&id='.$categoryId.'&category_id='.$categoryId.'" title='.get_lang('Modify').'">'.
1164
            Display:: return_icon(
1165
                'edit.png',
1166
                get_lang('Modify'),
1167
                [],
1168
                ICON_SIZE_SMALL
1169
            ).'</a>';
1170
1171
        // DISPLAY MOVE UP COMMAND only if it is not the top link.
1172
        if ($currentCategory != 0) {
1173
            $tools .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=up&up='.$categoryId.'&category_id='.$categoryId.'" title="'.get_lang('Up').'">'.
1174
                Display:: return_icon(
1175
                    'up.png',
1176
                    get_lang('Up'),
1177
                    [],
1178
                    ICON_SIZE_SMALL
1179
                ).'</a>';
1180
        } else {
1181
            $tools .= Display:: return_icon(
1182
                'up_na.png',
1183
                get_lang('Up'),
1184
                [],
1185
                ICON_SIZE_SMALL
1186
            ).'</a>';
1187
        }
1188
1189
        // DISPLAY MOVE DOWN COMMAND only if it is not the bottom link.
1190
        if ($currentCategory < $countCategories - 1) {
1191
            $tools .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=down&down='.$categoryId.'&category_id='.$categoryId.'">'.
1192
                Display:: return_icon(
1193
                    'down.png',
1194
                    get_lang('Down'),
1195
                    [],
1196
                    ICON_SIZE_SMALL
1197
                ).'</a>';
1198
        } else {
1199
            $tools .= Display:: return_icon(
1200
                'down_na.png',
1201
                get_lang('Down'),
1202
                [],
1203
                ICON_SIZE_SMALL
1204
            ).'</a>';
1205
        }
1206
1207
        $tools .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&sec_token='.$token.'&action=deletecategory&id='.$categoryId."&category_id=$categoryId\"
1208
            onclick=\"javascript: if(!confirm('".get_lang('CategoryDelconfirm')."')) return false;\">".
1209
            Display:: return_icon(
1210
                'delete.png',
1211
                get_lang('Delete'),
1212
                [],
1213
                ICON_SIZE_SMALL
1214
            ).'</a>';
1215
1216
        return $tools;
1217
    }
1218
1219
    /**
1220
     * move a link or a linkcategory up or down
1221
     * @param   int Category ID
1222
     * @param   int Course ID
1223
     * @param   int Session ID
1224
     * @author Patrick Cool <[email protected]>, Ghent University
1225
     * @todo support sessions
1226
     */
1227
    public static function movecatlink($action, $catlinkid, $courseId = null, $sessionId = null)
1228
    {
1229
        $tbl_categories = Database::get_course_table(TABLE_LINK_CATEGORY);
1230
1231
        if (is_null($courseId)) {
1232
            $courseId = api_get_course_int_id();
1233
        }
1234
        $courseId = intval($courseId);
1235
        if (is_null($sessionId)) {
1236
            $sessionId = api_get_session_id();
1237
        }
1238
        $sessionId = intval($sessionId);
1239
        $thiscatlinkId = intval($catlinkid);
1240
1241
        if ($action == 'down') {
1242
            $sortDirection = 'DESC';
1243
        }
1244
1245
        if ($action == 'up') {
1246
            $sortDirection = 'ASC';
1247
        }
1248
1249
        $movetable = $tbl_categories;
1250
1251
        if (!empty($sortDirection)) {
1252
            if (!in_array(trim(strtoupper($sortDirection)), ['ASC', 'DESC'])) {
1253
                $sortDirection = 'ASC';
1254
            }
1255
1256
            $sql = "SELECT id, display_order FROM $movetable
1257
                    WHERE c_id = $courseId
1258
                    ORDER BY display_order $sortDirection";
1259
            $linkresult = Database:: query($sql);
1260
            $thislinkOrder = 1;
1261
            while ($sortrow = Database:: fetch_array($linkresult)) {
1262
                // STEP 2 : FOUND THE NEXT LINK ID AND ORDER, COMMIT SWAP
1263
                // This part seems unlogic, but it isn't . We first look for the current link with the querystring ID
1264
                // and we know the next iteration of the while loop is the next one. These should be swapped.
1265
                if (isset($thislinkFound) && $thislinkFound) {
1266
                    $nextlinkId = $sortrow['id'];
1267
                    $nextlinkOrder = $sortrow['display_order'];
1268
1269
                    Database:: query(
1270
                        "UPDATE ".$movetable."
1271
                        SET display_order = '$nextlinkOrder'
1272
                        WHERE c_id = $courseId  AND id =  '$thiscatlinkId'"
1273
                    );
1274
                    Database:: query(
1275
                        "UPDATE ".$movetable."
1276
                        SET display_order = '$thislinkOrder'
1277
                        WHERE c_id = $courseId  AND id =  '$nextlinkId'"
1278
                    );
1279
1280
                    break;
1281
                }
1282
                if ($sortrow['id'] == $thiscatlinkId) {
1283
                    $thislinkOrder = $sortrow['display_order'];
1284
                    $thislinkFound = true;
1285
                }
1286
            }
1287
        }
1288
1289
        Display::addFlash(Display::return_message(get_lang('LinkMoved')));
1290
    }
1291
1292
    /**
1293
     * CSV file import functions
1294
     * @author René Haentjens , Ghent University
1295
     * @param string $catname
1296
     * @return int
1297
     */
1298
    public static function get_cat($catname)
1299
    {
1300
        // Get category id (existing or make new).
1301
        $tbl_categories = Database::get_course_table(TABLE_LINK_CATEGORY);
1302
        $course_id = api_get_course_int_id();
1303
1304
        $result = Database:: query(
1305
            "SELECT id FROM ".$tbl_categories."
1306
            WHERE c_id = $course_id AND category_title='".Database::escape_string($catname)."'"
1307
        );
1308
        if (Database:: num_rows($result) >= 1 && ($row = Database:: fetch_array($result))) {
1309
            return $row['id']; // Several categories with same name: take the first.
1310
        }
1311
1312
        $result = Database:: query(
1313
            "SELECT MAX(display_order) FROM ".$tbl_categories." WHERE c_id = $course_id "
1314
        );
1315
        list($max_order) = Database:: fetch_row($result);
1316
1317
        $params = [
1318
            'c_id' => $course_id,
1319
            'category_title' => $catname,
1320
            'description' => '',
1321
            'display_order' => $max_order + 1
1322
        ];
1323
        $id = Database::insert($tbl_categories, $params);
1324
1325
        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...
1326
    }
1327
1328
    /**
1329
     * CSV file import functions
1330
     * @author René Haentjens , Ghent University
1331
     * @param string $url
1332
     * @param string $title
1333
     * @param string $description
1334
     * @param string $on_homepage
1335
     * @param string $hidden
1336
     */
1337
    public static function put_link($url, $cat, $title, $description, $on_homepage, $hidden)
1338
    {
1339
        $_course = api_get_course_info();
1340
        $_user = api_get_user_info();
1341
1342
        $tbl_link = Database::get_course_table(TABLE_LINK);
1343
        $course_id = api_get_course_int_id();
1344
1345
        $urleq = "url='".Database:: escape_string($url)."'";
1346
        $cateq = "category_id=".intval($cat);
1347
1348
        $result = Database:: query(
1349
            "
1350
            SELECT id FROM $tbl_link
1351
            WHERE c_id = $course_id AND ".$urleq.' AND '.$cateq
1352
        );
1353
1354
        if (Database:: num_rows($result) >= 1 && ($row = Database:: fetch_array($result))) {
1355
            $sql = "UPDATE $tbl_link SET 
1356
                        title = '".Database:: escape_string($title)."', 
1357
                        description = '" . Database:: escape_string($description)."'
1358
                    WHERE c_id = $course_id AND  id='".Database:: escape_string($row['id'])."'";
1359
            Database:: query($sql);
1360
1361
            $ipu = 'LinkUpdated';
1362
            $rv = 1; // 1 = upd
1363
        } else {
1364
            // Add new link
1365
            $result = Database:: query(
1366
                "SELECT MAX(display_order) FROM  $tbl_link
1367
                WHERE c_id = $course_id AND category_id='".intval($cat)."'"
1368
            );
1369
            list($max_order) = Database:: fetch_row($result);
1370
1371
            Database:: query(
1372
                "INSERT INTO $tbl_link (c_id, url, title, description, category_id, display_order, on_homepage)
1373
                VALUES (".api_get_course_int_id().",
1374
                '" . Database:: escape_string($url)."',
1375
                '" . Database:: escape_string($title)."',
1376
                '" . Database:: escape_string($description)."',
1377
                '" . intval($cat)."','".(intval($max_order) + 1)."',
1378
                '" . intval($on_homepage).
1379
                "')"
1380
            );
1381
1382
            $id = Database:: insert_id();
1383
            $ipu = 'LinkAdded';
1384
            $rv = 2; // 2 = new
1385
        }
1386
1387
        api_item_property_update(
1388
            $_course,
1389
            TOOL_LINK,
1390
            $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...
1391
            $ipu,
1392
            $_user['user_id']
1393
        );
1394
1395
        if ($hidden && $ipu == 'LinkAdded') {
1396
            api_item_property_update(
1397
                $_course,
1398
                TOOL_LINK,
1399
                $id,
1400
                'invisible',
1401
                $_user['user_id']
1402
            );
1403
        }
1404
1405
        return $rv;
1406
    }
1407
1408
    /**
1409
     * CSV file import functions
1410
     * @author René Haentjens , Ghent University
1411
     */
1412
    public static function import_link($linkdata)
1413
    {
1414
        // url, category_id, title, description, ...
1415
        // Field names used in the uploaded file
1416
        $known_fields = [
1417
            'url',
1418
            'category',
1419
            'title',
1420
            'description',
1421
            'on_homepage',
1422
            'hidden'
1423
        ];
1424
1425
        $hide_fields = [
1426
            'kw',
1427
            'kwd',
1428
            'kwds',
1429
            'keyword',
1430
            'keywords'
1431
        ];
1432
1433
        // All other fields are added to description, as "name:value".
1434
        // Only one hide_field is assumed to be present, <> is removed from value.
1435
        if (!($url = trim($linkdata['url'])) || !($title = trim($linkdata['title']))) {
1436
            return 0; // 0 = fail
1437
        }
1438
1439
        $cat = ($catname = trim($linkdata['category'])) ? self::get_cat($catname) : 0;
1440
1441
        $regs = []; // Will be passed to ereg()
1442
        $d = '';
1443
        foreach ($linkdata as $key => $value) {
1444
            if (!in_array($key, $known_fields)) {
1445
                if (in_array($key, $hide_fields) && ereg(
0 ignored issues
show
Deprecated Code introduced by
The function ereg() has been deprecated: 5.3.0 Use preg_match() instead ( Ignorable by Annotation )

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

1445
                if (in_array($key, $hide_fields) && /** @scrutinizer ignore-deprecated */ ereg(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1446
                        '^<?([^>]*)>?$',
1447
                        $value,
1448
                        $regs
1449
                    )
1450
                ) { // possibly in <...>
1451
                    if (($kwlist = trim($regs[1])) != '') {
1452
                        $kw = '<i kw="'.htmlspecialchars($kwlist).'">';
1453
                    } else {
1454
                        $kw = '';
1455
                    }
1456
                    // i.e. assume only one of the $hide_fields will be present
1457
                    // and if found, hide the value as expando property of an <i> tag
1458
                } elseif (trim($value)) {
1459
                    $d .= ', '.$key.':'.$value;
1460
                }
1461
            }
1462
        }
1463
        if (!empty($d)) {
1464
            $d = substr($d, 2).' - ';
1465
        }
1466
1467
        return self::put_link(
1468
            $url,
1469
            $cat,
1470
            $title,
1471
            $kw.ereg_replace(
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $kw does not seem to be defined for all execution paths leading up to this point.
Loading history...
Deprecated Code introduced by
The function ereg_replace() has been deprecated: 5.3.0 Use preg_replace() instead ( Ignorable by Annotation )

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

1471
            $kw./** @scrutinizer ignore-deprecated */ ereg_replace(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1472
                '\[((/?(b|big|i|small|sub|sup|u))|br/)\]',
1473
                '<\\1>',
1474
                htmlspecialchars($d.$linkdata['description'])
1475
            ).($kw ? '</i>' : ''),
1476
            $linkdata['on_homepage'] ? '1' : '0',
1477
            $linkdata['hidden'] ? '1' : '0'
1478
        );
1479
        // i.e. allow some BBcode tags, e.g. [b]...[/b]
1480
    }
1481
1482
    /**
1483
     * This function checks if the url is a vimeo link
1484
     * @author Julio Montoya
1485
     * @version 1.0
1486
     */
1487
    public static function isVimeoLink($url)
1488
    {
1489
        $isLink = strrpos($url, "vimeo.com");
1490
1491
        return $isLink;
1492
    }
1493
1494
    /**
1495
     * Get vimeo id from URL
1496
     * @param string $url
1497
     * @return bool|mixed
1498
     */
1499
    public static function getVimeoLinkId($url)
1500
    {
1501
        $possibleUrls = [
1502
            'http://www.vimeo.com/',
1503
            'http://vimeo.com/',
1504
            'https://www.vimeo.com/',
1505
            'https://vimeo.com/'
1506
        ];
1507
        $url = str_replace($possibleUrls, '', $url);
1508
1509
        if (is_numeric($url)) {
1510
            return $url;
1511
        }
1512
        return false;
1513
    }
1514
1515
    /**
1516
     * This function checks if the url is a youtube link
1517
     * @author Jorge Frisancho
1518
     * @author Julio Montoya - Fixing code
1519
     * @version 1.0
1520
     */
1521
    public static function is_youtube_link($url)
1522
    {
1523
        $is_youtube_link = strrpos($url, "youtube") || strrpos(
1524
            $url,
1525
            "youtu.be"
1526
        );
1527
        return $is_youtube_link;
1528
    }
1529
1530
    /**
1531
     * Get youtube id from an URL
1532
     * @param string $url
1533
     * @return string
1534
     */
1535
    public static function get_youtube_video_id($url)
1536
    {
1537
        // This is the length of YouTube's video IDs
1538
        $len = 11;
1539
1540
        // The ID string starts after "v=", which is usually right after
1541
        // "youtube.com/watch?" in the URL
1542
        $pos = strpos($url, "v=");
1543
        $id = '';
1544
1545
        //If false try other options
1546
        if ($pos === false) {
1547
            $url_parsed = parse_url($url);
1548
1549
            //Youtube shortener
1550
            //http://youtu.be/ID
1551
            $pos = strpos($url, "youtu.be");
1552
1553
            if ($pos == false) {
1554
                $id = '';
1555
            } else {
1556
                return substr($url_parsed['path'], 1);
1557
            }
1558
1559
            //if empty try the youtube.com/embed/ID
1560
            if (empty($id)) {
1561
                $pos = strpos($url, "embed");
1562
                if ($pos === false) {
1563
                    return '';
1564
                } else {
1565
                    return substr($url_parsed['path'], 7);
1566
                }
1567
            }
1568
        } else {
1569
            // Offset the start location to match the beginning of the ID string
1570
            $pos += 2;
1571
            // Get the ID string and return it
1572
            $id = substr($url, $pos, $len);
1573
            return $id;
1574
        }
1575
    }
1576
1577
    /**
1578
     * @param int $course_id
1579
     * @param int $session_id
1580
     * @param int $categoryId
1581
     * @param string $show
1582
     * @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...
1583
     */
1584
    public static function listLinksAndCategories(
1585
        $course_id,
1586
        $session_id,
1587
        $categoryId,
1588
        $show = 'none',
1589
        $token = null
1590
    ) {
1591
        $tbl_link = Database::get_course_table(TABLE_LINK);
1592
        $tblCIP = Database::get_course_table(TABLE_ITEM_PROPERTY);
1593
        $categoryId = intval($categoryId);
1594
1595
        /*	Action Links */
1596
        echo '<div class="actions">';
1597
        if (api_is_allowed_to_edit(null, true)) {
1598
            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=addlink&category_id='.$categoryId.'">'.
1599
                Display::return_icon('new_link.png', get_lang('LinkAdd'), '', ICON_SIZE_MEDIUM).'</a>';
1600
            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=addcategory&category_id='.$categoryId.'">'.
1601
                Display::return_icon('new_folder.png', get_lang('CategoryAdd'), '', ICON_SIZE_MEDIUM).'</a>';
1602
        }
1603
1604
        $categories = self::getLinkCategories($course_id, $session_id);
1605
        $countCategories = count($categories);
1606
        if (!empty($countCategories)) {
1607
            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=list&show=none">';
1608
            echo Display::return_icon('forum_listview.png', get_lang('FlatView'), '', ICON_SIZE_MEDIUM).' </a>';
1609
1610
            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=list&show=all">';
1611
            echo Display::return_icon('forum_nestedview.png', get_lang('NestedView'), '', ICON_SIZE_MEDIUM).'</a>';
1612
        }
1613
        echo '</div>';
1614
        $linksPerCategory = self::showLinksPerCategory(0, $course_id, $session_id);
1615
1616
        if (empty($countCategories)) {
1617
            echo $linksPerCategory;
1618
        } else {
1619
            if (!empty($linksPerCategory)) {
1620
                echo Display::panel($linksPerCategory, get_lang('NoCategory'));
1621
            }
1622
        }
1623
1624
        $counter = 0;
1625
        foreach ($categories as $myrow) {
1626
            // Student don't see invisible categories.
1627
            if (!api_is_allowed_to_edit(null, true)) {
1628
                if ($myrow['visibility'] == 0) {
1629
                    continue;
1630
                }
1631
            }
1632
1633
            // Validation when belongs to a session
1634
            $showChildren = $categoryId == $myrow['id'] || $show == 'all';
1635
            $myrow['description'] = $myrow['description'];
1636
1637
            $strVisibility = '';
1638
            $visibilityClass = null;
1639
            if ($myrow['visibility'] == '1') {
1640
                $strVisibility = '<a href="link.php?'.api_get_cidreq().'&sec_token='.$token.'&action=invisible&id='.$myrow['id'].'&scope='.TOOL_LINK_CATEGORY.'" title="'.get_lang('Hide').'">'.
1641
                    Display::return_icon('visible.png', get_lang('Hide'), [], ICON_SIZE_SMALL).'</a>';
1642
            } elseif ($myrow['visibility'] == '0') {
1643
                $visibilityClass = 'text-muted';
1644
                $strVisibility = ' <a href="link.php?'.api_get_cidreq().'&sec_token='.$token.'&action=visible&id='.$myrow['id'].'&scope='.TOOL_LINK_CATEGORY.'" title="'.get_lang('Show').'">'.
1645
                    Display::return_icon('invisible.png', get_lang('Show'), [], ICON_SIZE_SMALL).'</a>';
1646
            }
1647
1648
            $header = '';
1649
            if ($showChildren) {
1650
                $header .= '<a class="'.$visibilityClass.'" href="'.api_get_self().'?'.api_get_cidreq().'&category_id=">';
1651
                $header .= Display::return_icon('forum_nestedview.png');
1652
            } else {
1653
                $header .= '<a class="'.$visibilityClass.'" href="'.api_get_self().'?'.api_get_cidreq().'&category_id='.$myrow['id'].'">';
1654
                $header .= Display::return_icon('forum_listview.png');
1655
            }
1656
1657
            $header .= Security::remove_XSS($myrow['category_title']).'</a>';
1658
            $header .= '<div class="pull-right">';
1659
1660
            if (api_is_allowed_to_edit(null, true)) {
1661
                if ($session_id == $myrow['session_id']) {
1662
                    $header .= $strVisibility;
1663
                    $header .= self::showCategoryAdminTools($myrow, $counter, count($categories));
1664
                } else {
1665
                    $header .= get_lang('EditionNotAvailableFromSession');
1666
                }
1667
            }
1668
1669
            $childrenContent = '';
1670
            if ($showChildren) {
1671
                $childrenContent = self::showLinksPerCategory(
1672
                    $myrow['id'],
1673
                    api_get_course_int_id(),
1674
                    api_get_session_id()
1675
                );
1676
            }
1677
1678
            echo Display::panel($myrow['description'].$childrenContent, $header);
1679
1680
            $counter++;
1681
        }
1682
    }
1683
1684
    /**
1685
     * @param int $linkId
1686
     * @param $action
1687
     * @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...
1688
     *
1689
     * @return FormValidator
1690
     */
1691
    public static function getLinkForm($linkId, $action, $token = null)
1692
    {
1693
        $course_id = api_get_course_int_id();
1694
        $session_id = api_get_session_id();
1695
        $linkInfo = self::getLinkInfo($linkId);
1696
        $categoryId = isset($linkInfo['category_id']) ? $linkInfo['category_id'] : '';
1697
        $lpId = isset($_GET['lp_id']) ? Security::remove_XSS($_GET['lp_id']) : null;
1698
1699
        $form = new FormValidator(
1700
            'link',
1701
            'post',
1702
            api_get_self().'?action='.$action.
1703
            '&category_id='.$categoryId.
1704
            '&'.api_get_cidreq().
1705
            '&id='.$linkId.
1706
            '&sec_token='.$token
1707
        );
1708
1709
        if ($action == 'addlink') {
1710
            $form->addHeader(get_lang('LinkAdd'));
1711
        } else {
1712
            $form->addHeader(get_lang('LinkMod'));
1713
        }
1714
1715
        $target_link = '_blank';
1716
        $title = '';
1717
        $category = '';
1718
        $onhomepage = '';
1719
        $description = '';
1720
1721
        if (!empty($linkInfo)) {
1722
            $urllink = $linkInfo['url'];
1723
            $title = $linkInfo['title'];
1724
            $description = $linkInfo['description'];
1725
            $category = $linkInfo['category_id'];
1726
            if ($linkInfo['on_homepage'] != 0) {
1727
                $onhomepage = 1;
1728
            }
1729
            $target_link = $linkInfo['target'];
1730
        }
1731
1732
        $form->addHidden('id', $linkId);
1733
        $form->addText('url', 'URL');
1734
        $form->addRule('url', get_lang('GiveURL'), 'url');
1735
        $form->addText('title', get_lang('LinkName'));
1736
        $form->addTextarea('description', get_lang('Description'));
1737
1738
        $resultcategories = self::getLinkCategories($course_id, $session_id);
1739
        $options = ['0' => '--'];
1740
        if (!empty($resultcategories)) {
1741
            foreach ($resultcategories as $myrow) {
1742
                $options[$myrow['id']] = $myrow['category_title'];
1743
            }
1744
        }
1745
1746
        $form->addSelect('category_id', get_lang('Category'), $options);
1747
        $form->addCheckBox('on_homepage', null, get_lang('OnHomepage'));
1748
1749
        $targets = [
1750
            '_self' => get_lang('LinkOpenSelf'),
1751
            '_blank' => get_lang('LinkOpenBlank'),
1752
            '_parent' => get_lang('LinkOpenParent'),
1753
            '_top' => get_lang('LinkOpenTop')
1754
        ];
1755
1756
        $form->addSelect(
1757
            'target',
1758
            [
1759
                get_lang('LinkTarget'),
1760
                get_lang('AddTargetOfLinkOnHomepage')
1761
            ],
1762
            $targets
1763
        );
1764
1765
        $defaults = [
1766
            'url' => empty($urllink) ? 'http://' : Security::remove_XSS($urllink),
1767
            'title' => Security::remove_XSS($title),
1768
            'category_id' => $category,
1769
            'on_homepage' => $onhomepage,
1770
            'description' => $description,
1771
            'target' => $target_link
1772
        ];
1773
1774
        if (api_get_setting('search_enabled') == 'true') {
1775
            require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
1776
            $specific_fields = get_specific_field_list();
1777
            $form->addCheckBox('index_document', get_lang('SearchFeatureDoIndexLink'), get_lang('Yes'));
1778
1779
            foreach ($specific_fields as $specific_field) {
1780
                $default_values = '';
1781
                if ($action == 'editlink') {
1782
                    $filter = [
1783
                        'field_id' => $specific_field['id'],
1784
                        'ref_id' => intval($_GET['id']),
1785
                        'tool_id' => '\''.TOOL_LINK.'\''
1786
                    ];
1787
                    $values = get_specific_field_values_list($filter, ['value']);
1788
                    if (!empty($values)) {
1789
                        $arr_str_values = [];
1790
                        foreach ($values as $value) {
1791
                            $arr_str_values[] = $value['value'];
1792
                        }
1793
                        $default_values = implode(', ', $arr_str_values);
1794
                    }
1795
                }
1796
                $form->addText($specific_field['name'], $specific_field['code']);
1797
                $defaults[$specific_field['name']] = $default_values;
1798
            }
1799
        }
1800
1801
        $form->addHidden('lp_id', $lpId);
1802
        $form->addButtonSave(get_lang('SaveLink'), 'submitLink');
1803
        $form->setDefaults($defaults);
1804
1805
        return $form;
1806
    }
1807
1808
    /**
1809
     * @param int $id
1810
     * @param string $action
1811
     *
1812
     * @return FormValidator
1813
     */
1814
    public static function getCategoryForm($id, $action)
1815
    {
1816
        $form = new FormValidator(
1817
            'category',
1818
            'post',
1819
            api_get_self().'?action='.$action.'&'.api_get_cidreq()
1820
        );
1821
1822
        $defaults = [];
1823
        if ($action == 'addcategory') {
1824
            $form->addHeader(get_lang('CategoryAdd'));
1825
            $my_cat_title = get_lang('CategoryAdd');
1826
        } else {
1827
            $form->addHeader(get_lang('CategoryMod'));
1828
            $my_cat_title = get_lang('CategoryMod');
1829
            $defaults = self::getCategory($id);
1830
        }
1831
        $form->addHidden('id', $id);
1832
        $form->addText('category_title', get_lang('CategoryName'));
1833
        $form->addTextarea('description', get_lang('Description'));
1834
        $form->addButtonSave($my_cat_title, 'submitCategory');
1835
        $form->setDefaults($defaults);
1836
1837
        return $form;
1838
    }
1839
1840
    /**
1841
     * @param int $id
1842
     * @return array
1843
     */
1844
    public static function getCategory($id)
1845
    {
1846
        $table = Database::get_course_table(TABLE_LINK_CATEGORY);
1847
        $id = intval($id);
1848
        $courseId = api_get_course_int_id();
1849
1850
        if (empty($id) || empty($courseId)) {
1851
            return [];
1852
        }
1853
        $sql = "SELECT * FROM $table 
1854
                WHERE id = $id AND c_id = $courseId";
1855
        $result = Database::query($sql);
1856
        $category = Database::fetch_array($result, 'ASSOC');
1857
1858
        return $category;
1859
    }
1860
1861
    /**
1862
     * Move a link inside its category (display_order field)
1863
     * @param int $id The link ID
1864
     * @param string $direction The direction to sort the links
1865
     * @return bool
1866
     */
1867
    private static function moveLinkDisplayOrder($id, $direction)
1868
    {
1869
        $em = Database::getManager();
1870
        /** @var CLink $link */
1871
        $link = $em->find('ChamiloCourseBundle:CLink', $id);
1872
1873
        if (!$link) {
1874
            return false;
1875
        }
1876
1877
        $compareLinks = $em
1878
            ->getRepository('ChamiloCourseBundle:CLink')
1879
            ->findBy(
1880
                [
1881
                    'cId' => $link->getCId(),
1882
                    'categoryId' => $link->getCategoryId()
1883
                ],
1884
                ['displayOrder' => $direction]
1885
            );
1886
1887
        /** @var CLink $prevLink */
1888
        $prevLink = null;
1889
1890
        /** @var CLink $compareLink */
1891
        foreach ($compareLinks as $compareLink) {
1892
            if ($compareLink->getId() !== $link->getId()) {
1893
                $prevLink = $compareLink;
1894
1895
                continue;
1896
            }
1897
1898
            if (!$prevLink) {
1899
                return false;
1900
            }
1901
1902
            $newPrevLinkDisplayOrder = $link->getDisplayOrder();
1903
            $newLinkDisplayOrder = $prevLink->getDisplayOrder();
1904
1905
            $link->setDisplayOrder($newLinkDisplayOrder);
1906
            $prevLink->setDisplayOrder($newPrevLinkDisplayOrder);
1907
1908
            $em->merge($prevLink);
1909
            $em->merge($link);
1910
            break;
1911
        }
1912
1913
        $em->flush();
1914
1915
        return true;
1916
    }
1917
1918
    /**
1919
     * Move a link up in its category
1920
     * @param int $id
1921
     * @return bool
1922
     */
1923
    public static function moveLinkUp($id)
1924
    {
1925
        return self::moveLinkDisplayOrder($id, 'ASC');
1926
    }
1927
1928
    /**
1929
     * Move a link down in its category
1930
     * @param int $id
1931
     * @return bool
1932
     */
1933
    public static function moveLinkDown($id)
1934
    {
1935
        return self::moveLinkDisplayOrder($id, 'DESC');
1936
    }
1937
1938
    /**
1939
     * @param string $url
1940
     * @return bool
1941
     */
1942
    public static function checkUrl($url)
1943
    {
1944
        // Check if curl is available.
1945
        if (!in_array('curl', get_loaded_extensions())) {
1946
            return false;
1947
        }
1948
1949
        // set URL and other appropriate options
1950
        $defaults = [
1951
            CURLOPT_URL => $url,
1952
            CURLOPT_FOLLOWLOCATION => true, // follow redirects accept youtube.com
1953
            CURLOPT_HEADER => 0,
1954
            CURLOPT_RETURNTRANSFER => true,
1955
            CURLOPT_TIMEOUT => 4
1956
        ];
1957
1958
        $proxySettings = api_get_configuration_value('proxy_settings');
1959
1960
        if (!empty($proxySettings) &&
1961
            isset($proxySettings['curl_setopt_array'])
1962
        ) {
1963
            $defaults[CURLOPT_PROXY] = $proxySettings['curl_setopt_array']['CURLOPT_PROXY'];
1964
            $defaults[CURLOPT_PROXYPORT] = $proxySettings['curl_setopt_array']['CURLOPT_PROXYPORT'];
1965
        }
1966
1967
        // Create a new cURL resource
1968
        $ch = curl_init();
1969
        curl_setopt_array($ch, $defaults);
1970
1971
        // grab URL and pass it to the browser
1972
        ob_start();
1973
        $result = curl_exec($ch);
1974
        ob_get_clean();
1975
1976
        // close cURL resource, and free up system resources
1977
        curl_close($ch);
1978
1979
        return $result;
1980
    }
1981
}
1982