Passed
Push — 1.11.x ( 7bee13...5b4dc0 )
by Yannick
08:35
created

Wiki::check_emailcue()   D

Complexity

Conditions 15
Paths 140

Size

Total Lines 214
Code Lines 155

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 155
dl 0
loc 214
rs 4.4666
c 2
b 0
f 0
cc 15
nc 140
nop 4

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CourseBundle\Entity\CWiki;
6
use Chamilo\CourseBundle\Entity\CWikiCategory;
7
use ChamiloSession as Session;
8
use Doctrine\DBAL\Driver\Statement;
9
10
/**
11
 * Class Wiki
12
 * Functions library for the wiki tool.
13
 *
14
 * @author Juan Carlos Raña <[email protected]>
15
 * @author Patrick Cool <[email protected]>, Ghent University, Belgium
16
 * @author Julio Montoya <[email protected]> using the pdf.lib.php library
17
 */
18
class Wiki
19
{
20
    public $tbl_wiki;
21
    public $tbl_wiki_discuss;
22
    public $tbl_wiki_mailcue;
23
    public $tbl_wiki_conf;
24
    public $session_id = null;
25
    public $course_id = null;
26
    public $condition_session = null;
27
    public $group_id;
28
    public $assig_user_id;
29
    public $groupfilter = 'group_id=0';
30
    public $courseInfo;
31
    public $charset;
32
    public $page;
33
    public $action;
34
    public $wikiData = [];
35
    public $url;
36
37
    /**
38
     * Constructor.
39
     */
40
    public function __construct()
41
    {
42
        // Database table definition
43
        $this->tbl_wiki = Database::get_course_table(TABLE_WIKI);
44
        $this->tbl_wiki_discuss = Database::get_course_table(
45
            TABLE_WIKI_DISCUSS
46
        );
47
        $this->tbl_wiki_mailcue = Database::get_course_table(
48
            TABLE_WIKI_MAILCUE
49
        );
50
        $this->tbl_wiki_conf = Database::get_course_table(TABLE_WIKI_CONF);
51
52
        $this->session_id = api_get_session_id();
53
        $this->condition_session = api_get_session_condition($this->session_id);
54
        $this->course_id = api_get_course_int_id();
55
        $this->group_id = api_get_group_id();
56
57
        if (!empty($this->group_id)) {
58
            $this->groupfilter = ' group_id="'.$this->group_id.'"';
59
        }
60
        $this->courseInfo = api_get_course_info();
61
        $this->courseCode = api_get_course_id();
62
        $this->url = api_get_path(WEB_CODE_PATH).'wiki/index.php?'.api_get_cidreq();
63
    }
64
65
    /**
66
     * Check whether this title is already used.
67
     *
68
     * @param string $link
69
     *
70
     * @return bool False if title is already taken
71
     *
72
     * @author Patrick Cool <[email protected]>, Ghent University
73
     */
74
    public function checktitle($link)
75
    {
76
        $tbl_wiki = $this->tbl_wiki;
77
        $condition_session = $this->condition_session;
78
        $course_id = $this->course_id;
79
        $groupfilter = $this->groupfilter;
80
81
        $sql = 'SELECT * FROM '.$tbl_wiki.'
82
                WHERE
83
                    c_id = '.$course_id.' AND
84
                    reflink="'.Database::escape_string($link).'" AND
85
                    '.$groupfilter.$condition_session.'';
86
        $result = Database::query($sql);
87
        $num = Database::num_rows($result);
88
        // the value has not been found and is this available
89
        if ($num == 0) {
90
            return true;
91
        }
92
93
        return false;
94
    }
95
96
    /**
97
     * check wikilinks that has a page.
98
     *
99
     * @author Juan Carlos Raña <[email protected]>
100
     *
101
     * @param string $input
102
     *
103
     * @return string
104
     */
105
    public function links_to($input)
106
    {
107
        $input_array = preg_split(
108
            "/(\[\[|\]\])/",
109
            $input,
110
            -1,
111
            PREG_SPLIT_DELIM_CAPTURE
112
        );
113
        $all_links = [];
114
115
        foreach ($input_array as $key => $value) {
116
            if (isset($input_array[$key - 1]) && $input_array[$key - 1] == '[[' &&
117
                isset($input_array[$key + 1]) && $input_array[$key + 1] == ']]'
118
            ) {
119
                if (api_strpos($value, "|") !== false) {
120
                    $full_link_array = explode("|", $value);
121
                    $link = trim($full_link_array[0]);
122
                    $title = trim($full_link_array[1]);
123
                } else {
124
                    $link = trim($value);
125
                    $title = trim($value);
126
                }
127
                unset($input_array[$key - 1]);
128
                unset($input_array[$key + 1]);
129
                //replace blank spaces by _ within the links. But to remove links at the end add a blank space
130
                $all_links[] = Database::escape_string(
131
                    str_replace(' ', '_', $link)
132
                ).' ';
133
            }
134
        }
135
136
        return implode($all_links);
137
    }
138
139
    /**
140
     * detect and add style to external links.
141
     *
142
     * @author Juan Carlos Raña Trabado
143
     */
144
    public function detect_external_link($input)
145
    {
146
        $exlink = 'href=';
147
        $exlinkStyle = 'class="wiki_link_ext" href=';
148
149
        return str_replace($exlink, $exlinkStyle, $input);
150
    }
151
152
    /**
153
     * detect and add style to anchor links.
154
     *
155
     * @author Juan Carlos Raña Trabado
156
     */
157
    public function detect_anchor_link($input)
158
    {
159
        $anchorlink = 'href="#';
160
        $anchorlinkStyle = 'class="wiki_anchor_link" href="#';
161
        $output = str_replace($anchorlink, $anchorlinkStyle, $input);
162
163
        return $output;
164
    }
165
166
    /**
167
     * detect and add style to mail links
168
     * author Juan Carlos Raña Trabado.
169
     */
170
    public function detect_mail_link($input)
171
    {
172
        $maillink = 'href="mailto';
173
        $maillinkStyle = 'class="wiki_mail_link" href="mailto';
174
        $output = str_replace($maillink, $maillinkStyle, $input);
175
176
        return $output;
177
    }
178
179
    /**
180
     * detect and add style to ftp links.
181
     *
182
     * @author Juan Carlos Raña Trabado
183
     */
184
    public function detect_ftp_link($input)
185
    {
186
        $ftplink = 'href="ftp';
187
        $ftplinkStyle = 'class="wiki_ftp_link" href="ftp';
188
        $output = str_replace($ftplink, $ftplinkStyle, $input);
189
190
        return $output;
191
    }
192
193
    /**
194
     * detect and add style to news links.
195
     *
196
     * @author Juan Carlos Raña Trabado
197
     */
198
    public function detect_news_link($input)
199
    {
200
        $newslink = 'href="news';
201
        $newslinkStyle = 'class="wiki_news_link" href="news';
202
        $output = str_replace($newslink, $newslinkStyle, $input);
203
204
        return $output;
205
    }
206
207
    /**
208
     * detect and add style to irc links.
209
     *
210
     * @author Juan Carlos Raña Trabado
211
     */
212
    public function detect_irc_link($input)
213
    {
214
        $irclink = 'href="irc';
215
        $irclinkStyle = 'class="wiki_irc_link" href="irc';
216
        $output = str_replace($irclink, $irclinkStyle, $input);
217
218
        return $output;
219
    }
220
221
    /**
222
     * This function allows users to have [link to a title]-style links like in most regular wikis.
223
     * It is true that the adding of links is probably the most anoying part of Wiki for the people
224
     * who know something about the wiki syntax.
225
     *
226
     * @author Patrick Cool <[email protected]>, Ghent University
227
     * Improvements [[]] and [[ | ]]by Juan Carlos Raña
228
     * Improvements internal wiki style and mark group by Juan Carlos Raña
229
     */
230
    public function make_wiki_link_clickable($input)
231
    {
232
        //now doubles brackets
233
        $input_array = preg_split(
234
            "/(\[\[|\]\])/",
235
            $input,
236
            -1,
237
            PREG_SPLIT_DELIM_CAPTURE
238
        );
239
240
        foreach ($input_array as $key => $value) {
241
            //now doubles brackets
242
            if (isset($input_array[$key - 1]) &&
243
                $input_array[$key - 1] == '[[' && $input_array[$key + 1] == ']]'
244
            ) {
245
                // now full wikilink
246
                if (api_strpos($value, "|") !== false) {
247
                    $full_link_array = explode("|", $value);
248
                    $link = trim(strip_tags($full_link_array[0]));
249
                    $title = trim($full_link_array[1]);
250
                } else {
251
                    $link = trim(strip_tags($value));
252
                    $title = trim($value);
253
                }
254
255
                //if wikilink is homepage
256
                if ($link == 'index') {
257
                    $title = get_lang('DefaultTitle');
258
                }
259
                if ($link == get_lang('DefaultTitle')) {
260
                    $link = 'index';
261
                }
262
263
                // note: checkreflink checks if the link is still free. If it is not used then it returns true, if it is used, then it returns false. Now the title may be different
264
                if (self::checktitle(
265
                    strtolower(str_replace(' ', '_', $link))
266
                )) {
267
                    $link = api_html_entity_decode($link);
268
                    $input_array[$key] = '<a href="'.$this->url.'&action=addnew&title='.Security::remove_XSS($link).'" class="new_wiki_link">'.$title.'</a>';
269
                } else {
270
                    $input_array[$key] = '<a href="'.$this->url.'&action=showpage&title='.urlencode(strtolower(str_replace(' ', '_', $link))).'" class="wiki_link">'.$title.'</a>';
271
                }
272
                unset($input_array[$key - 1]);
273
                unset($input_array[$key + 1]);
274
            }
275
        }
276
        $output = implode('', $input_array);
277
278
        return $output;
279
    }
280
281
    /**
282
     * This function saves a change in a wiki page.
283
     *
284
     * @author Patrick Cool <[email protected]>, Ghent University
285
     *
286
     * @param array $values
287
     *
288
     * @return string
289
     */
290
    public function save_wiki($values)
291
    {
292
        $tbl_wiki = $this->tbl_wiki;
293
        $tbl_wiki_conf = $this->tbl_wiki_conf;
294
295
        $_course = $this->courseInfo;
296
        $time = api_get_utc_datetime(null, false, true);
297
        $userId = api_get_user_id();
298
        $groupInfo = GroupManager::get_group_properties($this->group_id);
299
300
        $_clean = [
301
            'task' => '',
302
            'feedback1' => '',
303
            'feedback2' => '',
304
            'feedback3' => '',
305
            'fprogress1' => '',
306
            'fprogress2' => '',
307
            'fprogress3' => '',
308
            'max_text' => 0,
309
            'max_version' => 0,
310
            'delayedsubmit' => '',
311
            'assignment' => 0,
312
        ];
313
314
        $pageId = intval($values['page_id']);
315
316
        // NOTE: visibility, visibility_disc and ratinglock_disc changes
317
        // are not made here, but through the interce buttons
318
319
        // cleaning the variables
320
        if (api_get_setting('htmlpurifier_wiki') == 'true') {
321
            //$purifier = new HTMLPurifier();
322
            $values['content'] = Security::remove_XSS($values['content']);
323
        }
324
        $version = intval($values['version']) + 1;
325
        $linkTo = self::links_to($values['content']); //and check links content
326
327
        //cleaning config variables
328
        if (!empty($values['task'])) {
329
            $_clean['task'] = $values['task'];
330
        }
331
332
        if (!empty($values['feedback1']) ||
333
            !empty($values['feedback2']) ||
334
            !empty($values['feedback3'])
335
        ) {
336
            $_clean['feedback1'] = $values['feedback1'];
337
            $_clean['feedback2'] = $values['feedback2'];
338
            $_clean['feedback3'] = $values['feedback3'];
339
            $_clean['fprogress1'] = $values['fprogress1'];
340
            $_clean['fprogress2'] = $values['fprogress2'];
341
            $_clean['fprogress3'] = $values['fprogress3'];
342
        }
343
344
        if (isset($values['initstartdate']) && $values['initstartdate'] == 1) {
345
            $_clean['startdate_assig'] = $values['startdate_assig'];
346
        } else {
347
            $_clean['startdate_assig'] = null;
348
        }
349
350
        if (isset($values['initenddate']) && $values['initenddate'] == 1) {
351
            $_clean['enddate_assig'] = $values['enddate_assig'];
352
        } else {
353
            $_clean['enddate_assig'] = null;
354
        }
355
356
        if (isset($values['delayedsubmit'])) {
357
            $_clean['delayedsubmit'] = $values['delayedsubmit'];
358
        }
359
360
        if (!empty($values['max_text']) || !empty($values['max_version'])) {
361
            $_clean['max_text'] = $values['max_text'];
362
            $_clean['max_version'] = $values['max_version'];
363
        }
364
365
        $values['assignment'] = $values['assignment'] ?? 0;
366
        $values['page_id'] = $values['page_id'] ?? 0;
367
368
        $em = Database::getManager();
369
370
        $newWiki = (new CWiki())
371
            ->setCId($this->course_id)
372
            ->setAddlock(1)
373
            ->setVisibility(1)
374
            ->setVisibilityDisc(1)
375
            ->setAddlockDisc(1)
376
            ->setRatinglockDisc(1)
377
            ->setPageId($pageId)
378
            ->setReflink(trim($values['reflink']))
379
            ->setTitle(trim($values['title']))
380
            ->setContent($values['content'])
381
            ->setUserId($userId)
382
            ->setGroupId($this->group_id)
383
            ->setDtime($time)
384
            ->setAssignment($values['assignment'])
385
            ->setComment($values['comment'])
386
            ->setProgress($values['progress'])
387
            ->setVersion($version)
388
            ->setLinksto($linkTo)
389
            ->setUserIp(api_get_real_ip())
390
            ->setSessionId($this->session_id)
391
            ->setPageId($values['page_id'])
392
            ->setEditlock(0)
393
            ->setIsEditing(0)
394
            ->setTimeEdit($time)
395
            ->setTag('')
396
        ;
397
398
        $em->persist($newWiki);
399
        $em->flush();
400
401
        $id = $newWiki->getIid();
402
403
        if ($id > 0) {
404
            $sql = "UPDATE $tbl_wiki SET id = iid WHERE iid = $id";
405
            Database::query($sql);
406
407
            // insert into item_property
408
            api_item_property_update(
409
                $_course,
410
                TOOL_WIKI,
411
                $id,
412
                'WikiAdded',
413
                $userId,
414
                $groupInfo
415
            );
416
417
            if ($values['page_id'] == 0) {
418
                $sql = 'UPDATE '.$tbl_wiki.' SET page_id="'.$id.'"
419
                        WHERE c_id = '.$this->course_id.' AND iid ="'.$id.'"';
420
                Database::query($sql);
421
            }
422
423
            self::assignCategoriesToWiki($newWiki, $values['category'] ?? []);
424
        }
425
426
        // Update wiki config
427
        if ($values['reflink'] == 'index' && $version == 1) {
428
            $params = [
429
                'c_id' => $this->course_id,
430
                'page_id' => $id,
431
                'task' => $_clean['task'],
432
                'feedback1' => $_clean['feedback1'],
433
                'feedback2' => $_clean['feedback2'],
434
                'feedback3' => $_clean['feedback3'],
435
                'fprogress1' => $_clean['fprogress1'],
436
                'fprogress2' => $_clean['fprogress2'],
437
                'fprogress3' => $_clean['fprogress3'],
438
                'max_text' => intval($_clean['max_text']),
439
                'max_version' => intval($_clean['max_version']),
440
                'startdate_assig' => $_clean['startdate_assig'],
441
                'enddate_assig' => $_clean['enddate_assig'],
442
                'delayedsubmit' => $_clean['delayedsubmit'],
443
            ];
444
            Database::insert($tbl_wiki_conf, $params);
445
        } else {
446
            $params = [
447
                'task' => $_clean['task'],
448
                'feedback1' => $_clean['feedback1'],
449
                'feedback2' => $_clean['feedback2'],
450
                'feedback3' => $_clean['feedback3'],
451
                'fprogress1' => $_clean['fprogress1'],
452
                'fprogress2' => $_clean['fprogress2'],
453
                'fprogress3' => $_clean['fprogress3'],
454
                'max_text' => intval($_clean['max_text']),
455
                'max_version' => intval($_clean['max_version']),
456
                'startdate_assig' => $_clean['startdate_assig'],
457
                'enddate_assig' => $_clean['enddate_assig'],
458
                'delayedsubmit' => $_clean['delayedsubmit'],
459
            ];
460
            Database::update(
461
                $tbl_wiki_conf,
462
                $params,
463
                ['page_id = ? AND c_id = ?' => [$pageId, $this->course_id]]
464
            );
465
        }
466
467
        api_item_property_update(
468
            $_course,
469
            'wiki',
470
            $id,
471
            'WikiAdded',
472
            $userId,
473
            $groupInfo
474
        );
475
        self::check_emailcue($_clean['reflink'], 'P', $time, $userId);
476
        $this->setWikiData($id);
477
478
        return get_lang('Saved');
479
    }
480
481
    /**
482
     * This function restore a wikipage.
483
     *
484
     * @author Juan Carlos Raña <[email protected]>
485
     *
486
     * @return string Message of success (to be printed on screen)
487
     */
488
    public function restore_wikipage(
489
        $r_page_id,
490
        $r_reflink,
491
        $r_title,
492
        $r_content,
493
        $r_group_id,
494
        $r_assignment,
495
        $r_progress,
496
        $c_version,
497
        $r_version,
498
        $r_linksto
499
    ) {
500
        $_course = $this->courseInfo;
501
        $r_user_id = api_get_user_id();
502
        $r_dtime = api_get_utc_datetime();
503
        $dTime = api_get_utc_datetime(null, false, true);
504
        $r_version = $r_version + 1;
505
        $r_comment = get_lang('RestoredFromVersion').': '.$c_version;
506
        $groupInfo = GroupManager::get_group_properties($r_group_id);
507
508
        $em = Database::getManager();
509
510
        $newWiki = (new CWiki())
511
            ->setCId($this->course_id)
512
            ->setPageId($r_page_id)
513
            ->setReflink($r_reflink)
514
            ->setTitle($r_title)
515
            ->setContent($r_content)
516
            ->setUserId($r_user_id)
517
            ->setGroupId($r_group_id)
518
            ->setDtime($dTime)
519
            ->setAssignment($r_assignment)
520
            ->setComment($r_comment)
521
            ->setProgress($r_progress)
522
            ->setVersion($r_version)
523
            ->setLinksto($r_linksto)
524
            ->setUserIp(api_get_real_ip())
525
            ->setSessionId($this->session_id)
526
            ->setAddlock(0)
527
            ->setEditlock(0)
528
            ->setVisibility(0)
529
            ->setAddlockDisc(0)
530
            ->setVisibilityDisc(0)
531
            ->setRatinglockDisc(0)
532
            ->setIsEditing(0)
533
            ->setTag('')
534
        ;
535
536
        $em->persist($newWiki);
537
        $em->flush();
538
539
        $newWiki->setId(
540
            $newWiki->getIid()
541
        );
542
543
        $em->flush();
544
545
        api_item_property_update(
546
            $_course,
547
            'wiki',
548
            $newWiki->getIid(),
549
            'WikiAdded',
550
            api_get_user_id(),
551
            $groupInfo
552
        );
553
        self::check_emailcue($r_reflink, 'P', $r_dtime, $r_user_id);
554
555
        return get_lang('PageRestored');
556
    }
557
558
    /**
559
     * This function delete a wiki.
560
     *
561
     * @author Juan Carlos Raña <[email protected]>
562
     *
563
     * @return string Message of success (to be printed)
564
     */
565
    public function delete_wiki()
566
    {
567
        $tbl_wiki = $this->tbl_wiki;
568
        $tbl_wiki_discuss = $this->tbl_wiki_discuss;
569
        $tbl_wiki_mailcue = $this->tbl_wiki_mailcue;
570
        $tbl_wiki_conf = $this->tbl_wiki_conf;
571
        $conditionSession = $this->condition_session;
572
        $groupFilter = $this->groupfilter;
573
574
        $sql = "SELECT page_id FROM $tbl_wiki
575
                WHERE c_id = ".$this->course_id." AND $groupFilter $conditionSession
576
                ORDER BY id DESC";
577
578
        $result = Database::query($sql);
579
        $pageList = Database::store_result($result);
580
        if ($pageList) {
581
            foreach ($pageList as $pageData) {
582
                $pageId = $pageData['page_id'];
583
                $sql = "DELETE FROM $tbl_wiki_conf
584
                        WHERE c_id = ".$this->course_id." AND page_id = $pageId";
585
                Database::query($sql);
586
587
                $sql = "DELETE FROM $tbl_wiki_discuss
588
                        WHERE c_id = ".$this->course_id." AND publication_id = $pageId";
589
                Database::query($sql);
590
            }
591
        }
592
593
        $sql = "DELETE FROM $tbl_wiki_mailcue
594
                WHERE c_id = ".$this->course_id." AND $groupFilter $conditionSession ";
595
        Database::query($sql);
596
597
        $sql = "DELETE FROM $tbl_wiki
598
                WHERE c_id = ".$this->course_id." AND $groupFilter $conditionSession ";
599
        Database::query($sql);
600
601
        return get_lang('WikiDeleted');
602
    }
603
604
    /**
605
     * This function saves a new wiki page.
606
     *
607
     * @author Patrick Cool <[email protected]>, Ghent University
608
     *
609
     * @todo consider merging this with the function save_wiki into one single function.
610
     */
611
    public function save_new_wiki($values)
612
    {
613
        $tbl_wiki = $this->tbl_wiki;
614
        $tbl_wiki_conf = $this->tbl_wiki_conf;
615
        $assig_user_id = $this->assig_user_id;
616
        $_clean = [];
617
618
        // cleaning the variables
619
        $_clean['assignment'] = '';
620
        if (isset($values['assignment'])) {
621
            $_clean['assignment'] = $values['assignment'];
622
        }
623
624
        // Unlike ordinary pages of pages of assignments.
625
        // Allow create a ordinary page although there is a assignment with the same name
626
        if ($_clean['assignment'] == 2 || $_clean['assignment'] == 1) {
627
            $page = str_replace(
628
                ' ',
629
                '_',
630
                $values['title']."_uass".$assig_user_id
631
            );
632
        } else {
633
            $page = str_replace(' ', '_', $values['title']);
634
        }
635
        $_clean['reflink'] = $page;
636
        $_clean['title'] = trim($values['title']);
637
        $_clean['content'] = $values['content'];
638
639
        if (api_get_setting('htmlpurifier_wiki') === 'true') {
640
            $purifier = new HTMLPurifier();
641
            $_clean['content'] = $purifier->purify($_clean['content']);
642
        }
643
644
        //re-check after strip_tags if the title is empty
645
        if (empty($_clean['title']) || empty($_clean['reflink'])) {
646
            return false;
647
        }
648
649
        if ($_clean['assignment'] == 2) {
650
            //config by default for individual assignment (students)
651
            //Identifies the user as a creator, not the teacher who created
652
            $_clean['user_id'] = intval($assig_user_id);
653
            $_clean['visibility'] = 0;
654
            $_clean['visibility_disc'] = 0;
655
            $_clean['ratinglock_disc'] = 0;
656
        } else {
657
            $_clean['user_id'] = api_get_user_id();
658
            $_clean['visibility'] = 1;
659
            $_clean['visibility_disc'] = 1;
660
            $_clean['ratinglock_disc'] = 1;
661
        }
662
663
        $_clean['comment'] = $values['comment'];
664
        $_clean['progress'] = $values['progress'];
665
        $_clean['version'] = 1;
666
667
        $groupInfo = GroupManager::get_group_properties($this->group_id);
668
669
        //check wikilinks
670
        $_clean['linksto'] = self::links_to($_clean['content']);
671
672
        // cleaning config variables
673
        $_clean['task'] = $values['task'] ?? '';
674
        $_clean['feedback1'] = $values['feedback1'] ?? '';
675
        $_clean['feedback2'] = $values['feedback2'] ?? '';
676
        $_clean['feedback3'] = $values['feedback3'] ?? '';
677
        $_clean['fprogress1'] = $values['fprogress1'] ?? '';
678
        $_clean['fprogress2'] = $values['fprogress2'] ?? '';
679
        $_clean['fprogress3'] = $values['fprogress3'] ?? '';
680
681
        if (isset($values['initstartdate']) && $values['initstartdate'] == 1) {
682
            $_clean['startdate_assig'] = $values['startdate_assig'];
683
        } else {
684
            $_clean['startdate_assig'] = null;
685
        }
686
687
        if (isset($values['initenddate']) && $values['initenddate'] == 1) {
688
            $_clean['enddate_assig'] = $values['enddate_assig'];
689
        } else {
690
            $_clean['enddate_assig'] = null;
691
        }
692
693
        $_clean['delayedsubmit'] = $values['delayedsubmit'] ?? '';
694
        $_clean['max_text'] = $values['max_text'] ?? '';
695
        $_clean['max_version'] = $values['max_version'] ?? '';
696
697
        // Filter no _uass
698
        if (api_strtoupper(trim($values['title'])) === 'INDEX') {
699
            Display::addFlash(
700
                Display::return_message(
701
                    get_lang('GoAndEditMainPage'),
702
                    'warning',
703
                    false
704
                )
705
            );
706
        } else {
707
            $var = $_clean['reflink'];
708
            if (!self::checktitle($var)) {
709
                return get_lang('WikiPageTitleExist').
710
                    '<a href="'.$this->url.'&action=edit&title='.$var.'">'.
711
                    $values['title'].'</a>';
712
            } else {
713
                $em = Database::getManager();
714
                $dtime = api_get_utc_datetime(null, false, true);
715
716
                $newWiki = (new CWiki())
717
                    ->setCId($this->course_id)
718
                    ->setReflink($_clean['reflink'])
719
                    ->setTitle($_clean['title'])
720
                    ->setContent($_clean['content'])
721
                    ->setUserId($_clean['user_id'])
722
                    ->setGroupId($this->group_id)
723
                    ->setDtime($dtime)
724
                    ->setVisibility($_clean['visibility'])
725
                    ->setVisibilityDisc($_clean['visibility_disc'])
726
                    ->setRatinglockDisc($_clean['ratinglock_disc'])
727
                    ->setAssignment($_clean['assignment'])
728
                    ->setComment($_clean['comment'])
729
                    ->setProgress($_clean['progress'])
730
                    ->setVersion($_clean['version'])
731
                    ->setLinksto($_clean['linksto'])
732
                    ->setUserIp(api_get_real_ip())
733
                    ->setSessionId($this->session_id)
734
                    ->setAddlock(0)
735
                    ->setAddlockDisc(1)
736
                    ->setEditlock(0)
737
                    ->setIsEditing(0)
738
                    ->setTag('')
739
                ;
740
741
                $em->persist($newWiki);
742
                $em->flush();
743
744
                $id = $newWiki->getIid();
745
746
                if ($id > 0) {
747
                    $sql = "UPDATE $tbl_wiki SET id = iid WHERE iid = $id";
748
                    Database::query($sql);
749
750
                    //insert into item_property
751
                    api_item_property_update(
752
                        $this->courseInfo,
753
                        TOOL_WIKI,
754
                        $id,
755
                        'WikiAdded',
756
                        api_get_user_id(),
757
                        $groupInfo
758
                    );
759
760
                    $sql = 'UPDATE '.$tbl_wiki.' SET page_id="'.$id.'"
761
                            WHERE c_id = '.$this->course_id.' AND id = "'.$id.'"';
762
                    Database::query($sql);
763
764
                    // insert wiki config
765
                    $params = [
766
                        'c_id' => $this->course_id,
767
                        'page_id' => $id,
768
                        'task' => $_clean['task'],
769
                        'feedback1' => $_clean['feedback1'],
770
                        'feedback2' => $_clean['feedback2'],
771
                        'feedback3' => $_clean['feedback3'],
772
                        'fprogress1' => $_clean['fprogress1'],
773
                        'fprogress2' => $_clean['fprogress2'],
774
                        'fprogress3' => $_clean['fprogress3'],
775
                        'max_text' => $_clean['max_text'],
776
                        'max_version' => $_clean['max_version'],
777
                        'startdate_assig' => $_clean['startdate_assig'],
778
                        'enddate_assig' => $_clean['enddate_assig'],
779
                        'delayedsubmit' => $_clean['delayedsubmit'],
780
                    ];
781
782
                    Database::insert($tbl_wiki_conf, $params);
783
784
                    self::assignCategoriesToWiki($newWiki, $values['category'] ?? []);
785
786
                    $this->setWikiData($id);
787
                    self::check_emailcue(0, 'A');
788
789
                    return get_lang('NewWikiSaved');
790
                }
791
            }
792
        }
793
    }
794
795
    public function setForm(FormValidator $form, array $row = [])
796
    {
797
        $toolBar = api_is_allowed_to_edit(null, true)
798
            ? [
799
                'ToolbarSet' => 'Wiki',
800
                'Width' => '100%',
801
                'Height' => '400',
802
            ]
803
            : [
804
                'ToolbarSet' => 'WikiStudent',
805
                'Width' => '100%',
806
                'Height' => '400',
807
                'UserStatus' => 'student',
808
            ];
809
810
        $form->addHtmlEditor(
811
            'content',
812
            get_lang('Content'),
813
            false,
814
            false,
815
            $toolBar
816
        );
817
        //$content
818
        $form->addElement('text', 'comment', get_lang('Comments'));
819
        $progress = ['', 10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
820
821
        $form->addElement(
822
            'select',
823
            'progress',
824
            get_lang('Progress'),
825
            $progress
826
        );
827
828
        if (true === api_get_configuration_value('wiki_categories_enabled')) {
829
            $em = Database::getManager();
830
831
            $categories = $em->getRepository(CWikiCategory::class)
832
                ->findByCourse(
833
                    api_get_course_entity(),
834
                    api_get_session_entity()
835
                );
836
837
            $form->addSelectFromCollection(
838
                'category',
839
                get_lang('Categories'),
840
                $categories,
841
                ['multiple' => 'multiple'],
842
                false,
843
                'getNodeName'
844
            );
845
        }
846
847
        if ((api_is_allowed_to_edit(false, true) ||
848
            api_is_platform_admin()) &&
849
            isset($row['reflink']) && $row['reflink'] != 'index'
850
        ) {
851
            $form->addElement(
852
                'advanced_settings',
853
                'advanced_params',
854
                get_lang('AdvancedParameters')
855
            );
856
            $form->addElement(
857
                'html',
858
                '<div id="advanced_params_options" style="display:none">'
859
            );
860
861
            $form->addHtmlEditor(
862
                'task',
863
                get_lang('DescriptionOfTheTask'),
864
                false,
865
                false,
866
                [
867
                    'ToolbarSet' => 'wiki_task',
868
                    'Width' => '100%',
869
                    'Height' => '200',
870
                ]
871
            );
872
873
            $form->addElement('label', null, get_lang('AddFeedback'));
874
            $form->addElement('textarea', 'feedback1', get_lang('Feedback1'));
875
            $form->addElement(
876
                'select',
877
                'fprogress1',
878
                get_lang('FProgress'),
879
                $progress
880
            );
881
882
            $form->addElement('textarea', 'feedback2', get_lang('Feedback2'));
883
            $form->addElement(
884
                'select',
885
                'fprogress2',
886
                get_lang('FProgress'),
887
                $progress
888
            );
889
890
            $form->addElement('textarea', 'feedback3', get_lang('Feedback3'));
891
            $form->addElement(
892
                'select',
893
                'fprogress3',
894
                get_lang('FProgress'),
895
                $progress
896
            );
897
898
            $form->addElement(
899
                'checkbox',
900
                'initstartdate',
901
                null,
902
                get_lang('StartDate'),
903
                ['id' => 'start_date_toggle']
904
            );
905
906
            $style = "display:block";
907
            $row['initstartdate'] = 1;
908
            if (empty($row['startdate_assig'])) {
909
                $style = "display:none";
910
                $row['initstartdate'] = null;
911
            }
912
913
            $form->addElement(
914
                'html',
915
                '<div id="start_date" style="'.$style.'">'
916
            );
917
            $form->addDatePicker('startdate_assig', '');
918
            $form->addElement('html', '</div>');
919
            $form->addElement(
920
                'checkbox',
921
                'initenddate',
922
                null,
923
                get_lang('EndDate'),
924
                ['id' => 'end_date_toggle']
925
            );
926
927
            $style = "display:block";
928
            $row['initenddate'] = 1;
929
            if (empty($row['enddate_assig'])) {
930
                $style = "display:none";
931
                $row['initenddate'] = null;
932
            }
933
934
            $form->addHtml('<div id="end_date" style="'.$style.'">');
935
            $form->addDatePicker('enddate_assig', '');
936
            $form->addHtml('</div>');
937
            $form->addElement(
938
                'checkbox',
939
                'delayedsubmit',
940
                null,
941
                get_lang('AllowLaterSends')
942
            );
943
            $form->addElement('text', 'max_text', get_lang('NMaxWords'));
944
            $form->addElement('text', 'max_version', get_lang('NMaxVersion'));
945
            $form->addElement(
946
                'checkbox',
947
                'assignment',
948
                null,
949
                get_lang('CreateAssignmentPage')
950
            );
951
            $form->addElement('html', '</div>');
952
        }
953
954
        $form->addElement('hidden', 'page_id');
955
        $form->addElement('hidden', 'reflink');
956
        $form->addElement('hidden', 'version');
957
        $form->addElement('hidden', 'wpost_id', api_get_unique_id());
958
    }
959
960
    /**
961
     * This function displays the form for adding a new wiki page.
962
     *
963
     * @author Patrick Cool <[email protected]>, Ghent University
964
     *
965
     * @return string html code
966
     */
967
    public function display_new_wiki_form()
968
    {
969
        $url = $this->url.'&'.http_build_query(['action' => 'addnew']);
970
        $form = new FormValidator('wiki_new', 'post', $url);
971
        $form->addElement('text', 'title', get_lang('Title'));
972
        $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
973
        self::setForm($form);
974
        $title = isset($_GET['title']) ? Security::remove_XSS($_GET['title']) : '';
975
        $form->setDefaults(['title' => $title]);
976
        $form->addButtonSave(get_lang('Save'), 'SaveWikiNew');
977
        $form->display();
978
979
        if ($form->validate()) {
980
            $values = $form->exportValues();
981
            if (isset($values['startdate_assig']) &&
982
                isset($values['enddate_assig']) &&
983
                strtotime($values['startdate_assig']) > strtotime(
984
                    $values['enddate_assig']
985
                )
986
            ) {
987
                Display::addFlash(
988
                    Display::return_message(
989
                        get_lang("EndDateCannotBeBeforeTheStartDate"),
990
                        'error',
991
                        false
992
                    )
993
                );
994
            } elseif (!self::double_post($_POST['wpost_id'])) {
995
                //double post
996
            } else {
997
                if (isset($values['assignment']) && $values['assignment'] == 1) {
998
                    self::auto_add_page_users($values);
999
                }
1000
1001
                $return_message = $this->save_new_wiki($values);
1002
1003
                if ($return_message == false) {
1004
                    Display::addFlash(
1005
                        Display::return_message(
1006
                            get_lang('NoWikiPageTitle'),
1007
                            'error',
1008
                            false
1009
                        )
1010
                    );
1011
                } else {
1012
                    Display::addFlash(
1013
                        Display::return_message(
1014
                            $return_message,
1015
                            'confirmation',
1016
                            false
1017
                        )
1018
                    );
1019
                }
1020
1021
                $wikiData = self::getWikiData();
1022
                $redirectUrl = $this->url.'&'
1023
                    .http_build_query(['action' => 'showpage', 'title' => $wikiData['reflink']]);
1024
                header('Location: '.$redirectUrl);
1025
                exit;
1026
            }
1027
        }
1028
    }
1029
1030
    /**
1031
     * This function displays a wiki entry.
1032
     *
1033
     * @author Patrick Cool <[email protected]>, Ghent University
1034
     * @author Juan Carlos Raña Trabado
1035
     */
1036
    public function display_wiki_entry(string $newtitle)
1037
    {
1038
        $tblWiki = $this->tbl_wiki;
1039
        $tblWikiConf = $this->tbl_wiki_conf;
1040
        $conditionSession = $this->condition_session;
1041
        $groupfilter = $this->groupfilter;
1042
        $page = $this->page;
1043
1044
        if ($newtitle) {
1045
            $pageMIX = $newtitle; //display the page after it is created
1046
        } else {
1047
            $pageMIX = $page; //display current page
1048
        }
1049
1050
        $filter = null;
1051
        if (isset($_GET['view']) && $_GET['view']) {
1052
            $_clean['view'] = Database::escape_string($_GET['view']);
1053
            $filter = ' AND w.id="'.$_clean['view'].'"';
1054
        }
1055
1056
        // First, check page visibility in the first page version
1057
        $sql = 'SELECT * FROM '.$tblWiki.'
1058
                WHERE
1059
                    c_id = '.$this->course_id.' AND
1060
                    reflink = "'.Database::escape_string($pageMIX).'" AND
1061
                   '.$groupfilter.$conditionSession.'
1062
                ORDER BY id';
1063
        $result = Database::query($sql);
1064
        $row = Database::fetch_array($result, 'ASSOC');
1065
1066
        $KeyVisibility = null;
1067
        if ($KeyVisibility) {
1068
            $KeyVisibility = $row['visibility'];
1069
        }
1070
1071
        // second, show the last version
1072
        $sql = 'SELECT * FROM '.$tblWiki.' w
1073
            INNER JOIN '.$tblWikiConf.' wc
1074
            ON (wc.page_id = w.page_id AND wc.c_id = w.c_id)
1075
            WHERE
1076
                w.c_id = '.$this->course_id.' AND
1077
                w.reflink = "'.Database::escape_string($pageMIX).'" AND
1078
                w.session_id = '.$this->session_id.' AND
1079
                w.'.$groupfilter.'  '.$filter.'
1080
            ORDER BY id DESC';
1081
1082
        $result = Database::query($sql);
1083
        // we do not need awhile loop since we are always displaying the last version
1084
        $row = Database::fetch_array($result, 'ASSOC');
1085
1086
        //log users access to wiki (page_id)
1087
        if (!empty($row['page_id'])) {
1088
            Event::addEvent(LOG_WIKI_ACCESS, LOG_WIKI_PAGE_ID, $row['page_id']);
1089
        }
1090
        //update visits
1091
        if ($row && $row['id']) {
1092
            $sql = 'UPDATE '.$tblWiki.' SET hits=(hits+1)
1093
                WHERE c_id = '.$this->course_id.' AND id='.$row['id'];
1094
            Database::query($sql);
1095
        }
1096
1097
        $groupInfo = GroupManager::get_group_properties($this->group_id);
1098
1099
        // if both are empty, and we are displaying the index page then we display the default text.
1100
        if (!$row || ($row['content'] == '' && $row['title'] == '' && $page == 'index')) {
1101
            if (api_is_allowed_to_edit(false, true) ||
1102
                api_is_platform_admin() ||
1103
                GroupManager::is_user_in_group(api_get_user_id(), $groupInfo) ||
1104
                api_is_allowed_in_course()
1105
            ) {
1106
                //Table structure for better export to pdf
1107
                $default_table_for_content_Start = '<div class="text-center">';
1108
                $default_table_for_content_End = '</div>';
1109
                $content = $default_table_for_content_Start.
1110
                    sprintf(
1111
                        get_lang('DefaultContent'),
1112
                        api_get_path(WEB_IMG_PATH)
1113
                    ).
1114
                    $default_table_for_content_End;
1115
                $title = get_lang('DefaultTitle');
1116
            } else {
1117
                Display::addFlash(
1118
                    Display::return_message(
1119
                        get_lang('WikiStandBy'),
1120
                        'normal',
1121
                        false
1122
                    )
1123
                );
1124
1125
                return;
1126
            }
1127
        } else {
1128
            if (true === api_get_configuration_value('wiki_html_strict_filtering')) {
1129
                $content = Security::remove_XSS($row['content'], COURSEMANAGERLOWSECURITY);
1130
            } else {
1131
                $content = Security::remove_XSS($row['content']);
1132
            }
1133
            $title = Security::remove_XSS($row['title']);
1134
        }
1135
1136
        if (self::wiki_exist($title)) {
1137
            //assignment mode: identify page type
1138
            $icon_assignment = null;
1139
            if ($row['assignment'] == 1) {
1140
                $icon_assignment = Display::return_icon('wiki_assignment.png', get_lang('AssignmentDescExtra'));
1141
            } elseif ($row['assignment'] == 2) {
1142
                $icon_assignment = Display::return_icon('wiki_work.png', get_lang('AssignmentWork'));
1143
            }
1144
1145
            // task mode
1146
            $icon_task = null;
1147
            if (!empty($row['task'])) {
1148
                $icon_task = Display::return_icon('wiki_task.png', get_lang('StandardTask'));
1149
            }
1150
1151
            $pageTitle = $icon_assignment.PHP_EOL.$icon_task.'&nbsp;'.api_htmlentities($title);
1152
        } else {
1153
            $pageTitle = api_htmlentities($title);
1154
        }
1155
1156
        // Show page. Show page to all users if isn't hide page. Mode assignments: if student is the author, can view
1157
        if ($KeyVisibility != "1"
1158
            && !api_is_allowed_to_edit(false, true)
1159
            && !api_is_platform_admin()
1160
            && ($row['assignment'] != 2 || $KeyVisibility != "0" || api_get_user_id() != $row['user_id'])
1161
            && !api_is_allowed_in_course()
1162
        ) {
1163
            return;
1164
        }
1165
1166
        $actionsLeft = '';
1167
        $actionsRight = '';
1168
        // menu edit page
1169
        $editLink = '<a href="'.$this->url.'&action=edit&title='.api_htmlentities(urlencode($page)).'"'
1170
            .self::is_active_navigation_tab('edit').'>'
1171
            .Display::return_icon('edit.png', get_lang('EditThisPage'), [], ICON_SIZE_MEDIUM).'</a>';
1172
1173
        if (api_is_allowed_to_edit(false, true)) {
1174
            $actionsLeft .= $editLink;
1175
        } else {
1176
            if ((api_is_allowed_in_course() ||
1177
                GroupManager::is_user_in_group(
1178
                    api_get_user_id(),
1179
                    $groupInfo
1180
                ))
1181
            ) {
1182
                $actionsLeft .= $editLink;
1183
            } else {
1184
                $actionsLeft .= '';
1185
            }
1186
        }
1187
1188
        $pageProgress = 0;
1189
        $pageScore = 0;
1190
1191
        if ($row && $row['id']) {
1192
            $pageProgress = $row['progress'] * 10;
1193
            $pageScore = $row['score'];
1194
1195
            $protect_page = null;
1196
            $lock_unlock_protect = null;
1197
            // page action: protecting (locking) the page
1198
            if (api_is_allowed_to_edit(false, true) ||
1199
                api_is_platform_admin()
1200
            ) {
1201
                if (self::check_protect_page() == 1) {
1202
                    $protect_page = Display::return_icon(
1203
                        'lock.png',
1204
                        get_lang('PageLockedExtra'),
1205
                        [],
1206
                        ICON_SIZE_MEDIUM
1207
                    );
1208
                    $lock_unlock_protect = 'unlock';
1209
                } else {
1210
                    $protect_page = Display::return_icon(
1211
                        'unlock.png',
1212
                        get_lang('PageUnlockedExtra'),
1213
                        [],
1214
                        ICON_SIZE_MEDIUM
1215
                    );
1216
                    $lock_unlock_protect = 'lock';
1217
                }
1218
            }
1219
1220
            $actionsRight .= '<a href="'.$this->url.'&action=showpage&actionpage='.$lock_unlock_protect
1221
                .'&title='.api_htmlentities(urlencode($page)).'">'.
1222
            $protect_page.'</a>';
1223
1224
            $visibility_page = null;
1225
            $lock_unlock_visibility = null;
1226
            //page action: visibility
1227
            if (api_is_allowed_to_edit(false, true) ||
1228
                api_is_platform_admin()
1229
            ) {
1230
                if (self::check_visibility_page() == 1) {
1231
                    $visibility_page = Display::return_icon(
1232
                        'visible.png',
1233
                        get_lang('ShowPageExtra'),
1234
                        [],
1235
                        ICON_SIZE_MEDIUM
1236
                    );
1237
                    $lock_unlock_visibility = 'invisible';
1238
                } else {
1239
                    $visibility_page = Display::return_icon(
1240
                        'invisible.png',
1241
                        get_lang('HidePageExtra'),
1242
                        [],
1243
                        ICON_SIZE_MEDIUM
1244
                    );
1245
                    $lock_unlock_visibility = 'visible';
1246
                }
1247
            }
1248
1249
            $actionsRight .= '<a href="'.$this->url.'&action=showpage&actionpage='
1250
                .$lock_unlock_visibility.'&title='.api_htmlentities(urlencode($page)).'">'.$visibility_page.'</a>';
1251
1252
            // Only available if row['id'] is set
1253
            //page action: notification
1254
            $lock_unlock_notify_page = '';
1255
1256
            if (api_is_allowed_to_session_edit()) {
1257
                if (self::check_notify_page($page) == 1) {
1258
                    $notify_page = Display::return_icon(
1259
                        'messagebox_info.png',
1260
                        get_lang('NotifyByEmail'),
1261
                        [],
1262
                        ICON_SIZE_MEDIUM
1263
                    );
1264
                    $lock_unlock_notify_page = 'unlocknotify';
1265
                } else {
1266
                    $notify_page = Display::return_icon(
1267
                        'mail.png',
1268
                        get_lang('CancelNotifyByEmail'),
1269
                        [],
1270
                        ICON_SIZE_MEDIUM
1271
                    );
1272
                    $lock_unlock_notify_page = 'locknotify';
1273
                }
1274
            }
1275
1276
            if (api_is_allowed_to_session_edit(false, true)
1277
                && api_is_allowed_to_edit()
1278
                || GroupManager::is_user_in_group(api_get_user_id(), $groupInfo)
1279
            ) {
1280
                // menu discuss page
1281
                $actionsRight .= '<a href="'.$this->url.'&action=discuss&title='
1282
                    .api_htmlentities(urlencode($page)).'" '.self::is_active_navigation_tab('discuss').'>'
1283
                    .Display::return_icon(
1284
                        'discuss.png',
1285
                        get_lang('DiscussThisPage'),
1286
                        [],
1287
                        ICON_SIZE_MEDIUM
1288
                    ).'</a>';
1289
            }
1290
1291
            //menu history
1292
            $actionsRight .= '<a href="'.$this->url.'&action=history&title='
1293
                .api_htmlentities(urlencode($page)).'" '.self::is_active_navigation_tab('history').'>'.
1294
                Display::return_icon(
1295
                    'history.png',
1296
                    get_lang('ShowPageHistory'),
1297
                    [],
1298
                    ICON_SIZE_MEDIUM
1299
                ).'</a>';
1300
            //menu linkspages
1301
            $actionsRight .= '<a href="'.$this->url.'&action=links&title='
1302
                .api_htmlentities(urlencode($page)).'" '.self::is_active_navigation_tab('links').'>'
1303
                .Display::return_icon(
1304
                    'what_link_here.png',
1305
                    get_lang('LinksPages'),
1306
                    [],
1307
                    ICON_SIZE_MEDIUM
1308
                ).'</a>';
1309
1310
            //menu delete wikipage
1311
            if (api_is_allowed_to_edit(false, true) ||
1312
                api_is_platform_admin()
1313
            ) {
1314
                $actionsRight .= '<a href="'.$this->url.'&action=delete&title='
1315
                    .api_htmlentities(urlencode($page)).'"'.self::is_active_navigation_tab('delete').'>'
1316
                    .Display::return_icon(
1317
                        'delete.png',
1318
                        get_lang('DeleteThisPage'),
1319
                        [],
1320
                        ICON_SIZE_MEDIUM
1321
                    ).'</a>';
1322
            }
1323
1324
            $actionsRight .= '<a href="'.$this->url.'&action=showpage&actionpage='
1325
                .$lock_unlock_notify_page.'&title='.api_htmlentities(urlencode($page)).'">'.$notify_page.'</a>';
1326
1327
            // Page action: copy last version to doc area
1328
            if (api_is_allowed_to_edit(false, true) ||
1329
                api_is_platform_admin()
1330
            ) {
1331
                $actionsRight .= '<a href="'.$this->url.'&action=export2doc&wiki_id='.$row['id'].'">'
1332
                    .Display::return_icon(
1333
                        'export_to_documents.png',
1334
                        get_lang('ExportToDocArea'),
1335
                        [],
1336
                        ICON_SIZE_MEDIUM
1337
                    ).'</a>';
1338
            }
1339
1340
            $actionsRight .= '<a href="'.$this->url.'&action=export_to_pdf&wiki_id='.$row['id'].'">'
1341
                .Display::return_icon(
1342
                    'pdf.png',
1343
                    get_lang('ExportToPDF'),
1344
                    [],
1345
                    ICON_SIZE_MEDIUM
1346
                ).'</a>';
1347
1348
            $unoconv = api_get_configuration_value('unoconv.binaries');
1349
            if ($unoconv) {
1350
                $actionsRight .= Display::url(
1351
                    Display::return_icon('export_doc.png', get_lang('ExportToDoc'), [], ICON_SIZE_MEDIUM),
1352
                    $this->url.'&'.http_build_query(['action' => 'export_to_doc_file', 'id' => $row['id']])
1353
                );
1354
            }
1355
1356
            //export to print?>
1357
            <script>
1358
                function goprint() {
1359
                    var a = window.open('', '', 'width=800,height=600');
1360
                    a.document.open("text/html");
1361
                    a.document.write($('#wikicontent .panel-heading').html());
1362
                    a.document.write($('#wikicontent .panel-body').html());
1363
                    a.document.close();
1364
                    a.print();
1365
                }
1366
            </script>
1367
            <?php
1368
            $actionsRight .= Display::url(
1369
                Display::return_icon(
1370
                    'printer.png',
1371
                    get_lang('Print'),
1372
                    [],
1373
                    ICON_SIZE_MEDIUM
1374
                ),
1375
                '#',
1376
                ['onclick' => "javascript: goprint();"]
1377
            );
1378
        }
1379
1380
        $contentHtml = Display::toolbarAction(
1381
            'toolbar-wikistudent',
1382
            [$actionsLeft, $actionsRight],
1383
            [3, 9]
1384
        );
1385
1386
        $pageWiki = self::detect_news_link($content);
1387
        $pageWiki = self::detect_irc_link($pageWiki);
1388
        $pageWiki = self::detect_ftp_link($pageWiki);
1389
        $pageWiki = self::detect_mail_link($pageWiki);
1390
        $pageWiki = self::detect_anchor_link($pageWiki);
1391
        $pageWiki = self::detect_external_link($pageWiki);
1392
        $pageWiki = self::make_wiki_link_clickable($pageWiki);
1393
1394
        $footerWiki = '<ul class="list-inline" style="margin-bottom: 0;">'
1395
            .'<li>'.get_lang('Progress').': '.$pageProgress.'%</li>'
1396
            .'<li>'.get_lang('Rating').': '.$pageScore.'</li>'
1397
            .'<li>'.get_lang('Words').': '.self::word_count($content).'</li>';
1398
1399
        $footerWiki .= $this->returnCategoriesBlock(
1400
            !empty($row['id']) ? $row['id'] : 0,
1401
            '<li class="pull-right">',
1402
            '</li>'
1403
        );
1404
1405
        $footerWiki .= '</ul>';
1406
        // wikicontent require to print wiki document
1407
        $contentHtml .= '<div id="wikicontent">'.Display::panel($pageWiki, $pageTitle, $footerWiki).'</div>'; //end filter visibility
1408
1409
        $this->renderShowPage($contentHtml);
1410
    }
1411
1412
    /**
1413
     * This function counted the words in a document. Thanks Adeel Khan.
1414
     *
1415
     * @param   string  Document's text
0 ignored issues
show
Documentation Bug introduced by
The doc comment Document's at position 0 could not be parsed: Unknown type name 'Document's' at position 0 in Document's.
Loading history...
1416
     *
1417
     * @return int Number of words
1418
     */
1419
    public function word_count($document)
1420
    {
1421
        $search = [
1422
            '@<script[^>]*?>.*?</script>@si',
1423
            '@<style[^>]*?>.*?</style>@siU',
1424
            '@<div id="player.[^>]*?>.*?</div>@',
1425
            '@<![\s\S]*?--[ \t\n\r]*>@',
1426
        ];
1427
1428
        $document = preg_replace($search, '', $document);
1429
1430
        // strip all html tags
1431
        $wc = strip_tags($document);
1432
        $wc = html_entity_decode(
1433
            $wc,
1434
            ENT_NOQUOTES,
1435
            'UTF-8'
1436
        ); // TODO:test also old html_entity_decode(utf8_encode($wc))
1437
1438
        // remove 'words' that don't consist of alphanumerical characters or punctuation. And fix accents and some letters
1439
        $pattern = "#[^(\w|\d|\'|\"|\.|\!|\?|;|,|\\|\/|\-|:|\&|@|á|é|í|ó|ú|à|è|ì|ò|ù|ä|ë|ï|ö|ü|Á|É|Í|Ó|Ú|À|È|Ò|Ù|Ä|Ë|Ï|Ö|Ü|â|ê|î|ô|û|Â|Ê|Î|Ô|Û|ñ|Ñ|ç|Ç)]+#";
1440
        $wc = trim(preg_replace($pattern, " ", $wc));
1441
1442
        // remove one-letter 'words' that consist only of punctuation
1443
        $wc = trim(
1444
            preg_replace(
1445
                "#\s*[(\'|\"|\.|\!|\?|;|,|\\|\/|\-|:|\&|@)]\s*#",
1446
                " ",
1447
                $wc
1448
            )
1449
        );
1450
1451
        // remove superfluous whitespace
1452
        $wc = preg_replace("/\s\s+/", " ", $wc);
1453
1454
        // split string into an array of words
1455
        $wc = explode(" ", $wc);
1456
1457
        // remove empty elements
1458
        $wc = array_filter($wc);
1459
1460
        // return the number of words
1461
        return count($wc);
1462
    }
1463
1464
    /**
1465
     * This function checks if wiki title exist.
1466
     */
1467
    public function wiki_exist($title)
1468
    {
1469
        $tbl_wiki = $this->tbl_wiki;
1470
        $groupfilter = $this->groupfilter;
1471
        $condition_session = $this->condition_session;
1472
1473
        $sql = 'SELECT id FROM '.$tbl_wiki.'
1474
              WHERE
1475
                c_id = '.$this->course_id.' AND
1476
                title="'.Database::escape_string($title).'" AND
1477
                '.$groupfilter.$condition_session.'
1478
              ORDER BY id ASC';
1479
        $result = Database::query($sql);
1480
        $cant = Database::num_rows($result);
1481
        if ($cant > 0) {
1482
            return true;
1483
        } else {
1484
            return false;
1485
        }
1486
    }
1487
1488
    /**
1489
     * Checks if this navigation tab has to be set to active.
1490
     *
1491
     * @author Patrick Cool <[email protected]>, Ghent University
1492
     *
1493
     * @return string html code
1494
     */
1495
    public function is_active_navigation_tab($paramwk)
1496
    {
1497
        if (isset($_GET['action']) && $_GET['action'] == $paramwk) {
1498
            return ' class="active"';
1499
        }
1500
    }
1501
1502
    /**
1503
     * Lock add pages.
1504
     *
1505
     * @author Juan Carlos Raña <[email protected]>
1506
     * return current database status of protect page and change it if get action
1507
     */
1508
    public function check_addnewpagelock()
1509
    {
1510
        $tbl_wiki = $this->tbl_wiki;
1511
        $condition_session = $this->condition_session;
1512
        $groupfilter = $this->groupfilter;
1513
1514
        $sql = 'SELECT *
1515
                FROM '.$tbl_wiki.'
1516
                WHERE c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.'
1517
                ORDER BY id ASC';
1518
1519
        $result = Database::query($sql);
1520
        $row = Database::fetch_array($result);
1521
1522
        $status_addlock = null;
1523
        if ($row) {
1524
            $status_addlock = $row['addlock'];
1525
        }
1526
1527
        // Change status
1528
        if (api_is_allowed_to_edit(false, true) ||
1529
            api_is_platform_admin()
1530
        ) {
1531
            if (isset($_GET['actionpage'])) {
1532
                if ($_GET['actionpage'] == 'lockaddnew' && $status_addlock == 1) {
1533
                    $status_addlock = 0;
1534
                }
1535
                if ($_GET['actionpage'] == 'unlockaddnew' && $status_addlock == 0) {
1536
                    $status_addlock = 1;
1537
                }
1538
                $sql = 'UPDATE '.$tbl_wiki.' SET
1539
                            addlock="'.Database::escape_string($status_addlock).'"
1540
                        WHERE c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session;
1541
                Database::query($sql);
1542
            }
1543
1544
            $sql = 'SELECT *
1545
                    FROM '.$tbl_wiki.'
1546
                    WHERE c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.'
1547
                    ORDER BY id ASC';
1548
            $result = Database::query($sql);
1549
            $row = Database::fetch_array($result);
1550
            if ($row) {
1551
                return $row['addlock'];
1552
            }
1553
        }
1554
1555
        return null;
1556
    }
1557
1558
    /**
1559
     * Protect page.
1560
     *
1561
     * @author Juan Carlos Raña <[email protected]>
1562
     * return current database status of protect page and change it if get action
1563
     */
1564
    public function check_protect_page()
1565
    {
1566
        $tbl_wiki = $this->tbl_wiki;
1567
        $condition_session = $this->condition_session;
1568
        $groupfilter = $this->groupfilter;
1569
        $page = $this->page;
1570
1571
        $sql = 'SELECT * FROM '.$tbl_wiki.'
1572
              WHERE
1573
                c_id = '.$this->course_id.' AND
1574
                reflink="'.Database::escape_string($page).'" AND
1575
                '.$groupfilter.$condition_session.'
1576
              ORDER BY id ASC';
1577
1578
        $result = Database::query($sql);
1579
        $row = Database::fetch_array($result);
1580
1581
        if (!$row) {
1582
            return 0;
1583
        }
1584
1585
        $status_editlock = $row['editlock'];
1586
        $id = $row['page_id'];
1587
1588
        // Change status
1589
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
1590
            if (isset($_GET['actionpage']) && $_GET['actionpage'] == 'lock' && $status_editlock == 0) {
1591
                $status_editlock = 1;
1592
            }
1593
            if (isset($_GET['actionpage']) && $_GET['actionpage'] == 'unlock' && $status_editlock == 1) {
1594
                $status_editlock = 0;
1595
            }
1596
1597
            $sql = 'UPDATE '.$tbl_wiki.' SET
1598
                    editlock="'.Database::escape_string($status_editlock).'"
1599
                    WHERE c_id = '.$this->course_id.' AND page_id="'.$id.'"';
1600
            Database::query($sql);
1601
1602
            $sql = 'SELECT * FROM '.$tbl_wiki.'
1603
                    WHERE
1604
                        c_id = '.$this->course_id.' AND
1605
                        reflink="'.Database::escape_string($page).'" AND
1606
                    '.$groupfilter.$condition_session.'
1607
                  ORDER BY id ASC';
1608
            $result = Database::query($sql);
1609
            $row = Database::fetch_array($result);
1610
        }
1611
1612
        //show status
1613
        return (int) $row['editlock'];
1614
    }
1615
1616
    /**
1617
     * Visibility page.
1618
     *
1619
     * @author Juan Carlos Raña <[email protected]>
1620
     * return current database status of visibility and change it if get action
1621
     */
1622
    public function check_visibility_page()
1623
    {
1624
        $tbl_wiki = $this->tbl_wiki;
1625
        $page = $this->page;
1626
        $condition_session = $this->condition_session;
1627
        $groupfilter = $this->groupfilter;
1628
1629
        $sql = 'SELECT * FROM '.$tbl_wiki.'
1630
                WHERE
1631
                    c_id = '.$this->course_id.' AND
1632
                    reflink="'.Database::escape_string($page).'" AND
1633
                    '.$groupfilter.$condition_session.'
1634
                ORDER BY id';
1635
        $result = Database::query($sql);
1636
        $row = Database::fetch_array($result);
1637
1638
        if (!$row) {
1639
            return 0;
1640
        }
1641
1642
        $status_visibility = $row['visibility'];
1643
        //change status
1644
        if (api_is_allowed_to_edit(false, true) ||
1645
            api_is_platform_admin()
1646
        ) {
1647
            if (isset($_GET['actionpage']) &&
1648
                $_GET['actionpage'] == 'visible' &&
1649
                $status_visibility == 0
1650
            ) {
1651
                $status_visibility = 1;
1652
            }
1653
            if (isset($_GET['actionpage']) &&
1654
                $_GET['actionpage'] == 'invisible' &&
1655
                $status_visibility == 1
1656
            ) {
1657
                $status_visibility = 0;
1658
            }
1659
1660
            $sql = 'UPDATE '.$tbl_wiki.' SET
1661
                    visibility = "'.Database::escape_string($status_visibility).'"
1662
                    WHERE
1663
                        c_id = '.$this->course_id.' AND
1664
                        reflink="'.Database::escape_string($page).'" AND
1665
                        '.$groupfilter.$condition_session;
1666
            Database::query($sql);
1667
1668
            // Although the value now is assigned to all (not only the first),
1669
            // these three lines remain necessary.
1670
            // They do that by changing the page state is
1671
            // made when you press the button and not have to wait to change his page
1672
            $sql = 'SELECT * FROM '.$tbl_wiki.'
1673
                    WHERE
1674
                        c_id = '.$this->course_id.' AND
1675
                        reflink="'.Database::escape_string($page).'" AND
1676
                        '.$groupfilter.$condition_session.'
1677
                    ORDER BY id ASC';
1678
            $result = Database::query($sql);
1679
            $row = Database::fetch_array($result);
1680
        }
1681
1682
        if (empty($row['id'])) {
1683
            $row['visibility'] = 1;
1684
        }
1685
1686
        //show status
1687
        return $row['visibility'];
1688
    }
1689
1690
    /**
1691
     * Visibility discussion.
1692
     *
1693
     * @author Juan Carlos Raña <[email protected]>
1694
     *
1695
     * @return int current database status of discuss visibility
1696
     *             and change it if get action page
1697
     */
1698
    public function check_visibility_discuss()
1699
    {
1700
        $tbl_wiki = $this->tbl_wiki;
1701
        $page = $this->page;
1702
        $condition_session = $this->condition_session;
1703
        $groupfilter = $this->groupfilter;
1704
1705
        $sql = 'SELECT * FROM '.$tbl_wiki.'
1706
                WHERE
1707
                    c_id = '.$this->course_id.' AND
1708
                    reflink="'.Database::escape_string($page).'" AND
1709
                    '.$groupfilter.$condition_session.'
1710
                ORDER BY id ASC';
1711
        $result = Database::query($sql);
1712
        $row = Database::fetch_array($result);
1713
1714
        $status_visibility_disc = $row['visibility_disc'];
1715
1716
        //change status
1717
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
1718
            if (isset($_GET['actionpage']) &&
1719
                $_GET['actionpage'] == 'showdisc' &&
1720
                $status_visibility_disc == 0
1721
            ) {
1722
                $status_visibility_disc = 1;
1723
            }
1724
            if (isset($_GET['actionpage']) &&
1725
                $_GET['actionpage'] == 'hidedisc' &&
1726
                $status_visibility_disc == 1
1727
            ) {
1728
                $status_visibility_disc = 0;
1729
            }
1730
1731
            $sql = 'UPDATE '.$tbl_wiki.' SET
1732
                    visibility_disc="'.Database::escape_string($status_visibility_disc).'"
1733
                    WHERE
1734
                        c_id = '.$this->course_id.' AND
1735
                        reflink="'.Database::escape_string($page).'" AND
1736
                        '.$groupfilter.$condition_session;
1737
            Database::query($sql);
1738
1739
            // Although the value now is assigned to all (not only the first),
1740
            // these three lines remain necessary.
1741
            // They do that by changing the page state is made when you press
1742
            // the button and not have to wait to change his page
1743
            $sql = 'SELECT * FROM '.$tbl_wiki.'
1744
                    WHERE
1745
                        c_id = '.$this->course_id.' AND
1746
                        reflink="'.Database::escape_string($page).'" AND
1747
                        '.$groupfilter.$condition_session.'
1748
                    ORDER BY id ASC';
1749
            $result = Database::query($sql);
1750
            $row = Database::fetch_array($result);
1751
        }
1752
1753
        return $row['visibility_disc'];
1754
    }
