Passed
Pull Request — 1.11.x (#4515)
by Angel Fernando Quiroz
09:41 queued 32s
created

Wiki::gelAllPagesQuery()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 33
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 15
c 1
b 0
f 0
dl 0
loc 33
rs 9.4555
cc 5
nc 8
nop 5
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
        $groupId = api_get_group_id();
233
        //now doubles brackets
234
        $input_array = preg_split(
235
            "/(\[\[|\]\])/",
236
            $input,
237
            -1,
238
            PREG_SPLIT_DELIM_CAPTURE
239
        );
240
241
        foreach ($input_array as $key => $value) {
242
            //now doubles brackets
243
            if (isset($input_array[$key - 1]) &&
244
                $input_array[$key - 1] == '[[' && $input_array[$key + 1] == ']]'
245
            ) {
246
                // now full wikilink
247
                if (api_strpos($value, "|") !== false) {
248
                    $full_link_array = explode("|", $value);
249
                    $link = trim(strip_tags($full_link_array[0]));
250
                    $title = trim($full_link_array[1]);
251
                } else {
252
                    $link = trim(strip_tags($value));
253
                    $title = trim($value);
254
                }
255
256
                //if wikilink is homepage
257
                if ($link == 'index') {
258
                    $title = get_lang('DefaultTitle');
259
                }
260
                if ($link == get_lang('DefaultTitle')) {
261
                    $link = 'index';
262
                }
263
264
                // 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
265
                if (self::checktitle(
266
                    strtolower(str_replace(' ', '_', $link))
267
                )) {
268
                    $link = api_html_entity_decode($link);
269
                    $input_array[$key] = '<a href="'.api_get_path(WEB_PATH).'main/wiki/index.php?'.api_get_cidreq().'&action=addnew&title='.Security::remove_XSS($link).'&group_id='.$groupId.'" class="new_wiki_link">'.$title.'</a>';
270
                } else {
271
                    $input_array[$key] = '<a href="'.api_get_path(WEB_PATH).'main/wiki/index.php?'.api_get_cidreq().'&action=showpage&title='.urlencode(strtolower(str_replace(' ', '_', $link))).'&group_id='.$groupId.'" class="wiki_link">'.$title.'</a>';
272
                }
273
                unset($input_array[$key - 1]);
274
                unset($input_array[$key + 1]);
275
            }
276
        }
277
        $output = implode('', $input_array);
278
279
        return $output;
280
    }
281
282
    /**
283
     * This function saves a change in a wiki page.
284
     *
285
     * @author Patrick Cool <[email protected]>, Ghent University
286
     *
287
     * @param array $values
288
     *
289
     * @return string
290
     */
291
    public function save_wiki($values)
292
    {
293
        $tbl_wiki = $this->tbl_wiki;
294
        $tbl_wiki_conf = $this->tbl_wiki_conf;
295
296
        $_course = $this->courseInfo;
297
        $time = api_get_utc_datetime(null, false, true);
298
        $session_id = api_get_session_id();
299
        $groupId = api_get_group_id();
300
        $userId = api_get_user_id();
301
        $groupInfo = GroupManager::get_group_properties($groupId);
302
        $course_id = api_get_course_int_id();
303
304
        $_clean = [
305
            'task' => '',
306
            'feedback1' => '',
307
            'feedback2' => '',
308
            'feedback3' => '',
309
            'fprogress1' => '',
310
            'fprogress2' => '',
311
            'fprogress3' => '',
312
            'max_text' => 0,
313
            'max_version' => 0,
314
            'delayedsubmit' => '',
315
            'assignment' => 0,
316
        ];
317
318
        $pageId = intval($values['page_id']);
319
320
        // NOTE: visibility, visibility_disc and ratinglock_disc changes
321
        // are not made here, but through the interce buttons
322
323
        // cleaning the variables
324
        if (api_get_setting('htmlpurifier_wiki') == 'true') {
325
            //$purifier = new HTMLPurifier();
326
            $values['content'] = Security::remove_XSS($values['content']);
327
        }
328
        $version = intval($values['version']) + 1;
329
        $linkTo = self::links_to($values['content']); //and check links content
330
331
        //cleaning config variables
332
        if (!empty($values['task'])) {
333
            $_clean['task'] = $values['task'];
334
        }
335
336
        if (!empty($values['feedback1']) ||
337
            !empty($values['feedback2']) ||
338
            !empty($values['feedback3'])
339
        ) {
340
            $_clean['feedback1'] = $values['feedback1'];
341
            $_clean['feedback2'] = $values['feedback2'];
342
            $_clean['feedback3'] = $values['feedback3'];
343
            $_clean['fprogress1'] = $values['fprogress1'];
344
            $_clean['fprogress2'] = $values['fprogress2'];
345
            $_clean['fprogress3'] = $values['fprogress3'];
346
        }
347
348
        if (isset($values['initstartdate']) && $values['initstartdate'] == 1) {
349
            $_clean['startdate_assig'] = $values['startdate_assig'];
350
        } else {
351
            $_clean['startdate_assig'] = null;
352
        }
353
354
        if (isset($values['initenddate']) && $values['initenddate'] == 1) {
355
            $_clean['enddate_assig'] = $values['enddate_assig'];
356
        } else {
357
            $_clean['enddate_assig'] = null;
358
        }
359
360
        if (isset($values['delayedsubmit'])) {
361
            $_clean['delayedsubmit'] = $values['delayedsubmit'];
362
        }
363
364
        if (!empty($values['max_text']) || !empty($values['max_version'])) {
365
            $_clean['max_text'] = $values['max_text'];
366
            $_clean['max_version'] = $values['max_version'];
367
        }
368
369
        $values['assignment'] = $values['assignment'] ?? 0;
370
        $values['page_id'] = $values['page_id'] ?? 0;
371
372
        $em = Database::getManager();
373
374
        $newWiki = (new CWiki())
375
            ->setCId($course_id)
376
            ->setAddlock(1)
377
            ->setVisibility(1)
378
            ->setVisibilityDisc(1)
379
            ->setAddlockDisc(1)
380
            ->setRatinglockDisc(1)
381
            ->setPageId($pageId)
382
            ->setReflink(trim($values['reflink']))
383
            ->setTitle(trim($values['title']))
384
            ->setContent($values['content'])
385
            ->setUserId($userId)
386
            ->setGroupId($groupId)
387
            ->setDtime($time)
388
            ->setAssignment($values['assignment'])
389
            ->setComment($values['comment'])
390
            ->setProgress($values['progress'])
391
            ->setVersion($version)
392
            ->setLinksto($linkTo)
393
            ->setUserIp(api_get_real_ip())
394
            ->setSessionId($session_id)
395
            ->setPageId($values['page_id'])
396
            ->setEditlock(0)
397
            ->setIsEditing(0)
398
            ->setTimeEdit($time)
399
            ->setTag('')
400
        ;
401
402
        $em->persist($newWiki);
403
        $em->flush();
404
405
        $id = $newWiki->getIid();
406
407
        if ($id > 0) {
408
            $sql = "UPDATE $tbl_wiki SET id = iid WHERE iid = $id";
409
            Database::query($sql);
410
411
            // insert into item_property
412
            api_item_property_update(
413
                $_course,
414
                TOOL_WIKI,
415
                $id,
416
                'WikiAdded',
417
                $userId,
418
                $groupInfo
419
            );
420
421
            if ($values['page_id'] == 0) {
422
                $sql = 'UPDATE '.$tbl_wiki.' SET page_id="'.$id.'"
423
                        WHERE c_id = '.$course_id.' AND iid ="'.$id.'"';
424
                Database::query($sql);
425
            }
426
427
            self::assignCategoriesToWiki($newWiki, $values['category'] ?? []);
428
        }
429
430
        // Update wiki config
431
        if ($values['reflink'] == 'index' && $version == 1) {
432
            $params = [
433
                'c_id' => $course_id,
434
                'page_id' => $id,
435
                'task' => $_clean['task'],
436
                'feedback1' => $_clean['feedback1'],
437
                'feedback2' => $_clean['feedback2'],
438
                'feedback3' => $_clean['feedback3'],
439
                'fprogress1' => $_clean['fprogress1'],
440
                'fprogress2' => $_clean['fprogress2'],
441
                'fprogress3' => $_clean['fprogress3'],
442
                'max_text' => intval($_clean['max_text']),
443
                'max_version' => intval($_clean['max_version']),
444
                'startdate_assig' => $_clean['startdate_assig'],
445
                'enddate_assig' => $_clean['enddate_assig'],
446
                'delayedsubmit' => $_clean['delayedsubmit'],
447
            ];
448
            Database::insert($tbl_wiki_conf, $params);
449
        } else {
450
            $params = [
451
                'task' => $_clean['task'],
452
                'feedback1' => $_clean['feedback1'],
453
                'feedback2' => $_clean['feedback2'],
454
                'feedback3' => $_clean['feedback3'],
455
                'fprogress1' => $_clean['fprogress1'],
456
                'fprogress2' => $_clean['fprogress2'],
457
                'fprogress3' => $_clean['fprogress3'],
458
                'max_text' => intval($_clean['max_text']),
459
                'max_version' => intval($_clean['max_version']),
460
                'startdate_assig' => $_clean['startdate_assig'],
461
                'enddate_assig' => $_clean['enddate_assig'],
462
                'delayedsubmit' => $_clean['delayedsubmit'],
463
            ];
464
            Database::update(
465
                $tbl_wiki_conf,
466
                $params,
467
                ['page_id = ? AND c_id = ?' => [$pageId, $course_id]]
468
            );
469
        }
470
471
        api_item_property_update(
472
            $_course,
473
            'wiki',
474
            $id,
475
            'WikiAdded',
476
            $userId,
477
            $groupInfo
478
        );
479
        self::check_emailcue($_clean['reflink'], 'P', $time, $userId);
480
        $this->setWikiData($id);
481
482
        return get_lang('Saved');
483
    }
484
485
    /**
486
     * This function restore a wikipage.
487
     *
488
     * @author Juan Carlos Raña <[email protected]>
489
     *
490
     * @return string Message of success (to be printed on screen)
491
     */
492
    public function restore_wikipage(
493
        $r_page_id,
494
        $r_reflink,
495
        $r_title,
496
        $r_content,
497
        $r_group_id,
498
        $r_assignment,
499
        $r_progress,
500
        $c_version,
501
        $r_version,
502
        $r_linksto
503
    ) {
504
        $_course = $this->courseInfo;
505
        $r_user_id = api_get_user_id();
506
        $r_dtime = api_get_utc_datetime();
507
        $dTime = api_get_utc_datetime(null, false, true);
508
        $r_version = $r_version + 1;
509
        $r_comment = get_lang('RestoredFromVersion').': '.$c_version;
510
        $session_id = api_get_session_id();
511
        $course_id = api_get_course_int_id();
512
        $groupInfo = GroupManager::get_group_properties($r_group_id);
513
514
        $em = Database::getManager();
515
516
        $newWiki = (new CWiki())
517
            ->setCId($course_id)
518
            ->setPageId($r_page_id)
519
            ->setReflink($r_reflink)
520
            ->setTitle($r_title)
521
            ->setContent($r_content)
522
            ->setUserId($r_user_id)
523
            ->setGroupId($r_group_id)
524
            ->setDtime($dTime)
525
            ->setAssignment($r_assignment)
526
            ->setComment($r_comment)
527
            ->setProgress($r_progress)
528
            ->setVersion($r_version)
529
            ->setLinksto($r_linksto)
530
            ->setUserIp(api_get_real_ip())
531
            ->setSessionId($session_id)
532
            ->setAddlock(0)
533
            ->setEditlock(0)
534
            ->setVisibility(0)
535
            ->setAddlockDisc(0)
536
            ->setVisibilityDisc(0)
537
            ->setRatinglockDisc(0)
538
            ->setIsEditing(0)
539
            ->setTag('')
540
        ;
541
542
        $em->persist($newWiki);
543
        $em->flush();
544
545
        $newWiki->setId(
546
            $newWiki->getIid()
547
        );
548
549
        $em->flush();
550
551
        api_item_property_update(
552
            $_course,
553
            'wiki',
554
            $newWiki->getIid(),
555
            'WikiAdded',
556
            api_get_user_id(),
557
            $groupInfo
558
        );
559
        self::check_emailcue($r_reflink, 'P', $r_dtime, $r_user_id);
560
561
        return get_lang('PageRestored');
562
    }
563
564
    /**
565
     * This function delete a wiki.
566
     *
567
     * @author Juan Carlos Raña <[email protected]>
568
     *
569
     * @return string Message of success (to be printed)
570
     */
571
    public function delete_wiki()
572
    {
573
        $tbl_wiki = $this->tbl_wiki;
574
        $tbl_wiki_discuss = $this->tbl_wiki_discuss;
575
        $tbl_wiki_mailcue = $this->tbl_wiki_mailcue;
576
        $tbl_wiki_conf = $this->tbl_wiki_conf;
577
        $conditionSession = $this->condition_session;
578
        $groupFilter = $this->groupfilter;
579
        $course_id = $this->course_id;
580
581
        $sql = "SELECT page_id FROM $tbl_wiki
582
                WHERE c_id = $course_id AND $groupFilter $conditionSession
583
                ORDER BY id DESC";
584
585
        $result = Database::query($sql);
586
        $pageList = Database::store_result($result);
587
        if ($pageList) {
588
            foreach ($pageList as $pageData) {
589
                $pageId = $pageData['page_id'];
590
                $sql = "DELETE FROM $tbl_wiki_conf
591
                        WHERE c_id = $course_id AND page_id = $pageId";
592
                Database::query($sql);
593
594
                $sql = "DELETE FROM $tbl_wiki_discuss
595
                        WHERE c_id = $course_id AND publication_id = $pageId";
596
                Database::query($sql);
597
            }
598
        }
599
600
        $sql = "DELETE FROM $tbl_wiki_mailcue
601
                WHERE c_id = $course_id AND $groupFilter $conditionSession ";
602
        Database::query($sql);
603
604
        $sql = "DELETE FROM $tbl_wiki
605
                WHERE c_id = $course_id AND $groupFilter $conditionSession ";
606
        Database::query($sql);
607
608
        return get_lang('WikiDeleted');
609
    }
610
611
    /**
612
     * This function saves a new wiki page.
613
     *
614
     * @author Patrick Cool <[email protected]>, Ghent University
615
     *
616
     * @todo consider merging this with the function save_wiki into one single function.
617
     */
618
    public function save_new_wiki($values)
619
    {
620
        $tbl_wiki = $this->tbl_wiki;
621
        $tbl_wiki_conf = $this->tbl_wiki_conf;
622
        $assig_user_id = $this->assig_user_id;
623
        $_clean = [];
624
625
        // cleaning the variables
626
        $_clean['assignment'] = '';
627
        if (isset($values['assignment'])) {
628
            $_clean['assignment'] = $values['assignment'];
629
        }
630
631
        // session_id
632
        $session_id = api_get_session_id();
633
        // Unlike ordinary pages of pages of assignments.
634
        // Allow create a ordinary page although there is a assignment with the same name
635
        if ($_clean['assignment'] == 2 || $_clean['assignment'] == 1) {
636
            $page = str_replace(
637
                ' ',
638
                '_',
639
                $values['title']."_uass".$assig_user_id
640
            );
641
        } else {
642
            $page = str_replace(' ', '_', $values['title']);
643
        }
644
        $_clean['reflink'] = $page;
645
        $_clean['title'] = trim($values['title']);
646
        $_clean['content'] = $values['content'];
647
648
        if (api_get_setting('htmlpurifier_wiki') === 'true') {
649
            $purifier = new HTMLPurifier();
650
            $_clean['content'] = $purifier->purify($_clean['content']);
651
        }
652
653
        //re-check after strip_tags if the title is empty
654
        if (empty($_clean['title']) || empty($_clean['reflink'])) {
655
            return false;
656
        }
657
658
        if ($_clean['assignment'] == 2) {
659
            //config by default for individual assignment (students)
660
            //Identifies the user as a creator, not the teacher who created
661
            $_clean['user_id'] = intval($assig_user_id);
662
            $_clean['visibility'] = 0;
663
            $_clean['visibility_disc'] = 0;
664
            $_clean['ratinglock_disc'] = 0;
665
        } else {
666
            $_clean['user_id'] = api_get_user_id();
667
            $_clean['visibility'] = 1;
668
            $_clean['visibility_disc'] = 1;
669
            $_clean['ratinglock_disc'] = 1;
670
        }
671
672
        $_clean['comment'] = $values['comment'];
673
        $_clean['progress'] = $values['progress'];
674
        $_clean['version'] = 1;
675
676
        $groupId = api_get_group_id();
677
        $groupInfo = GroupManager::get_group_properties($groupId);
678
679
        //check wikilinks
680
        $_clean['linksto'] = self::links_to($_clean['content']);
681
682
        // cleaning config variables
683
        $_clean['task'] = $values['task'] ?? '';
684
        $_clean['feedback1'] = $values['feedback1'] ?? '';
685
        $_clean['feedback2'] = $values['feedback2'] ?? '';
686
        $_clean['feedback3'] = $values['feedback3'] ?? '';
687
        $_clean['fprogress1'] = $values['fprogress1'] ?? '';
688
        $_clean['fprogress2'] = $values['fprogress2'] ?? '';
689
        $_clean['fprogress3'] = $values['fprogress3'] ?? '';
690
691
        if (isset($values['initstartdate']) && $values['initstartdate'] == 1) {
692
            $_clean['startdate_assig'] = $values['startdate_assig'];
693
        } else {
694
            $_clean['startdate_assig'] = null;
695
        }
696
697
        if (isset($values['initenddate']) && $values['initenddate'] == 1) {
698
            $_clean['enddate_assig'] = $values['enddate_assig'];
699
        } else {
700
            $_clean['enddate_assig'] = null;
701
        }
702
703
        $_clean['delayedsubmit'] = $values['delayedsubmit'] ?? '';
704
        $_clean['max_text'] = $values['max_text'] ?? '';
705
        $_clean['max_version'] = $values['max_version'] ?? '';
706
707
        $course_id = api_get_course_int_id();
708
709
        // Filter no _uass
710
        if (api_strtoupper(trim($values['title'])) === 'INDEX') {
711
            Display::addFlash(
712
                Display::return_message(
713
                    get_lang('GoAndEditMainPage'),
714
                    'warning',
715
                    false
716
                )
717
            );
718
        } else {
719
            $var = $_clean['reflink'];
720
            $group_id = intval($_GET['group_id']);
721
            if (!self::checktitle($var)) {
722
                return get_lang('WikiPageTitleExist').
723
                    '<a href="index.php?action=edit&title='.$var.'&group_id='.$group_id.'">'.
724
                    $values['title'].'</a>';
725
            } else {
726
                $em = Database::getManager();
727
                $dtime = api_get_utc_datetime(null, false, true);
728
729
                $newWiki = (new CWiki())
730
                    ->setCId($course_id)
731
                    ->setReflink($_clean['reflink'])
732
                    ->setTitle($_clean['title'])
733
                    ->setContent($_clean['content'])
734
                    ->setUserId($_clean['user_id'])
735
                    ->setGroupId($groupId)
736
                    ->setDtime($dtime)
737
                    ->setVisibility($_clean['visibility'])
738
                    ->setVisibilityDisc($_clean['visibility_disc'])
739
                    ->setRatinglockDisc($_clean['ratinglock_disc'])
740
                    ->setAssignment($_clean['assignment'])
741
                    ->setComment($_clean['comment'])
742
                    ->setProgress($_clean['progress'])
743
                    ->setVersion($_clean['version'])
744
                    ->setLinksto($_clean['linksto'])
745
                    ->setUserIp(api_get_real_ip())
746
                    ->setSessionId($session_id)
747
                    ->setAddlock(0)
748
                    ->setAddlockDisc(1)
749
                    ->setEditlock(0)
750
                    ->setIsEditing(0)
751
                    ->setTag('')
752
                ;
753
754
                $em->persist($newWiki);
755
                $em->flush();
756
757
                $id = $newWiki->getIid();
758
759
                if ($id > 0) {
760
                    $sql = "UPDATE $tbl_wiki SET id = iid WHERE iid = $id";
761
                    Database::query($sql);
762
763
                    //insert into item_property
764
                    api_item_property_update(
765
                        api_get_course_info(),
766
                        TOOL_WIKI,
767
                        $id,
768
                        'WikiAdded',
769
                        api_get_user_id(),
770
                        $groupInfo
771
                    );
772
773
                    $sql = 'UPDATE '.$tbl_wiki.' SET page_id="'.$id.'"
774
                            WHERE c_id = '.$course_id.' AND id = "'.$id.'"';
775
                    Database::query($sql);
776
777
                    // insert wiki config
778
                    $params = [
779
                        'c_id' => $course_id,
780
                        'page_id' => $id,
781
                        'task' => $_clean['task'],
782
                        'feedback1' => $_clean['feedback1'],
783
                        'feedback2' => $_clean['feedback2'],
784
                        'feedback3' => $_clean['feedback3'],
785
                        'fprogress1' => $_clean['fprogress1'],
786
                        'fprogress2' => $_clean['fprogress2'],
787
                        'fprogress3' => $_clean['fprogress3'],
788
                        'max_text' => $_clean['max_text'],
789
                        'max_version' => $_clean['max_version'],
790
                        'startdate_assig' => $_clean['startdate_assig'],
791
                        'enddate_assig' => $_clean['enddate_assig'],
792
                        'delayedsubmit' => $_clean['delayedsubmit'],
793
                    ];
794
795
                    Database::insert($tbl_wiki_conf, $params);
796
797
                    self::assignCategoriesToWiki($newWiki, $values['category'] ?? []);
798
799
                    $this->setWikiData($id);
800
                    self::check_emailcue(0, 'A');
801
802
                    return get_lang('NewWikiSaved');
803
                }
804
            }
805
        }
806
    }
807
808
    public function setForm(FormValidator $form, array $row = [])
