Passed
Push — master ( 4bcd7f...0f4d24 )
by Julito
10:45 queued 10s
created

GlossaryManager::sorter()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 3
nc 3
nop 2
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Framework\Container;
6
use Chamilo\CourseBundle\Entity\CGlossary;
7
use ChamiloSession as Session;
8
use Doctrine\ORM\NoResultException;
9
10
/**
11
 * Class GlossaryManager
12
 * This library provides functions for the glossary tool.
13
 * Include/require it in your code to use its functionality.
14
 *
15
 * @author Julio Montoya
16
 * @author Christian Fasanando
17
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium januari 2009, dokeos 1.8.6
18
 */
19
class GlossaryManager
20
{
21
    /**
22
     * Get all glossary terms.
23
     *
24
     * @author Isaac Flores <[email protected]>
25
     *
26
     * @return array Contain glossary terms
27
     */
28
    public static function get_glossary_terms()
29
    {
30
        $glossaryData = [];
31
        $repo = Container::getGlossaryRepository();
32
33
        $courseId = api_get_course_int_id();
34
        $sessionId = api_get_session_id();
35
36
        $course = api_get_course_entity($courseId);
37
        $session = api_get_session_entity($sessionId);
38
39
        $glossaries = $repo->getResourcesByCourse($course, $session);
40
        /** @var CGlossary $item */
41
        foreach ($glossaries as $item) {
42
            $glossaryData[] = [
43
                'id' => $item->getIid(),
44
                'name' => $item->getName(),
45
                'description' => $item->getDescription(),
46
            ];
47
        }
48
49
        return $glossaryData;
50
51
        /*
52
        $table = Database::get_course_table(TABLE_GLOSSARY);
53
        $session_id = api_get_session_id();
54
        $sql_filter = api_get_session_condition($session_id);
55
        $course_id = api_get_course_int_id();
56
57
        $sql = "SELECT glossary_id as id, name, description
58
                FROM $table
59
                WHERE c_id = $course_id $sql_filter";
60
        $rs = Database::query($sql);
61
        while ($row = Database::fetch_array($rs)) {
62
            $glossary_data[] = $row;
63
        }
64
65
        return $glossary_data;
66
        */
67
    }
68
69
    /**
70
     * Get glossary description by glossary id.
71
     *
72
     * @author Isaac Flores <[email protected]>
73
     *
74
     * @param int $glossary_id
75
     *
76
     * @return string The glossary description
77
     */
78
    public static function get_glossary_term_by_glossary_id($glossary_id)
79
    {
80
        $repo = Container::getGlossaryRepository();
81
        /** @var CGlossary $glossary */
82
        $glossary = $repo->find($glossary_id);
83
        $description = '';
84
        if (null !== $glossary) {
85
            $description = $glossary->getDescription();
86
        }
87
88
        return $description;
89
90
        /*
91
        $table = Database::get_course_table(TABLE_GLOSSARY);
92
        $course_id = api_get_course_int_id();
93
        $glossary_id = (int) $glossary_id;
94
95
        $sql = "SELECT description
96
                FROM $table
97
                WHERE c_id = $course_id  AND glossary_id =".$glossary_id;
98
        $rs = Database::query($sql);
99
        if (Database::num_rows($rs) > 0) {
100
            $row = Database::fetch_array($rs);
101
102
            return $row['description'];
103
        }
104
105
        return '';
106
        */
107
    }
108
109
    /**
110
     * Get glossary term by glossary id.
111
     *
112
     * @author Isaac Flores <[email protected]>
113
     *
114
     * @param string $name The glossary term name
115
     *
116
     * @return array The glossary info
117
     */
118
    public static function get_glossary_term_by_glossary_name($name)
119
    {
120
        // @todo Filter by like on ORM
121
        $table = Database::get_course_table(TABLE_GLOSSARY);
122
        $sessionId = api_get_session_id();
123
        $course_id = api_get_course_int_id();
124
        $sessionCondition = api_get_session_condition($sessionId);
125
126
        $glossaryName = Security::remove_XSS($name);
127
        $glossaryName = api_convert_encoding($glossaryName, 'UTF-8', 'UTF-8');
128
        $glossaryName = trim($glossaryName);
129
        $parsed = $glossaryName;
130
131
        if (api_get_configuration_value('save_titles_as_html')) {
132
            $parsed = api_htmlentities($parsed);
133
            $parsed = "%$parsed%";
134
        }
135
136
        $sql = "SELECT * FROM $table
137
		        WHERE
138
		            c_id = $course_id AND
139
		            (
140
		                name LIKE '".Database::escape_string($glossaryName)."'
141
		                OR
142
		                name LIKE '".Database::escape_string($parsed)."'
143
                    )
144
                    $sessionCondition
145
                LIMIT 1
146
                ";
147
        $rs = Database::query($sql);
148
149
        if (Database::num_rows($rs) > 0) {
150
            return Database::fetch_array($rs, 'ASSOC');
151
        }
152
153
        return [];
154
    }
155
156
    /**
157
     * This functions stores the glossary in the database.
158
     *
159
     * @param array $values Array of title + description (name => $title, description => $comment)
160
     *
161
     * @return mixed Term id on success, false on failure
162
     */
163
    public static function save_glossary($values, $showMessage = true)
164
    {
165
        if (!is_array($values) || !isset($values['name'])) {
166
            return false;
167
        }
168
169
        // get the maximum display order of all the glossary items
170
        $max_glossary_item = self::get_max_glossary_item();
171
172
        // check if the glossary term already exists
173
        if (self::glossary_exists($values['name'])) {
174
            // display the feedback message
175
            if ($showMessage) {
176
                Display::addFlash(
177
                    Display::return_message(get_lang('This glossary term already exists. Please change the term name.'), 'error')
178
                );
179
            }
180
181
            return false;
182
        } else {
183
            $glossary = new CGlossary();
184
185
            $courseId = api_get_course_int_id();
186
            $sessionId = api_get_session_id();
187
188
            $glossary
189
                ->setName($values['name'])
190
                ->setDescription($values['description'])
191
                ->setDisplayOrder($max_glossary_item + 1)
192
            ;
193
194
            $course = api_get_course_entity($courseId);
195
            $session = api_get_session_entity($sessionId);
196
            $glossary->setParent($course);
197
            $glossary->addCourseLink($course, $session);
198
199
            $repo = Container::getGlossaryRepository();
200
            $repo->create($glossary);
201
            /*
202
            throw new Exception('implement resources');
203
204
205
            // Database table definition
206
            $table = Database::get_course_table(TABLE_GLOSSARY);
207
            $params = [
208
                'glossary_id' => 0,
209
                'c_id' => api_get_course_int_id(),
210
                'name' => $values['name'],
211
                'description' => $values['description'],
212
                'display_order' => $max_glossary_item + 1,
213
                'session_id' => $session_id,
214
            ];
215
            $id = Database::insert($table, $params);
216
217
            if ($id) {
218
                $sql = "UPDATE $table SET glossary_id = $id WHERE iid = $id";
219
                Database::query($sql);
220
221
                //insert into item_property
222
                /*api_item_property_update(
223
                    api_get_course_info(),
224
                    TOOL_GLOSSARY,
225
                    $id,
226
                    'GlossaryAdded',
227
                    api_get_user_id()
228
                );* /
229
            }
230
            */
231
            // display the feedback message
232
            if ($showMessage) {
233
                Display::addFlash(
234
                    Display::return_message(get_lang('Term added'))
235
                );
236
            }
237
238
            return $glossary;
239
        }
240
    }
241
242
    /**
243
     * update the information of a glossary term in the database.
244
     *
245
     * @param array $values an array containing all the form elements
246
     *
247
     * @return bool True on success, false on failure
248
     */
249
    public static function update_glossary($values, $showMessage = true)
250
    {
251
        /*
252
        // Database table definition
253
        $table = Database::get_course_table(TABLE_GLOSSARY);
254
        $course_id = api_get_course_int_id();
255
256
        */
257
        // check if the glossary term already exists
258
        if (self::glossary_exists($values['name'], $values['glossary_id'])) {
259
            // display the feedback message
260
            if ($showMessage) {
261
                Display::addFlash(
262
                    Display::return_message(get_lang('This glossary term already exists. Please change the term name.'), 'error')
263
                );
264
            }
265
266
            return false;
267
        } else {
268
            $repo = Container::getGlossaryRepository();
269
270
            /** @var CGlossary $glossary */
271
            $glossary = $repo->find($values['glossary_id']);
272
            if (null !== $glossary) {
273
                $glossary
274
                    ->setName($values['name'])
275
                    ->setDescription($values['description']);
276
                $repo->update($glossary);
277
            }
278
            /*
279
280
            $sql = "UPDATE $table SET
281
                        name = '".Database::escape_string($values['name'])."',
282
                        description	= '".Database::escape_string($values['description'])."'
283
                    WHERE
284
                        c_id = $course_id AND
285
                        glossary_id = ".intval($values['glossary_id']);
286
            $result = Database::query($sql);
287
            if (false === $result) {
288
                return false;
289
            }
290
291
            //update glossary into item_property
292
            /*api_item_property_update(
293
                api_get_course_info(),
294
                TOOL_GLOSSARY,
295
                intval($values['glossary_id']),
296
                'GlossaryUpdated',
297
                api_get_user_id()
298
            );* /
299
300
            */
301
            if ($showMessage) {
302
                // display the feedback message
303
                Display::addFlash(
304
                    Display::return_message(get_lang('Term updated'))
305
                );
306
            }
307
        }
308
309
        return true;
310
    }
311
312
    /**
313
     * Get the maximum display order of the glossary item.
314
     *
315
     * @return int Maximum glossary display order
316
     */
317
    public static function get_max_glossary_item()
318
    {
319
        // @todo get max by orm
320
        /*
321
        $repo = Container::getGlossaryRepository();
322
323
        $findArray  = [
324
            'cId' => api_get_course_int_id(),
325
            'sessionId' => api_get_session_id(),
326
            'name'=>$term,
327
        ];
328
        $glossary = $repo->findBy($findArray);
329
        */
330
        // Database table definition
331
332
        $repo = Container::getGlossaryRepository();
333
334
        $courseId = api_get_course_int_id();
335
        $sessionId = api_get_session_id();
336
337
        $course = api_get_course_entity($courseId);
338
        $session = api_get_session_entity($sessionId);
339
        $qb = $repo->getResourcesByCourse($course, $session);
340
341
        try {
342
            $count = $qb->select('COUNT(resource)')->getQuery()->getSingleScalarResult();
343
        } catch (NoResultException $e) {
344
            $count = 0;
345
        }
346
347
        return $count;
348
349
        $table = Database::get_course_table(TABLE_GLOSSARY);
0 ignored issues
show
Unused Code introduced by
$table = Database::get_c...e_table(TABLE_GLOSSARY) is not reachable.

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

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

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

    return false;
}

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

Loading history...
350
        $course_id = api_get_course_int_id();
351
        $get_max = "SELECT MAX(display_order) FROM $table
352
                    WHERE c_id = $course_id ";
353
        $res_max = Database::query($get_max);
354
        if (0 == Database::num_rows($res_max)) {
355
            return 0;
356
        }
357
        $row = Database::fetch_array($res_max);
358
        if (!empty($row[0])) {
359
            return $row[0];
360
        }
361
362
        return 0;
363
    }