1755
1756
    /**
1757
     * Lock add discussion.
1758
     *
1759
     * @author Juan Carlos Raña <[email protected]>
1760
     *
1761
     * @return int current database status of lock dicuss and change if get action
1762
     */
1763
    public function check_addlock_discuss()
1764
    {
1765
        $tbl_wiki = $this->tbl_wiki;
1766
        $page = $this->page;
1767
        $condition_session = $this->condition_session;
1768
        $groupfilter = $this->groupfilter;
1769
1770
        $sql = 'SELECT * FROM '.$tbl_wiki.'
1771
                WHERE
1772
                    c_id = '.$this->course_id.' AND
1773
                    reflink="'.Database::escape_string($page).'" AND
1774
                    '.$groupfilter.$condition_session.'
1775
                ORDER BY id ASC';
1776
        $result = Database::query($sql);
1777
        $row = Database::fetch_array($result);
1778
1779
        $status_addlock_disc = $row['addlock_disc'];
1780
1781
        //change status
1782
        if (api_is_allowed_to_edit() || api_is_platform_admin()) {
1783
            if (isset($_GET['actionpage']) &&
1784
                $_GET['actionpage'] == 'lockdisc' &&
1785
                $status_addlock_disc == 0
1786
            ) {
1787
                $status_addlock_disc = 1;
1788
            }
1789
            if (isset($_GET['actionpage']) &&
1790
                $_GET['actionpage'] == 'unlockdisc' &&
1791
                $status_addlock_disc == 1
1792
            ) {
1793
                $status_addlock_disc = 0;
1794
            }
1795
1796
            $sql = 'UPDATE '.$tbl_wiki.' SET
1797
                    addlock_disc="'.Database::escape_string($status_addlock_disc).'"
1798
                    WHERE
1799
                        c_id = '.$this->course_id.' AND
1800
                        reflink = "'.Database::escape_string($page).'" AND
1801
                         '.$groupfilter.$condition_session;
1802
            Database::query($sql);
1803
1804
            // Although the value now is assigned to all (not only the first),
1805
            // these three lines remain necessary.
1806
            // They do that by changing the page state is made when you press
1807
            // the button and not have to wait to change his page
1808
            $sql = 'SELECT * FROM '.$tbl_wiki.'
1809
                    WHERE
1810
                        c_id = '.$this->course_id.' AND
1811
                        reflink="'.Database::escape_string($page).'" AND
1812
                        '.$groupfilter.$condition_session.'
1813
                    ORDER BY id ASC';
1814
            $result = Database::query($sql);
1815
            $row = Database::fetch_array($result);
1816
        }
1817
1818
        return $row['addlock_disc'];
1819
    }
1820
1821
    /**
1822
     * Lock rating discussion.
1823
     *
1824
     * @author Juan Carlos Raña <[email protected]>
1825
     *
1826
     * @return int current database status of rating discuss and change it if get action
1827
     */
1828
    public function check_ratinglock_discuss()
1829
    {
1830
        $tbl_wiki = $this->tbl_wiki;
1831
        $page = $this->page;
1832
        $condition_session = $this->condition_session;
1833
        $groupfilter = $this->groupfilter;
1834
1835
        $sql = 'SELECT * FROM '.$tbl_wiki.'
1836
                WHERE
1837
                    c_id = '.$this->course_id.' AND
1838
                    reflink="'.Database::escape_string($page).'" AND
1839
                    '.$groupfilter.$condition_session.'
1840
                ORDER BY id ASC';
1841
        $result = Database::query($sql);
1842
        $row = Database::fetch_array($result);
1843
        $status_ratinglock_disc = $row['ratinglock_disc'];
1844
1845
        //change status
1846
        if (api_is_allowed_to_edit(false, true) ||
1847
            api_is_platform_admin()
1848
        ) {
1849
            if (isset($_GET['actionpage']) &&
1850
                $_GET['actionpage'] == 'lockrating' &&
1851
                $status_ratinglock_disc == 0
1852
            ) {
1853
                $status_ratinglock_disc = 1;
1854
            }
1855
            if (isset($_GET['actionpage']) &&
1856
                $_GET['actionpage'] == 'unlockrating' &&
1857
                $status_ratinglock_disc == 1
1858
            ) {
1859
                $status_ratinglock_disc = 0;
1860
            }
1861
1862
            $sql = 'UPDATE '.$tbl_wiki.'
1863
                    SET ratinglock_disc="'.Database::escape_string($status_ratinglock_disc).'"
1864
                    WHERE
1865
                        c_id = '.$this->course_id.' AND
1866
                        reflink="'.Database::escape_string($page).'" AND
1867
                        '.$groupfilter.$condition_session;
1868
            // Visibility. Value to all,not only for the first
1869
            Database::query($sql);
1870
1871
            // Although the value now is assigned to all (not only the first),
1872
            // these three lines remain necessary. They do that by changing the
1873
            // page state is made when you press the button and not have to wait
1874
            // to change his page
1875
            $sql = 'SELECT * FROM '.$tbl_wiki.'
1876
                    WHERE
1877
                        c_id = '.$this->course_id.' AND
1878
                        reflink="'.Database::escape_string($page).'" AND
1879
                    '.$groupfilter.$condition_session.'
1880
                  ORDER BY id ASC';
1881
            $result = Database::query($sql);
1882
            $row = Database::fetch_array($result);
1883
        }
1884
1885
        return $row['ratinglock_disc'];
1886
    }