809
    {
810
        $toolBar = api_is_allowed_to_edit(null, true)
811
            ? [
812
                'ToolbarSet' => 'Wiki',
813
                'Width' => '100%',
814
                'Height' => '400',
815
            ]
816
            : [
817
                'ToolbarSet' => 'WikiStudent',
818
                'Width' => '100%',
819
                'Height' => '400',
820
                'UserStatus' => 'student',
821
            ];
822
823
        $form->addHtmlEditor(
824
            'content',
825
            get_lang('Content'),
826
            false,
827
            false,
828
            $toolBar
829
        );
830
        //$content
831
        $form->addElement('text', 'comment', get_lang('Comments'));
832
        $progress = ['', 10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
833
834
        $form->addElement(
835
            'select',
836
            'progress',
837
            get_lang('Progress'),
838
            $progress
839
        );
840
841
        if (true === api_get_configuration_value('wiki_categories_enabled')) {
842
            $em = Database::getManager();
843
844
            $categories = $em->getRepository(CWikiCategory::class)
845
                ->findByCourse(
846
                    api_get_course_entity(),
847
                    api_get_session_entity()
848
                );
849
850
            $form->addSelectFromCollection(
851
                'category',
852
                get_lang('Categories'),
853
                $categories,
854
                ['multiple' => 'multiple'],
855
                false,
856
                'getNodeName'
857
            );
858
        }
859
860
        if ((api_is_allowed_to_edit(false, true) ||
861
            api_is_platform_admin()) &&
862
            isset($row['reflink']) && $row['reflink'] != 'index'
863
        ) {
864
            $form->addElement(
865
                'advanced_settings',
866
                'advanced_params',
867
                get_lang('AdvancedParameters')
868
            );
869
            $form->addElement(
870
                'html',
871
                '<div id="advanced_params_options" style="display:none">'
872
            );
873
874
            $form->addHtmlEditor(
875
                'task',
876
                get_lang('DescriptionOfTheTask'),
877
                false,
878
                false,
879
                [
880
                    'ToolbarSet' => 'wiki_task',
881
                    'Width' => '100%',
882
                    'Height' => '200',
883
                ]
884
            );
885
886
            $form->addElement('label', null, get_lang('AddFeedback'));
887
            $form->addElement('textarea', 'feedback1', get_lang('Feedback1'));
888
            $form->addElement(
889
                'select',
890
                'fprogress1',
891
                get_lang('FProgress'),
892
                $progress
893
            );
894
895
            $form->addElement('textarea', 'feedback2', get_lang('Feedback2'));
896
            $form->addElement(
897
                'select',
898
                'fprogress2',
899
                get_lang('FProgress'),
900
                $progress
901
            );
902
903
            $form->addElement('textarea', 'feedback3', get_lang('Feedback3'));
904
            $form->addElement(
905
                'select',
906
                'fprogress3',
907
                get_lang('FProgress'),
908
                $progress
909
            );
910
911
            $form->addElement(
912
                'checkbox',
913
                'initstartdate',
914
                null,
915
                get_lang('StartDate'),
916
                ['id' => 'start_date_toggle']
917
            );
918
919
            $style = "display:block";
920
            $row['initstartdate'] = 1;
921
            if (empty($row['startdate_assig'])) {
922
                $style = "display:none";
923
                $row['initstartdate'] = null;
924
            }
925
926
            $form->addElement(
927
                'html',
928
                '<div id="start_date" style="'.$style.'">'
929
            );
930
            $form->addDatePicker('startdate_assig', '');
931
            $form->addElement('html', '</div>');
932
            $form->addElement(
933
                'checkbox',
934
                'initenddate',
935
                null,
936
                get_lang('EndDate'),
937
                ['id' => 'end_date_toggle']
938
            );
939
940
            $style = "display:block";
941
            $row['initenddate'] = 1;
942
            if (empty($row['enddate_assig'])) {
943
                $style = "display:none";
944
                $row['initenddate'] = null;
945
            }
946
947
            $form->addHtml('<div id="end_date" style="'.$style.'">');
948
            $form->addDatePicker('enddate_assig', '');
949
            $form->addHtml('</div>');
950
            $form->addElement(
951
                'checkbox',
952
                'delayedsubmit',
953
                null,
954
                get_lang('AllowLaterSends')
955
            );
956
            $form->addElement('text', 'max_text', get_lang('NMaxWords'));
957
            $form->addElement('text', 'max_version', get_lang('NMaxVersion'));
958
            $form->addElement(
959
                'checkbox',
960
                'assignment',
961
                null,
962
                get_lang('CreateAssignmentPage')
963
            );
964
            $form->addElement('html', '</div>');
965
        }
966
967
        $form->addElement('hidden', 'page_id');
968
        $form->addElement('hidden', 'reflink');
969
        $form->addElement('hidden', 'version');
970
        $form->addElement('hidden', 'wpost_id', api_get_unique_id());
971
    }
972
973
    /**
974
     * This function displays the form for adding a new wiki page.
975
     *
976
     * @author Patrick Cool <[email protected]>, Ghent University
977
     *
978
     * @return string html code
979
     */
980
    public function display_new_wiki_form()
981
    {
982
        $url = api_get_self().'?'.api_get_cidreq(
983
            ).'&action=addnew&group_id='.api_get_group_id();
984
        $form = new FormValidator('wiki_new', 'post', $url);
985
        $form->addElement('text', 'title', get_lang('Title'));
986
        $form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
987
        self::setForm($form);
988
        $title = isset($_GET['title']) ? Security::remove_XSS(
989
            $_GET['title']
990
        ) : '';
991
        $form->setDefaults(['title' => $title]);
992
        $form->addButtonSave(get_lang('Save'), 'SaveWikiNew');
993
        $form->display();
994
995
        if ($form->validate()) {
996
            $values = $form->exportValues();
997
            if (isset($values['startdate_assig']) &&
998
                isset($values['enddate_assig']) &&
999
                strtotime($values['startdate_assig']) > strtotime(
1000
                    $values['enddate_assig']
1001
                )
1002
            ) {
1003
                Display::addFlash(
1004
                    Display::return_message(
1005
                        get_lang("EndDateCannotBeBeforeTheStartDate"),
1006
                        'error',
1007
                        false
1008
                    )
1009
                );
1010
            } elseif (!self::double_post($_POST['wpost_id'])) {
1011
                //double post
1012
            } else {
1013
                if (isset($values['assignment']) && $values['assignment'] == 1) {
1014
                    self::auto_add_page_users($values);
1015
                }
1016
1017
                $return_message = $this->save_new_wiki($values);
1018
1019
                if ($return_message == false) {
1020
                    Display::addFlash(
1021
                        Display::return_message(
1022
                            get_lang('NoWikiPageTitle'),
1023
                            'error',
1024
                            false
1025
                        )
1026
                    );
1027
                } else {
1028
                    Display::addFlash(
1029
                        Display::return_message(
1030
                            $return_message,
1031
                            'confirmation',
1032
                            false
1033
                        )
1034
                    );
1035
                }
1036
1037
                $wikiData = self::getWikiData();
1038
                $redirectUrl = $this->url.'&action=showpage&title='.$wikiData['reflink'].'&'.api_get_cidreq();
1039
                header('Location: '.$redirectUrl);
1040
                exit;
1041
            }
1042
        }
1043
    }
1044
1045
    /**
1046
     * This function displays a wiki entry.
1047
     *
1048
     * @author Patrick Cool <[email protected]>, Ghent University
1049
     * @author Juan Carlos Raña Trabado
1050
     */
1051
    public function display_wiki_entry(string $newtitle)
1052
    {
1053
        $tblWiki = $this->tbl_wiki;
1054
        $tblWikiConf = $this->tbl_wiki_conf;
1055
        $conditionSession = $this->condition_session;
1056
        $groupfilter = $this->groupfilter;
1057
        $page = $this->page;
1058
1059
        $sessionId = api_get_session_id();
1060
        $courseId = api_get_course_int_id();
1061
1062
        if ($newtitle) {
1063
            $pageMIX = $newtitle; //display the page after it is created
1064
        } else {
1065
            $pageMIX = $page; //display current page
1066
        }
1067
1068
        $filter = null;
1069
        if (isset($_GET['view']) && $_GET['view']) {
1070
            $_clean['view'] = Database::escape_string($_GET['view']);
1071
            $filter = ' AND w.id="'.$_clean['view'].'"';
1072
        }
1073
1074
        // First, check page visibility in the first page version
1075
        $sql = 'SELECT * FROM '.$tblWiki.'
1076
                WHERE
1077
                    c_id = '.$courseId.' AND
1078
                    reflink = "'.Database::escape_string($pageMIX).'" AND
1079
                   '.$groupfilter.$conditionSession.'
1080
                ORDER BY id';
1081
        $result = Database::query($sql);
1082
        $row = Database::fetch_array($result, 'ASSOC');
1083
1084
        $KeyVisibility = null;
1085
        if ($KeyVisibility) {
1086
            $KeyVisibility = $row['visibility'];
1087
        }
1088
1089
        // second, show the last version
1090
        $sql = 'SELECT * FROM '.$tblWiki.' w
1091
            INNER JOIN '.$tblWikiConf.' wc
1092
            ON (wc.page_id = w.page_id AND wc.c_id = w.c_id)
1093
            WHERE
1094
                w.c_id = '.$courseId.' AND
1095
                w.reflink = "'.Database::escape_string($pageMIX).'" AND
1096
                w.session_id = '.$sessionId.' AND
1097
                w.'.$groupfilter.'  '.$filter.'
1098
            ORDER BY id DESC';
1099
1100
        $result = Database::query($sql);
1101
        // we do not need awhile loop since we are always displaying the last version
1102
        $row = Database::fetch_array($result, 'ASSOC');
1103
1104
        //log users access to wiki (page_id)
1105
        if (!empty($row['page_id'])) {
1106
            Event::addEvent(LOG_WIKI_ACCESS, LOG_WIKI_PAGE_ID, $row['page_id']);
1107
        }
1108
        //update visits
1109
        if ($row && $row['id']) {
1110
            $sql = 'UPDATE '.$tblWiki.' SET hits=(hits+1)
1111
                WHERE c_id = '.$courseId.' AND id='.$row['id'];
1112
            Database::query($sql);
1113
        }
1114
1115
        $groupInfo = GroupManager::get_group_properties(api_get_group_id());
1116
1117
        // if both are empty, and we are displaying the index page then we display the default text.
1118
        if (!$row || ($row['content'] == '' && $row['title'] == '' && $page == 'index')) {
1119
            if (api_is_allowed_to_edit(false, true) ||
1120
                api_is_platform_admin() ||
1121
                GroupManager::is_user_in_group(api_get_user_id(), $groupInfo) ||
1122
                api_is_allowed_in_course()
1123
            ) {
1124
                //Table structure for better export to pdf
1125
                $default_table_for_content_Start = '<div class="text-center">';
1126
                $default_table_for_content_End = '</div>';
1127
                $content = $default_table_for_content_Start.
1128
                    sprintf(
1129
                        get_lang('DefaultContent'),
1130
                        api_get_path(WEB_IMG_PATH)
1131
                    ).
1132
                    $default_table_for_content_End;
1133
                $title = get_lang('DefaultTitle');
1134
            } else {
1135
                Display::addFlash(
1136
                    Display::return_message(
1137
                        get_lang('WikiStandBy'),
1138
                        'normal',
1139
                        false
1140
                    )
1141
                );
1142
1143
                return;
1144
            }
1145
        } else {
1146
            if (true === api_get_configuration_value('wiki_html_strict_filtering')) {
1147
                $content = Security::remove_XSS($row['content'], COURSEMANAGERLOWSECURITY);
1148
            } else {
1149
                $content = Security::remove_XSS($row['content']);
1150
            }
1151
            $title = Security::remove_XSS($row['title']);
1152
        }
1153
1154
        if (self::wiki_exist($title)) {
1155
            //assignment mode: identify page type
1156
            $icon_assignment = null;
1157
            if ($row['assignment'] == 1) {
1158
                $icon_assignment = Display::return_icon('wiki_assignment.png', get_lang('AssignmentDescExtra'));
1159
            } elseif ($row['assignment'] == 2) {
1160
                $icon_assignment = Display::return_icon('wiki_work.png', get_lang('AssignmentWork'));
1161
            }
1162
1163
            // task mode
1164
            $icon_task = null;
1165
            if (!empty($row['task'])) {
1166
                $icon_task = Display::return_icon('wiki_task.png', get_lang('StandardTask'));
1167
            }
1168
1169
            $pageTitle = $icon_assignment.PHP_EOL.$icon_task.'&nbsp;'.api_htmlentities($title);
1170
        } else {
1171
            $pageTitle = api_htmlentities($title);
1172
        }
1173
1174
        // Show page. Show page to all users if isn't hide page. Mode assignments: if student is the author, can view
1175
        if ($KeyVisibility != "1"
1176
            && !api_is_allowed_to_edit(false, true)
1177
            && !api_is_platform_admin()
1178
            && ($row['assignment'] != 2 || $KeyVisibility != "0" || api_get_user_id() != $row['user_id'])
1179
            && !api_is_allowed_in_course()
1180
        ) {
1181
            return;
1182
        }
1183
1184
        $actionsLeft = '';
1185
        $actionsRight = '';
1186
        // menu edit page
1187
        $editLink = '<a href="index.php?'.api_get_cidreq().'&action=edit&title='.api_htmlentities(urlencode($page)).'"'
1188
            .self::is_active_navigation_tab('edit').'>'
1189
            .Display::return_icon('edit.png', get_lang('EditThisPage'), [], ICON_SIZE_MEDIUM).'</a>';
1190
1191
        if (api_is_allowed_to_edit(false, true)) {
1192
            $actionsLeft .= $editLink;
1193
        } else {
1194
            if ((api_is_allowed_in_course() ||
1195
                GroupManager::is_user_in_group(
1196
                    api_get_user_id(),
1197
                    $groupInfo
1198
                ))
1199
            ) {
1200
                $actionsLeft .= $editLink;
1201
            } else {
1202
                $actionsLeft .= '';
1203
            }
1204
        }
1205
1206
        $pageProgress = 0;
1207
        $pageScore = 0;
1208
1209
        if ($row && $row['id']) {
1210
            $pageProgress = $row['progress'] * 10;
1211
            $pageScore = $row['score'];
1212
1213
            $protect_page = null;
1214
            $lock_unlock_protect = null;
1215
            // page action: protecting (locking) the page
1216
            if (api_is_allowed_to_edit(false, true) ||
1217
                api_is_platform_admin()
1218
            ) {
1219
                if (self::check_protect_page() == 1) {
1220
                    $protect_page = Display::return_icon(
1221
                        'lock.png',
1222
                        get_lang('PageLockedExtra'),
1223
                        [],
1224
                        ICON_SIZE_MEDIUM
1225
                    );
1226
                    $lock_unlock_protect = 'unlock';
1227
                } else {
1228
                    $protect_page = Display::return_icon(
1229
                        'unlock.png',
1230
                        get_lang('PageUnlockedExtra'),
1231
                        [],
1232
                        ICON_SIZE_MEDIUM
1233
                    );
1234
                    $lock_unlock_protect = 'lock';
1235
                }
1236
            }
1237
1238
            $actionsRight .= '<a href="index.php?'.api_get_cidreq().'&action=showpage&actionpage='.$lock_unlock_protect
1239
                .'&title='.api_htmlentities(urlencode($page)).'">'.
1240
            $protect_page.'</a>';
1241
1242
            $visibility_page = null;
1243
            $lock_unlock_visibility = null;
1244
            //page action: visibility
1245
            if (api_is_allowed_to_edit(false, true) ||
1246
                api_is_platform_admin()
1247
            ) {
1248
                if (self::check_visibility_page() == 1) {
1249
                    $visibility_page = Display::return_icon(
1250
                        'visible.png',
1251
                        get_lang('ShowPageExtra'),
1252
                        [],
1253
                        ICON_SIZE_MEDIUM
1254
                    );
1255
                    $lock_unlock_visibility = 'invisible';
1256
                } else {
1257
                    $visibility_page = Display::return_icon(
1258
                        'invisible.png',
1259
                        get_lang('HidePageExtra'),
1260
                        [],
1261
                        ICON_SIZE_MEDIUM
1262
                    );
1263
                    $lock_unlock_visibility = 'visible';
1264
                }
1265
            }
1266
1267
            $actionsRight .= '<a href="index.php?'.api_get_cidreq().'&action=showpage&actionpage='
1268
                .$lock_unlock_visibility.'&title='.api_htmlentities(urlencode($page)).'">'.$visibility_page.'</a>';
1269
1270
            // Only available if row['id'] is set
1271
            //page action: notification
1272
            $lock_unlock_notify_page = '';
1273
1274
            if (api_is_allowed_to_session_edit()) {
1275
                if (self::check_notify_page($page) == 1) {
1276
                    $notify_page = Display::return_icon(
1277
                        'messagebox_info.png',
1278
                        get_lang('NotifyByEmail'),
1279
                        [],
1280
                        ICON_SIZE_MEDIUM
1281
                    );
1282
                    $lock_unlock_notify_page = 'unlocknotify';
1283
                } else {
1284
                    $notify_page = Display::return_icon(
1285
                        'mail.png',
1286
                        get_lang('CancelNotifyByEmail'),
1287
                        [],
1288
                        ICON_SIZE_MEDIUM
1289
                    );
1290
                    $lock_unlock_notify_page = 'locknotify';
1291
                }
1292
            }
1293
1294
            if (api_is_allowed_to_session_edit(false, true)
1295
                && api_is_allowed_to_edit()
1296
                || GroupManager::is_user_in_group(api_get_user_id(), $groupInfo)
1297
            ) {
1298
                // menu discuss page
1299
                $actionsRight .= '<a href="index.php?'.api_get_cidreq().'&action=discuss&title='
1300
                    .api_htmlentities(urlencode($page)).'" '.self::is_active_navigation_tab('discuss').'>'
1301
                    .Display::return_icon(
1302
                        'discuss.png',
1303
                        get_lang('DiscussThisPage'),
1304
                        [],
1305
                        ICON_SIZE_MEDIUM
1306
                    ).'</a>';
1307
            }
1308
1309
            //menu history
1310
            $actionsRight .= '<a href="index.php?'.api_get_cidreq().'&action=history&title='
1311
                .api_htmlentities(urlencode($page)).'" '.self::is_active_navigation_tab('history').'>'.
1312
                Display::return_icon(
1313
                    'history.png',
1314
                    get_lang('ShowPageHistory'),
1315
                    [],
1316
                    ICON_SIZE_MEDIUM
1317
                ).'</a>';
1318
            //menu linkspages
1319
            $actionsRight .= '<a href="index.php?'.api_get_cidreq().'action=links&title='
1320
                .api_htmlentities(urlencode($page)).'" '.self::is_active_navigation_tab('links').'>'
1321
                .Display::return_icon(
1322
                    'what_link_here.png',
1323
                    get_lang('LinksPages'),
1324
                    [],
1325
                    ICON_SIZE_MEDIUM
1326
                ).'</a>';
1327
1328
            //menu delete wikipage
1329
            if (api_is_allowed_to_edit(false, true) ||
1330
                api_is_platform_admin()
1331
            ) {
1332
                $actionsRight .= '<a href="index.php?action=delete&'.api_get_cidreq().'&title='
1333
                    .api_htmlentities(urlencode($page)).'"'.self::is_active_navigation_tab('delete').'>'
1334
                    .Display::return_icon(
1335
                        'delete.png',
1336
                        get_lang('DeleteThisPage'),
1337
                        [],
1338
                        ICON_SIZE_MEDIUM
1339
                    ).'</a>';
1340
            }
1341
1342
            $actionsRight .= '<a href="index.php?'.api_get_cidreq().'&action=showpage&actionpage='
1343
                .$lock_unlock_notify_page.'&title='.api_htmlentities(urlencode($page)).'">'.$notify_page.'</a>';
1344
1345
            // Page action: copy last version to doc area
1346
            if (api_is_allowed_to_edit(false, true) ||
1347
                api_is_platform_admin()
1348
            ) {
1349
                $actionsRight .= '<a href="index.php?'.api_get_cidreq().'&action=export2doc&wiki_id='.$row['id'].'">'
1350
                    .Display::return_icon(
1351
                        'export_to_documents.png',
1352
                        get_lang('ExportToDocArea'),
1353
                        [],
1354
                        ICON_SIZE_MEDIUM
1355
                    ).'</a>';
1356
            }
1357
1358
            $actionsRight .= '<a href="index.php?'.api_get_cidreq().'&action=export_to_pdf&wiki_id='.$row['id'].'">'
1359
                .Display::return_icon(
1360
                    'pdf.png',
1361
                    get_lang('ExportToPDF'),
1362
                    [],
1363
                    ICON_SIZE_MEDIUM
1364
                ).'</a>';
1365
1366
            $unoconv = api_get_configuration_value('unoconv.binaries');
1367
            if ($unoconv) {
1368
                $actionsRight .= '<a href="'.api_get_path(WEB_CODE_PATH).'wiki/index.php?action=export_to_doc_file&id='
1369
                    .$row['id'].'&'.api_get_cidreq().'">'
1370
                    .Display::return_icon(
1371
                        'export_doc.png',
1372
                        get_lang('ExportToDoc'),
1373
                        [],
1374
                        ICON_SIZE_MEDIUM
1375
                    ).'</a>';
1376
            }
1377
1378
            //export to print?>
1379
            <script>
1380
                function goprint() {
1381
                    var a = window.open('', '', 'width=800,height=600');
1382
                    a.document.open("text/html");
1383
                    a.document.write($('#wikicontent .panel-heading').html());
1384
                    a.document.write($('#wikicontent .panel-body').html());
1385
                    a.document.close();
1386
                    a.print();
1387
                }
1388
            </script>
1389
            <?php
1390
            $actionsRight .= Display::url(
1391
                Display::return_icon(
1392
                    'printer.png',
1393
                    get_lang('Print'),
1394
                    [],
1395
                    ICON_SIZE_MEDIUM
1396
                ),
1397
                '#',
1398
                ['onclick' => "javascript: goprint();"]
1399
            );
1400
        }
1401
1402
        echo Display::toolbarAction(
1403
            'toolbar-wikistudent',
1404
            [$actionsLeft, $actionsRight]
1405
        );
1406
1407
        $pageWiki = self::detect_news_link($content);
1408
        $pageWiki = self::detect_irc_link($pageWiki);
1409
        $pageWiki = self::detect_ftp_link($pageWiki);
1410
        $pageWiki = self::detect_mail_link($pageWiki);
1411
        $pageWiki = self::detect_anchor_link($pageWiki);
1412
        $pageWiki = self::detect_external_link($pageWiki);
1413
        $pageWiki = self::make_wiki_link_clickable($pageWiki);
1414
1415
        $footerWiki = '<ul class="list-inline" style="margin-bottom: 0;">'
1416
            .'<li>'.get_lang('Progress').': '.$pageProgress.'%</li>'
1417
            .'<li>'.get_lang('Rating').': '.$pageScore.'</li>'
1418
            .'<li>'.get_lang('Words').': '.self::word_count($content).'</li>';
1419
1420
        $footerWiki .= $this->returnCategoriesBlock(
1421
            !empty($row['id']) ? $row['id'] : 0,
1422
            '<li class="pull-right">',
1423
            '</li>'
1424
        );
1425
1426
        $footerWiki .= '</ul>';
1427
        // wikicontent require to print wiki document
1428
        echo '<div id="wikicontent">'.Display::panel($pageWiki, $pageTitle, $footerWiki).'</div>'; //end filter visibility
1429
    }
1430
1431
    /**
1432
     * This function counted the words in a document. Thanks Adeel Khan.
1433
     *
1434
     * @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...
1435
     *
1436
     * @return int Number of words
1437
     */
1438
    public function word_count($document)
1439
    {
1440
        $search = [
1441
            '@<script[^>]*?>.*?</script>@si',
1442
            '@<style[^>]*?>.*?</style>@siU',
1443
            '@<div id="player.[^>]*?>.*?</div>@',
1444
            '@<![\s\S]*?--[ \t\n\r]*>@',
1445
        ];
1446
1447
        $document = preg_replace($search, '', $document);
1448
1449
        // strip all html tags
1450
        $wc = strip_tags($document);
1451
        $wc = html_entity_decode(
1452
            $wc,
1453
            ENT_NOQUOTES,
1454
            'UTF-8'
1455
        ); // TODO:test also old html_entity_decode(utf8_encode($wc))
1456
1457
        // remove 'words' that don't consist of alphanumerical characters or punctuation. And fix accents and some letters
1458
        $pattern = "#[^(\w|\d|\'|\"|\.|\!|\?|;|,|\\|\/|\-|:|\&|@|á|é|í|ó|ú|à|è|ì|ò|ù|ä|ë|ï|ö|ü|Á|É|Í|Ó|Ú|À|È|Ò|Ù|Ä|Ë|Ï|Ö|Ü|â|ê|î|ô|û|Â|Ê|Î|Ô|Û|ñ|Ñ|ç|Ç)]+#";
1459
        $wc = trim(preg_replace($pattern, " ", $wc));
1460
1461
        // remove one-letter 'words' that consist only of punctuation
1462
        $wc = trim(
1463
            preg_replace(
1464
                "#\s*[(\'|\"|\.|\!|\?|;|,|\\|\/|\-|:|\&|@)]\s*#",
1465
                " ",
1466
                $wc
1467
            )
1468
        );
1469
1470
        // remove superfluous whitespace
1471
        $wc = preg_replace("/\s\s+/", " ", $wc);
1472
1473
        // split string into an array of words
1474
        $wc = explode(" ", $wc);
1475
1476
        // remove empty elements
1477
        $wc = array_filter($wc);
1478
1479
        // return the number of words
1480
        return count($wc);
1481
    }
1482
1483
    /**
1484
     * This function checks if wiki title exist.
1485
     */
1486
    public function wiki_exist($title)
1487
    {
1488
        $tbl_wiki = $this->tbl_wiki;
1489
        $groupfilter = $this->groupfilter;
1490
        $condition_session = $this->condition_session;
1491
        $course_id = api_get_course_int_id();
1492
1493
        $sql = 'SELECT id FROM '.$tbl_wiki.'
1494
              WHERE
1495
                c_id = '.$course_id.' AND
1496
                title="'.Database::escape_string($title).'" AND
1497
                '.$groupfilter.$condition_session.'
1498
              ORDER BY id ASC';
1499
        $result = Database::query($sql);
1500
        $cant = Database::num_rows($result);
1501
        if ($cant > 0) {
1502
            return true;
1503
        } else {
1504
            return false;
1505
        }
1506
    }
1507
1508
    /**
1509
     * Checks if this navigation tab has to be set to active.
1510
     *
1511
     * @author Patrick Cool <[email protected]>, Ghent University
1512
     *
1513
     * @return string html code
1514
     */
1515
    public function is_active_navigation_tab($paramwk)
1516
    {
1517
        if (isset($_GET['action']) && $_GET['action'] == $paramwk) {
1518
            return ' class="active"';
1519
        }
1520
    }
1521
1522
    /**
1523
     * Lock add pages.
1524
     *
1525
     * @author Juan Carlos Raña <[email protected]>
1526
     * return current database status of protect page and change it if get action
1527
     */
1528
    public function check_addnewpagelock()
1529
    {
1530
        $tbl_wiki = $this->tbl_wiki;
1531
        $condition_session = $this->condition_session;
1532
        $groupfilter = $this->groupfilter;
1533
        $course_id = api_get_course_int_id();
1534
1535
        $sql = 'SELECT *
1536
                FROM '.$tbl_wiki.'
1537
                WHERE c_id = '.$course_id.' AND '.$groupfilter.$condition_session.'
1538
                ORDER BY id ASC';
1539
1540
        $result = Database::query($sql);
1541
        $row = Database::fetch_array($result);
1542
1543
        $status_addlock = null;
1544
        if ($row) {
1545
            $status_addlock = $row['addlock'];
1546
        }
1547
1548
        // Change status
1549
        if (api_is_allowed_to_edit(false, true) ||
1550
            api_is_platform_admin()
1551
        ) {
1552
            if (isset($_GET['actionpage'])) {
1553
                if ($_GET['actionpage'] == 'lockaddnew' && $status_addlock == 1) {
1554
                    $status_addlock = 0;
1555
                }
1556
                if ($_GET['actionpage'] == 'unlockaddnew' && $status_addlock == 0) {
1557
                    $status_addlock = 1;
1558
                }
1559
                $sql = 'UPDATE '.$tbl_wiki.' SET
1560
                            addlock="'.Database::escape_string($status_addlock).'"
1561
                        WHERE c_id = '.$course_id.' AND '.$groupfilter.$condition_session;
1562
                Database::query($sql);
1563
            }
1564
1565
            $sql = 'SELECT *
1566
                    FROM '.$tbl_wiki.'
1567
                    WHERE c_id = '.$course_id.' AND '.$groupfilter.$condition_session.'
1568
                    ORDER BY id ASC';
1569
            $result = Database::query($sql);
1570
            $row = Database::fetch_array($result);
1571
            if ($row) {
1572
                return $row['addlock'];
1573
            }
1574
        }
1575
1576
        return null;
1577
    }
1578
1579
    /**
1580
     * Protect page.
1581
     *
1582
     * @author Juan Carlos Raña <[email protected]>
1583
     * return current database status of protect page and change it if get action
1584
     */
1585
    public function check_protect_page()
1586
    {
1587
        $tbl_wiki = $this->tbl_wiki;
1588
        $condition_session = $this->condition_session;
1589
        $groupfilter = $this->groupfilter;
1590
        $page = $this->page;
1591
1592
        $course_id = api_get_course_int_id();
1593
        $sql = 'SELECT * FROM '.$tbl_wiki.'
1594
              WHERE
1595
                c_id = '.$course_id.' AND
1596
                reflink="'.Database::escape_string($page).'" AND
1597
                '.$groupfilter.$condition_session.'
1598
              ORDER BY id ASC';
1599
1600
        $result = Database::query($sql);
1601
        $row = Database::fetch_array($result);
1602
1603
        if (!$row) {
1604
            return 0;
1605
        }
1606
1607
        $status_editlock = $row['editlock'];
1608
        $id = $row['page_id'];
1609
1610
        // Change status
1611
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
1612
            if (isset($_GET['actionpage']) && $_GET['actionpage'] == 'lock' && $status_editlock == 0) {
1613
                $status_editlock = 1;
1614
            }
1615
            if (isset($_GET['actionpage']) && $_GET['actionpage'] == 'unlock' && $status_editlock == 1) {
1616
                $status_editlock = 0;
1617
            }
1618
1619
            $sql = 'UPDATE '.$tbl_wiki.' SET
1620
                    editlock="'.Database::escape_string($status_editlock).'"
1621
                    WHERE c_id = '.$course_id.' AND page_id="'.$id.'"';
1622
            Database::query($sql);
1623
1624
            $sql = 'SELECT * FROM '.$tbl_wiki.'
1625
                    WHERE
1626
                        c_id = '.$course_id.' AND
1627
                        reflink="'.Database::escape_string($page).'" AND
1628
                    '.$groupfilter.$condition_session.'
1629
                  ORDER BY id ASC';
1630
            $result = Database::query($sql);
1631
            $row = Database::fetch_array($result);
1632
        }
1633
1634
        //show status
1635
        return (int) $row['editlock'];
1636
    }
1637
1638
    /**
1639
     * Visibility page.
1640
     *
1641
     * @author Juan Carlos Raña <[email protected]>
1642
     * return current database status of visibility and change it if get action
1643
     */
1644
    public function check_visibility_page()
1645
    {
1646
        $tbl_wiki = $this->tbl_wiki;
1647
        $page = $this->page;
1648
        $condition_session = $this->condition_session;
1649
        $groupfilter = $this->groupfilter;
1650
        $course_id = api_get_course_int_id();
1651
1652
        $sql = 'SELECT * FROM '.$tbl_wiki.'
1653
                WHERE
1654
                    c_id = '.$course_id.' AND
1655
                    reflink="'.Database::escape_string($page).'" AND
1656
                    '.$groupfilter.$condition_session.'
1657
                ORDER BY id';
1658
        $result = Database::query($sql);
1659
        $row = Database::fetch_array($result);
1660
1661
        if (!$row) {
1662
            return 0;
1663
        }
1664
1665
        $status_visibility = $row['visibility'];
1666
        //change status
1667
        if (api_is_allowed_to_edit(false, true) ||
1668
            api_is_platform_admin()
1669
        ) {
1670
            if (isset($_GET['actionpage']) &&
1671
                $_GET['actionpage'] == 'visible' &&
1672
                $status_visibility == 0
1673
            ) {
1674
                $status_visibility = 1;
1675
            }
1676
            if (isset($_GET['actionpage']) &&
1677
                $_GET['actionpage'] == 'invisible' &&
1678
                $status_visibility == 1
1679
            ) {
1680
                $status_visibility = 0;
1681
            }
1682
1683
            $sql = 'UPDATE '.$tbl_wiki.' SET
1684
                    visibility = "'.Database::escape_string($status_visibility).'"
1685
                    WHERE
1686
                        c_id = '.$course_id.' AND
1687
                        reflink="'.Database::escape_string($page).'" AND
1688
                        '.$groupfilter.$condition_session;
1689
            Database::query($sql);
1690
1691
            // Although the value now is assigned to all (not only the first),
1692
            // these three lines remain necessary.
1693
            // They do that by changing the page state is
1694
            // made when you press the button and not have to wait to change his page
1695
            $sql = 'SELECT * FROM '.$tbl_wiki.'
1696
                    WHERE
1697
                        c_id = '.$course_id.' AND
1698
                        reflink="'.Database::escape_string($page).'" AND
1699
                        '.$groupfilter.$condition_session.'
1700
                    ORDER BY id ASC';
1701
            $result = Database::query($sql);
1702
            $row = Database::fetch_array($result);
1703
        }
1704
1705
        if (empty($row['id'])) {
1706
            $row['visibility'] = 1;
1707
        }
1708
1709
        //show status
1710
        return $row['visibility'];
1711
    }
1712
1713
    /**
1714
     * Visibility discussion.
1715
     *
1716
     * @author Juan Carlos Raña <[email protected]>
1717
     *
1718
     * @return int current database status of discuss visibility
1719
     *             and change it if get action page
1720
     */
1721
    public function check_visibility_discuss()
1722
    {
1723
        $tbl_wiki = $this->tbl_wiki;
1724
        $page = $this->page;
1725
        $condition_session = $this->condition_session;
1726
        $groupfilter = $this->groupfilter;
1727
        $course_id = api_get_course_int_id();
1728
1729
        $sql = 'SELECT * FROM '.$tbl_wiki.'
1730
                WHERE
1731
                    c_id = '.$course_id.' AND
1732
                    reflink="'.Database::escape_string($page).'" AND
1733
                    '.$groupfilter.$condition_session.'
1734
                ORDER BY id ASC';
1735
        $result = Database::query($sql);
1736
        $row = Database::fetch_array($result);
1737
1738
        $status_visibility_disc = $row['visibility_disc'];
1739
1740
        //change status
1741
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
1742
            if (isset($_GET['actionpage']) &&
1743
                $_GET['actionpage'] == 'showdisc' &&
1744
                $status_visibility_disc == 0
1745
            ) {
1746
                $status_visibility_disc = 1;
1747
            }
1748
            if (isset($_GET['actionpage']) &&
1749
                $_GET['actionpage'] == 'hidedisc' &&
1750
                $status_visibility_disc == 1
1751
            ) {
1752
                $status_visibility_disc = 0;
1753
            }
1754
1755
            $sql = 'UPDATE '.$tbl_wiki.' SET
1756
                    visibility_disc="'.Database::escape_string($status_visibility_disc).'"
1757
                    WHERE
1758
                        c_id = '.$course_id.' AND
1759
                        reflink="'.Database::escape_string($page).'" AND
1760
                        '.$groupfilter.$condition_session;
1761
            Database::query($sql);
1762
1763
            // Although the value now is assigned to all (not only the first),
1764
            // these three lines remain necessary.
1765
            // They do that by changing the page state is made when you press
1766
            // the button and not have to wait to change his page
1767
            $sql = 'SELECT * FROM '.$tbl_wiki.'
1768
                    WHERE
1769
                        c_id = '.$course_id.' AND
1770
                        reflink="'.Database::escape_string($page).'" AND
1771
                        '.$groupfilter.$condition_session.'
1772
                    ORDER BY id ASC';
1773
            $result = Database::query($sql);
1774
            $row = Database::fetch_array($result);
1775
        }
1776
1777
        return $row['visibility_disc'];
1778
    }
1779
1780
    /**
1781
     * Lock add discussion.
1782
     *
1783
     * @author Juan Carlos Raña <[email protected]>
1784
     *
1785
     * @return int current database status of lock dicuss and change if get action
1786
     */
1787
    public function check_addlock_discuss()
1788
    {
1789
        $tbl_wiki = $this->tbl_wiki;
1790
        $page = $this->page;
1791
        $condition_session = $this->condition_session;
1792
        $groupfilter = $this->groupfilter;
1793
        $course_id = api_get_course_int_id();
1794
1795
        $sql = 'SELECT * FROM '.$tbl_wiki.'
1796
                WHERE
1797
                    c_id = '.$course_id.' AND
1798
                    reflink="'.Database::escape_string($page).'" AND
1799
                    '.$groupfilter.$condition_session.'
1800
                ORDER BY id ASC';
1801
        $result = Database::query($sql);
1802
        $row = Database::fetch_array($result);
1803
1804
        $status_addlock_disc = $row['addlock_disc'];
1805
1806
        //change status
1807
        if (api_is_allowed_to_edit() || api_is_platform_admin()) {
1808
            if (isset($_GET['actionpage']) &&
1809
                $_GET['actionpage'] == 'lockdisc' &&
1810
                $status_addlock_disc == 0
1811
            ) {
1812
                $status_addlock_disc = 1;
1813
            }
1814
            if (isset($_GET['actionpage']) &&
1815
                $_GET['actionpage'] == 'unlockdisc' &&
1816
                $status_addlock_disc == 1
1817
            ) {
1818
                $status_addlock_disc = 0;
1819
            }
1820
1821
            $sql = 'UPDATE '.$tbl_wiki.' SET
1822
                    addlock_disc="'.Database::escape_string($status_addlock_disc).'"
1823
                    WHERE
1824
                        c_id = '.$course_id.' AND
1825
                        reflink = "'.Database::escape_string($page).'" AND
1826
                         '.$groupfilter.$condition_session;
1827
            Database::query($sql);
1828
1829
            // Although the value now is assigned to all (not only the first),
1830
            // these three lines remain necessary.
1831
            // They do that by changing the page state is made when you press
1832
            // the button and not have to wait to change his page
1833
            $sql = 'SELECT * FROM '.$tbl_wiki.'
1834
                    WHERE
1835
                        c_id = '.$course_id.' AND
1836
                        reflink="'.Database::escape_string($page).'" AND
1837
                        '.$groupfilter.$condition_session.'
1838
                    ORDER BY id ASC';
1839
            $result = Database::query($sql);
1840
            $row = Database::fetch_array($result);
1841
        }
1842
1843
        return $row['addlock_disc'];
1844
    }
1845
1846
    /**
1847
     * Lock rating discussion.
1848
     *
1849
     * @author Juan Carlos Raña <[email protected]>
1850
     *
1851
     * @return int current database status of rating discuss and change it if get action
1852
     */
1853
    public function check_ratinglock_discuss()
1854
    {
1855
        $tbl_wiki = $this->tbl_wiki;
1856
        $page = $this->page;
1857
        $condition_session = $this->condition_session;
1858
        $groupfilter = $this->groupfilter;
1859
        $course_id = api_get_course_int_id();
1860
1861
        $sql = 'SELECT * FROM '.$tbl_wiki.'
1862
                WHERE
1863
                    c_id = '.$course_id.' AND
1864
                    reflink="'.Database::escape_string($page).'" AND
1865
                    '.$groupfilter.$condition_session.'
1866
                ORDER BY id ASC';
1867
        $result = Database::query($sql);
1868
        $row = Database::fetch_array($result);
1869
        $status_ratinglock_disc = $row['ratinglock_disc'];
1870
1871
        //change status
1872
        if (api_is_allowed_to_edit(false, true) ||
1873
            api_is_platform_admin()
1874
        ) {
1875
            if (isset($_GET['actionpage']) &&
1876
                $_GET['actionpage'] == 'lockrating' &&
1877
                $status_ratinglock_disc == 0
1878
            ) {
1879
                $status_ratinglock_disc = 1;
1880
            }
1881
            if (isset($_GET['actionpage']) &&
1882
                $_GET['actionpage'] == 'unlockrating' &&
1883
                $status_ratinglock_disc == 1
1884
            ) {
1885
                $status_ratinglock_disc = 0;
1886
            }
1887
1888
            $sql = 'UPDATE '.$tbl_wiki.'
1889
                    SET ratinglock_disc="'.Database::escape_string($status_ratinglock_disc).'"
1890
                    WHERE
1891
                        c_id = '.$course_id.' AND
1892
                        reflink="'.Database::escape_string($page).'" AND
1893
                        '.$groupfilter.$condition_session;
1894
            // Visibility. Value to all,not only for the first
1895
            Database::query($sql);
1896
1897
            // Although the value now is assigned to all (not only the first),
1898
            // these three lines remain necessary. They do that by changing the
1899
            // page state is made when you press the button and not have to wait
1900
            // to change his page
1901
            $sql = 'SELECT * FROM '.$tbl_wiki.'
1902
                    WHERE
1903
                        c_id = '.$course_id.' AND
1904
                        reflink="'.Database::escape_string($page).'" AND
1905
                    '.$groupfilter.$condition_session.'
1906
                  ORDER BY id ASC';
1907
            $result = Database::query($sql);
1908
            $row = Database::fetch_array($result);
1909
        }
1910
1911
        return $row['ratinglock_disc'];
1912
    }
1913
1914
    /**
1915
     * Notify page changes.
1916
     *
1917
     * @author Juan Carlos Raña <[email protected]>
1918
     *
1919
     * @return int the current notification status
1920
     */
1921
    public function check_notify_page($reflink)
1922
    {
1923
        $tbl_wiki = $this->tbl_wiki;
1924
        $tbl_wiki_mailcue = $this->tbl_wiki_mailcue;
1925
        $condition_session = $this->condition_session;
1926
        $groupfilter = $this->groupfilter;
1927
        $groupId = api_get_group_id();
1928
        $session_id = api_get_session_id();
1929
        $course_id = api_get_course_int_id();
1930
        $userId = api_get_user_id();
1931
1932
        $sql = 'SELECT * FROM '.$tbl_wiki.'
1933
                WHERE
1934
                    c_id = '.$course_id.' AND
1935
                    reflink="'.$reflink.'" AND
1936
                    '.$groupfilter.$condition_session.'
1937
                ORDER BY id ASC';
1938
        $result = Database::query($sql);
1939
        $row = Database::fetch_array($result);
1940
        $id = $row['id'];
1941
        $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
1942
                WHERE
1943
                    c_id = '.$course_id.' AND
1944
                    id="'.$id.'" AND
1945
                    user_id="'.api_get_user_id().'" AND
1946
                    type="P"';
1947
        $result = Database::query($sql);
1948
        $row = Database::fetch_array($result);
1949
1950
        $idm = $row ? $row['id'] : 0;
1951
        if (empty($idm)) {
1952
            $status_notify = 0;
1953
        } else {
1954
            $status_notify = 1;
1955
        }
1956
1957
        // Change status
1958
        if (isset($_GET['actionpage']) &&
1959
            $_GET['actionpage'] == 'locknotify' &&
1960
            $status_notify == 0
1961
        ) {
1962
            $sql = "SELECT id FROM $tbl_wiki_mailcue
1963
                    WHERE c_id = $course_id AND id = $id AND user_id = $userId";
1964
            $result = Database::query($sql);
1965
            $exist = false;
1966
            if (Database::num_rows($result)) {
1967
                $exist = true;
1968
            }
1969
            if ($exist == false) {
1970
                $sql = "INSERT INTO ".$tbl_wiki_mailcue." (c_id, id, user_id, type, group_id, session_id) VALUES
1971
                ($course_id, '".$id."','".api_get_user_id()."','P','".$groupId."','".$session_id."')";
1972
                Database::query($sql);
1973
            }
1974
            $status_notify = 1;
1975
        }
1976
1977
        if (isset($_GET['actionpage']) &&
1978
            $_GET['actionpage'] == 'unlocknotify' &&
1979
            $status_notify == 1
1980
        ) {
1981
            $sql = 'DELETE FROM '.$tbl_wiki_mailcue.'
1982
                    WHERE
1983
                        id="'.$id.'" AND
1984
                        user_id="'.api_get_user_id().'" AND
1985
                        type="P" AND
1986
                        c_id = '.$course_id;
1987
            Database::query($sql);
1988
            $status_notify = 0;
1989
        }
1990
1991
        return $status_notify;
1992
    }
1993
1994
    /**
1995
     * Notify discussion changes.
1996
     *
1997
     * @author Juan Carlos Raña <[email protected]>
1998
     *
1999
     * @param string $reflink
2000
     *
2001
     * @return int current database status of rating discuss and change it if get action
2002
     */
2003
    public function check_notify_discuss($reflink)