364
365
    /**
366
     * check if the glossary term exists or not.
367
     *
368
     * @param string $term   Term to look for
369
     * @param int    $not_id ID to counter-check if the term exists with this ID as well (optional)
370
     *
371
     * @return bool True if term exists
372
     */
373
    public static function glossary_exists($term, $not_id = 0)
374
    {
375
        $repo = Container::getGlossaryRepository();
376
377
        $courseId = api_get_course_int_id();
378
        $sessionId = api_get_session_id();
379
380
        $course = api_get_course_entity($courseId);
381
        $session = api_get_session_entity($sessionId);
382
383
        $qb = $repo->getResourcesByCourse($course, $session);
384
        $glossaries = $qb->getQuery()->getResult();
385
386
        if (0 == count($glossaries)) {
387
            return false;
388
        }
389
390
        /** @var CGlossary $item */
391
        foreach ($glossaries as $item) {
392
            if ($term == $item->getName() && $not_id != $item->getIid()) {
393
                return true;
394
            }
395
        }
396
397
        return false;
398
        /*
399
400
        // Database table definition
401
        $table = Database::get_course_table(TABLE_GLOSSARY);
402
        $course_id = api_get_course_int_id();
403
404
        $sql = "SELECT name FROM $table
405
                WHERE
406
                    c_id = $course_id AND
407
                    name = '".Database::escape_string($term)."'";
408
        if ('' != $not_id) {
409
            $sql .= " AND glossary_id <> '".intval($not_id)."'";
410
        }
411
        $result = Database::query($sql);
412
        $count = Database::num_rows($result);
413
        if ($count > 0) {
414
            return true;
415
        } else {
416
            return false;
417
        }
418
        */
419
    }
