Passed
Pull Request — 1.11.x (#4538)
by Angel Fernando Quiroz
10:51
created

Wiki   F

Complexity

Total Complexity 737

Size/Duplication

Total Lines 7169
Duplicated Lines 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
wmc 737
eloc 4534
c 6
b 0
f 0
dl 0
loc 7169
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
A delete_wiki() 0 37 3
B make_wiki_link_clickable() 0 49 9
B display_new_wiki_form() 0 59 10
F save_new_wiki() 0 179 15
A restore_wikipage() 0 68 1
C setForm() 0 163 9
F save_wiki() 0 189 17
B getWantedPages() 0 82 8
F getOrphaned() 0 134 15
B check_addnewpagelock() 0 48 10
F getStats() 0 678 28
D recentChanges() 0 160 13
A wiki_exist() 0 18 2
F display_wiki_search_results() 0 245 26
B check_ratinglock_discuss() 0 58 9
B getSearchPages() 0 87 5
A updateWikiIsEditing() 0 14 1
C getUserContributions() 0 140 9
B check_visibility_discuss() 0 56 9
A checkLastVersion() 0 51 3
B getMostChangedPages() 0 84 8
B getActiveUsers() 0 57 5
A is_active_navigation_tab() 0 4 3
A setWikiData() 0 3 1
B check_notify_page() 0 68 11
A deletePage() 0 35 2
A getPageByTitle() 0 23 5
B check_notify_all() 0 50 9
A double_post() 0 15 3
A word_count() 0 43 1
F display_wiki_entry() 0 374 50
B check_visibility_page() 0 66 11
B getMostLinked() 0 91 8
C check_emailcue() 0 203 14
C auto_add_page_users() 0 155 12
F restorePage() 0 145 23
B blockConcurrentEditions() 0 22 7
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 getWikiData() 0 3 1
F getLinks() 0 162 15
F getDiscuss() 0 442 48
A getLastWikiData() 0 16 1
B check_protect_page() 0 50 10
A export_to_pdf() 0 60 3
B check_addlock_discuss() 0 56 9
A getAllWiki() 0 12 1
B createCategoryForm() 0 66 7
A renderShowPage() 0 54 5
B addCategory() 0 63 9
A deleteCategory() 0 31 6
A redirectHome() 0 4 1
A assignCategoriesToWiki() 0 14 3
B deletePageWarning() 0 65 9
A gelAllPagesQuery() 0 33 5
A returnCategoriesBlock() 0 31 4
B showActionBar() 0 67 7
F handleAction() 0 198 52
A getStatsTable() 0 35 3
F editPage() 0 321 73
F getHistory() 0 281 29
A exportTo() 0 9 3

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