2004
    {
2005
        $tbl_wiki_mailcue = $this->tbl_wiki_mailcue;
2006
        $tbl_wiki = $this->tbl_wiki;
2007
        $condition_session = $this->condition_session;
2008
        $groupfilter = $this->groupfilter;
2009
2010
        $course_id = api_get_course_int_id();
2011
        $groupId = api_get_group_id();
2012
        $session_id = api_get_session_id();
2013
2014
        $sql = 'SELECT * FROM '.$tbl_wiki.'
2015
                WHERE
2016
                    c_id = '.$course_id.' AND
2017
                    reflink="'.$reflink.'" AND
2018
                    '.$groupfilter.$condition_session.'
2019
                ORDER BY id ASC';
2020
        $result = Database::query($sql);
2021
        $row = Database::fetch_array($result);
2022
        $id = $row['id'];
2023
        $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
2024
                WHERE
2025
                    c_id = '.$course_id.' AND id="'.$id.'" AND user_id="'.api_get_user_id().'" AND type="D"';
2026
        $result = Database::query($sql);
2027
        $row = Database::fetch_array($result);
2028
        $idm = $row ? $row['id'] : 0;
2029
2030
        if (empty($idm)) {
2031
            $status_notify_disc = 0;
2032
        } else {
2033
            $status_notify_disc = 1;
2034
        }
2035
2036
        // change status
2037
        if (isset($_GET['actionpage']) &&
2038
            $_GET['actionpage'] == 'locknotifydisc' &&
2039
            $status_notify_disc == 0
2040
        ) {
2041
            $sql = "INSERT INTO ".$tbl_wiki_mailcue." (c_id, id, user_id, type, group_id, session_id) VALUES
2042
            ($course_id, '".$id."','".api_get_user_id()."','D','".$groupId."','".$session_id."')";
2043
            Database::query($sql);
2044
            $status_notify_disc = 1;
2045
        }
2046
        if (isset($_GET['actionpage']) &&
2047
            $_GET['actionpage'] == 'unlocknotifydisc' &&
2048
            $status_notify_disc == 1
2049
        ) {
2050
            $sql = 'DELETE FROM '.$tbl_wiki_mailcue.'
2051
                    WHERE
2052
                        c_id = '.$course_id.' AND
2053
                        id="'.$id.'" AND
2054
                        user_id="'.api_get_user_id().'" AND
2055
                        type="D" AND
2056
                        c_id = '.$course_id;
2057
            Database::query($sql);
2058
            $status_notify_disc = 0;
2059
        }
2060
2061
        return $status_notify_disc;
2062
    }
2063
2064
    /**
2065
     * Notify all changes.
2066
     *
2067
     * @author Juan Carlos Raña <[email protected]>
2068
     */
2069
    public function check_notify_all()
2070
    {
2071
        $tbl_wiki_mailcue = $this->tbl_wiki_mailcue;
2072
        $course_id = api_get_course_int_id();
2073
        $groupId = api_get_group_id();
2074
        $session_id = api_get_session_id();
2075
2076
        $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
2077
                WHERE
2078
                    c_id = '.$course_id.' AND
2079
                    user_id="'.api_get_user_id().'" AND
2080
                    type="F" AND
2081
                    group_id="'.$groupId.'" AND
2082
                    session_id="'.$session_id.'"';
2083
        $result = Database::query($sql);
2084
        $row = Database::fetch_array($result);
2085
2086
        $idm = $row ? $row['user_id'] : 0;
2087
2088
        if (empty($idm)) {
2089
            $status_notify_all = 0;
2090
        } else {
2091
            $status_notify_all = 1;
2092
        }
2093
2094
        //change status
2095
        if (isset($_GET['actionpage']) &&
2096
            $_GET['actionpage'] == 'locknotifyall' &&
2097
            $status_notify_all == 0
2098
        ) {
2099
            $sql = "INSERT INTO ".$tbl_wiki_mailcue." (c_id, user_id, type, group_id, session_id) VALUES
2100
            ($course_id, '".api_get_user_id()."','F','".$groupId."','".$session_id."')";
2101
            Database::query($sql);
2102
            $status_notify_all = 1;
2103
        }
2104
2105
        if (isset($_GET['actionpage']) &&
2106
            $_GET['actionpage'] == 'unlocknotifyall' &&
2107
            $status_notify_all == 1
2108
        ) {
2109
            $sql = 'DELETE FROM '.$tbl_wiki_mailcue.'
2110
                   WHERE
2111
                    c_id = '.$course_id.' AND
2112
                    user_id="'.api_get_user_id().'" AND
2113
                    type="F" AND
2114
                    group_id="'.$groupId.'" AND
2115
                    session_id="'.$session_id.'" AND
2116
                    c_id = '.$course_id;
2117
            Database::query($sql);
2118
            $status_notify_all = 0;
2119
        }
2120
2121
        //show status
2122
        return $status_notify_all;
2123
    }
2124
2125
    /**
2126
     * Sends pending e-mails.
2127
     */
2128
    public function check_emailcue(
2129
        $id_or_ref,
2130
        $type,
2131
        $lastime = '',
2132
        $lastuser = ''
2133
    ) {
2134
        $tbl_wiki_mailcue = $this->tbl_wiki_mailcue;
2135
        $tbl_wiki = $this->tbl_wiki;
2136
        $condition_session = $this->condition_session;
2137
        $groupfilter = $this->groupfilter;
2138
        $_course = $this->courseInfo;
2139
        $groupId = api_get_group_id();
2140
        $session_id = api_get_session_id();
2141
        $course_id = api_get_course_int_id();
2142
        $group_properties = GroupManager::get_group_properties($groupId);
2143
        $group_name = $group_properties ? $group_properties['name'] : '';
2144
        $allow_send_mail = false; //define the variable to below
2145
        $email_assignment = null;
2146
        if ($type == 'P') {
2147
            //if modifying a wiki page
2148
            //first, current author and time
2149
            //Who is the author?
2150
            $userinfo = api_get_user_info($lastuser);
2151
            $email_user_author = get_lang('EditedBy').': '.$userinfo['complete_name'];
2152
2153
            //When ?
2154
            $year = substr($lastime, 0, 4);
2155
            $month = substr($lastime, 5, 2);
2156
            $day = substr($lastime, 8, 2);
2157
            $hours = substr($lastime, 11, 2);
2158
            $minutes = substr($lastime, 14, 2);
2159
            $seconds = substr($lastime, 17, 2);
2160
            $email_date_changes = $day.' '.$month.' '.$year.' '.$hours.":".$minutes.":".$seconds;
2161
2162
            //second, extract data from first reg
2163
            $sql = 'SELECT * FROM '.$tbl_wiki.'
2164
                    WHERE
2165
                        c_id = '.$course_id.' AND
2166
                        reflink="'.$id_or_ref.'" AND
2167
                        '.$groupfilter.$condition_session.'
2168
                    ORDER BY id ASC';
2169
            $result = Database::query($sql);
2170
            $row = Database::fetch_array($result);
2171
            $id = $row['id'];
2172
            $email_page_name = $row['title'];
2173
            if ($row['visibility'] == 1) {
2174
                $allow_send_mail = true; //if visibility off - notify off
2175
                $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
2176
                        WHERE
2177
                            c_id = '.$course_id.' AND
2178
                            id="'.$id.'" AND
2179
                            type="'.$type.'" OR
2180
                            type="F" AND
2181
                            group_id="'.$groupId.'" AND
2182
                            session_id="'.$session_id.'"';
2183
                //type: P=page, D=discuss, F=full.
2184
                $result = Database::query($sql);
2185
                $emailtext = get_lang('EmailWikipageModified').
2186
                    '<strong>'.$email_page_name.'</strong> '.
2187
                    get_lang('Wiki');
2188
            }
2189
        } elseif ($type == 'D') {
2190
            //if added a post to discuss
2191
            //first, current author and time
2192
            //Who is the author of last message?
2193
            $userinfo = api_get_user_info($lastuser);
2194
            $email_user_author = get_lang('AddedBy').': '.$userinfo['complete_name'];
2195
2196
            //When ?
2197
            $year = substr($lastime, 0, 4);
2198
            $month = substr($lastime, 5, 2);
2199
            $day = substr($lastime, 8, 2);
2200
            $hours = substr($lastime, 11, 2);
2201
            $minutes = substr($lastime, 14, 2);
2202
            $seconds = substr($lastime, 17, 2);
2203
            $email_date_changes = $day.' '.$month.' '.$year.' '.$hours.":".$minutes.":".$seconds;
2204
            //second, extract data from first reg
2205
            $id = $id_or_ref; //$id_or_ref is id from tblwiki
2206
            $sql = 'SELECT * FROM '.$tbl_wiki.'
2207
                    WHERE c_id = '.$course_id.' AND id="'.$id.'"
2208
                    ORDER BY id ASC';
2209
2210
            $result = Database::query($sql);
2211
            $row = Database::fetch_array($result);
2212
2213
            $email_page_name = $row['title'];
2214
            if ($row['visibility_disc'] == 1) {
2215
                $allow_send_mail = true; //if visibility off - notify off
2216
                $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
2217
                        WHERE
2218
                            c_id = '.$course_id.' AND
2219
                            id="'.$id.'" AND
2220
                            type="'.$type.'" OR
2221
                            type="F" AND
2222
                            group_id="'.$groupId.'" AND
2223
                            session_id="'.$session_id.'"';
2224
                //type: P=page, D=discuss, F=full
2225
                $result = Database::query($sql);
2226
                $emailtext = get_lang(
2227
                        'EmailWikiPageDiscAdded'
2228
                    ).' <strong>'.$email_page_name.'</strong> '.get_lang(
2229
                        'Wiki'
2230
                    );
2231
            }
2232
        } elseif ($type == 'A') {
2233
            //for added pages
2234
            $id = 0; //for tbl_wiki_mailcue
2235
            $sql = 'SELECT * FROM '.$tbl_wiki.'
2236
                    WHERE c_id = '.$course_id.'
2237
                    ORDER BY id DESC'; //the added is always the last
2238
2239
            $result = Database::query($sql);
2240
            $row = Database::fetch_array($result);
2241
            $email_page_name = $row['title'];
2242
2243
            //Who is the author?
2244
            $userinfo = api_get_user_info($row['user_id']);
2245
            $email_user_author = get_lang('AddedBy').': '.$userinfo['complete_name'];
2246
2247
            //When ?
2248
            $year = substr($row['dtime'], 0, 4);
2249
            $month = substr($row['dtime'], 5, 2);
2250
            $day = substr($row['dtime'], 8, 2);
2251
            $hours = substr($row['dtime'], 11, 2);
2252
            $minutes = substr($row['dtime'], 14, 2);
2253
            $seconds = substr($row['dtime'], 17, 2);
2254
            $email_date_changes = $day.' '.$month.' '.$year.' '.$hours.":".$minutes.":".$seconds;
2255
2256
            if ($row['assignment'] == 0) {
2257
                $allow_send_mail = true;
2258
            } elseif ($row['assignment'] == 1) {
2259
                $email_assignment = get_lang('AssignmentDescExtra').' ('.get_lang('AssignmentMode').')';
2260
                $allow_send_mail = true;
2261
            } elseif ($row['assignment'] == 2) {
2262
                $allow_send_mail = false; //Mode tasks: avoids notifications to all users about all users
2263
            }
2264
2265
            $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
2266
                    WHERE
2267
                        c_id = '.$course_id.' AND
2268
                        id="'.$id.'" AND
2269
                        type="F" AND
2270
                        group_id="'.$groupId.'" AND
2271
                        session_id="'.$session_id.'"';
2272
2273
            //type: P=page, D=discuss, F=full
2274
            $result = Database::query($sql);
2275
            $emailtext = get_lang('EmailWikiPageAdded').' <strong>'.
2276
                $email_page_name.'</strong> '.get_lang('In').' '.get_lang('Wiki');
2277
        } elseif ($type == 'E') {
2278
            $id = 0;
2279
            $allow_send_mail = true;
2280
            // Who is the author?
2281
            $userinfo = api_get_user_info(api_get_user_id()); //current user
2282
            $email_user_author = get_lang('DeletedBy').': '.$userinfo['complete_name'];
2283
            //When ?
2284
            $today = date('r'); //current time
2285
            $email_date_changes = $today;
2286
            $sql = 'SELECT * FROM '.$tbl_wiki_mailcue.'
2287
                    WHERE
2288
                        c_id = '.$course_id.' AND
2289
                        id="'.$id.'" AND type="F" AND
2290
                        group_id="'.$groupId.'" AND
2291
                        session_id="'.$session_id.'"'; //type: P=page, D=discuss, F=wiki
2292
            $result = Database::query($sql);
2293
            $emailtext = get_lang('EmailWikipageDedeleted');
2294
        }
2295
        ///make and send email
2296
        if ($allow_send_mail) {
2297
            while ($row = Database::fetch_array($result)) {
2298
                $userinfo = api_get_user_info(
2299
                    $row['user_id']
2300
                ); //$row['user_id'] obtained from tbl_wiki_mailcue
2301
                $name_to = $userinfo['complete_name'];
2302
                $email_to = $userinfo['email'];
2303
                $sender_name = api_get_setting('emailAdministrator');
2304
                $sender_email = api_get_setting('emailAdministrator');
2305
                $email_subject = get_lang(
2306
                        'EmailWikiChanges'
2307
                    ).' - '.$_course['official_code'];
2308
                $email_body = get_lang('DearUser').' '.api_get_person_name(
2309
                        $userinfo['firstname'],
2310
                        $userinfo['lastname']
2311
                    ).',<br /><br />';
2312
                if ($session_id == 0) {
2313
                    $email_body .= $emailtext.' <strong>'.$_course['name'].' - '.$group_name.'</strong><br /><br /><br />';
2314
                } else {
2315
                    $email_body .= $emailtext.' <strong>'.$_course['name'].' ('.api_get_session_name(
2316
                            api_get_session_id()
2317
                        ).') - '.$group_name.'</strong><br /><br /><br />';
2318
                }
2319
                $email_body .= $email_user_author.' ('.$email_date_changes.')<br /><br /><br />';
2320
                $email_body .= $email_assignment.'<br /><br /><br />';
2321
                $email_body .= '<font size="-2">'.get_lang(
2322
                        'EmailWikiChangesExt_1'
2323
                    ).': <strong>'.get_lang('NotifyChanges').'</strong><br />';
2324
                $email_body .= get_lang(
2325
                        'EmailWikiChangesExt_2'
2326
                    ).': <strong>'.get_lang(
2327
                        'NotNotifyChanges'
2328
                    ).'</strong></font><br />';
2329
                @api_mail_html(
2330
                    $name_to,
2331
                    $email_to,
2332
                    $email_subject,
2333
                    $email_body,
2334
                    $sender_name,
2335
                    $sender_email
2336
                );
2337
            }
2338
        }
2339
    }
2340
2341
    /**
2342
     * Function export last wiki page version to document area.
2343
     *
2344
     * @param int $doc_id wiki page id
2345
     *
2346
     * @return mixed
2347
     *
2348
     * @author Juan Carlos Raña <[email protected]>
2349
     */
2350
    public function export2doc($doc_id)
2351
    {
2352
        $_course = $this->courseInfo;
2353
        $groupId = api_get_group_id();
2354
        $groupInfo = GroupManager::get_group_properties($groupId);
2355
        $data = self::getWikiDataFromDb($doc_id);
2356
2357
        if (empty($data)) {
2358
            return false;
2359
        }
2360
2361
        $wikiTitle = $data['title'];
2362
        $wikiContents = $data['content'];
2363
2364
        $template =
2365
            '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2366
            <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{LANGUAGE}" lang="{LANGUAGE}">
2367
            <head>
2368
            <title>{TITLE}</title>
2369
            <meta http-equiv="Content-Type" content="text/html; charset={ENCODING}" />
2370
            <style type="text/css" media="screen, projection">
2371
            /*<![CDATA[*/
2372
            {CSS}
2373
            /*]]>*/
2374
            </style>
2375
            {ASCIIMATHML_SCRIPT}</head>
2376
            <body dir="{TEXT_DIRECTION}">
2377
            {CONTENT}
2378
            </body>
2379
            </html>';
2380
2381
        $css_file = api_get_path(SYS_CSS_PATH).'themes/'.api_get_setting('stylesheets').'/default.css';
2382
        if (file_exists($css_file)) {
2383
            $css = @file_get_contents($css_file);
2384
        } else {
2385
            $css = '';
2386
        }
2387
        // Fixing some bugs in css files.
2388
        $root_rel = api_get_path(REL_PATH);
2389
        $css_path = 'main/css/';
2390
        $theme = api_get_setting('stylesheets').'/';
2391
        $css = str_replace(
2392
            'behavior:url("/main/css/csshover3.htc");',
2393
            '',
2394
            $css
2395
        );
2396
        $css = str_replace('main/', $root_rel.'main/', $css);
2397
        $css = str_replace(
2398
            'images/',
2399
            $root_rel.$css_path.$theme.'images/',
2400
            $css
2401
        );
2402
        $css = str_replace('../../img/', $root_rel.'main/img/', $css);
2403
        $asciimathmal_script = (api_contains_asciimathml(
2404
                $wikiContents
2405
            ) || api_contains_asciisvg($wikiContents))
2406
            ? '<script src="'.api_get_path(
2407
                WEB_CODE_PATH
2408
            ).'inc/lib/javascript/asciimath/ASCIIMathML.js" type="text/javascript"></script>'."\n" : '';
2409
2410
        $template = str_replace(
2411
            [
2412
                '{LANGUAGE}',
2413
                '{ENCODING}',
2414
                '{TEXT_DIRECTION}',
2415
                '{TITLE}',
2416
                '{CSS}',
2417
                '{ASCIIMATHML_SCRIPT}',
2418
            ],
2419
            [
2420
                api_get_language_isocode(),
2421
                api_get_system_encoding(),
2422
                api_get_text_direction(),
2423
                $wikiTitle,
2424
                $css,
2425
                $asciimathmal_script,
2426
            ],
2427
            $template
2428
        );
2429
2430
        if (0 != $groupId) {
2431
            $groupPart = '_group'.$groupId; // and add groupId to put the same document title in different groups
2432
            $group_properties = GroupManager::get_group_properties($groupId);
2433
            $groupPath = $group_properties['directory'];
2434
        } else {
2435
            $groupPart = '';
2436
            $groupPath = '';
2437
        }
2438
2439
        $exportDir = api_get_path(SYS_COURSE_PATH).api_get_course_path(
2440
            ).'/document'.$groupPath;
2441
        $exportFile = api_replace_dangerous_char($wikiTitle).$groupPart;
2442
        $wikiContents = trim(
2443
            preg_replace(
2444
                "/\[[\[]?([^\]|]*)[|]?([^|\]]*)\][\]]?/",
2445
                "$1",
2446
                $wikiContents
2447
            )
2448
        );
2449
        //TODO: put link instead of title
2450
        $wikiContents = str_replace('{CONTENT}', $wikiContents, $template);
2451
        // replace relative path by absolute path for courses, so you can see
2452
        // items into this page wiki (images, mp3, etc..) exported in documents
2453
        if (api_strpos(
2454
                $wikiContents,
2455
                '../..'.api_get_path(REL_COURSE_PATH)
2456
            ) !== false) {
2457
            $web_course_path = api_get_path(WEB_COURSE_PATH);
2458
            $wikiContents = str_replace(
2459
                '../..'.api_get_path(REL_COURSE_PATH),
2460
                $web_course_path,
2461
                $wikiContents
2462
            );
2463
        }
2464
2465
        $i = 1;
2466
        //only export last version, but in new export new version in document area
2467
        while (file_exists($exportDir.'/'.$exportFile.'_'.$i.'.html')) {
2468
            $i++;
2469
        }
2470
2471
        $wikiFileName = $exportFile.'_'.$i.'.html';
2472
        $exportPath = $exportDir.'/'.$wikiFileName;
2473
2474
        file_put_contents($exportPath, $wikiContents);
2475
        $doc_id = add_document(
2476
            $_course,
2477
            $groupPath.'/'.$wikiFileName,
2478
            'file',
2479
            filesize($exportPath),
2480
            $wikiTitle
2481
        );
2482
2483
        api_item_property_update(
2484
            $_course,
2485
            TOOL_DOCUMENT,
2486
            $doc_id,
2487
            'DocumentAdded',
2488
            api_get_user_id(),
2489
            $groupInfo
2490
        );
2491
2492
        return $doc_id;
2493
    }
2494
2495
    /**
2496
     * Exports the wiki page to PDF.
2497
     */
2498
    public function export_to_pdf($id, $course_code)
2499
    {
2500
        if (!api_is_platform_admin()) {
2501
            if (api_get_setting('students_export2pdf') !== 'true') {
2502
                Display::addFlash(
2503
                    Display::return_message(
2504
                        get_lang('PDFDownloadNotAllowedForStudents'),
2505
                        'error',
2506
                        false
2507
                    )
2508
                );
2509
2510
                return false;
2511
            }
2512
        }
2513
2514
        $data = self::getWikiDataFromDb($id);
2515
        $content_pdf = api_html_entity_decode(
2516
            $data['content'],
2517
            ENT_QUOTES,
2518
            api_get_system_encoding()
2519
        );
2520
2521
        //clean wiki links
2522
        $content_pdf = trim(
2523
            preg_replace(
2524
                "/\[[\[]?([^\]|]*)[|]?([^|\]]*)\][\]]?/",
2525
                "$1",
2526
                $content_pdf
2527
            )
2528
        );
2529
        //TODO: It should be better to display the link insted of the tile but it is hard for [[title]] links
2530
2531
        $title_pdf = api_html_entity_decode(
2532
            $data['title'],
2533
            ENT_QUOTES,
2534
            api_get_system_encoding()
2535
        );
2536
        $title_pdf = api_utf8_encode($title_pdf, api_get_system_encoding());
2537
        $content_pdf = api_utf8_encode($content_pdf, api_get_system_encoding());
2538
2539
        $html = '
2540
        <!-- defines the headers/footers - this must occur before the headers/footers are set -->
2541
2542
        <!--mpdf
2543
        <pageheader name="odds" content-left="'.$title_pdf.'"  header-style-left="color: #880000; font-style: italic;"  line="1" />
2544
        <pagefooter name="odds" content-right="{PAGENO}/{nb}" line="1" />
2545
2546
        <!-- set the headers/footers - they will occur from here on in the document -->
2547
        <!--mpdf
2548
        <setpageheader name="odds" page="odd" value="on" show-this-page="1" />
2549
        <setpagefooter name="odds" page="O" value="on" />
2550
2551
        mpdf-->'.$content_pdf;
2552
2553
        $css = api_get_print_css();
2554
2555
        $pdf = new PDF();
2556
        $pdf->content_to_pdf($html, $css, $title_pdf, $course_code);
2557
        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...
2558
    }
2559
2560
    /**
2561
     * Function prevent double post (reload or F5).
2562
     */
2563
    public function double_post($wpost_id)
2564
    {
2565
        $postId = Session::read('wpost_id');
2566
        if (!empty($postId)) {
2567
            if ($wpost_id == $postId) {
2568
                return false;
2569
            } else {
2570
                Session::write('wpost_id', $wpost_id);
2571
2572
                return true;
2573
            }
2574
        } else {
2575
            Session::write('wpost_id', $wpost_id);
2576
2577
            return true;
2578
        }
2579
    }
2580
2581
    /**
2582
     * Function wizard individual assignment.
2583
     *
2584
     * @author Juan Carlos Raña <[email protected]>
2585
     */
2586
    public function auto_add_page_users($values)
2587
    {
2588
        $assignment_type = $values['assignment'];
2589
        $session_id = $this->session_id;
2590
        $groupId = api_get_group_id();
2591
        $groupInfo = GroupManager::get_group_properties($groupId);
2592
        if ($groupId == 0) {
2593
            //extract course members
2594
            if (!empty($session_id)) {
2595
                $a_users_to_add = CourseManager::get_user_list_from_course_code(
2596
                    api_get_course_id(),
2597
                    $session_id
2598
                );
2599
            } else {
2600
                $a_users_to_add = CourseManager::get_user_list_from_course_code(
2601
                    api_get_course_id(),
2602
                    0
2603
                );
2604
            }
2605
        } else {
2606
            //extract group members
2607
            $subscribed_users = GroupManager::get_subscribed_users($groupInfo);
2608
            $subscribed_tutors = GroupManager::get_subscribed_tutors(
2609
                $groupInfo
2610
            );
2611
            $a_users_to_add_with_duplicates = array_merge(
2612
                $subscribed_users,
2613
                $subscribed_tutors
2614
            );
2615
            //remove duplicates
2616
            $a_users_to_add = $a_users_to_add_with_duplicates;
2617
            $a_users_to_add = array_unique($a_users_to_add);
2618
        }
2619
2620
        $all_students_pages = [];
2621
        // Data about teacher
2622
        $userId = api_get_user_id();
2623
        $userinfo = api_get_user_info($userId);
2624
        $username = api_htmlentities(
2625
            sprintf(get_lang('LoginX'), $userinfo['username'], ENT_QUOTES)
2626
        );
2627
        $name = $userinfo['complete_name']." - ".$username;
2628
        $photo = '<img src="'.$userinfo['avatar'].'" alt="'.$name.'"  width="40" height="50" align="top" title="'.$name.'"  />';
2629
2630
        // teacher assignment title
2631
        $title_orig = $values['title'];
2632
2633
        // teacher assignment reflink
2634
        $link2teacher = $values['title'] = $title_orig."_uass".$userId;
2635
2636
        // first: teacher name, photo, and assignment description (original content)
2637
        $content_orig_A = '<div align="center" style="background-color: #F5F8FB; border:solid; border-color: #E6E6E6">
2638
        <table border="0">
2639
            <tr><td style="font-size:24px">'.get_lang('AssignmentDesc').'</td></tr>
2640
            <tr><td>'.$photo.'<br />'.Display::tag(
2641
                'span',
2642
                api_get_person_name(
2643
                    $userinfo['firstname'],
2644
                    $userinfo['lastname']
2645
                ),
2646
                ['title' => $username]
2647
            ).'</td></tr>
2648
        </table></div>';
2649
2650
        $content_orig_B = '<br/><div align="center" style="font-size:24px">'.
2651
            get_lang('AssignmentDescription').': '.
2652
            $title_orig.'</div><br/>'.Security::remove_XSS($_POST['content']);
2653
2654
        //Second: student list (names, photo and links to their works).
2655
        //Third: Create Students work pages.
2656
        foreach ($a_users_to_add as $o_user_to_add) {
2657
            if ($o_user_to_add['user_id'] != $userId) {
2658
                // except that puts the task
2659
                $assig_user_id = $o_user_to_add['user_id'];
2660
                // identifies each page as created by the student, not by teacher
2661
2662
                $userPicture = UserManager::getUserPicture($assig_user_id);
2663
                $username = api_htmlentities(
2664
                    sprintf(
2665
                        get_lang('LoginX'),
2666
                        $o_user_to_add['username'],
2667
                        ENT_QUOTES
2668
                    )
2669
                );
2670
                $name = api_get_person_name(
2671
                        $o_user_to_add['firstname'],
2672
                        $o_user_to_add['lastname']
2673
                    )." . ".$username;
2674
                $photo = '<img src="'.$userPicture.'" alt="'.$name.'"  width="40" height="50" align="bottom" title="'.$name.'"  />';
2675
2676
                $is_tutor_of_group = GroupManager::is_tutor_of_group(
2677
                    $assig_user_id,
2678
                    $groupInfo
2679
                ); //student is tutor
2680
                $is_tutor_and_member = GroupManager::is_tutor_of_group(
2681
                        $assig_user_id,
2682
                        $groupInfo
2683
                    ) &&
2684
                    GroupManager::is_subscribed($assig_user_id, $groupInfo);
2685
                // student is tutor and member
2686
                if ($is_tutor_and_member) {
2687
                    $status_in_group = get_lang('GroupTutorAndMember');
2688
                } else {
2689
                    if ($is_tutor_of_group) {
2690
                        $status_in_group = get_lang('GroupTutor');
2691
                    } else {
2692
                        $status_in_group = " "; //get_lang('GroupStandardMember')
2693
                    }
2694
                }
2695
2696
                if ($assignment_type == 1) {
2697
                    $values['title'] = $title_orig;
2698
                    $values['content'] = '<div align="center" style="background-color: #F5F8FB; border:solid; border-color: #E6E6E6">
2699
                    <table border="0">
2700
                    <tr><td style="font-size:24px">'.get_lang('AssignmentWork').'</td></tr>
2701
                    <tr><td>'.$photo.'<br />'.$name.'</td></tr></table>
2702
                    </div>[['.$link2teacher.' | '.get_lang(
2703
                            'AssignmentLinktoTeacherPage'
2704
                        ).']] ';
2705
                    //If $content_orig_B is added here, the task written by
2706
                    // the professor was copied to the page of each student.
2707
                    // TODO: config options
2708
                    // AssignmentLinktoTeacherPage
2709
                    $all_students_pages[] = '<li>'.
2710
                        Display::tag(
2711
                            'span',
2712
                            strtoupper(
2713
                                $o_user_to_add['lastname']
2714
                            ).', '.$o_user_to_add['firstname'],
2715
                            ['title' => $username]
2716
                        ).
2717
                        ' [['.Security::remove_XSS(
2718
                            $_POST['title']
2719
                        )."_uass".$assig_user_id.' | '.$photo.']] '.$status_in_group.'</li>';
2720
                    // don't change this line without guaranteeing
2721
                    // that users will be ordered by last names in the
2722
                    // following format (surname, name)
2723
                    $values['assignment'] = 2;
2724
                }
2725
                $this->assig_user_id = $assig_user_id;
2726
                $this->save_new_wiki($values);
2727
            }
2728
        }
2729
2730
        foreach ($a_users_to_add as $o_user_to_add) {
2731
            if ($o_user_to_add['user_id'] == $userId) {
2732
                $assig_user_id = $o_user_to_add['user_id'];
2733
                if ($assignment_type == 1) {
2734
                    $values['title'] = $title_orig;
2735
                    $values['comment'] = get_lang('AssignmentDesc');
2736
                    sort($all_students_pages);
2737
                    $values['content'] = $content_orig_A.$content_orig_B.'<br/>
2738
                    <div align="center" style="font-size:18px; background-color: #F5F8FB; border:solid; border-color:#E6E6E6">
2739
                    '.get_lang('AssignmentLinkstoStudentsPage').'
2740
                    </div><br/>
2741
                    <div style="background-color: #F5F8FB; border:solid; border-color:#E6E6E6">
2742
                    <ol>'.implode($all_students_pages).'</ol>
2743
                    </div>
2744
                    <br/>';
2745
                    $values['assignment'] = 1;
2746
                }
2747
                $this->assig_user_id = $assig_user_id;
2748
                $this->save_new_wiki($values);
2749
            }
2750
        }
2751
    }
2752
2753
    /**
2754
     * Displays the results of a wiki search.
2755
     */