420
421
    /**
422
     * Get one specific glossary term data.
423
     *
424
     * @param int $glossary_id ID of the glossary term
425
     *
426
     * @return mixed Array(glossary_id,name,description,glossary_display_order) or false on error
427
     */
428
    public static function get_glossary_information($glossary_id)
429
    {
430
        throw new Exception('Use repo find');
431
        $repo = Container::getGlossaryRepository();
0 ignored issues
show
Unused Code introduced by
$repo = Chamilo\CoreBund...getGlossaryRepository() is not reachable.

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

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

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

    return false;
}

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

Loading history...
432
        /** @var CGlossary $glossary */
433
        $glossary = $repo->find($glossary_id);
434
        $data = [];
435
        if (null !== $glossary) {
436
            $resourceNode = $glossary->getResourceNode();
437
            $data = [
438
                'glossary_id' => $glossary_id,
439
                'name' => $glossary->getName(),
440
                'description' => $glossary->getDescription(),
441
                'glossary_display_order' => $glossary->getDisplayOrder(),
442
                'insert_date' => $resourceNode->getCreatedAt(),
443
                'lastedit_date' => $resourceNode->getUpdatedAt(),
444
                'session_id' => $glossary->getSessionId(),
445
            ];
446
        }
447
448
        return $data;
449
        /*
450
        // Database table definition
451
        $t_glossary = Database::get_course_table(TABLE_GLOSSARY);
452
        $t_item_propery = Database::get_course_table(TABLE_ITEM_PROPERTY);
453
        if (empty($glossary_id)) {
454
            return false;
455
        }
456
        $sql = "SELECT
457
                    g.glossary_id 		as glossary_id,
458
                    g.name 				as name,
459
                    g.description 		as description,
460
                    g.display_order		as glossary_display_order,
461
                    ip.insert_date      as insert_date,
462
                    ip.lastedit_date    as update_date,
463
                    g.session_id
464
                FROM $t_glossary g
465
                INNER JOIN $t_item_propery ip
466
                ON (g.glossary_id = ip.ref AND g.c_id = ip.c_id)
467
                WHERE
468
                    tool = '".TOOL_GLOSSARY."' AND
469
                    g.glossary_id = '".intval($glossary_id)."' AND
470
                    g.c_id = ".api_get_course_int_id()." AND
471
                    ip.c_id = ".api_get_course_int_id();
472
473
        $result = Database::query($sql);
474
        if (false === $result || 1 != Database::num_rows($result)) {
475
            return false;
476
        }
477
478
        return Database::fetch_array($result);
479
        */