1887
1888
    /**
1889
     * Notify page changes.
1890
     *
1891
     * @author Juan Carlos Raña <[email protected]>
1892
     *
1893
     * @return int the current notification status
1894
     */
1895
    public function check_notify_page($reflink)
1896
    {
1897
        $tbl_wiki = $this->tbl_wiki;
1898
        $tbl_wiki_mailcue = $this->tbl_wiki_mailcue;
1899
        $condition_session = $this->condition_session;
1900
        $groupfilter = $this->groupfilter;
1901
        $userId = api_get_user_id();
1902
1903
        $sql = 'SELECT * FROM '.$tbl_wiki.'
1904
                WHERE
1905
                    c_id = '.$this->course_id.' AND
1906
                    reflink="'.$reflink.'" AND
1907
                    '.$groupfilter.$condition_session.'
1908
                ORDER BY id ASC';
1909
        $result = Database::query($sql);
1910
        $row = Database::fetch_array($result);
1911
        $id = $row['id'];
1912
        $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
1913
                WHERE
1914
                    c_id = '.$this->course_id.' AND
1915
                    id="'.$id.'" AND
1916
                    user_id="'.api_get_user_id().'" AND
1917
                    type="P"';
1918
        $result = Database::query($sql);
1919
        $row = Database::fetch_array($result);
1920
1921
        $idm = $row ? $row['id'] : 0;
1922
        if (empty($idm)) {
1923
            $status_notify = 0;
1924
        } else {
1925
            $status_notify = 1;
1926
        }
1927
1928
        // Change status
1929
        if (isset($_GET['actionpage']) &&
1930
            $_GET['actionpage'] == 'locknotify' &&
1931
            $status_notify == 0
1932
        ) {
1933
            $sql = "SELECT id FROM $tbl_wiki_mailcue
1934
                    WHERE c_id = ".$this->course_id." AND id = $id AND user_id = $userId";
1935
            $result = Database::query($sql);
1936
            $exist = false;
1937
            if (Database::num_rows($result)) {
1938
                $exist = true;
1939
            }
1940
            if ($exist == false) {
1941
                $sql = "INSERT INTO ".$tbl_wiki_mailcue." (c_id, id, user_id, type, group_id, session_id) VALUES
1942
                (".$this->course_id.", '".$id."','".api_get_user_id()."','P','".$this->group_id."','".$this->session_id."')";
1943
                Database::query($sql);
1944
            }
1945
            $status_notify = 1;
1946
        }
1947
1948
        if (isset($_GET['actionpage']) &&
1949
            $_GET['actionpage'] == 'unlocknotify' &&
1950
            $status_notify == 1
1951
        ) {
1952
            $sql = 'DELETE FROM '.$tbl_wiki_mailcue.'
1953
                    WHERE
1954
                        id="'.$id.'" AND
1955
                        user_id="'.api_get_user_id().'" AND
1956
                        type="P" AND
1957
                        c_id = '.$this->course_id;
1958
            Database::query($sql);
1959
            $status_notify = 0;
1960
        }
1961
1962
        return $status_notify;
1963
    }
1964
1965
    /**
1966
     * Notify discussion changes.
1967
     *
1968
     * @author Juan Carlos Raña <[email protected]>
1969
     *
1970
     * @param string $reflink
1971
     *
1972
     * @return int current database status of rating discuss and change it if get action
1973
     */
1974
    public function check_notify_discuss($reflink)
1975
    {
1976
        $tbl_wiki_mailcue = $this->tbl_wiki_mailcue;
1977
        $tbl_wiki = $this->tbl_wiki;
1978
        $condition_session = $this->condition_session;
1979
        $groupfilter = $this->groupfilter;
1980
1981
        $sql = 'SELECT * FROM '.$tbl_wiki.'
1982
                WHERE
1983
                    c_id = '.$this->course_id.' AND
1984
                    reflink="'.$reflink.'" AND
1985
                    '.$groupfilter.$condition_session.'
1986
                ORDER BY id ASC';
1987
        $result = Database::query($sql);
1988
        $row = Database::fetch_array($result);
1989
        $id = $row['id'];
1990
        $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
1991
                WHERE
1992
                    c_id = '.$this->course_id.' AND id="'.$id.'" AND user_id="'.api_get_user_id().'" AND type="D"';
1993
        $result = Database::query($sql);
1994
        $row = Database::fetch_array($result);
1995
        $idm = $row ? $row['id'] : 0;
1996
1997
        if (empty($idm)) {
1998
            $status_notify_disc = 0;
1999
        } else {
2000
            $status_notify_disc = 1;
2001
        }
2002
2003
        // change status
2004
        if (isset($_GET['actionpage']) &&
2005
            $_GET['actionpage'] == 'locknotifydisc' &&
2006
            $status_notify_disc == 0
2007
        ) {
2008
            $sql = "INSERT INTO ".$tbl_wiki_mailcue." (c_id, id, user_id, type, group_id, session_id) VALUES
2009
            (".$this->course_id.", '".$id."','".api_get_user_id()."','D','".$this->group_id."','".$this->session_id."')";
2010
            Database::query($sql);
2011
            $status_notify_disc = 1;
2012
        }
2013
        if (isset($_GET['actionpage']) &&
2014
            $_GET['actionpage'] == 'unlocknotifydisc' &&
2015
            $status_notify_disc == 1
2016
        ) {
2017
            $sql = 'DELETE FROM '.$tbl_wiki_mailcue.'
2018
                    WHERE
2019
                        id="'.$id.'" AND
2020
                        user_id="'.api_get_user_id().'" AND
2021
                        type="D" AND
2022
                        c_id = '.$this->course_id;
2023
            Database::query($sql);
2024
            $status_notify_disc = 0;
2025
        }
2026
2027
        return $status_notify_disc;
2028
    }
2029
2030
    /**
2031
     * Notify all changes.
2032
     *
2033
     * @author Juan Carlos Raña <[email protected]>
2034
     */
2035
    public function check_notify_all()
2036
    {
2037
        $tbl_wiki_mailcue = $this->tbl_wiki_mailcue;
2038
2039
        $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
2040
                WHERE
2041
                    c_id = '.$this->course_id.' AND
2042
                    user_id="'.api_get_user_id().'" AND
2043
                    type="F" AND
2044
                    group_id="'.$this->group_id.'" AND
2045
                    session_id="'.$this->session_id.'"';
2046
        $result = Database::query($sql);
2047
        $row = Database::fetch_array($result);
2048
2049
        $idm = $row ? $row['user_id'] : 0;
2050
2051
        if (empty($idm)) {
2052
            $status_notify_all = 0;
2053
        } else {
2054
            $status_notify_all = 1;
2055
        }
2056
2057
        //change status
2058
        if (isset($_GET['actionpage']) &&
2059
            $_GET['actionpage'] == 'locknotifyall' &&
2060
            $status_notify_all == 0
2061
        ) {
2062
            $sql = "INSERT INTO ".$tbl_wiki_mailcue." (c_id, user_id, type, group_id, session_id) VALUES
2063
            (".$this->course_id.", '".api_get_user_id()."','F','".$this->group_id."','".$this->session_id."')";
2064
            Database::query($sql);
2065
            $status_notify_all = 1;
2066
        }
2067
2068
        if (isset($_GET['actionpage']) &&
2069
            $_GET['actionpage'] == 'unlocknotifyall' &&
2070
            $status_notify_all == 1
2071
        ) {
2072
            $sql = 'DELETE FROM '.$tbl_wiki_mailcue.'
2073
                   WHERE
2074
                    user_id="'.api_get_user_id().'" AND
2075
                    type="F" AND
2076
                    group_id="'.$this->group_id.'" AND
2077
                    session_id="'.$this->session_id.'" AND
2078
                    c_id = '.$this->course_id;
2079
            Database::query($sql);
2080
            $status_notify_all = 0;
2081
        }
2082
2083
        //show status
2084
        return $status_notify_all;
2085
    }
2086
2087
    /**
2088
     * Sends pending e-mails.
2089
     */
2090
    public function check_emailcue(
2091
        $id_or_ref,
2092
        $type,
2093
        $lastime = '',
2094
        $lastuser = ''
2095
    ) {
2096
        $tbl_wiki_mailcue = $this->tbl_wiki_mailcue;
2097
        $tbl_wiki = $this->tbl_wiki;
2098
        $condition_session = $this->condition_session;
2099
        $groupfilter = $this->groupfilter;
2100
        $_course = $this->courseInfo;
2101
        $group_properties = GroupManager::get_group_properties($this->group_id);
2102
        $group_name = $group_properties ? $group_properties['name'] : '';
2103
        $allow_send_mail = false; //define the variable to below
2104
        $email_assignment = null;
2105
        if ($type == 'P') {
2106
            //if modifying a wiki page
2107
            //first, current author and time
2108
            //Who is the author?
2109
            $userinfo = api_get_user_info($lastuser);
2110
            $email_user_author = get_lang('EditedBy').': '.$userinfo['complete_name'];
2111
2112
            //When ?
2113
            $year = substr($lastime, 0, 4);
2114
            $month = substr($lastime, 5, 2);
2115
            $day = substr($lastime, 8, 2);
2116
            $hours = substr($lastime, 11, 2);
2117
            $minutes = substr($lastime, 14, 2);
2118
            $seconds = substr($lastime, 17, 2);
2119
            $email_date_changes = $day.' '.$month.' '.$year.' '.$hours.":".$minutes.":".$seconds;
2120
2121
            //second, extract data from first reg
2122
            $sql = 'SELECT * FROM '.$tbl_wiki.'
2123
                    WHERE
2124
                        c_id = '.$this->course_id.' AND
2125
                        reflink="'.$id_or_ref.'" AND
2126
                        '.$groupfilter.$condition_session.'
2127
                    ORDER BY id ASC';
2128
            $result = Database::query($sql);
2129
            $row = Database::fetch_array($result);
2130
            $id = $row['id'];
2131
            $email_page_name = $row['title'];
2132
            if ($row['visibility'] == 1) {
2133
                $allow_send_mail = true; //if visibility off - notify off
2134
                $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
2135
                        WHERE
2136
                            c_id = '.$this->course_id.' AND
2137
                            id="'.$id.'" AND
2138
                            type="'.$type.'" OR
2139
                            type="F" AND
2140
                            group_id="'.$this->group_id.'" AND
2141
                            session_id="'.$this->session_id.'"';
2142
                //type: P=page, D=discuss, F=full.
2143
                $result = Database::query($sql);
2144
                $emailtext = get_lang('EmailWikipageModified').
2145
                    '<strong>'.$email_page_name.'</strong> '.
2146
                    get_lang('Wiki');
2147
            }
2148
        } elseif ($type == 'D') {
2149
            //if added a post to discuss
2150
            //first, current author and time
2151
            //Who is the author of last message?
2152
            $userinfo = api_get_user_info($lastuser);
2153
            $email_user_author = get_lang('AddedBy').': '.$userinfo['complete_name'];
2154
2155
            //When ?
2156
            $year = substr($lastime, 0, 4);
2157
            $month = substr($lastime, 5, 2);
2158
            $day = substr($lastime, 8, 2);
2159
            $hours = substr($lastime, 11, 2);
2160
            $minutes = substr($lastime, 14, 2);
2161
            $seconds = substr($lastime, 17, 2);
2162
            $email_date_changes = $day.' '.$month.' '.$year.' '.$hours.":".$minutes.":".$seconds;
2163
            //second, extract data from first reg
2164
            $id = $id_or_ref; //$id_or_ref is id from tblwiki
2165
            $sql = 'SELECT * FROM '.$tbl_wiki.'
2166
                    WHERE c_id = '.$this->course_id.' AND id="'.$id.'"
2167
                    ORDER BY id ASC';
2168
2169
            $result = Database::query($sql);
2170
            $row = Database::fetch_array($result);
2171
2172
            $email_page_name = $row['title'];
2173
            if ($row['visibility_disc'] == 1) {
2174
                $allow_send_mail = true; //if visibility off - notify off
2175
                $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
2176
                        WHERE
2177
                            c_id = '.$this->course_id.' AND
2178
                            id="'.$id.'" AND
2179
                            type="'.$type.'" OR
2180
                            type="F" AND
2181
                            group_id="'.$this->group_id.'" AND
2182
                            session_id="'.$this->session_id.'"';
2183
                //type: P=page, D=discuss, F=full
2184
                $result = Database::query($sql);
2185
                $emailtext = get_lang(
2186
                        'EmailWikiPageDiscAdded'
2187
                    ).' <strong>'.$email_page_name.'</strong> '.get_lang(
2188
                        'Wiki'
2189
                    );
2190
            }
2191
        } elseif ($type == 'A') {
2192
            //for added pages
2193
            $id = 0; //for tbl_wiki_mailcue
2194
            $sql = 'SELECT * FROM '.$tbl_wiki.'
2195
                    WHERE c_id = '.$this->course_id.'
2196
                    ORDER BY id DESC'; //the added is always the last
2197
2198
            $result = Database::query($sql);
2199
            $row = Database::fetch_array($result);
2200
            $email_page_name = $row['title'];
2201
2202
            //Who is the author?
2203
            $userinfo = api_get_user_info($row['user_id']);
2204
            $email_user_author = get_lang('AddedBy').': '.$userinfo['complete_name'];
2205
2206
            //When ?
2207
            $year = substr($row['dtime'], 0, 4);
2208
            $month = substr($row['dtime'], 5, 2);
2209
            $day = substr($row['dtime'], 8, 2);
2210
            $hours = substr($row['dtime'], 11, 2);
2211
            $minutes = substr($row['dtime'], 14, 2);
2212
            $seconds = substr($row['dtime'], 17, 2);
2213
            $email_date_changes = $day.' '.$month.' '.$year.' '.$hours.":".$minutes.":".$seconds;
2214
2215
            if ($row['assignment'] == 0) {
2216
                $allow_send_mail = true;
2217
            } elseif ($row['assignment'] == 1) {
2218
                $email_assignment = get_lang('AssignmentDescExtra').' ('.get_lang('AssignmentMode').')';
2219
                $allow_send_mail = true;
2220
            } elseif ($row['assignment'] == 2) {
2221
                $allow_send_mail = false; //Mode tasks: avoids notifications to all users about all users
2222
            }
2223
2224
            $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
2225
                    WHERE
2226
                        c_id = '.$this->course_id.' AND
2227
                        id="'.$id.'" AND
2228
                        type="F" AND
2229
                        group_id="'.$this->group_id.'" AND
2230
                        session_id="'.$this->session_id.'"';
2231
2232
            //type: P=page, D=discuss, F=full
2233
            $result = Database::query($sql);
2234
            $emailtext = get_lang('EmailWikiPageAdded').' <strong>'.
2235
                $email_page_name.'</strong> '.get_lang('In').' '.get_lang('Wiki');
2236
        } elseif ($type == 'E') {
2237
            $id = 0;
2238
            $allow_send_mail = true;
2239
            // Who is the author?
2240
            $userinfo = api_get_user_info(api_get_user_id()); //current user
2241
            $email_user_author = get_lang('DeletedBy').': '.$userinfo['complete_name'];
2242
            //When ?
2243
            $today = date('r'); //current time
2244
            $email_date_changes = $today;
2245
            $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
2246
                    WHERE
2247
                        c_id = '.$this->course_id.' AND
2248
                        id="'.$id.'" AND type="F" AND
2249
                        group_id="'.$this->group_id.'" AND
2250
                        session_id="'.$this->session_id.'"'; //type: P=page, D=discuss, F=wiki
2251
            $result = Database::query($sql);
2252
            $emailtext = get_lang('EmailWikipageDedeleted');
2253
        }
2254
        ///make and send email
2255
        if ($allow_send_mail) {
2256
2257
            $extraParameters = [];
2258
            if (api_get_configuration_value('mail_header_from_custom_course_logo') == true) {
2259
                $extraParameters = ['logo' => CourseManager::getCourseEmailPicture($_course)];
2260
            }
2261
2262
            while ($row = Database::fetch_array($result)) {
2263
                $userinfo = api_get_user_info(
2264
                    $row['user_id']
2265
                ); //$row['user_id'] obtained from tbl_wiki_mailcue
2266
                $name_to = $userinfo['complete_name'];
2267
                $email_to = $userinfo['email'];
2268
                $sender_name = api_get_setting('emailAdministrator');
2269
                $sender_email = api_get_setting('emailAdministrator');
2270
                $email_subject = get_lang(
2271
                        'EmailWikiChanges'
2272
                    ).' - '.$_course['official_code'];
2273
                $email_body = get_lang('DearUser').' '.api_get_person_name(
2274
                        $userinfo['firstname'],
2275
                        $userinfo['lastname']
2276
                    ).',<br /><br />';
2277
                if (0 == $this->session_id) {
2278
                    $email_body .= $emailtext.' <strong>'.$_course['name'].' - '.$group_name.'</strong><br /><br /><br />';
2279
                } else {
2280
                    $email_body .= $emailtext.' <strong>'.$_course['name'].' ('.api_get_session_name().') - '.$group_name.'</strong><br /><br /><br />';
2281
                }
2282
                $email_body .= $email_user_author.' ('.$email_date_changes.')<br /><br /><br />';
2283
                $email_body .= $email_assignment.'<br /><br /><br />';
2284
                $email_body .= '<font size="-2">'.get_lang(
2285
                        'EmailWikiChangesExt_1'
2286
                    ).': <strong>'.get_lang('NotifyChanges').'</strong><br />';
2287
                $email_body .= get_lang(
2288
                        'EmailWikiChangesExt_2'
2289
                    ).': <strong>'.get_lang(
2290
                        'NotNotifyChanges'
2291
                    ).'</strong></font><br />';
2292
                @api_mail_html(
2293
                    $name_to,
2294
                    $email_to,
2295
                    $email_subject,
2296
                    $email_body,
2297
                    $sender_name,
2298
                    $sender_email,
2299
                    [],
2300
                    [],
2301
                    false,
2302
                    $extraParameters,
2303
                    ''
2304
                );
2305
            }
2306
        }
2307
    }
2308
2309
    /**
2310
     * Function export last wiki page version to document area.
2311
     *
2312
     * @param int $doc_id wiki page id
2313
     *
2314
     * @return mixed
2315
     *
2316
     * @author Juan Carlos Raña <[email protected]>
2317
     */
2318
    public function export2doc($doc_id)
2319
    {
2320
        $_course = $this->courseInfo;
2321
        $groupInfo = GroupManager::get_group_properties($this->group_id);
2322
        $data = self::getWikiDataFromDb($doc_id);
2323
2324
        if (empty($data)) {
2325
            return false;
2326
        }
2327
2328
        $wikiTitle = $data['title'];
2329
        $wikiContents = $data['content'];
2330
2331
        $template =
2332
            '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2333
            <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{LANGUAGE}" lang="{LANGUAGE}">
2334
            <head>
2335
            <title>{TITLE}</title>
2336
            <meta http-equiv="Content-Type" content="text/html; charset={ENCODING}" />
2337
            <style type="text/css" media="screen, projection">
2338
            /*<![CDATA[*/
2339
            {CSS}
2340
            /*]]>*/
2341
            </style>
2342
            {ASCIIMATHML_SCRIPT}</head>
2343
            <body dir="{TEXT_DIRECTION}">
2344
            {CONTENT}
2345
            </body>
2346
            </html>';
2347
2348
        $css_file = api_get_path(SYS_CSS_PATH).'themes/'.api_get_setting('stylesheets').'/default.css';
2349
        if (file_exists($css_file)) {
2350
            $css = @file_get_contents($css_file);
2351
        } else {
2352
            $css = '';
2353
        }
2354
        // Fixing some bugs in css files.
2355
        $root_rel = api_get_path(REL_PATH);
2356
        $css_path = 'main/css/';
2357
        $theme = api_get_setting('stylesheets').'/';
2358
        $css = str_replace(
2359
            'behavior:url("/main/css/csshover3.htc");',
2360
            '',
2361
            $css
2362
        );
2363
        $css = str_replace('main/', $root_rel.'main/', $css);
2364
        $css = str_replace(
2365
            'images/',
2366
            $root_rel.$css_path.$theme.'images/',
2367
            $css
2368
        );
2369
        $css = str_replace('../../img/', $root_rel.'main/img/', $css);
2370
        $asciimathmal_script = (api_contains_asciimathml(
2371
                $wikiContents
2372
            ) || api_contains_asciisvg($wikiContents))
2373
            ? '<script src="'.api_get_path(
2374
                WEB_CODE_PATH
2375
            ).'inc/lib/javascript/asciimath/ASCIIMathML.js" type="text/javascript"></script>'."\n" : '';
2376
2377
        $template = str_replace(
2378
            [
2379
                '{LANGUAGE}',
2380
                '{ENCODING}',
2381
                '{TEXT_DIRECTION}',
2382
                '{TITLE}',
2383
                '{CSS}',
2384
                '{ASCIIMATHML_SCRIPT}',
2385
            ],
2386
            [
2387
                api_get_language_isocode(),
2388
                api_get_system_encoding(),
2389
                api_get_text_direction(),
2390
                $wikiTitle,
2391
                $css,
2392
                $asciimathmal_script,
2393
            ],
2394
            $template
2395
        );
2396
2397
        if (0 != $this->group_id) {
2398
            $groupPart = '_group'.$this->group_id; // and add groupId to put the same document title in different groups
2399
            $group_properties = GroupManager::get_group_properties($this->group_id);
2400
            $groupPath = $group_properties['directory'];
2401
        } else {
2402
            $groupPart = '';
2403
            $groupPath = '';
2404
        }
2405
2406
        $exportDir = api_get_path(SYS_COURSE_PATH).api_get_course_path(
2407
            ).'/document'.$groupPath;
2408
        $exportFile = api_replace_dangerous_char($wikiTitle).$groupPart;
2409
        $wikiContents = trim(
2410
            preg_replace(
2411
                "/\[[\[]?([^\]|]*)[|]?([^|\]]*)\][\]]?/",
2412
                "$1",
2413
                $wikiContents
2414
            )
2415
        );
2416
        //TODO: put link instead of title
2417
        $wikiContents = str_replace('{CONTENT}', $wikiContents, $template);
2418
        // replace relative path by absolute path for courses, so you can see
2419
        // items into this page wiki (images, mp3, etc..) exported in documents
2420
        if (api_strpos(
2421
                $wikiContents,
2422
                '../..'.api_get_path(REL_COURSE_PATH)
2423
            ) !== false) {
2424
            $web_course_path = api_get_path(WEB_COURSE_PATH);
2425
            $wikiContents = str_replace(
2426
                '../..'.api_get_path(REL_COURSE_PATH),
2427
                $web_course_path,
2428
                $wikiContents
2429
            );
2430
        }
2431
2432
        $i = 1;
2433
        //only export last version, but in new export new version in document area
2434
        while (file_exists($exportDir.'/'.$exportFile.'_'.$i.'.html')) {
2435
            $i++;
2436
        }
2437
2438
        $wikiFileName = $exportFile.'_'.$i.'.html';
2439
        $exportPath = $exportDir.'/'.$wikiFileName;
2440
2441
        file_put_contents($exportPath, $wikiContents);
2442
        $doc_id = add_document(
2443
            $_course,
2444
            $groupPath.'/'.$wikiFileName,
2445
            'file',
2446
            filesize($exportPath),
2447
            $wikiTitle
2448
        );
2449
2450
        api_item_property_update(
2451
            $_course,
2452
            TOOL_DOCUMENT,
2453
            $doc_id,
2454
            'DocumentAdded',
2455
            api_get_user_id(),
2456
            $groupInfo
2457
        );
2458
2459
        return $doc_id;
2460
    }
2461
2462
    /**
2463
     * Exports the wiki page to PDF.
2464
     */
2465
    public function export_to_pdf($id, $course_code)
2466
    {
2467
        if (!api_is_platform_admin()) {
2468
            if (api_get_setting('students_export2pdf') !== 'true') {
2469
                Display::addFlash(
2470
                    Display::return_message(
2471
                        get_lang('PDFDownloadNotAllowedForStudents'),
2472
                        'error',
2473
                        false
2474
                    )
2475
                );
2476
2477
                return false;
2478
            }
2479
        }
2480
2481
        $data = self::getWikiDataFromDb($id);
2482
        $content_pdf = api_html_entity_decode(
2483
            $data['content'],
2484
            ENT_QUOTES,
2485
            api_get_system_encoding()
2486
        );
2487
2488
        //clean wiki links
2489
        $content_pdf = trim(
2490
            preg_replace(
2491
                "/\[[\[]?([^\]|]*)[|]?([^|\]]*)\][\]]?/",
2492
                "$1",
2493
                $content_pdf
2494
            )
2495
        );
2496
        //TODO: It should be better to display the link insted of the tile but it is hard for [[title]] links
2497
2498
        $title_pdf = api_html_entity_decode(
2499
            $data['title'],
2500
            ENT_QUOTES,
2501
            api_get_system_encoding()
2502
        );
2503
        $title_pdf = api_utf8_encode($title_pdf, api_get_system_encoding());
2504
        $content_pdf = api_utf8_encode($content_pdf, api_get_system_encoding());
2505
2506
        $html = '
2507
        <!-- defines the headers/footers - this must occur before the headers/footers are set -->
2508
2509
        <!--mpdf
2510
        <pageheader name="odds" content-left="'.$title_pdf.'"  header-style-left="color: #880000; font-style: italic;"  line="1" />
2511
        <pagefooter name="odds" content-right="{PAGENO}/{nb}" line="1" />
2512
2513
        <!-- set the headers/footers - they will occur from here on in the document -->
2514
        <!--mpdf
2515
        <setpageheader name="odds" page="odd" value="on" show-this-page="1" />
2516
        <setpagefooter name="odds" page="O" value="on" />
2517
2518
        mpdf-->'.$content_pdf;
2519
2520
        $css = api_get_print_css();
2521
2522
        $pdf = new PDF();
2523
        $pdf->content_to_pdf($html, $css, $title_pdf, $course_code);
2524
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
2525
    }
2526
2527
    /**
2528
     * Function prevent double post (reload or F5).
2529
     */
2530
    public function double_post($wpost_id)
2531
    {
2532
        $postId = Session::read('wpost_id');
2533
        if (!empty($postId)) {
2534
            if ($wpost_id == $postId) {
2535
                return false;
2536
            } else {
2537
                Session::write('wpost_id', $wpost_id);
2538
2539
                return true;
2540
            }
2541
        } else {
2542
            Session::write('wpost_id', $wpost_id);
2543
2544
            return true;
2545
        }
2546
    }
2547
2548
    /**
2549
     * Function wizard individual assignment.
2550
     *
2551
     * @author Juan Carlos Raña <[email protected]>
2552
     */
2553
    public function auto_add_page_users($values)
2554
    {
2555
        $assignment_type = $values['assignment'];
2556
        $groupInfo = GroupManager::get_group_properties($this->group_id);
2557
        if (0 == $this->group_id) {
2558
            //extract course members
2559
            if (!empty($this->session_id)) {
2560
                $a_users_to_add = CourseManager::get_user_list_from_course_code($this->courseCode, $this->session_id);
2561
            } else {
2562
                $a_users_to_add = CourseManager::get_user_list_from_course_code($this->courseCode);
2563
            }
2564
        } else {
2565
            //extract group members
2566
            $subscribed_users = GroupManager::get_subscribed_users($groupInfo);
2567
            $subscribed_tutors = GroupManager::get_subscribed_tutors(
2568
                $groupInfo
2569
            );
2570
            $a_users_to_add_with_duplicates = array_merge(
2571
                $subscribed_users,
2572
                $subscribed_tutors
2573
            );
2574
            //remove duplicates
2575
            $a_users_to_add = $a_users_to_add_with_duplicates;
2576
            $a_users_to_add = array_unique($a_users_to_add);
2577
        }
2578
2579
        $all_students_pages = [];
2580
        // Data about teacher
2581
        $userId = api_get_user_id();
2582
        $userinfo = api_get_user_info($userId);
2583
        $username = api_htmlentities(
2584
            sprintf(get_lang('LoginX'), $userinfo['username'], ENT_QUOTES)
2585
        );
2586
        $name = $userinfo['complete_name']." - ".$username;
2587
        $photo = '<img src="'.$userinfo['avatar'].'" alt="'.$name.'"  width="40" height="50" align="top" title="'.$name.'"  />';
2588
2589
        // teacher assignment title
2590
        $title_orig = $values['title'];
2591
2592
        // teacher assignment reflink
2593
        $link2teacher = $values['title'] = $title_orig."_uass".$userId;
2594
2595
        // first: teacher name, photo, and assignment description (original content)
2596
        $content_orig_A = '<div align="center" style="background-color: #F5F8FB; border:solid; border-color: #E6E6E6">
2597
        <table border="0">
2598
            <tr><td style="font-size:24px">'.get_lang('AssignmentDesc').'</td></tr>
2599
            <tr><td>'.$photo.'<br />'.Display::tag(
2600
                'span',
2601
                api_get_person_name(
2602
                    $userinfo['firstname'],
2603
                    $userinfo['lastname']
2604
                ),
2605
                ['title' => $username]
2606
            ).'</td></tr>
2607
        </table></div>';
2608
2609
        $content_orig_B = '<br/><div align="center" style="font-size:24px">'.
2610
            get_lang('AssignmentDescription').': '.
2611
            $title_orig.'</div><br/>'.Security::remove_XSS($_POST['content']);
2612
2613
        //Second: student list (names, photo and links to their works).
2614
        //Third: Create Students work pages.
2615
        foreach ($a_users_to_add as $o_user_to_add) {
2616
            if ($o_user_to_add['user_id'] != $userId) {
2617
                // except that puts the task
2618
                $assig_user_id = $o_user_to_add['user_id'];
2619
                // identifies each page as created by the student, not by teacher
2620
2621
                $userPicture = UserManager::getUserPicture($assig_user_id);
2622
                $username = api_htmlentities(
2623
                    sprintf(
2624
                        get_lang('LoginX'),
2625
                        $o_user_to_add['username'],
2626
                        ENT_QUOTES
2627
                    )
2628
                );
2629
                $name = api_get_person_name(
2630
                        $o_user_to_add['firstname'],
2631
                        $o_user_to_add['lastname']
2632
                    )." . ".$username;
2633
                $photo = '<img src="'.$userPicture.'" alt="'.$name.'"  width="40" height="50" align="bottom" title="'.$name.'"  />';
2634
2635
                $is_tutor_of_group = GroupManager::is_tutor_of_group(
2636
                    $assig_user_id,
2637
                    $groupInfo
2638
                ); //student is tutor
2639
                $is_tutor_and_member = GroupManager::is_tutor_of_group(
2640
                        $assig_user_id,
2641
                        $groupInfo
2642
                    ) &&
2643
                    GroupManager::is_subscribed($assig_user_id, $groupInfo);
2644
                // student is tutor and member
2645
                if ($is_tutor_and_member) {
2646
                    $status_in_group = get_lang('GroupTutorAndMember');
2647
                } else {
2648
                    if ($is_tutor_of_group) {
2649
                        $status_in_group = get_lang('GroupTutor');
2650
                    } else {
2651
                        $status_in_group = " "; //get_lang('GroupStandardMember')
2652
                    }
2653
                }
2654
2655
                if ($assignment_type == 1) {
2656
                    $values['title'] = $title_orig;
2657
                    $values['content'] = '<div align="center" style="background-color: #F5F8FB; border:solid; border-color: #E6E6E6">
2658
                    <table border="0">
2659
                    <tr><td style="font-size:24px">'.get_lang('AssignmentWork').'</td></tr>
2660
                    <tr><td>'.$photo.'<br />'.$name.'</td></tr></table>
2661
                    </div>[['.$link2teacher.' | '.get_lang(
2662
                            'AssignmentLinktoTeacherPage'
2663
                        ).']] ';
2664
                    //If $content_orig_B is added here, the task written by
2665
                    // the professor was copied to the page of each student.
2666
                    // TODO: config options
2667
                    // AssignmentLinktoTeacherPage
2668
                    $all_students_pages[] = '<li>'.
2669
                        Display::tag(
2670
                            'span',
2671
                            strtoupper(
2672
                                $o_user_to_add['lastname']
2673
                            ).', '.$o_user_to_add['firstname'],
2674
                            ['title' => $username]
2675
                        ).
2676
                        ' [['.Security::remove_XSS(
2677
                            $_POST['title']
2678
                        )."_uass".$assig_user_id.' | '.$photo.']] '.$status_in_group.'</li>';
2679
                    // don't change this line without guaranteeing
2680
                    // that users will be ordered by last names in the
2681
                    // following format (surname, name)
2682
                    $values['assignment'] = 2;
2683
                }
2684
                $this->assig_user_id = $assig_user_id;
2685
                $this->save_new_wiki($values);
2686
            }
2687
        }
2688
2689
        foreach ($a_users_to_add as $o_user_to_add) {
2690
            if ($o_user_to_add['user_id'] == $userId) {
2691
                $assig_user_id = $o_user_to_add['user_id'];
2692
                if ($assignment_type == 1) {
2693
                    $values['title'] = $title_orig;
2694
                    $values['comment'] = get_lang('AssignmentDesc');
2695
                    sort($all_students_pages);
2696
                    $values['content'] = $content_orig_A.$content_orig_B.'<br/>
2697
                    <div align="center" style="font-size:18px; background-color: #F5F8FB; border:solid; border-color:#E6E6E6">
2698
                    '.get_lang('AssignmentLinkstoStudentsPage').'
2699
                    </div><br/>
2700
                    <div style="background-color: #F5F8FB; border:solid; border-color:#E6E6E6">
2701
                    <ol>'.implode($all_students_pages).'</ol>
2702
                    </div>
2703
                    <br/>';
2704
                    $values['assignment'] = 1;
2705
                }
2706
                $this->assig_user_id = $assig_user_id;
2707
                $this->save_new_wiki($values);
2708
            }
2709
        }
2710
    }
2711
2712
    /**
2713
     * Displays the results of a wiki search.
2714
     */