2756
    public function display_wiki_search_results(
2757
        string $search_term,
2758
        int $search_content = 0,
2759
        int $all_vers = 0,
2760
        array $categoryIdList = [],
2761
        bool $matchAllCategories = false
2762
    ) {
2763
        $tbl_wiki = $this->tbl_wiki;
2764
        $sessionCondition = api_get_session_condition($this->session_id, true, false, 'wp.session_id');
2765
        $groupfilter = ' wp.group_id = '.$this->group_id.' ';
2766
        $subGroupfilter = ' s2.group_id = '.$this->group_id.' ';
2767
        $subSessionCondition = api_get_session_condition($this->session_id, true, false, 's2.session_id').' ';
2768
        $categoryIdList = array_map('intval', $categoryIdList);
2769
        $categoriesJoin = '';
2770
2771
        if ($categoryIdList) {
2772
            if ($matchAllCategories) {
2773
                foreach ($categoryIdList as $categoryId) {
2774
                    $categoriesJoin .= "INNER JOIN c_wiki_rel_category AS wrc$categoryId
2775
                            ON (wp.iid = wrc$categoryId.wiki_id AND wrc$categoryId.category_id = $categoryId)
2776
                        INNER JOIN c_wiki_category AS wc$categoryId
2777
                            ON (wrc$categoryId.category_id = wc$categoryId.id) ";
2778
                }
2779
            } else {
2780
                $categoriesJoin = 'INNER JOIN c_wiki_rel_category AS wrc ON (wp.iid = wrc.wiki_id)
2781
                    INNER JOIN c_wiki_category AS wc ON (wrc.category_id = wc.id) ';
2782
            }
2783
        }
2784
2785
        $categoriesCondition = !$matchAllCategories
2786
            ? ($categoryIdList ? 'AND wc.id IN ('.implode(', ', $categoryIdList).')' : '')
2787
            : '';
2788
2789
        $course_id = api_get_course_int_id();
2790
        echo '<legend>'.get_lang('WikiSearchResults').': '.Security::remove_XSS($search_term).'</legend>';
2791
2792
        //only by professors when page is hidden
2793
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
2794
            if (1 === $all_vers) {
2795
                $sql = "SELECT * FROM $tbl_wiki AS wp $categoriesJoin
2796
                    WHERE wp.c_id = $course_id
2797
                        AND (wp.title LIKE '%".Database::escape_string($search_term)."%' ";
2798
2799
                if (1 === $search_content) {
2800
                    $sql .= "OR wp.content LIKE '%".Database::escape_string($search_term)."%' ";
2801
                }
2802
2803
                $sql .= ") AND ".$groupfilter.$sessionCondition.$categoriesCondition;
2804
            } else {
2805
                // warning don't use group by reflink because don't return the last version
2806
                $sql = "SELECT * FROM $tbl_wiki AS wp
2807
                    WHERE wp.c_id = $course_id
2808
                        AND (wp.title LIKE '%".Database::escape_string($search_term)."%' ";
2809
2810
                if (1 === $search_content) {
2811
                    // warning don't use group by reflink because don't return the last version
2812
                    $sql .= "OR wp.content LIKE '%".Database::escape_string($search_term)."%' ";
2813
                }
2814
2815
                $sql .= ") AND wp.id IN (
2816
                    SELECT MAX(s2.id)
2817
                    FROM ".$tbl_wiki." s2 $categoriesJoin
2818
                    WHERE s2.c_id = $course_id
2819
                        AND s2.reflink = wp.reflink
2820
                        AND ".$subGroupfilter.$subSessionCondition.$categoriesCondition."
2821
                )";
2822
            }
2823
        } else {
2824
            if (1 === $all_vers) {
2825
                $sql = "SELECT * FROM $tbl_wiki AS wp $categoriesJoin
2826
                    WHERE wp.c_id = $course_id
2827
                        AND wp.visibility = 1
2828
                        AND (wp.title LIKE '%".Database::escape_string($search_term)."%' ";
2829
2830
                if (1 === $search_content) {
2831
                    //search all pages and all versions
2832
                    $sql .= "OR wp.content LIKE '%".Database::escape_string($search_term)."%' ";
2833
                }
2834
2835
                $sql .= ") AND ".$groupfilter.$sessionCondition.$categoriesCondition;
2836
            } else {
2837
                // warning don't use group by reflink because don't return the last version
2838
                $sql = "SELECT * FROM $tbl_wiki AS wp 
2839
                    WHERE wp.c_id = $course_id
2840
                        AND wp.visibility = 1
2841
                        AND (wp.title LIKE '%".Database::escape_string($search_term)."%' ";
2842
2843
                if (1 === $search_content) {
2844
                    $sql .= "OR wp.content LIKE '%".Database::escape_string($search_term)."%' ";
2845
                }
2846
2847
                $sql .= ") AND wp.id IN (
2848
                        SELECT MAX(s2.id) FROM $tbl_wiki s2 $categoriesJoin
2849
                        WHERE s2.c_id = $course_id
2850
                            AND s2.reflink = wp.reflink
2851
                            AND ".$subGroupfilter.$subSessionCondition.$categoriesCondition."
2852
                    )";
2853
            }
2854
        }
2855
2856
        $result = Database::query($sql);
2857
2858
        //show table
2859
        $rows = [];
2860
        if (Database::num_rows($result) > 0) {
2861
            $self = api_get_self();
2862
            $cidReq = api_get_cidreq();
2863
2864
            $iconEdit = Display::return_icon('edit.png', get_lang('EditPage'));
2865
            $iconDiscuss = Display::return_icon('discuss.png', get_lang('Discuss'));
2866
            $iconHistory = Display::return_icon('history.png', get_lang('History'));
2867
            $iconLinks = Display::return_icon('what_link_here.png', get_lang('LinksPages'));
2868
            $iconDelete = Display::return_icon('delete.png', get_lang('Delete'));
2869
2870
            while ($obj = Database::fetch_object($result)) {
2871
                //get author
2872
                $userinfo = api_get_user_info($obj->user_id);
2873
2874
                //get type assignment icon
2875
                $ShowAssignment = '';
2876
                if ($obj->assignment == 1) {
2877
                    $ShowAssignment = Display::return_icon('wiki_assignment.png', get_lang('AssignmentDesc'));
2878
                } elseif ($obj->assignment == 2) {
2879
                    $ShowAssignment = Display::return_icon('wiki_work.png', get_lang('AssignmentWork'));
2880
                } elseif ($obj->assignment == 0) {
2881
                    $ShowAssignment = Display::return_icon('px_transparent.gif');
2882
                }
2883
                $row = [];
2884
                $row[] = $ShowAssignment;
2885
2886
                $wikiLinkParams = [
2887
                    'action' => 'showpage',
2888
                    'title' => api_htmlentities($obj->reflink),
2889
                    'session_id' => (int) $_GET['session_id'],
2890
                    'group_id' => (int) $_GET['group_id'],
2891
                ];
2892
2893
                if (1 === $all_vers) {
2894
                    $wikiLinkParams['view'] = $obj->id;
2895
                }
2896
2897
                $row[] = Display::url(
2898
                    api_htmlentities($obj->title),
2899
                    "$self?$cidReq&".http_build_query($wikiLinkParams)
2900
                ).$this->returnCategoriesBlock($obj->iid, '<div><small>', '</small></div>');
2901
2902
                $row[] = ($obj->user_id != 0 && $userinfo !== false)
2903
                    ? UserManager::getUserProfileLink($userinfo)
2904
                    : get_lang('Anonymous').' ('.$obj->user_ip.')';
2905
                $row[] = api_convert_and_format_date($obj->dtime);
2906
2907
                if (1 === $all_vers) {
2908
                    $row[] = $obj->version;
2909
                } else {
2910
                    $showdelete = '';
2911
                    if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
2912
                        $showdelete = Display::url(
2913
                            $iconDelete,
2914
                            "$self?$cidReq&".http_build_query([
2915
                                'action' => 'delete',
2916
                                'title' => api_htmlentities($obj->reflink),
2917
                                'group_id' => (int) $_GET['group_id'],
2918
                            ])
2919
                        );
2920
                    }
2921
2922
                    $row[] = Display::url(
2923
                            $iconEdit,
2924
                            "$self?$cidReq&".http_build_query([
2925
                                'action' => 'edit',
2926
                                'title' => api_htmlentities($obj->reflink),
2927
                                'group_id' => (int) $_GET['group_id'],
2928
                            ])
2929
                        )
2930
                        .Display::url(
2931
                            $iconDiscuss,
2932
                            "$self?$cidReq&".http_build_query([
2933
                                'action' => 'discuss',
2934
                                'title' => api_htmlentities($obj->reflink),
2935
                                'session_id' => (int) $_GET['session_id'],
2936
                                'group_id' => (int) $_GET['group_id'],
2937
                            ])
2938
                        )
2939
                        .Display::url(
2940
                            $iconHistory,
2941
                            "$self?$cidReq&".http_build_query([
2942
                                'action' => 'history',
2943
                                'title' => api_htmlentities($obj->reflink),
2944
                                'session_id' => (int) $_GET['session_id'],
2945
                                'group_id' => (int) $_GET['group_id'],
2946
                            ])
2947
                        )
2948
                        .Display::url(
2949
                            $iconLinks,
2950
                            "$self?$cidReq&".http_build_query([
2951
                                'action' => 'links',
2952
                                'title' => api_htmlentities($obj->reflink),
2953
                                'group_id' => (int) $_GET['group_id'],
2954
                            ])
2955
                        )
2956
                        .$showdelete;
2957
                }
2958
                $rows[] = $row;
2959
            }
2960
2961
            $table = new SortableTableFromArrayConfig(
2962
                $rows,
2963
                1,
2964
                10,
2965
                'SearchPages_table',
2966
                '',
2967
                '',
2968
                'ASC'
2969
            );
2970
            $table->set_additional_parameters(
2971
                [
2972
                    'cidReq' => $this->courseCode,
2973
                    'gidReq' => $this->group_id,
2974
                    'id_session' => $this->session_id,
2975
                    'action' => $_GET['action'],
2976
                    'mode_table' => 'yes2',
2977
                    'search_term' => $search_term,
2978
                    'search_content' => $search_content,
2979
                    'all_vers' => $all_vers,
2980
                ]
2981
            );
2982
            $table->set_header(
2983
                0,
2984
                get_lang('Type'),
2985
                true,
2986
                ['style' => 'width:30px;']
2987
            );
2988
            $table->set_header(1, get_lang('Title'));
2989
            if (1 === $all_vers) {
2990
                $table->set_header(2, get_lang('Author'));
2991
                $table->set_header(3, get_lang('Date'));
2992
                $table->set_header(4, get_lang('Version'));
2993
            } else {
2994
                $table->set_header(
2995
                    2,
2996
                    get_lang('Author').' <small>'.get_lang('LastVersion').'</small>'
2997
                );
2998
                $table->set_header(
2999
                    3,
3000
                    get_lang('Date').' <small>'.get_lang('LastVersion').'</small>'
3001
                );
3002
                $table->set_header(
3003
                    4,
3004
                    get_lang('Actions'),
3005
                    false,
3006
                    ['style' => 'width:130px;']
3007
                );
3008
            }
3009
            $table->display();
3010
        } else {
3011
            echo get_lang('NoSearchResults');
3012
        }
3013
    }
3014
3015
    /**
3016
     * Get wiki information.
3017
     *
3018
     * @param   int|bool wiki id
3019
     *
3020
     * @return array wiki data
3021
     */
3022
    public function getWikiDataFromDb($id)
3023
    {
3024
        $tbl_wiki = $this->tbl_wiki;
3025
        $course_id = api_get_course_int_id();
3026
        if ($id === false) {
3027
            return [];
3028
        }
3029
        $id = intval($id);
3030
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3031
                WHERE c_id = '.$course_id.' AND id = '.$id.' ';
3032
        $result = Database::query($sql);
3033
        $data = [];
3034
        while ($row = Database::fetch_array($result, 'ASSOC')) {
3035
            $data = $row;
3036
        }
3037
3038
        return $data;
3039
    }
3040
3041
    /**
3042
     * @param string $refLink
3043
     *
3044
     * @return array
3045
     */
3046
    public function getLastWikiData($refLink)
3047
    {
3048
        $tbl_wiki = $this->tbl_wiki;
3049
        $groupfilter = $this->groupfilter;
3050
        $condition_session = $this->condition_session;
3051
        $course_id = api_get_course_int_id();
3052
3053
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3054
                WHERE
3055
                    c_id = '.$course_id.' AND
3056
                    reflink="'.Database::escape_string($refLink).'" AND
3057
                    '.$groupfilter.$condition_session.'
3058
                ORDER BY id DESC';
3059
3060
        $result = Database::query($sql);
3061
3062
        return Database::fetch_array($result);
3063
    }
3064
3065
    /**
3066
     * Get wiki information.
3067
     *
3068
     * @param   string     wiki id
3069
     * @param int $courseId
3070
     *
3071
     * @return array wiki data
3072
     */
3073
    public function getPageByTitle($title, $courseId = null)
3074
    {
3075
        $tbl_wiki = $this->tbl_wiki;
3076
        if (empty($courseId)) {
3077
            $courseId = api_get_course_int_id();
3078
        } else {
3079
            $courseId = intval($courseId);
3080
        }
3081
3082
        if (empty($title) || empty($courseId)) {
3083
            return [];
3084
        }
3085
3086
        $title = Database::escape_string($title);
3087
        $sql = "SELECT * FROM $tbl_wiki
3088
                WHERE c_id = $courseId AND reflink = '$title'";
3089
        $result = Database::query($sql);
3090
        $data = [];
3091
        if (Database::num_rows($result)) {
3092
            $data = Database::fetch_array($result, 'ASSOC');
3093
        }
3094
3095
        return $data;
3096
    }
3097
3098
    /**
3099
     * @param string $title
3100
     * @param int    $courseId
3101
     * @param string
3102
     * @param string
3103
     *
3104
     * @return bool
3105
     */
3106
    public function deletePage(
3107
        $title,
3108
        $courseId,
3109
        $groupfilter = null,
3110
        $condition_session = null
3111
    ) {
3112
        $tbl_wiki = $this->tbl_wiki;
3113
        $tbl_wiki_discuss = $this->tbl_wiki_discuss;
3114
        $tbl_wiki_mailcue = $this->tbl_wiki_mailcue;
3115
        $tbl_wiki_conf = $this->tbl_wiki_conf;
3116
3117
        $pageInfo = self::getPageByTitle($title, $courseId);
3118
        if (!empty($pageInfo)) {
3119
            $pageId = $pageInfo['id'];
3120
            $sql = "DELETE FROM $tbl_wiki_conf
3121
                    WHERE c_id = $courseId AND page_id = $pageId";
3122
            Database::query($sql);
3123
3124
            $sql = 'DELETE FROM '.$tbl_wiki_discuss.'
3125
                    WHERE c_id = '.$courseId.' AND publication_id = '.$pageId;
3126
            Database::query($sql);
3127
3128
            $sql = 'DELETE FROM  '.$tbl_wiki_mailcue.'
3129
                    WHERE c_id = '.$courseId.' AND id = '.$pageId.' AND '.$groupfilter.$condition_session.'';
3130
            Database::query($sql);
3131
3132
            $sql = 'DELETE FROM '.$tbl_wiki.'
3133
                    WHERE c_id = '.$courseId.' AND id = '.$pageId.' AND '.$groupfilter.$condition_session.'';
3134
            Database::query($sql);
3135
            self::check_emailcue(0, 'E');
3136
3137
            return true;
3138
        }
3139
3140
        return false;
3141
    }
3142
3143
    /**
3144
     * @return array
3145
     */
3146
    public function getAllWiki()
3147
    {
3148
        $tbl_wiki = $this->tbl_wiki;
3149
        $course_id = $this->course_id;
3150
        $condition_session = $this->condition_session;
3151
3152
        $sql = "SELECT * FROM $tbl_wiki
3153
                WHERE
3154
                    c_id = $course_id AND
3155
                    is_editing != '0' ".$condition_session;
3156
        $result = Database::query($sql);
3157
3158
        return Database::store_result($result, 'ASSOC');
3159
    }
3160
3161
    /**
3162
     * @param int $isEditing
3163
     */
3164
    public function updateWikiIsEditing($isEditing)
3165
    {
3166
        $tbl_wiki = $this->tbl_wiki;
3167
        $course_id = $this->course_id;
3168
        $condition_session = $this->condition_session;
3169
        $isEditing = Database::escape_string($isEditing);
3170
3171
        $sql = 'UPDATE '.$tbl_wiki.' SET
3172
                is_editing = "0",
3173
                time_edit = NULL
3174
                WHERE
3175
                    c_id = '.$course_id.' AND
3176
                    is_editing="'.$isEditing.'" '.
3177
            $condition_session;
3178
        Database::query($sql);
3179
    }
3180
3181
    /**
3182
     * Release of blocked pages to prevent concurrent editions.
3183
     *
3184
     * @param int    $userId
3185
     * @param string $action
3186
     */
3187
    public function blockConcurrentEditions($userId, $action = null)
3188
    {
3189
        $result = self::getAllWiki();
3190
        if (!empty($result)) {
3191
            foreach ($result as $is_editing_block) {
3192
                $max_edit_time = 1200; // 20 minutes
3193
                $timestamp_edit = strtotime($is_editing_block['time_edit']);
3194
                $time_editing = time() - $timestamp_edit;
3195
3196
                // First prevent concurrent users and double version
3197
                if ($is_editing_block['is_editing'] == $userId) {
3198
                    Session::write('_version', $is_editing_block['version']);
3199
                } else {
3200
                    Session::erase('_version');
3201
                }
3202
                // Second checks if has exceeded the time that a page may
3203
                // be available or if a page was edited and saved by its author
3204
                if ($time_editing > $max_edit_time ||
3205
                    ($is_editing_block['is_editing'] == $userId &&
3206
                        $action != 'edit')
3207
                ) {
3208
                    self::updateWikiIsEditing($is_editing_block['is_editing']);
3209
                }
3210
            }
3211
        }
3212
    }
3213
3214
    /**
3215
     * Showing wiki stats.
3216
     */
3217
    public function getStats()
3218
    {
3219
        if (!api_is_allowed_to_edit(false, true)) {
3220
            return false;
3221
        }
3222
3223
        $tbl_wiki = $this->tbl_wiki;
3224
        $course_id = $this->course_id;
3225
        $condition_session = $this->condition_session;
3226
        $groupfilter = $this->groupfilter;
3227
        $session_id = $this->session_id;
3228
        $tbl_wiki_conf = $this->tbl_wiki_conf;
3229
3230
        echo '<div class="actions">'.get_lang('Statistics').'</div>';
3231
3232
        // Check all versions of all pages
3233
        $total_words = 0;
3234
        $total_links = 0;
3235
        $total_links_anchors = 0;
3236
        $total_links_mail = 0;
3237
        $total_links_ftp = 0;
3238
        $total_links_irc = 0;
3239
        $total_links_news = 0;
3240
        $total_wlinks = 0;
3241
        $total_images = 0;
3242
        $clean_total_flash = 0;
3243
        $total_flash = 0;
3244
        $total_mp3 = 0;
3245
        $total_flv_p = 0;
3246
        $total_flv = 0;
3247
        $total_youtube = 0;
3248
        $total_multimedia = 0;
3249
        $total_tables = 0;
3250
3251
        $sql = "SELECT *, COUNT(*) AS TOTAL_VERS, SUM(hits) AS TOTAL_VISITS
3252
                FROM ".$tbl_wiki."
3253
                WHERE c_id = $course_id AND ".$groupfilter.$condition_session."";
3254
3255
        $allpages = Database::query($sql);
3256
        while ($row = Database::fetch_array($allpages)) {
3257
            $total_versions = $row['TOTAL_VERS'];
3258
            $total_visits = intval($row['TOTAL_VISITS']);
3259
        }
3260
3261
        $sql = "SELECT * FROM ".$tbl_wiki."
3262
                WHERE c_id = $course_id AND ".$groupfilter.$condition_session."";
3263
        $allpages = Database::query($sql);
3264
3265
        while ($row = Database::fetch_array($allpages)) {
3266
            $total_words = $total_words + self::word_count($row['content']);
3267
            $total_links = $total_links + substr_count(
3268
                $row['content'],
3269
                "href="
3270
            );
3271
            $total_links_anchors = $total_links_anchors + substr_count(
3272
                $row['content'],
3273
                'href="#'
3274
            );
3275
            $total_links_mail = $total_links_mail + substr_count(
3276
                $row['content'],
3277
                'href="mailto'
3278
            );
3279
            $total_links_ftp = $total_links_ftp + substr_count(
3280
                $row['content'],
3281
                'href="ftp'
3282
            );
3283
            $total_links_irc = $total_links_irc + substr_count(
3284
                $row['content'],
3285
                'href="irc'
3286
            );
3287
            $total_links_news = $total_links_news + substr_count(
3288
                $row['content'],
3289
                'href="news'
3290
            );
3291
            $total_wlinks = $total_wlinks + substr_count($row['content'], "[[");
3292
            $total_images = $total_images + substr_count(
3293
                $row['content'],
3294
                "<img"
3295
            );
3296
            $clean_total_flash = preg_replace(
3297
                '/player.swf/',
3298
                ' ',
3299
                $row['content']
3300
            );
3301
            $total_flash = $total_flash + substr_count(
3302
                $clean_total_flash,
3303
                '.swf"'
3304
            );
3305
            //.swf" end quotes prevent insert swf through flvplayer (is not counted)
3306
            $total_mp3 = $total_mp3 + substr_count($row['content'], ".mp3");
3307
            $total_flv_p = $total_flv_p + substr_count($row['content'], ".flv");
3308
            $total_flv = $total_flv_p / 5;
3309
            $total_youtube = $total_youtube + substr_count(
3310
                $row['content'],
3311
                "http://www.youtube.com"
3312
            );
3313
            $total_multimedia = $total_multimedia + substr_count(
3314
                $row['content'],
3315
                "video/x-msvideo"
3316
            );
3317
            $total_tables = $total_tables + substr_count(
3318
                $row['content'],
3319
                "<table"
3320
            );
3321
        }
3322
3323
        // Check only last version of all pages (current page)
3324
        $sql = ' SELECT *, COUNT(*) AS TOTAL_PAGES, SUM(hits) AS TOTAL_VISITS_LV
3325
                FROM  '.$tbl_wiki.' s1
3326
                WHERE s1.c_id = '.$course_id.' AND id=(
3327
                    SELECT MAX(s2.id)
3328
                    FROM '.$tbl_wiki.' s2
3329
                    WHERE
3330
                        s2.c_id = '.$course_id.' AND
3331
                        s1.reflink = s2.reflink AND
3332
                        '.$groupfilter.' AND
3333
                        session_id='.$session_id.')';
3334
        $allpages = Database::query($sql);
3335
        while ($row = Database::fetch_array($allpages)) {
3336
            $total_pages = $row['TOTAL_PAGES'];
3337
            $total_visits_lv = intval($row['TOTAL_VISITS_LV']);
3338
        }
3339
3340
        $total_words_lv = 0;
3341
        $total_links_lv = 0;
3342
        $total_links_anchors_lv = 0;
3343
        $total_links_mail_lv = 0;
3344
        $total_links_ftp_lv = 0;
3345
        $total_links_irc_lv = 0;
3346
        $total_links_news_lv = 0;
3347
        $total_wlinks_lv = 0;
3348
        $total_images_lv = 0;
3349
        $clean_total_flash_lv = 0;
3350
        $total_flash_lv = 0;
3351
        $total_mp3_lv = 0;
3352
        $total_flv_p_lv = 0;
3353
        $total_flv_lv = 0;
3354
        $total_youtube_lv = 0;
3355
        $total_multimedia_lv = 0;
3356
        $total_tables_lv = 0;
3357
3358
        $sql = 'SELECT * FROM  '.$tbl_wiki.' s1
3359
                WHERE s1.c_id = '.$course_id.' AND id=(
3360
                    SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
3361
                    WHERE
3362
                        s2.c_id = '.$course_id.' AND
3363
                        s1.reflink = s2.reflink AND
3364
                        '.$groupfilter.' AND
3365
                        session_id='.$session_id.'
3366
                )';
3367
        $allpages = Database::query($sql);
3368
3369
        while ($row = Database::fetch_array($allpages)) {
3370
            $total_words_lv = $total_words_lv + self::word_count(
3371
                $row['content']
3372
            );
3373
            $total_links_lv = $total_links_lv + substr_count(
3374
                $row['content'],
3375
                "href="
3376
            );
3377
            $total_links_anchors_lv = $total_links_anchors_lv + substr_count(
3378
                $row['content'],
3379
                'href="#'
3380
            );
3381
            $total_links_mail_lv = $total_links_mail_lv + substr_count(
3382
                $row['content'],
3383
                'href="mailto'
3384
            );
3385
            $total_links_ftp_lv = $total_links_ftp_lv + substr_count(
3386
                $row['content'],
3387
                'href="ftp'
3388
            );
3389
            $total_links_irc_lv = $total_links_irc_lv + substr_count(
3390
                $row['content'],
3391
                'href="irc'
3392
            );
3393
            $total_links_news_lv = $total_links_news_lv + substr_count(
3394
                $row['content'],
3395
                'href="news'
3396
            );
3397
            $total_wlinks_lv = $total_wlinks_lv + substr_count(
3398
                $row['content'],
3399
                "[["
3400
            );
3401
            $total_images_lv = $total_images_lv + substr_count(
3402
                $row['content'],
3403
                "<img"
3404
            );
3405
            $clean_total_flash_lv = preg_replace(
3406
                '/player.swf/',
3407
                ' ',
3408
                $row['content']
3409
            );
3410
            $total_flash_lv = $total_flash_lv + substr_count(
3411
                $clean_total_flash_lv,
3412
                '.swf"'
3413
            );
3414
            //.swf" end quotes prevent insert swf through flvplayer (is not counted)
3415
            $total_mp3_lv = $total_mp3_lv + substr_count(
3416
                $row['content'],
3417
                ".mp3"
3418
            );
3419
            $total_flv_p_lv = $total_flv_p_lv + substr_count(
3420
                $row['content'],
3421
                ".flv"
3422
            );
3423
            $total_flv_lv = $total_flv_p_lv / 5;
3424
            $total_youtube_lv = $total_youtube_lv + substr_count(
3425
                $row['content'],
3426
                "http://www.youtube.com"
3427
            );
3428
            $total_multimedia_lv = $total_multimedia_lv + substr_count(
3429
                $row['content'],
3430
                "video/x-msvideo"
3431
            );
3432
            $total_tables_lv = $total_tables_lv + substr_count(
3433
                $row['content'],
3434
                "<table"
3435
            );
3436
        }
3437
3438
        //Total pages edited at this time
3439
        $total_editing_now = 0;
3440
        $sql = 'SELECT *, COUNT(*) AS TOTAL_EDITING_NOW
3441
                FROM  '.$tbl_wiki.' s1
3442
                WHERE is_editing!=0 AND s1.c_id = '.$course_id.' AND
3443
                id=(
3444
                    SELECT MAX(s2.id)
3445
                    FROM '.$tbl_wiki.' s2
3446
                    WHERE
3447
                        s2.c_id = '.$course_id.' AND
3448
                        s1.reflink = s2.reflink AND
3449
                        '.$groupfilter.' AND
3450
                        session_id='.$session_id.'
3451
        )';
3452
3453
        // Can not use group by because the mark is set in the latest version
3454
        $allpages = Database::query($sql);
3455
        while ($row = Database::fetch_array($allpages)) {
3456
            $total_editing_now = $row['TOTAL_EDITING_NOW'];
3457
        }
3458
3459
        // Total hidden pages
3460
        $total_hidden = 0;
3461
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3462
                WHERE
3463
                    c_id = '.$course_id.' AND
3464
                    visibility = 0 AND
3465
                    '.$groupfilter.$condition_session.'
3466
                GROUP BY reflink';
3467
        // or group by page_id. As the mark of hidden places it in all
3468
        // versions of the page, I can use group by to see the first
3469
        $allpages = Database::query($sql);
3470
        while ($row = Database::fetch_array($allpages)) {
3471
            $total_hidden = $total_hidden + 1;
3472
        }
3473
3474
        //Total protect pages
3475
        $total_protected = 0;
3476
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3477
                WHERE
3478
                    c_id = '.$course_id.' AND
3479
                    editlock = 1 AND
3480
                     '.$groupfilter.$condition_session.'
3481
                GROUP BY reflink';
3482
        // or group by page_id. As the mark of protected page is the
3483
        // first version of the page, I can use group by
3484
        $allpages = Database::query($sql);
3485
        while ($row = Database::fetch_array($allpages)) {
3486
            $total_protected = $total_protected + 1;
3487
        }
3488
3489
        // Total empty versions.
3490
        $total_empty_content = 0;
3491
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3492
                WHERE
3493
                    c_id = '.$course_id.' AND
3494
                    content="" AND
3495
                    '.$groupfilter.$condition_session.'';
3496
        $allpages = Database::query($sql);
3497
        while ($row = Database::fetch_array($allpages)) {
3498
            $total_empty_content = $total_empty_content + 1;
3499
        }
3500
3501
        //Total empty pages (last version)
3502
3503
        $total_empty_content_lv = 0;
3504
        $sql = 'SELECT  * FROM  '.$tbl_wiki.' s1
3505
                WHERE s1.c_id = '.$course_id.' AND content="" AND id=(
3506
                    SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
3507
                    WHERE
3508
                        s1.c_id = '.$course_id.' AND
3509
                        s1.reflink = s2.reflink AND
3510
                        '.$groupfilter.' AND
3511
                        session_id='.$session_id.'
3512
                )';
3513
        $allpages = Database::query($sql);
3514
        while ($row = Database::fetch_array($allpages)) {
3515
            $total_empty_content_lv = $total_empty_content_lv + 1;
3516
        }
3517
3518
        // Total locked discuss pages
3519
        $total_lock_disc = 0;
3520
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3521
                WHERE c_id = '.$course_id.' AND addlock_disc=0 AND '.$groupfilter.$condition_session.'
3522
                GROUP BY reflink'; //group by because mark lock in all vers, then always is ok
3523
        $allpages = Database::query($sql);
3524
        while ($row = Database::fetch_array($allpages)) {
3525
            $total_lock_disc = $total_lock_disc + 1;
3526
        }
3527
3528
        // Total hidden discuss pages.
3529
        $total_hidden_disc = 0;
3530
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3531
                WHERE c_id = '.$course_id.' AND visibility_disc=0 AND '.$groupfilter.$condition_session.'
3532
                GROUP BY reflink';
3533
        //group by because mark lock in all vers, then always is ok
3534
        $allpages = Database::query($sql);
3535
        while ($row = Database::fetch_array($allpages)) {
3536
            $total_hidden_disc = $total_hidden_disc + 1;
3537
        }
3538
3539
        // Total versions with any short comment by user or system
3540
        $total_comment_version = 0;
3541
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3542
                WHERE c_id = '.$course_id.' AND comment!="" AND '.$groupfilter.$condition_session.'';
3543
        $allpages = Database::query($sql);
3544
        while ($row = Database::fetch_array($allpages)) {
3545
            $total_comment_version = $total_comment_version + 1;
3546
        }
3547
3548
        // Total pages that can only be scored by teachers.
3549
        $total_only_teachers_rating = 0;
3550
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3551
                WHERE c_id = '.$course_id.' AND
3552
                ratinglock_disc = 0 AND
3553
                '.$groupfilter.$condition_session.'
3554
                GROUP BY reflink'; //group by because mark lock in all vers, then always is ok
3555
        $allpages = Database::query($sql);
3556
        while ($row = Database::fetch_array($allpages)) {
3557
            $total_only_teachers_rating = $total_only_teachers_rating + 1;
3558
        }
3559
3560
        // Total pages scored by peers
3561
        // put always this line alfter check num all pages and num pages rated by teachers
3562
        $total_rating_by_peers = $total_pages - $total_only_teachers_rating;
3563
3564
        //Total pages identified as standard task
3565
        $total_task = 0;
3566
        $sql = 'SELECT * FROM '.$tbl_wiki.', '.$tbl_wiki_conf.'
3567
              WHERE '.$tbl_wiki_conf.'.c_id = '.$course_id.' AND
3568
               '.$tbl_wiki_conf.'.task!="" AND
3569
               '.$tbl_wiki_conf.'.page_id='.$tbl_wiki.'.page_id AND
3570
                '.$tbl_wiki.'.'.$groupfilter.$condition_session;
3571
        $allpages = Database::query($sql);
3572
        while ($row = Database::fetch_array($allpages)) {
3573
            $total_task = $total_task + 1;
3574
        }
3575
3576
        //Total pages identified as teacher page (wiki portfolio mode - individual assignment)
3577
        $total_teacher_assignment = 0;
3578
        $sql = 'SELECT  * FROM  '.$tbl_wiki.' s1
3579
                WHERE s1.c_id = '.$course_id.' AND assignment=1 AND id=(
3580
                    SELECT MAX(s2.id)
3581
                    FROM '.$tbl_wiki.' s2
3582
                    WHERE
3583
                        s2.c_id = '.$course_id.' AND
3584
                        s1.reflink = s2.reflink AND
3585
                        '.$groupfilter.' AND
3586
                         session_id='.$session_id.'
3587
                )';
3588
        //mark all versions, but do not use group by reflink because y want the pages not versions
3589
        $allpages = Database::query($sql);
3590
        while ($row = Database::fetch_array($allpages)) {
3591
            $total_teacher_assignment = $total_teacher_assignment + 1;
3592
        }
3593
3594
        //Total pages identifies as student page (wiki portfolio mode - individual assignment)
3595
        $total_student_assignment = 0;
3596
        $sql = 'SELECT  * FROM  '.$tbl_wiki.' s1
3597
                WHERE s1.c_id = '.$course_id.' AND assignment=2 AND
3598
                id = (SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
3599
                WHERE
3600
                    s2.c_id = '.$course_id.' AND
3601
                    s1.reflink = s2.reflink AND
3602
                    '.$groupfilter.' AND
3603
                    session_id='.$session_id.'
3604
                )';
3605
        //mark all versions, but do not use group by reflink because y want the pages not versions
3606
        $allpages = Database::query($sql);
3607
        while ($row = Database::fetch_array($allpages)) {
3608
            $total_student_assignment = $total_student_assignment + 1;
3609
        }
3610
3611
        //Current Wiki status add new pages
3612
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3613
                WHERE c_id = '.$course_id.' AND '.$groupfilter.$condition_session.'
3614
                GROUP BY addlock'; //group by because mark 0 in all vers, then always is ok
3615
        $allpages = Database::query($sql);
3616
        $wiki_add_lock = null;
3617
        while ($row = Database::fetch_array($allpages)) {
3618
            $wiki_add_lock = $row['addlock'];
3619
        }
3620
3621
        if ($wiki_add_lock == 1) {
3622
            $status_add_new_pag = get_lang('Yes');
3623
        } else {
3624
            $status_add_new_pag = get_lang('No');
3625
        }
3626
3627
        // Creation date of the oldest wiki page and version
3628
        $first_wiki_date = null;
3629
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3630
                WHERE c_id = '.$course_id.' AND '.$groupfilter.$condition_session.'
3631
                ORDER BY dtime ASC
3632
                LIMIT 1';
3633
        $allpages = Database::query($sql);
3634
        while ($row = Database::fetch_array($allpages)) {
3635
            $first_wiki_date = api_get_local_time($row['dtime']);
3636
        }
3637
3638
        // Date of publication of the latest wiki version.
3639
3640
        $last_wiki_date = null;
3641
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3642
                WHERE c_id = '.$course_id.' AND '.$groupfilter.$condition_session.'
3643
                ORDER BY dtime DESC
3644
                LIMIT 1';
3645
        $allpages = Database::query($sql);
3646
        while ($row = Database::fetch_array($allpages)) {
3647
            $last_wiki_date = api_get_local_time($row['dtime']);
3648
        }
3649
3650
        // Average score of all wiki pages. (If a page has not scored zero rated)
3651
        $media_score = 0;
3652
        $sql = "SELECT *, SUM(score) AS TOTAL_SCORE FROM ".$tbl_wiki."
3653
                WHERE c_id = $course_id AND ".$groupfilter.$condition_session."
3654
                GROUP BY reflink ";
3655
        //group by because mark in all versions, then always is ok.
3656
        // Do not use "count" because using "group by", would give a wrong value
3657
        $allpages = Database::query($sql);
3658
        $total_score = 0;
3659
        while ($row = Database::fetch_array($allpages)) {
3660
            $total_score = $total_score + $row['TOTAL_SCORE'];
3661
        }
3662
3663
        if (!empty($total_pages)) {
3664
            $media_score = $total_score / $total_pages;
3665
            //put always this line alfter check num all pages
3666
        }
3667
3668
        // Average user progress in his pages.
3669
        $media_progress = 0;
3670
        $sql = 'SELECT  *, SUM(progress) AS TOTAL_PROGRESS
3671
                FROM  '.$tbl_wiki.' s1
3672
                WHERE s1.c_id = '.$course_id.' AND id=
3673
                (
3674
                    SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
3675
                    WHERE
3676
                        s2.c_id = '.$course_id.' AND
3677
                        s1.reflink = s2.reflink AND
3678
                        '.$groupfilter.' AND
3679
                        session_id='.$session_id.'
3680
                )';
3681
        // As the value is only the latest version I can not use group by
3682
        $allpages = Database::query($sql);
3683
        while ($row = Database::fetch_array($allpages)) {
3684
            $total_progress = $row['TOTAL_PROGRESS'];
3685
        }
3686
3687
        if (!empty($total_pages)) {
3688
            $media_progress = $total_progress / $total_pages;
3689
            //put always this line alfter check num all pages
3690
        }
3691
3692
        // Total users that have participated in the Wiki
3693
        $total_users = 0;
3694
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3695
                WHERE  c_id = '.$course_id.' AND '.$groupfilter.$condition_session.'
3696
                GROUP BY user_id';
3697
        //as the mark of user it in all versions of the page, I can use group by to see the first
3698
        $allpages = Database::query($sql);
3699
        while ($row = Database::fetch_array($allpages)) {
3700
            $total_users = $total_users + 1;
3701
        }
3702
3703
        // Total of different IP addresses that have participated in the wiki
3704
        $total_ip = 0;
3705
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3706
              WHERE c_id = '.$course_id.' AND '.$groupfilter.$condition_session.'
3707
              GROUP BY user_ip';
3708
        $allpages = Database::query($sql);
3709
        while ($row = Database::fetch_array($allpages)) {
3710
            $total_ip = $total_ip + 1;
3711
        }
3712
3713
        echo '<table class="table table-hover table-striped data_table">';
3714
        echo '<thead>';
3715
        echo '<tr>';
3716
        echo '<th colspan="2">'.get_lang('General').'</th>';
3717
        echo '</tr>';
3718
        echo '</thead>';
3719
        echo '<tr>';
3720
        echo '<td>'.get_lang('StudentAddNewPages').'</td>';
3721
        echo '<td>'.$status_add_new_pag.'</td>';
3722
        echo '</tr>';
3723
        echo '<tr>';
3724
        echo '<td>'.get_lang('DateCreateOldestWikiPage').'</td>';
3725
        echo '<td>'.$first_wiki_date.'</td>';
3726
        echo '</tr>';
3727
        echo '<tr>';
3728
        echo '<td>'.get_lang('DateEditLatestWikiVersion').'</td>';
3729
        echo '<td>'.$last_wiki_date.'</td>';
3730
        echo '</tr>';
3731
        echo '<tr>';
3732
        echo '<td>'.get_lang('AverageScoreAllPages').'</td>';
3733
        echo '<td>'.$media_score.' %</td>';
3734
        echo '</tr>';
3735
        echo '<tr>';
3736
        echo '<td>'.get_lang('AverageMediaUserProgress').'</td>';
3737
        echo '<td>'.$media_progress.' %</td>';
3738
        echo '</tr>';
3739
        echo '<tr>';
3740
        echo '<td>'.get_lang('TotalWikiUsers').'</td>';
3741
        echo '<td>'.$total_users.'</td>';
3742
        echo '</tr>';
3743
        echo '<tr>';
3744
        echo '<td>'.get_lang('TotalIpAdress').'</td>';
3745
        echo '<td>'.$total_ip.'</td>';
3746
        echo '</tr>';
3747
        echo '</table>';
3748
        echo '<br/>';
3749
3750
        echo '<table class="table table-hover table-striped data_table">';
3751
        echo '<thead>';
3752
        echo '<tr>';
3753
        echo '<th colspan="2">'.get_lang('Pages').' '.get_lang(
3754
                'And'
3755
            ).' '.get_lang('Versions').'</th>';
3756
        echo '</tr>';
3757
        echo '</thead>';
3758
        echo '<tr>';
3759
        echo '<td>'.get_lang('Pages').' - '.get_lang(
3760
                'NumContributions'
3761
            ).'</td>';
3762
        echo '<td>'.$total_pages.' ('.get_lang(
3763
                'Versions'
3764
            ).': '.$total_versions.')</td>';
3765
        echo '</tr>';
3766
        echo '<tr>';
3767
        echo '<td>'.get_lang('EmptyPages').'</td>';
3768
        echo '<td>'.$total_empty_content_lv.' ('.get_lang(
3769
                'Versions'
3770
            ).': '.$total_empty_content.')</td>';
3771
        echo '</tr>';
3772
        echo '<tr>';
3773
        echo '<td>'.get_lang('NumAccess').'</td>';
3774
        echo '<td>'.$total_visits_lv.' ('.get_lang(
3775
                'Versions'
3776
            ).': '.$total_visits.')</td>';
3777
        echo '</tr>';
3778
        echo '<tr>';
3779
        echo '<td>'.get_lang('TotalPagesEditedAtThisTime').'</td>';
3780
        echo '<td>'.$total_editing_now.'</td>';
3781
        echo '</tr>';
3782
        echo '<tr>';
3783
        echo '<td>'.get_lang('TotalHiddenPages').'</td>';
3784
        echo '<td>'.$total_hidden.'</td>';
3785
        echo '</tr>';
3786
        echo '<tr>';
3787
        echo '<td>'.get_lang('NumProtectedPages').'</td>';
3788
        echo '<td>'.$total_protected.'</td>';
3789
        echo '</tr>';
3790
        echo '<tr>';
3791
        echo '<td>'.get_lang('LockedDiscussPages').'</td>';
3792
        echo '<td>'.$total_lock_disc.'</td>';
3793
        echo '</tr>';
3794
        echo '<tr>';
3795
        echo '<td>'.get_lang('HiddenDiscussPages').'</td>';
3796
        echo '<td>'.$total_hidden_disc.'</td>';
3797
        echo '</tr>';
3798
        echo '<tr>';
3799
        echo '<td>'.get_lang('TotalComments').'</td>';
3800
        echo '<td>'.$total_comment_version.'</td>';
3801
        echo '</tr>';
3802
        echo '<tr>';
3803
        echo '<td>'.get_lang('TotalOnlyRatingByTeacher').'</td>';
3804
        echo '<td>'.$total_only_teachers_rating.'</td>';
3805
        echo '</tr>';
3806
        echo '<tr>';
3807
        echo '<td>'.get_lang('TotalRatingPeers').'</td>';
3808
        echo '<td>'.$total_rating_by_peers.'</td>';
3809
        echo '</tr>';
3810
        echo '<tr>';
3811
        echo '<td>'.get_lang('TotalTeacherAssignments').' - '.get_lang(
3812
                'PortfolioMode'
3813
            ).'</td>';
3814
        echo '<td>'.$total_teacher_assignment.'</td>';
3815
        echo '</tr>';
3816
        echo '<tr>';
3817
        echo '<td>'.get_lang('TotalStudentAssignments').' - '.get_lang(
3818
                'PortfolioMode'
3819
            ).'</td>';
3820
        echo '<td>'.$total_student_assignment.'</td>';
3821
        echo '</tr>';
3822
        echo '<tr>';
3823
        echo '<td>'.get_lang('TotalTask').' - '.get_lang(
3824
                'StandardMode'
3825
            ).'</td>';
3826
        echo '<td>'.$total_task.'</td>';
3827
        echo '</tr>';
3828
        echo '</table>';
3829
        echo '<br/>';
3830
3831
        echo '<table class="table table-hover table-striped data_table">';
3832
        echo '<thead>';
3833
        echo '<tr>';
3834
        echo '<th colspan="3">'.get_lang('ContentPagesInfo').'</th>';
3835
        echo '</tr>';
3836
        echo '<tr>';
3837
        echo '<td></td>';
3838
        echo '<td>'.get_lang('InTheLastVersion').'</td>';
3839
        echo '<td>'.get_lang('InAllVersions').'</td>';
3840
        echo '</tr>';
3841
        echo '</thead>';
3842
        echo '<tr>';
3843
        echo '<td>'.get_lang('NumWords').'</td>';
3844
        echo '<td>'.$total_words_lv.'</td>';
3845
        echo '<td>'.$total_words.'</td>';
3846
        echo '</tr>';
3847
        echo '<tr>';
3848
        echo '<td>'.get_lang('NumlinksHtmlImagMedia').'</td>';
3849
        echo '<td>'.$total_links_lv.' ('.get_lang(
3850
                'Anchors'
3851
            ).':'.$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>';
3852
        echo '<td>'.$total_links.' ('.get_lang(
3853
                'Anchors'
3854
            ).':'.$total_links_anchors.', Mail:'.$total_links_mail.', FTP:'.$total_links_ftp.', IRC:'.$total_links_irc.', News:'.$total_links_news.', ... ) </td>';
3855
        echo '</tr>';
3856
        echo '<tr>';
3857
        echo '<td>'.get_lang('NumWikilinks').'</td>';
3858
        echo '<td>'.$total_wlinks_lv.'</td>';
3859
        echo '<td>'.$total_wlinks.'</td>';
3860
        echo '</tr>';
3861
        echo '<tr>';
3862
        echo '<td>'.get_lang('NumImages').'</td>';
3863
        echo '<td>'.$total_images_lv.'</td>';
3864
        echo '<td>'.$total_images.'</td>';
3865
        echo '</tr>';
3866
        echo '<tr>';
3867
        echo '<td>'.get_lang('NumFlash').'</td>';
3868
        echo '<td>'.$total_flash_lv.'</td>';
3869
        echo '<td>'.$total_flash.'</td>';
3870
        echo '</tr>';
3871
        echo '<tr>';
3872
        echo '<td>'.get_lang('NumMp3').'</td>';
3873
        echo '<td>'.$total_mp3_lv.'</td>';
3874
        echo '<td>'.$total_mp3.'</td>';
3875
        echo '</tr>';
3876
        echo '<tr>';
3877
        echo '<td>'.get_lang('NumFlvVideo').'</td>';
3878
        echo '<td>'.$total_flv_lv.'</td>';
3879
        echo '<td>'.$total_flv.'</td>';
3880
        echo '</tr>';
3881
        echo '<tr>';
3882
        echo '<td>'.get_lang('NumYoutubeVideo').'</td>';
3883
        echo '<td>'.$total_youtube_lv.'</td>';
3884
        echo '<td>'.$total_youtube.'</td>';
3885
        echo '</tr>';
3886
        echo '<tr>';
3887
        echo '<td>'.get_lang('NumOtherAudioVideo').'</td>';
3888
        echo '<td>'.$total_multimedia_lv.'</td>';
3889
        echo '<td>'.$total_multimedia.'</td>';
3890
        echo '</tr>';
3891
        echo '<tr>';
3892
        echo '<td>'.get_lang('NumTables').'</td>';
3893
        echo '<td>'.$total_tables_lv.'</td>';
3894
        echo '<td>'.$total_tables.'</td>';
3895
        echo '</tr>';
3896
        echo '</table>';
3897
    }