480
    }
481
482
    /**
483
     * Delete a glossary term (and re-order all the others).
484
     *
485
     * @param int  $glossary_id
486
     * @param bool $showMessage
487
     *
488
     * @return bool True on success, false on failure
489
     */
490
    public static function delete_glossary($glossary_id, $showMessage = true)
491
    {
492
        $repo = Container::getGlossaryRepository();
493
        /** @var CGlossary $glossary */
494
        $glossary = $repo->find($glossary_id);
495
        if (null !== $glossary) {
496
            $repo->delete($glossary);
497
        } else {
498
            $showMessage = false;
499
        }
500
501
        /*
502
         // update item_property (delete)
503
        api_item_property_update(
504
            api_get_course_info(),
505
            TOOL_GLOSSARY,
506
            $glossary_id,
507
            'delete',
508
            api_get_user_id()
509
        );
510
        */
511
        // reorder the remaining terms
512
        self::reorder_glossary();
513
514
        if ($showMessage) {
515
            Display::addFlash(
516
                Display::return_message(
517
                    get_lang('Term removed').': '.Security::remove_XSS($glossary->getName()),
518
                    'normal',
519
                    false
520
                )
521
            );
522
        }
523
524
        return true;
525
    }
526
527
    /**
528
     * @return string
529
     */
530
    public static function getGlossaryView()
531
    {
532
        $view = Session::read('glossary_view');
533
        if (empty($view)) {
534
            $defaultView = api_get_configuration_value('default_glossary_view');
535
            if (empty($defaultView)) {
536
                $defaultView = 'table';
537
            }
538
539
            return $defaultView;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $defaultView also could return the type boolean which is incompatible with the documented return type string.
Loading history...
540
        }
541
542
        return $view;
543
    }
544
545
    /**
546
     * This is the main function that displays the list or the table with all
547
     * the glossary terms
548
     * Defaults to 'table' and prefers glossary_view from the session by default.
549
     *
550
     * @return string
551
     */
552
    public static function display_glossary()
553
    {
554
        // This function should always be called with the corresponding
555
        // parameter for view type. Meanwhile, use this cheap trick.
556
        $view = self::getGlossaryView();
557
        // action links
558
        $actionsLeft = '';
559
        if (api_is_allowed_to_edit(null, true)) {
560
            $actionsLeft .= '<a href="index.php?'.api_get_cidreq().'&action=addglossary&msg=add?'.api_get_cidreq().'">'.
561
                Display::return_icon('new_glossary_term.png', get_lang('Add new glossary term'), '', ICON_SIZE_MEDIUM).'</a>';
562
        }
563
564
        if (api_is_allowed_to_edit(null, true)) {
565
            $actionsLeft .= '<a href="index.php?'.api_get_cidreq().'&action=import">'.
566
                Display::return_icon('import.png', get_lang('Import glossary'), '', ICON_SIZE_MEDIUM).'</a>';
567
        }
568
569
        if (!api_is_anonymous()) {
570
            $actionsLeft .= '<a id="export_opener" href="'.api_get_self().'?'.api_get_cidreq().'&action=export">'.
571
                Display::return_icon('save.png', get_lang('Export'), '', ICON_SIZE_MEDIUM).'</a>';
572
        }
573
574
        if ('table' === $view || !isset($view)) {
575
            $actionsLeft .= '<a href="index.php?'.api_get_cidreq().'&action=changeview&view=list">'.
576
                Display::return_icon('view_detailed.png', get_lang('List view'), '', ICON_SIZE_MEDIUM).'</a>';
577
        } else {
578
            $actionsLeft .= '<a href="index.php?'.api_get_cidreq().'&action=changeview&view=table">'.
579
                Display::return_icon('view_text.png', get_lang('Table view'), '', ICON_SIZE_MEDIUM).'</a>';
580
        }
581
582
        if (api_is_allowed_to_edit(true, true, true)) {
583
            $actionsLeft .= Display::url(
584
                Display::return_icon('export_to_documents.png', get_lang('Export latest version of this page to Documents'), [], ICON_SIZE_MEDIUM),
585
                api_get_self().'?'.api_get_cidreq().'&'.http_build_query(['action' => 'export_documents'])
586
            );
587
        }
588
589
        $orderList = isset($_GET['order']) ? Database::escape_string($_GET['order']) : '';
590
        if (empty($orderList)) {
591
            $orderList = 'ASC';
592
        }
593
        if (!api_is_allowed_to_edit(true, true, true)) {
594
            if ('ASC' === $orderList) {
595
                $actionsLeft .= Display::url(
596
                    Display::return_icon('falling.png', get_lang('Sort Descending'), [], ICON_SIZE_MEDIUM),
597
                    api_get_self().'?'.api_get_cidreq().'&'.http_build_query(['order' => 'DESC'])
598
                );
599
            } else {
600
                $actionsLeft .= Display::url(
601
                    Display::return_icon('upward.png', get_lang('Sort Ascending'), [], ICON_SIZE_MEDIUM),
602
                    api_get_self().'?'.api_get_cidreq().'&'.http_build_query(['order' => 'ASC'])
603
                );
604
            }
605
        }
606
607
        /* BUILD SEARCH FORM */
608
        $form = new FormValidator(
609
            'search',
610
            'get',
611
            api_get_self().'?'.api_get_cidreq(),
612
            '',
613
            [],
614
            FormValidator::LAYOUT_INLINE
615
        );
616
        $form->addText('keyword', '', false, ['class' => '']);
617
        $form->addElement('hidden', 'cidReq', api_get_course_id());
618
        $form->addElement('hidden', 'id_session', api_get_session_id());
619
        $form->addButtonSearch(get_lang('Search'));
620
        $actionsRight = $form->returnForm();
621
622
        $toolbar = Display::toolbarAction(
623
            'toolbar-document',
624
            [$actionsLeft, $actionsRight]
625
        );
626
627
        $content = $toolbar;
628
629
        $items = self::get_number_glossary_terms();
630
        if (0 != $items && (!$view || 'table' === $view)) {
631
            // @todo Table haven't paggination
632
            $table = new SortableTable(
633
                'glossary',
634
                ['GlossaryManager', 'get_number_glossary_terms'],
635
                ['GlossaryManager', 'get_glossary_data'],
636
                0
637
            );
638
            $table->set_header(0, get_lang('Term'), true);
639
            $table->set_header(1, get_lang('Term definition'), true);
640
            if (api_is_allowed_to_edit(null, true)) {
641
                $table->set_header(2, get_lang('Detail'), false, 'width=90px', ['class' => 'td_actions']);
642
                $table->set_column_filter(2, ['GlossaryManager', 'actions_filter']);
643
            }
644
            $content .= $table->return_table();
645
        }
646
647
        if ('list' === $view) {
648
            $content .= self::displayGlossaryList();
649
        }
650
651
        return $content;
652
    }