2715
    public function display_wiki_search_results(
2716
        string $search_term,
2717
        int $search_content = 0,
2718
        int $all_vers = 0,
2719
        array $categoryIdList = [],
2720
        bool $matchAllCategories = false
2721
    ) {
2722
        $tbl_wiki = $this->tbl_wiki;
2723
        $sessionCondition = api_get_session_condition($this->session_id, true, false, 'wp.session_id');
2724
        $groupfilter = ' wp.group_id = '.$this->group_id.' ';
2725
        $subGroupfilter = ' s2.group_id = '.$this->group_id.' ';
2726
        $subSessionCondition = api_get_session_condition($this->session_id, true, false, 's2.session_id').' ';
2727
        $categoryIdList = array_map('intval', $categoryIdList);
2728
        $categoriesJoin = '';
2729
2730
        if ($categoryIdList) {
2731
            if ($matchAllCategories) {
2732
                foreach ($categoryIdList as $categoryId) {
2733
                    $categoriesJoin .= "INNER JOIN c_wiki_rel_category AS wrc$categoryId
2734
                            ON (wp.iid = wrc$categoryId.wiki_id AND wrc$categoryId.category_id = $categoryId)
2735
                        INNER JOIN c_wiki_category AS wc$categoryId
2736
                            ON (wrc$categoryId.category_id = wc$categoryId.id) ";
2737
                }
2738
            } else {
2739
                $categoriesJoin = 'INNER JOIN c_wiki_rel_category AS wrc ON (wp.iid = wrc.wiki_id)
2740
                    INNER JOIN c_wiki_category AS wc ON (wrc.category_id = wc.id) ';
2741
            }
2742
        }
2743
2744
        $categoriesCondition = !$matchAllCategories
2745
            ? ($categoryIdList ? 'AND wc.id IN ('.implode(', ', $categoryIdList).')' : '')
2746
            : '';
2747
2748
        echo '<legend>'.get_lang('WikiSearchResults').': '.Security::remove_XSS($search_term).'</legend>';
2749
2750
        //only by professors when page is hidden
2751
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
2752
            if (1 === $all_vers) {
2753
                $sql = "SELECT * FROM $tbl_wiki AS wp $categoriesJoin
2754
                    WHERE wp.c_id = ".$this->course_id."
2755
                        AND (wp.title LIKE '%".Database::escape_string($search_term)."%' ";
2756
2757
                if (1 === $search_content) {
2758
                    $sql .= "OR wp.content LIKE '%".Database::escape_string($search_term)."%' ";
2759
                }
2760
2761
                $sql .= ") AND ".$groupfilter.$sessionCondition.$categoriesCondition;
2762
            } else {
2763
                // warning don't use group by reflink because don't return the last version
2764
                $sql = "SELECT * FROM $tbl_wiki AS wp
2765
                    WHERE wp.c_id = ".$this->course_id."
2766
                        AND (wp.title LIKE '%".Database::escape_string($search_term)."%' ";
2767
2768
                if (1 === $search_content) {
2769
                    // warning don't use group by reflink because don't return the last version
2770
                    $sql .= "OR wp.content LIKE '%".Database::escape_string($search_term)."%' ";
2771
                }
2772
2773
                $sql .= ") AND wp.id IN (
2774
                    SELECT MAX(s2.id)
2775
                    FROM ".$tbl_wiki." s2 $categoriesJoin
2776
                    WHERE s2.c_id = ".$this->course_id."
2777
                        AND s2.reflink = wp.reflink
2778
                        AND ".$subGroupfilter.$subSessionCondition.$categoriesCondition."
2779
                )";
2780
            }
2781
        } else {
2782
            if (1 === $all_vers) {
2783
                $sql = "SELECT * FROM $tbl_wiki AS wp $categoriesJoin
2784
                    WHERE wp.c_id = ".$this->course_id."
2785
                        AND wp.visibility = 1
2786
                        AND (wp.title LIKE '%".Database::escape_string($search_term)."%' ";
2787
2788
                if (1 === $search_content) {
2789
                    //search all pages and all versions
2790
                    $sql .= "OR wp.content LIKE '%".Database::escape_string($search_term)."%' ";
2791
                }
2792
2793
                $sql .= ") AND ".$groupfilter.$sessionCondition.$categoriesCondition;
2794
            } else {
2795
                // warning don't use group by reflink because don't return the last version
2796
                $sql = "SELECT * FROM $tbl_wiki AS wp
2797
                    WHERE wp.c_id = ".$this->course_id."
2798
                        AND wp.visibility = 1
2799
                        AND (wp.title LIKE '%".Database::escape_string($search_term)."%' ";
2800
2801
                if (1 === $search_content) {
2802
                    $sql .= "OR wp.content LIKE '%".Database::escape_string($search_term)."%' ";
2803
                }
2804
2805
                $sql .= ") AND wp.id IN (
2806
                        SELECT MAX(s2.id) FROM $tbl_wiki s2 $categoriesJoin
2807
                        WHERE s2.c_id = ".$this->course_id."
2808
                            AND s2.reflink = wp.reflink
2809
                            AND ".$subGroupfilter.$subSessionCondition.$categoriesCondition."
2810
                    )";
2811
            }
2812
        }
2813
2814
        $result = Database::query($sql);
2815
2816
        //show table
2817
        $rows = [];
2818
        if (Database::num_rows($result) > 0) {
2819
            $iconEdit = Display::return_icon('edit.png', get_lang('EditPage'));
2820
            $iconDiscuss = Display::return_icon('discuss.png', get_lang('Discuss'));
2821
            $iconHistory = Display::return_icon('history.png', get_lang('History'));
2822
            $iconLinks = Display::return_icon('what_link_here.png', get_lang('LinksPages'));
2823
            $iconDelete = Display::return_icon('delete.png', get_lang('Delete'));
2824
2825
            while ($obj = Database::fetch_object($result)) {
2826
                //get author
2827
                $userinfo = api_get_user_info($obj->user_id);
2828
2829
                //get type assignment icon
2830
                $ShowAssignment = '';
2831
                if ($obj->assignment == 1) {
2832
                    $ShowAssignment = Display::return_icon('wiki_assignment.png', get_lang('AssignmentDesc'));
2833
                } elseif ($obj->assignment == 2) {
2834
                    $ShowAssignment = Display::return_icon('wiki_work.png', get_lang('AssignmentWork'));
2835
                } elseif ($obj->assignment == 0) {
2836
                    $ShowAssignment = Display::return_icon('px_transparent.gif');
2837
                }
2838
                $row = [];
2839
                $row[] = $ShowAssignment;
2840
2841
                $wikiLinkParams = [
2842
                    'action' => 'showpage',
2843
                    'title' => api_htmlentities($obj->reflink),
2844
                ];
2845
2846
                if (1 === $all_vers) {
2847
                    $wikiLinkParams['view'] = $obj->id;
2848
                }
2849
2850
                $row[] = Display::url(
2851
                    api_htmlentities($obj->title),
2852
                    $this->url.'&'.http_build_query($wikiLinkParams)
2853
                ).$this->returnCategoriesBlock($obj->iid, '<div><small>', '</small></div>');
2854
2855
                $row[] = ($obj->user_id != 0 && $userinfo !== false)
2856
                    ? UserManager::getUserProfileLink($userinfo)
2857
                    : get_lang('Anonymous').' ('.$obj->user_ip.')';
2858
                $row[] = api_convert_and_format_date($obj->dtime);
2859
2860
                if (1 === $all_vers) {
2861
                    $row[] = $obj->version;
2862
                } else {
2863
                    $showdelete = '';
2864
                    if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
2865
                        $showdelete = Display::url(
2866
                            $iconDelete,
2867
                            $this->url.'&'.http_build_query([
2868
                                'action' => 'delete',
2869
                                'title' => api_htmlentities($obj->reflink),
2870
                            ])
2871
                        );
2872
                    }
2873
2874
                    $row[] = Display::url(
2875
                            $iconEdit,
2876
                            $this->url.'&'.http_build_query([
2877
                                'action' => 'edit',
2878
                                'title' => api_htmlentities($obj->reflink),
2879
                            ])
2880
                        )
2881
                        .Display::url(
2882
                            $iconDiscuss,
2883
                            $this->url.'&'.http_build_query([
2884
                                'action' => 'discuss',
2885
                                'title' => api_htmlentities($obj->reflink),
2886
                            ])
2887
                        )
2888
                        .Display::url(
2889
                            $iconHistory,
2890
                            $this->url.'&'.http_build_query([
2891
                                'action' => 'history',
2892
                                'title' => api_htmlentities($obj->reflink),
2893
                            ])
2894
                        )
2895
                        .Display::url(
2896
                            $iconLinks,
2897
                            $this->url.'&'.http_build_query([
2898
                                'action' => 'links',
2899
                                'title' => api_htmlentities($obj->reflink),
2900
                            ])
2901
                        )
2902
                        .$showdelete;
2903
                }
2904
                $rows[] = $row;
2905
            }
2906
2907
            $table = new SortableTableFromArrayConfig(
2908
                $rows,
2909
                1,
2910
                10,
2911
                'SearchPages_table',
2912
                '',
2913
                '',
2914
                'ASC'
2915
            );
2916
            $table->set_additional_parameters(
2917
                [
2918
                    'cidReq' => $this->courseCode,
2919
                    'gidReq' => $this->group_id,
2920
                    'id_session' => $this->session_id,
2921
                    'action' => $_GET['action'],
2922
                    'mode_table' => 'yes2',
2923
                    'search_term' => $search_term,
2924
                    'search_content' => $search_content,
2925
                    'all_vers' => $all_vers,
2926
                    'categories' => $categoryIdList,
2927
                    'match_all_categories' => $matchAllCategories,
2928
                ]
2929
            );
2930
            $table->set_header(
2931
                0,
2932
                get_lang('Type'),
2933
                true,
2934
                ['style' => 'width:30px;']
2935
            );
2936
            $table->set_header(1, get_lang('Title'));
2937
            if (1 === $all_vers) {
2938
                $table->set_header(2, get_lang('Author'));
2939
                $table->set_header(3, get_lang('Date'));
2940
                $table->set_header(4, get_lang('Version'));
2941
            } else {
2942
                $table->set_header(
2943
                    2,
2944
                    get_lang('Author').' <small>'.get_lang('LastVersion').'</small>'
2945
                );
2946
                $table->set_header(
2947
                    3,
2948
                    get_lang('Date').' <small>'.get_lang('LastVersion').'</small>'
2949
                );
2950
                $table->set_header(
2951
                    4,
2952
                    get_lang('Actions'),
2953
                    false,
2954
                    ['style' => 'width:130px;']
2955
                );
2956
            }
2957
            $table->display();
2958
        } else {
2959
            echo get_lang('NoSearchResults');
2960
        }
2961
    }
2962
2963
    /**
2964
     * Get wiki information.
2965
     *
2966
     * @param   int|bool wiki id
2967
     *
2968
     * @return array wiki data
2969
     */
2970
    public function getWikiDataFromDb($id)
2971
    {
2972
        $tbl_wiki = $this->tbl_wiki;
2973
        if ($id === false) {
2974
            return [];
2975
        }
2976
        $id = intval($id);
2977
        $sql = 'SELECT * FROM '.$tbl_wiki.'
2978
                WHERE c_id = '.$this->course_id.' AND id = '.$id.' ';
2979
        $result = Database::query($sql);
2980
        $data = [];
2981
        while ($row = Database::fetch_array($result, 'ASSOC')) {
2982
            $data = $row;
2983
        }
2984
2985
        return $data;
2986
    }
2987
2988
    /**
2989
     * @param string $refLink
2990
     *
2991
     * @return array
2992
     */
2993
    public function getLastWikiData($refLink)
2994
    {
2995
        $tbl_wiki = $this->tbl_wiki;
2996
        $groupfilter = $this->groupfilter;
2997
        $condition_session = $this->condition_session;
2998
2999
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3000
                WHERE
3001
                    c_id = '.$this->course_id.' AND
3002
                    reflink="'.Database::escape_string($refLink).'" AND
3003
                    '.$groupfilter.$condition_session.'
3004
                ORDER BY id DESC';
3005
3006
        $result = Database::query($sql);
3007
3008
        return Database::fetch_array($result);
3009
    }
3010
3011
    /**
3012
     * Get wiki information.
3013
     *
3014
     * @param   string     wiki id
3015
     * @param int $courseId
3016
     *
3017
     * @return array wiki data
3018
     */
3019
    public function getPageByTitle($title, $courseId = null)
3020
    {
3021
        $tbl_wiki = $this->tbl_wiki;
3022
        if (empty($courseId)) {
3023
            $courseId = $this->course_id;
3024
        } else {
3025
            $courseId = intval($courseId);
3026
        }
3027
3028
        if (empty($title) || empty($courseId)) {
3029
            return [];
3030
        }
3031
3032
        $title = Database::escape_string($title);
3033
        $sql = "SELECT * FROM $tbl_wiki
3034
                WHERE c_id = $courseId AND reflink = '$title'";
3035
        $result = Database::query($sql);
3036
        $data = [];
3037
        if (Database::num_rows($result)) {
3038
            $data = Database::fetch_array($result, 'ASSOC');
3039
        }
3040
3041
        return $data;
3042
    }
3043
3044
    /**
3045
     * @param string $title
3046
     * @param int    $courseId
3047
     * @param string
3048
     * @param string
3049
     *
3050
     * @return bool
3051
     */
3052
    public function deletePage(
3053
        $title,
3054
        $courseId,
3055
        $groupfilter = null,
3056
        $condition_session = null
3057
    ) {
3058
        $tbl_wiki = $this->tbl_wiki;
3059
        $tbl_wiki_discuss = $this->tbl_wiki_discuss;
3060
        $tbl_wiki_mailcue = $this->tbl_wiki_mailcue;
3061
        $tbl_wiki_conf = $this->tbl_wiki_conf;
3062
3063
        $pageInfo = self::getPageByTitle($title, $courseId);
3064
        if (!empty($pageInfo)) {
3065
            $pageId = $pageInfo['id'];
3066
            $sql = "DELETE FROM $tbl_wiki_conf
3067
                    WHERE c_id = $courseId AND page_id = $pageId";
3068
            Database::query($sql);
3069
3070
            $sql = 'DELETE FROM '.$tbl_wiki_discuss.'
3071
                    WHERE c_id = '.$courseId.' AND publication_id = '.$pageId;
3072
            Database::query($sql);
3073
3074
            $sql = 'DELETE FROM  '.$tbl_wiki_mailcue.'
3075
                    WHERE c_id = '.$courseId.' AND id = '.$pageId.' AND '.$groupfilter.$condition_session.'';
3076
            Database::query($sql);
3077
3078
            $sql = 'DELETE FROM '.$tbl_wiki.'
3079
                    WHERE c_id = '.$courseId.' AND id = '.$pageId.' AND '.$groupfilter.$condition_session.'';
3080
            Database::query($sql);
3081
            self::check_emailcue(0, 'E');
3082
3083
            return true;
3084
        }
3085
3086
        return false;
3087
    }
3088
3089
    /**
3090
     * @return array
3091
     */
3092
    public function getAllWiki()
3093
    {
3094
        $tbl_wiki = $this->tbl_wiki;
3095
        $condition_session = $this->condition_session;
3096
3097
        $sql = "SELECT * FROM $tbl_wiki
3098
                WHERE
3099
                    c_id = ".$this->course_id." AND
3100
                    is_editing != '0' ".$condition_session;
3101
        $result = Database::query($sql);
3102
3103
        return Database::store_result($result, 'ASSOC');
3104
    }
3105
3106
    /**
3107
     * @param int $isEditing
3108
     */
3109
    public function updateWikiIsEditing($isEditing)
3110
    {
3111
        $tbl_wiki = $this->tbl_wiki;
3112
        $condition_session = $this->condition_session;
3113
        $isEditing = Database::escape_string($isEditing);
3114
3115
        $sql = 'UPDATE '.$tbl_wiki.' SET
3116
                is_editing = "0",
3117
                time_edit = NULL
3118
                WHERE
3119
                    c_id = '.$this->course_id.' AND
3120
                    is_editing="'.$isEditing.'" '.
3121
            $condition_session;
3122
        Database::query($sql);
3123
    }
3124
3125
    /**
3126
     * Release of blocked pages to prevent concurrent editions.
3127
     *
3128
     * @param int    $userId
3129
     * @param string $action
3130
     */
3131
    public function blockConcurrentEditions($userId, $action = null)
3132
    {
3133
        $result = self::getAllWiki();
3134
        if (!empty($result)) {
3135
            foreach ($result as $is_editing_block) {
3136
                $max_edit_time = 1200; // 20 minutes
3137
                $timestamp_edit = strtotime($is_editing_block['time_edit']);
3138
                $time_editing = time() - $timestamp_edit;
3139
3140
                // First prevent concurrent users and double version
3141
                if ($is_editing_block['is_editing'] == $userId) {
3142
                    Session::write('_version', $is_editing_block['version']);
3143
                } else {
3144
                    Session::erase('_version');
3145
                }
3146
                // Second checks if has exceeded the time that a page may
3147
                // be available or if a page was edited and saved by its author
3148
                if ($time_editing > $max_edit_time ||
3149
                    ($is_editing_block['is_editing'] == $userId &&
3150
                        $action != 'edit')
3151
                ) {
3152
                    self::updateWikiIsEditing($is_editing_block['is_editing']);
3153
                }
3154
            }
3155
        }
3156
    }
3157
3158
    /**
3159
     * Showing wiki stats.
3160
     */
3161
    public function getStats()
3162
    {
3163
        if (!api_is_allowed_to_edit(false, true)) {
3164
            return false;
3165
        }
3166
3167
        $tbl_wiki = $this->tbl_wiki;
3168
        $condition_session = $this->condition_session;
3169
        $groupfilter = $this->groupfilter;
3170
        $tbl_wiki_conf = $this->tbl_wiki_conf;
3171
3172
        echo '<div class="actions">'.get_lang('Statistics').'</div>';
3173
3174
        // Check all versions of all pages
3175
        $total_words = 0;
3176
        $total_links = 0;
3177
        $total_links_anchors = 0;
3178
        $total_links_mail = 0;
3179
        $total_links_ftp = 0;
3180
        $total_links_irc = 0;
3181
        $total_links_news = 0;
3182
        $total_wlinks = 0;
3183
        $total_images = 0;
3184
        $clean_total_flash = 0;
3185
        $total_flash = 0;
3186
        $total_mp3 = 0;
3187
        $total_flv_p = 0;
3188
        $total_flv = 0;
3189
        $total_youtube = 0;
3190
        $total_multimedia = 0;
3191
        $total_tables = 0;
3192
3193
        $sql = "SELECT *, COUNT(*) AS TOTAL_VERS, SUM(hits) AS TOTAL_VISITS
3194
                FROM ".$tbl_wiki."
3195
                WHERE c_id = ".$this->course_id." AND ".$groupfilter.$condition_session;
3196
3197
        $allpages = Database::query($sql);
3198
        while ($row = Database::fetch_array($allpages)) {
3199
            $total_versions = $row['TOTAL_VERS'];
3200
            $total_visits = intval($row['TOTAL_VISITS']);
3201
        }
3202
3203
        $sql = "SELECT * FROM ".$tbl_wiki."
3204
                WHERE c_id = ".$this->course_id." AND ".$groupfilter.$condition_session."";
3205
        $allpages = Database::query($sql);
3206
3207
        while ($row = Database::fetch_array($allpages)) {
3208
            $total_words = $total_words + self::word_count($row['content']);
3209
            $total_links = $total_links + substr_count(
3210
                $row['content'],
3211
                "href="
3212
            );
3213
            $total_links_anchors = $total_links_anchors + substr_count(
3214
                $row['content'],
3215
                'href="#'
3216
            );
3217
            $total_links_mail = $total_links_mail + substr_count(
3218
                $row['content'],
3219
                'href="mailto'
3220
            );
3221
            $total_links_ftp = $total_links_ftp + substr_count(
3222
                $row['content'],
3223
                'href="ftp'
3224
            );
3225
            $total_links_irc = $total_links_irc + substr_count(
3226
                $row['content'],
3227
                'href="irc'
3228
            );
3229
            $total_links_news = $total_links_news + substr_count(
3230
                $row['content'],
3231
                'href="news'
3232
            );
3233
            $total_wlinks = $total_wlinks + substr_count($row['content'], "[[");
3234
            $total_images = $total_images + substr_count(
3235
                $row['content'],
3236
                "<img"
3237
            );
3238
            $clean_total_flash = preg_replace(
3239
                '/player.swf/',
3240
                ' ',
3241
                $row['content']
3242
            );
3243
            $total_flash = $total_flash + substr_count(
3244
                $clean_total_flash,
3245
                '.swf"'
3246
            );
3247
            //.swf" end quotes prevent insert swf through flvplayer (is not counted)
3248
            $total_mp3 = $total_mp3 + substr_count($row['content'], ".mp3");
3249
            $total_flv_p = $total_flv_p + substr_count($row['content'], ".flv");
3250
            $total_flv = $total_flv_p / 5;
3251
            $total_youtube = $total_youtube + substr_count(
3252
                $row['content'],
3253
                "http://www.youtube.com"
3254
            );
3255
            $total_multimedia = $total_multimedia + substr_count(
3256
                $row['content'],
3257
                "video/x-msvideo"
3258
            );
3259
            $total_tables = $total_tables + substr_count(
3260
                $row['content'],
3261
                "<table"
3262
            );
3263
        }
3264
3265
        // Check only last version of all pages (current page)
3266
        $sql = ' SELECT *, COUNT(*) AS TOTAL_PAGES, SUM(hits) AS TOTAL_VISITS_LV
3267
                FROM  '.$tbl_wiki.' s1
3268
                WHERE s1.c_id = '.$this->course_id.' AND id=(
3269
                    SELECT MAX(s2.id)
3270
                    FROM '.$tbl_wiki.' s2
3271
                    WHERE
3272
                        s2.c_id = '.$this->course_id.' AND
3273
                        s1.reflink = s2.reflink AND
3274
                        '.$groupfilter.' AND
3275
                        session_id='.$this->session_id.')';
3276
        $allpages = Database::query($sql);
3277
        while ($row = Database::fetch_array($allpages)) {
3278
            $total_pages = $row['TOTAL_PAGES'];
3279
            $total_visits_lv = intval($row['TOTAL_VISITS_LV']);
3280
        }
3281
3282
        $total_words_lv = 0;
3283
        $total_links_lv = 0;
3284
        $total_links_anchors_lv = 0;
3285
        $total_links_mail_lv = 0;
3286
        $total_links_ftp_lv = 0;
3287
        $total_links_irc_lv = 0;
3288
        $total_links_news_lv = 0;
3289
        $total_wlinks_lv = 0;
3290
        $total_images_lv = 0;
3291
        $clean_total_flash_lv = 0;
3292
        $total_flash_lv = 0;
3293
        $total_mp3_lv = 0;
3294
        $total_flv_p_lv = 0;
3295
        $total_flv_lv = 0;
3296
        $total_youtube_lv = 0;
3297
        $total_multimedia_lv = 0;
3298
        $total_tables_lv = 0;
3299
3300
        $sql = 'SELECT * FROM  '.$tbl_wiki.' s1
3301
                WHERE s1.c_id = '.$this->course_id.' AND id=(
3302
                    SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
3303
                    WHERE
3304
                        s2.c_id = '.$this->course_id.' AND
3305
                        s1.reflink = s2.reflink AND
3306
                        '.$groupfilter.' AND
3307
                        session_id='.$this->session_id.'
3308
                )';
3309
        $allpages = Database::query($sql);
3310
3311
        while ($row = Database::fetch_array($allpages)) {
3312
            $total_words_lv = $total_words_lv + self::word_count(
3313
                $row['content']
3314
            );
3315
            $total_links_lv = $total_links_lv + substr_count(
3316
                $row['content'],
3317
                "href="
3318
            );
3319
            $total_links_anchors_lv = $total_links_anchors_lv + substr_count(
3320
                $row['content'],
3321
                'href="#'
3322
            );
3323
            $total_links_mail_lv = $total_links_mail_lv + substr_count(
3324
                $row['content'],
3325
                'href="mailto'
3326
            );
3327
            $total_links_ftp_lv = $total_links_ftp_lv + substr_count(
3328
                $row['content'],
3329
                'href="ftp'
3330
            );
3331
            $total_links_irc_lv = $total_links_irc_lv + substr_count(
3332
                $row['content'],
3333
                'href="irc'
3334
            );
3335
            $total_links_news_lv = $total_links_news_lv + substr_count(
3336
                $row['content'],
3337
                'href="news'
3338
            );
3339
            $total_wlinks_lv = $total_wlinks_lv + substr_count(
3340
                $row['content'],
3341
                "[["
3342
            );
3343
            $total_images_lv = $total_images_lv + substr_count(
3344
                $row['content'],
3345
                "<img"
3346
            );
3347
            $clean_total_flash_lv = preg_replace(
3348
                '/player.swf/',
3349
                ' ',
3350
                $row['content']
3351
            );
3352
            $total_flash_lv = $total_flash_lv + substr_count(
3353
                $clean_total_flash_lv,
3354
                '.swf"'
3355
            );
3356
            //.swf" end quotes prevent insert swf through flvplayer (is not counted)
3357
            $total_mp3_lv = $total_mp3_lv + substr_count(
3358
                $row['content'],
3359
                ".mp3"
3360
            );
3361
            $total_flv_p_lv = $total_flv_p_lv + substr_count(
3362
                $row['content'],
3363
                ".flv"
3364
            );
3365
            $total_flv_lv = $total_flv_p_lv / 5;
3366
            $total_youtube_lv = $total_youtube_lv + substr_count(
3367
                $row['content'],
3368
                "http://www.youtube.com"
3369
            );
3370
            $total_multimedia_lv = $total_multimedia_lv + substr_count(
3371
                $row['content'],
3372
                "video/x-msvideo"
3373
            );
3374
            $total_tables_lv = $total_tables_lv + substr_count(
3375
                $row['content'],
3376
                "<table"
3377
            );
3378
        }
3379
3380
        //Total pages edited at this time
3381
        $total_editing_now = 0;
3382
        $sql = 'SELECT *, COUNT(*) AS TOTAL_EDITING_NOW
3383
                FROM  '.$tbl_wiki.' s1
3384
                WHERE is_editing!=0 AND s1.c_id = '.$this->course_id.' AND
3385
                id=(
3386
                    SELECT MAX(s2.id)
3387
                    FROM '.$tbl_wiki.' s2
3388
                    WHERE
3389
                        s2.c_id = '.$this->course_id.' AND
3390
                        s1.reflink = s2.reflink AND
3391
                        '.$groupfilter.' AND
3392
                        session_id='.$this->session_id.'
3393
        )';
3394
3395
        // Can not use group by because the mark is set in the latest version
3396
        $allpages = Database::query($sql);
3397
        while ($row = Database::fetch_array($allpages)) {
3398
            $total_editing_now = $row['TOTAL_EDITING_NOW'];
3399
        }
3400
3401
        // Total hidden pages
3402
        $total_hidden = 0;
3403
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3404
                WHERE
3405
                    c_id = '.$this->course_id.' AND
3406
                    visibility = 0 AND
3407
                    '.$groupfilter.$condition_session.'
3408
                GROUP BY reflink';
3409
        // or group by page_id. As the mark of hidden places it in all
3410
        // versions of the page, I can use group by to see the first
3411
        $allpages = Database::query($sql);
3412
        while ($row = Database::fetch_array($allpages)) {
3413
            $total_hidden = $total_hidden + 1;
3414
        }
3415
3416
        //Total protect pages
3417
        $total_protected = 0;
3418
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3419
                WHERE
3420
                    c_id = '.$this->course_id.' AND
3421
                    editlock = 1 AND
3422
                     '.$groupfilter.$condition_session.'
3423
                GROUP BY reflink';
3424
        // or group by page_id. As the mark of protected page is the
3425
        // first version of the page, I can use group by
3426
        $allpages = Database::query($sql);
3427
        while ($row = Database::fetch_array($allpages)) {
3428
            $total_protected = $total_protected + 1;
3429
        }
3430
3431
        // Total empty versions.
3432
        $total_empty_content = 0;
3433
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3434
                WHERE
3435
                    c_id = '.$this->course_id.' AND
3436
                    content="" AND
3437
                    '.$groupfilter.$condition_session.'';
3438
        $allpages = Database::query($sql);
3439
        while ($row = Database::fetch_array($allpages)) {
3440
            $total_empty_content = $total_empty_content + 1;
3441
        }
3442
3443
        //Total empty pages (last version)
3444
3445
        $total_empty_content_lv = 0;
3446
        $sql = 'SELECT  * FROM  '.$tbl_wiki.' s1
3447
                WHERE s1.c_id = '.$this->course_id.' AND content="" AND id=(
3448
                    SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
3449
                    WHERE
3450
                        s1.c_id = '.$this->course_id.' AND
3451
                        s1.reflink = s2.reflink AND
3452
                        '.$groupfilter.' AND
3453
                        session_id='.$this->session_id.'
3454
                )';
3455
        $allpages = Database::query($sql);
3456
        while ($row = Database::fetch_array($allpages)) {
3457
            $total_empty_content_lv = $total_empty_content_lv + 1;
3458
        }
3459
3460
        // Total locked discuss pages
3461
        $total_lock_disc = 0;
3462
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3463
                WHERE c_id = '.$this->course_id.' AND addlock_disc=0 AND '.$groupfilter.$condition_session.'
3464
                GROUP BY reflink'; //group by because mark lock in all vers, then always is ok
3465
        $allpages = Database::query($sql);
3466
        while ($row = Database::fetch_array($allpages)) {
3467
            $total_lock_disc = $total_lock_disc + 1;
3468
        }
3469
3470
        // Total hidden discuss pages.
3471
        $total_hidden_disc = 0;
3472
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3473
                WHERE c_id = '.$this->course_id.' AND visibility_disc=0 AND '.$groupfilter.$condition_session.'
3474
                GROUP BY reflink';
3475
        //group by because mark lock in all vers, then always is ok
3476
        $allpages = Database::query($sql);
3477
        while ($row = Database::fetch_array($allpages)) {
3478
            $total_hidden_disc = $total_hidden_disc + 1;
3479
        }
3480
3481
        // Total versions with any short comment by user or system
3482
        $total_comment_version = 0;
3483
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3484
                WHERE c_id = '.$this->course_id.' AND comment!="" AND '.$groupfilter.$condition_session.'';
3485
        $allpages = Database::query($sql);
3486
        while ($row = Database::fetch_array($allpages)) {
3487
            $total_comment_version = $total_comment_version + 1;
3488
        }
3489
3490
        // Total pages that can only be scored by teachers.
3491
        $total_only_teachers_rating = 0;
3492
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3493
                WHERE c_id = '.$this->course_id.' AND
3494
                ratinglock_disc = 0 AND
3495
                '.$groupfilter.$condition_session.'
3496
                GROUP BY reflink'; //group by because mark lock in all vers, then always is ok
3497
        $allpages = Database::query($sql);
3498
        while ($row = Database::fetch_array($allpages)) {
3499
            $total_only_teachers_rating = $total_only_teachers_rating + 1;
3500
        }
3501
3502
        // Total pages scored by peers
3503
        // put always this line alfter check num all pages and num pages rated by teachers
3504
        $total_rating_by_peers = $total_pages - $total_only_teachers_rating;
3505
3506
        //Total pages identified as standard task
3507
        $total_task = 0;
3508
        $sql = 'SELECT * FROM '.$tbl_wiki.', '.$tbl_wiki_conf.'
3509
              WHERE '.$tbl_wiki_conf.'.c_id = '.$this->course_id.' AND
3510
               '.$tbl_wiki_conf.'.task!="" AND
3511
               '.$tbl_wiki_conf.'.page_id='.$tbl_wiki.'.page_id AND
3512
                '.$tbl_wiki.'.'.$groupfilter.$condition_session;
3513
        $allpages = Database::query($sql);
3514
        while ($row = Database::fetch_array($allpages)) {
3515
            $total_task = $total_task + 1;
3516
        }
3517
3518
        //Total pages identified as teacher page (wiki portfolio mode - individual assignment)
3519
        $total_teacher_assignment = 0;
3520
        $sql = 'SELECT  * FROM  '.$tbl_wiki.' s1
3521
                WHERE s1.c_id = '.$this->course_id.' AND assignment=1 AND id=(
3522
                    SELECT MAX(s2.id)
3523
                    FROM '.$tbl_wiki.' s2
3524
                    WHERE
3525
                        s2.c_id = '.$this->course_id.' AND
3526
                        s1.reflink = s2.reflink AND
3527
                        '.$groupfilter.' AND
3528
                         session_id='.$this->session_id.'
3529
                )';
3530
        //mark all versions, but do not use group by reflink because y want the pages not versions
3531
        $allpages = Database::query($sql);
3532
        while ($row = Database::fetch_array($allpages)) {
3533
            $total_teacher_assignment = $total_teacher_assignment + 1;
3534
        }
3535
3536
        //Total pages identifies as student page (wiki portfolio mode - individual assignment)
3537
        $total_student_assignment = 0;
3538
        $sql = 'SELECT  * FROM  '.$tbl_wiki.' s1
3539
                WHERE s1.c_id = '.$this->course_id.' AND assignment=2 AND
3540
                id = (SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
3541
                WHERE
3542
                    s2.c_id = '.$this->course_id.' AND
3543
                    s1.reflink = s2.reflink AND
3544
                    '.$groupfilter.' AND
3545
                    session_id='.$this->session_id.'
3546
                )';
3547
        //mark all versions, but do not use group by reflink because y want the pages not versions
3548
        $allpages = Database::query($sql);
3549
        while ($row = Database::fetch_array($allpages)) {
3550
            $total_student_assignment = $total_student_assignment + 1;
3551
        }
3552
3553
        //Current Wiki status add new pages
3554
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3555
                WHERE c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.'
3556
                GROUP BY addlock'; //group by because mark 0 in all vers, then always is ok
3557
        $allpages = Database::query($sql);
3558
        $wiki_add_lock = null;
3559
        while ($row = Database::fetch_array($allpages)) {
3560
            $wiki_add_lock = $row['addlock'];
3561
        }
3562
3563
        if ($wiki_add_lock == 1) {
3564
            $status_add_new_pag = get_lang('Yes');
3565
        } else {
3566
            $status_add_new_pag = get_lang('No');
3567
        }
3568
3569
        // Creation date of the oldest wiki page and version
3570
        $first_wiki_date = null;
3571
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3572
                WHERE c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.'
3573
                ORDER BY dtime ASC
3574
                LIMIT 1';
3575
        $allpages = Database::query($sql);
3576
        while ($row = Database::fetch_array($allpages)) {
3577
            $first_wiki_date = api_get_local_time($row['dtime']);
3578
        }
3579
3580
        // Date of publication of the latest wiki version.
3581
3582
        $last_wiki_date = null;
3583
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3584
                WHERE c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.'
3585
                ORDER BY dtime DESC
3586
                LIMIT 1';
3587
        $allpages = Database::query($sql);
3588
        while ($row = Database::fetch_array($allpages)) {
3589
            $last_wiki_date = api_get_local_time($row['dtime']);
3590
        }
3591
3592
        // Average score of all wiki pages. (If a page has not scored zero rated)
3593
        $media_score = 0;
3594
        $sql = "SELECT *, SUM(score) AS TOTAL_SCORE FROM ".$tbl_wiki."
3595
                WHERE c_id = ".$this->course_id." AND ".$groupfilter.$condition_session."
3596
                GROUP BY reflink ";
3597
        //group by because mark in all versions, then always is ok.
3598
        // Do not use "count" because using "group by", would give a wrong value
3599
        $allpages = Database::query($sql);
3600
        $total_score = 0;
3601
        while ($row = Database::fetch_array($allpages)) {
3602
            $total_score = $total_score + $row['TOTAL_SCORE'];
3603
        }
3604
3605
        if (!empty($total_pages)) {
3606
            $media_score = $total_score / $total_pages;
3607
            //put always this line alfter check num all pages
3608
        }
3609
3610
        // Average user progress in his pages.
3611
        $media_progress = 0;
3612
        $sql = 'SELECT  *, SUM(progress) AS TOTAL_PROGRESS
3613
                FROM  '.$tbl_wiki.' s1
3614
                WHERE s1.c_id = '.$this->course_id.' AND id=
3615
                (
3616
                    SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
3617
                    WHERE
3618
                        s2.c_id = '.$this->course_id.' AND
3619
                        s1.reflink = s2.reflink AND
3620
                        '.$groupfilter.' AND
3621
                        session_id='.$this->session_id.'
3622
                )';
3623
        // As the value is only the latest version I can not use group by
3624
        $allpages = Database::query($sql);
3625
        while ($row = Database::fetch_array($allpages)) {
3626
            $total_progress = $row['TOTAL_PROGRESS'];
3627
        }
3628
3629
        if (!empty($total_pages)) {
3630
            $media_progress = $total_progress / $total_pages;
3631
            //put always this line alfter check num all pages
3632
        }
3633
3634
        // Total users that have participated in the Wiki
3635
        $total_users = 0;
3636
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3637
                WHERE  c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.'
3638
                GROUP BY user_id';
3639
        //as the mark of user it in all versions of the page, I can use group by to see the first
3640
        $allpages = Database::query($sql);
3641
        while ($row = Database::fetch_array($allpages)) {
3642
            $total_users = $total_users + 1;
3643
        }
3644
3645
        // Total of different IP addresses that have participated in the wiki
3646
        $total_ip = 0;
3647
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3648
              WHERE c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.'
3649
              GROUP BY user_ip';
3650
        $allpages = Database::query($sql);
3651
        while ($row = Database::fetch_array($allpages)) {
3652
            $total_ip = $total_ip + 1;
3653
        }
3654
3655
        echo '<table class="table table-hover table-striped data_table">';
3656
        echo '<thead>';
3657
        echo '<tr>';
3658
        echo '<th colspan="2">'.get_lang('General').'</th>';
3659
        echo '</tr>';
3660
        echo '</thead>';
3661
        echo '<tr>';
3662
        echo '<td>'.get_lang('StudentAddNewPages').'</td>';
3663
        echo '<td>'.$status_add_new_pag.'</td>';
3664
        echo '</tr>';
3665
        echo '<tr>';
3666
        echo '<td>'.get_lang('DateCreateOldestWikiPage').'</td>';
3667
        echo '<td>'.$first_wiki_date.'</td>';
3668
        echo '</tr>';
3669
        echo '<tr>';
3670
        echo '<td>'.get_lang('DateEditLatestWikiVersion').'</td>';
3671
        echo '<td>'.$last_wiki_date.'</td>';
3672
        echo '</tr>';
3673
        echo '<tr>';
3674
        echo '<td>'.get_lang('AverageScoreAllPages').'</td>';
3675
        echo '<td>'.$media_score.' %</td>';
3676
        echo '</tr>';
3677
        echo '<tr>';
3678
        echo '<td>'.get_lang('AverageMediaUserProgress').'</td>';
3679
        echo '<td>'.$media_progress.' %</td>';
3680
        echo '</tr>';
3681
        echo '<tr>';
3682
        echo '<td>'.get_lang('TotalWikiUsers').'</td>';
3683
        echo '<td>'.$total_users.'</td>';
3684
        echo '</tr>';
3685
        echo '<tr>';
3686
        echo '<td>'.get_lang('TotalIpAdress').'</td>';
3687
        echo '<td>'.$total_ip.'</td>';
3688
        echo '</tr>';
3689
        echo '</table>';
3690
        echo '<br/>';
3691
3692
        echo '<table class="table table-hover table-striped data_table">';
3693
        echo '<thead>';
3694
        echo '<tr>';
3695
        echo '<th colspan="2">'.get_lang('Pages').' '.get_lang(
3696
                'And'
3697
            ).' '.get_lang('Versions').'</th>';
3698
        echo '</tr>';
3699
        echo '</thead>';
3700
        echo '<tr>';
3701
        echo '<td>'.get_lang('Pages').' - '.get_lang(
3702
                'NumContributions'
3703
            ).'</td>';
3704
        echo '<td>'.$total_pages.' ('.get_lang(
3705
                'Versions'
3706
            ).': '.$total_versions.')</td>';
3707
        echo '</tr>';
3708
        echo '<tr>';
3709
        echo '<td>'.get_lang('EmptyPages').'</td>';
3710
        echo '<td>'.$total_empty_content_lv.' ('.get_lang(
3711
                'Versions'
3712
            ).': '.$total_empty_content.')</td>';
3713
        echo '</tr>';
3714
        echo '<tr>';
3715
        echo '<td>'.get_lang('NumAccess').'</td>';
3716
        echo '<td>'.$total_visits_lv.' ('.get_lang(
3717
                'Versions'
3718
            ).': '.$total_visits.')</td>';
3719
        echo '</tr>';
3720
        echo '<tr>';
3721
        echo '<td>'.get_lang('TotalPagesEditedAtThisTime').'</td>';
3722
        echo '<td>'.$total_editing_now.'</td>';
3723
        echo '</tr>';
3724
        echo '<tr>';
3725
        echo '<td>'.get_lang('TotalHiddenPages').'</td>';
3726
        echo '<td>'.$total_hidden.'</td>';
3727
        echo '</tr>';
3728
        echo '<tr>';
3729
        echo '<td>'.get_lang('NumProtectedPages').'</td>';
3730
        echo '<td>'.$total_protected.'</td>';
3731
        echo '</tr>';
3732
        echo '<tr>';
3733
        echo '<td>'.get_lang('LockedDiscussPages').'</td>';
3734
        echo '<td>'.$total_lock_disc.'</td>';
3735
        echo '</tr>';
3736
        echo '<tr>';
3737
        echo '<td>'.get_lang('HiddenDiscussPages').'</td>';
3738
        echo '<td>'.$total_hidden_disc.'</td>';
3739
        echo '</tr>';
3740
        echo '<tr>';
3741
        echo '<td>'.get_lang('TotalComments').'</td>';
3742
        echo '<td>'.$total_comment_version.'</td>';
3743
        echo '</tr>';
3744
        echo '<tr>';
3745
        echo '<td>'.get_lang('TotalOnlyRatingByTeacher').'</td>';
3746
        echo '<td>'.$total_only_teachers_rating.'</td>';
3747
        echo '</tr>';
3748
        echo '<tr>';
3749
        echo '<td>'.get_lang('TotalRatingPeers').'</td>';
3750
        echo '<td>'.$total_rating_by_peers.'</td>';
3751
        echo '</tr>';
3752
        echo '<tr>';
3753
        echo '<td>'.get_lang('TotalTeacherAssignments').' - '.get_lang(
3754
                'PortfolioMode'
3755
            ).'</td>';
3756
        echo '<td>'.$total_teacher_assignment.'</td>';
3757
        echo '</tr>';
3758
        echo '<tr>';
3759
        echo '<td>'.get_lang('TotalStudentAssignments').' - '.get_lang(
3760
                'PortfolioMode'
3761
            ).'</td>';
3762
        echo '<td>'.$total_student_assignment.'</td>';
3763
        echo '</tr>';
3764
        echo '<tr>';
3765
        echo '<td>'.get_lang('TotalTask').' - '.get_lang(
3766
                'StandardMode'
3767
            ).'</td>';
3768
        echo '<td>'.$total_task.'</td>';
3769
        echo '</tr>';
3770
        echo '</table>';
3771
        echo '<br/>';
3772
3773
        echo '<table class="table table-hover table-striped data_table">';
3774
        echo '<thead>';
3775
        echo '<tr>';
3776
        echo '<th colspan="3">'.get_lang('ContentPagesInfo').'</th>';
3777
        echo '</tr>';
3778
        echo '<tr>';
3779
        echo '<td></td>';
3780
        echo '<td>'.get_lang('InTheLastVersion').'</td>';
3781
        echo '<td>'.get_lang('InAllVersions').'</td>';
3782
        echo '</tr>';
3783
        echo '</thead>';
3784
        echo '<tr>';
3785
        echo '<td>'.get_lang('NumWords').'</td>';
3786
        echo '<td>'.$total_words_lv.'</td>';
3787
        echo '<td>'.$total_words.'</td>';
3788
        echo '</tr>';
3789
        echo '<tr>';
3790
        echo '<td>'.get_lang('NumlinksHtmlImagMedia').'</td>';
3791
        echo '<td>'.$total_links_lv.' ('.get_lang(
3792
                'Anchors'
3793
            ).':'.$total_links_anchors_lv.', Mail:'.$total_links_mail_lv.', FTP:'.$total_links_ftp_lv.' IRC:'.$total_links_irc_lv.', News:'.$total_links_news_lv.', ... ) </td>';
3794
        echo '<td>'.$total_links.' ('.get_lang(
3795
                'Anchors'
3796
            ).':'.$total_links_anchors.', Mail:'.$total_links_mail.', FTP:'.$total_links_ftp.', IRC:'.$total_links_irc.', News:'.$total_links_news.', ... ) </td>';
3797
        echo '</tr>';
3798
        echo '<tr>';
3799
        echo '<td>'.get_lang('NumWikilinks').'</td>';
3800
        echo '<td>'.$total_wlinks_lv.'</td>';
3801
        echo '<td>'.$total_wlinks.'</td>';
3802
        echo '</tr>';
3803
        echo '<tr>';
3804
        echo '<td>'.get_lang('NumImages').'</td>';
3805
        echo '<td>'.$total_images_lv.'</td>';
3806
        echo '<td>'.$total_images.'</td>';
3807
        echo '</tr>';
3808
        echo '<tr>';
3809
        echo '<td>'.get_lang('NumFlash').'</td>';
3810
        echo '<td>'.$total_flash_lv.'</td>';
3811
        echo '<td>'.$total_flash.'</td>';
3812
        echo '</tr>';
3813
        echo '<tr>';
3814
        echo '<td>'.get_lang('NumMp3').'</td>';
3815
        echo '<td>'.$total_mp3_lv.'</td>';
3816
        echo '<td>'.$total_mp3.'</td>';
3817
        echo '</tr>';
3818
        echo '<tr>';
3819
        echo '<td>'.get_lang('NumFlvVideo').'</td>';
3820
        echo '<td>'.$total_flv_lv.'</td>';
3821
        echo '<td>'.$total_flv.'</td>';
3822
        echo '</tr>';
3823
        echo '<tr>';
3824
        echo '<td>'.get_lang('NumYoutubeVideo').'</td>';
3825
        echo '<td>'.$total_youtube_lv.'</td>';
3826
        echo '<td>'.$total_youtube.'</td>';
3827
        echo '</tr>';
3828
        echo '<tr>';
3829
        echo '<td>'.get_lang('NumOtherAudioVideo').'</td>';
3830
        echo '<td>'.$total_multimedia_lv.'</td>';
3831
        echo '<td>'.$total_multimedia.'</td>';
3832
        echo '</tr>';
3833
        echo '<tr>';
3834
        echo '<td>'.get_lang('NumTables').'</td>';
3835
        echo '<td>'.$total_tables_lv.'</td>';
3836
        echo '<td>'.$total_tables.'</td>';
3837
        echo '</tr>';
3838
        echo '</table>';
3839
    }
