Wiki   F
last analyzed

Complexity

Total Complexity 741

Size/Duplication

Total Lines 7184
Duplicated Lines 0 %

Importance

Changes 9
Bugs 5 Features 0
Metric Value
wmc 741
eloc 4542
c 9
b 5
f 0
dl 0
loc 7184
rs 0.8

74 Methods

Rating   Name   Duplication   Size   Complexity  
A checktitle() 0 20 2
B links_to() 0 32 7
A detect_mail_link() 0 7 1
A detect_news_link() 0 7 1
A detect_ftp_link() 0 7 1
A detect_irc_link() 0 7 1
A detect_anchor_link() 0 7 1
A detect_external_link() 0 6 1
A __construct() 0 23 2
C setForm() 0 163 9
A word_count() 0 43 1
B createCategoryForm() 0 66 7
A renderShowPage() 0 54 5
D recentChanges() 0 160 13
A assignCategoriesToWiki() 0 14 3
A setWikiData() 0 3 1
A getPageByTitle() 0 23 5
A double_post() 0 15 3
A returnCategoriesBlock() 0 31 5
B blockConcurrentEditions() 0 22 7
A getWikiData() 0 3 1
A exportTo() 0 9 3
A export_to_pdf() 0 60 3
A getAllWiki() 0 12 1
B getWantedPages() 0 82 8
A delete_wiki() 0 37 3
F getOrphaned() 0 134 15
B check_addnewpagelock() 0 48 10
B addCategory() 0 63 9
F getStats() 0 678 28
A deleteCategory() 0 31 6
A wiki_exist() 0 18 2
B make_wiki_link_clickable() 0 49 9
A redirectHome() 0 4 1
B display_new_wiki_form() 0 59 10
A updateWikiIsEditing() 0 14 1
C getUserContributions() 0 140 9
A checkLastVersion() 0 51 3
B deletePageWarning() 0 65 9
B getMostChangedPages() 0 84 8
B getActiveUsers() 0 57 5
A is_active_navigation_tab() 0 4 3
F save_new_wiki() 0 179 15
B check_notify_page() 0 68 11
A deletePage() 0 35 2
A restore_wikipage() 0 68 1
B check_notify_all() 0 50 9
A gelAllPagesQuery() 0 33 5
B getMostLinked() 0 91 8
C auto_add_page_users() 0 155 12
B showActionBar() 0 67 7
F restorePage() 0 145 23
F handleAction() 0 198 52
B check_notify_discuss() 0 54 9
C allPages() 0 181 13
C export2doc() 0 142 8
A getWikiDataFromDb() 0 16 3
B getMostVisited() 0 86 8
A getStatsTable() 0 35 3
F editPage() 0 321 73
F getLinks() 0 162 15
A getLastWikiData() 0 16 1
F save_wiki() 0 189 17
F getHistory() 0 281 29
F display_wiki_search_results() 0 245 26
B getSearchPages() 0 87 5
F check_emailcue() 0 218 17
F display_wiki_entry() 0 374 50
F getDiscuss() 0 442 48
B check_visibility_page() 0 66 11
B check_protect_page() 0 50 10
B check_addlock_discuss() 0 56 9
B check_ratinglock_discuss() 0 58 9
B check_visibility_discuss() 0 56 9

How to fix   Complexity   

Complex Class

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

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

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

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