653
654
    /**
655
     * Display the glossary terms in a list.
656
     *
657
     * @return bool true
658
     */
659
    public static function displayGlossaryList()
660
    {
661
        $glossaryList = self::get_glossary_data(0, 1000, 0, 'ASC');
662
        $content = '';
663
        foreach ($glossaryList as $key => $glossary_item) {
664
            $actions = '';
665
            if (api_is_allowed_to_edit(null, true)) {
666
                $actions = '<div class="pull-right">'.self::actions_filter($glossary_item[2], '', $glossary_item).'</div>';
667
            }
668
            $content .= Display::panel($glossary_item[1], $glossary_item[0].' '.$actions);
669
        }
670
671
        return $content;
672
    }
673
674
    /**
675
     * Get the number of glossary terms in the course (or course+session).
676
     *
677
     * @param  int     Session ID filter (optional)
678
     *
679
     * @return int Count of glossary terms
680
     */
681
    public static function get_number_glossary_terms($sessionId = 0)
682
    {
683
        // @todo Filter by keywork dont work
684
        $repo = Container::getGlossaryRepository();
685
686
        $courseId = api_get_course_int_id();
687
        $sessionId = !empty($sessionId) ? $sessionId : api_get_session_id();
688
689
        $course = api_get_course_entity($courseId);
690
        $session = api_get_session_entity($sessionId);
691
692
        $qb = $repo->getResourcesByCourse($course, $session);
693
        /*
694
        $keyword = isset($_GET['keyword']) ? Database::escape_string($_GET['keyword']) : '';
695
        if(!empty($keyword)){
696
            $qb->andWhere(
697
                $qb->expr()->like('resource.name',':keyword')
698
            )->andWhere(
699
                $qb->expr()->like('resource.description',':keyword')
700
            )->setParameter('keyword', '%'.$keyword.'%');
701
        }
702
        */
703
704
        try {
705
            $count = $qb->select('COUNT(resource)')->getQuery()->getSingleScalarResult();
706
        } catch (NoResultException $e) {
707
            $count = 0;
708
        }
709
710
        return $count;
711
        /*
712
713
        // Database table definition
714
        $t_glossary = Database::get_course_table(TABLE_GLOSSARY);
715
        $course_id = api_get_course_int_id();
716
        $session_id = (int) $session_id;
717
        $sql_filter = api_get_session_condition($session_id, true, true);
718
719
        $keyword = isset($_GET['keyword']) ? Database::escape_string($_GET['keyword']) : '';
720
        $keywordCondition = '';
721
        if (!empty($keyword)) {
722
            $keywordCondition = "AND (name LIKE '%$keyword%' OR description LIKE '%$keyword%')";
723
        }
724
725
        $sql = "SELECT count(glossary_id) as total
726
                FROM $t_glossary
727
                WHERE c_id = $course_id $sql_filter
728
                $keywordCondition ";
729
        $res = Database::query($sql);
730
        if (false === $res) {
731
            return 0;
732
        }
733
        $obj = Database::fetch_object($res);
734
735
        return $obj->total;
736
        */
737
    }