3898
3899
    /**
3900
     * @param string $action
3901
     */
3902
    public function getActiveUsers($action)
3903
    {
3904
        $tbl_wiki = $this->tbl_wiki;
3905
        $course_id = $this->course_id;
3906
        $condition_session = $this->condition_session;
3907
        $groupfilter = $this->groupfilter;
3908
        $_course = $this->courseInfo;
3909
3910
        echo '<div class="actions">'.get_lang('MostActiveUsers').'</div>';
3911
        $sql = 'SELECT *, COUNT(*) AS NUM_EDIT FROM '.$tbl_wiki.'
3912
                WHERE  c_id = '.$course_id.' AND '.$groupfilter.$condition_session.'
3913
                GROUP BY user_id';
3914
        $allpages = Database::query($sql);
3915
3916
        //show table
3917
        if (Database::num_rows($allpages) > 0) {
3918
            while ($obj = Database::fetch_object($allpages)) {
3919
                $userinfo = api_get_user_info($obj->user_id);
3920
                $row = [];
3921
                if ($obj->user_id != 0 && $userinfo !== false) {
3922
                    $row[] = Display::url(
3923
                        $userinfo['complete_name_with_username'],
3924
                        $this->url.'&'.http_build_query(['action' => 'usercontrib', 'user_id' => (int) $obj->user_id])
3925
                    );
3926
                } else {
3927
                    $row[] = get_lang('Anonymous').' ('.$obj->user_ip.')';
3928
                }
3929
                $row[] = Display::url(
3930
                    $obj->NUM_EDIT,
3931
                    $this->url.'&'.http_build_query(['action' => 'usercontrib', 'user_id' => (int) $obj->user_id])
3932
                );
3933
                $rows[] = $row;
3934
            }
3935
3936
            $table = new SortableTableFromArrayConfig(
3937
                $rows,
3938
                1,
3939
                10,
3940
                'MostActiveUsersA_table',
3941
                '',
3942
                '',
3943
                'DESC'
3944
            );
3945
            $table->set_additional_parameters(
3946
                [
3947
                    'cidReq' => $this->courseCode,
3948
                    'gidReq' => $this->group_id,
3949
                    'id_session' => $this->session_id,
3950
                    'action' => Security::remove_XSS($action),
3951
                ]
3952
            );
3953
            $table->set_header(0, get_lang('Author'), true);
3954
            $table->set_header(
3955
                1,
3956
                get_lang('Contributions'),
3957
                true,
3958
                ['style' => 'width:30px;']
3959
            );
3960
            $table->display();
3961
        }
3962
    }
3963
3964
    /**
3965
     * @param string $page
3966
     */
3967
    public function getDiscuss($page)
3968
    {
3969
        $tbl_wiki = $this->tbl_wiki;
3970
        $course_id = $this->course_id;
3971
        $condition_session = $this->condition_session;
3972
        $groupfilter = $this->groupfilter;
3973
        $tbl_wiki_discuss = $this->tbl_wiki_discuss;
3974
3975
        if (api_get_session_id() != 0 &&
3976
            api_is_allowed_to_session_edit(false, true) == false
3977
        ) {
3978
            api_not_allowed();
3979
        }
3980
3981
        if (!$_GET['title']) {
3982
            Display::addFlash(
3983
                Display::return_message(
3984
                    get_lang("MustSelectPage"),
3985
                    'error',
3986
                    false
3987
                )
3988
            );
3989
3990
            return;
3991
        }
3992
3993
        // First extract the date of last version
3994
        $sql = 'SELECT * FROM '.$tbl_wiki.'
3995
                WHERE
3996
                    c_id = '.$course_id.' AND
3997
                    reflink = "'.Database::escape_string($page).'" AND
3998
                    '.$groupfilter.$condition_session.'
3999
                ORDER BY id DESC';
4000
        $result = Database::query($sql);
4001
        $row = Database::fetch_array($result);
4002
        $lastversiondate = api_get_local_time($row['dtime']);
4003
        $lastuserinfo = api_get_user_info($row['user_id']);
4004
4005
        // Select page to discuss
4006
        $sql = 'SELECT * FROM '.$tbl_wiki.'
4007
                WHERE
4008
                    c_id = '.$course_id.' AND
4009
                    reflink="'.Database::escape_string($page).'" AND
4010
                    '.$groupfilter.$condition_session.'
4011
                ORDER BY id ASC';
4012
        $result = Database::query($sql);
4013
        $row = Database::fetch_array($result);
4014
        $id = $row['id'];
4015
        $firstuserid = $row['user_id'];
4016
4017
        if (isset($_POST['Submit']) && self::double_post($_POST['wpost_id'])) {
4018
            $dtime = api_get_utc_datetime();
4019
            $message_author = api_get_user_id();
4020
4021
            $params = [
4022
                'c_id' => $course_id,
4023
                'publication_id' => $id,
4024
                'userc_id' => $message_author,
4025
                'comment' => $_POST['comment'],
4026
                'p_score' => $_POST['rating'],
4027
                'dtime' => $dtime,
4028
            ];
4029
            $discussId = Database::insert($tbl_wiki_discuss, $params);
4030
            if ($discussId) {
4031
                $sql = "UPDATE $tbl_wiki_discuss SET id = iid WHERE iid = $discussId";
4032
                Database::query($sql);
4033
            }
4034
4035
            self::check_emailcue($id, 'D', $dtime, $message_author);
4036
4037
            header(
4038
                'Location: index.php?action=discuss&title='.api_htmlentities(urlencode($page)).'&'.api_get_cidreq()
4039
            );
4040
            exit;
4041
        }
4042
4043
        // mode assignment: previous to show  page type
4044
        $icon_assignment = null;
4045
        if ($row['assignment'] == 1) {
4046
            $icon_assignment = Display::return_icon(
4047
                'wiki_assignment.png',
4048
                get_lang('AssignmentDescExtra'),
4049
                '',
4050
                ICON_SIZE_SMALL
4051
            );
4052
        } elseif ($row['assignment'] == 2) {
4053
            $icon_assignment = Display::return_icon(
4054
                'wiki_work.png',
4055
                get_lang('AssignmentWorkExtra'),
4056
                '',
4057
                ICON_SIZE_SMALL
4058
            );
4059
        }
4060
4061
        $countWPost = null;
4062
        $avg_WPost_score = null;
4063
4064
        // Show title and form to discuss if page exist
4065
        if ($id != '') {
4066
            // Show discussion to students if isn't hidden.
4067
            // Show page to all teachers if is hidden.
4068
            // Mode assignments: If is hidden, show pages to student only if student is the author
4069
            if ($row['visibility_disc'] == 1 ||
4070
                api_is_allowed_to_edit(false, true) ||
4071
                api_is_platform_admin() ||
4072
                ($row['assignment'] == 2 && $row['visibility_disc'] == 0 && (api_get_user_id() == $row['user_id']))
4073
            ) {
4074
                echo '<div id="wikititle">';
4075
                // discussion action: protecting (locking) the discussion
4076
                $addlock_disc = null;
4077
                $lock_unlock_disc = null;
4078
                if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4079
                    if (self::check_addlock_discuss() == 1) {
4080
                        $addlock_disc = Display::return_icon(
4081
                            'unlock.png',
4082
                            get_lang('UnlockDiscussExtra'),
4083
                            '',
4084
                            ICON_SIZE_SMALL
4085
                        );
4086
                        $lock_unlock_disc = 'unlockdisc';
4087
                    } else {
4088
                        $addlock_disc = Display::return_icon(
4089
                            'lock.png',
4090
                            get_lang('LockDiscussExtra'),
4091
                            '',
4092
                            ICON_SIZE_SMALL
4093
                        );
4094
                        $lock_unlock_disc = 'lockdisc';
4095
                    }
4096
                }
4097
                echo '<span style="float:right">';
4098
                echo '<a href="index.php?'.api_get_cidreq().'&action=discuss&actionpage='.$lock_unlock_disc.'&title='.api_htmlentities(
4099
                        urlencode($page)
4100
                    ).'">'.$addlock_disc.'</a>';
4101
                echo '</span>';
4102
4103
                // discussion action: visibility.  Show discussion to students if isn't hidden. Show page to all teachers if is hidden.
4104
                $visibility_disc = null;
4105
                $hide_show_disc = null;
4106
                if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4107
                    if (self::check_visibility_discuss() == 1) {
4108
                        /// TODO: 	Fix Mode assignments: If is hidden, show discussion to student only if student is the author
4109
                        $visibility_disc = Display::return_icon(
4110
                            'visible.png',
4111
                            get_lang('ShowDiscussExtra'),
4112
                            '',
4113
                            ICON_SIZE_SMALL
4114
                        );
4115
                        $hide_show_disc = 'hidedisc';
4116
                    } else {
4117
                        $visibility_disc = Display::return_icon(
4118
                            'invisible.png',
4119
                            get_lang('HideDiscussExtra'),
4120
                            '',
4121
                            ICON_SIZE_SMALL
4122
                        );
4123
                        $hide_show_disc = 'showdisc';
4124
                    }
4125
                }
4126
                echo '<span style="float:right">';
4127
                echo '<a href="index.php?'.api_get_cidreq().'&action=discuss&actionpage='.$hide_show_disc.'&title='.api_htmlentities(
4128
                        urlencode($page)
4129
                    ).'">'.$visibility_disc.'</a>';
4130
                echo '</span>';
4131
4132
                // discussion action: check add rating lock. Show/Hide list to rating for all student
4133
                $lock_unlock_rating_disc = null;
4134
                $ratinglock_disc = null;
4135
                if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4136
                    if (self::check_ratinglock_discuss() == 1) {
4137
                        $ratinglock_disc = Display::return_icon(
4138
                            'star.png',
4139
                            get_lang('UnlockRatingDiscussExtra'),
4140
                            '',
4141
                            ICON_SIZE_SMALL
4142
                        );
4143
                        $lock_unlock_rating_disc = 'unlockrating';
4144
                    } else {
4145
                        $ratinglock_disc = Display::return_icon(
4146
                            'star_na.png',
4147
                            get_lang('LockRatingDiscussExtra'),
4148
                            '',
4149
                            ICON_SIZE_SMALL
4150
                        );
4151
                        $lock_unlock_rating_disc = 'lockrating';
4152
                    }
4153
                }
4154
4155
                echo '<span style="float:right">';
4156
                echo '<a href="index.php?'.api_get_cidreq().'&action=discuss&actionpage='.$lock_unlock_rating_disc.'&title='.api_htmlentities(
4157
                        urlencode($page)
4158
                    ).'">'.$ratinglock_disc.'</a>';
4159
                echo '</span>';
4160
4161
                // discussion action: email notification
4162
                if (self::check_notify_discuss($page) == 1) {
4163
                    $notify_disc = Display::return_icon(
4164
                        'messagebox_info.png',
4165
                        get_lang('NotifyDiscussByEmail'),
4166
                        '',
4167
                        ICON_SIZE_SMALL
4168
                    );
4169
                    $lock_unlock_notify_disc = 'unlocknotifydisc';
4170
                } else {
4171
                    $notify_disc = Display::return_icon(
4172
                        'mail.png',
4173
                        get_lang('CancelNotifyDiscussByEmail'),
4174
                        '',
4175
                        ICON_SIZE_SMALL
4176
                    );
4177
                    $lock_unlock_notify_disc = 'locknotifydisc';
4178
                }
4179
                echo '<span style="float:right">';
4180
                echo '<a href="index.php?'.api_get_cidreq().'&action=discuss&actionpage='.$lock_unlock_notify_disc.'&title='.api_htmlentities(
4181
                        urlencode($page)
4182
                    ).'">'.$notify_disc.'</a>';
4183
                echo '</span>';
4184
                echo $icon_assignment.'&nbsp;&nbsp;&nbsp;'.api_htmlentities(
4185
                        $row['title']
4186
                    );
4187
                if ($lastuserinfo !== false) {
4188
                    echo ' ('.get_lang('MostRecentVersionBy').' '.
4189
                        UserManager::getUserProfileLink($lastuserinfo).' '.$lastversiondate.$countWPost.')'.$avg_WPost_score.' '; //TODO: read average score
4190
                }
4191
4192
                echo '</div>';
4193
                if ($row['addlock_disc'] == 1 || api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4194
                    //show comments but students can't add theirs
4195
                    ?>
4196
                    <div class="panel panel-default">
4197
                        <div class="panel-body">
4198
                            <form name="form1" method="post" action=""
4199
                                  class="form-horizontal">
4200
                                <div class="form-group">
4201
                                    <label
4202
                                        class="col-sm-2 control-label">
4203
                                        <?php echo get_lang('Comments'); ?>:</label>
4204
                                    <div class="col-sm-10">
4205
                                        <?php echo '<input type="hidden" name="wpost_id" value="'.md5(uniqid(rand(), true)).'">'; //prevent double post?>
4206
                                        <textarea class="form-control"
4207
                                                  name="comment" cols="80"
4208
                                                  rows="5"
4209
                                                  id="comment">
4210
                                        </textarea>
4211
                                    </div>
4212
                                </div>
4213
                                <div class="form-group">
4214
                                    <?php
4215
                                    //check if rating is allowed
4216
                                    if ($row['ratinglock_disc'] == 1 || api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4217
                                        ?>
4218
                                        <label
4219
                                            class="col-sm-2 control-label"><?php echo get_lang('Rating'); ?>:</label>
4220
                                        <div class="col-sm-10">
4221
                                            <select name="rating" id="rating" class="selectpicker">
4222
                                                <option value="-" selected>-</option>
4223
                                                <option value="0">0</option>
4224
                                                <option value="1">1</option>
4225
                                                <option value="2">2</option>
4226
                                                <option value="3">3</option>
4227
                                                <option value="4">4</option>
4228
                                                <option value="5">5</option>
4229
                                                <option value="6">6</option>
4230
                                                <option value="7">7</option>
4231
                                                <option value="8">8</option>
4232
                                                <option value="9">9</option>
4233
                                                <option value="10">10</option>
4234
                                            </select>
4235
                                        </div>
4236
                                        <?php
4237
                                    } else {
4238
                                        echo '<input type=hidden name="rating" value="-">';
4239
                                        // must pass a default value to avoid rate automatically
4240
                                    } ?>
4241
4242
                                </div>
4243
                                <div class="form-group">
4244
                                    <div class="col-sm-offset-2 col-sm-10">
4245
                                        <?php echo '<button class="btn btn-default" type="submit" name="Submit"> '.
4246
                                            get_lang('Send').'</button>'; ?>
4247
                                    </div>
4248
                                </div>
4249
                        </div>
4250
                    </div>
4251
                    </form>
4252
                    <?php
4253
                }
4254
                // end discuss lock
4255
4256
                echo '<hr noshade size="1">';
4257
                $user_table = Database::get_main_table(TABLE_MAIN_USER);
4258
4259
                $sql = "SELECT *
4260
                        FROM $tbl_wiki_discuss reviews, $user_table user
4261
                        WHERE
4262
                            reviews.c_id = $course_id AND
4263
                            reviews.publication_id='".$id."' AND
4264
                            user.user_id='".$firstuserid."'
4265
                        ORDER BY reviews.id DESC";
4266
                $result = Database::query($sql);
4267
4268
                $countWPost = Database::num_rows($result);
4269
                echo get_lang('NumComments').": ".$countWPost; //comment's numbers
4270
4271
                $sql = "SELECT SUM(p_score) as sumWPost
4272
                        FROM $tbl_wiki_discuss
4273
                        WHERE c_id = $course_id AND publication_id = '".$id."' AND NOT p_score='-'
4274
                        ORDER BY id DESC";
4275
                $result2 = Database::query($sql);
4276
                $row2 = Database::fetch_array($result2);
4277
4278
                $sql = "SELECT * FROM $tbl_wiki_discuss
4279
                        WHERE c_id = $course_id AND publication_id='".$id."' AND NOT p_score='-'";
4280
                $result3 = Database::query($sql);
4281
                $countWPost_score = Database::num_rows($result3);
4282
4283
                echo ' - '.get_lang('NumCommentsScore').': '.$countWPost_score;
4284
4285
                if ($countWPost_score != 0) {
4286
                    $avg_WPost_score = round($row2['sumWPost'] / $countWPost_score, 2).' / 10';
4287
                } else {
4288
                    $avg_WPost_score = $countWPost_score;
4289
                }
4290
4291
                echo ' - '.get_lang('RatingMedia').': '.$avg_WPost_score; // average rating
4292
4293
                $sql = 'UPDATE '.$tbl_wiki.' SET
4294
                        score = "'.Database::escape_string($avg_WPost_score).'"
4295
                        WHERE
4296
                            c_id = '.$course_id.' AND
4297
                            reflink="'.Database::escape_string($page).'" AND
4298
                            '.$groupfilter.$condition_session;
4299
                // check if work ok. TODO:
4300
                Database::query($sql);
4301
4302
                echo '<hr noshade size="1">';
4303
                while ($row = Database::fetch_array($result)) {
4304
                    $userinfo = api_get_user_info($row['userc_id']);
4305
                    if (($userinfo['status']) == "5") {
4306
                        $author_status = get_lang('Student');
4307
                    } else {
4308
                        $author_status = get_lang('Teacher');
4309
                    }
4310
4311
                    $name = $userinfo['complete_name'];
4312
                    $author_photo = '<img src="'.$userinfo['avatar'].'" alt="'.api_htmlentities($name).'"  width="40" height="50" align="top"  title="'.api_htmlentities($name).'"  />';
4313
4314
                    // stars
4315
                    $p_score = $row['p_score'];
4316
                    switch ($p_score) {
4317
                        case 0:
4318
                            $imagerating = Display::return_icon(
4319
                                'rating/stars_0.gif'
4320
                            );
4321
                            break;
4322
                        case 1:
4323
                            $imagerating = Display::return_icon(
4324
                                'rating/stars_5.gif'
4325
                            );
4326
                            break;
4327
                        case 2:
4328
                            $imagerating = Display::return_icon(
4329
                                'rating/stars_10.gif'
4330
                            );
4331
                            break;
4332
                        case 3:
4333
                            $imagerating = Display::return_icon(
4334
                                'rating/stars_15.gif'
4335
                            );
4336
                            break;
4337
                        case 4:
4338
                            $imagerating = Display::return_icon(
4339
                                'rating/stars_20.gif'
4340
                            );
4341
                            break;
4342
                        case 5:
4343
                            $imagerating = Display::return_icon(
4344
                                'rating/stars_25.gif'
4345
                            );
4346
                            break;
4347
                        case 6:
4348
                            $imagerating = Display::return_icon(
4349
                                'rating/stars_30.gif'
4350
                            );
4351
                            break;
4352
                        case 7:
4353
                            $imagerating = Display::return_icon(
4354
                                'rating/stars_35.gif'
4355
                            );
4356
                            break;
4357
                        case 8:
4358
                            $imagerating = Display::return_icon(
4359
                                'rating/stars_40.gif'
4360
                            );
4361
                            break;
4362
                        case 9:
4363
                            $imagerating = Display::return_icon(
4364
                                'rating/stars_45.gif'
4365
                            );
4366
                            break;
4367
                        case 10:
4368
                            $imagerating = Display::return_icon(
4369
                                'rating/stars_50.gif'
4370
                            );
4371
                            break;
4372
                    }
4373
                    echo '<p><table>';
4374
                    echo '<tr>';
4375
                    echo '<td rowspan="2">'.$author_photo.'</td>';
4376
                    $userProfile = '';
4377
                    if ($userinfo !== false) {
4378
                        $userProfile = UserManager::getUserProfileLink(
4379
                            $userinfo
4380
                        );
4381
                    }
4382
                    echo '<td style=" color:#999999">'.$userProfile.' ('.$author_status.') '.
4383
                        api_get_local_time(
4384
                            $row['dtime']
4385
                        ).
4386
                        ' - '.get_lang(
4387
                            'Rating'
4388
                        ).': '.$row['p_score'].' '.$imagerating.' </td>';
4389
                    echo '</tr>';
4390
                    echo '<tr>';
4391
                    echo '<td>'.api_htmlentities($row['comment']).'</td>';
4392
                    echo '</tr>';
4393
                    echo "</table>";
4394
                }
4395
            } else {
4396
                Display::addFlash(
4397
                    Display::return_message(
4398
                        get_lang('LockByTeacher'),
4399
                        'warning',
4400
                        false
4401
                    )
4402
                );
4403
            }
4404
        } else {
4405
            Display::addFlash(
4406
                Display::return_message(
4407
                    get_lang('DiscussNotAvailable'),
4408
                    'normal',
4409
                    false
4410
                )
4411
            );
4412
        }
4413
    }
4414
4415
    /**
4416
     * Show all pages.
4417
     */
4418
    public function allPages($action)
4419
    {
4420
        $_course = $this->courseInfo;
4421
4422
        echo '<div class="actions">'.get_lang('AllPages');
4423
4424
        // menu delete all wiki
4425
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4426
            echo ' <a href="index.php?action=deletewiki&'.api_get_cidreq().'">'.
4427
                Display::return_icon(
4428
                    'delete.png',
4429
                    get_lang('DeleteWiki'),
4430
                    '',
4431
                    ICON_SIZE_MEDIUM
4432
                ).'</a>';
4433
        }
4434
        echo '</div>';
4435
4436
        //show table
4437
        $table = new SortableTable(
4438
            'AllPages_table',
4439
            function () {
4440
                $result = $this->gelAllPagesQuery(true);
4441
4442
                return (int) Database::fetch_assoc($result)['nbr'];
4443
            },
4444
            function ($from, $numberOfItems, $column, $direction) {
4445
                $result = $this->gelAllPagesQuery(false, $from, $numberOfItems, $column, $direction);
4446
                $rows = [];
4447
4448
                while ($data = Database::fetch_assoc($result)) {
4449
                    $rows[] = [
4450
                        $data['col0'],
4451
                        [$data['col1'], $data['reflink'], $data['iid']],
4452
                        [$data['col2'], $data['user_ip']],
4453
                        $data['col3'],
4454
                        $data['reflink'],
4455
                    ];
4456
                }
4457
4458
                return $rows;
4459
            }
4460
        );
4461
        $table->set_additional_parameters(
4462
            [
4463
                'cidReq' => $this->courseCode,
4464
                'gidReq' => $this->group_id,
4465
                'id_session' => $this->session_id,
4466
                'action' => Security::remove_XSS($action),
4467
            ]
4468
        );
4469
        $table->set_header(
4470
            0,
4471
            get_lang('Type'),
4472
            true,
4473
            ['style' => 'width:30px;']
4474
        );
4475
        $table->set_header(1, get_lang('Title'));
4476
        $table->set_header(
4477
            2,
4478
            get_lang('Author').' <small>'.get_lang('LastVersion').'</small>'
4479
        );
4480
        $table->set_header(
4481
            3,
4482
            get_lang('Date').' <small>'.get_lang('LastVersion').'</small>'
4483
        );
4484
        if (api_is_allowed_to_session_edit(false, true)) {
4485
            $table->set_header(
4486
                4,
4487
                get_lang('Actions'),
4488
                false,
4489
                ['style' => 'width: 145px;']
4490
            );
4491
        }