3840
3841
    /**
3842
     * @param string $action
3843
     */
3844
    public function getActiveUsers($action)
3845
    {
3846
        $tbl_wiki = $this->tbl_wiki;
3847
        $condition_session = $this->condition_session;
3848
        $groupfilter = $this->groupfilter;
3849
3850
        echo '<div class="actions">'.get_lang('MostActiveUsers').'</div>';
3851
        $sql = 'SELECT *, COUNT(*) AS NUM_EDIT FROM '.$tbl_wiki.'
3852
                WHERE  c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.'
3853
                GROUP BY user_id';
3854
        $allpages = Database::query($sql);
3855
3856
        //show table
3857
        if (Database::num_rows($allpages) > 0) {
3858
            while ($obj = Database::fetch_object($allpages)) {
3859
                $userinfo = api_get_user_info($obj->user_id);
3860
                $row = [];
3861
                if ($obj->user_id != 0 && $userinfo !== false) {
3862
                    $row[] = Display::url(
3863
                        $userinfo['complete_name_with_username'],
3864
                        $this->url.'&'.http_build_query(['action' => 'usercontrib', 'user_id' => (int) $obj->user_id])
3865
                    );
3866
                } else {
3867
                    $row[] = get_lang('Anonymous').' ('.$obj->user_ip.')';
3868
                }
3869
                $row[] = Display::url(
3870
                    $obj->NUM_EDIT,
3871
                    $this->url.'&'.http_build_query(['action' => 'usercontrib', 'user_id' => (int) $obj->user_id])
3872
                );
3873
                $rows[] = $row;
3874
            }
3875
3876
            $table = new SortableTableFromArrayConfig(
3877
                $rows,
3878
                1,
3879
                10,
3880
                'MostActiveUsersA_table',
3881
                '',
3882
                '',
3883
                'DESC'
3884
            );
3885
            $table->set_additional_parameters(
3886
                [
3887
                    'cidReq' => $this->courseCode,
3888
                    'gidReq' => $this->group_id,
3889
                    'id_session' => $this->session_id,
3890
                    'action' => Security::remove_XSS($action),
3891
                ]
3892
            );
3893
            $table->set_header(0, get_lang('Author'), true);
3894
            $table->set_header(
3895
                1,
3896
                get_lang('Contributions'),
3897
                true,
3898
                ['style' => 'width:30px;']
3899
            );
3900
            $table->display();
3901
        }
3902
    }
3903
3904
    /**
3905
     * @param string $page
3906
     */
3907
    public function getDiscuss($page)
3908
    {
3909
        $tbl_wiki = $this->tbl_wiki;
3910
        $condition_session = $this->condition_session;
3911
        $groupfilter = $this->groupfilter;
3912
        $tbl_wiki_discuss = $this->tbl_wiki_discuss;
3913
3914
        if (0 != $this->session_id &&
3915
            api_is_allowed_to_session_edit(false, true) == false
3916
        ) {
3917
            api_not_allowed();
3918
        }
3919
3920
        if (!$_GET['title']) {
3921
            Display::addFlash(
3922
                Display::return_message(
3923
                    get_lang("MustSelectPage"),
3924
                    'error',
3925
                    false
3926
                )
3927
            );
3928
3929
            return;
3930
        }
3931
3932
        // First extract the date of last version
3933
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3934
                WHERE
3935
                    c_id = '.$this->course_id.' AND
3936
                    reflink = "'.Database::escape_string($page).'" AND
3937
                    '.$groupfilter.$condition_session.'
3938
                ORDER BY id DESC';
3939
        $result = Database::query($sql);
3940
        $row = Database::fetch_array($result);
3941
        $lastversiondate = api_get_local_time($row['dtime']);
3942
        $lastuserinfo = api_get_user_info($row['user_id']);
3943
3944
        // Select page to discuss
3945
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3946
                WHERE
3947
                    c_id = '.$this->course_id.' AND
3948
                    reflink="'.Database::escape_string($page).'" AND
3949
                    '.$groupfilter.$condition_session.'
3950
                ORDER BY id ASC';
3951
        $result = Database::query($sql);
3952
        $row = Database::fetch_array($result);
3953
        $id = $row['id'];
3954
        $firstuserid = $row['user_id'];
3955
3956
        if (isset($_POST['Submit']) && self::double_post($_POST['wpost_id'])) {
3957
            $dtime = api_get_utc_datetime();
3958
            $message_author = api_get_user_id();
3959
3960
            $params = [
3961
                'c_id' => $this->course_id,
3962
                'publication_id' => $id,
3963
                'userc_id' => $message_author,
3964
                'comment' => $_POST['comment'],
3965
                'p_score' => $_POST['rating'],
3966
                'dtime' => $dtime,
3967
            ];
3968
            $discussId = Database::insert($tbl_wiki_discuss, $params);
3969
            if ($discussId) {
3970
                $sql = "UPDATE $tbl_wiki_discuss SET id = iid WHERE iid = $discussId";
3971
                Database::query($sql);
3972
            }
3973
3974
            self::check_emailcue($id, 'D', $dtime, $message_author);
3975
3976
            header(
3977
                'Location: '.$this->url.'&action=discuss&title='.api_htmlentities(urlencode($page))
3978
            );
3979
            exit;
3980
        }
3981
3982
        // mode assignment: previous to show  page type
3983
        $icon_assignment = null;
3984
        if ($row['assignment'] == 1) {
3985
            $icon_assignment = Display::return_icon(
3986
                'wiki_assignment.png',
3987
                get_lang('AssignmentDescExtra'),
3988
                '',
3989
                ICON_SIZE_SMALL
3990
            );
3991
        } elseif ($row['assignment'] == 2) {
3992
            $icon_assignment = Display::return_icon(
3993
                'wiki_work.png',
3994
                get_lang('AssignmentWorkExtra'),
3995
                '',
3996
                ICON_SIZE_SMALL
3997
            );
3998
        }
3999
4000
        $countWPost = null;
4001
        $avg_WPost_score = null;
4002
4003
        // Show title and form to discuss if page exist
4004
        if ($id != '') {
4005
            // Show discussion to students if isn't hidden.
4006
            // Show page to all teachers if is hidden.
4007
            // Mode assignments: If is hidden, show pages to student only if student is the author
4008
            if ($row['visibility_disc'] == 1 ||
4009
                api_is_allowed_to_edit(false, true) ||
4010
                api_is_platform_admin() ||
4011
                ($row['assignment'] == 2 && $row['visibility_disc'] == 0 && (api_get_user_id() == $row['user_id']))
4012
            ) {
4013
                echo '<div id="wikititle">';
4014
                // discussion action: protecting (locking) the discussion
4015
                $addlock_disc = null;
4016
                $lock_unlock_disc = null;
4017
                if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4018
                    if (self::check_addlock_discuss() == 1) {
4019
                        $addlock_disc = Display::return_icon(
4020
                            'unlock.png',
4021
                            get_lang('UnlockDiscussExtra'),
4022
                            '',
4023
                            ICON_SIZE_SMALL
4024
                        );
4025
                        $lock_unlock_disc = 'unlockdisc';
4026
                    } else {
4027
                        $addlock_disc = Display::return_icon(
4028
                            'lock.png',
4029
                            get_lang('LockDiscussExtra'),
4030
                            '',
4031
                            ICON_SIZE_SMALL
4032
                        );
4033
                        $lock_unlock_disc = 'lockdisc';
4034
                    }
4035
                }
4036
                echo '<span style="float:right">';
4037
                echo '<a href="'.$this->url.'&action=discuss&actionpage='.$lock_unlock_disc.'&title='.api_htmlentities(
4038
                        urlencode($page)
4039
                    ).'">'.$addlock_disc.'</a>';
4040
                echo '</span>';
4041
4042
                // discussion action: visibility.  Show discussion to students if isn't hidden. Show page to all teachers if is hidden.
4043
                $visibility_disc = null;
4044
                $hide_show_disc = null;
4045
                if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4046
                    if (self::check_visibility_discuss() == 1) {
4047
                        /// TODO: 	Fix Mode assignments: If is hidden, show discussion to student only if student is the author
4048
                        $visibility_disc = Display::return_icon(
4049
                            'visible.png',
4050
                            get_lang('ShowDiscussExtra'),
4051
                            '',
4052
                            ICON_SIZE_SMALL
4053
                        );
4054
                        $hide_show_disc = 'hidedisc';
4055
                    } else {
4056
                        $visibility_disc = Display::return_icon(
4057
                            'invisible.png',
4058
                            get_lang('HideDiscussExtra'),
4059
                            '',
4060
                            ICON_SIZE_SMALL
4061
                        );
4062
                        $hide_show_disc = 'showdisc';
4063
                    }
4064
                }
4065
                echo '<span style="float:right">';
4066
                echo '<a href="'.$this->url.'&action=discuss&actionpage='.$hide_show_disc.'&title='.api_htmlentities(
4067
                        urlencode($page)
4068
                    ).'">'.$visibility_disc.'</a>';
4069
                echo '</span>';
4070
4071
                // discussion action: check add rating lock. Show/Hide list to rating for all student
4072
                $lock_unlock_rating_disc = null;
4073
                $ratinglock_disc = null;
4074
                if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4075
                    if (self::check_ratinglock_discuss() == 1) {
4076
                        $ratinglock_disc = Display::return_icon(
4077
                            'star.png',
4078
                            get_lang('UnlockRatingDiscussExtra'),
4079
                            '',
4080
                            ICON_SIZE_SMALL
4081
                        );
4082
                        $lock_unlock_rating_disc = 'unlockrating';
4083
                    } else {
4084
                        $ratinglock_disc = Display::return_icon(
4085
                            'star_na.png',
4086
                            get_lang('LockRatingDiscussExtra'),
4087
                            '',
4088
                            ICON_SIZE_SMALL
4089
                        );
4090
                        $lock_unlock_rating_disc = 'lockrating';
4091
                    }
4092
                }
4093
4094
                echo '<span style="float:right">';
4095
                echo '<a href="'.$this->url.'&action=discuss&actionpage='.$lock_unlock_rating_disc.'&title='.api_htmlentities(
4096
                        urlencode($page)
4097
                    ).'">'.$ratinglock_disc.'</a>';
4098
                echo '</span>';
4099
4100
                // discussion action: email notification
4101
                if (self::check_notify_discuss($page) == 1) {
4102
                    $notify_disc = Display::return_icon(
4103
                        'messagebox_info.png',
4104
                        get_lang('NotifyDiscussByEmail'),
4105
                        '',
4106
                        ICON_SIZE_SMALL
4107
                    );
4108
                    $lock_unlock_notify_disc = 'unlocknotifydisc';
4109
                } else {
4110
                    $notify_disc = Display::return_icon(
4111
                        'mail.png',
4112
                        get_lang('CancelNotifyDiscussByEmail'),
4113
                        '',
4114
                        ICON_SIZE_SMALL
4115
                    );
4116
                    $lock_unlock_notify_disc = 'locknotifydisc';
4117
                }
4118
                echo '<span style="float:right">';
4119
                echo '<a href="'.$this->url.'&action=discuss&actionpage='.$lock_unlock_notify_disc.'&title='.api_htmlentities(
4120
                        urlencode($page)
4121
                    ).'">'.$notify_disc.'</a>';
4122
                echo '</span>';
4123
                echo $icon_assignment.'&nbsp;&nbsp;&nbsp;'.api_htmlentities(
4124
                        $row['title']
4125
                    );
4126
                if ($lastuserinfo !== false) {
4127
                    echo ' ('.get_lang('MostRecentVersionBy').' '.
4128
                        UserManager::getUserProfileLink($lastuserinfo).' '.$lastversiondate.$countWPost.')'.$avg_WPost_score.' '; //TODO: read average score
4129
                }
4130
4131
                echo '</div>';
4132
                if ($row['addlock_disc'] == 1 || api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4133
                    //show comments but students can't add theirs
4134
                    ?>
4135
                    <div class="panel panel-default">
4136
                        <div class="panel-body">
4137
                            <form name="form1" method="post" action=""
4138
                                  class="form-horizontal">
4139
                                <div class="form-group">
4140
                                    <label
4141
                                        class="col-sm-2 control-label">
4142
                                        <?php echo get_lang('Comments'); ?>:</label>
4143
                                    <div class="col-sm-10">
4144
                                        <?php echo '<input type="hidden" name="wpost_id" value="'.md5(uniqid(rand(), true)).'">'; //prevent double post?>
4145
                                        <textarea class="form-control"
4146
                                                  name="comment" cols="80"
4147
                                                  rows="5"
4148
                                                  id="comment">
4149
                                        </textarea>
4150
                                    </div>
4151
                                </div>
4152
                                <div class="form-group">
4153
                                    <?php
4154
                                    //check if rating is allowed
4155
                                    if ($row['ratinglock_disc'] == 1 || api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4156
                                        ?>
4157
                                        <label
4158
                                            class="col-sm-2 control-label"><?php echo get_lang('Rating'); ?>:</label>
4159
                                        <div class="col-sm-10">
4160
                                            <select name="rating" id="rating" class="selectpicker">
4161
                                                <option value="-" selected>-</option>
4162
                                                <option value="0">0</option>
4163
                                                <option value="1">1</option>
4164
                                                <option value="2">2</option>
4165
                                                <option value="3">3</option>
4166
                                                <option value="4">4</option>
4167
                                                <option value="5">5</option>
4168
                                                <option value="6">6</option>
4169
                                                <option value="7">7</option>
4170
                                                <option value="8">8</option>
4171
                                                <option value="9">9</option>
4172
                                                <option value="10">10</option>
4173
                                            </select>
4174
                                        </div>
4175
                                        <?php
4176
                                    } else {
4177
                                        echo '<input type=hidden name="rating" value="-">';
4178
                                        // must pass a default value to avoid rate automatically
4179
                                    } ?>
4180
4181
                                </div>
4182
                                <div class="form-group">
4183
                                    <div class="col-sm-offset-2 col-sm-10">
4184
                                        <?php echo '<button class="btn btn-default" type="submit" name="Submit"> '.
4185
                                            get_lang('Send').'</button>'; ?>
4186
                                    </div>
4187
                                </div>
4188
                        </div>
4189
                    </div>
4190
                    </form>
4191
                    <?php
4192
                }
4193
                // end discuss lock
4194
4195
                echo '<hr noshade size="1">';
4196
                $user_table = Database::get_main_table(TABLE_MAIN_USER);
4197
4198
                $sql = "SELECT *
4199
                        FROM $tbl_wiki_discuss reviews, $user_table user
4200
                        WHERE
4201
                            reviews.c_id = ".$this->course_id." AND
4202
                            reviews.publication_id='".$id."' AND
4203
                            user.user_id='".$firstuserid."'
4204
                        ORDER BY reviews.id DESC";
4205
                $result = Database::query($sql);
4206
4207
                $countWPost = Database::num_rows($result);
4208
                echo get_lang('NumComments').": ".$countWPost; //comment's numbers
4209
4210
                $sql = "SELECT SUM(p_score) as sumWPost
4211
                        FROM $tbl_wiki_discuss
4212
                        WHERE c_id = ".$this->course_id." AND publication_id = '".$id."' AND NOT p_score='-'
4213
                        ORDER BY id DESC";
4214
                $result2 = Database::query($sql);
4215
                $row2 = Database::fetch_array($result2);
4216
4217
                $sql = "SELECT * FROM $tbl_wiki_discuss
4218
                        WHERE c_id = ".$this->course_id." AND publication_id='".$id."' AND NOT p_score='-'";
4219
                $result3 = Database::query($sql);
4220
                $countWPost_score = Database::num_rows($result3);
4221
4222
                echo ' - '.get_lang('NumCommentsScore').': '.$countWPost_score;
4223
4224
                if ($countWPost_score != 0) {
4225
                    $avg_WPost_score = round($row2['sumWPost'] / $countWPost_score, 2).' / 10';
4226
                } else {
4227
                    $avg_WPost_score = $countWPost_score;
4228
                }
4229
4230
                echo ' - '.get_lang('RatingMedia').': '.$avg_WPost_score; // average rating
4231
4232
                $sql = 'UPDATE '.$tbl_wiki.' SET
4233
                        score = "'.Database::escape_string($avg_WPost_score).'"
4234
                        WHERE
4235
                            c_id = '.$this->course_id.' AND
4236
                            reflink="'.Database::escape_string($page).'" AND
4237
                            '.$groupfilter.$condition_session;
4238
                // check if work ok. TODO:
4239
                Database::query($sql);
4240
4241
                echo '<hr noshade size="1">';
4242
                while ($row = Database::fetch_array($result)) {
4243
                    $userinfo = api_get_user_info($row['userc_id']);
4244
                    if (($userinfo['status']) == "5") {
4245
                        $author_status = get_lang('Student');
4246
                    } else {
4247
                        $author_status = get_lang('Teacher');
4248
                    }
4249
4250
                    $name = $userinfo['complete_name'];
4251
                    $author_photo = '<img src="'.$userinfo['avatar'].'" alt="'.api_htmlentities($name).'"  width="40" height="50" align="top"  title="'.api_htmlentities($name).'"  />';
4252
4253
                    // stars
4254
                    $p_score = $row['p_score'];
4255
                    switch ($p_score) {
4256
                        case 0:
4257
                            $imagerating = Display::return_icon(
4258
                                'rating/stars_0.gif'
4259
                            );
4260
                            break;
4261
                        case 1:
4262
                            $imagerating = Display::return_icon(
4263
                                'rating/stars_5.gif'
4264
                            );
4265
                            break;
4266
                        case 2:
4267
                            $imagerating = Display::return_icon(
4268
                                'rating/stars_10.gif'
4269
                            );
4270
                            break;
4271
                        case 3:
4272
                            $imagerating = Display::return_icon(
4273
                                'rating/stars_15.gif'
4274
                            );
4275
                            break;
4276
                        case 4:
4277
                            $imagerating = Display::return_icon(
4278
                                'rating/stars_20.gif'
4279
                            );
4280
                            break;
4281
                        case 5:
4282
                            $imagerating = Display::return_icon(
4283
                                'rating/stars_25.gif'
4284
                            );
4285
                            break;
4286
                        case 6:
4287
                            $imagerating = Display::return_icon(
4288
                                'rating/stars_30.gif'
4289
                            );
4290
                            break;
4291
                        case 7:
4292
                            $imagerating = Display::return_icon(
4293
                                'rating/stars_35.gif'
4294
                            );
4295
                            break;
4296
                        case 8:
4297
                            $imagerating = Display::return_icon(
4298
                                'rating/stars_40.gif'
4299
                            );
4300
                            break;
4301
                        case 9:
4302
                            $imagerating = Display::return_icon(
4303
                                'rating/stars_45.gif'
4304
                            );
4305
                            break;
4306
                        case 10:
4307
                            $imagerating = Display::return_icon(
4308
                                'rating/stars_50.gif'
4309
                            );
4310
                            break;
4311
                    }
4312
                    echo '<p><table>';
4313
                    echo '<tr>';
4314
                    echo '<td rowspan="2">'.$author_photo.'</td>';
4315
                    $userProfile = '';
4316
                    if ($userinfo !== false) {
4317
                        $userProfile = UserManager::getUserProfileLink(
4318
                            $userinfo
4319
                        );
4320
                    }
4321
                    echo '<td style=" color:#999999">'.$userProfile.' ('.$author_status.') '.
4322
                        api_get_local_time(
4323
                            $row['dtime']
4324
                        ).
4325
                        ' - '.get_lang(
4326
                            'Rating'
4327
                        ).': '.$row['p_score'].' '.$imagerating.' </td>';
4328
                    echo '</tr>';
4329
                    echo '<tr>';
4330
                    echo '<td>'.api_htmlentities($row['comment']).'</td>';
4331
                    echo '</tr>';
4332
                    echo "</table>";
4333
                }
4334
            } else {
4335
                Display::addFlash(
4336
                    Display::return_message(
4337
                        get_lang('LockByTeacher'),
4338
                        'warning',
4339
                        false
4340
                    )
4341
                );
4342
            }
4343
        } else {
4344
            Display::addFlash(
4345
                Display::return_message(
4346
                    get_lang('DiscussNotAvailable'),
4347
                    'normal',
4348
                    false
4349
                )
4350
            );
4351
        }
4352
    }
4353
4354
    /**
4355
     * Show all pages.
4356
     */
4357
    public function allPages($action)
4358
    {
4359
        echo '<div class="actions">'.get_lang('AllPages');
4360
4361
        // menu delete all wiki
4362
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4363
            echo ' <a href="'.$this->url.'&action=deletewiki">'.
4364
                Display::return_icon(
4365
                    'delete.png',
4366
                    get_lang('DeleteWiki'),
4367
                    '',
4368
                    ICON_SIZE_MEDIUM
4369
                ).'</a>';
4370
        }
4371
        echo '</div>';
4372
4373
        //show table
4374
        $table = new SortableTable(
4375
            'AllPages_table',
4376
            function () {
4377
                $result = $this->gelAllPagesQuery(true);
4378
4379
                return (int) Database::fetch_assoc($result)['nbr'];
4380
            },
4381
            function ($from, $numberOfItems, $column, $direction) {
4382
                $result = $this->gelAllPagesQuery(false, $from, $numberOfItems, $column, $direction);
4383
                $rows = [];
4384
4385
                while ($data = Database::fetch_assoc($result)) {
4386
                    $rows[] = [
4387
                        $data['col0'],
4388
                        [$data['col1'], $data['reflink'], $data['iid']],
4389
                        [$data['col2'], $data['user_ip']],
4390
                        $data['col3'],
4391
                        $data['reflink'],
4392
                    ];
4393
                }
4394
4395
                return $rows;
4396
            }
4397
        );
4398
        $table->set_additional_parameters(
4399
            [
4400
                'cidReq' => $this->courseCode,
4401
                'gidReq' => $this->group_id,
4402
                'id_session' => $this->session_id,
4403
                'action' => Security::remove_XSS($action),
4404
            ]
4405
        );
4406
        $table->set_header(
4407
            0,
4408
            get_lang('Type'),
4409
            true,
4410
            ['style' => 'width:30px;']
4411
        );
4412
        $table->set_header(1, get_lang('Title'));