738
739
    /**
740
     * Get all the data of a glossary.
741
     *
742
     * @param int    $from            From which item
743
     * @param int    $number_of_items Number of items to collect
744
     * @param string $column          Name of column on which to order
745
     * @param string $direction       Whether to sort in ascending (ASC) or descending (DESC)
746
     *
747
     * @return array
748
     */
749
    public static function get_glossary_data(
750
        $from,
751
        $number_of_items,
752
        $column,
753
        $direction
754
    ) {
755
        // @todo Table haven't paggination
756
        // @todo Filter by keywork dont work
757
        $repo = Container::getGlossaryRepository();
758
        $courseId = api_get_course_int_id();
759
        $sessionId = api_get_session_id();
760
761
        $course = api_get_course_entity($courseId);
762
        $session = api_get_session_entity($sessionId);
763
764
        $qb = $repo->getResourcesByCourse($course, $session);
765
766
        /*
767
        $keyword = isset($_GET['keyword']) ? Database::escape_string($_GET['keyword']) : '';
768
        if(!empty($keyword)){
769
            $qb->andWhere(
770
                $qb->expr()->like('resource.name',':keyword')
771
772
            )->andWhere(
773
                $qb->expr()->like('resource.description',':keyword')
774
775
            )->setParameter('keyword', '%'.$keyword.'%');
776
        }
777
        */
778
779
        $return = [];
780
        $array = [];
781
        $_user = api_get_user_info();
782
        $view = self::getGlossaryView();
783
        $glossaries = $qb->getQuery()->getResult();
784
785
        foreach ($glossaries as $glossary) {
786
            /** @var CGlossary $glossary */
787
            $session_img = api_get_session_image($sessionId, $_user['status']);
788
            $array[0] = $glossary->getName().$session_img;
789
            if (!$view || 'table' === $view) {
790
                $array[1] = str_replace(['<p>', '</p>'], ['', '<br />'], $glossary->getDescription());
791
            } else {
792
                $array[1] = $glossary->getDescription();
793
            }
794
795
            if (isset($_GET['action']) && 'export' === $_GET['action']) {
796
                $array[1] = api_html_entity_decode($glossary->getDescription());
797
            }
798
            if (api_is_allowed_to_edit(null, true)) {
799
                $array[2] = $glossary->getIid();
800
            }
801
            $return[] = $array;
802
        }
803
804
        return $return;
805
        /*
806
        $_user = api_get_user_info();
807
        $view = self::getGlossaryView();
808
809
        // Database table definition
810
        $t_glossary = Database::get_course_table(TABLE_GLOSSARY);
811
        $t_item_propery = Database::get_course_table(TABLE_ITEM_PROPERTY);
812
813
        if (api_is_allowed_to_edit(null, true)) {
814
            $col2 = ' glossary.glossary_id	as col2, ';
815
        } else {
816
            $col2 = ' ';
817
        }
818
819
        // Condition for the session
820
        $session_id = api_get_session_id();
821
        $condition_session = api_get_session_condition(
822
            $session_id,
823
            true,
824
            true,
825
            'glossary.session_id'
826
        );
827
828
        $column = (int) $column;
829
        $from = (int) $from;
830
        $number_of_items = (int) $number_of_items;
831
832
        if (!in_array($direction, ['DESC', 'ASC'])) {
833
            $direction = 'ASC';
834
        }
835
836
        $keyword = isset($_GET['keyword']) ? Database::escape_string($_GET['keyword']) : '';
837
        $keywordCondition = '';
838
        if (!empty($keyword)) {
839
            $keywordCondition = "AND (glossary.name LIKE '%$keyword%' OR glossary.description LIKE '%$keyword%')";
840
        }
841
        $sql = "SELECT
842
                    glossary.name as col0,
843
                    glossary.description as col1,
844
                    $col2
845
                    glossary.session_id
846
                FROM $t_glossary glossary
847
                INNER JOIN $t_item_propery ip
848
                ON (glossary.glossary_id = ip.ref AND glossary.c_id = ip.c_id)
849
                WHERE
850
                    tool = '".TOOL_GLOSSARY."'
851
                    $condition_session AND
852
                    glossary.c_id = ".api_get_course_int_id()." AND
853
                    ip.c_id = ".api_get_course_int_id()."
854
                    $keywordCondition
855
                ORDER BY col$column $direction
856
                LIMIT $from, $number_of_items";
857
        $res = Database::query($sql);
858
859
        $return = [];
860
        $array = [];
861
        while ($data = Database::fetch_array($res)) {
862
            // Validation when belongs to a session
863
            $session_img = api_get_session_image($data['session_id'], $_user['status']);
864
            $array[0] = $data[0].$session_img;
865
866
            if (!$view || 'table' === $view) {
867
                $array[1] = str_replace(['<p>', '</p>'], ['', '<br />'], $data[1]);
868
            } else {
869
                $array[1] = $data[1];
870
            }
871
872
            if (isset($_GET['action']) && 'export' === $_GET['action']) {
873
                $array[1] = api_html_entity_decode($data[1]);
874
            }
875
876
            if (api_is_allowed_to_edit(null, true)) {
877
                $array[2] = $data[2];
878
            }
879
            $return[] = $array;
880
        }
881
882
        return $return;
883
        */
884
    }