4492
        $table->set_column_filter(
4493
            0,
4494
            function ($value, string $urlParams, array $row) {
4495
                $return = '';
4496
                //get type assignment icon
4497
                if (1 == $value) {
4498
                    $return .= Display::return_icon(
4499
                        'wiki_assignment.png',
4500
                        get_lang('AssignmentDesc'),
4501
                        '',
4502
                        ICON_SIZE_SMALL
4503
                    );
4504
                } elseif (2 == $value) {
4505
                    $return .= Display::return_icon(
4506
                        'wiki_work.png',
4507
                        get_lang('AssignmentWork'),
4508
                        '',
4509
                        ICON_SIZE_SMALL
4510
                    );
4511
                } elseif (0 == $value) {
4512
                    $return .= Display::return_icon(
4513
                        'px_transparent.gif'
4514
                    );
4515
                }
4516
4517
                //get icon task
4518
                if (!empty($row['task'])) {
4519
                    $return .= Display::return_icon(
4520
                        'wiki_task.png',
4521
                        get_lang('StandardTask'),
4522
                        '',
4523
                        ICON_SIZE_SMALL
4524
                    );
4525
                } else {
4526
                    $return .= Display::return_icon('px_transparent.gif');
4527
                }
4528
4529
                return $return;
4530
            }
4531
        );
4532
        $table->set_column_filter(
4533
            1,
4534
            function ($value) {
4535
                list($title, $refLink, $iid) = $value;
4536
4537
                return Display::url(
4538
                        api_htmlentities($title),
4539
                        $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($refLink)])
4540
                    )
4541
                    .$this->returnCategoriesBlock($iid, '<div><small>', '</small></div>');
4542
            }
4543
        );
4544
        $table->set_column_filter(
4545
            2,
4546
            function ($value) {
4547
                list($userId, $userIp) = $value;
4548
                //get author
4549
                $userinfo = api_get_user_info($userId);
4550
4551
                if ($userinfo !== false) {
4552
                    return UserManager::getUserProfileLink($userinfo);
4553
                }
4554
4555
                return get_lang('Anonymous').' ('.api_htmlentities($userIp).')';
4556
            }
4557
        );
4558
        $table->set_column_filter(
4559
            3,
4560
            function ($value) {
4561
                return api_get_local_time($value);
4562
            }
4563
        );
4564
        $table->set_column_filter(
4565
            4,
4566
            function ($value) {
4567
                $actions = '';
4568
4569
                if (api_is_allowed_to_session_edit(false, true)) {
4570
                    $actions = Display::url(
4571
                            Display::return_icon('edit.png', get_lang('EditPage')),
4572
                            $this->url.'&'.http_build_query(['action' => 'edit', 'title' => api_htmlentities($value)])
4573
                        )
4574
                        .Display::url(
4575
                            Display::return_icon('discuss.png', get_lang('Discuss')),
4576
                            $this->url.'&'.http_build_query(['action' => 'discuss', 'title' => api_htmlentities($value)])
4577
                        )
4578
                        .Display::url(
4579
                            Display::return_icon('history.png', get_lang('History')),
4580
                            $this->url.'&'.http_build_query(['action' => 'history', 'title' => api_htmlentities($value)])
4581
                        )
4582
                        .Display::url(
4583
                            Display::return_icon('what_link_here.png', get_lang('LinksPages')),
4584
                            $this->url.'&'.http_build_query(['action' => 'links', 'title' => api_htmlentities($value)])
4585
                        )
4586
                    ;
4587
                }
4588
4589
                if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4590
                    $actions .= Display::url(
4591
                            Display::return_icon('delete.png', get_lang('Delete')),
4592
                            $this->url.'&'.http_build_query(['action' => 'delete', 'title' => api_htmlentities($value)])
4593
                        )
4594
                    ;
4595
                }
4596
4597
                return $actions;
4598
            }
4599
        );
4600
        $table->display();
4601
    }
4602
4603
    /**
4604
     * Get recent changes.
4605
     *
4606
     * @param string $page
4607
     * @param string $action
4608
     */
4609
    public function recentChanges($page, $action)
4610
    {
4611
        $tbl_wiki = $this->tbl_wiki;
4612
        $course_id = $this->course_id;
4613
        $condition_session = $this->condition_session;
4614
        $groupfilter = $this->groupfilter;
4615
        $tbl_wiki_conf = $this->tbl_wiki_conf;
4616
4617
        if (api_is_allowed_to_session_edit(false, true)) {
4618
            if (self::check_notify_all() == 1) {
4619
                $notify_all = Display::return_icon(
4620
                        'messagebox_info.png',
4621
                        get_lang('NotifyByEmail'),
4622
                        '',
4623
                        ICON_SIZE_SMALL
4624
                    ).' '.get_lang('NotNotifyChanges');
4625
                $lock_unlock_notify_all = 'unlocknotifyall';
4626
            } else {
4627
                $notify_all = Display::return_icon(
4628
                        'mail.png',
4629
                        get_lang('CancelNotifyByEmail'),
4630
                        '',
4631
                        ICON_SIZE_SMALL
4632
                    ).' '.get_lang('NotifyChanges');
4633
                $lock_unlock_notify_all = 'locknotifyall';
4634
            }
4635
        }
4636
4637
        echo '<div class="actions"><span style="float: right;">';
4638
        echo '<a href="index.php?action=recentchanges&actionpage='.$lock_unlock_notify_all.'&'.api_get_cidreq().'&title='.api_htmlentities(
4639
                urlencode($page)
4640
            ).'">'.$notify_all.'</a>';
4641
        echo '</span>'.get_lang('RecentChanges').'</div>';
4642
4643
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4644
            //only by professors if page is hidden
4645
            $sql = 'SELECT * FROM '.$tbl_wiki.', '.$tbl_wiki_conf.'
4646
        		WHERE 	'.$tbl_wiki_conf.'.c_id= '.$course_id.' AND
4647
        				'.$tbl_wiki.'.c_id= '.$course_id.' AND
4648
        				'.$tbl_wiki_conf.'.page_id='.$tbl_wiki.'.page_id AND
4649
        				'.$tbl_wiki.'.'.$groupfilter.$condition_session.'
4650
        		ORDER BY dtime DESC'; // new version
4651
        } else {
4652
            $sql = 'SELECT *
4653
                FROM '.$tbl_wiki.'
4654
                WHERE
4655
                    c_id = '.$course_id.' AND
4656
                    '.$groupfilter.$condition_session.' AND
4657
                    visibility=1
4658
                ORDER BY dtime DESC';
4659
            // old version TODO: Replace by the bottom line
4660
        }
4661
4662
        $allpages = Database::query($sql);
4663
4664
        //show table
4665
        if (Database::num_rows($allpages) > 0) {
4666
            $rows = [];
4667
            while ($obj = Database::fetch_object($allpages)) {
4668
                //get author
4669
                $userinfo = api_get_user_info($obj->user_id);
4670
4671
                //get type assignment icon
4672
                if ($obj->assignment == 1) {
4673
                    $ShowAssignment = Display::return_icon(
4674
                        'wiki_assignment.png',
4675
                        get_lang('AssignmentDesc'),
4676
                        '',
4677
                        ICON_SIZE_SMALL
4678
                    );
4679
                } elseif ($obj->assignment == 2) {
4680
                    $ShowAssignment = Display::return_icon(
4681
                        'wiki_work.png',
4682
                        get_lang('AssignmentWork'),
4683
                        '',
4684
                        ICON_SIZE_SMALL
4685
                    );
4686
                } elseif ($obj->assignment == 0) {
4687
                    $ShowAssignment = Display::return_icon(
4688
                        'px_transparent.gif'
4689
                    );
4690
                }
4691
4692
                // Get icon task
4693
                if (!empty($obj->task)) {
4694
                    $icon_task = Display::return_icon(
4695
                        'wiki_task.png',
4696
                        get_lang('StandardTask'),
4697
                        '',
4698
                        ICON_SIZE_SMALL
4699
                    );
4700
                } else {
4701
                    $icon_task = Display::return_icon('px_transparent.gif');
4702
                }
4703
4704
                $row = [];
4705
                $row[] = api_get_local_time(
4706
                    $obj->dtime
4707
                );
4708
                $row[] = $ShowAssignment.$icon_task;
4709
                $row[] = '<a href="'.api_get_self().'?'.api_get_cidreq(
4710
                    ).'&action=showpage&title='.api_htmlentities(
4711
                        urlencode($obj->reflink)
4712
                    ).'&view='.$obj->id.'&session_id='.api_get_session_id(
4713
                    ).'&group_id='.api_get_group_id().'">'.
4714
                    api_htmlentities($obj->title).'</a>';
4715
                $row[] = $obj->version > 1 ? get_lang('EditedBy') : get_lang(
4716
                    'AddedBy'
4717
                );
4718
                if ($userinfo !== false) {
4719
                    $row[] = UserManager::getUserProfileLink($userinfo);
4720
                } else {
4721
                    $row[] = get_lang('Anonymous').' ('.api_htmlentities(
4722
                            $obj->user_ip
4723
                        ).')';
4724
                }
4725
                $rows[] = $row;
4726
            }
4727
4728
            $table = new SortableTableFromArrayConfig(
4729
                $rows,
4730
                0,
4731
                10,
4732
                'RecentPages_table',
4733
                '',
4734
                '',
4735
                'DESC'
4736
            );
4737
            $table->set_additional_parameters(
4738
                [
4739
                    'cidReq' => $this->courseCode,
4740
                    'gidReq' => $this->group_id,
4741
                    'id_session' => $this->session_id,
4742
                    'action' => Security::remove_XSS($action),
4743
                ]
4744
            );
4745
            $table->set_header(
4746
                0,
4747
                get_lang('Date'),
4748
                true,
4749
                ['style' => 'width:200px;']
4750
            );
4751
            $table->set_header(
4752
                1,
4753
                get_lang('Type'),
4754
                true,
4755
                ['style' => 'width:30px;']
4756
            );
4757
            $table->set_header(2, get_lang('Title'), true);
4758
            $table->set_header(
4759
                3,
4760
                get_lang('Actions'),
4761
                true,
4762
                ['style' => 'width:80px;']
4763
            );
4764
            $table->set_header(4, get_lang('Author'), true);
4765
            $table->display();
4766
        }
4767
    }
4768
4769
    /**
4770
     * What links here. Show pages that have linked this page.
4771
     *
4772
     * @param string $page
4773
     */
4774
    public function getLinks($page)
4775
    {
4776
        $tbl_wiki = $this->tbl_wiki;
4777
        $course_id = $this->course_id;
4778
        $condition_session = $this->condition_session;
4779
        $groupfilter = $this->groupfilter;
4780
        $_course = $this->courseInfo;
4781
        $action = $this->action;
4782
4783
        if (!$_GET['title']) {
4784
            Display::addFlash(
4785
                Display::return_message(
4786
                    get_lang("MustSelectPage"),
4787
                    'error',
4788
                    false
4789
                )
4790
            );
4791
        } else {
4792
            $sql = 'SELECT * FROM '.$tbl_wiki.'
4793
                    WHERE
4794
                        c_id = '.$course_id.' AND
4795
                        reflink="'.Database::escape_string($page).'" AND
4796
                        '.$groupfilter.$condition_session;
4797
            $result = Database::query($sql);
4798
            $row = Database::fetch_array($result);
4799
4800
            //get type assignment icon
4801
            $ShowAssignment = '';
4802
            if ($row['assignment'] == 1) {
4803
                $ShowAssignment = Display::return_icon(
4804
                    'wiki_assignment.png',
4805
                    get_lang('AssignmentDesc'),
4806
                    '',
4807
                    ICON_SIZE_SMALL
4808
                );
4809
            } elseif ($row['assignment'] == 2) {
4810
                $ShowAssignment = Display::return_icon(
4811
                    'wiki_work.png',
4812
                    get_lang('AssignmentWork'),
4813
                    '',
4814
                    ICON_SIZE_SMALL
4815
                );
4816
            } elseif ($row['assignment'] == 0) {
4817
                $ShowAssignment = Display::return_icon('px_transparent.gif');
4818
            }
4819
4820
            //fix Title to reflink (link Main Page)
4821
            if ($page == get_lang('DefaultTitle')) {
4822
                $page = 'index';
4823
            }
4824
4825
            echo '<div id="wikititle">'
4826
                .get_lang('LinksPagesFrom').": $ShowAssignment "
4827
                .Display::url(
4828
                    api_htmlentities($row['title']),
4829
                    $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($page)])
4830
                )
4831
                .'</div>'
4832
            ;
4833
4834
            //fix index to title Main page into linksto
4835
4836
            if ($page == 'index') {
4837
                $page = str_replace(' ', '_', get_lang('DefaultTitle'));
4838
            }
4839
4840
            if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
4841
                // only by professors if page is hidden
4842
                $sql = "SELECT * FROM ".$tbl_wiki." s1
4843
                        WHERE s1.c_id = $course_id AND linksto LIKE '%".Database::escape_string(
4844
                        $page
4845
                    )."%' AND id=(
4846
                        SELECT MAX(s2.id) FROM ".$tbl_wiki." s2
4847
                        WHERE s2.c_id = $course_id AND s1.reflink = s2.reflink AND ".$groupfilter.$condition_session.")";
4848
            } else {
4849
                //add blank space after like '%" " %' to identify each word
4850
                $sql = "SELECT * FROM ".$tbl_wiki." s1
4851
                        WHERE s1.c_id = $course_id AND visibility=1 AND linksto LIKE '%".Database::escape_string(
4852
                        $page
4853
                    )."%' AND id=(
4854
                        SELECT MAX(s2.id) FROM ".$tbl_wiki." s2
4855
                        WHERE s2.c_id = $course_id AND s1.reflink = s2.reflink AND ".$groupfilter.$condition_session.")";
4856
            }
4857
4858
            $allpages = Database::query($sql);
4859
4860
            //show table
4861
            if (Database::num_rows($allpages) > 0) {
4862
                $rows = [];
4863
                while ($obj = Database::fetch_object($allpages)) {
4864
                    //get author
4865
                    $userinfo = api_get_user_info($obj->user_id);
4866
4867
                    //get time
4868
                    $year = substr($obj->dtime, 0, 4);
4869
                    $month = substr($obj->dtime, 5, 2);
4870
                    $day = substr($obj->dtime, 8, 2);
4871
                    $hours = substr($obj->dtime, 11, 2);
4872
                    $minutes = substr($obj->dtime, 14, 2);
4873
                    $seconds = substr($obj->dtime, 17, 2);
4874
4875
                    //get type assignment icon
4876
                    if ($obj->assignment == 1) {
4877
                        $ShowAssignment = Display::return_icon(
4878
                            'wiki_assignment.png',
4879
                            get_lang('AssignmentDesc'),
4880
                            '',
4881
                            ICON_SIZE_SMALL
4882
                        );
4883
                    } elseif ($obj->assignment == 2) {
4884
                        $ShowAssignment = Display::return_icon(
4885
                            'wiki_work.png',
4886
                            get_lang('AssignmentWork'),
4887
                            '',
4888
                            ICON_SIZE_SMALL
4889
                        );
4890
                    } elseif ($obj->assignment == 0) {
4891
                        $ShowAssignment = Display::return_icon(
4892
                            'px_transparent.gif'
4893
                        );
4894
                    }
4895
4896
                    $row = [];
4897
                    $row[] = $ShowAssignment;
4898
                    $row[] = Display::url(
4899
                        api_htmlentities($obj->title),
4900
                        $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($obj->reflink)])
4901
                    );
4902
                    if ($userinfo !== false) {
4903
                        $row[] = UserManager::getUserProfileLink($userinfo);
4904
                    } else {
4905
                        $row[] = get_lang('Anonymous').' ('.$obj->user_ip.')';
4906
                    }
4907
                    $row[] = $year.'-'.$month.'-'.$day.' '.$hours.":".$minutes.":".$seconds;
4908
                    $rows[] = $row;
4909
                }
4910
4911
                $table = new SortableTableFromArrayConfig(
4912
                    $rows,
4913
                    1,
4914
                    10,
4915
                    'AllPages_table',
4916
                    '',
4917
                    '',
4918
                    'ASC'
4919
                );
4920
                $table->set_additional_parameters(
4921
                    [
4922
                        'cidReq' => $this->courseCode,
4923
                        'gidReq' => $this->group_id,
4924
                        'id_session' => $this->session_id,
4925
                        'action' => Security::remove_XSS($action),
4926
                    ]
4927
                );
4928
                $table->set_header(
4929
                    0,
4930
                    get_lang('Type'),
4931
                    true,
4932
                    ['style' => 'width:30px;']
4933
                );
4934
                $table->set_header(1, get_lang('Title'), true);
4935
                $table->set_header(2, get_lang('Author'), true);
4936
                $table->set_header(3, get_lang('Date'), true);
4937
                $table->display();
4938
            }
4939
        }
4940
    }
4941
4942
    /**
4943
     * @param string $action
4944
     */
4945
    public function getSearchPages($action)
4946
    {
4947
        echo '<div class="actions">'.get_lang('SearchPages').'</div>';
4948
        if (isset($_GET['mode_table'])) {
4949
            if (!isset($_GET['SearchPages_table_page_nr'])) {
4950
                $_GET['search_term'] = $_POST['search_term'] ?? '';
4951
                $_GET['search_content'] = $_POST['search_content'] ?? '';
4952
                $_GET['all_vers'] = $_POST['all_vers'] ?? '';
4953
                $_GET['categories'] = $_POST['categories'] ?? [];
4954
                $_GET['match_all_categories'] = isset($_POST['match_all_categories']);
4955
            }
4956
            $this->display_wiki_search_results(
4957
                $_GET['search_term'],
4958
                (int) $_GET['search_content'],
4959
                (int) $_GET['all_vers'],
4960
                $_GET['categories'],
4961
                $_GET['match_all_categories']
4962
            );
4963
        } else {
4964
            // initiate the object
4965
            $form = new FormValidator(
4966
                'wiki_search',
4967
                'post',
4968
                $this->url.'&'.http_build_query(['action' => api_htmlentities($action), 'mode_table' => 'yes1'])
4969
            );
4970
4971
            // Setting the form elements
4972
4973
            $form->addText(
4974
                'search_term',
4975
                get_lang('SearchTerm'),
4976
                true,
4977
                ['autofocus' => 'autofocus']
4978
            );
4979
            $form->addCheckBox('search_content', '', get_lang('AlsoSearchContent'));
4980
            $form->addCheckbox('all_vers', '', get_lang('IncludeAllVersions'));
4981
4982
            if (true === api_get_configuration_value('wiki_categories_enabled')) {
4983
                $categories = Database::getManager()
4984
                    ->getRepository(CWikiCategory::class)
4985
                    ->findByCourse(api_get_course_entity(), api_get_session_entity())
4986
                ;
4987
4988
                $form->addSelectFromCollection(
4989
                    'categories',
4990
                    get_lang('Categories'),
4991
                    $categories,
4992
                    ['multiple' => 'multiple'],
4993
                    false,
4994
                    'getNodeName'
4995
                );
4996
                $form->addCheckBox(
4997
                    'match_all_categories',
4998
                    '',
4999
                    get_lang('OnlyThoseThatCorrespondToAllTheSelectedCategories')
5000
                );
5001
            }
5002
5003
            $form->addButtonSearch(get_lang('Search'), 'SubmitWikiSearch');
5004
5005
            // setting the rules
5006
            $form->addRule(
5007
                'search_term',
5008
                get_lang('TooShort'),
5009
                'minlength',
5010
                3
5011
            ); //TODO: before fixing the pagination rules worked, not now
5012
5013
            if ($form->validate()) {
5014
                $form->display();
5015
                $values = $form->exportValues();
5016
                $this->display_wiki_search_results(
5017
                    $values['search_term'],
5018
                    (int) $values['search_content'],
5019
                    (int) $values['all_vers'],
5020
                    $values['categories'] ?? [],
5021
                    isset($values['match_all_categories'])
5022
                );
5023
            } else {
5024
                $form->display();
5025
            }
5026
        }
5027
    }
5028
5029
    /**
5030
     * @param int    $userId
5031
     * @param string $action
5032
     */
5033
    public function getUserContributions($userId, $action)
5034
    {
5035
        $_course = $this->courseInfo;
5036
        $tbl_wiki = $this->tbl_wiki;
5037
        $course_id = $this->course_id;
5038
        $condition_session = $this->condition_session;
5039
        $groupfilter = $this->groupfilter;
5040
        $userId = (int) $userId;
5041
        $userinfo = api_get_user_info($userId);
5042
        if ($userinfo !== false) {
5043
            echo '<div class="actions">'
5044
                .Display::url(
5045
                    get_lang('UserContributions').': '.$userinfo['complete_name_with_username'],
5046
                    $this->url.'&'.http_build_query(['action' => 'usercontrib', 'user_id' => $userId])
5047
                )
5048
            ;
5049
        }
5050
5051
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
5052
            //only by professors if page is hidden
5053
            $sql = 'SELECT * FROM '.$tbl_wiki.'
5054
                    WHERE
5055
                        c_id = '.$course_id.' AND
5056
                        '.$groupfilter.$condition_session.' AND
5057
                        user_id="'.$userId.'"';
5058
        } else {
5059
            $sql = 'SELECT * FROM '.$tbl_wiki.'
5060
                    WHERE
5061
                        c_id = '.$course_id.' AND
5062
                        '.$groupfilter.$condition_session.' AND
5063
                        user_id="'.$userId.'" AND
5064
                        visibility=1';
5065
        }
5066
5067
        $allpages = Database::query($sql);
5068
5069
        //show table
5070
        if (Database::num_rows($allpages) > 0) {
5071
            $rows = [];
5072
            while ($obj = Database::fetch_object($allpages)) {
5073
                //get type assignment icon
5074
                $ShowAssignment = '';
5075
                if ($obj->assignment == 1) {
5076
                    $ShowAssignment = Display::return_icon(
5077
                        'wiki_assignment.png',
5078
                        get_lang('AssignmentDescExtra'),
5079
                        '',
5080
                        ICON_SIZE_SMALL
5081
                    );
5082
                } elseif ($obj->assignment == 2) {
5083
                    $ShowAssignment = Display::return_icon(
5084
                        'wiki_work.png',
5085
                        get_lang('AssignmentWork'),
5086
                        '',
5087
                        ICON_SIZE_SMALL
5088
                    );
5089
                } elseif ($obj->assignment == 0) {
5090
                    $ShowAssignment = Display::return_icon(
5091
                        'px_transparent.gif'
5092
                    );
5093
                }
5094
5095
                $row = [];
5096
                $row[] = api_get_local_time($obj->dtime);
5097
                $row[] = $ShowAssignment;
5098
                $row[] = Display::url(
5099
                    api_htmlentities($obj->title),
5100
                    $this->url.'&'
5101
                        .http_build_query([
5102
                            'action' => 'showpage',
5103
                            'title' => api_htmlentities($obj->reflink),
5104
                            'view' => (int) $obj->id,
5105
                        ])
5106
                );
5107
                $row[] = Security::remove_XSS($obj->version);
5108
                $row[] = Security::remove_XSS($obj->comment);
5109
                $row[] = Security::remove_XSS($obj->progress).' %';
5110
                $row[] = Security::remove_XSS($obj->score);
5111
                $rows[] = $row;
5112
            }
5113
5114
            $table = new SortableTableFromArrayConfig(
5115
                $rows,
5116
                2,
5117
                10,
5118
                'UsersContributions_table',
5119
                '',
5120
                '',
5121
                'ASC'
5122
            );
5123
            $table->set_additional_parameters(
5124
                [
5125
                    'cidReq' => $this->courseCode,
5126
                    'gidReq' => $this->group_id,
5127
                    'id_session' => $this->session_id,
5128
                    'action' => Security::remove_XSS($action),
5129
                    'user_id' => intval($userId),
5130
                ]
5131
            );
5132
            $table->set_header(
5133
                0,
5134
                get_lang('Date'),
5135
                true,
5136
                ['style' => 'width:200px;']
5137
            );
5138
            $table->set_header(
5139
                1,
5140
                get_lang('Type'),
5141
                true,
5142
                ['style' => 'width:30px;']
5143
            );
5144
            $table->set_header(
5145
                2,
5146
                get_lang('Title'),
5147
                true,
5148
                ['style' => 'width:200px;']
5149
            );
5150
            $table->set_header(
5151
                3,
5152
                get_lang('Version'),
5153
                true,
5154
                ['style' => 'width:30px;']
5155
            );
5156
            $table->set_header(
5157
                4,
5158
                get_lang('Comment'),
5159
                true,
5160
                ['style' => 'width:200px;']
5161
            );
5162
            $table->set_header(
5163
                5,
5164
                get_lang('Progress'),
5165
                true,
5166
                ['style' => 'width:30px;']
5167
            );
5168
            $table->set_header(
5169
                6,
5170
                get_lang('Rating'),
5171
                true,
5172
                ['style' => 'width:30px;']
5173
            );
5174
            $table->display();
5175
        }
5176
    }
5177
5178
    /**
5179
     * @param string $action
5180
     */
5181
    public function getMostChangedPages($action)
5182
    {
5183
        $_course = $this->courseInfo;
5184
        $tbl_wiki = $this->tbl_wiki;
5185
        $course_id = $this->course_id;
5186
        $condition_session = $this->condition_session;
5187
        $groupfilter = $this->groupfilter;
5188
5189
        echo '<div class="actions">'.get_lang('MostChangedPages').'</div>';
5190
5191
        if (api_is_allowed_to_edit(false, true) ||
5192
            api_is_platform_admin()
5193
        ) { //only by professors if page is hidden
5194
            $sql = 'SELECT *, MAX(version) AS MAX FROM '.$tbl_wiki.'
5195
                    WHERE c_id = '.$course_id.' AND '.$groupfilter.$condition_session.'
5196
                    GROUP BY reflink'; //TODO:check MAX and group by return last version
5197
        } else {
5198
            $sql = 'SELECT *, MAX(version) AS MAX FROM '.$tbl_wiki.'
5199
                    WHERE c_id = '.$course_id.' AND '.$groupfilter.$condition_session.' AND visibility=1
5200
                    GROUP BY reflink'; //TODO:check MAX and group by return last version
5201
        }
5202
5203
        $allpages = Database::query($sql);
5204
5205
        //show table
5206
        if (Database::num_rows($allpages) > 0) {
5207
            $rows = [];
5208
            while ($obj = Database::fetch_object($allpages)) {
5209
                //get type assignment icon
5210
                $ShowAssignment = '';
5211
                if ($obj->assignment == 1) {
5212
                    $ShowAssignment = Display::return_icon(
5213
                        'wiki_assignment.png',
5214
                        get_lang('AssignmentDesc'),
5215
                        '',
5216
                        ICON_SIZE_SMALL
5217
                    );
5218
                } elseif ($obj->assignment == 2) {
5219
                    $ShowAssignment = Display::return_icon(
5220
                        'wiki_work.png',
5221
                        get_lang('AssignmentWork'),
5222
                        '',
5223
                        ICON_SIZE_SMALL
5224
                    );
5225
                } elseif ($obj->assignment == 0) {
5226
                    $ShowAssignment = Display::return_icon(
5227
                        'px_transparent.gif'
5228
                    );
5229
                }
5230
5231
                $row = [];
5232
                $row[] = $ShowAssignment;
5233
                $row[] = Display::url(
5234
                    api_htmlentities($obj->title),
5235
                    $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($obj->reflink)])
5236
                );
5237
                $row[] = $obj->MAX;
5238
                $rows[] = $row;
5239
            }
5240
5241
            $table = new SortableTableFromArrayConfig(
5242
                $rows,
5243
                2,
5244
                10,
5245
                'MostChangedPages_table',
5246
                '',
5247
                '',
5248
                'DESC'
5249
            );
5250
            $table->set_additional_parameters(
5251
                [
5252
                    'cidReq' => $this->courseCode,
5253
                    'gidReq' => $this->group_id,
5254
                    'id_session' => $this->session_id,
5255
                    'action' => Security::remove_XSS($action),
5256
                ]
5257
            );
5258
            $table->set_header(
5259
                0,
5260
                get_lang('Type'),
5261
                true,
5262
                ['style' => 'width:30px;']
5263
            );
5264
            $table->set_header(1, get_lang('Title'), true);
5265
            $table->set_header(2, get_lang('Changes'), true);
5266
            $table->display();
5267
        }
5268
    }
5269
5270
    /**
5271
     * Restore page.
5272
     *
5273
     * @return bool
5274
     */
5275
    public function restorePage()
5276
    {
5277
        $userId = api_get_user_id();
5278
        $_course = $this->courseInfo;
5279
        $current_row = $this->getWikiData();
5280
        $last_row = $this->getLastWikiData($this->page);
5281
5282
        if (empty($last_row)) {
5283
            return false;
5284
        }
5285
5286
        $PassEdit = false;
5287
5288
        /* Only teachers and platform admin can edit the index page.
5289
        Only teachers and platform admin can edit an assignment teacher*/
5290
        if (($current_row['reflink'] == 'index' ||
5291
                $current_row['reflink'] == '' ||
5292
                $current_row['assignment'] == 1) &&
5293
            (!api_is_allowed_to_edit(false, true) &&
5294
                $this->group_id == 0)
5295
        ) {
5296
            Display::addFlash(
5297
                Display::return_message(
5298
                    get_lang('OnlyEditPagesCourseManager'),
5299
                    'normal',
5300
                    false
5301
                )
5302
            );
5303
        } else {
5304
            // check if is a wiki group
5305
            if ($current_row['group_id'] != 0) {
5306
                $groupInfo = GroupManager::get_group_properties(
5307
                    $this->group_id
5308
                );
5309
                //Only teacher, platform admin and group members can edit a wiki group
5310
                if (api_is_allowed_to_edit(false, true) ||
5311
                    api_is_platform_admin() ||
5312
                    GroupManager::is_user_in_group($userId, $groupInfo) ||
5313
                    api_is_allowed_in_course()
5314
                ) {
5315
                    $PassEdit = true;
5316
                } else {
5317
                    Display::addFlash(
5318
                        Display::return_message(
5319
                            get_lang('OnlyEditPagesGroupMembers'),
5320
                            'normal',
5321
                            false
5322
                        )
5323
                    );
5324
                }
5325
            } else {
5326
                $PassEdit = true;
5327
            }
5328
5329
            // check if is an assignment
5330
            //$icon_assignment = null;
5331
            if ($current_row['assignment'] == 1) {
5332
                Display::addFlash(
5333
                    Display::return_message(
5334
                        get_lang('EditAssignmentWarning'),
5335
                        'normal',
5336
                        false
5337
                    )
5338
                );
5339
            } elseif ($current_row['assignment'] == 2) {
5340
                if (($userId == $current_row['user_id']) == false) {
5341
                    if (api_is_allowed_to_edit(
5342
                            false,
5343
                            true
5344
                        ) || api_is_platform_admin()) {
5345
                        $PassEdit = true;
5346
                    } else {
5347
                        Display::addFlash(
5348
                            Display::return_message(
5349
                                get_lang('LockByTeacher'),
5350
                                'normal',
5351
                                false
5352
                            )
5353
                        );
5354
                        $PassEdit = false;
5355
                    }
5356
                } else {
5357
                    $PassEdit = true;
5358
                }
5359
            }
5360
5361
            //show editor if edit is allowed
5362
            if ($PassEdit) {
5363
                if ($current_row['editlock'] == 1 &&
5364
                    (api_is_allowed_to_edit(false, true) == false ||
5365
                        api_is_platform_admin() == false)
5366
                ) {
5367
                    Display::addFlash(
5368
                        Display::return_message(
5369
                            get_lang('PageLockedExtra'),
5370
                            'normal',
5371
                            false
5372
                        )
5373
                    );
5374
                } else {
5375
                    if ($last_row['is_editing'] != 0 && $last_row['is_editing'] != $userId) {
5376
                        // Checking for concurrent users
5377
                        $timestamp_edit = strtotime($last_row['time_edit']);
5378
                        $time_editing = time() - $timestamp_edit;
5379
                        $max_edit_time = 1200; // 20 minutes
5380
                        $rest_time = $max_edit_time - $time_editing;
5381
                        $userinfo = api_get_user_info($last_row['is_editing']);
5382
                        $is_being_edited = get_lang(
5383
                                'ThisPageisBeginEditedBy'
5384
                            ).' <a href='.$userinfo['profile_url'].'>'.
5385
                            Display::tag(
5386
                                'span',
5387
                                $userinfo['complete_name_with_username']
5388
                            ).
5389
                            get_lang('ThisPageisBeginEditedTryLater').' '.date(
5390
                                "i",
5391
                                $rest_time
5392
                            ).' '.get_lang('MinMinutes');
5393
                        Display::addFlash(
5394
                            Display::return_message(
5395
                                $is_being_edited,
5396
                                'normal',
5397
                                false
5398
                            )
5399
                        );
5400
                    } else {
5401
                        Display::addFlash(
5402
                            Display::return_message(
5403
                                self::restore_wikipage(
5404
                                    $current_row['page_id'],
5405
                                    $current_row['reflink'],
5406
                                    $current_row['title'],
5407
                                    $current_row['content'],
5408
                                    $current_row['group_id'],
5409
                                    $current_row['assignment'],
5410
                                    $current_row['progress'],
5411
                                    $current_row['version'],
5412
                                    $last_row['version'],
5413
                                    $current_row['linksto']
5414
                                ).': '
5415
                                .Display::url(
5416
                                    api_htmlentities($last_row['title']),
5417
                                    $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($last_row['reflink'])])
5418
                                ),
5419
                                'confirmation',
5420
                                false
5421
                            )
5422
                        );
5423
                    }
5424
                }
5425
            }
5426
        }
5427
    }
5428
5429
    /**
5430
     * @param int|bool $wikiId
5431
     */
5432
    public function setWikiData($wikiId)
5433
    {
5434
        $this->wikiData = self::getWikiDataFromDb($wikiId);
5435
    }
5436
5437
    /**
5438
     * @return array
5439
     */
5440
    public function getWikiData()
5441
    {
5442
        return $this->wikiData;
5443
    }
5444
5445
    /**
5446
     * Check last version.
5447
     *
5448
     * @param int $view
5449
     */
5450
    public function checkLastVersion($view)