4413
        $table->set_header(
4414
            2,
4415
            get_lang('Author').' <small>'.get_lang('LastVersion').'</small>'
4416
        );
4417
        $table->set_header(
4418
            3,
4419
            get_lang('Date').' <small>'.get_lang('LastVersion').'</small>'
4420
        );
4421
        if (api_is_allowed_to_session_edit(false, true)) {
4422
            $table->set_header(
4423
                4,
4424
                get_lang('Actions'),
4425
                false,
4426
                ['style' => 'width: 145px;']
4427
            );
4428
        }
4429
        $table->set_column_filter(
4430
            0,
4431
            function ($value, string $urlParams, array $row) {
4432
                $return = '';
4433
                //get type assignment icon
4434
                if (1 == $value) {
4435
                    $return .= Display::return_icon(
4436
                        'wiki_assignment.png',
4437
                        get_lang('AssignmentDesc'),
4438
                        '',
4439
                        ICON_SIZE_SMALL
4440
                    );
4441
                } elseif (2 == $value) {
4442
                    $return .= Display::return_icon(
4443
                        'wiki_work.png',
4444
                        get_lang('AssignmentWork'),
4445
                        '',
4446
                        ICON_SIZE_SMALL
4447
                    );
4448
                } elseif (0 == $value) {
4449
                    $return .= Display::return_icon(
4450
                        'px_transparent.gif'
4451
                    );
4452
                }
4453
4454
                //get icon task
4455
                if (!empty($row['task'])) {
4456
                    $return .= Display::return_icon(
4457
                        'wiki_task.png',
4458
                        get_lang('StandardTask'),
4459
                        '',
4460
                        ICON_SIZE_SMALL
4461
                    );
4462
                } else {
4463
                    $return .= Display::return_icon('px_transparent.gif');
4464
                }
4465
4466
                return $return;
4467
            }
4468
        );
4469
        $table->set_column_filter(
4470
            1,
4471
            function ($value) {
4472
                list($title, $refLink, $iid) = $value;
4473
4474
                return Display::url(
4475
                        api_htmlentities($title),
4476
                        $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($refLink)])
4477
                    )
4478
                    .$this->returnCategoriesBlock($iid, '<div><small>', '</small></div>');
4479
            }
4480
        );
4481
        $table->set_column_filter(
4482
            2,
4483
            function ($value) {
4484
                list($userId, $userIp) = $value;
4485
                //get author
4486
                $userinfo = api_get_user_info($userId);
4487
4488
                if ($userinfo !== false) {
4489
                    return UserManager::getUserProfileLink($userinfo);
4490
                }
4491
4492
                return get_lang('Anonymous').' ('.api_htmlentities($userIp).')';
4493
            }
4494
        );
4495
        $table->set_column_filter(
4496
            3,
4497
            function ($value) {
4498
                return api_get_local_time($value);
4499
            }
4500
        );
4501
        $table->set_column_filter(
4502
            4,
4503
            function ($value) {
4504
                $actions = '';
4505
4506
                if (api_is_allowed_to_session_edit(false, true)) {
4507
                    $actions = Display::url(
4508
                            Display::return_icon('edit.png', get_lang('EditPage')),
4509
                            $this->url.'&'.http_build_query(['action' => 'edit', 'title' => api_htmlentities($value)])
4510
                        )
4511
                        .Display::url(
4512
                            Display::return_icon('discuss.png', get_lang('Discuss')),
4513
                            $this->url.'&'.http_build_query(['action' => 'discuss', 'title' => api_htmlentities($value)])
4514
                        )
4515
                        .Display::url(
4516
                            Display::return_icon('history.png', get_lang('History')),
4517
                            $this->url.'&'.http_build_query(['action' => 'history', 'title' => api_htmlentities($value)])
4518
                        )
4519
                        .Display::url(
4520
                            Display::return_icon('what_link_here.png', get_lang('LinksPages')),
4521
                            $this->url.'&'.http_build_query(['action' => 'links', 'title' => api_htmlentities($value)])
4522
                        )
4523
                    ;
4524
                }
4525
4526
                if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4527
                    $actions .= Display::url(
4528
                            Display::return_icon('delete.png', get_lang('Delete')),
4529
                            $this->url.'&'.http_build_query(['action' => 'delete', 'title' => api_htmlentities($value)])
4530
                        )
4531
                    ;
4532
                }
4533
4534
                return $actions;
4535
            }
4536
        );
4537
        $table->display();
4538
    }
4539
4540
    /**
4541
     * Get recent changes.
4542
     *
4543
     * @param string $page
4544
     * @param string $action
4545
     */
4546
    public function recentChanges($page, $action)
4547
    {
4548
        $tbl_wiki = $this->tbl_wiki;
4549
        $condition_session = $this->condition_session;
4550
        $groupfilter = $this->groupfilter;
4551
        $tbl_wiki_conf = $this->tbl_wiki_conf;
4552
4553
        if (api_is_allowed_to_session_edit(false, true)) {
4554
            if (self::check_notify_all() == 1) {
4555
                $notify_all = Display::return_icon(
4556
                        'messagebox_info.png',
4557
                        get_lang('NotifyByEmail'),
4558
                        '',
4559
                        ICON_SIZE_SMALL
4560
                    ).' '.get_lang('NotNotifyChanges');
4561
                $lock_unlock_notify_all = 'unlocknotifyall';
4562
            } else {
4563
                $notify_all = Display::return_icon(
4564
                        'mail.png',
4565
                        get_lang('CancelNotifyByEmail'),
4566
                        '',
4567
                        ICON_SIZE_SMALL
4568
                    ).' '.get_lang('NotifyChanges');
4569
                $lock_unlock_notify_all = 'locknotifyall';
4570
            }
4571
        }
4572
4573
        echo '<div class="actions"><span style="float: right;">';
4574
        echo '<a href="'.$this->url.'&action=recentchanges&actionpage='.$lock_unlock_notify_all.'&title='.api_htmlentities(
4575
                urlencode($page)
4576
            ).'">'.$notify_all.'</a>';
4577
        echo '</span>'.get_lang('RecentChanges').'</div>';
4578
4579
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4580
            //only by professors if page is hidden
4581
            $sql = 'SELECT * FROM '.$tbl_wiki.', '.$tbl_wiki_conf.'
4582
        		WHERE 	'.$tbl_wiki_conf.'.c_id= '.$this->course_id.' AND
4583
        				'.$tbl_wiki.'.c_id= '.$this->course_id.' AND
4584
        				'.$tbl_wiki_conf.'.page_id='.$tbl_wiki.'.page_id AND
4585
        				'.$tbl_wiki.'.'.$groupfilter.$condition_session.'
4586
        		ORDER BY dtime DESC'; // new version
4587
        } else {
4588
            $sql = 'SELECT *
4589
                FROM '.$tbl_wiki.'
4590
                WHERE
4591
                    c_id = '.$this->course_id.' AND
4592
                    '.$groupfilter.$condition_session.' AND
4593
                    visibility=1
4594
                ORDER BY dtime DESC';
4595
            // old version TODO: Replace by the bottom line
4596
        }
4597
4598
        $allpages = Database::query($sql);
4599
4600
        //show table
4601
        if (Database::num_rows($allpages) > 0) {
4602
            $rows = [];
4603
            while ($obj = Database::fetch_object($allpages)) {
4604
                //get author
4605
                $userinfo = api_get_user_info($obj->user_id);
4606
4607
                //get type assignment icon
4608
                if ($obj->assignment == 1) {
4609
                    $ShowAssignment = Display::return_icon(
4610
                        'wiki_assignment.png',
4611
                        get_lang('AssignmentDesc'),
4612
                        '',
4613
                        ICON_SIZE_SMALL
4614
                    );
4615
                } elseif ($obj->assignment == 2) {
4616
                    $ShowAssignment = Display::return_icon(
4617
                        'wiki_work.png',
4618
                        get_lang('AssignmentWork'),
4619
                        '',
4620
                        ICON_SIZE_SMALL
4621
                    );
4622
                } elseif ($obj->assignment == 0) {
4623
                    $ShowAssignment = Display::return_icon(
4624
                        'px_transparent.gif'
4625
                    );
4626
                }
4627
4628
                // Get icon task
4629
                if (!empty($obj->task)) {
4630
                    $icon_task = Display::return_icon(
4631
                        'wiki_task.png',
4632
                        get_lang('StandardTask'),
4633
                        '',
4634
                        ICON_SIZE_SMALL
4635
                    );
4636
                } else {
4637
                    $icon_task = Display::return_icon('px_transparent.gif');
4638
                }
4639
4640
                $row = [];
4641
                $row[] = api_get_local_time(
4642
                    $obj->dtime
4643
                );
4644
                $row[] = $ShowAssignment.$icon_task;
4645
                $row[] = Display::url(
4646
                    api_htmlentities($obj->title),
4647
                    $this->url.'&'.http_build_query(
4648
                        [
4649
                            'action' => 'showpage',
4650
                            'title' => api_htmlentities($obj->reflink),
4651
                            'view' => $obj->id,
4652
                        ]
4653
                    )
4654
                );
4655
                $row[] = $obj->version > 1 ? get_lang('EditedBy') : get_lang(
4656
                    'AddedBy'
4657
                );
4658
                if ($userinfo !== false) {
4659
                    $row[] = UserManager::getUserProfileLink($userinfo);
4660
                } else {
4661
                    $row[] = get_lang('Anonymous').' ('.api_htmlentities(
4662
                            $obj->user_ip
4663
                        ).')';
4664
                }
4665
                $rows[] = $row;
4666
            }
4667
4668
            $table = new SortableTableFromArrayConfig(
4669
                $rows,
4670
                0,
4671
                10,
4672
                'RecentPages_table',
4673
                '',
4674
                '',
4675
                'DESC'
4676
            );
4677
            $table->set_additional_parameters(
4678
                [
4679
                    'cidReq' => $this->courseCode,
4680
                    'gidReq' => $this->group_id,
4681
                    'id_session' => $this->session_id,
4682
                    'action' => Security::remove_XSS($action),
4683
                ]
4684
            );
4685
            $table->set_header(
4686
                0,
4687
                get_lang('Date'),
4688
                true,
4689
                ['style' => 'width:200px;']
4690
            );
4691
            $table->set_header(
4692
                1,
4693
                get_lang('Type'),
4694
                true,
4695
                ['style' => 'width:30px;']
4696
            );
4697
            $table->set_header(2, get_lang('Title'), true);
4698
            $table->set_header(
4699
                3,
4700
                get_lang('Actions'),
4701
                true,
4702
                ['style' => 'width:80px;']
4703
            );
4704
            $table->set_header(4, get_lang('Author'), true);
4705
            $table->display();
4706
        }
4707
    }
4708
4709
    /**
4710
     * What links here. Show pages that have linked this page.
4711
     *
4712
     * @param string $page
4713
     */
4714
    public function getLinks($page)
4715
    {
4716
        $tbl_wiki = $this->tbl_wiki;
4717
        $condition_session = $this->condition_session;
4718
        $groupfilter = $this->groupfilter;
4719
        $action = $this->action;
4720
4721
        if (!$_GET['title']) {
4722
            Display::addFlash(
4723
                Display::return_message(
4724
                    get_lang("MustSelectPage"),
4725
                    'error',
4726
                    false
4727
                )
4728
            );
4729
        } else {
4730
            $sql = 'SELECT * FROM '.$tbl_wiki.'
4731
                    WHERE
4732
                        c_id = '.$this->course_id.' AND
4733
                        reflink="'.Database::escape_string($page).'" AND
4734
                        '.$groupfilter.$condition_session;
4735
            $result = Database::query($sql);
4736
            $row = Database::fetch_array($result);
4737
4738
            //get type assignment icon
4739
            $ShowAssignment = '';
4740
            if ($row['assignment'] == 1) {
4741
                $ShowAssignment = Display::return_icon(
4742
                    'wiki_assignment.png',
4743
                    get_lang('AssignmentDesc'),
4744
                    '',
4745
                    ICON_SIZE_SMALL
4746
                );
4747
            } elseif ($row['assignment'] == 2) {
4748
                $ShowAssignment = Display::return_icon(
4749
                    'wiki_work.png',
4750
                    get_lang('AssignmentWork'),
4751
                    '',
4752
                    ICON_SIZE_SMALL
4753
                );
4754
            } elseif ($row['assignment'] == 0) {
4755
                $ShowAssignment = Display::return_icon('px_transparent.gif');
4756
            }
4757
4758
            //fix Title to reflink (link Main Page)
4759
            if ($page == get_lang('DefaultTitle')) {
4760
                $page = 'index';
4761
            }
4762
4763
            echo '<div id="wikititle">'
4764
                .get_lang('LinksPagesFrom').": $ShowAssignment "
4765
                .Display::url(
4766
                    api_htmlentities($row['title']),
4767
                    $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($page)])
4768
                )
4769
                .'</div>'
4770
            ;
4771
4772
            //fix index to title Main page into linksto
4773
4774
            if ($page == 'index') {
4775
                $page = str_replace(' ', '_', get_lang('DefaultTitle'));
4776
            }
4777
4778
            if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4779
                // only by professors if page is hidden
4780
                $sql = "SELECT * FROM ".$tbl_wiki." s1
4781
                        WHERE s1.c_id = ".$this->course_id." AND linksto LIKE '%".Database::escape_string(
4782
                        $page
4783
                    )."%' AND id=(
4784
                        SELECT MAX(s2.id) FROM ".$tbl_wiki." s2
4785
                        WHERE s2.c_id = ".$this->course_id." AND s1.reflink = s2.reflink AND ".$groupfilter.$condition_session.")";
4786
            } else {
4787
                //add blank space after like '%" " %' to identify each word
4788
                $sql = "SELECT * FROM ".$tbl_wiki." s1
4789
                        WHERE s1.c_id = ".$this->course_id." AND visibility=1 AND linksto LIKE '%".Database::escape_string(
4790
                        $page
4791
                    )."%' AND id=(
4792
                        SELECT MAX(s2.id) FROM ".$tbl_wiki." s2
4793
                        WHERE s2.c_id = ".$this->course_id." AND s1.reflink = s2.reflink AND ".$groupfilter.$condition_session.")";
4794
            }
4795
4796
            $allpages = Database::query($sql);
4797
4798
            //show table
4799
            if (Database::num_rows($allpages) > 0) {
4800
                $rows = [];
4801
                while ($obj = Database::fetch_object($allpages)) {
4802
                    //get author
4803
                    $userinfo = api_get_user_info($obj->user_id);
4804
4805
                    //get time
4806
                    $year = substr($obj->dtime, 0, 4);
4807
                    $month = substr($obj->dtime, 5, 2);
4808
                    $day = substr($obj->dtime, 8, 2);
4809
                    $hours = substr($obj->dtime, 11, 2);
4810
                    $minutes = substr($obj->dtime, 14, 2);
4811
                    $seconds = substr($obj->dtime, 17, 2);
4812
4813
                    //get type assignment icon
4814
                    if ($obj->assignment == 1) {
4815
                        $ShowAssignment = Display::return_icon(
4816
                            'wiki_assignment.png',
4817
                            get_lang('AssignmentDesc'),
4818
                            '',
4819
                            ICON_SIZE_SMALL
4820
                        );
4821
                    } elseif ($obj->assignment == 2) {
4822
                        $ShowAssignment = Display::return_icon(
4823
                            'wiki_work.png',
4824
                            get_lang('AssignmentWork'),
4825
                            '',
4826
                            ICON_SIZE_SMALL
4827
                        );
4828
                    } elseif ($obj->assignment == 0) {
4829
                        $ShowAssignment = Display::return_icon(
4830
                            'px_transparent.gif'
4831
                        );
4832
                    }
4833
4834
                    $row = [];
4835
                    $row[] = $ShowAssignment;
4836
                    $row[] = Display::url(
4837
                        api_htmlentities($obj->title),
4838
                        $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($obj->reflink)])
4839
                    );
4840
                    if ($userinfo !== false) {
4841
                        $row[] = UserManager::getUserProfileLink($userinfo);
4842
                    } else {
4843
                        $row[] = get_lang('Anonymous').' ('.$obj->user_ip.')';
4844
                    }
4845
                    $row[] = $year.'-'.$month.'-'.$day.' '.$hours.":".$minutes.":".$seconds;
4846
                    $rows[] = $row;
4847
                }
4848
4849
                $table = new SortableTableFromArrayConfig(
4850
                    $rows,
4851
                    1,
4852
                    10,
4853
                    'AllPages_table',
4854
                    '',
4855
                    '',
4856
                    'ASC'
4857
                );
4858
                $table->set_additional_parameters(
4859
                    [
4860
                        'cidReq' => $this->courseCode,
4861
                        'gidReq' => $this->group_id,
4862
                        'id_session' => $this->session_id,
4863
                        'action' => Security::remove_XSS($action),
4864
                    ]
4865
                );
4866
                $table->set_header(
4867
                    0,
4868
                    get_lang('Type'),
4869
                    true,
4870
                    ['style' => 'width:30px;']
4871
                );
4872
                $table->set_header(1, get_lang('Title'), true);
4873
                $table->set_header(2, get_lang('Author'), true);
4874
                $table->set_header(3, get_lang('Date'), true);
4875
                $table->display();
4876
            }
4877
        }
4878
    }
4879
4880
    /**
4881
     * @param string $action
4882
     */
4883
    public function getSearchPages($action)
4884
    {
4885
        echo '<div class="actions">'.get_lang('SearchPages').'</div>';
4886
        if (isset($_GET['mode_table'])) {
4887
            if (!isset($_GET['SearchPages_table_page_nr'])) {
4888
                $_GET['search_term'] = $_POST['search_term'] ?? '';
4889
                $_GET['search_content'] = $_POST['search_content'] ?? '';
4890
                $_GET['all_vers'] = $_POST['all_vers'] ?? '';
4891
                $_GET['categories'] = $_POST['categories'] ?? [];
4892
                $_GET['match_all_categories'] = !empty($_POST['match_all_categories']);
4893
            }
4894
            $this->display_wiki_search_results(
4895
                $_GET['search_term'],
4896
                (int) $_GET['search_content'],
4897
                (int) $_GET['all_vers'],
4898
                $_GET['categories'],
4899
                $_GET['match_all_categories']
4900
            );
4901
        } else {
4902
            // initiate the object
4903
            $form = new FormValidator(
4904
                'wiki_search',
4905
                'get',
4906
                $this->url.'&'.http_build_query(['action' => api_htmlentities($action), 'mode_table' => 'yes1'])
4907
            );
4908
4909
            $form->addHidden('cidReq', $this->courseCode);
4910
            $form->addHidden('id_session', $this->session_id);
4911
            $form->addHidden('gidReq', $this->group_id);
4912
            $form->addHidden('gradebook', '0');
4913
            $form->addHidden('origin', '');
4914
            $form->addHidden('action', 'searchpages');
4915
4916
            // Setting the form elements
4917
4918
            $form->addText(
4919
                'search_term',
4920
                get_lang('SearchTerm'),
4921
                false,
4922
                ['autofocus' => 'autofocus']
4923
            );
4924
            $form->addCheckBox('search_content', '', get_lang('AlsoSearchContent'));
4925
            $form->addCheckbox('all_vers', '', get_lang('IncludeAllVersions'));
4926
4927
            if (true === api_get_configuration_value('wiki_categories_enabled')) {
4928
                $categories = Database::getManager()
4929
                    ->getRepository(CWikiCategory::class)
4930
                    ->findByCourse(api_get_course_entity(), api_get_session_entity())
4931
                ;
4932
4933
                $form->addSelectFromCollection(
4934
                    'categories',
4935
                    get_lang('Categories'),
4936
                    $categories,
4937
                    ['multiple' => 'multiple'],
4938
                    false,
4939
                    'getNodeName'
4940
                );
4941
                $form->addCheckBox(
4942
                    'match_all_categories',
4943
                    '',
4944
                    get_lang('OnlyThoseThatCorrespondToAllTheSelectedCategories')
4945
                );
4946
            }
4947
4948
            $form->addButtonSearch(get_lang('Search'), 'SubmitWikiSearch');
4949
4950
            // setting the rules
4951
            $form->addRule(
4952
                'search_term',
4953
                get_lang('TooShort'),
4954
                'minlength',
4955
                3
4956
            ); //TODO: before fixing the pagination rules worked, not now
4957
4958
            if ($form->validate()) {
4959
                $form->display();
4960
                $values = $form->exportValues();
4961
                $this->display_wiki_search_results(
4962
                    $values['search_term'],
4963
                    (int) ($values['search_content'] ?? ''),
4964
                    (int) ($values['all_vers'] ?? ''),
4965
                    $values['categories'] ?? [],
4966
                    !empty($values['match_all_categories'])
4967
                );
4968
            } else {
4969
                $form->display();
4970
            }
4971
        }
4972
    }
4973
4974
    /**
4975
     * @param int    $userId
4976
     * @param string $action
4977
     */
4978
    public function getUserContributions($userId, $action)
4979
    {
4980
        $tbl_wiki = $this->tbl_wiki;
4981
        $condition_session = $this->condition_session;
4982
        $groupfilter = $this->groupfilter;
4983
        $userId = (int) $userId;
4984
        $userinfo = api_get_user_info($userId);
4985
        if ($userinfo !== false) {
4986
            echo '<div class="actions">'
4987
                .Display::url(
4988
                    get_lang('UserContributions').': '.$userinfo['complete_name_with_username'],
4989
                    $this->url.'&'.http_build_query(['action' => 'usercontrib', 'user_id' => $userId])
4990
                )
4991
            ;
4992
        }
4993
4994
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4995
            //only by professors if page is hidden
4996
            $sql = 'SELECT * FROM '.$tbl_wiki.'
4997
                    WHERE
4998
                        c_id = '.$this->course_id.' AND
4999
                        '.$groupfilter.$condition_session.' AND
5000
                        user_id="'.$userId.'"';
5001
        } else {
5002
            $sql = 'SELECT * FROM '.$tbl_wiki.'
5003
                    WHERE
5004
                        c_id = '.$this->course_id.' AND
5005
                        '.$groupfilter.$condition_session.' AND
5006
                        user_id="'.$userId.'" AND
5007
                        visibility=1';
5008
        }
5009
5010
        $allpages = Database::query($sql);
5011
5012
        //show table
5013
        if (Database::num_rows($allpages) > 0) {
5014
            $rows = [];
5015
            while ($obj = Database::fetch_object($allpages)) {
5016
                //get type assignment icon
5017
                $ShowAssignment = '';
5018
                if ($obj->assignment == 1) {
5019
                    $ShowAssignment = Display::return_icon(
5020
                        'wiki_assignment.png',
5021
                        get_lang('AssignmentDescExtra'),
5022
                        '',
5023
                        ICON_SIZE_SMALL
5024
                    );
5025
                } elseif ($obj->assignment == 2) {
5026
                    $ShowAssignment = Display::return_icon(
5027
                        'wiki_work.png',
5028
                        get_lang('AssignmentWork'),
5029
                        '',
5030
                        ICON_SIZE_SMALL
5031
                    );
5032
                } elseif ($obj->assignment == 0) {
5033
                    $ShowAssignment = Display::return_icon(
5034
                        'px_transparent.gif'
5035
                    );
5036
                }
5037
5038
                $row = [];
5039
                $row[] = api_get_local_time($obj->dtime);
5040
                $row[] = $ShowAssignment;
5041
                $row[] = Display::url(
5042
                    api_htmlentities($obj->title),
5043
                    $this->url.'&'
5044
                        .http_build_query([
5045
                            'action' => 'showpage',
5046
                            'title' => api_htmlentities($obj->reflink),
5047
                            'view' => (int) $obj->id,
5048
                        ])
5049
                );
5050
                $row[] = Security::remove_XSS($obj->version);
5051
                $row[] = Security::remove_XSS($obj->comment);
5052
                $row[] = Security::remove_XSS($obj->progress).' %';
5053
                $row[] = Security::remove_XSS($obj->score);
5054
                $rows[] = $row;
5055
            }
5056
5057
            $table = new SortableTableFromArrayConfig(
5058
                $rows,
5059
                2,
5060
                10,
5061
                'UsersContributions_table',
5062
                '',
5063
                '',
5064
                'ASC'
5065
            );
5066
            $table->set_additional_parameters(
5067
                [
5068
                    'cidReq' => $this->courseCode,
5069
                    'gidReq' => $this->group_id,
5070
                    'id_session' => $this->session_id,
5071
                    'action' => Security::remove_XSS($action),
5072
                    'user_id' => intval($userId),
5073
                ]
5074
            );
5075
            $table->set_header(
5076
                0,
5077
                get_lang('Date'),
5078
                true,
5079
                ['style' => 'width:200px;']
5080
            );
5081
            $table->set_header(
5082
                1,
5083
                get_lang('Type'),
5084
                true,
5085
                ['style' => 'width:30px;']
5086
            );
5087
            $table->set_header(
5088
                2,
5089
                get_lang('Title'),
5090
                true,
5091
                ['style' => 'width:200px;']
5092
            );
5093
            $table->set_header(
5094
                3,
5095
                get_lang('Version'),
5096
                true,
5097
                ['style' => 'width:30px;']
5098
            );
5099
            $table->set_header(
5100
                4,
5101
                get_lang('Comment'),
5102
                true,
5103
                ['style' => 'width:200px;']
5104
            );
5105
            $table->set_header(
5106
                5,
5107
                get_lang('Progress'),
5108
                true,
5109
                ['style' => 'width:30px;']
5110
            );
5111
            $table->set_header(
5112
                6,
5113
                get_lang('Rating'),
5114
                true,
5115
                ['style' => 'width:30px;']
5116
            );
5117
            $table->display();
5118
        }
5119
    }
5120
5121
    /**
5122
     * @param string $action
5123
     */
5124
    public function getMostChangedPages($action)
5125
    {
5126
        $tbl_wiki = $this->tbl_wiki;
5127
        $condition_session = $this->condition_session;
5128
        $groupfilter = $this->groupfilter;
5129
5130
        echo '<div class="actions">'.get_lang('MostChangedPages').'</div>';
5131
5132
        if (api_is_allowed_to_edit(false, true) ||
5133
            api_is_platform_admin()
5134
        ) { //only by professors if page is hidden
5135
            $sql = 'SELECT *, MAX(version) AS MAX FROM '.$tbl_wiki.'
5136
                    WHERE c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.'
5137
                    GROUP BY reflink'; //TODO:check MAX and group by return last version
5138
        } else {
5139
            $sql = 'SELECT *, MAX(version) AS MAX FROM '.$tbl_wiki.'
5140
                    WHERE c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.' AND visibility=1
5141
                    GROUP BY reflink'; //TODO:check MAX and group by return last version
5142
        }
5143
5144
        $allpages = Database::query($sql);
5145
5146
        //show table
5147
        if (Database::num_rows($allpages) > 0) {
5148
            $rows = [];
5149
            while ($obj = Database::fetch_object($allpages)) {
5150
                //get type assignment icon
5151
                $ShowAssignment = '';
5152
                if ($obj->assignment == 1) {
5153
                    $ShowAssignment = Display::return_icon(
5154
                        'wiki_assignment.png',
5155
                        get_lang('AssignmentDesc'),
5156
                        '',
5157
                        ICON_SIZE_SMALL
5158
                    );
5159
                } elseif ($obj->assignment == 2) {
5160
                    $ShowAssignment = Display::return_icon(
5161
                        'wiki_work.png',
5162
                        get_lang('AssignmentWork'),
5163
                        '',
5164
                        ICON_SIZE_SMALL
5165
                    );
5166
                } elseif ($obj->assignment == 0) {
5167
                    $ShowAssignment = Display::return_icon(
5168
                        'px_transparent.gif'
5169
                    );
5170
                }
5171
5172
                $row = [];
5173
                $row[] = $ShowAssignment;
5174
                $row[] = Display::url(
5175
                    api_htmlentities($obj->title),
5176
                    $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($obj->reflink)])
5177
                );
5178
                $row[] = $obj->MAX;
5179
                $rows[] = $row;
5180
            }
5181
5182
            $table = new SortableTableFromArrayConfig(
5183
                $rows,
5184
                2,
5185
                10,
5186
                'MostChangedPages_table',
5187
                '',
5188
                '',
5189
                'DESC'
5190
            );
5191
            $table->set_additional_parameters(
5192
                [
5193
                    'cidReq' => $this->courseCode,
5194
                    'gidReq' => $this->group_id,
5195
                    'id_session' => $this->session_id,
5196
                    'action' => Security::remove_XSS($action),
5197
                ]
5198
            );
5199
            $table->set_header(
5200
                0,
5201
                get_lang('Type'),
5202
                true,
5203
                ['style' => 'width:30px;']
5204
            );
5205
            $table->set_header(1, get_lang('Title'), true);
5206
            $table->set_header(2, get_lang('Changes'), true);
5207
            $table->display();
5208
        }
5209
    }
5210
5211
    /**
5212
     * Restore page.
5213
     *
5214
     * @return bool
5215
     */
5216
    public function restorePage()
5217
    {
5218
        $userId = api_get_user_id();
5219
        $current_row = $this->getWikiData();
5220
        $last_row = $this->getLastWikiData($this->page);
5221
5222
        if (empty($last_row)) {
5223
            return false;
5224
        }
5225
5226
        $PassEdit = false;
5227
5228
        /* Only teachers and platform admin can edit the index page.
5229
        Only teachers and platform admin can edit an assignment teacher*/
5230
        if (($current_row['reflink'] == 'index' ||
5231
                $current_row['reflink'] == '' ||
5232
                $current_row['assignment'] == 1) &&
5233
            (!api_is_allowed_to_edit(false, true) &&
5234
                $this->group_id == 0)
5235
        ) {
5236
            Display::addFlash(
5237
                Display::return_message(
5238
                    get_lang('OnlyEditPagesCourseManager'),
5239
                    'normal',
5240
                    false
5241
                )
5242
            );
5243
        } else {
5244
            // check if is a wiki group
5245
            if ($current_row['group_id'] != 0) {
5246
                $groupInfo = GroupManager::get_group_properties(
5247
                    $this->group_id
5248
                );
5249
                //Only teacher, platform admin and group members can edit a wiki group
5250
                if (api_is_allowed_to_edit(false, true) ||
5251
                    api_is_platform_admin() ||
5252
                    GroupManager::is_user_in_group($userId, $groupInfo) ||
5253
                    api_is_allowed_in_course()
5254
                ) {
5255
                    $PassEdit = true;
5256
                } else {
5257
                    Display::addFlash(
5258
                        Display::return_message(
5259
                            get_lang('OnlyEditPagesGroupMembers'),
5260
                            'normal',
5261
                            false
5262
                        )
5263
                    );
5264
                }
5265
            } else {
5266
                $PassEdit = true;
5267
            }
5268
5269
            // check if is an assignment
5270
            //$icon_assignment = null;
5271
            if ($current_row['assignment'] == 1) {
5272
                Display::addFlash(
5273
                    Display::return_message(
5274
                        get_lang('EditAssignmentWarning'),
5275
                        'normal',
5276
                        false
5277
                    )
5278
                );
5279
            } elseif ($current_row['assignment'] == 2) {
5280
                if (($userId == $current_row['user_id']) == false) {
5281
                    if (api_is_allowed_to_edit(
5282
                            false,
5283
                            true
5284
                        ) || api_is_platform_admin()) {
5285
                        $PassEdit = true;
5286
                    } else {
5287
                        Display::addFlash(
5288
                            Display::return_message(
5289
                                get_lang('LockByTeacher'),
5290
                                'normal',
5291
                                false
5292
                            )
5293
                        );
5294
                        $PassEdit = false;
5295
                    }
5296
                } else {
5297
                    $PassEdit = true;
5298
                }
5299
            }
5300
5301
            //show editor if edit is allowed
5302
            if ($PassEdit) {
5303
                if ($current_row['editlock'] == 1 &&
5304
                    (api_is_allowed_to_edit(false, true) == false ||
5305
                        api_is_platform_admin() == false)
5306
                ) {
5307
                    Display::addFlash(
5308
                        Display::return_message(
5309
                            get_lang('PageLockedExtra'),
5310
                            'normal',
5311
                            false
5312
                        )
5313
                    );
5314
                } else {
5315
                    if ($last_row['is_editing'] != 0 && $last_row['is_editing'] != $userId) {
5316
                        // Checking for concurrent users
5317
                        $timestamp_edit = strtotime($last_row['time_edit']);
5318
                        $time_editing = time() - $timestamp_edit;
5319
                        $max_edit_time = 1200; // 20 minutes
5320
                        $rest_time = $max_edit_time - $time_editing;
5321
                        $userinfo = api_get_user_info($last_row['is_editing']);
5322
                        $is_being_edited = get_lang(
5323
                                'ThisPageisBeginEditedBy'
5324
                            ).' <a href='.$userinfo['profile_url'].'>'.
5325
                            Display::tag(
5326
                                'span',
5327
                                $userinfo['complete_name_with_username']
5328
                            ).
5329
                            get_lang('ThisPageisBeginEditedTryLater').' '.date(
5330
                                "i",
5331
                                $rest_time
5332
                            ).' '.get_lang('MinMinutes');
5333
                        Display::addFlash(
5334
                            Display::return_message(
5335
                                $is_being_edited,
5336
                                'normal',
5337
                                false
5338
                            )
5339
                        );
5340
                    } else {
5341
                        Display::addFlash(
5342
                            Display::return_message(
5343
                                self::restore_wikipage(
5344
                                    $current_row['page_id'],
5345
                                    $current_row['reflink'],
5346
                                    $current_row['title'],
5347
                                    $current_row['content'],
5348
                                    $current_row['group_id'],
5349
                                    $current_row['assignment'],
5350
                                    $current_row['progress'],
5351
                                    $current_row['version'],
5352
                                    $last_row['version'],
5353
                                    $current_row['linksto']
5354
                                ).': '
5355
                                .Display::url(
5356
                                    api_htmlentities($last_row['title']),
5357
                                    $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($last_row['reflink'])])
5358
                                ),
5359
                                'confirmation',
5360
                                false
5361
                            )
5362
                        );
5363
                    }
5364
                }
5365
            }
5366
        }
5367
    }
5368
5369
    /**
5370
     * @param int|bool $wikiId
5371
     */
5372
    public function setWikiData($wikiId)
5373
    {
5374
        $this->wikiData = self::getWikiDataFromDb($wikiId);
5375
    }
5376
5377
    /**
5378
     * @return array
5379
     */
5380
    public function getWikiData()
5381
    {
5382
        return $this->wikiData;
5383
    }
5384
5385
    /**
5386
     * Check last version.
5387
     *
5388
     * @param int $view
5389
     */
5390
    public function checkLastVersion($view)