885
886
    /**
887
     * Update action icons column.
888
     *
889
     * @param int   $glossary_id
890
     * @param array $url_params  Parameters to use to affect links
891
     * @param array $row         The line of results from a query on the glossary table
892
     *
893
     * @return string HTML string for the action icons columns
894
     */
895
    public static function actions_filter($glossary_id, $url_params, $row)
896
    {
897
        $glossary_id = $row[2];
898
        $return = '<a href="'.api_get_self().'?action=edit_glossary&glossary_id='.$glossary_id.'&'.api_get_cidreq().'&msg=edit">'.
899
            Display::return_icon('edit.png', get_lang('Edit'), '', 22).'</a>';
900
        $repo = Container::getGlossaryRepository();
901
        /** @var CGlossary $glossaryData */
902
        $glossaryData = $repo->find($glossary_id);
903
        $glossaryTerm = Security::remove_XSS(strip_tags($glossaryData->getName()));
904
        if (api_is_allowed_to_edit(null, true)) {
905
            $return .= '<a href="'.api_get_self().'?action=delete_glossary&glossary_id='.$glossary_id.'&'.api_get_cidreq().'" onclick="return confirmation(\''.$glossaryTerm.'\');">'.
906
                Display::return_icon('delete.png', get_lang('Delete'), '', 22).'</a>';
907
            /*
908
             * if ($glossaryData->getSessionId() == api_get_session_id()) {
909
            } else {
910
                $return = get_lang('Edition not available from the session, please edit from the basic course.');
911
            }
912
            */
913
        }
914
915
        return $return;
916
    }
917
918
    /**
919
     * a little bit of javascript to display a prettier warning when deleting a term.
920
     *
921
     * @return string HTML string including JavaScript
922
     */
923
    public static function javascript_glossary()