5451
    {
5452
        $tbl_wiki = $this->tbl_wiki;
5453
        $course_id = $this->course_id;
5454
        $condition_session = $this->condition_session;
5455
        $groupfilter = $this->groupfilter;
5456
        $page = $this->page;
5457
        $_course = $this->courseInfo;
5458
5459
        if (empty($view)) {
5460
            return false;
5461
        }
5462
5463
        $current_row = $this->getWikiData();
5464
        $sql = 'SELECT * FROM '.$tbl_wiki.'
5465
                WHERE
5466
                    c_id = '.$course_id.' AND
5467
                    reflink = "'.Database::escape_string($page).'" AND
5468
                    '.$groupfilter.$condition_session.'
5469
                ORDER BY id DESC'; //last version
5470
        $result = Database::query($sql);
5471
        $last_row = Database::fetch_array($result);
5472
5473
        if ($view < $last_row['id']) {
5474
            $message = '<center>'.get_lang('NoAreSeeingTheLastVersion').'<br />'
5475
                .get_lang("Version").' ('
5476
                .Display::url(
5477
                    $current_row['version'],
5478
                    $this->url.'&'.http_build_query([
5479
                        'action' => 'showpage',
5480
                        'title' => api_htmlentities($current_row['reflink']),
5481
                        'view' => (int) $_GET['view'],
5482
                    ]),
5483
                    ['title' => get_lang('CurrentVersion')]
5484
                )
5485
                .' / '
5486
                .Display::url(
5487
                    $last_row['version'],
5488
                    $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($last_row['reflink'])]),
5489
                    ['title' => get_lang('LastVersion')]
5490
                )
5491
                .')<br>'.get_lang('ConvertToLastVersion').': '
5492
                .Display::url(
5493
                    get_lang("Restore"),
5494
                    $this->url.'&'.http_build_query([
5495
                        'action' => 'restorepage',
5496
                        'title' => api_htmlentities($last_row['reflink']),
5497
                        'view' => (int) $_GET['view'],
5498
                    ])
5499
                )
5500
                .'</center>'
5501
            ;
5502
            echo Display::return_message($message, 'warning', false);
5503
        }
5504
    }
5505
5506
    /**
5507
     *  Get most linked pages.
5508
     */
5509
    public function getMostLinked()
5510
    {
5511
        $tbl_wiki = $this->tbl_wiki;
5512
        $course_id = $this->course_id;
5513
        $groupfilter = $this->groupfilter;
5514
        $condition_session = $this->condition_session;
5515
        $_course = $this->courseInfo;
5516
5517
        echo '<div class="actions">'.get_lang('MostLinkedPages').'</div>';
5518
        $pages = [];
5519
        $linked = [];
5520
5521
        // Get name pages
5522
        $sql = 'SELECT * FROM '.$tbl_wiki.'
5523
                WHERE  c_id = '.$course_id.' AND '.$groupfilter.$condition_session.'
5524
                GROUP BY reflink
5525
                ORDER BY reflink ASC';
5526
        $allpages = Database::query($sql);
5527
        while ($row = Database::fetch_array($allpages)) {
5528
            if ($row['reflink'] == 'index') {
5529
                $row['reflink'] = str_replace(
5530
                    ' ',
5531
                    '_',
5532
                    get_lang('DefaultTitle')
5533
                );
5534
            }
5535
            $pages[] = $row['reflink'];
5536
        }
5537
5538
        // Get name refs in last pages
5539
        $sql = 'SELECT *
5540
                FROM '.$tbl_wiki.' s1
5541
                WHERE s1.c_id = '.$course_id.' AND id=(
5542
                    SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
5543
                    WHERE
5544
                        s2.c_id = '.$course_id.' AND
5545
                        s1.reflink = s2.reflink AND
5546
                        '.$groupfilter.$condition_session.'
5547
                )';
5548
5549
        $allpages = Database::query($sql);
5550
5551
        while ($row = Database::fetch_array($allpages)) {
5552
            //remove self reference
5553
            $row['linksto'] = str_replace(
5554
                $row["reflink"],
5555
                " ",
5556
                trim($row["linksto"])
5557
            );
5558
            $refs = explode(" ", trim($row["linksto"]));
5559
5560
            // Find linksto into reflink. If found ->page is linked
5561
            foreach ($refs as $v) {
5562
                if (in_array($v, $pages)) {
5563
                    if (trim($v) != "") {
5564
                        $linked[] = $v;
5565
                    }
5566
                }
5567
            }
5568
        }
5569
5570
        $linked = array_unique($linked);
5571
        //make a unique list. TODO:delete this line and count how many for each page
5572
        //show table
5573
        $rows = [];
5574
        foreach ($linked as $linked_show) {
5575
            $row = [];
5576
            $row[] = Display::url(
5577
                str_replace('_', ' ', $linked_show),
5578
                $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => str_replace('_', ' ', $linked_show)])
5579
            );
5580
            $rows[] = $row;
5581
        }
5582
5583
        $table = new SortableTableFromArrayConfig(
5584
            $rows,
5585
            0,
5586
            10,
5587
            'LinkedPages_table',
5588
            '',
5589
            '',
5590
            'DESC'
5591
        );
5592
        $table->set_additional_parameters(
5593
            [
5594
                'cidReq' => $this->courseCode,
5595
                'gidReq' => $this->group_id,
5596
                'id_session' => $this->session_id,
5597
                'action' => Security::remove_XSS($this->action),
5598
            ]
5599
        );
5600
        $table->set_header(0, get_lang('Title'), true);
5601
        $table->display();
5602
    }
5603
5604
    /**
5605
     * Get orphan pages.
5606
     */
5607
    public function getOrphaned()
5608
    {
5609
        $tbl_wiki = $this->tbl_wiki;
5610
        $course_id = $this->course_id;
5611
        $groupfilter = $this->groupfilter;
5612
        $condition_session = $this->condition_session;
5613
        $_course = $this->courseInfo;
5614
5615
        echo '<div class="actions">'.get_lang('OrphanedPages').'</div>';
5616
5617
        $pages = [];
5618
        $orphaned = [];
5619
5620
        //get name pages
5621
        $sql = 'SELECT * FROM '.$tbl_wiki.'
5622
                WHERE c_id = '.$course_id.' AND '.$groupfilter.$condition_session.'
5623
                GROUP BY reflink
5624
                ORDER BY reflink ASC';
5625
        $allpages = Database::query($sql);
5626
        while ($row = Database::fetch_array($allpages)) {
5627
            $pages[] = $row['reflink'];
5628
        }
5629
5630
        //get name refs in last pages and make a unique list
5631
        $sql = 'SELECT  *  FROM   '.$tbl_wiki.' s1
5632
                WHERE s1.c_id = '.$course_id.' AND id=(
5633
                SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
5634
                WHERE
5635
                    s2.c_id = '.$course_id.' AND
5636
                    s1.reflink = s2.reflink AND
5637
                    '.$groupfilter.$condition_session.'
5638
                )';
5639
        $allpages = Database::query($sql);
5640
        $array_refs_linked = [];
5641
        while ($row = Database::fetch_array($allpages)) {
5642
            $row['linksto'] = str_replace(
5643
                $row["reflink"],
5644
                " ",
5645
                trim($row["linksto"])
5646
            ); //remove self reference
5647
            $refs = explode(" ", trim($row["linksto"]));
5648
            foreach ($refs as $ref_linked) {
5649
                if ($ref_linked == str_replace(
5650
                        ' ',
5651
                        '_',
5652
                        get_lang('DefaultTitle')
5653
                    )) {
5654
                    $ref_linked = 'index';
5655
                }
5656
                $array_refs_linked[] = $ref_linked;
5657
            }
5658
        }
5659
5660
        $array_refs_linked = array_unique($array_refs_linked);
5661
5662
        //search each name of list linksto into list reflink
5663
        foreach ($pages as $v) {
5664
            if (!in_array($v, $array_refs_linked)) {
5665
                $orphaned[] = $v;
5666
            }
5667
        }
5668
        $rows = [];
5669
        foreach ($orphaned as $orphaned_show) {
5670
            // get visibility status and title
5671
            $sql = 'SELECT *
5672
                    FROM  '.$tbl_wiki.'
5673
		            WHERE
5674
		                c_id = '.$course_id.' AND
5675
		                '.$groupfilter.$condition_session.' AND
5676
		                reflink="'.Database::escape_string($orphaned_show).'"
5677
                    GROUP BY reflink';
5678
            $allpages = Database::query($sql);
5679
            while ($row = Database::fetch_array($allpages)) {
5680
                $orphaned_title = $row['title'];
5681
                $orphaned_visibility = $row['visibility'];
5682
                if ($row['assignment'] == 1) {
5683
                    $ShowAssignment = Display::return_icon(
5684
                        'wiki_assignment.png',
5685
                        '',
5686
                        '',
5687
                        ICON_SIZE_SMALL
5688
                    );
5689
                } elseif ($row['assignment'] == 2) {
5690
                    $ShowAssignment = Display::return_icon(
5691
                        'wiki_work.png',
5692
                        '',
5693
                        '',
5694
                        ICON_SIZE_SMALL
5695
                    );
5696
                } elseif ($row['assignment'] == 0) {
5697
                    $ShowAssignment = Display::return_icon(
5698
                        'px_transparent.gif'
5699
                    );
5700
                }
5701
            }
5702
5703
            if (!api_is_allowed_to_edit(false, true) || !api_is_platform_admin(
5704
                ) && $orphaned_visibility == 0) {
5705
                continue;
5706
            }
5707
5708
            //show table
5709
            $row = [];
5710
            $row[] = $ShowAssignment;
5711
            $row[] = Display::url(
5712
                api_htmlentities($orphaned_title),
5713
                $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($orphaned_show)])
5714
            );
5715
            $rows[] = $row;
5716
        }
5717
5718
        $table = new SortableTableFromArrayConfig(
5719
            $rows,
5720
            1,
5721
            10,
5722
            'OrphanedPages_table',
5723
            '',
5724
            '',
5725
            'DESC'
5726
        );
5727
        $table->set_additional_parameters(
5728
            [
5729
                'cidReq' => $this->courseCode,
5730
                'gidReq' => $this->group_id,
5731
                'id_session' => $this->session_id,
5732
                'action' => Security::remove_XSS($this->action),
5733
            ]
5734
        );
5735
        $table->set_header(
5736
            0,
5737
            get_lang('Type'),
5738
            true,
5739
            ['style' => 'width:30px;']
5740
        );
5741
        $table->set_header(1, get_lang('Title'), true);
5742
        $table->display();
5743
    }
5744
5745
    /**
5746
     * Get wanted pages.
5747
     */
5748
    public function getWantedPages()
5749
    {
5750
        $tbl_wiki = $this->tbl_wiki;
5751
        $course_id = $this->course_id;
5752
        $groupfilter = $this->groupfilter;
5753
        $condition_session = $this->condition_session;
5754
5755
        echo '<div class="actions">'.get_lang('WantedPages').'</div>';
5756
        $pages = [];
5757
        $wanted = [];
5758
        //get name pages
5759
        $sql = 'SELECT * FROM '.$tbl_wiki.'
5760
                WHERE  c_id = '.$course_id.' AND '.$groupfilter.$condition_session.'
5761
                GROUP BY reflink
5762
                ORDER BY reflink ASC';
5763
        $allpages = Database::query($sql);
5764
5765
        while ($row = Database::fetch_array($allpages)) {
5766
            if ($row['reflink'] == 'index') {
5767
                $row['reflink'] = str_replace(
5768
                    ' ',
5769
                    '_',
5770
                    get_lang('DefaultTitle')
5771
                );
5772
            }
5773
            $pages[] = $row['reflink'];
5774
        }
5775
5776
        //get name refs in last pages
5777
        $sql = 'SELECT * FROM   '.$tbl_wiki.' s1
5778
                WHERE s1.c_id = '.$course_id.' AND id=(
5779
                    SELECT MAX(s2.id) FROM '.$tbl_wiki.' s2
5780
                    WHERE s2.c_id = '.$course_id.' AND s1.reflink = s2.reflink AND '.$groupfilter.$condition_session.'
5781
                )';
5782
5783
        $allpages = Database::query($sql);
5784
5785
        while ($row = Database::fetch_array($allpages)) {
5786
            $refs = explode(" ", trim($row["linksto"]));
5787
            // Find linksto into reflink. If not found ->page is wanted
5788
            foreach ($refs as $v) {
5789
                if (!in_array($v, $pages)) {
5790
                    if (trim($v) != "") {
5791
                        $wanted[] = $v;
5792
                    }
5793
                }
5794
            }
5795
        }
5796
5797
        $wanted = array_unique($wanted); //make a unique list
5798
5799
        //show table
5800
        $rows = [];
5801
        foreach ($wanted as $wanted_show) {
5802
            $row = [];
5803
            $wanted_show = Security::remove_XSS($wanted_show);
5804
            $row[] = Display::url(
5805
                str_replace('_', ' ', $wanted_show),
5806
                $this->url.'&'.http_build_query(['action' => 'addnew', 'title' => str_replace('_', ' ', $wanted_show)]),
5807
                ['class' => 'new_wiki_link']
5808
            );
5809
            $rows[] = $row;
5810
        }
5811
5812
        $table = new SortableTableFromArrayConfig(
5813
            $rows,
5814
            0,
5815
            10,
5816
            'WantedPages_table',
5817
            '',
5818
            '',
5819
            'DESC'
5820
        );
5821
        $table->set_additional_parameters(
5822
            [
5823
                'cidReq' => $this->courseCode,
5824
                'gidReq' => $this->group_id,
5825
                'id_session' => $this->session_id,
5826
                'action' => Security::remove_XSS($this->action),
5827
            ]
5828
        );
5829
        $table->set_header(0, get_lang('Title'), true);
5830
        $table->display();
5831
    }
5832
5833
    /**
5834
     * Most visited.
5835
     */
5836
    public function getMostVisited()
5837
    {
5838
        $tbl_wiki = $this->tbl_wiki;
5839
        $course_id = $this->course_id;
5840
        $groupfilter = $this->groupfilter;
5841
        $condition_session = $this->condition_session;
5842
        $_course = $this->courseInfo;
5843
5844
        echo '<div class="actions">'.get_lang('MostVisitedPages').'</div>';
5845
5846
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin(
5847
            )) { //only by professors if page is hidden
5848
            $sql = 'SELECT *, SUM(hits) AS tsum FROM '.$tbl_wiki.'
5849
                    WHERE c_id = '.$course_id.' AND '.$groupfilter.$condition_session.'
5850
                    GROUP BY reflink';
5851
        } else {
5852
            $sql = 'SELECT *, SUM(hits) AS tsum FROM '.$tbl_wiki.'
5853
                    WHERE
5854
                        c_id = '.$course_id.' AND
5855
                        '.$groupfilter.$condition_session.' AND
5856
                        visibility=1
5857
                    GROUP BY reflink';
5858
        }
5859
5860
        $allpages = Database::query($sql);
5861
5862
        //show table
5863
        if (Database::num_rows($allpages) > 0) {
5864
            $rows = [];
5865
            while ($obj = Database::fetch_object($allpages)) {
5866
                //get type assignment icon
5867
                $ShowAssignment = '';
5868
                if ($obj->assignment == 1) {
5869
                    $ShowAssignment = Display::return_icon(
5870
                        'wiki_assignment.png',
5871
                        get_lang('AssignmentDesc'),
5872
                        '',
5873
                        ICON_SIZE_SMALL
5874
                    );
5875
                } elseif ($obj->assignment == 2) {
5876
                    $ShowAssignment = $ShowAssignment = Display::return_icon(
5877
                        'wiki_work.png',
5878
                        get_lang('AssignmentWork'),
5879
                        '',
5880
                        ICON_SIZE_SMALL
5881
                    );
5882
                } elseif ($obj->assignment == 0) {
5883
                    $ShowAssignment = Display::return_icon(
5884
                        'px_transparent.gif'
5885
                    );
5886
                }
5887
5888
                $row = [];
5889
                $row[] = $ShowAssignment;
5890
                $row[] = Display::url(
5891
                    api_htmlentities($obj->title),
5892
                    $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => api_htmlentities($obj->reflink)])
5893
                );
5894
                $row[] = $obj->tsum;
5895
                $rows[] = $row;
5896
            }
5897
5898
            $table = new SortableTableFromArrayConfig(
5899
                $rows,
5900
                2,
5901
                10,
5902
                'MostVisitedPages_table',
5903
                '',
5904
                '',
5905
                'DESC'
5906
            );
5907
            $table->set_additional_parameters(
5908
                [
5909
                    'cidReq' => $this->courseCode,
5910
                    'gidReq' => $this->group_id,
5911
                    'id_session' => $this->session_id,
5912
                    'action' => Security::remove_XSS($this->action),
5913
                ]
5914
            );
5915
            $table->set_header(
5916
                0,
5917
                get_lang('Type'),
5918
                true,
5919
                ['style' => 'width:30px;']
5920
            );
5921
            $table->set_header(1, get_lang('Title'), true);
5922
            $table->set_header(2, get_lang('Visits'), true);
5923
            $table->display();
5924
        }
5925
    }
5926
5927
    /**
5928
     * Get actions bar.
5929
     */
5930
    public function showActionBar()
5931
    {
5932
        $_course = $this->courseInfo;
5933
        $session_id = $this->session_id;
5934
        $groupId = $this->group_id;
5935
        $page = $this->page;
5936
        $actionsLeft = Display::url(
5937
            Display::return_icon('home.png', get_lang('Home'), [], ICON_SIZE_MEDIUM),
5938
            $this->url.'&'.http_build_query(['action' => 'showpage', 'title' => 'index'])
5939
        );
5940
5941
        if (api_is_allowed_to_session_edit(false, true) && api_is_allowed_to_edit()) {
5942
            // menu add page
5943
            $actionsLeft .= '<a href="'.$this->url.'&action=addnew" '.self::is_active_navigation_tab('addnew').'>'
5944
                .Display::return_icon('new_document.png', get_lang('AddNew'), [], ICON_SIZE_MEDIUM).'</a>';
5945
        }
5946
5947
        if (
5948
            true === api_get_configuration_value('wiki_categories_enabled')
5949
            && (api_is_allowed_to_edit(false, true) || api_is_platform_admin())
5950
        ) {
5951
            $actionsLeft .= Display::url(
5952
                Display::return_icon('folder.png', get_lang('Categories'), [], ICON_SIZE_MEDIUM),
5953
                $this->url.'&action=category'
5954
            );
5955
5956
            // page action: enable or disable the adding of new pages
5957
            if (self::check_addnewpagelock() == 0) {
5958
                $protect_addnewpage = Display::return_icon(
5959
                    'off.png',
5960
                    get_lang('AddOptionProtected')
5961
                );
5962
                $lock_unlock_addnew = 'unlockaddnew';
5963
            } else {
5964
                $protect_addnewpage = Display::return_icon(
5965
                    'on.png',
5966
                    get_lang('AddOptionUnprotected')
5967
                );
5968
                $lock_unlock_addnew = 'lockaddnew';
5969
            }
5970
        }
5971
5972
        // menu find
5973
        $actionsLeft .= '<a href="'.$this->url.'&action=searchpages"'.self::is_active_navigation_tab('searchpages').'>'
5974
            .Display::return_icon('search.png', get_lang('SearchPages'), '', ICON_SIZE_MEDIUM).'</a>';
5975
        ///menu more
5976
        $actionsLeft .= '<a href="'.$this->url.'&action=more&title='.api_htmlentities(urlencode($page)).'" '
5977
            .self::is_active_navigation_tab('more').'>'
5978
            .Display::return_icon('statistics.png', get_lang('Statistics'), [], ICON_SIZE_MEDIUM).'</a>';
5979
5980
        // menu all pages
5981
        $actionsLeft .= '<a href="'.$this->url.'&action=allpages" '.self::is_active_navigation_tab('allpages').'>'
5982
            .Display::return_icon('list_badges.png', get_lang('AllPages'), [], ICON_SIZE_MEDIUM).'</a>';
5983
        // menu recent changes
5984
        $actionsLeft .= '<a href="'.$this->url.'&action=recentchanges" '.self::is_active_navigation_tab('recentchanges').'>'
5985
            .Display::return_icon('history.png', get_lang('RecentChanges'), [], ICON_SIZE_MEDIUM).'</a>';
5986
        echo Display::toolbarAction('toolbar-wiki', [$actionsLeft]);
5987
    }
5988
5989
    /**
5990
     * Showing warning.
5991
     */
5992
    public function deletePageWarning()
5993
    {
5994
        $page = $this->page;
5995
        $course_id = $this->course_id;
5996
        $groupfilter = $this->groupfilter;
5997
        $condition_session = $this->condition_session;
5998
5999
        if (!$_GET['title']) {
6000
            Display::addFlash(
6001
                Display::return_message(
6002
                    get_lang('MustSelectPage'),
6003
                    'error',
6004
                    false
6005
                )
6006
            );
6007
6008
            return;
6009
        }
6010
6011
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
6012
            Display::addFlash(
6013
                '<div id="wikititle">'.get_lang('DeletePageHistory').'</div>'
6014
            );
6015
            if ($page == "index") {
6016
                Display::addFlash(
6017
                    Display::return_message(
6018
                        get_lang('WarningDeleteMainPage'),
6019
                        'warning',
6020
                        false
6021
                    )
6022
                );
6023
            }
6024
            $message = get_lang('ConfirmDeletePage')."
6025
                <a href=\"index.php?".api_get_cidreq()."\">".get_lang("No")."</a>
6026
                <a href=\"".api_get_self()."?".api_get_cidreq(
6027
                )."&action=delete&title=".api_htmlentities(
6028
                    urlencode($page)
6029
                )."&delete=yes\">".
6030
                get_lang("Yes")."</a>";
6031
6032
            if (!isset($_GET['delete'])) {
6033
                Display::addFlash(
6034
                    Display::return_message($message, 'warning', false)
6035
                );
6036
            }
6037
6038
            if (isset($_GET['delete']) && $_GET['delete'] == 'yes') {
6039
                $result = self::deletePage(
6040
                    $page,
6041
                    $course_id,
6042
                    $groupfilter,
6043
                    $condition_session
6044
                );
6045
                if ($result) {
6046
                    Display::addFlash(
6047
                        Display::return_message(
6048
                            get_lang('WikiPageDeleted'),
6049
                            'confirmation',
6050
                            false
6051
                        )
6052
                    );
6053
                }
6054
            }
6055
        } else {
6056
            Display::addFlash(
6057
                Display::return_message(
6058
                    get_lang('OnlyAdminDeletePageWiki'),
6059
                    'normal',
6060
                    false
6061
                )
6062
            );
6063
        }
6064
    }
6065
6066
    /**
6067
     * Edit page.
6068
     */
6069
    public function editPage()
6070
    {
6071
        $tbl_wiki = $this->tbl_wiki;
6072
        $tbl_wiki_conf = $this->tbl_wiki_conf;
6073
        $condition_session = $this->condition_session;
6074
        $groupfilter = $this->groupfilter;
6075
        $page = $this->page;
6076
        $course_id = $this->course_id;
6077
        $groupId = $this->group_id;
6078
        $userId = api_get_user_id();
6079
6080
        if (api_get_session_id() != 0 &&
6081
            api_is_allowed_to_session_edit(false, true) == false
6082
        ) {
6083
            api_not_allowed();
6084
        }
6085
6086
        $sql = 'SELECT *
6087
            FROM '.$tbl_wiki.' w INNER JOIN '.$tbl_wiki_conf.' c
6088
            ON  (w.c_id = c.c_id AND w.page_id = c.page_id)
6089
            WHERE
6090
                w.c_id = '.$course_id.' AND
6091
                w.reflink= "'.Database::escape_string($page).'" AND
6092
                w.'.$groupfilter.$condition_session.'
6093
            ORDER BY id DESC';
6094
        $result = Database::query($sql);
6095
        $row = Database::fetch_array($result);
6096
6097
        $PassEdit = false;
6098
        // Check if is a wiki group
6099
        if (!empty($groupId)) {
6100
            $groupInfo = GroupManager::get_group_properties($groupId);
6101
            //Only teacher, platform admin and group members can edit a wiki group
6102
            if (api_is_allowed_to_edit(false, true) ||
6103
                api_is_platform_admin() ||
6104
                GroupManager::is_user_in_group($userId, $groupInfo)
6105
            ) {
6106
                $PassEdit = true;
6107
            } else {
6108
                Display::addFlash(
6109
                    Display::return_message(
6110
                        get_lang('OnlyEditPagesGroupMembers')
6111
                    )
6112
                );
6113
            }
6114
        } else {
6115
            $PassEdit = true;
6116
        }
6117
6118
        $content = '<div class="text-center">'
6119
            .sprintf(get_lang('DefaultContent'), api_get_path(WEB_IMG_PATH))
6120
            .'</div>';
6121
        $title = get_lang('DefaultTitle');
6122
        $page_id = 0;
6123
6124
        $icon_assignment = '';
6125
6126
        // we do not need awhile loop since we are always displaying the last version
6127
        if ($row) {
6128
            if ($row['content'] == '' && $row['title'] == '' && $page == '') {
6129
                Display::addFlash(
6130
                    Display::return_message(get_lang('MustSelectPage'), 'error', false)
6131
                );
6132
6133
                return;
6134
            }
6135
6136
            $content = api_html_entity_decode($row['content']);
6137
            $title = api_html_entity_decode($row['title']);
6138
            $page_id = $row['page_id'];
6139
6140
            // Only teachers and platform admin can edit the index page.
6141
            // Only teachers and platform admin can edit an assignment teacher.
6142
            // And users in groups
6143
6144
            if (($row['reflink'] == 'index' || $row['reflink'] == '' || $row['assignment'] == 1)
6145
                && (!api_is_allowed_to_edit(false, true) && $groupId == 0)
6146
                && !api_is_allowed_in_course()
6147
            ) {
6148
                Display::addFlash(
6149
                    Display::return_message(get_lang('OnlyEditPagesCourseManager'), 'error')
6150
                );
6151
6152
                return;
6153
            }
6154
6155
            // check if is an assignment
6156
            if ($row['assignment'] == 1) {
6157
                Display::addFlash(
6158
                    Display::return_message(get_lang('EditAssignmentWarning'))
6159
                );
6160
6161
                $icon_assignment = Display::return_icon('wiki_assignment.png', get_lang('AssignmentDescExtra'));
6162
            } elseif ($row['assignment'] == 2) {
6163
                $icon_assignment = Display::return_icon('wiki_work.png', get_lang('AssignmentWorkExtra'));
6164
                if (($userId == $row['user_id']) == false) {
6165
                    if (api_is_allowed_to_edit(
6166
                            false,
6167
                            true
6168
                        ) || api_is_platform_admin()) {
6169
                        $PassEdit = true;
6170
                    } else {
6171
                        Display::addFlash(
6172
                            Display::return_message(get_lang('LockByTeacher'), 'warning')
6173
                        );
6174
                        $PassEdit = false;
6175
                    }
6176
                } else {
6177
                    $PassEdit = true;
6178
                }
6179
            }
6180
6181
            if ($PassEdit) {
6182
                if ($row['editlock'] == 1 &&
6183
                    (api_is_allowed_to_edit(false, true) == false ||
6184
                        api_is_platform_admin() == false)
6185
                ) {
6186
                    Display::addFlash(
6187
                        Display::return_message(get_lang('PageLockedExtra'))
6188
                    );
6189
                }
6190
            }
6191
        }
6192
6193
        if ($PassEdit) {
6194
            //show editor if edit is allowed <<<<<
6195
            if ((!empty($row['id']) && $row['editlock'] != 1)
6196
                || api_is_allowed_to_edit(false, true) != false
6197
                && api_is_platform_admin() != false
6198
            ) {
6199
                // Check tasks
6200
                if (!empty($row['startdate_assig']) && time() <
6201
                    api_strtotime($row['startdate_assig'])
6202
                ) {
6203
                    $message = get_lang('TheTaskDoesNotBeginUntil').': '.api_get_local_time($row['startdate_assig']);
6204
6205
                    Display::addFlash(
6206
                        Display::return_message($message, 'warning')
6207
                    );
6208
6209
                    if (!api_is_allowed_to_edit(false, true)) {
6210
                        $this->redirectHome();
6211
                    }
6212
                }
6213
6214
                if (!empty($row['enddate_assig']) &&
6215
                    time() > strtotime($row['enddate_assig']) &&
6216
                    $row['delayedsubmit'] == 0
6217
                ) {
6218
                    $message = get_lang('TheDeadlineHasBeenCompleted').': '.api_get_local_time($row['enddate_assig']);
6219
                    Display::addFlash(
6220
                        Display::return_message($message, 'warning')
6221
                    );
6222
                    if (!api_is_allowed_to_edit(false, true)) {
6223
                        $this->redirectHome();
6224
                    }
6225
                }
6226
6227
                if (!empty($row['max_version']) && $row['version'] >= $row['max_version']) {
6228
                    $message = get_lang('HasReachedMaxiNumVersions');
6229
                    Display::addFlash(
6230
                        Display::return_message($message, 'warning')
6231
                    );
6232
                    if (!api_is_allowed_to_edit(false, true)) {
6233
                        $this->redirectHome();
6234
                    }
6235
                }
6236
6237
                if (!empty($row['max_text']) && $row['max_text'] <= self::word_count(
6238
                        $row['content']
6239
                    )) {
6240
                    $message = get_lang('HasReachedMaxNumWords');
6241
                    Display::addFlash(
6242
                        Display::return_message($message, 'warning')
6243
                    );
6244
                    if (!api_is_allowed_to_edit(false, true)) {
6245
                        $this->redirectHome();
6246
                    }
6247
                }
6248
6249
                if (!empty($row['task'])) {
6250
                    //previous change 0 by text
6251
                    $message_task_startdate = empty($row['startdate_assig'])
6252
                        ? api_get_local_time($row['startdate_assig'])
6253
                        : get_lang('No');
6254
6255
                    $message_task_enddate = empty($row['enddate_assig'])
6256
                        ? api_get_local_time($row['enddate_assig'])
6257
                        : get_lang('No');
6258
6259
                    $message_task_delayedsubmit = $row['delayedsubmit'] == 0 ? get_lang('No') : get_lang('Yes');
6260
6261
                    $message_task_max_version = $row['max_version'] == 0 ? get_lang('No') : $row['max_version'];
6262
6263
                    $message_task_max_text = $row['max_text'] == 0 ? get_lang('No') : $row['max_text'];
6264
6265
                    // Comp message
6266
                    $message_task = '<b>'.get_lang('DescriptionOfTheTask').'</b><p>'.$row['task'].'</p><hr>'
6267
                        .'<p>'.get_lang('StartDate').': '.$message_task_startdate.'</p>'
6268
                        .'<p>'.get_lang('EndDate').': '.$message_task_enddate
6269
                        .' ('.get_lang('AllowLaterSends').') '.$message_task_delayedsubmit.'</p>'
6270
                        .'<p>'.get_lang('OtherSettings').': '.get_lang('NMaxVersion').': '.$message_task_max_version
6271
                        .' '.get_lang('NMaxWords').': '.$message_task_max_text.'</p>';
6272
                    // Display message
6273
                    Display::addFlash(
6274
                        Display::return_message($message_task)
6275
                    );
6276
                }
6277
6278
                if (!empty($row['id'])) {
6279
                    $feedback_message = '';
6280
                    if ($row['progress'] == $row['fprogress1'] && !empty($row['fprogress1'])) {
6281
                        $feedback_message = '<b>'.get_lang('Feedback').'</b>'
6282
                            .'<p>'.api_htmlentities($row['feedback1']).'</p>';
6283
                    } elseif ($row['progress'] == $row['fprogress2'] && !empty($row['fprogress2'])) {
6284
                        $feedback_message = '<b>'.get_lang('Feedback').'</b>'
6285
                            .'<p>'.api_htmlentities($row['feedback2']).'</p>';
6286
                    } elseif ($row['progress'] == $row['fprogress3'] && !empty($row['fprogress3'])) {
6287
                        $feedback_message = '<b>'.get_lang('Feedback').'</b>'
6288
                            .'<p>'.api_htmlentities($row['feedback3']).'</p>';
6289
                    }
6290
6291
                    if (!empty($feedback_message)) {
6292
                        Display::addFlash(
6293
                            Display::return_message($feedback_message)
6294
                        );
6295
                    }
6296
                }
6297
6298
                // Previous checking for concurrent editions
6299
                if (!empty($row['id']) && $row['is_editing'] == 0) {
6300
                    Display::addFlash(
6301
                        Display::return_message(get_lang('WarningMaxEditingTime'))
6302
                    );
6303
                    $time_edit = api_get_utc_datetime();
6304
                    $sql = 'UPDATE '.$tbl_wiki.' SET
6305
                            is_editing = "'.$userId.'",
6306
                            time_edit = "'.$time_edit.'"
6307
                            WHERE c_id = '.$course_id.' AND id="'.$row['id'].'"';
6308
                    Database::query($sql);
6309
                } elseif (!empty($row['id']) && $row['is_editing'] != $userId) {
6310
                    $timestamp_edit = strtotime($row['time_edit']);
6311
                    $time_editing = time() - $timestamp_edit;
6312
                    $max_edit_time = 1200; // 20 minutes
6313
                    $rest_time = $max_edit_time - $time_editing;
6314
6315
                    $userinfo = api_get_user_info($row['is_editing']);
6316
                    if ($userinfo !== false) {
6317
                        $is_being_edited = get_lang('ThisPageisBeginEditedBy').PHP_EOL
6318
                            .UserManager::getUserProfileLink($userinfo).PHP_EOL
6319
                            .get_lang('ThisPageisBeginEditedTryLater').PHP_EOL
6320
                            .date("i", $rest_time).PHP_EOL
6321
                            .get_lang('MinMinutes');
6322
6323
                        Display::addFlash(
6324
                            Display::return_message($is_being_edited, 'normal', false)
6325
                        );
6326
                    }
6327
6328
                    $this->redirectHome();
6329
                }
6330
6331
                // Form.
6332
                $url = api_get_self().'?action=edit&title='.urlencode($page).'&session_id='.api_get_session_id()
6333
                    .'&group_id='.api_get_group_id().'&'.api_get_cidreq();
6334
                $form = new FormValidator('wiki', 'post', $url);
6335
                $form->addElement(
6336
                    'header',
6337
                    $icon_assignment.str_repeat('&nbsp;', 3).api_htmlentities($title)
6338
                );
6339
                self::setForm($form, !empty($row['id']) ? $row : []);
6340
                $form->addElement('hidden', 'title');
6341
                $form->addButtonSave(get_lang('Save'), 'SaveWikiChange');
6342
                $row['title'] = $title;
6343
                $row['page_id'] = $page_id;
6344
                $row['reflink'] = $page;
6345
                $row['content'] = $content;
6346
6347
                if (!empty($row['id']) && true === api_get_configuration_value('wiki_categories_enabled')) {
6348
                    $wiki = Database::getManager()->find(CWiki::class, $row['id']);
6349
6350
                    foreach ($wiki->getCategories() as $category) {
6351
                        $row['category'][] = $category->getId();
6352
                    }
6353
                }
6354
6355
                $form->setDefaults($row);
6356
                $form->display();
6357
6358
                // Saving a change
6359
                if ($form->validate()) {
6360
                    $versionFromSession = Session::read('_version');
6361
                    if (empty($_POST['title'])) {
6362
                        Display::addFlash(
6363
                            Display::return_message(
6364
                                get_lang("NoWikiPageTitle"),
6365
                                'error'
6366
                            )
6367
                        );
6368
                    } elseif (!self::double_post($_POST['wpost_id'])) {
6369
                        //double post
6370
                    } elseif ($_POST['version'] != '' && $versionFromSession != 0 && $_POST['version'] != $versionFromSession) {
6371
                        //prevent concurrent users and double version
6372
                        Display::addFlash(
6373
                            Display::return_message(
6374
                                get_lang("EditedByAnotherUser"),
6375
                                'error'
6376
                            )
6377
                        );
6378
                    } else {
6379
                        $returnMessage = self::save_wiki(
6380
                            $form->exportValues()
6381
                        );
6382
                        Display::addFlash(
6383
                            Display::return_message(
6384
                                $returnMessage,
6385
                                'confirmation'
6386
                            )
6387
                        );
6388
                    }
6389
                    $wikiData = self::getWikiData();
6390
                    $redirectUrl = $this->url.'&action=showpage&title='.$wikiData['reflink'].'&'.api_get_cidreq();
6391
                    header('Location: '.$redirectUrl);
6392
                    exit;
6393
                }
6394
            }
6395
        }
6396
    }