5391
    {
5392
        $tbl_wiki = $this->tbl_wiki;
5393
        $condition_session = $this->condition_session;
5394
        $groupfilter = $this->groupfilter;
5395
        $page = $this->page;
5396
5397
        if (empty($view)) {
5398
            return false;
5399
        }
5400
5401
        $current_row = $this->getWikiData();
5402
        $sql = 'SELECT * FROM '.$tbl_wiki.'
5403
                WHERE
5404
                    c_id = '.$this->course_id.' AND
5405
                    reflink = "'.Database::escape_string($page).'" AND
5406
                    '.$groupfilter.$condition_session.'
5407
                ORDER BY id DESC'; //last version
5408
        $result = Database::query($sql);
5409
        $last_row = Database::fetch_array($result);
5410
5411
        if ($view < $last_row['id']) {
5412
            $message = '<center>'.get_lang('NoAreSeeingTheLastVersion').'<br />'
5413
                .get_lang("Version").' ('
5414
                .Display::url(
5415
                    $current_row['version'],
5416
                    $this->url.'&'.http_build_query([
5417
                        'action' => 'showpage',
5418
                        'title' => api_htmlentities($current_row['reflink']),
5419
                        'view' => (int) $_GET['view'],
5420
                    ]),
5421
                    ['title' => get_lang('CurrentVersion')]
5422
                )
5423
                .' / '
5424
                .Display::url(
5425
                    $last_row['version'],
5426
                    $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($last_row['reflink'])]),
5427
                    ['title' => get_lang('LastVersion')]
5428
                )
5429
                .')<br>'.get_lang('ConvertToLastVersion').': '
5430
                .Display::url(
5431
                    get_lang("Restore"),
5432
                    $this->url.'&'.http_build_query([
5433
                        'action' => 'restorepage',
5434
                        'title' => api_htmlentities($last_row['reflink']),
5435
                        'view' => (int) $_GET['view'],
5436
                    ])
5437
                )
5438
                .'</center>'
5439
            ;
5440
            echo Display::return_message($message, 'warning', false);
5441
        }
5442
    }
5443
5444
    /**
5445
     *  Get most linked pages.
5446
     */
5447
    public function getMostLinked()
5448
    {
5449
        $tbl_wiki = $this->tbl_wiki;
5450
        $groupfilter = $this->groupfilter;
5451
        $condition_session = $this->condition_session;
5452
5453
        echo '<div class="actions">'.get_lang('MostLinkedPages').'</div>';
5454
        $pages = [];
5455
        $linked = [];
5456
5457
        // Get name pages
5458
        $sql = 'SELECT * FROM '.$tbl_wiki.'
5459
                WHERE  c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.'
5460
                GROUP BY reflink
5461
                ORDER BY reflink ASC';
5462
        $allpages = Database::query($sql);
5463
        while ($row = Database::fetch_array($allpages)) {
5464
            if ($row['reflink'] == 'index') {
5465
                $row['reflink'] = str_replace(
5466
                    ' ',
5467
                    '_',
5468
                    get_lang('DefaultTitle')
5469
                );
5470
            }
5471
            $pages[] = $row['reflink'];
5472
        }
5473
5474
        // Get name refs in last pages
5475
        $sql = 'SELECT *
5476
                FROM '.$tbl_wiki.' s1
5477
                WHERE s1.c_id = '.$this->course_id.' AND id=(
5478
                    SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
5479
                    WHERE
5480
                        s2.c_id = '.$this->course_id.' AND
5481
                        s1.reflink = s2.reflink AND
5482
                        '.$groupfilter.$condition_session.'
5483
                )';
5484
5485
        $allpages = Database::query($sql);
5486
5487
        while ($row = Database::fetch_array($allpages)) {
5488
            //remove self reference
5489
            $row['linksto'] = str_replace(
5490
                $row["reflink"],
5491
                " ",
5492
                trim($row["linksto"])
5493
            );
5494
            $refs = explode(" ", trim($row["linksto"]));
5495
5496
            // Find linksto into reflink. If found ->page is linked
5497
            foreach ($refs as $v) {
5498
                if (in_array($v, $pages)) {
5499
                    if (trim($v) != "") {
5500
                        $linked[] = $v;
5501
                    }
5502
                }
5503
            }
5504
        }
5505
5506
        $linked = array_unique($linked);
5507
        //make a unique list. TODO:delete this line and count how many for each page
5508
        //show table
5509
        $rows = [];
5510
        foreach ($linked as $linked_show) {
5511
            $row = [];
5512
            $row[] = Display::url(
5513
                str_replace('_', ' ', $linked_show),
5514
                $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => str_replace('_', ' ', $linked_show)])
5515
            );
5516
            $rows[] = $row;
5517
        }
5518
5519
        $table = new SortableTableFromArrayConfig(
5520
            $rows,
5521
            0,
5522
            10,
5523
            'LinkedPages_table',
5524
            '',
5525
            '',
5526
            'DESC'
5527
        );
5528
        $table->set_additional_parameters(
5529
            [
5530
                'cidReq' => $this->courseCode,
5531
                'gidReq' => $this->group_id,
5532
                'id_session' => $this->session_id,
5533
                'action' => Security::remove_XSS($this->action),
5534
            ]
5535
        );
5536
        $table->set_header(0, get_lang('Title'), true);
5537
        $table->display();
5538
    }
5539
5540
    /**
5541
     * Get orphan pages.
5542
     */
5543
    public function getOrphaned()
5544
    {
5545
        $tbl_wiki = $this->tbl_wiki;
5546
        $groupfilter = $this->groupfilter;
5547
        $condition_session = $this->condition_session;
5548
5549
        echo '<div class="actions">'.get_lang('OrphanedPages').'</div>';
5550
5551
        $pages = [];
5552
        $orphaned = [];
5553
5554
        //get name pages
5555
        $sql = 'SELECT * FROM '.$tbl_wiki.'
5556
                WHERE c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.'
5557
                GROUP BY reflink
5558
                ORDER BY reflink ASC';
5559
        $allpages = Database::query($sql);
5560
        while ($row = Database::fetch_array($allpages)) {
5561
            $pages[] = $row['reflink'];
5562
        }
5563
5564
        //get name refs in last pages and make a unique list
5565
        $sql = 'SELECT  *  FROM   '.$tbl_wiki.' s1
5566
                WHERE s1.c_id = '.$this->course_id.' AND id=(
5567
                SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
5568
                WHERE
5569
                    s2.c_id = '.$this->course_id.' AND
5570
                    s1.reflink = s2.reflink AND
5571
                    '.$groupfilter.$condition_session.'
5572
                )';
5573
        $allpages = Database::query($sql);
5574
        $array_refs_linked = [];
5575
        while ($row = Database::fetch_array($allpages)) {
5576
            $row['linksto'] = str_replace(
5577
                $row["reflink"],
5578
                " ",
5579
                trim($row["linksto"])
5580
            ); //remove self reference
5581
            $refs = explode(" ", trim($row["linksto"]));
5582
            foreach ($refs as $ref_linked) {
5583
                if ($ref_linked == str_replace(
5584
                        ' ',
5585
                        '_',
5586
                        get_lang('DefaultTitle')
5587
                    )) {
5588
                    $ref_linked = 'index';
5589
                }
5590
                $array_refs_linked[] = $ref_linked;
5591
            }
5592
        }
5593
5594
        $array_refs_linked = array_unique($array_refs_linked);
5595
5596
        //search each name of list linksto into list reflink
5597
        foreach ($pages as $v) {
5598
            if (!in_array($v, $array_refs_linked)) {
5599
                $orphaned[] = $v;
5600
            }
5601
        }
5602
        $rows = [];
5603
        foreach ($orphaned as $orphaned_show) {
5604
            // get visibility status and title
5605
            $sql = 'SELECT *
5606
                    FROM  '.$tbl_wiki.'
5607
		            WHERE
5608
		                c_id = '.$this->course_id.' AND
5609
		                '.$groupfilter.$condition_session.' AND
5610
		                reflink="'.Database::escape_string($orphaned_show).'"
5611
                    GROUP BY reflink';
5612
            $allpages = Database::query($sql);
5613
            while ($row = Database::fetch_array($allpages)) {
5614
                $orphaned_title = $row['title'];
5615
                $orphaned_visibility = $row['visibility'];
5616
                if ($row['assignment'] == 1) {
5617
                    $ShowAssignment = Display::return_icon(
5618
                        'wiki_assignment.png',
5619
                        '',
5620
                        '',
5621
                        ICON_SIZE_SMALL
5622
                    );
5623
                } elseif ($row['assignment'] == 2) {
5624
                    $ShowAssignment = Display::return_icon(
5625
                        'wiki_work.png',
5626
                        '',
5627
                        '',
5628
                        ICON_SIZE_SMALL
5629
                    );
5630
                } elseif ($row['assignment'] == 0) {
5631
                    $ShowAssignment = Display::return_icon(
5632
                        'px_transparent.gif'
5633
                    );
5634
                }
5635
            }
5636
5637
            if (!api_is_allowed_to_edit(false, true) || !api_is_platform_admin(
5638
                ) && $orphaned_visibility == 0) {
5639
                continue;
5640
            }
5641
5642
            //show table
5643
            $row = [];
5644
            $row[] = $ShowAssignment;
5645
            $row[] = Display::url(
5646
                api_htmlentities($orphaned_title),
5647
                $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($orphaned_show)])
5648
            );
5649
            $rows[] = $row;
5650
        }
5651
5652
        $table = new SortableTableFromArrayConfig(
5653
            $rows,
5654
            1,
5655
            10,
5656
            'OrphanedPages_table',
5657
            '',
5658
            '',
5659
            'DESC'
5660
        );
5661
        $table->set_additional_parameters(
5662
            [
5663
                'cidReq' => $this->courseCode,
5664
                'gidReq' => $this->group_id,
5665
                'id_session' => $this->session_id,
5666
                'action' => Security::remove_XSS($this->action),
5667
            ]
5668
        );
5669
        $table->set_header(
5670
            0,
5671
            get_lang('Type'),
5672
            true,
5673
            ['style' => 'width:30px;']
5674
        );
5675
        $table->set_header(1, get_lang('Title'), true);
5676
        $table->display();
5677
    }
5678
5679
    /**
5680
     * Get wanted pages.
5681
     */
5682
    public function getWantedPages()
5683
    {
5684
        $tbl_wiki = $this->tbl_wiki;
5685
        $groupfilter = $this->groupfilter;
5686
        $condition_session = $this->condition_session;
5687
5688
        echo '<div class="actions">'.get_lang('WantedPages').'</div>';
5689
        $pages = [];
5690
        $wanted = [];
5691
        //get name pages
5692
        $sql = 'SELECT * FROM '.$tbl_wiki.'
5693
                WHERE  c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.'
5694
                GROUP BY reflink
5695
                ORDER BY reflink ASC';
5696
        $allpages = Database::query($sql);
5697
5698
        while ($row = Database::fetch_array($allpages)) {
5699
            if ($row['reflink'] == 'index') {
5700
                $row['reflink'] = str_replace(
5701
                    ' ',
5702
                    '_',
5703
                    get_lang('DefaultTitle')
5704
                );
5705
            }
5706
            $pages[] = $row['reflink'];
5707
        }
5708
5709
        //get name refs in last pages
5710
        $sql = 'SELECT * FROM   '.$tbl_wiki.' s1
5711
                WHERE s1.c_id = '.$this->course_id.' AND id=(
5712
                    SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
5713
                    WHERE s2.c_id = '.$this->course_id.' AND s1.reflink = s2.reflink AND '.$groupfilter.$condition_session.'
5714
                )';
5715
5716
        $allpages = Database::query($sql);
5717
5718
        while ($row = Database::fetch_array($allpages)) {
5719
            $refs = explode(" ", trim($row["linksto"]));
5720
            // Find linksto into reflink. If not found ->page is wanted
5721
            foreach ($refs as $v) {
5722
                if (!in_array($v, $pages)) {
5723
                    if (trim($v) != "") {
5724
                        $wanted[] = $v;
5725
                    }
5726
                }
5727
            }
5728
        }
5729
5730
        $wanted = array_unique($wanted); //make a unique list
5731
5732
        //show table
5733
        $rows = [];
5734
        foreach ($wanted as $wanted_show) {
5735
            $row = [];
5736
            $wanted_show = Security::remove_XSS($wanted_show);
5737
            $row[] = Display::url(
5738
                str_replace('_', ' ', $wanted_show),
5739
                $this->url.'&'.http_build_query(['action' => 'addnew', 'title' => str_replace('_', ' ', $wanted_show)]),
5740
                ['class' => 'new_wiki_link']
5741
            );
5742
            $rows[] = $row;
5743
        }
5744
5745
        $table = new SortableTableFromArrayConfig(
5746
            $rows,
5747
            0,
5748
            10,
5749
            'WantedPages_table',
5750
            '',
5751
            '',
5752
            'DESC'
5753
        );
5754
        $table->set_additional_parameters(
5755
            [
5756
                'cidReq' => $this->courseCode,
5757
                'gidReq' => $this->group_id,
5758
                'id_session' => $this->session_id,
5759
                'action' => Security::remove_XSS($this->action),
5760
            ]
5761
        );
5762
        $table->set_header(0, get_lang('Title'), true);
5763
        $table->display();
5764
    }
5765
5766
    /**
5767
     * Most visited.
5768
     */
5769
    public function getMostVisited()
5770
    {
5771
        $tbl_wiki = $this->tbl_wiki;
5772
        $groupfilter = $this->groupfilter;
5773
        $condition_session = $this->condition_session;
5774
5775
        echo '<div class="actions">'.get_lang('MostVisitedPages').'</div>';
5776
5777
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin(
5778
            )) { //only by professors if page is hidden
5779
            $sql = 'SELECT *, SUM(hits) AS tsum FROM '.$tbl_wiki.'
5780
                    WHERE c_id = '.$this->course_id.' AND '.$groupfilter.$condition_session.'
5781
                    GROUP BY reflink';
5782
        } else {
5783
            $sql = 'SELECT *, SUM(hits) AS tsum FROM '.$tbl_wiki.'
5784
                    WHERE
5785
                        c_id = '.$this->course_id.' AND
5786
                        '.$groupfilter.$condition_session.' AND
5787
                        visibility=1
5788
                    GROUP BY reflink';
5789
        }
5790
5791
        $allpages = Database::query($sql);
5792
5793
        //show table
5794
        if (Database::num_rows($allpages) > 0) {
5795
            $rows = [];
5796
            while ($obj = Database::fetch_object($allpages)) {
5797
                //get type assignment icon
5798
                $ShowAssignment = '';
5799
                if ($obj->assignment == 1) {
5800
                    $ShowAssignment = Display::return_icon(
5801
                        'wiki_assignment.png',
5802
                        get_lang('AssignmentDesc'),
5803
                        '',
5804
                        ICON_SIZE_SMALL
5805
                    );
5806
                } elseif ($obj->assignment == 2) {
5807
                    $ShowAssignment = $ShowAssignment = Display::return_icon(
5808
                        'wiki_work.png',
5809
                        get_lang('AssignmentWork'),
5810
                        '',
5811
                        ICON_SIZE_SMALL
5812
                    );
5813
                } elseif ($obj->assignment == 0) {
5814
                    $ShowAssignment = Display::return_icon(
5815
                        'px_transparent.gif'
5816
                    );
5817
                }
5818
5819
                $row = [];
5820
                $row[] = $ShowAssignment;
5821
                $row[] = Display::url(
5822
                    api_htmlentities($obj->title),
5823
                    $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($obj->reflink)])
5824
                );
5825
                $row[] = $obj->tsum;
5826
                $rows[] = $row;
5827
            }
5828
5829
            $table = new SortableTableFromArrayConfig(
5830
                $rows,
5831
                2,
5832
                10,
5833
                'MostVisitedPages_table',
5834
                '',
5835
                '',
5836
                'DESC'
5837
            );
5838
            $table->set_additional_parameters(
5839
                [
5840
                    'cidReq' => $this->courseCode,
5841
                    'gidReq' => $this->group_id,
5842
                    'id_session' => $this->session_id,
5843
                    'action' => Security::remove_XSS($this->action),
5844
                ]
5845
            );
5846
            $table->set_header(
5847
                0,
5848
                get_lang('Type'),
5849
                true,
5850
                ['style' => 'width:30px;']
5851
            );
5852
            $table->set_header(1, get_lang('Title'), true);
5853
            $table->set_header(2, get_lang('Visits'), true);
5854
            $table->display();
5855
        }
5856
    }
5857
5858
    /**
5859
     * Get actions bar.
5860
     */
5861
    public function showActionBar()
5862
    {
5863
        $page = $this->page;
5864
        $actionsLeft = Display::url(
5865
            Display::return_icon('home.png', get_lang('Home'), [], ICON_SIZE_MEDIUM),
5866
            $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => 'index'])
5867
        );
5868
5869
        if (api_is_allowed_to_session_edit(false, true) && api_is_allowed_to_edit()) {
5870
            // menu add page
5871
            $actionsLeft .= '<a href="'.$this->url.'&action=addnew" '.self::is_active_navigation_tab('addnew').'>'
5872
                .Display::return_icon('new_document.png', get_lang('AddNew'), [], ICON_SIZE_MEDIUM).'</a>';
5873
        }
5874
5875
        if (
5876
            true === api_get_configuration_value('wiki_categories_enabled')
5877
            && (api_is_allowed_to_edit(false, true) || api_is_platform_admin())
5878
        ) {
5879
            $actionsLeft .= Display::url(
5880
                Display::return_icon('folder.png', get_lang('Categories'), [], ICON_SIZE_MEDIUM),
5881
                $this->url.'&action=category'
5882
            );
5883
5884
            // page action: enable or disable the adding of new pages
5885
            if (self::check_addnewpagelock() == 0) {
5886
                $protect_addnewpage = Display::return_icon(
5887
                    'off.png',
5888
                    get_lang('AddOptionProtected')
5889
                );
5890
                $lock_unlock_addnew = 'unlockaddnew';
5891
            } else {
5892
                $protect_addnewpage = Display::return_icon(
5893
                    'on.png',
5894
                    get_lang('AddOptionUnprotected')
5895
                );
5896
                $lock_unlock_addnew = 'lockaddnew';
5897
            }
5898
        }
5899
5900
        // menu find
5901
        $actionsLeft .= '<a href="'.$this->url.'&action=searchpages"'.self::is_active_navigation_tab('searchpages').'>'
5902
            .Display::return_icon('search.png', get_lang('SearchPages'), '', ICON_SIZE_MEDIUM).'</a>';
5903
        ///menu more
5904
        $actionsLeft .= '<a href="'.$this->url.'&action=more&title='.api_htmlentities(urlencode($page)).'" '
5905
            .self::is_active_navigation_tab('more').'>'
5906
            .Display::return_icon('statistics.png', get_lang('Statistics'), [], ICON_SIZE_MEDIUM).'</a>';
5907
5908
        // menu all pages
5909
        $actionsLeft .= '<a href="'.$this->url.'&action=allpages" '.self::is_active_navigation_tab('allpages').'>'
5910
            .Display::return_icon('list_badges.png', get_lang('AllPages'), [], ICON_SIZE_MEDIUM).'</a>';
5911
        // menu recent changes
5912
        $actionsLeft .= '<a href="'.$this->url.'&action=recentchanges" '.self::is_active_navigation_tab('recentchanges').'>'
5913
            .Display::return_icon('history.png', get_lang('RecentChanges'), [], ICON_SIZE_MEDIUM).'</a>';
5914
5915
        $frmSearch = new FormValidator('wiki_search', 'get', '', '', [], FormValidator::LAYOUT_INLINE);
5916
        $frmSearch->addText('search_term', get_lang('SearchTerm'), false);
5917
        $frmSearch->addHidden('cidReq', $this->courseCode);
5918
        $frmSearch->addHidden('id_session', $this->session_id);
5919
        $frmSearch->addHidden('gidReq', $this->group_id);
5920
        $frmSearch->addHidden('gradebook', '0');
5921
        $frmSearch->addHidden('origin', '');
5922
        $frmSearch->addHidden('action', 'searchpages');
5923
        $frmSearch->addButtonSearch(get_lang('Search'));
5924
5925
        $actionsRight = $frmSearch->returnForm();
5926
5927
        echo Display::toolbarAction('toolbar-wiki', [$actionsLeft, $actionsRight]);
5928
    }
5929
5930
    /**
5931
     * Showing warning.
5932
     */
5933
    public function deletePageWarning()
5934
    {
5935
        $page = $this->page;
5936
        $groupfilter = $this->groupfilter;
5937
        $condition_session = $this->condition_session;
5938
5939
        if (!$_GET['title']) {
5940
            Display::addFlash(
5941
                Display::return_message(
5942
                    get_lang('MustSelectPage'),
5943
                    'error',
5944
                    false
5945
                )
5946
            );
5947
5948
            return;
5949
        }
5950
5951
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
5952
            Display::addFlash(
5953
                '<div id="wikititle">'.get_lang('DeletePageHistory').'</div>'
5954
            );
5955
            if ($page == "index") {
5956
                Display::addFlash(
5957
                    Display::return_message(
5958
                        get_lang('WarningDeleteMainPage'),
5959
                        'warning',
5960
                        false
5961
                    )
5962
                );
5963
            }
5964
            $message = get_lang('ConfirmDeletePage')."
5965
                <a href=\"".$this->url."\">".get_lang("No")."</a>
5966
                <a href=\"".$this->url."&action=delete&title=".api_htmlentities(urlencode($page))."&delete=yes\">".
5967
                get_lang("Yes")."</a>";
5968
5969
            if (!isset($_GET['delete'])) {
5970
                Display::addFlash(
5971
                    Display::return_message($message, 'warning', false)
5972
                );
5973
            }
5974
5975
            if (isset($_GET['delete']) && $_GET['delete'] == 'yes') {
5976
                $result = self::deletePage(
5977
                    $page,
5978
                    $this->course_id,
5979
                    $groupfilter,
5980
                    $condition_session
5981
                );
5982
                if ($result) {
5983
                    Display::addFlash(
5984
                        Display::return_message(
5985
                            get_lang('WikiPageDeleted'),
5986
                            'confirmation',
5987
                            false
5988
                        )
5989
                    );
5990
                }
5991
            }
5992
        } else {
5993
            Display::addFlash(
5994
                Display::return_message(
5995
                    get_lang('OnlyAdminDeletePageWiki'),
5996
                    'normal',
5997
                    false
5998
                )
5999
            );
6000
        }
6001
    }
6002
6003
    /**
6004
     * Edit page.
6005
     */
6006
    public function editPage()
6007
    {
6008
        $tbl_wiki = $this->tbl_wiki;
6009
        $tbl_wiki_conf = $this->tbl_wiki_conf;
6010
        $condition_session = $this->condition_session;
6011
        $groupfilter = $this->groupfilter;
6012
        $page = $this->page;
6013
        $userId = api_get_user_id();
6014
6015
        if (0 != $this->session_id &&
6016
            api_is_allowed_to_session_edit(false, true) == false
6017
        ) {
6018
            api_not_allowed();
6019
        }
6020
6021
        $sql = 'SELECT *
6022
            FROM '.$tbl_wiki.' w INNER JOIN '.$tbl_wiki_conf.' c
6023
            ON  (w.c_id = c.c_id AND w.page_id = c.page_id)
6024
            WHERE
6025
                w.c_id = '.$this->course_id.' AND
6026
                w.reflink= "'.Database::escape_string($page).'" AND
6027
                w.'.$groupfilter.$condition_session.'
6028
            ORDER BY id DESC';
6029
        $result = Database::query($sql);
6030
        $row = Database::fetch_array($result);
6031
6032
        $PassEdit = false;
6033
        // Check if is a wiki group
6034
        if (!empty($this->group_id)) {
6035
            $groupInfo = GroupManager::get_group_properties($this->group_id);
6036
            //Only teacher, platform admin and group members can edit a wiki group
6037
            if (api_is_allowed_to_edit(false, true) ||
6038
                api_is_platform_admin() ||
6039
                GroupManager::is_user_in_group($userId, $groupInfo)
6040
            ) {
6041
                $PassEdit = true;
6042
            } else {
6043
                Display::addFlash(
6044
                    Display::return_message(
6045
                        get_lang('OnlyEditPagesGroupMembers')
6046
                    )
6047
                );
6048
            }
6049
        } else {
6050
            $PassEdit = true;
6051
        }
6052
6053
        $content = '<div class="text-center">'
6054
            .sprintf(get_lang('DefaultContent'), api_get_path(WEB_IMG_PATH))
6055
            .'</div>';
6056
        $title = get_lang('DefaultTitle');
6057
        $page_id = 0;
6058
6059
        $icon_assignment = '';
6060
6061
        // we do not need awhile loop since we are always displaying the last version
6062
        if ($row) {
6063
            if ($row['content'] == '' && $row['title'] == '' && $page == '') {
6064
                Display::addFlash(
6065
                    Display::return_message(get_lang('MustSelectPage'), 'error', false)
6066
                );
6067
6068
                return;
6069
            }
6070
6071
            $content = api_html_entity_decode($row['content']);
6072
            $title = api_html_entity_decode($row['title']);
6073
            $page_id = $row['page_id'];
6074
6075
            // Only teachers and platform admin can edit the index page.
6076
            // Only teachers and platform admin can edit an assignment teacher.
6077
            // And users in groups
6078
6079
            if (($row['reflink'] == 'index' || $row['reflink'] == '' || $row['assignment'] == 1)
6080
                && (!api_is_allowed_to_edit(false, true) && 0 == $this->group_id)
6081
                && !api_is_allowed_in_course()
6082
            ) {
6083
                Display::addFlash(
6084
                    Display::return_message(get_lang('OnlyEditPagesCourseManager'), 'error')
6085
                );
6086
6087
                return;
6088
            }
6089
6090
            // check if is an assignment
6091
            if ($row['assignment'] == 1) {
6092
                Display::addFlash(
6093
                    Display::return_message(get_lang('EditAssignmentWarning'))
6094
                );
6095
6096
                $icon_assignment = Display::return_icon('wiki_assignment.png', get_lang('AssignmentDescExtra'));
6097
            } elseif ($row['assignment'] == 2) {
6098
                $icon_assignment = Display::return_icon('wiki_work.png', get_lang('AssignmentWorkExtra'));
6099
                if (($userId == $row['user_id']) == false) {
6100
                    if (api_is_allowed_to_edit(
6101
                            false,
6102
                            true
6103
                        ) || api_is_platform_admin()) {
6104
                        $PassEdit = true;
6105
                    } else {
6106
                        Display::addFlash(
6107
                            Display::return_message(get_lang('LockByTeacher'), 'warning')
6108
                        );
6109
                        $PassEdit = false;
6110
                    }
6111
                } else {
6112
                    $PassEdit = true;
6113
                }
6114
            }
6115
6116
            if ($PassEdit) {
6117
                if ($row['editlock'] == 1 &&
6118
                    (api_is_allowed_to_edit(false, true) == false ||
6119
                        api_is_platform_admin() == false)
6120
                ) {
6121
                    Display::addFlash(
6122
                        Display::return_message(get_lang('PageLockedExtra'))
6123
                    );
6124
                }
6125
            }
6126
        }
6127
6128
        if ($PassEdit) {
6129
            //show editor if edit is allowed <<<<<
6130
            if ((!empty($row['id']) && $row['editlock'] != 1)
6131
                || api_is_allowed_to_edit(false, true) != false
6132
                && api_is_platform_admin() != false
6133
            ) {
6134
                // Check tasks
6135
                if (!empty($row['startdate_assig']) && time() <
6136
                    api_strtotime($row['startdate_assig'])
6137
                ) {
6138
                    $message = get_lang('TheTaskDoesNotBeginUntil').': '.api_get_local_time($row['startdate_assig']);
6139
6140
                    Display::addFlash(
6141
                        Display::return_message($message, 'warning')
6142
                    );
6143
6144
                    if (!api_is_allowed_to_edit(false, true)) {
6145
                        $this->redirectHome();
6146
                    }
6147
                }
6148
6149
                if (!empty($row['enddate_assig']) &&
6150
                    time() > strtotime($row['enddate_assig']) &&
6151
                    $row['delayedsubmit'] == 0
6152
                ) {
6153
                    $message = get_lang('TheDeadlineHasBeenCompleted').': '.api_get_local_time($row['enddate_assig']);
6154
                    Display::addFlash(
6155
                        Display::return_message($message, 'warning')
6156
                    );
6157
                    if (!api_is_allowed_to_edit(false, true)) {
6158
                        $this->redirectHome();
6159
                    }
6160
                }
6161
6162
                if (!empty($row['max_version']) && $row['version'] >= $row['max_version']) {
6163
                    $message = get_lang('HasReachedMaxiNumVersions');
6164
                    Display::addFlash(
6165
                        Display::return_message($message, 'warning')
6166
                    );
6167
                    if (!api_is_allowed_to_edit(false, true)) {
6168
                        $this->redirectHome();
6169
                    }
6170
                }
6171
6172
                if (!empty($row['max_text']) && $row['max_text'] <= self::word_count(
6173
                        $row['content']
6174
                    )) {
6175
                    $message = get_lang('HasReachedMaxNumWords');
6176
                    Display::addFlash(
6177
                        Display::return_message($message, 'warning')
6178
                    );
6179
                    if (!api_is_allowed_to_edit(false, true)) {
6180
                        $this->redirectHome();
6181
                    }
6182
                }
6183
6184
                if (!empty($row['task'])) {
6185
                    //previous change 0 by text
6186
                    $message_task_startdate = empty($row['startdate_assig'])
6187
                        ? api_get_local_time($row['startdate_assig'])
6188
                        : get_lang('No');
6189
6190
                    $message_task_enddate = empty($row['enddate_assig'])
6191
                        ? api_get_local_time($row['enddate_assig'])
6192
                        : get_lang('No');
6193
6194
                    $message_task_delayedsubmit = $row['delayedsubmit'] == 0 ? get_lang('No') : get_lang('Yes');
6195
6196
                    $message_task_max_version = $row['max_version'] == 0 ? get_lang('No') : $row['max_version'];
6197
6198
                    $message_task_max_text = $row['max_text'] == 0 ? get_lang('No') : $row['max_text'];
6199
6200
                    // Comp message
6201
                    $message_task = '<b>'.get_lang('DescriptionOfTheTask').'</b><p>'.$row['task'].'</p><hr>'
6202
                        .'<p>'.get_lang('StartDate').': '.$message_task_startdate.'</p>'
6203
                        .'<p>'.get_lang('EndDate').': '.$message_task_enddate
6204
                        .' ('.get_lang('AllowLaterSends').') '.$message_task_delayedsubmit.'</p>'
6205
                        .'<p>'.get_lang('OtherSettings').': '.get_lang('NMaxVersion').': '.$message_task_max_version
6206
                        .' '.get_lang('NMaxWords').': '.$message_task_max_text.'</p>';
6207
                    // Display message
6208
                    Display::addFlash(
6209
                        Display::return_message($message_task)
6210
                    );
6211
                }
6212
6213
                if (!empty($row['id'])) {
6214
                    $feedback_message = '';
6215
                    if ($row['progress'] == $row['fprogress1'] && !empty($row['fprogress1'])) {
6216
                        $feedback_message = '<b>'.get_lang('Feedback').'</b>'
6217
                            .'<p>'.api_htmlentities($row['feedback1']).'</p>';
6218
                    } elseif ($row['progress'] == $row['fprogress2'] && !empty($row['fprogress2'])) {
6219
                        $feedback_message = '<b>'.get_lang('Feedback').'</b>'
6220
                            .'<p>'.api_htmlentities($row['feedback2']).'</p>';
6221
                    } elseif ($row['progress'] == $row['fprogress3'] && !empty($row['fprogress3'])) {
6222
                        $feedback_message = '<b>'.get_lang('Feedback').'</b>'
6223
                            .'<p>'.api_htmlentities($row['feedback3']).'</p>';
6224
                    }
6225
6226
                    if (!empty($feedback_message)) {
6227
                        Display::addFlash(
6228
                            Display::return_message($feedback_message)
6229
                        );
6230
                    }
6231
                }
6232
6233
                // Previous checking for concurrent editions
6234
                if (!empty($row['id']) && $row['is_editing'] == 0) {
6235
                    Display::addFlash(
6236
                        Display::return_message(get_lang('WarningMaxEditingTime'))
6237
                    );
6238
                    $time_edit = api_get_utc_datetime();
6239
                    $sql = 'UPDATE '.$tbl_wiki.' SET
6240
                            is_editing = "'.$userId.'",
6241
                            time_edit = "'.$time_edit.'"
6242
                            WHERE c_id = '.$this->course_id.' AND id="'.$row['id'].'"';
6243
                    Database::query($sql);
6244
                } elseif (!empty($row['id']) && $row['is_editing'] != $userId) {
6245
                    $timestamp_edit = strtotime($row['time_edit']);
6246
                    $time_editing = time() - $timestamp_edit;
6247
                    $max_edit_time = 1200; // 20 minutes
6248
                    $rest_time = $max_edit_time - $time_editing;
6249
6250
                    $userinfo = api_get_user_info($row['is_editing']);
6251
                    if ($userinfo !== false) {
6252
                        $is_being_edited = get_lang('ThisPageisBeginEditedBy').PHP_EOL
6253
                            .UserManager::getUserProfileLink($userinfo).PHP_EOL
6254
                            .get_lang('ThisPageisBeginEditedTryLater').PHP_EOL
6255
                            .date("i", $rest_time).PHP_EOL
6256
                            .get_lang('MinMinutes');
6257
6258
                        Display::addFlash(
6259
                            Display::return_message($is_being_edited, 'normal', false)
6260
                        );
6261
                    }
6262
6263
                    $this->redirectHome();
6264
                }
6265
6266
                // Form.
6267
                $url = $this->url.'&'.http_build_query(['action' => 'edit', 'title' => $page]);
6268
                $form = new FormValidator('wiki', 'post', $url);
6269
                $form->addElement(
6270
                    'header',
6271
                    $icon_assignment.str_repeat('&nbsp;', 3).api_htmlentities($title)
6272
                );
6273
                self::setForm($form, !empty($row['id']) ? $row : []);
6274
                $form->addElement('hidden', 'title');
6275
                $form->addButtonSave(get_lang('Save'), 'SaveWikiChange');
6276
                $row['title'] = $title;
6277
                $row['page_id'] = $page_id;
6278
                $row['reflink'] = $page;
6279
                $row['content'] = $content;
6280
6281
                if (!empty($row['id']) && true === api_get_configuration_value('wiki_categories_enabled')) {
6282
                    $wiki = Database::getManager()->find(CWiki::class, $row['id']);
6283
6284
                    foreach ($wiki->getCategories() as $category) {
6285
                        $row['category'][] = $category->getId();
6286
                    }
6287
                }
6288
6289
                $form->setDefaults($row);
6290
                $form->display();
6291
6292
                // Saving a change
6293
                if ($form->validate()) {
6294
                    $versionFromSession = Session::read('_version');
6295
                    if (empty($_POST['title'])) {
6296
                        Display::addFlash(
6297
                            Display::return_message(
6298
                                get_lang("NoWikiPageTitle"),
6299
                                'error'
6300
                            )
6301
                        );
6302
                    } elseif (!self::double_post($_POST['wpost_id'])) {
6303
                        //double post
6304
                    } elseif ($_POST['version'] != '' && $versionFromSession != 0 && $_POST['version'] != $versionFromSession) {
6305
                        //prevent concurrent users and double version
6306
                        Display::addFlash(
6307
                            Display::return_message(
6308
                                get_lang("EditedByAnotherUser"),
6309
                                'error'
6310
                            )
6311
                        );
6312
                    } else {
6313
                        $returnMessage = self::save_wiki(
6314
                            $form->exportValues()
6315
                        );
6316
                        Display::addFlash(
6317
                            Display::return_message(
6318
                                $returnMessage,
6319
                                'confirmation'
6320
                            )
6321
                        );
6322
                    }
6323
                    $wikiData = self::getWikiData();
6324
                    $redirectUrl = $this->url.'&action=showpage&title='.$wikiData['reflink'];
6325
                    header('Location: '.$redirectUrl);
6326
                    exit;
6327
                }
6328
            }
6329
        }
6330
    }