924
    {
925
        return "<script>
926
            function confirmation (name) {
927
                if (confirm(\" ".get_lang("Do you really want to delete this term")." \"+ name + \" ?\")) {
928
                    return true;
929
                } else {
930
                    return false;
931
                }
932
            }
933
        </script>";
934
    }
935
936
    /**
937
     * Re-order glossary.
938
     */
939
    public static function reorder_glossary()
940
    {
941
        $repo = Container::getGlossaryRepository();
942
943
        $courseId = api_get_course_int_id();
944
        $sessionId = api_get_session_id();
945
946
        $course = api_get_course_entity($courseId);
947
        $session = api_get_session_entity($sessionId);
948
949
        $glossaries = $repo->getResourcesByCourse($course, $session);
950
        $i = 1;
951
        /** @var CGlossary $item */
952
        foreach ($glossaries as $item) {
953
            $item->setDisplayOrder($i);
954
            $repo->update($item);
955
            $i++;
956
        }
957
        /*
958
        // Database table definition
959
        $table = Database::get_course_table(TABLE_GLOSSARY);
960
        $course_id = api_get_course_int_id();
961
        $sql = "SELECT * FROM $table
962
                WHERE c_id = $course_id
963
                ORDER by display_order ASC";
964
        $res = Database::query($sql);
965
966
        $i = 1;
967
        while ($data = Database::fetch_array($res)) {
968
            $sql = "UPDATE $table SET display_order = $i
969
                    WHERE c_id = $course_id AND glossary_id = '".intval($data['glossary_id'])."'";
970
            Database::query($sql);
971
            $i++;
972
        }
973
        */
974
    }
975
976
    /**
977
     * Move a glossary term.
978
     *
979
     * @param string $direction
980
     * @param string $glossary_id
981
     */
982
    public static function move_glossary($direction, $glossary_id)
983
    {
984
        // Database table definition
985
        $table = Database::get_course_table(TABLE_GLOSSARY);
986
987
        // sort direction
988
        if ('up' === $direction) {
989
            $sortorder = 'DESC';
990
        } else {
991
            $sortorder = 'ASC';
992
        }
993
        $course_id = api_get_course_int_id();
994
995
        $sql = "SELECT * FROM $table
996
                WHERE c_id = $course_id
997
                ORDER BY display_order $sortorder";
998
        $res = Database::query($sql);
999
        $found = false;
1000
        while ($row = Database::fetch_array($res)) {
1001
            if ($found && empty($next_id)) {
1002
                $next_id = $row['glossary_id'];
1003
                $next_display_order = $row['display_order'];
1004
            }
1005
1006
            if ($row['glossary_id'] == $glossary_id) {
1007
                $current_id = $glossary_id;
1008
                $current_display_order = $row['display_order'];
1009
                $found = true;
1010
            }
1011
        }
1012
1013
        $sql1 = "UPDATE $table SET display_order = '".Database::escape_string($next_display_order)."'
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $next_display_order does not seem to be defined for all execution paths leading up to this point.
Loading history...
1014
                 WHERE c_id = $course_id  AND glossary_id = '".Database::escape_string($current_id)."'";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $current_id does not seem to be defined for all execution paths leading up to this point.
Loading history...
1015
        $sql2 = "UPDATE $table SET display_order = '".Database::escape_string($current_display_order)."'
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $current_display_order does not seem to be defined for all execution paths leading up to this point.
Loading history...
1016
                 WHERE c_id = $course_id  AND glossary_id = '".Database::escape_string($next_id)."'";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $next_id does not seem to be defined for all execution paths leading up to this point.
Loading history...
1017
        Database::query($sql1);
1018
        Database::query($sql2);
1019
1020
        Display::addFlash(Display::return_message(get_lang('The term has moved')));
1021
    }
1022
1023
    /**
1024
     * Export to pdf.
1025
     */
1026
    public static function export_to_pdf()
1027
    {
1028
        $data = self::get_glossary_data(
1029
            0,
1030
            self::get_number_glossary_terms(api_get_session_id()),
1031
            0,
1032
            'ASC'
1033
        );
1034
        $template = new Template('', false, false, false, true, false, false);
1035
        $layout = $template->get_template('glossary/export_pdf.tpl');
1036
        $template->assign('items', $data);
1037
1038
        $html = $template->fetch($layout);
1039
        $courseCode = api_get_course_id();
1040
        $pdf = new PDF();
1041
        $pdf->content_to_pdf($html, '', get_lang('Glossary').'_'.$courseCode, $courseCode);
1042
    }
1043
1044
    /**
1045
     * Generate a PDF with all glossary terms and move file to documents.
1046
     *
1047
     * @return bool false if there's nothing in the glossary
1048
     */
1049
    public static function movePdfToDocuments()
1050
    {
1051
        $sessionId = api_get_session_id();
1052
        $courseId = api_get_course_int_id();
1053
        $data = self::get_glossary_data(
1054
            0,
1055
            self::get_number_glossary_terms($sessionId),
1056
            0,
1057
            'ASC'
1058
        );
1059
1060
        if (!empty($data)) {
1061
            $template = new Template('', false, false, false, true, false, false);
1062
            $layout = $template->get_template('glossary/export_pdf.tpl');
1063
            $template->assign('items', $data);
1064
            $fileName = get_lang('Glossary').'-'.api_get_local_time();
1065
            $signatures = ['Drh', 'Teacher', 'Date'];
1066
1067
            $pdf = new PDF(
1068
                'A4-P',
1069
                'P',
1070
                [
1071
                    'filename' => $fileName,
1072
                    'pdf_title' => $fileName,
1073
                    'add_signatures' => $signatures,
1074
                ]
1075
            );
1076
            $pdf->exportFromHtmlToDocumentsArea(
1077
                $template->fetch($layout),
1078
                $fileName,
1079
                $courseId
1080
            );
1081
1082
            return true;
1083
        } else {
1084
            Display::addFlash(Display::return_message(get_lang('Nothing to add')));
1085
        }
1086
1087
        return false;
1088
    }
1089
1090
    /**
1091
     * @param string $format
1092
     */
1093
    public static function exportToFormat($format)
1094
    {
1095
        if ('pdf' == $format) {
1096
            self::export_to_pdf();
1097
1098
            return;
1099
        }
1100
1101
        $data = self::get_glossary_data(
1102
            0,
1103
            self::get_number_glossary_terms(api_get_session_id()),
1104
            0,
1105
            'ASC'
1106
        );
1107
        usort($data, 'self::sorter');
1108
        //usort($data, 'sorter');
1109
        $list = [];
1110
        $list[] = ['term', 'definition'];
1111
        $allowStrip = api_get_configuration_value('allow_remove_tags_in_glossary_export');
1112
        foreach ($data as $line) {
1113
            $definition = $line[1];
1114
            if ($allowStrip) {
1115
                // htmlspecialchars_decode replace &#39 to '
1116
                // strip_tags remove HTML tags
1117
                $definition = htmlspecialchars_decode(strip_tags($definition), ENT_QUOTES);
1118
            }
1119
            $list[] = [$line[0], $definition];
1120
        }
1121
        $filename = 'glossary_course_'.api_get_course_id();
1122
1123
        switch ($format) {
1124
            case 'csv':
1125
                Export::arrayToCsv($list, $filename);
1126
                break;
1127
            case 'xls':
1128
                Export::arrayToXls($list, $filename);
1129
                break;
1130
        }
1131
    }
1132
1133
    public static function sorter($item1, $item2)
1134
    {
1135
        if ($item1[2] == $item2[2]) {
1136
            return 0;
1137
        }
1138
1139
        return $item1[2] < $item2[2] ? -1 : 1;
1140
    }
1141
}
1142