6397
6398
    /**
6399
     * Get history.
6400
     */
6401
    public function getHistory()
6402
    {
6403
        $tbl_wiki = $this->tbl_wiki;
6404
        $condition_session = $this->condition_session;
6405
        $groupfilter = $this->groupfilter;
6406
        $page = $this->page;
6407
        $course_id = $this->course_id;
6408
        $session_id = $this->session_id;
6409
        $userId = api_get_user_id();
6410
6411
        if (!$_GET['title']) {
6412
            Display::addFlash(
6413
                Display::return_message(
6414
                    get_lang("MustSelectPage"),
6415
                    'error',
6416
                    false
6417
                )
6418
            );
6419
6420
            return;
6421
        }
6422
6423
        /* First, see the property visibility that is at the last register and
6424
        therefore we should select descending order.
6425
        But to give ownership to each record,
6426
        this is no longer necessary except for the title. TODO: check this*/
6427
6428
        $sql = 'SELECT * FROM '.$tbl_wiki.'
6429
                WHERE
6430
                    c_id = '.$course_id.' AND
6431
                    reflink="'.Database::escape_string($page).'" AND
6432
                    '.$groupfilter.$condition_session.'
6433
                ORDER BY id DESC';
6434
        $result = Database::query($sql);
6435
6436
        $KeyVisibility = null;
6437
        $KeyAssignment = null;
6438
        $KeyTitle = null;
6439
        $KeyUserId = null;
6440
        while ($row = Database::fetch_array($result)) {
6441
            $KeyVisibility = $row['visibility'];
6442
            $KeyAssignment = $row['assignment'];
6443
            $KeyTitle = $row['title'];
6444
            $KeyUserId = $row['user_id'];
6445
        }
6446
        $icon_assignment = null;
6447
        if ($KeyAssignment == 1) {
6448
            $icon_assignment = Display::return_icon(
6449
                'wiki_assignment.png',
6450
                get_lang('AssignmentDescExtra'),
6451
                '',
6452
                ICON_SIZE_SMALL
6453
            );
6454
        } elseif ($KeyAssignment == 2) {
6455
            $icon_assignment = Display::return_icon(
6456
                'wiki_work.png',
6457
                get_lang('AssignmentWorkExtra'),
6458
                '',
6459
                ICON_SIZE_SMALL
6460
            );
6461
        }
6462
6463
        // Second, show
6464
        //if the page is hidden and is a job only sees its author and professor
6465
        if ($KeyVisibility == 1 ||
6466
            api_is_allowed_to_edit(false, true) ||
6467
            api_is_platform_admin() ||
6468
            (
6469
                $KeyAssignment == 2 && $KeyVisibility == 0 &&
6470
                ($userId == $KeyUserId)
6471
            )
6472
        ) {
6473
            // We show the complete history
6474
            if (!isset($_POST['HistoryDifferences']) &&
6475
                !isset($_POST['HistoryDifferences2'])
6476
            ) {
6477
                $sql = 'SELECT * FROM '.$tbl_wiki.'
6478
                        WHERE
6479
                            c_id = '.$course_id.' AND
6480
                            reflink="'.Database::escape_string($page).'" AND
6481
                            '.$groupfilter.$condition_session.'
6482
                        ORDER BY id DESC';
6483
                $result = Database::query($sql);
6484
                $title = $_GET['title'];
6485
                $group_id = api_get_group_id();
6486
6487
                echo '<div id="wikititle">';
6488
                echo $icon_assignment.'&nbsp;&nbsp;&nbsp;'.api_htmlentities(
6489
                        $KeyTitle
6490
                    );
6491
                echo '</div>';
6492
6493
                echo '<form id="differences" method="POST" action="index.php?'.api_get_cidreq(
6494
                    ).'&action=history&title='.api_htmlentities(
6495
                        urlencode($title)
6496
                    ).'&session_id='.api_htmlentities(
6497
                        $session_id
6498
                    ).'&group_id='.api_htmlentities($group_id).'">';
6499
6500
                echo '<ul style="list-style-type: none;">';
6501
                echo '<br/>';
6502
                echo '<button class="search" type="submit" name="HistoryDifferences" value="HistoryDifferences">'.
6503
                    get_lang('ShowDifferences').' '.get_lang(
6504
                        'LinesDiff'
6505
                    ).'</button>';
6506
                echo '<button class="search" type="submit" name="HistoryDifferences2" value="HistoryDifferences2">'.
6507
                    get_lang('ShowDifferences').' '.get_lang(
6508
                        'WordsDiff'
6509
                    ).'</button>';
6510
                echo '<br/><br/>';
6511
6512
                $counter = 0;
6513
                $total_versions = Database::num_rows($result);
6514
6515
                while ($row = Database::fetch_array($result)) {
6516
                    $userinfo = api_get_user_info($row['user_id']);
6517
                    $username = api_htmlentities(
6518
                        sprintf(get_lang('LoginX'), $userinfo['username']),
6519
                        ENT_QUOTES
6520
                    );
6521
6522
                    echo '<li style="margin-bottom: 5px;">';
6523
                    ($counter == 0) ? $oldstyle = 'style="visibility: hidden;"' : $oldstyle = '';
6524
                    ($counter == 0) ? $newchecked = ' checked' : $newchecked = '';
6525
                    ($counter == $total_versions - 1) ? $newstyle = 'style="visibility: hidden;"' : $newstyle = '';
6526
                    ($counter == 1) ? $oldchecked = ' checked' : $oldchecked = '';
6527
                    echo '<input name="old" value="'.$row['id'].'" type="radio" '.$oldstyle.' '.$oldchecked.'/> ';
6528
                    echo '<input name="new" value="'.$row['id'].'" type="radio" '.$newstyle.' '.$newchecked.'/> ';
6529
                    echo '<a href="'.api_get_self(
6530
                        ).'?action=showpage&title='.api_htmlentities(
6531
                            urlencode($page)
6532
                        ).'&view='.$row['id'].'">';
6533
                    echo '<a href="'.api_get_self().'?'.api_get_cidreq(
6534
                        ).'&action=showpage&title='.api_htmlentities(
6535
                            urlencode($page)
6536
                        ).'&view='.$row['id'].'">';
6537
                    echo api_get_local_time(
6538
                        $row['dtime']
6539
                    );
6540
                    echo '</a>';
6541
                    echo ' ('.get_lang('Version').' '.$row['version'].')';
6542
                    echo ' '.get_lang('By').' ';
6543
                    if ($userinfo !== false) {
6544
                        echo UserManager::getUserProfileLink($userinfo);
6545
                    } else {
6546
                        echo get_lang('Anonymous').' ('.api_htmlentities(
6547
                                $row['user_ip']
6548
                            ).')';
6549
                    }
6550
                    echo ' ( '.get_lang('Progress').': '.api_htmlentities(
6551
                            $row['progress']
6552
                        ).'%, ';
6553
                    $comment = $row['comment'];
6554
                    if (!empty($comment)) {
6555
                        $comment = api_substr($comment, 0, 100);
6556
                        if ($comment !== false) {
6557
                            $comment = api_htmlentities($comment);
6558
                            echo get_lang('Comments').': '.$comment;
6559
                            if (api_strlen($row['comment']) > 100) {
6560
                                echo '... ';
6561
                            }
6562
                        }
6563
                    } else {
6564
                        echo get_lang('Comments').':  ---';
6565
                    }
6566
                    echo ' ) </li>';
6567
                    $counter++;
6568
                } //end while
6569
6570
                echo '<br/>';
6571
                echo '<button class="search" type="submit" name="HistoryDifferences" value="HistoryDifferences">'.get_lang(
6572
                        'ShowDifferences'
6573
                    ).' '.get_lang('LinesDiff').'</button>';
6574
                echo '<button class="search" type="submit" name="HistoryDifferences2" value="HistoryDifferences2">'.get_lang(
6575
                        'ShowDifferences'
6576
                    ).' '.get_lang('WordsDiff').'</button>';
6577
                echo '</ul></form>';
6578
            } else { // We show the differences between two versions
6579
                $version_old = [];
6580
                if (isset($_POST['old'])) {
6581
                    $sql_old = "SELECT * FROM $tbl_wiki
6582
                                WHERE c_id = $course_id AND id='".Database::escape_string(
6583
                            $_POST['old']
6584
                        )."'";
6585
                    $result_old = Database::query($sql_old);
6586
                    $version_old = Database::fetch_array($result_old);
6587
                }
6588
6589
                $sql_new = "SELECT * FROM $tbl_wiki
6590
                            WHERE
6591
                              c_id = $course_id AND
6592
                              id = '".Database::escape_string($_POST['new'])."'";
6593
                $result_new = Database::query($sql_new);
6594
                $version_new = Database::fetch_array($result_new);
6595
                $oldTime = isset($version_old['dtime']) ? api_get_local_time($version_old['dtime']) : null;
6596
                $oldContent = isset($version_old['content']) ? $version_old['content'] : null;
6597
6598
                if (isset($_POST['HistoryDifferences'])) {
6599
                    include 'diff.inc.php';
6600
                    //title
6601
                    echo '<div id="wikititle">'.api_htmlentities(
6602
                            $version_new['title']
6603
                        ).'
6604
                            <font size="-2"><i>('.get_lang('DifferencesNew').'</i>
6605
                            <font style="background-color:#aaaaaa">'.api_get_local_time($version_new['dtime']).'</font>
6606
                            <i>'.get_lang('DifferencesOld').'</i>
6607
                            <font style="background-color:#aaaaaa">'.$oldTime.'</font>
6608
                ) '.get_lang('Legend').':  <span class="diffAdded" >'.get_lang(
6609
                            'WikiDiffAddedLine'
6610
                        ).'</span>
6611
                <span class="diffDeleted" >'.get_lang(
6612
                            'WikiDiffDeletedLine'
6613
                        ).'</span> <span class="diffMoved">'.get_lang(
6614
                            'WikiDiffMovedLine'
6615
                        ).'</span></font>
6616
                </div>';
6617
                }
6618
                if (isset($_POST['HistoryDifferences2'])) {
6619
                    //title
6620
                    echo '<div id="wikititle">'.api_htmlentities(
6621
                            $version_new['title']
6622
                        ).'
6623
                        <font size="-2"><i>('.get_lang(
6624
                            'DifferencesNew'
6625
                        ).'</i> <font style="background-color:#aaaaaa">'.api_get_local_time($version_new['dtime']).'</font>
6626
                        <i>'.get_lang(
6627
                            'DifferencesOld'
6628
                        ).'</i> <font style="background-color:#aaaaaa">'.$oldTime.'</font>)
6629
                        '.get_lang(
6630
                            'Legend'
6631
                        ).':  <span class="diffAddedTex" >'.get_lang(
6632
                            'WikiDiffAddedTex'
6633
                        ).'</span>
6634
                        <span class="diffDeletedTex" >'.get_lang(
6635
                            'WikiDiffDeletedTex'
6636
                        ).'</span></font></div>';
6637
                }
6638
6639
                if (isset($_POST['HistoryDifferences'])) {
6640
                    echo '<table>'.diff(
6641
                            $oldContent,
6642
                            $version_new['content'],
6643
                            true,
6644
                            'format_table_line'
6645
                        ).'</table>'; // format_line mode is better for words
6646
                    echo '<br />';
6647
                    echo '<strong>'.get_lang(
6648
                            'Legend'
6649
                        ).'</strong><div class="diff">'."\n";
6650
                    echo '<table><tr>';
6651
                    echo '<td>';
6652
                    echo '</td><td>';
6653
                    echo '<span class="diffEqual" >'.get_lang(
6654
                            'WikiDiffUnchangedLine'
6655
                        ).'</span><br />';
6656
                    echo '<span class="diffAdded" >'.get_lang(
6657
                            'WikiDiffAddedLine'
6658
                        ).'</span><br />';
6659
                    echo '<span class="diffDeleted" >'.get_lang(
6660
                            'WikiDiffDeletedLine'
6661
                        ).'</span><br />';
6662
                    echo '<span class="diffMoved" >'.get_lang(
6663
                            'WikiDiffMovedLine'
6664
                        ).'</span><br />';
6665
                    echo '</td>';
6666
                    echo '</tr></table>';
6667
                }
6668
6669
                if (isset($_POST['HistoryDifferences2'])) {
6670
                    $lines1 = [strip_tags($oldContent)]; //without <> tags
6671
                    $lines2 = [
6672
                        strip_tags(
6673
                            $version_new['content']
6674
                        ),
6675
                    ]; //without <> tags
6676
                    $diff = new Text_Diff($lines1, $lines2);
6677
                    $renderer = new Text_Diff_Renderer_inline();
6678
                    echo '<style>del{background:#fcc}ins{background:#cfc}</style>'.$renderer->render(
6679
                            $diff
6680
                        ); // Code inline
6681
                    echo '<br />';
6682
                    echo '<strong>'.get_lang(
6683
                            'Legend'
6684
                        ).'</strong><div class="diff">'."\n";
6685
                    echo '<table><tr>';
6686
                    echo '<td>';
6687
                    echo '</td><td>';
6688
                    echo '<span class="diffAddedTex" >'.get_lang(
6689
                            'WikiDiffAddedTex'
6690
                        ).'</span><br />';
6691
                    echo '<span class="diffDeletedTex" >'.get_lang(
6692
                            'WikiDiffDeletedTex'
6693
                        ).'</span><br />';
6694
                    echo '</td>';
6695
                    echo '</tr></table>';
6696
                }
6697
            }
6698
        }
6699
    }
6700
6701
    /**
6702
     * Get stat tables.
6703
     */
6704
    public function getStatsTable()
6705
    {
6706
        $_course = $this->courseInfo;
6707
        $session_id = $this->session_id;
6708
        $groupId = $this->group_id;
6709
6710
        echo '<div class="actions">'.get_lang('More').'</div>';
6711
        echo '<table border="0">';
6712
        echo '  <tr>';
6713
        echo '    <td>';
6714
        echo '      <ul>';
6715
        //Submenu Most active users
6716
        echo '        <li><a href="'.$this->url.'&action=mactiveusers">'.get_lang('MostActiveUsers').'</a></li>';
6717
        //Submenu Most visited pages
6718
        echo '        <li><a href="'.$this->url.'&action=mvisited">'.get_lang('MostVisitedPages').'</a></li>';
6719
        //Submenu Most changed pages
6720
        echo '        <li><a href="'.$this->url.'&action=mostchanged">'.get_lang('MostChangedPages').'</a></li>';
6721
        echo '      </ul>';
6722
        echo '    </td>';
6723
        echo '    <td>';
6724
        echo '      <ul>';
6725
        // Submenu Orphaned pages
6726
        echo '        <li><a href="'.$this->url.'&action=orphaned">'.get_lang('OrphanedPages').'</a></li>';
6727
        // Submenu Wanted pages
6728
        echo '        <li><a href="'.$this->url.'&action=wanted">'.get_lang('WantedPages').'</a></li>';
6729
        // Submenu Most linked pages
6730
        echo '<li><a href="'.$this->url.'&action=mostlinked">'.get_lang('MostLinkedPages').'</a></li>';
6731
        echo '</ul>';
6732
        echo '</td>';
6733
        echo '<td style="vertical-align:top">';
6734
        echo '<ul>';
6735
        // Submenu Statistics
6736
        if (api_is_allowed_to_edit(false, true) || api_is_platform_admin()) {
6737
            echo '<li><a href="'.$this->url.'&action=statistics">'.get_lang('Statistics').'</a></li>';
6738
        }
6739
        echo '      </ul>';
6740
        echo '    </td>';
6741
        echo '  </tr>';
6742
        echo '</table>';
6743
    }
6744
6745
    /**
6746
     * Kind of controller.
6747
     */
6748
    public function handleAction(string $action)
6749
    {
6750
        $page = $this->page;
6751
        switch ($action) {
6752
            case 'export_to_pdf':
6753
                if (isset($_GET['wiki_id'])) {
6754
                    self::export_to_pdf($_GET['wiki_id'], api_get_course_id());
6755
                    break;
6756
                }
6757
                break;
6758
            case 'export2doc':
6759
                if (isset($_GET['wiki_id'])) {
6760
                    $export2doc = self::export2doc($_GET['wiki_id']);
6761
                    if ($export2doc) {
6762
                        Display::addFlash(
6763
                            Display::return_message(
6764
                                get_lang('ThePageHasBeenExportedToDocArea'),
6765
                                'confirmation',
6766
                                false
6767
                            )
6768
                        );
6769
                    }
6770
                }
6771
                break;
6772
            case 'restorepage':
6773
                self::restorePage();
6774
                break;
6775
            case 'more':
6776
                self::getStatsTable();
6777
                break;
6778
            case 'statistics':
6779
                self::getStats();
6780
                break;
6781
            case 'mactiveusers':
6782
                self::getActiveUsers($action);
6783
                break;
6784
            case 'usercontrib':
6785
                self::getUserContributions($_GET['user_id'], $action);
6786
                break;
6787
            case 'mostchanged':
6788
                $this->getMostChangedPages($action);
6789
                break;
6790
            case 'mvisited':
6791
                self::getMostVisited();
6792
                break;
6793
            case 'wanted':
6794
                $this->getWantedPages();
6795
                break;
6796
            case 'orphaned':
6797
                self::getOrphaned();
6798
                break;
6799
            case 'mostlinked':
6800
                self::getMostLinked();
6801
                break;
6802
            case 'delete':
6803
                self::deletePageWarning($page);
6804
                break;
6805
            case 'deletewiki':
6806
                $title = '<div class="actions">'.get_lang(
6807
                        'DeleteWiki'
6808
                    ).'</div>';
6809
                if (api_is_allowed_to_edit(
6810
                        false,
6811
                        true
6812
                    ) || api_is_platform_admin()) {
6813
                    $message = get_lang('ConfirmDeleteWiki');
6814
                    $message .= '<p>
6815
                        <a href="index.php?'.api_get_cidreq().'">'.get_lang(
6816
                            'No'
6817
                        ).'</a>
6818
                        &nbsp;&nbsp;|&nbsp;&nbsp;
6819
                        <a href="'.api_get_self().'?'.api_get_cidreq(
6820
                        ).'&action=deletewiki&delete=yes">'.
6821
                        get_lang('Yes').'</a>
6822
                    </p>';
6823
6824
                    if (!isset($_GET['delete'])) {
6825
                        Display::addFlash(
6826
                            $title.Display::return_message(
6827
                                $message,
6828
                                'warning',
6829
                                false
6830
                            )
6831
                        );
6832
                    }
6833
                } else {
6834
                    Display::addFlash(
6835
                        Display::return_message(
6836
                            get_lang("OnlyAdminDeleteWiki"),
6837
                            'normal',
6838
                            false
6839
                        )
6840
                    );
6841
                }
6842
6843
                if (api_is_allowed_to_edit(
6844
                        false,
6845
                        true
6846
                    ) || api_is_platform_admin()) {
6847
                    if (isset($_GET['delete']) && $_GET['delete'] == 'yes') {
6848
                        $return_message = self::delete_wiki();
6849
                        Display::addFlash(
6850
                            Display::return_message(
6851
                                $return_message,
6852
                                'confirmation',
6853
                                false
6854
                            )
6855
                        );
6856
                        $this->redirectHome();
6857
                    }
6858
                }
6859
                break;
6860
            case 'searchpages':
6861
                self::getSearchPages($action);
6862
                break;
6863
            case 'links':
6864
                self::getLinks($page);
6865
                break;
6866
            case 'addnew':
6867
                if (api_get_session_id() != 0 && api_is_allowed_to_session_edit(false, true) == false) {
6868
                    api_not_allowed();
6869
                }
6870
                $groupInfo = GroupManager::get_group_properties(
6871
                    api_get_group_id()
6872
                );
6873
                echo '<div class="actions">'.get_lang('AddNew').'</div>';
6874
                echo '<br/>';
6875
                //first, check if page index was created. chektitle=false
6876
                if (self::checktitle('index')) {
6877
                    if (api_is_allowed_to_edit(false, true) ||
6878
                        api_is_platform_admin() ||
6879
                        GroupManager::is_user_in_group(
6880
                            api_get_user_id(),
6881
                            $groupInfo
6882
                        ) ||
6883
                        api_is_allowed_in_course()
6884
                    ) {
6885
                        Display::addFlash(
6886
                            Display::return_message(get_lang('GoAndEditMainPage'), 'normal', false)
6887
                        );
6888
                    } else {
6889
                        Display::addFlash(
6890
                            Display::return_message(get_lang('WikiStandBy'), 'normal', false)
6891
                        );
6892
                    }
6893
                } elseif (self::check_addnewpagelock() == 0
6894
                    && (
6895
                        api_is_allowed_to_edit(false, true) == false
6896
                        || api_is_platform_admin() == false
6897
                    )
6898
                ) {
6899
                    Display::addFlash(
6900
                        Display::return_message(get_lang('AddPagesLocked'), 'error', false)
6901
                    );
6902
                } else {
6903
                    $groupInfo = GroupManager::get_group_properties(
6904
                        api_get_group_id()
6905
                    );
6906
                    if (api_is_allowed_to_edit(false, true) ||
6907
                        api_is_platform_admin() ||
6908
                        GroupManager::is_user_in_group(
6909
                            api_get_user_id(),
6910
                            $groupInfo
6911
                        ) ||
6912
                        $_GET['group_id'] == 0
6913
                    ) {
6914
                        self::display_new_wiki_form();
6915
                    } else {
6916
                        Display::addFlash(
6917
                            Display::return_message(get_lang('OnlyAddPagesGroupMembers'), 'normal', false)
6918
                        );
6919
                    }
6920
                }
6921
                break;
6922
            case 'show':
6923
            case 'showpage':
6924
                self::display_wiki_entry($page);
6925
                break;
6926
            case 'edit':
6927
                self::editPage();
6928
                break;
6929
            case 'history':
6930
                self::getHistory();
6931
                break;
6932
            case 'recentchanges':
6933
                self::recentChanges($page, $action);
6934
                break;
6935
            case 'allpages':
6936
                self::allPages($action);
6937
                break;
6938
            case 'discuss':
6939
                self::getDiscuss($page);
6940
                break;
6941
            case 'export_to_doc_file':
6942
                self::exportTo($_GET['id'], 'odt');
6943
                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...
6944
                break;
6945
            case 'category':
6946
                $this->addCategory();
6947
                break;
6948
            case 'delete_category':
6949
                $this->deleteCategory();
6950
                break;
6951
        }
6952
    }
6953
6954
    /**
6955
     * Redirect to home.
6956
     */
6957
    public function redirectHome()
6958
    {
6959
        $redirectUrl = $this->url.'&action=showpage&title=index';
6960
        header('Location: '.$redirectUrl.'&'.api_get_cidreq());
6961
        exit;
6962
    }
6963
6964
    /**
6965
     * Export wiki content in a ODF.
6966
     *
6967
     * @param int $id
6968
     * @param string int
6969
     *
6970
     * @return bool
6971
     */
6972
    public function exportTo($id, $format = 'doc')
6973
    {
6974
        $data = self::getWikiDataFromDb($id);
6975
6976
        if (isset($data['content']) && !empty($data['content'])) {
6977
            Export::htmlToOdt($data['content'], $data['reflink'], $format);
6978
        }
6979
6980
        return false;
6981
    }
6982
6983
    private function returnCategoriesBlock(int $wikiId, string $tagStart = '<div>', string $tagEnd = '</div>'): string
6984
    {
6985
        if (true !== api_get_configuration_value('wiki_categories_enabled') || empty($wikiId)) {
6986
            return '';
6987
        }
6988
6989
        $wiki = Database::getManager()->find(CWiki::class, $wikiId);
6990
6991
        return $tagStart.implode(', ', $wiki->getCategories()->getValues()).$tagEnd;
6992
    }
6993
6994
    private function gelAllPagesQuery(
6995
        $onlyCount = false,
6996
        $from = 0,
6997
        $numberOfItems = 10,
6998
        $column = 0,
6999
        $direction = 'ASC'
7000
    ): ?Statement {
7001
        $tblWiki = $this->tbl_wiki;
7002
7003
        $fields = $onlyCount
7004
            ? 'COUNT(s1.iid) AS nbr'
7005
            : 's1.assignment col0, s1.title col1, s1.user_id col2, s1.dtime col3, s1.reflink, s1.user_ip, s1.iid';
7006
7007
        $query = 'SELECT '.$fields.' FROM '.$tblWiki.' s1 WHERE s1.c_id = '.$this->course_id.' ';
7008
7009
        if (!api_is_allowed_to_edit(false, true) && !api_is_platform_admin()) {
7010
            // warning don't use group by reflink because does not return the last version
7011
            $query .= 'AND visibility = 1 ';
7012
        }
7013
7014
        $query .= 'AND id = (
7015
            SELECT MAX(s2.id) FROM '.$tblWiki.' s2
7016
            WHERE s2.c_id = '.$this->course_id.'
7017
                AND s1.reflink = s2.reflink
7018
                AND '.$this->groupfilter.'
7019
                AND session_id = '.$this->session_id.'
7020
        ) ';
7021
7022
        if (!$onlyCount) {
7023
            $query .= "ORDER BY col$column $direction LIMIT $from, $numberOfItems";
7024
        }
7025
7026
        return Database::query($query);
7027
    }
7028
7029
    private function deleteCategory()
7030
    {
7031
        if (!api_is_allowed_to_edit(false, true) && !api_is_platform_admin()) {
7032
            api_not_allowed(true);
7033
        }
7034
7035
        if (true !== api_get_configuration_value('wiki_categories_enabled')) {
7036
            api_not_allowed(true);
7037
        }
7038
7039
        $em = Database::getManager();
7040
7041
        $category = null;
7042
7043
        if (isset($_GET['id'])) {
7044
            $category = $em->find(CWikiCategory::class, $_GET['id']);
7045
7046
            if (!$category) {
7047
                api_not_allowed(true);
7048
            }
7049
        }
7050
7051
        $em->remove($category);
7052
        $em->flush();
7053
7054
        Display::addFlash(
7055
            Display::return_message(get_lang('CategoryDeleted'), 'success')
7056
        );
7057
7058
        header('Location: index.php?'.api_get_cidreq().'&action=category');
7059
        exit;
7060
    }
7061
7062
    private function addCategory()
7063
    {
7064
        if (!api_is_allowed_to_edit(false, true) && !api_is_platform_admin()) {
7065
            api_not_allowed(true);
7066
        }
7067
7068
        if (true !== api_get_configuration_value('wiki_categories_enabled')) {
7069
            api_not_allowed(true);
7070
        }
7071
7072
        $categoryRepo = Database::getManager()->getRepository(CWikiCategory::class);
7073
7074
        $categoryToEdit = null;
7075
7076
        if (isset($_GET['id'])) {
7077
            $categoryToEdit = $categoryRepo->find($_GET['id']);
7078
7079
            if (!$categoryToEdit) {
7080
                api_not_allowed(true);
7081
            }
7082
        }
7083
7084
        $course = api_get_course_entity();
7085
        $session = api_get_session_entity();
7086
7087
        if ($categoryToEdit
7088
            && ($course !== $categoryToEdit->getCourse() || $session !== $categoryToEdit->getSession())
7089
        ) {
7090
            api_not_allowed(true);
7091
        }
7092
7093
        $self = api_get_self();
7094
        $cidReq = api_get_cidreq();
7095
        $iconEdit = Display::return_icon('edit.png', get_lang('Edit'));
7096
        $iconDelete = Display::return_icon('delete.png', get_lang('Delete'));
7097
7098
        $categories = $categoryRepo->findByCourse($course, $session);
7099
        $categoryList = array_map(
7100
            function (CWikiCategory $category) use ($self, $cidReq, $iconEdit, $iconDelete) {
7101
                $actions = [];
7102
                $actions[] = Display::url(
7103
                    $iconEdit,
7104
                    "$self?$cidReq&".http_build_query(['action' => 'category', 'id' => $category->getId()])
7105
                );
7106
                $actions[] = Display::url(
7107
                    $iconDelete,
7108
                    "$self?$cidReq&".http_build_query(['action' => 'delete_category', 'id' => $category->getId()])
7109
                );
7110
7111
                return [
7112
                    $category->getNodeName(),
7113
                    implode(PHP_EOL, $actions),
7114
                ];
7115
            },
7116
            $categories
7117
        );
7118
7119
        $table = new SortableTableFromArray($categoryList);
7120
        $table->set_header(0, get_lang('Name'), false);
7121
        $table->set_header(1, get_lang('Actions'), false, ['class' => 'text-right'], ['class' => 'text-right']);
7122
7123
        $form = $this->createCategoryForm($categoryToEdit);
7124
        $form->display();
7125
        echo '<hr>';
7126
        $table->display();
7127
    }
7128
7129
    private function createCategoryForm(CWikiCategory $category = null): FormValidator
7130
    {
7131
        $em = Database::getManager();
7132
        $categoryRepo = $em->getRepository(CWikiCategory::class);
7133
7134
        $course = api_get_course_entity($this->courseInfo['real_id']);
7135
        $session = api_get_session_entity($this->session_id);
7136
7137
        $categories = $categoryRepo->findByCourse($course, $session);
7138
7139
        $formAction = $this->url.'&'.http_build_query([
7140
                'action' => 'category',
7141
                'id' => $category ? $category->getId() : null,
7142
            ]);
7143
7144
        $form = new FormValidator('category', 'post', $formAction);
7145
        $form->addHeader(get_lang('AddCategory'));
7146
        $form->addSelectFromCollection('parent', get_lang('Parent'), $categories, [], true, 'getNodeName');
7147
        $form->addText('name', get_lang('Name'));
7148
7149
        if ($category) {
7150
            $form->addButtonUpdate(get_lang('Update'));
7151
        } else {
7152
            $form->addButtonSave(get_lang('Save'));
7153
        }
7154
7155
        if ($form->validate()) {
7156
            $values = $form->exportValues();
7157
            $parent = $categoryRepo->find($values['parent']);
7158
7159
            if (!$category) {
7160
                $category = (new CWikiCategory())
7161
                    ->setCourse($course)
7162
                    ->setSession($session)
7163
                ;
7164
7165
                $em->persist($category);
7166
7167
                Display::addFlash(
7168
                    Display::return_message(get_lang('CategoryAdded'), 'success')
7169
                );
7170
            } else {
7171
                Display::addFlash(
7172
                    Display::return_message(get_lang('CategoryEdited'), 'success')
7173
                );
7174
            }
7175
7176
            $category
7177
                ->setName($values['name'])
7178
                ->setParent($parent)
7179
            ;
7180
7181
            $em->flush();
7182
7183
            header('Location: index.php?'.api_get_cidreq().'&action=category');
7184
            exit;
7185
        }
7186
7187
        if ($category) {
7188
            $form->setDefaults([
7189
                'parent' => $category->getParent() ? $category->getParent()->getId() : 0,
7190
                'name' => $category->getName(),
7191
            ]);
7192
        }
7193
7194
        return $form;
7195
    }
7196
7197
    private static function assignCategoriesToWiki(CWiki $wiki, array $categoriesIdList)
7198
    {
7199
        if (true !== api_get_configuration_value('wiki_categories_enabled')) {
7200
            return;
7201
        }
7202
7203
        $em = Database::getManager();
7204
7205
        foreach ($categoriesIdList as $categoryId) {
7206
            $category = $em->find(CWikiCategory::class, $categoryId);
7207
            $wiki->addCategory($category);
7208
        }
7209
7210
        $em->flush();
7211
    }
7212
}
7213