6331
6332
    /**
6333
     * Get history.
6334
     */
6335
    public function getHistory()
6336
    {
6337
        $tbl_wiki = $this->tbl_wiki;
6338
        $condition_session = $this->condition_session;
6339
        $groupfilter = $this->groupfilter;
6340
        $page = $this->page;
6341
        $course_id = $this->course_id;
6342
        $session_id = $this->session_id;
6343
        $userId = api_get_user_id();
6344
6345
        if (!$_GET['title']) {
6346
            Display::addFlash(
6347
                Display::return_message(
6348
                    get_lang("MustSelectPage"),
6349
                    'error',
6350
                    false
6351
                )
6352
            );
6353
6354
            return;
6355
        }
6356
6357
        /* First, see the property visibility that is at the last register and
6358
        therefore we should select descending order.
6359
        But to give ownership to each record,
6360
        this is no longer necessary except for the title. TODO: check this*/
6361
6362
        $sql = 'SELECT * FROM '.$tbl_wiki.'
6363
                WHERE
6364
                    c_id = '.$this->course_id.' AND
6365
                    reflink="'.Database::escape_string($page).'" AND
6366
                    '.$groupfilter.$condition_session.'
6367
                ORDER BY id DESC';
6368
        $result = Database::query($sql);
6369
6370
        $KeyVisibility = null;
6371
        $KeyAssignment = null;
6372
        $KeyTitle = null;
6373
        $KeyUserId = null;
6374
        while ($row = Database::fetch_array($result)) {
6375
            $KeyVisibility = $row['visibility'];
6376
            $KeyAssignment = $row['assignment'];
6377
            $KeyTitle = $row['title'];
6378
            $KeyUserId = $row['user_id'];
6379
        }
6380
        $icon_assignment = null;
6381
        if ($KeyAssignment == 1) {
6382
            $icon_assignment = Display::return_icon(
6383
                'wiki_assignment.png',
6384
                get_lang('AssignmentDescExtra'),
6385
                '',
6386
                ICON_SIZE_SMALL
6387
            );
6388
        } elseif ($KeyAssignment == 2) {
6389
            $icon_assignment = Display::return_icon(
6390
                'wiki_work.png',
6391
                get_lang('AssignmentWorkExtra'),
6392
                '',
6393
                ICON_SIZE_SMALL
6394
            );
6395
        }
6396
6397
        // Second, show
6398
        //if the page is hidden and is a job only sees its author and professor
6399
        if ($KeyVisibility == 1 ||
6400
            api_is_allowed_to_edit(false, true) ||
6401
            api_is_platform_admin() ||
6402
            (
6403
                $KeyAssignment == 2 && $KeyVisibility == 0 &&
6404
                ($userId == $KeyUserId)
6405
            )
6406
        ) {
6407
            // We show the complete history
6408
            if (!isset($_POST['HistoryDifferences']) &&
6409
                !isset($_POST['HistoryDifferences2'])
6410
            ) {
6411
                $sql = 'SELECT * FROM '.$tbl_wiki.'
6412
                        WHERE
6413
                            c_id = '.$this->course_id.' AND
6414
                            reflink="'.Database::escape_string($page).'" AND
6415
                            '.$groupfilter.$condition_session.'
6416
                        ORDER BY id DESC';
6417
                $result = Database::query($sql);
6418
                $title = $_GET['title'];
6419
6420
                echo '<div id="wikititle">';
6421
                echo $icon_assignment.'&nbsp;&nbsp;&nbsp;'.api_htmlentities(
6422
                        $KeyTitle
6423
                    );
6424
                echo '</div>';
6425
6426
                $actionUrl = $this->url.'&'.http_build_query(['action' => 'history', 'title' => api_htmlentities($title)]);
6427
                echo '<form id="differences" method="POST" action="'.$actionUrl.'">';
6428
6429
                echo '<ul style="list-style-type: none;">';
6430
                echo '<br/>';
6431
                echo '<button class="search" type="submit" name="HistoryDifferences" value="HistoryDifferences">'.
6432
                    get_lang('ShowDifferences').' '.get_lang(
6433
                        'LinesDiff'
6434
                    ).'</button>';
6435
                echo '<button class="search" type="submit" name="HistoryDifferences2" value="HistoryDifferences2">'.
6436
                    get_lang('ShowDifferences').' '.get_lang(
6437
                        'WordsDiff'
6438
                    ).'</button>';
6439
                echo '<br/><br/>';
6440
6441
                $counter = 0;
6442
                $total_versions = Database::num_rows($result);
6443
6444
                while ($row = Database::fetch_array($result)) {
6445
                    $userinfo = api_get_user_info($row['user_id']);
6446
                    $username = api_htmlentities(
6447
                        sprintf(get_lang('LoginX'), $userinfo['username']),
6448
                        ENT_QUOTES
6449
                    );
6450
6451
                    echo '<li style="margin-bottom: 5px;">';
6452
                    ($counter == 0) ? $oldstyle = 'style="visibility: hidden;"' : $oldstyle = '';
6453
                    ($counter == 0) ? $newchecked = ' checked' : $newchecked = '';
6454
                    ($counter == $total_versions - 1) ? $newstyle = 'style="visibility: hidden;"' : $newstyle = '';
6455
                    ($counter == 1) ? $oldchecked = ' checked' : $oldchecked = '';
6456
                    echo '<input name="old" value="'.$row['id'].'" type="radio" '.$oldstyle.' '.$oldchecked.'/> ';
6457
                    echo '<input name="new" value="'.$row['id'].'" type="radio" '.$newstyle.' '.$newchecked.'/> ';
6458
                    echo '<a href="'.$this->url.'&action=showpage&title='.api_htmlentities(urlencode($page)).'&view='.$row['id'].'">';
6459
                    echo api_get_local_time($row['dtime']);
6460
                    echo '</a>';
6461
                    echo ' ('.get_lang('Version').' '.$row['version'].')';
6462
                    echo ' '.get_lang('By').' ';
6463
                    if ($userinfo !== false) {
6464
                        echo UserManager::getUserProfileLink($userinfo);
6465
                    } else {
6466
                        echo get_lang('Anonymous').' ('.api_htmlentities(
6467
                                $row['user_ip']
6468
                            ).')';
6469
                    }
6470
                    echo ' ( '.get_lang('Progress').': '.api_htmlentities(
6471
                            $row['progress']
6472
                        ).'%, ';
6473
                    $comment = $row['comment'];
6474
                    if (!empty($comment)) {
6475
                        $comment = api_substr($comment, 0, 100);
6476
                        if ($comment !== false) {
6477
                            $comment = api_htmlentities($comment);
6478
                            echo get_lang('Comments').': '.$comment;
6479
                            if (api_strlen($row['comment']) > 100) {
6480
                                echo '... ';
6481
                            }
6482
                        }
6483
                    } else {
6484
                        echo get_lang('Comments').':  ---';
6485
                    }
6486
                    echo ' ) </li>';
6487
                    $counter++;
6488
                } //end while
6489
6490
                echo '<br/>';
6491
                echo '<button class="search" type="submit" name="HistoryDifferences" value="HistoryDifferences">'.get_lang(
6492
                        'ShowDifferences'
6493
                    ).' '.get_lang('LinesDiff').'</button>';
6494
                echo '<button class="search" type="submit" name="HistoryDifferences2" value="HistoryDifferences2">'.get_lang(
6495
                        'ShowDifferences'
6496
                    ).' '.get_lang('WordsDiff').'</button>';
6497
                echo '</ul></form>';
6498
            } else { // We show the differences between two versions
6499
                $version_old = [];
6500
                if (isset($_POST['old'])) {
6501
                    $sql_old = "SELECT * FROM $tbl_wiki
6502
                                WHERE c_id = ".$this->course_id." AND id='".Database::escape_string(
6503
                            $_POST['old']
6504
                        )."'";
6505
                    $result_old = Database::query($sql_old);
6506
                    $version_old = Database::fetch_array($result_old);
6507
                }
6508
6509
                $sql_new = "SELECT * FROM $tbl_wiki
6510
                            WHERE
6511
                              c_id = ".$this->course_id." AND
6512
                              id = '".Database::escape_string($_POST['new'])."'";
6513
                $result_new = Database::query($sql_new);
6514
                $version_new = Database::fetch_array($result_new);
6515
                $oldTime = isset($version_old['dtime']) ? api_get_local_time($version_old['dtime']) : null;
6516
                $oldContent = isset($version_old['content']) ? $version_old['content'] : null;
6517
6518
                if (isset($_POST['HistoryDifferences'])) {
6519
                    include 'diff.inc.php';
6520
                    //title
6521
                    echo '<div id="wikititle">'.api_htmlentities(
6522
                            $version_new['title']
6523
                        ).'
6524
                            <font size="-2"><i>('.get_lang('DifferencesNew').'</i>
6525
                            <font style="background-color:#aaaaaa">'.api_get_local_time($version_new['dtime']).'</font>
6526
                            <i>'.get_lang('DifferencesOld').'</i>
6527
                            <font style="background-color:#aaaaaa">'.$oldTime.'</font>
6528
                ) '.get_lang('Legend').':  <span class="diffAdded" >'.get_lang(
6529
                            'WikiDiffAddedLine'
6530
                        ).'</span>
6531
                <span class="diffDeleted" >'.get_lang(
6532
                            'WikiDiffDeletedLine'
6533
                        ).'</span> <span class="diffMoved">'.get_lang(
6534
                            'WikiDiffMovedLine'
6535
                        ).'</span></font>
6536
                </div>';
6537
                }
6538
                if (isset($_POST['HistoryDifferences2'])) {
6539
                    //title
6540
                    echo '<div id="wikititle">'.api_htmlentities(
6541
                            $version_new['title']
6542
                        ).'
6543
                        <font size="-2"><i>('.get_lang(
6544
                            'DifferencesNew'
6545
                        ).'</i> <font style="background-color:#aaaaaa">'.api_get_local_time($version_new['dtime']).'</font>
6546
                        <i>'.get_lang(
6547
                            'DifferencesOld'
6548
                        ).'</i> <font style="background-color:#aaaaaa">'.$oldTime.'</font>)
6549
                        '.get_lang(
6550
                            'Legend'
6551
                        ).':  <span class="diffAddedTex" >'.get_lang(
6552
                            'WikiDiffAddedTex'
6553
                        ).'</span>
6554
                        <span class="diffDeletedTex" >'.get_lang(
6555
                            'WikiDiffDeletedTex'
6556
                        ).'</span></font></div>';
6557
                }
6558
6559
                if (isset($_POST['HistoryDifferences'])) {
6560
                    echo '<table>'.diff(
6561
                            $oldContent,
6562
                            $version_new['content'],
6563
                            true,
6564
                            'format_table_line'
6565
                        ).'</table>'; // format_line mode is better for words
6566
                    echo '<br />';
6567
                    echo '<strong>'.get_lang(
6568
                            'Legend'
6569
                        ).'</strong><div class="diff">'."\n";
6570
                    echo '<table><tr>';
6571
                    echo '<td>';
6572
                    echo '</td><td>';
6573
                    echo '<span class="diffEqual" >'.get_lang(
6574
                            'WikiDiffUnchangedLine'
6575
                        ).'</span><br />';
6576
                    echo '<span class="diffAdded" >'.get_lang(
6577
                            'WikiDiffAddedLine'
6578
                        ).'</span><br />';
6579
                    echo '<span class="diffDeleted" >'.get_lang(
6580
                            'WikiDiffDeletedLine'
6581
                        ).'</span><br />';
6582
                    echo '<span class="diffMoved" >'.get_lang(
6583
                            'WikiDiffMovedLine'
6584
                        ).'</span><br />';
6585
                    echo '</td>';
6586
                    echo '</tr></table>';
6587
                }
6588
6589
                if (isset($_POST['HistoryDifferences2'])) {
6590
                    $lines1 = [strip_tags($oldContent)]; //without <> tags
6591
                    $lines2 = [
6592
                        strip_tags(
6593
                            $version_new['content']
6594
                        ),
6595
                    ]; //without <> tags
6596
                    $diff = new Text_Diff($lines1, $lines2);
6597
                    $renderer = new Text_Diff_Renderer_inline();
6598
                    echo '<style>del{background:#fcc}ins{background:#cfc}</style>'.$renderer->render(
6599
                            $diff
6600
                        ); // Code inline
6601
                    echo '<br />';
6602
                    echo '<strong>'.get_lang(
6603
                            'Legend'
6604
                        ).'</strong><div class="diff">'."\n";
6605
                    echo '<table><tr>';
6606
                    echo '<td>';
6607
                    echo '</td><td>';
6608
                    echo '<span class="diffAddedTex" >'.get_lang(
6609
                            'WikiDiffAddedTex'
6610
                        ).'</span><br />';
6611
                    echo '<span class="diffDeletedTex" >'.get_lang(
6612
                            'WikiDiffDeletedTex'
6613
                        ).'</span><br />';
6614
                    echo '</td>';
6615
                    echo '</tr></table>';
6616
                }
6617
            }
6618
        }
6619
    }
6620
6621
    /**
6622
     * Get stat tables.
6623
     */
6624
    public function getStatsTable()
6625
    {
6626
        echo '<div class="actions">'.get_lang('More').'</div>';
6627
        echo '<table border="0">';
6628
        echo '  <tr>';
6629
        echo '    <td>';
6630
        echo '      <ul>';
6631
        //Submenu Most active users
6632
        echo '        <li><a href="'.$this->url.'&action=mactiveusers">'.get_lang('MostActiveUsers').'</a></li>';
6633
        //Submenu Most visited pages
6634
        echo '        <li><a href="'.$this->url.'&action=mvisited">'.get_lang('MostVisitedPages').'</a></li>';
6635
        //Submenu Most changed pages
6636
        echo '        <li><a href="'.$this->url.'&action=mostchanged">'.get_lang('MostChangedPages').'</a></li>';
6637
        echo '      </ul>';
6638
        echo '    </td>';
6639
        echo '    <td>';
6640
        echo '      <ul>';
6641
        // Submenu Orphaned pages
6642
        echo '        <li><a href="'.$this->url.'&action=orphaned">'.get_lang('OrphanedPages').'</a></li>';
6643
        // Submenu Wanted pages
6644
        echo '        <li><a href="'.$this->url.'&action=wanted">'.get_lang('WantedPages').'</a></li>';
6645
        // Submenu Most linked pages
6646
        echo '<li><a href="'.$this->url.'&action=mostlinked">'.get_lang('MostLinkedPages').'</a></li>';
6647
        echo '</ul>';
6648
        echo '</td>';
6649
        echo '<td style="vertical-align:top">';
6650
        echo '<ul>';
6651
        // Submenu Statistics
6652
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
6653
            echo '<li><a href="'.$this->url.'&action=statistics">'.get_lang('Statistics').'</a></li>';
6654
        }
6655
        echo '      </ul>';
6656
        echo '    </td>';
6657
        echo '  </tr>';
6658
        echo '</table>';
6659
    }
6660
6661
    /**
6662
     * Kind of controller.
6663
     */
6664
    public function handleAction(string $action)
6665
    {
6666
        $page = $this->page;
6667
        switch ($action) {
6668
            case 'export_to_pdf':
6669
                if (isset($_GET['wiki_id'])) {
6670
                    self::export_to_pdf($_GET['wiki_id'], $this->courseCode);
6671
                    break;
6672
                }
6673
                break;
6674
            case 'export2doc':
6675
                if (isset($_GET['wiki_id'])) {
6676
                    $export2doc = self::export2doc($_GET['wiki_id']);
6677
                    if ($export2doc) {
6678
                        Display::addFlash(
6679
                            Display::return_message(
6680
                                get_lang('ThePageHasBeenExportedToDocArea'),
6681
                                'confirmation',
6682
                                false
6683
                            )
6684
                        );
6685
                    }
6686
                }
6687
                break;
6688
            case 'restorepage':
6689
                self::restorePage();
6690
                break;
6691
            case 'more':
6692
                self::getStatsTable();
6693
                break;
6694
            case 'statistics':
6695
                self::getStats();
6696
                break;
6697
            case 'mactiveusers':
6698
                self::getActiveUsers($action);
6699
                break;
6700
            case 'usercontrib':
6701
                self::getUserContributions($_GET['user_id'], $action);
6702
                break;
6703
            case 'mostchanged':
6704
                $this->getMostChangedPages($action);
6705
                break;
6706
            case 'mvisited':
6707
                self::getMostVisited();
6708
                break;
6709
            case 'wanted':
6710
                $this->getWantedPages();
6711
                break;
6712
            case 'orphaned':
6713
                self::getOrphaned();
6714
                break;
6715
            case 'mostlinked':
6716
                self::getMostLinked();
6717
                break;
6718
            case 'delete':
6719
                self::deletePageWarning($page);
6720
                break;
6721
            case 'deletewiki':
6722
                $title = '<div class="actions">'.get_lang(
6723
                        'DeleteWiki'
6724
                    ).'</div>';
6725
                if (api_is_allowed_to_edit(
6726
                        false,
6727
                        true
6728
                    ) || api_is_platform_admin()) {
6729
                    $message = get_lang('ConfirmDeleteWiki');
6730
                    $message .= '<p>
6731
                        <a href="'.$this->url.'">'.get_lang(
6732
                            'No'
6733
                        ).'</a>
6734
                        &nbsp;&nbsp;|&nbsp;&nbsp;
6735
                        <a href="'.$this->url.'&action=deletewiki&delete=yes">'.
6736
                        get_lang('Yes').'</a>
6737
                    </p>';
6738
6739
                    if (!isset($_GET['delete'])) {
6740
                        Display::addFlash(
6741
                            $title.Display::return_message(
6742
                                $message,
6743
                                'warning',
6744
                                false
6745
                            )
6746
                        );
6747
                    }
6748
                } else {
6749
                    Display::addFlash(
6750
                        Display::return_message(
6751
                            get_lang("OnlyAdminDeleteWiki"),
6752
                            'normal',
6753
                            false
6754
                        )
6755
                    );
6756
                }
6757
6758
                if (api_is_allowed_to_edit(
6759
                        false,
6760
                        true
6761
                    ) || api_is_platform_admin()) {
6762
                    if (isset($_GET['delete']) && $_GET['delete'] == 'yes') {
6763
                        $return_message = self::delete_wiki();
6764
                        Display::addFlash(
6765
                            Display::return_message(
6766
                                $return_message,
6767
                                'confirmation',
6768
                                false
6769
                            )
6770
                        );
6771
                        $this->redirectHome();
6772
                    }
6773
                }
6774
                break;
6775
            case 'searchpages':
6776
                self::getSearchPages($action);
6777
                break;
6778
            case 'links':
6779
                self::getLinks($page);
6780
                break;
6781
            case 'addnew':
6782
                if (0 != $this->session_id && api_is_allowed_to_session_edit(false, true) == false) {
6783
                    api_not_allowed();
6784
                }
6785
                $groupInfo = GroupManager::get_group_properties($this->group_id);
6786
                echo '<div class="actions">'.get_lang('AddNew').'</div>';
6787
                echo '<br/>';
6788
                //first, check if page index was created. chektitle=false
6789
                if (self::checktitle('index')) {
6790
                    if (api_is_allowed_to_edit(false, true) ||
6791
                        api_is_platform_admin() ||
6792
                        GroupManager::is_user_in_group(
6793
                            api_get_user_id(),
6794
                            $groupInfo
6795
                        ) ||
6796
                        api_is_allowed_in_course()
6797
                    ) {
6798
                        Display::addFlash(
6799
                            Display::return_message(get_lang('GoAndEditMainPage'), 'normal', false)
6800
                        );
6801
                    } else {
6802
                        Display::addFlash(
6803
                            Display::return_message(get_lang('WikiStandBy'), 'normal', false)
6804
                        );
6805
                    }
6806
                } elseif (self::check_addnewpagelock() == 0
6807
                    && (
6808
                        api_is_allowed_to_edit(false, true) == false
6809
                        || api_is_platform_admin() == false
6810
                    )
6811
                ) {
6812
                    Display::addFlash(
6813
                        Display::return_message(get_lang('AddPagesLocked'), 'error', false)
6814
                    );
6815
                } else {
6816
                    $groupInfo = GroupManager::get_group_properties($this->group_id);
6817
                    if (api_is_allowed_to_edit(false, true) ||
6818
                        api_is_platform_admin() ||
6819
                        GroupManager::is_user_in_group(
6820
                            api_get_user_id(),
6821
                            $groupInfo
6822
                        ) ||
6823
                        $_GET['group_id'] == 0
6824
                    ) {
6825
                        self::display_new_wiki_form();
6826
                    } else {
6827
                        Display::addFlash(
6828
                            Display::return_message(get_lang('OnlyAddPagesGroupMembers'), 'normal', false)
6829
                        );
6830
                    }
6831
                }
6832
                break;
6833
            case 'show':
6834
            case 'showpage':
6835
                self::display_wiki_entry($page);
6836
                break;
6837
            case 'edit':
6838
                self::editPage();
6839
                break;
6840
            case 'history':
6841
                self::getHistory();
6842
                break;
6843
            case 'recentchanges':
6844
                self::recentChanges($page, $action);
6845
                break;
6846
            case 'allpages':
6847
                self::allPages($action);
6848
                break;
6849
            case 'discuss':
6850
                self::getDiscuss($page);
6851
                break;
6852
            case 'export_to_doc_file':
6853
                self::exportTo($_GET['id'], 'odt');
6854
                exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
6855
                break;
6856
            case 'category':
6857
                $this->addCategory();
6858
                break;
6859
            case 'delete_category':
6860
                $this->deleteCategory();
6861
                break;
6862
        }
6863
    }
6864
6865
    /**
6866
     * Redirect to home.
6867
     */
6868
    public function redirectHome()
6869
    {
6870
        header('Location: '.$this->url.'&action=showpage&title=index');
6871
        exit;
6872
    }
6873
6874
    /**
6875
     * Export wiki content in a ODF.
6876
     *
6877
     * @param int $id
6878
     * @param string int
6879
     *
6880
     * @return bool
6881
     */
6882
    public function exportTo($id, $format = 'doc')
6883
    {
6884
        $data = self::getWikiDataFromDb($id);
6885
6886
        if (isset($data['content']) && !empty($data['content'])) {
6887
            Export::htmlToOdt($data['content'], $data['reflink'], $format);
6888
        }
6889
6890
        return false;
6891
    }
6892
6893
    private function renderShowPage(string $contentHtml)
6894
    {
6895
        $wikiCategoriesEnabled = api_get_configuration_value('wiki_categories_enabled');
6896
6897
        if ($wikiCategoriesEnabled) {
6898
            $em = Database::getManager();
6899
            $categoryRepo = $em->getRepository(CWikiCategory::class);
6900
6901
            $course = api_get_course_entity();
6902
            $session = api_get_session_entity();
6903
6904
            $count = $categoryRepo->countByCourse($course, $session);
6905
            $tree = get_lang('NoCategories');
6906
6907
            if ($count) {
6908
                $tree = $categoryRepo->buildCourseTree(
6909
                    $course,
6910
                    $session,
6911
                    [
6912
                        'decorate' => true,
6913
                        'rootOpen' => '<ul class="fa-ul">',
6914
                        'nodeDecorator' => function ($node) {
6915
                            $prefix = '<span aria-hidden="true" class="fa fa-li fa-angle-right text-muted"></span>';
6916
6917
                            $urlParams = [
6918
                                'search_term' => '',
6919
                                'SubmitWikiSearch' => '',
6920
                                '_qf__wiki_search' => '',
6921
                                'action' => 'searchpages',
6922
                                'categories' => ['' => $node['id']],
6923
                            ];
6924
6925
                            return Display::url(
6926
                                $prefix.$node['name'],
6927
                                $this->url.'&'.http_build_query($urlParams)
6928
                            );
6929
                        },
6930
                    ]
6931
                );
6932
            }
6933
6934
            echo '<div class="row">';
6935
            echo '<aside class="col-sm-3">';
6936
            echo $count > 0 ? '<h4>'.get_lang('Categories').'</h4>' : '';
6937
            echo $tree;
6938
            echo "</aside>"; // .col-sm-3
6939
            echo '<div class="col-sm-9">';
6940
        }
6941
6942
        echo $contentHtml;
6943
6944
        if ($wikiCategoriesEnabled) {
6945
            echo "</div>"; // .col-sm-9
6946
            echo "</div>"; // .row
6947
        }
6948
    }
6949
6950
    private function returnCategoriesBlock(int $wikiId, string $tagStart = '<div>', string $tagEnd = '</div>'): string
6951
    {
6952
        if (true !== api_get_configuration_value('wiki_categories_enabled') || empty($wikiId)) {
6953
            return '';
6954
        }
6955
6956
        try {
6957
            $wiki = Database::getManager()->find(CWiki::class, $wikiId);
6958
        } catch (Exception $e) {
6959
            return '';
6960
        }
6961
6962
        $categoryLinks = array_map(
6963
            function (CWikiCategory $category) {
6964
                $urlParams = [
6965
                    'search_term' => isset($_GET['search_term']) ? Security::remove_XSS($_GET['search_term']) : '',
6966
                    'SubmitWikiSearch' => '',
6967
                    '_qf__wiki_search' => '',
6968
                    'action' => 'searchpages',
6969
                    'categories' => ['' => $category->getId()],
6970
                ];
6971
6972
                return Display::url(
6973
                    $category->getName(),
6974
                    $this->url.'&'.http_build_query($urlParams)
6975
                );
6976
            },
6977
            $wiki->getCategories()->getValues()
6978
        );
6979
6980
        return $tagStart.implode(', ', $categoryLinks).$tagEnd;
6981
    }
6982
6983
    private function gelAllPagesQuery(
6984
        $onlyCount = false,
6985
        $from = 0,
6986
        $numberOfItems = 10,
6987
        $column = 0,
6988
        $direction = 'ASC'
6989
    ): ?Statement {
6990
        $tblWiki = $this->tbl_wiki;
6991
6992
        $fields = $onlyCount
6993
            ? 'COUNT(s1.iid) AS nbr'
6994
            : 's1.assignment col0, s1.title col1, s1.user_id col2, s1.dtime col3, s1.reflink, s1.user_ip, s1.iid';
6995
6996
        $query = 'SELECT '.$fields.' FROM '.$tblWiki.' s1 WHERE s1.c_id = '.$this->course_id.' ';
6997
6998
        if (!api_is_allowed_to_edit(false, true) && !api_is_platform_admin()) {
6999
            // warning don't use group by reflink because does not return the last version
7000
            $query .= 'AND visibility = 1 ';
7001
        }
7002
7003
        $query .= 'AND id = (
7004
            SELECT MAX(s2.id) FROM '.$tblWiki.' s2
7005
            WHERE s2.c_id = '.$this->course_id.'
7006
                AND s1.reflink = s2.reflink
7007
                AND '.$this->groupfilter.'
7008
                AND session_id = '.$this->session_id.'
7009
        ) ';
7010
7011
        if (!$onlyCount) {
7012
            $query .= "ORDER BY col$column $direction LIMIT $from, $numberOfItems";
7013
        }
7014
7015
        return Database::query($query);
7016
    }
7017
7018
    private function deleteCategory()
7019
    {
7020
        if (!api_is_allowed_to_edit(false, true) && !api_is_platform_admin()) {
7021
            api_not_allowed(true);
7022
        }
7023
7024
        if (true !== api_get_configuration_value('wiki_categories_enabled')) {
7025
            api_not_allowed(true);
7026
        }
7027
7028
        $em = Database::getManager();
7029
7030
        $category = null;
7031
7032
        if (isset($_GET['id'])) {
7033
            $category = $em->find(CWikiCategory::class, $_GET['id']);
7034
7035
            if (!$category) {
7036
                api_not_allowed(true);
7037
            }
7038
        }
7039
7040
        $em->remove($category);
7041
        $em->flush();
7042
7043
        Display::addFlash(
7044
            Display::return_message(get_lang('CategoryDeleted'), 'success')
7045
        );
7046
7047
        header('Location: '.$this->url.'&action=category');
7048
        exit;
7049
    }
7050
7051
    private function addCategory()
7052
    {
7053
        if (!api_is_allowed_to_edit(false, true) && !api_is_platform_admin()) {
7054
            api_not_allowed(true);
7055
        }
7056
7057
        if (true !== api_get_configuration_value('wiki_categories_enabled')) {
7058
            api_not_allowed(true);
7059
        }
7060
7061
        $categoryRepo = Database::getManager()->getRepository(CWikiCategory::class);
7062
7063
        $categoryToEdit = null;
7064
7065
        if (isset($_GET['id'])) {
7066
            $categoryToEdit = $categoryRepo->find($_GET['id']);
7067
7068
            if (!$categoryToEdit) {
7069
                api_not_allowed(true);
7070
            }
7071
        }
7072
7073
        $course = api_get_course_entity();
7074
        $session = api_get_session_entity();
7075
7076
        if ($categoryToEdit
7077
            && ($course !== $categoryToEdit->getCourse() || $session !== $categoryToEdit->getSession())
7078
        ) {
7079
            api_not_allowed(true);
7080
        }
7081
7082
        $iconEdit = Display::return_icon('edit.png', get_lang('Edit'));
7083
        $iconDelete = Display::return_icon('delete.png', get_lang('Delete'));
7084
7085
        $categories = $categoryRepo->findByCourse($course, $session);
7086
        $categoryList = array_map(
7087
            function (CWikiCategory $category) use ($iconEdit, $iconDelete) {
7088
                $actions = [];
7089
                $actions[] = Display::url(
7090
                    $iconEdit,
7091
                    $this->url.'&'.http_build_query(['action' => 'category', 'id' => $category->getId()])
7092
                );
7093
                $actions[] = Display::url(
7094
                    $iconDelete,
7095
                    $this->url.'&'.http_build_query(['action' => 'delete_category', 'id' => $category->getId()])
7096
                );
7097
7098
                return [
7099
                    $category->getNodeName(),
7100
                    implode(PHP_EOL, $actions),
7101
                ];
7102
            },
7103
            $categories
7104
        );
7105
7106
        $table = new SortableTableFromArray($categoryList);
7107
        $table->set_header(0, get_lang('Name'), false);
7108
        $table->set_header(1, get_lang('Actions'), false, ['class' => 'text-right'], ['class' => 'text-right']);
7109
7110
        $form = $this->createCategoryForm($categoryToEdit);
7111
        $form->display();
7112
        echo '<hr>';
7113
        $table->display();
7114
    }
7115
7116
    private function createCategoryForm(CWikiCategory $category = null): FormValidator
7117
    {
7118
        $em = Database::getManager();
7119
        $categoryRepo = $em->getRepository(CWikiCategory::class);
7120
7121
        $course = api_get_course_entity($this->courseInfo['real_id']);
7122
        $session = api_get_session_entity($this->session_id);
7123
7124
        $categories = $categoryRepo->findByCourse($course, $session);
7125
7126
        $formAction = $this->url.'&'.http_build_query([
7127
                'action' => 'category',
7128
                'id' => $category ? $category->getId() : null,
7129
            ]);
7130
7131
        $form = new FormValidator('category', 'post', $formAction);
7132
        $form->addHeader(get_lang('AddCategory'));
7133
        $form->addSelectFromCollection('parent', get_lang('Parent'), $categories, [], true, 'getNodeName');
7134
        $form->addText('name', get_lang('Name'));
7135
7136
        if ($category) {
7137
            $form->addButtonUpdate(get_lang('Update'));
7138
        } else {
7139
            $form->addButtonSave(get_lang('Save'));
7140
        }
7141
7142
        if ($form->validate()) {
7143
            $values = $form->exportValues();
7144
            $parent = $categoryRepo->find($values['parent']);
7145
7146
            if (!$category) {
7147
                $category = (new CWikiCategory())
7148
                    ->setCourse($course)
7149
                    ->setSession($session)
7150
                ;
7151
7152
                $em->persist($category);
7153
7154
                Display::addFlash(
7155
                    Display::return_message(get_lang('CategoryAdded'), 'success')
7156
                );
7157
            } else {
7158
                Display::addFlash(
7159
                    Display::return_message(get_lang('CategoryEdited'), 'success')
7160
                );
7161
            }
7162
7163
            $category
7164
                ->setName($values['name'])
7165
                ->setParent($parent)
7166
            ;
7167
7168
            $em->flush();
7169
7170
            header('Location: '.$this->url.'&action=category');
7171
            exit;
7172
        }
7173
7174
        if ($category) {
7175
            $form->setDefaults([
7176
                'parent' => $category->getParent() ? $category->getParent()->getId() : 0,
7177
                'name' => $category->getName(),
7178
            ]);
7179
        }
7180
7181
        return $form;
7182
    }
7183
7184
    private static function assignCategoriesToWiki(CWiki $wiki, array $categoriesIdList)
7185
    {
7186
        if (true !== api_get_configuration_value('wiki_categories_enabled')) {
7187
            return;
7188
        }
7189
7190
        $em = Database::getManager();
7191
7192
        foreach ($categoriesIdList as $categoryId) {
7193
            $category = $em->find(CWikiCategory::class, $categoryId);
7194
            $wiki->addCategory($category);
7195
        }
7196
7197
        $em->flush();
7198
    }
7199
}
7200