a43090d838af3e0801153f88e2c4a99a4e7a79d3
[moodle.git] / mod / wiki / pagelib.php
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * This file contains several classes uses to render the diferent pages
20  * of the wiki module
21  *
22  * @package mod_wiki
23  * @copyright 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu
24  * @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu
25  *
26  * @author Jordi Piguillem
27  * @author Marc Alier
28  * @author David Jimenez
29  * @author Josep Arus
30  * @author Daniel Serrano
31  * @author Kenneth Riba
32  *
33  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34  */
36 defined('MOODLE_INTERNAL') || die();
38 require_once($CFG->dirroot . '/mod/wiki/edit_form.php');
40 /**
41  * Class page_wiki contains the common code between all pages
42  *
43  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
44  */
45 abstract class page_wiki {
47     /**
48      * @var object Current subwiki
49      */
50     protected $subwiki;
52     /**
53      * @var int Current page
54      */
55     protected $page;
57     /**
58      * @var string Current page title
59      */
60     protected $title;
62     /**
63      * @var int Current group ID
64      */
65     protected $gid;
67     /**
68      * @var object module context object
69      */
70     protected $modcontext;
72     /**
73      * @var int Current user ID
74      */
75     protected $uid;
76     /**
77      * @var array The tabs set used in wiki module
78      */
79     protected $tabs = array('view' => 'view', 'edit' => 'edit', 'comments' => 'comments',
80                             'history' => 'history', 'map' => 'map', 'files' => 'files',
81                             'admin' => 'admin');
82     /**
83      * @var array tabs options
84      */
85     protected $tabs_options = array();
86     /**
87      * @var mod_wiki_renderer wiki renderer
88      */
89     protected $wikioutput;
90     /**
91      * @var stdClass course module.
92      */
93     protected $cm;
95     /**
96      * page_wiki constructor
97      *
98      * @param $wiki. Current wiki
99      * @param $subwiki. Current subwiki.
100      * @param $cm. Current course_module.
101      */
102     function __construct($wiki, $subwiki, $cm) {
103         global $PAGE, $CFG;
104         $this->subwiki = $subwiki;
105         $this->cm = $cm;
106         $this->modcontext = context_module::instance($this->cm->id);
108         // initialise wiki renderer
109         $this->wikioutput = $PAGE->get_renderer('mod_wiki');
110         $PAGE->set_cacheable(true);
111         $PAGE->set_cm($cm);
112         $PAGE->set_activity_record($wiki);
113         // the search box
114         if (!empty($subwiki->id)) {
115             $search = optional_param('searchstring', null, PARAM_TEXT);
116             $PAGE->set_button(wiki_search_form($cm, $search, $subwiki));
117         }
118     }
120     /**
121      * This method prints the top of the page.
122      */
123     function print_header() {
124         global $OUTPUT, $PAGE, $CFG, $USER, $SESSION;
126         $PAGE->set_heading($PAGE->course->fullname);
128         $this->set_url();
130         if (isset($SESSION->wikipreviousurl) && is_array($SESSION->wikipreviousurl)) {
131             $this->process_session_url();
132         }
133         $this->set_session_url();
135         $this->create_navbar();
136         $this->setup_tabs();
138         echo $OUTPUT->header();
139         $wiki = $PAGE->activityrecord;
140         echo $OUTPUT->heading(format_string($wiki->name));
142         echo $this->wikioutput->wiki_info();
144         // tabs are associated with pageid, so if page is empty, tabs should be disabled
145         if (!empty($this->page) && !empty($this->tabs)) {
146             echo $this->wikioutput->tabs($this->page, $this->tabs, $this->tabs_options);
147         }
148     }
150     /**
151      * Protected method to print current page title.
152      */
153     protected function print_pagetitle() {
154         global $OUTPUT;
155         $html = '';
157         $html .= $OUTPUT->container_start('wiki_headingtitle');
158         $html .= $OUTPUT->heading(format_string($this->title), 3);
159         $html .= $OUTPUT->container_end();
160         echo $html;
161     }
163     /**
164      * Setup page tabs, if options is empty, will set up active tab automatically
165      * @param array $options, tabs options
166      */
167     protected function setup_tabs($options = array()) {
168         global $CFG, $PAGE;
169         $groupmode = groups_get_activity_groupmode($this->cm);
171         if (empty($CFG->usecomments) || !has_capability('mod/wiki:viewcomment', $PAGE->context)){
172             unset($this->tabs['comments']);
173         }
175         if (!has_capability('mod/wiki:editpage', $PAGE->context)){
176             unset($this->tabs['edit']);
177         }
179         if ($groupmode and $groupmode == VISIBLEGROUPS) {
180             $currentgroup = groups_get_activity_group($this->cm);
181             $manage = has_capability('mod/wiki:managewiki', $this->modcontext);
182             $edit = has_capability('mod/wiki:editpage', $PAGE->context);
183             if (!$manage and !($edit and groups_is_member($currentgroup))) {
184                 unset($this->tabs['edit']);
185             }
186         }
188         if (empty($options)) {
189             $this->tabs_options = array('activetab' => substr(get_class($this), 10));
190         } else {
191             $this->tabs_options = $options;
192         }
194     }
196     /**
197      * This method must be overwritten to print the page content.
198      */
199     function print_content() {
200         throw new coding_exception('Page wiki class does not implement method print_content()');
201     }
203     /**
204      * Method to set the current page
205      *
206      * @param object $page Current page
207      */
208     function set_page($page) {
209         global $PAGE;
211         $this->page = $page;
212         $this->title = $page->title;
213         // set_title calls format_string itself so no probs there
214         $PAGE->set_title($this->title);
215     }
217     /**
218      * Method to set the current page title.
219      * This method must be called when the current page is not created yet.
220      * @param string $title Current page title.
221      */
222     function set_title($title) {
223         global $PAGE;
225         $this->page = null;
226         $this->title = $title;
227         // set_title calls format_string itself so no probs there
228         $PAGE->set_title($this->title);
229     }
231     /**
232      * Method to set current group id
233      * @param int $gid Current group id
234      */
235     function set_gid($gid) {
236         $this->gid = $gid;
237     }
239     /**
240      * Method to set current user id
241      * @param int $uid Current user id
242      */
243     function set_uid($uid) {
244         $this->uid = $uid;
245     }
247     /**
248      * Method to set the URL of the page.
249      * This method must be overwritten by every type of page.
250      */
251     protected function set_url() {
252         throw new coding_exception('Page wiki class does not implement method set_url()');
253     }
255     /**
256      * Protected method to create the common items of the navbar in every page type.
257      */
258     protected function create_navbar() {
259         global $PAGE, $CFG;
261         $PAGE->navbar->add(format_string($this->title), $CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $this->page->id);
262     }
264     /**
265      * This method print the footer of the page.
266      */
267     function print_footer() {
268         global $OUTPUT;
269         echo $OUTPUT->footer();
270     }
272     protected function process_session_url() {
273         global $USER, $SESSION;
275         //delete locks if edit
276         $url = $SESSION->wikipreviousurl;
277         switch ($url['page']) {
278         case 'edit':
279             wiki_delete_locks($url['params']['pageid'], $USER->id, $url['params']['section'], false);
280             break;
281         }
282     }
284     protected function set_session_url() {
285         global $SESSION;
286         unset($SESSION->wikipreviousurl);
287     }
291 /**
292  * View a wiki page
293  *
294  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
295  */
296 class page_wiki_view extends page_wiki {
298     function print_header() {
299         global $PAGE;
301         parent::print_header();
303         $this->wikioutput->wiki_print_subwiki_selector($PAGE->activityrecord, $this->subwiki, $this->page, 'view');
305         if (!empty($this->page)) {
306             echo $this->wikioutput->prettyview_link($this->page);
307         }
309         //echo $this->wikioutput->page_index();
311         $this->print_pagetitle();
312     }
314     function print_content() {
315         global $PAGE, $CFG;
317         if (wiki_user_can_view($this->subwiki)) {
319             if (!empty($this->page)) {
320                 wiki_print_page_content($this->page, $this->modcontext, $this->subwiki->id);
321                 $wiki = $PAGE->activityrecord;
322             } else {
323                 print_string('nocontent', 'wiki');
324                 // TODO: fix this part
325                 $swid = 0;
326                 if (!empty($this->subwiki)) {
327                     $swid = $this->subwiki->id;
328                 }
329             }
330         } else {
331             echo get_string('cannotviewpage', 'wiki');
332         }
333     }
335     function set_url() {
336         global $PAGE, $CFG;
337         $params = array();
339         if (isset($this->cm->id)) {
340             $params['id'] = $this->cm->id;
341         } else if (!empty($this->page) and $this->page != null) {
342             $params['pageid'] = $this->page->id;
343         } else if (!empty($this->gid)) {
344             $params['wid'] = $this->cm->instance;
345             $params['group'] = $this->gid;
346         } else if (!empty($this->title)) {
347             $params['swid'] = $this->subwiki->id;
348             $params['title'] = $this->title;
349         } else {
350             print_error(get_string('invalidparameters', 'wiki'));
351         }
352         $PAGE->set_url(new moodle_url($CFG->wwwroot . '/mod/wiki/view.php', $params));
353     }
355     protected function create_navbar() {
356         global $PAGE;
358         $PAGE->navbar->add(format_string($this->title));
359         $PAGE->navbar->add(get_string('view', 'wiki'));
360     }
363 /**
364  * Wiki page editing page
365  *
366  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
367  */
368 class page_wiki_edit extends page_wiki {
370     public static $attachmentoptions;
372     protected $sectioncontent;
373     /** @var string the section name needed to be edited */
374     protected $section;
375     protected $overridelock = false;
376     protected $versionnumber = -1;
377     protected $upload = false;
378     protected $attachments = 0;
379     protected $deleteuploads = array();
380     protected $format;
382     function __construct($wiki, $subwiki, $cm) {
383         global $CFG, $PAGE;
384         parent::__construct($wiki, $subwiki, $cm);
385         $showfilemanager = false;
386         if (has_capability('mod/wiki:managefiles', context_module::instance($cm->id))) {
387             $showfilemanager = true;
388         }
389         self::$attachmentoptions = array('subdirs' => false, 'maxfiles' => - 1, 'maxbytes' => $CFG->maxbytes,
390                 'accepted_types' => '*', 'enable_filemanagement' => $showfilemanager);
391         $PAGE->requires->js_init_call('M.mod_wiki.renew_lock', null, true);
392     }
394     protected function print_pagetitle() {
395         global $OUTPUT;
397         $title = $this->title;
398         if (isset($this->section)) {
399             $title .= ' : ' . $this->section;
400         }
401         echo $OUTPUT->container_start('wiki_clear wiki_headingtitle');
402         echo $OUTPUT->heading(format_string($title), 3);
403         echo $OUTPUT->container_end();
404     }
406     function print_header() {
407         global $OUTPUT, $PAGE;
408         $PAGE->requires->data_for_js('wiki', array('renew_lock_timeout' => LOCK_TIMEOUT - 5, 'pageid' => $this->page->id, 'section' => $this->section));
410         parent::print_header();
412         $this->print_pagetitle();
414         print '<noscript>' . $OUTPUT->box(get_string('javascriptdisabledlocks', 'wiki'), 'errorbox') . '</noscript>';
415     }
417     function print_content() {
418         global $PAGE;
420         if (wiki_user_can_edit($this->subwiki)) {
421             $this->print_edit();
422         } else {
423             echo get_string('cannoteditpage', 'wiki');
424         }
425     }
427     protected function set_url() {
428         global $PAGE, $CFG;
430         $params = array('pageid' => $this->page->id);
432         if (isset($this->section)) {
433             $params['section'] = $this->section;
434         }
436         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/edit.php', $params);
437     }
439     protected function set_session_url() {
440         global $SESSION;
442         $SESSION->wikipreviousurl = array('page' => 'edit', 'params' => array('pageid' => $this->page->id, 'section' => $this->section));
443     }
445     protected function process_session_url() {
446     }
448     function set_section($sectioncontent, $section) {
449         $this->sectioncontent = $sectioncontent;
450         $this->section = $section;
451     }
453     public function set_versionnumber($versionnumber) {
454         $this->versionnumber = $versionnumber;
455     }
457     public function set_overridelock($override) {
458         $this->overridelock = $override;
459     }
461     function set_format($format) {
462         $this->format = $format;
463     }
465     public function set_upload($upload) {
466         $this->upload = $upload;
467     }
469     public function set_attachments($attachments) {
470         $this->attachments = $attachments;
471     }
473     public function set_deleteuploads($deleteuploads) {
474         $this->deleteuploads = $deleteuploads;
475     }
477     protected function create_navbar() {
478         global $PAGE, $CFG;
480         parent::create_navbar();
482         $PAGE->navbar->add(get_string('edit', 'wiki'));
483     }
485     protected function check_locks() {
486         global $OUTPUT, $USER, $CFG;
488         if (!wiki_set_lock($this->page->id, $USER->id, $this->section, true)) {
489             print $OUTPUT->box(get_string('pageislocked', 'wiki'), 'generalbox boxwidthnormal boxaligncenter');
491             if ($this->overridelock) {
492                 $params = 'pageid=' . $this->page->id;
494                 if ($this->section) {
495                     $params .= '&section=' . urlencode($this->section);
496                 }
498                 $form = '<form method="post" action="' . $CFG->wwwroot . '/mod/wiki/overridelocks.php?' . $params . '">';
499                 $form .= '<input type="hidden" name="sesskey" value="' . sesskey() . '" />';
500                 $form .= '<input type="submit" value="' . get_string('overridelocks', 'wiki') . '" />';
501                 $form .= '</form>';
503                 print $OUTPUT->box($form, 'generalbox boxwidthnormal boxaligncenter');
504             }
505             return false;
506         }
507         return true;
508     }
510     protected function print_edit($content = null) {
511         global $CFG, $OUTPUT, $USER, $PAGE;
513         if (!$this->check_locks()) {
514             return;
515         }
517         //delete old locks (> 1 hour)
518         wiki_delete_old_locks();
520         $version = wiki_get_current_version($this->page->id);
521         $format = $version->contentformat;
523         if ($content == null) {
524             if (empty($this->section)) {
525                 $content = $version->content;
526             } else {
527                 $content = $this->sectioncontent;
528             }
529         }
531         $versionnumber = $version->version;
532         if ($this->versionnumber >= 0) {
533             if ($version->version != $this->versionnumber) {
534                 print $OUTPUT->box(get_string('wrongversionlock', 'wiki'), 'errorbox');
535                 $versionnumber = $this->versionnumber;
536             }
537         }
539         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
540         if (!empty($this->section)) {
541             $url .= "&section=" . urlencode($this->section);
542         }
544         $params = array(
545             'attachmentoptions' => page_wiki_edit::$attachmentoptions,
546             'format' => $version->contentformat,
547             'version' => $versionnumber,
548             'pagetitle' => $this->page->title,
549             'contextid' => $this->modcontext->id
550         );
552         $data = new StdClass();
553         $data->newcontent = $content;
554         $data->version = $versionnumber;
555         $data->format = $format;
557         switch ($format) {
558         case 'html':
559             $data->newcontentformat = FORMAT_HTML;
560             // Append editor context to editor options, giving preference to existing context.
561             page_wiki_edit::$attachmentoptions = array_merge(array('context' => $this->modcontext), page_wiki_edit::$attachmentoptions);
562             $data = file_prepare_standard_editor($data, 'newcontent', page_wiki_edit::$attachmentoptions, $this->modcontext, 'mod_wiki', 'attachments', $this->subwiki->id);
563             break;
564         default:
565             break;
566         }
568         if ($version->contentformat != 'html') {
569             $params['fileitemid'] = $this->subwiki->id;
570             $params['component']  = 'mod_wiki';
571             $params['filearea']   = 'attachments';
572         }
574         $data->tags = core_tag_tag::get_item_tags_array('mod_wiki', 'wiki_pages', $this->page->id);
576         $form = new mod_wiki_edit_form($url, $params);
577         $form->set_data($data);
578         $form->display();
579     }
583 /**
584  * Class that models the behavior of wiki's view comments page
585  *
586  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
587  */
588 class page_wiki_comments extends page_wiki {
590     function print_header() {
592         parent::print_header();
594         $this->print_pagetitle();
596     }
598     function print_content() {
599         global $CFG, $OUTPUT, $USER, $PAGE;
600         require_once($CFG->dirroot . '/mod/wiki/locallib.php');
602         $page = $this->page;
603         $subwiki = $this->subwiki;
604         $wiki = $PAGE->activityrecord;
605         list($context, $course, $cm) = get_context_info_array($this->modcontext->id);
607         require_capability('mod/wiki:viewcomment', $this->modcontext, NULL, true, 'noviewcommentpermission', 'wiki');
609         $comments = wiki_get_comments($this->modcontext->id, $page->id);
611         if (has_capability('mod/wiki:editcomment', $this->modcontext)) {
612             echo '<div class="midpad"><a href="' . $CFG->wwwroot . '/mod/wiki/editcomments.php?action=add&amp;pageid=' . $page->id . '">' . get_string('addcomment', 'wiki') . '</a></div>';
613         }
615         $options = array('swid' => $this->page->subwikiid, 'pageid' => $page->id);
616         $version = wiki_get_current_version($this->page->id);
617         $format = $version->contentformat;
619         if (empty($comments)) {
620             echo html_writer::tag('p', get_string('nocomments', 'wiki'), array('class' => 'bold'));
621         }
623         foreach ($comments as $comment) {
625             $user = wiki_get_user_info($comment->userid);
627             $fullname = fullname($user, has_capability('moodle/site:viewfullnames', context_course::instance($course->id)));
628             $by = new stdclass();
629             $by->name = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $user->id . '&amp;course=' . $course->id . '">' . $fullname . '</a>';
630             $by->date = userdate($comment->timecreated);
632             $t = new html_table();
633             $t->id = 'wiki-comments';
634             $cell1 = new html_table_cell($OUTPUT->user_picture($user, array('popup' => true)));
635             $cell2 = new html_table_cell(get_string('bynameondate', 'forum', $by));
636             $cell3 = new html_table_cell();
637             $cell3->atributtes ['width'] = "80%";
638             $cell4 = new html_table_cell();
639             $cell5 = new html_table_cell();
641             $row1 = new html_table_row();
642             $row1->cells[] = $cell1;
643             $row1->cells[] = $cell2;
644             $row2 = new html_table_row();
645             $row2->cells[] = $cell3;
647             if ($format != 'html') {
648                 if ($format == 'creole') {
649                     $parsedcontent = wiki_parse_content('creole', $comment->content, $options);
650                 } else if ($format == 'nwiki') {
651                     $parsedcontent = wiki_parse_content('nwiki', $comment->content, $options);
652                 }
654                 $cell4->text = format_text(html_entity_decode($parsedcontent['parsed_text'], ENT_QUOTES, 'UTF-8'), FORMAT_HTML);
655             } else {
656                 $cell4->text = format_text($comment->content, FORMAT_HTML);
657             }
659             $row2->cells[] = $cell4;
661             $t->data = array($row1, $row2);
663             $canedit = $candelete = false;
664             if ((has_capability('mod/wiki:editcomment', $this->modcontext)) and ($USER->id == $user->id)) {
665                 $candelete = $canedit = true;
666             }
667             if ((has_capability('mod/wiki:managecomment', $this->modcontext))) {
668                 $candelete = true;
669             }
671             $editicon = $deleteicon = '';
672             if ($canedit) {
673                 $urledit = new moodle_url('/mod/wiki/editcomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'edit'));
674                 $editicon = $OUTPUT->action_icon($urledit, new pix_icon('t/edit', get_string('edit'), '', array('class' => 'iconsmall')));
675             }
676             if ($candelete) {
677                 $urldelete = new moodle_url('/mod/wiki/instancecomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'delete'));
678                 $deleteicon = $OUTPUT->action_icon($urldelete,
679                                                   new pix_icon('t/delete',
680                                                                get_string('delete'),
681                                                                '',
682                                                                array('class' => 'iconsmall')));
683             }
685             if ($candelete || $canedit) {
686                 $cell6 = new html_table_cell($editicon.$deleteicon);
687                 $row3 = new html_table_row();
688                 $row3->cells[] = $cell5;
689                 $row3->cells[] = $cell6;
690                 $t->data[] = $row3;
691             }
693             echo html_writer::tag('div', html_writer::table($t), array('class'=>'no-overflow'));
695         }
696     }
698     function set_url() {
699         global $PAGE, $CFG;
700         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
701     }
703     protected function create_navbar() {
704         global $PAGE, $CFG;
706         parent::create_navbar();
707         $PAGE->navbar->add(get_string('comments', 'wiki'));
708     }
712 /**
713  * Class that models the behavior of wiki's edit comment
714  *
715  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
716  */
717 class page_wiki_editcomment extends page_wiki {
718     private $comment;
719     private $action;
720     private $form;
721     private $format;
723     function set_url() {
724         global $PAGE, $CFG;
725         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
726     }
728     function print_header() {
729         parent::print_header();
730         $this->print_pagetitle();
731     }
733     function print_content() {
734         global $PAGE;
736         require_capability('mod/wiki:editcomment', $this->modcontext, NULL, true, 'noeditcommentpermission', 'wiki');
738         if ($this->action == 'add') {
739             $this->add_comment_form();
740         } else if ($this->action == 'edit') {
741             $this->edit_comment_form($this->comment);
742         }
743     }
745     function set_action($action, $comment) {
746         global $CFG;
747         require_once($CFG->dirroot . '/mod/wiki/comments_form.php');
749         $this->action = $action;
750         $this->comment = $comment;
751         $version = wiki_get_current_version($this->page->id);
752         $this->format = $version->contentformat;
754         if ($this->format == 'html') {
755             $destination = $CFG->wwwroot . '/mod/wiki/instancecomments.php?pageid=' . $this->page->id;
756             $this->form = new mod_wiki_comments_form($destination);
757         }
758     }
760     protected function create_navbar() {
761         global $PAGE, $CFG;
763         $PAGE->navbar->add(get_string('comments', 'wiki'), $CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $this->page->id);
765         if ($this->action == 'add') {
766             $PAGE->navbar->add(get_string('insertcomment', 'wiki'));
767         } else {
768             $PAGE->navbar->add(get_string('editcomment', 'wiki'));
769         }
770     }
772     protected function setup_tabs($options = array()) {
773         parent::setup_tabs(array('linkedwhenactive' => 'comments', 'activetab' => 'comments'));
774     }
776     private function add_comment_form() {
777         global $CFG;
778         require_once($CFG->dirroot . '/mod/wiki/editors/wiki_editor.php');
780         $pageid = $this->page->id;
782         if ($this->format == 'html') {
783             $com = new stdClass();
784             $com->action = 'add';
785             $com->commentoptions = array('trusttext' => true, 'maxfiles' => 0);
786             $this->form->set_data($com);
787             $this->form->display();
788         } else {
789             wiki_print_editor_wiki($this->page->id, null, $this->format, -1, null, false, null, 'addcomments');
790         }
791     }
793     private function edit_comment_form($com) {
794         global $CFG;
795         require_once($CFG->dirroot . '/mod/wiki/comments_form.php');
796         require_once($CFG->dirroot . '/mod/wiki/editors/wiki_editor.php');
798         if ($this->format == 'html') {
799             $com->action = 'edit';
800             $com->entrycomment_editor['text'] = $com->content;
801             $com->commentoptions = array('trusttext' => true, 'maxfiles' => 0);
803             $this->form->set_data($com);
804             $this->form->display();
805         } else {
806             wiki_print_editor_wiki($this->page->id, $com->content, $this->format, -1, null, false, array(), 'editcomments', $com->id);
807         }
809     }
813 /**
814  * Wiki page search page
815  *
816  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
817  */
818 class page_wiki_search extends page_wiki {
819     private $search_result;
821     protected function create_navbar() {
822         global $PAGE, $CFG;
824         $PAGE->navbar->add(format_string($this->title));
825     }
827     function set_search_string($search, $searchcontent) {
828         $swid = $this->subwiki->id;
829         if ($searchcontent) {
830             $this->search_result = wiki_search_all($swid, $search);
831         } else {
832             $this->search_result = wiki_search_title($swid, $search);
833         }
835     }
837     function set_url() {
838         global $PAGE, $CFG;
839         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/search.php');
840     }
842     function print_header() {
843         global $PAGE;
845         parent::print_header();
847         $wiki = $PAGE->activityrecord;
848         $page = (object)array('title' => $wiki->firstpagetitle);
849         $this->wikioutput->wiki_print_subwiki_selector($wiki, $this->subwiki, $page, 'search');
850     }
852     function print_content() {
853         global $PAGE;
855         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
857         echo $this->wikioutput->search_result($this->search_result, $this->subwiki);
858     }
861 /**
862  *
863  * Class that models the behavior of wiki's
864  * create page
865  *
866  */
867 class page_wiki_create extends page_wiki {
869     private $format;
870     private $swid;
871     private $wid;
872     private $action;
873     private $mform;
874     private $groups;
876     function print_header() {
877         $this->set_url();
878         parent::print_header();
879     }
881     function set_url() {
882         global $PAGE, $CFG;
884         $params = array();
885         $params['swid'] = $this->swid;
886         if ($this->action == 'new') {
887             $params['action'] = 'new';
888             $params['wid'] = $this->wid;
889             if ($this->title != get_string('newpage', 'wiki')) {
890                 $params['title'] = $this->title;
891             }
892         } else {
893             $params['action'] = 'create';
894         }
895         $PAGE->set_url(new moodle_url('/mod/wiki/create.php', $params));
896     }
898     function set_format($format) {
899         $this->format = $format;
900     }
902     function set_wid($wid) {
903         $this->wid = $wid;
904     }
906     function set_swid($swid) {
907         $this->swid = $swid;
908     }
910     function set_availablegroups($group) {
911         $this->groups = $group;
912     }
914     function set_action($action) {
915         global $PAGE;
916         $this->action = $action;
918         require_once(__DIR__ . '/create_form.php');
919         $url = new moodle_url('/mod/wiki/create.php', array('action' => 'create', 'wid' => $PAGE->activityrecord->id, 'group' => $this->gid, 'uid' => $this->uid));
920         $formats = wiki_get_formats();
921         $options = array('formats' => $formats, 'defaultformat' => $PAGE->activityrecord->defaultformat, 'forceformat' => $PAGE->activityrecord->forceformat, 'groups' => $this->groups);
922         if ($this->title != get_string('newpage', 'wiki')) {
923             $options['disable_pagetitle'] = true;
924         }
925         $this->mform = new mod_wiki_create_form($url->out(false), $options);
926     }
928     protected function create_navbar() {
929         global $PAGE;
930         // navigation_node::get_content formats this before printing.
931         $PAGE->navbar->add($this->title);
932     }
934     function print_content($pagetitle = '') {
935         global $PAGE;
937         // @TODO: Change this to has_capability and show an alternative interface.
938         require_capability('mod/wiki:createpage', $this->modcontext, NULL, true, 'nocreatepermission', 'wiki');
939         $data = new stdClass();
940         if (!empty($pagetitle)) {
941             $data->pagetitle = $pagetitle;
942         }
943         $data->pageformat = $PAGE->activityrecord->defaultformat;
945         $this->mform->set_data($data);
946         $this->mform->display();
947     }
949     function create_page($pagetitle) {
950         global $USER, $PAGE;
952         $data = $this->mform->get_data();
953         if (isset($data->groupinfo)) {
954             $groupid = $data->groupinfo;
955         } else if (!empty($this->gid)) {
956             $groupid = $this->gid;
957         } else {
958             $groupid = '0';
959         }
960         if (empty($this->subwiki)) {
961             // If subwiki is not set then try find one and set else create one.
962             if (!$this->subwiki = wiki_get_subwiki_by_group($this->wid, $groupid, $this->uid)) {
963                 $swid = wiki_add_subwiki($PAGE->activityrecord->id, $groupid, $this->uid);
964                 $this->subwiki = wiki_get_subwiki($swid);
965             }
966         }
967         if ($data) {
968             $this->set_title($data->pagetitle);
969             $id = wiki_create_page($this->subwiki->id, $data->pagetitle, $data->pageformat, $USER->id);
970         } else {
971             $this->set_title($pagetitle);
972             $id = wiki_create_page($this->subwiki->id, $pagetitle, $PAGE->activityrecord->defaultformat, $USER->id);
973         }
974         $this->page = $id;
975         return $id;
976     }
979 class page_wiki_preview extends page_wiki_edit {
981     private $newcontent;
983     function print_header() {
984         global $PAGE, $CFG;
986         parent::print_header();
988     }
990     function print_content() {
991         global $PAGE;
993         require_capability('mod/wiki:editpage', $this->modcontext, NULL, true, 'noeditpermission', 'wiki');
995         $this->print_preview();
996     }
998     function set_newcontent($newcontent) {
999         $this->newcontent = $newcontent;
1000     }
1002     function set_url() {
1003         global $PAGE, $CFG;
1005         $params = array('pageid' => $this->page->id
1006         );
1008         if (isset($this->section)) {
1009             $params['section'] = $this->section;
1010         }
1012         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/edit.php', $params);
1013     }
1015     protected function setup_tabs($options = array()) {
1016         parent::setup_tabs(array('linkedwhenactive' => 'view', 'activetab' => 'view'));
1017     }
1019     protected function check_locks() {
1020         return true;
1021     }
1023     protected function print_preview() {
1024         global $CFG, $PAGE, $OUTPUT;
1026         $version = wiki_get_current_version($this->page->id);
1027         $format = $version->contentformat;
1028         $content = $version->content;
1030         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
1031         if (!empty($this->section)) {
1032             $url .= "&section=" . urlencode($this->section);
1033         }
1034         $params = array(
1035             'attachmentoptions' => page_wiki_edit::$attachmentoptions,
1036             'format' => $this->format,
1037             'version' => $this->versionnumber,
1038             'contextid' => $this->modcontext->id
1039         );
1041         if ($this->format != 'html') {
1042             $params['component'] = 'mod_wiki';
1043             $params['filearea'] = 'attachments';
1044             $params['fileitemid'] = $this->page->id;
1045         }
1046         $form = new mod_wiki_edit_form($url, $params);
1049         $options = array('swid' => $this->page->subwikiid, 'pageid' => $this->page->id, 'pretty_print' => true);
1051         if ($data = $form->get_data()) {
1052             if (isset($data->newcontent)) {
1053                 // wiki fromat
1054                 $text = $data->newcontent;
1055             } else {
1056                 // html format
1057                 $text = $data->newcontent_editor['text'];
1058             }
1059             $parseroutput = wiki_parse_content($data->contentformat, $text, $options);
1060             $this->set_newcontent($text);
1061             echo $OUTPUT->notification(get_string('previewwarning', 'wiki'), 'notifyproblem');
1062             $content = format_text($parseroutput['parsed_text'], FORMAT_HTML, array('overflowdiv'=>true, 'filter'=>false));
1063             echo $OUTPUT->box($content, 'generalbox wiki_previewbox');
1064             $content = $this->newcontent;
1065         }
1067         $this->print_edit($content);
1068     }
1072 /**
1073  *
1074  * Class that models the behavior of wiki's
1075  * view differences
1076  *
1077  */
1078 class page_wiki_diff extends page_wiki {
1080     private $compare;
1081     private $comparewith;
1083     function print_header() {
1084         global $OUTPUT;
1086         parent::print_header();
1088         $this->print_pagetitle();
1089         $vstring = new stdClass();
1090         $vstring->old = $this->compare;
1091         $vstring->new = $this->comparewith;
1092         echo html_writer::tag('div', get_string('comparewith', 'wiki', $vstring), array('class' => 'wiki_headingtitle'));
1093     }
1095     /**
1096      * Print the diff view
1097      */
1098     function print_content() {
1099         global $PAGE;
1101         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1103         $this->print_diff_content();
1104     }
1106     function set_url() {
1107         global $PAGE, $CFG;
1109         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/diff.php', array('pageid' => $this->page->id, 'comparewith' => $this->comparewith, 'compare' => $this->compare));
1110     }
1112     function set_comparison($compare, $comparewith) {
1113         $this->compare = $compare;
1114         $this->comparewith = $comparewith;
1115     }
1117     protected function create_navbar() {
1118         global $PAGE, $CFG;
1120         parent::create_navbar();
1121         $PAGE->navbar->add(get_string('history', 'wiki'), $CFG->wwwroot . '/mod/wiki/history.php?pageid=' . $this->page->id);
1122         $PAGE->navbar->add(get_string('diff', 'wiki'));
1123     }
1125     protected function setup_tabs($options = array()) {
1126         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history'));
1127     }
1129     /**
1130      * Given two versions of a page, prints a page displaying the differences between them.
1131      *
1132      * @global object $CFG
1133      * @global object $OUTPUT
1134      * @global object $PAGE
1135      */
1136     private function print_diff_content() {
1137         global $CFG, $OUTPUT, $PAGE;
1139         $pageid = $this->page->id;
1140         $total = wiki_count_wiki_page_versions($pageid) - 1;
1142         $oldversion = wiki_get_wiki_page_version($pageid, $this->compare);
1144         $newversion = wiki_get_wiki_page_version($pageid, $this->comparewith);
1146         if ($oldversion && $newversion) {
1148             $oldtext = format_text(file_rewrite_pluginfile_urls($oldversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id));
1149             $newtext = format_text(file_rewrite_pluginfile_urls($newversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id));
1150             list($diff1, $diff2) = ouwiki_diff_html($oldtext, $newtext);
1151             $oldversion->diff = $diff1;
1152             $oldversion->user = wiki_get_user_info($oldversion->userid);
1153             $newversion->diff = $diff2;
1154             $newversion->user = wiki_get_user_info($newversion->userid);
1156             echo $this->wikioutput->diff($pageid, $oldversion, $newversion, array('total' => $total));
1157         } else {
1158             print_error('versionerror', 'wiki');
1159         }
1160     }
1163 /**
1164  *
1165  * Class that models the behavior of wiki's history page
1166  *
1167  */
1168 class page_wiki_history extends page_wiki {
1169     /**
1170      * @var int $paging current page
1171      */
1172     private $paging;
1174     /**
1175      * @var int @rowsperpage Items per page
1176      */
1177     private $rowsperpage = 10;
1179     /**
1180      * @var int $allversion if $allversion != 0, all versions will be printed in a signle table
1181      */
1182     private $allversion;
1184     function __construct($wiki, $subwiki, $cm) {
1185         global $PAGE;
1186         parent::__construct($wiki, $subwiki, $cm);
1187         $PAGE->requires->js_init_call('M.mod_wiki.history', null, true);
1188     }
1190     function print_header() {
1191         parent::print_header();
1192         $this->print_pagetitle();
1193     }
1195     function print_pagetitle() {
1196         global $OUTPUT;
1197         $html = '';
1199         $html .= $OUTPUT->container_start('wiki_headingtitle');
1200         $html .= $OUTPUT->heading_with_help(format_string($this->title), 'history', 'wiki', '', '', 3);
1201         $html .= $OUTPUT->container_end();
1202         echo $html;
1203     }
1205     function print_content() {
1206         global $PAGE;
1208         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1210         $this->print_history_content();
1211     }
1213     function set_url() {
1214         global $PAGE, $CFG;
1215         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/history.php', array('pageid' => $this->page->id));
1216     }
1218     function set_paging($paging) {
1219         $this->paging = $paging;
1220     }
1222     function set_allversion($allversion) {
1223         $this->allversion = $allversion;
1224     }
1226     protected function create_navbar() {
1227         global $PAGE, $CFG;
1229         parent::create_navbar();
1230         $PAGE->navbar->add(get_string('history', 'wiki'));
1231     }
1233     /**
1234      * Prints the history for a given wiki page
1235      *
1236      * @global object $CFG
1237      * @global object $OUTPUT
1238      * @global object $PAGE
1239      */
1240     private function print_history_content() {
1241         global $CFG, $OUTPUT, $PAGE;
1243         $pageid = $this->page->id;
1244         $offset = $this->paging * $this->rowsperpage;
1245         // vcount is the latest version
1246         $vcount = wiki_count_wiki_page_versions($pageid) - 1;
1247         if ($this->allversion) {
1248             $versions = wiki_get_wiki_page_versions($pageid, 0, $vcount);
1249         } else {
1250             $versions = wiki_get_wiki_page_versions($pageid, $offset, $this->rowsperpage);
1251         }
1252         // We don't want version 0 to be displayed
1253         // version 0 is blank page
1254         if (end($versions)->version == 0) {
1255             array_pop($versions);
1256         }
1258         $contents = array();
1260         $version0page = wiki_get_wiki_page_version($this->page->id, 0);
1261         $creator = wiki_get_user_info($version0page->userid);
1262         $a = new StdClass;
1263         $a->date = userdate($this->page->timecreated, get_string('strftimedaydatetime', 'langconfig'));
1264         $a->username = fullname($creator);
1265         echo html_writer::tag ('div', get_string('createddate', 'wiki', $a), array('class' => 'wiki_headingtime'));
1266         if ($vcount > 0) {
1268             /// If there is only one version, we don't need radios nor forms
1269             if (count($versions) == 1) {
1271                 $row = array_shift($versions);
1273                 $username = wiki_get_user_info($row->userid);
1274                 $picture = $OUTPUT->user_picture($username);
1275                 $date = userdate($row->timecreated, get_string('strftimedate', 'langconfig'));
1276                 $time = userdate($row->timecreated, get_string('strftimetime', 'langconfig'));
1277                 $versionid = wiki_get_version($row->id);
1278                 $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
1279                 $userlink = new moodle_url('/user/view.php', array('id' => $username->id, 'course' => $this->cm->course));
1280                 $contents[] = array('', html_writer::link($versionlink->out(false), $row->version), $picture . html_writer::link($userlink->out(false), fullname($username)), $time, $OUTPUT->container($date, 'wiki_histdate'));
1282                 $table = new html_table();
1283                 $table->head = array('', get_string('version'), get_string('user'), get_string('modified'), '');
1284                 $table->data = $contents;
1286                 echo html_writer::table($table);
1288             } else {
1290                 $checked = $vcount - $offset;
1291                 $rowclass = array();
1293                 foreach ($versions as $version) {
1294                     $user = wiki_get_user_info($version->userid);
1295                     $picture = $OUTPUT->user_picture($user, array('popup' => true));
1296                     $date = userdate($version->timecreated, get_string('strftimedate'));
1297                     $rowclass[] = 'wiki_histnewdate';
1298                     $time = userdate($version->timecreated, get_string('strftimetime', 'langconfig'));
1299                     $versionid = wiki_get_version($version->id);
1300                     if ($versionid) {
1301                         $url = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
1302                         $viewlink = html_writer::link($url->out(false), $version->version);
1303                     } else {
1304                         $viewlink = $version->version;
1305                     }
1306                     $userlink = new moodle_url('/user/view.php', array('id' => $version->userid, 'course' => $this->cm->course));
1307                     $contents[] = array($this->choose_from_radio(array($version->version  => null), 'compare', 'M.mod_wiki.history()', $checked - 1, true) . $this->choose_from_radio(array($version->version  => null), 'comparewith', 'M.mod_wiki.history()', $checked, true), $viewlink, $picture . html_writer::link($userlink->out(false), fullname($user)), $time, $OUTPUT->container($date, 'wiki_histdate'));
1308                 }
1310                 $table = new html_table();
1312                 $icon = $OUTPUT->help_icon('diff', 'wiki');
1314                 $table->head = array(get_string('diff', 'wiki') . $icon, get_string('version'), get_string('user'), get_string('modified'), '');
1315                 $table->data = $contents;
1316                 $table->attributes['class'] = 'table generaltable';
1317                 $table->rowclasses = $rowclass;
1319                 // Print the form.
1320                 echo html_writer::start_tag('form', array('action'=>new moodle_url('/mod/wiki/diff.php'), 'method'=>'get', 'id'=>'diff'));
1321                 echo html_writer::tag('div', html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'pageid', 'value'=>$pageid)));
1322                 echo html_writer::table($table);
1323                 echo html_writer::start_tag('div');
1324                 echo html_writer::empty_tag('input', array('type'=>'submit', 'class'=>'wiki_form-button btn btn-secondary', 'value'=>get_string('comparesel', 'wiki')));
1325                 echo html_writer::end_tag('div');
1326                 echo html_writer::end_tag('form');
1327             }
1328         } else {
1329             print_string('nohistory', 'wiki');
1330         }
1331         if (!$this->allversion) {
1332             //$pagingbar = moodle_paging_bar::make($vcount, $this->paging, $this->rowsperpage, $CFG->wwwroot.'/mod/wiki/history.php?pageid='.$pageid.'&amp;');
1333             // $pagingbar->pagevar = $pagevar;
1334             echo $OUTPUT->paging_bar($vcount, $this->paging, $this->rowsperpage, $CFG->wwwroot . '/mod/wiki/history.php?pageid=' . $pageid . '&amp;');
1335             //print_paging_bar($vcount, $paging, $rowsperpage,$CFG->wwwroot.'/mod/wiki/history.php?pageid='.$pageid.'&amp;','paging');
1336             } else {
1337             $link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid));
1338             $OUTPUT->container(html_writer::link($link->out(false), get_string('viewperpage', 'wiki', $this->rowsperpage)));
1339         }
1340         if ($vcount > $this->rowsperpage && !$this->allversion) {
1341             $link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid, 'allversion' => 1));
1342             $OUTPUT->container(html_writer::link($link->out(false), get_string('viewallhistory', 'wiki')));
1343         }
1344     }
1346     /**
1347      * Given an array of values, creates a group of radio buttons to be part of a form
1348      *
1349      * @param array  $options  An array of value-label pairs for the radio group (values as keys).
1350      * @param string $name     Name of the radiogroup (unique in the form).
1351      * @param string $onclick  Function to be executed when the radios are clicked.
1352      * @param string $checked  The value that is already checked.
1353      * @param bool   $return   If true, return the HTML as a string, otherwise print it.
1354      *
1355      * @return mixed If $return is false, returns nothing, otherwise returns a string of HTML.
1356      */
1357     private function choose_from_radio($options, $name, $onclick = '', $checked = '', $return = false) {
1359         static $idcounter = 0;
1361         if (!$name) {
1362             $name = 'unnamed';
1363         }
1365         $output = '<span class="radiogroup ' . $name . "\">\n";
1367         if (!empty($options)) {
1368             $currentradio = 0;
1369             foreach ($options as $value => $label) {
1370                 $htmlid = 'auto-rb' . sprintf('%04d', ++$idcounter);
1371                 $output .= ' <span class="radioelement ' . $name . ' rb' . $currentradio . "\">";
1372                 $output .= '<input name="' . $name . '" id="' . $htmlid . '" type="radio" value="' . $value . '"';
1373                 if ($value == $checked) {
1374                     $output .= ' checked="checked"';
1375                 }
1376                 if ($onclick) {
1377                     $output .= ' onclick="' . $onclick . '"';
1378                 }
1379                 if ($label === '') {
1380                     $output .= ' /> <label for="' . $htmlid . '">' . $value . '</label></span>' . "\n";
1381                 } else {
1382                     $output .= ' /> <label for="' . $htmlid . '">' . $label . '</label></span>' . "\n";
1383                 }
1384                 $currentradio = ($currentradio + 1) % 2;
1385             }
1386         }
1388         $output .= '</span>' . "\n";
1390         if ($return) {
1391             return $output;
1392         } else {
1393             echo $output;
1394         }
1395     }
1398 /**
1399  * Class that models the behavior of wiki's map page
1400  *
1401  */
1402 class page_wiki_map extends page_wiki {
1404     /**
1405      * @var int wiki view option
1406      */
1407     private $view;
1409     function print_header() {
1410         parent::print_header();
1411         $this->print_pagetitle();
1412     }
1414     function print_content() {
1415         global $CFG, $PAGE;
1417         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1419         if ($this->view > 0) {
1420             //echo '<div><a href="' . $CFG->wwwroot . '/mod/wiki/map.php?pageid=' . $this->page->id . '">' . get_string('backtomapmenu', 'wiki') . '</a></div>';
1421         }
1423         switch ($this->view) {
1424         case 1:
1425             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1426             $this->print_contributions_content();
1427             break;
1428         case 2:
1429             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1430             $this->print_navigation_content();
1431             break;
1432         case 3:
1433             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1434             $this->print_orphaned_content();
1435             break;
1436         case 4:
1437             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1438             $this->print_index_content();
1439             break;
1440         case 6:
1441             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1442             $this->print_updated_content();
1443             break;
1444         case 5:
1445         default:
1446             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1447             $this->print_page_list_content();
1448         }
1449     }
1451     function set_view($option) {
1452         $this->view = $option;
1453     }
1455     function set_url() {
1456         global $PAGE, $CFG;
1457         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/map.php', array('pageid' => $this->page->id));
1458     }
1460     protected function create_navbar() {
1461         global $PAGE;
1463         parent::create_navbar();
1464         $PAGE->navbar->add(get_string('map', 'wiki'));
1465     }
1467     /**
1468      * Prints the contributions tab content
1469      *
1470      * @uses $OUTPUT, $USER
1471      *
1472      */
1473     private function print_contributions_content() {
1474         global $CFG, $OUTPUT, $USER;
1475         $page = $this->page;
1477         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1478             $fresh = wiki_refresh_cachedcontent($page);
1479             $page = $fresh['page'];
1480         }
1482         $swid = $this->subwiki->id;
1484         $table = new html_table();
1485         $table->head = array(get_string('contributions', 'wiki') . $OUTPUT->help_icon('contributions', 'wiki'));
1486         $table->attributes['class'] = 'generalbox table';
1487         $table->data = array();
1488         $table->rowclasses = array();
1490         $lastversions = array();
1491         $pages = array();
1492         $users = array();
1494         if ($contribs = wiki_get_contributions($swid, $USER->id)) {
1495             foreach ($contribs as $contrib) {
1496                 if (!array_key_exists($contrib->pageid, $pages)) {
1497                     $page = wiki_get_page($contrib->pageid);
1498                     $pages[$contrib->pageid] = $page;
1499                 } else {
1500                     continue;
1501                 }
1503                 if (!array_key_exists($page->id, $lastversions)) {
1504                     $version = wiki_get_last_version($page->id);
1505                     $lastversions[$page->id] = $version;
1506                 } else {
1507                     $version = $lastversions[$page->id];
1508                 }
1510                 if (!array_key_exists($version->userid, $users)) {
1511                     $user = wiki_get_user_info($version->userid);
1512                     $users[$version->userid] = $user;
1513                 } else {
1514                     $user = $users[$version->userid];
1515                 }
1517                 $link = wiki_parser_link($page->title, array('swid' => $swid));
1518                 $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1520                 $linkpage = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content'], true, array('context' => $this->modcontext)) . '</a>';
1521                 $icon = $OUTPUT->user_picture($user, array('popup' => true));
1523                 $table->data[] = array("$icon&nbsp;$linkpage");
1524             }
1525         } else {
1526             $table->data[] = array(get_string('nocontribs', 'wiki'));
1527         }
1528         echo html_writer::table($table);
1529     }
1531     /**
1532      * Prints the navigation tab content
1533      *
1534      * @uses $OUTPUT
1535      *
1536      */
1537     private function print_navigation_content() {
1538         global $OUTPUT;
1539         $page = $this->page;
1541         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1542             $fresh = wiki_refresh_cachedcontent($page);
1543             $page = $fresh['page'];
1544         }
1546         $tolinks = wiki_get_linked_to_pages($page->id);
1547         $fromlinks = wiki_get_linked_from_pages($page->id);
1549         $table = new html_table();
1550         $table->attributes['class'] = 'wiki_navigation_from table';
1551         $table->head = array(get_string('navigationfrom', 'wiki') . $OUTPUT->help_icon('navigationfrom', 'wiki') . ':');
1552         $table->data = array();
1553         $table->rowclasses = array();
1554         foreach ($fromlinks as $link) {
1555             $lpage = wiki_get_page($link->frompageid);
1556             $link = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
1557             $table->data[] = array(html_writer::link($link->out(false), format_string($lpage->title)));
1558         }
1560         $table_left = $OUTPUT->container(html_writer::table($table), 'col-md-6 span6');
1562         $table = new html_table();
1563         $table->attributes['class'] = 'wiki_navigation_to table';
1564         $table->head = array(get_string('navigationto', 'wiki') . $OUTPUT->help_icon('navigationto', 'wiki') . ':');
1565         $table->data = array();
1566         $table->rowclasses = array();
1567         foreach ($tolinks as $link) {
1568             if ($link->tomissingpage) {
1569                 $viewlink = new moodle_url('/mod/wiki/create.php', array('swid' => $page->subwikiid, 'title' => $link->tomissingpage, 'action' => 'new'));
1570                 $table->data[] = array(html_writer::link($viewlink->out(false), format_string($link->tomissingpage), array('class' => 'wiki_newentry')));
1571             } else {
1572                 $lpage = wiki_get_page($link->topageid);
1573                 $viewlink = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
1574                 $table->data[] = array(html_writer::link($viewlink->out(false), format_string($lpage->title)));
1575             }
1576         }
1577         $table_right = $OUTPUT->container(html_writer::table($table), 'col-md-6 span6');
1578         echo $OUTPUT->container($table_left . $table_right, 'wiki_navigation_container row');
1579     }
1581     /**
1582      * Prints the index page tab content
1583      *
1584      *
1585      */
1586     private function print_index_content() {
1587         global $OUTPUT;
1588         $page = $this->page;
1590         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1591             $fresh = wiki_refresh_cachedcontent($page);
1592             $page = $fresh['page'];
1593         }
1595         // navigation_node get_content calls format string for us
1596         $node = new navigation_node($page->title);
1598         $keys = array();
1599         $tree = array();
1600         $tree = wiki_build_tree($page, $node, $keys);
1602         $table = new html_table();
1603         $table->head = array(get_string('pageindex', 'wiki') . $OUTPUT->help_icon('pageindex', 'wiki'));
1604         $table->attributes['class'] = 'generalbox table';
1605         $table->data[] = array($this->render_navigation_node($tree));
1607         echo html_writer::table($table);
1608     }
1610     /**
1611      * Prints the page list tab content
1612      *
1613      *
1614      */
1615     private function print_page_list_content() {
1616         global $OUTPUT;
1617         $page = $this->page;
1619         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1620             $fresh = wiki_refresh_cachedcontent($page);
1621             $page = $fresh['page'];
1622         }
1624         $pages = wiki_get_page_list($this->subwiki->id);
1626         $stdaux = new stdClass();
1627         $strspecial = get_string('special', 'wiki');
1629         foreach ($pages as $page) {
1630             // We need to format the title here to account for any filtering
1631             $letter = format_string($page->title, true, array('context' => $this->modcontext));
1632             $letter = core_text::substr($letter, 0, 1);
1633             if (preg_match('/^[a-zA-Z]$/', $letter)) {
1634                 $letter = core_text::strtoupper($letter);
1635                 $stdaux->{$letter}[] = wiki_parser_link($page);
1636             } else {
1637                 $stdaux->{$strspecial}[] = wiki_parser_link($page);
1638             }
1639         }
1641         $table = new html_table();
1642         $table->head = array(get_string('pagelist', 'wiki') . $OUTPUT->help_icon('pagelist', 'wiki'));
1643         $table->attributes['class'] = 'generalbox table';
1644         foreach ($stdaux as $key => $elem) {
1645             $table->data[] = array($key);
1646             foreach ($elem as $e) {
1647                 $table->data[] = array(html_writer::link($e['url'], format_string($e['content'], true, array('context' => $this->modcontext))));
1648             }
1649         }
1650         echo html_writer::table($table);
1651     }
1653     /**
1654      * Prints the orphaned tab content
1655      *
1656      *
1657      */
1658     private function print_orphaned_content() {
1659         global $OUTPUT;
1661         $page = $this->page;
1663         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1664             $fresh = wiki_refresh_cachedcontent($page);
1665             $page = $fresh['page'];
1666         }
1668         $swid = $this->subwiki->id;
1670         $table = new html_table();
1671         $table->head = array(get_string('orphaned', 'wiki') . $OUTPUT->help_icon('orphaned', 'wiki'));
1672         $table->attributes['class'] = 'generalbox table';
1673         $table->data = array();
1674         $table->rowclasses = array();
1676         if ($orphanedpages = wiki_get_orphaned_pages($swid)) {
1677             foreach ($orphanedpages as $page) {
1678                 $link = wiki_parser_link($page->title, array('swid' => $swid));
1679                 $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1680                 $table->data[] = array('<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>');
1681             }
1682         } else {
1683             $table->data[] = array(get_string('noorphanedpages', 'wiki'));
1684         }
1686         echo html_writer::table($table);
1687     }
1689     /**
1690      * Prints the updated tab content
1691      *
1692      * @uses $COURSE, $OUTPUT
1693      *
1694      */
1695     private function print_updated_content() {
1696         global $COURSE, $OUTPUT;
1697         $page = $this->page;
1699         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1700             $fresh = wiki_refresh_cachedcontent($page);
1701             $page = $fresh['page'];
1702         }
1704         $swid = $this->subwiki->id;
1706         $table = new html_table();
1707         $table->head = array(get_string('updatedpages', 'wiki') . $OUTPUT->help_icon('updatedpages', 'wiki'));
1708         $table->attributes['class'] = 'generalbox table';
1709         $table->data = array();
1710         $table->rowclasses = array();
1712         if ($pages = wiki_get_updated_pages_by_subwiki($swid)) {
1713             $strdataux = '';
1714             foreach ($pages as $page) {
1715                 $user = wiki_get_user_info($page->userid);
1716                 $strdata = strftime('%d %b %Y', $page->timemodified);
1717                 if ($strdata != $strdataux) {
1718                     $table->data[] = array($OUTPUT->heading($strdata, 4));
1719                     $strdataux = $strdata;
1720                 }
1721                 $link = wiki_parser_link($page->title, array('swid' => $swid));
1722                 $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1724                 $linkpage = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>';
1725                 $icon = $OUTPUT->user_picture($user, array($COURSE->id));
1726                 $table->data[] = array("$icon&nbsp;$linkpage");
1727             }
1728         } else {
1729             $table->data[] = array(get_string('noupdatedpages', 'wiki'));
1730         }
1732         echo html_writer::table($table);
1733     }
1735     protected function render_navigation_node($items, $attrs = array(), $expansionlimit = null, $depth = 1) {
1737         // exit if empty, we don't want an empty ul element
1738         if (count($items) == 0) {
1739             return '';
1740         }
1742         // array of nested li elements
1743         $lis = array();
1744         foreach ($items as $item) {
1745             if (!$item->display) {
1746                 continue;
1747             }
1748             $content = $item->get_content();
1749             $title = $item->get_title();
1750             if ($item->icon instanceof renderable) {
1751                 $icon = $this->wikioutput->render($item->icon);
1752                 $content = $icon . '&nbsp;' . $content; // use CSS for spacing of icons
1753                 }
1754             if ($item->helpbutton !== null) {
1755                 $content = trim($item->helpbutton) . html_writer::tag('span', $content, array('class' => 'clearhelpbutton'));
1756             }
1758             if ($content === '') {
1759                 continue;
1760             }
1762             if ($item->action instanceof action_link) {
1763                 //TODO: to be replaced with something else
1764                 $link = $item->action;
1765                 if ($item->hidden) {
1766                     $link->add_class('dimmed');
1767                 }
1768                 $content = $this->output->render($link);
1769             } else if ($item->action instanceof moodle_url) {
1770                 $attributes = array();
1771                 if ($title !== '') {
1772                     $attributes['title'] = $title;
1773                 }
1774                 if ($item->hidden) {
1775                     $attributes['class'] = 'dimmed_text';
1776                 }
1777                 $content = html_writer::link($item->action, $content, $attributes);
1779             } else if (is_string($item->action) || empty($item->action)) {
1780                 $attributes = array();
1781                 if ($title !== '') {
1782                     $attributes['title'] = $title;
1783                 }
1784                 if ($item->hidden) {
1785                     $attributes['class'] = 'dimmed_text';
1786                 }
1787                 $content = html_writer::tag('span', $content, $attributes);
1788             }
1790             // this applies to the li item which contains all child lists too
1791             $liclasses = array($item->get_css_type(), 'depth_' . $depth);
1792             if ($item->has_children() && (!$item->forceopen || $item->collapse)) {
1793                 $liclasses[] = 'collapsed';
1794             }
1795             if ($item->isactive === true) {
1796                 $liclasses[] = 'current_branch';
1797             }
1798             $liattr = array('class' => join(' ', $liclasses));
1799             // class attribute on the div item which only contains the item content
1800             $divclasses = array('tree_item');
1801             if ((empty($expansionlimit) || $item->type != $expansionlimit) && ($item->children->count() > 0 || ($item->nodetype == navigation_node::NODETYPE_BRANCH && $item->children->count() == 0 && isloggedin()))) {
1802                 $divclasses[] = 'branch';
1803             } else {
1804                 $divclasses[] = 'leaf';
1805             }
1806             if (!empty($item->classes) && count($item->classes) > 0) {
1807                 $divclasses[] = join(' ', $item->classes);
1808             }
1809             $divattr = array('class' => join(' ', $divclasses));
1810             if (!empty($item->id)) {
1811                 $divattr['id'] = $item->id;
1812             }
1813             $content = html_writer::tag('p', $content, $divattr) . $this->render_navigation_node($item->children, array(), $expansionlimit, $depth + 1);
1814             if (!empty($item->preceedwithhr) && $item->preceedwithhr === true) {
1815                 $content = html_writer::empty_tag('hr') . $content;
1816             }
1817             $content = html_writer::tag('li', $content, $liattr);
1818             $lis[] = $content;
1819         }
1821         if (count($lis)) {
1822             return html_writer::tag('ul', implode("\n", $lis), $attrs);
1823         } else {
1824             return '';
1825         }
1826     }
1830 /**
1831  * Class that models the behavior of wiki's restore version page
1832  *
1833  */
1834 class page_wiki_restoreversion extends page_wiki {
1835     private $version;
1837     function print_header() {
1838         parent::print_header();
1839         $this->print_pagetitle();
1840     }
1842     function print_content() {
1843         global $PAGE;
1845         $wiki = $PAGE->activityrecord;
1846         if (wiki_user_can_edit($this->subwiki, $wiki)) {
1847             $this->print_restoreversion();
1848         } else {
1849             echo get_string('cannoteditpage', 'wiki');
1850         }
1852     }
1854     function set_url() {
1855         global $PAGE, $CFG;
1856         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
1857     }
1859     function set_versionid($versionid) {
1860         $this->version = wiki_get_version($versionid);
1861     }
1863     protected function create_navbar() {
1864         global $PAGE, $CFG;
1866         parent::create_navbar();
1867         $PAGE->navbar->add(get_string('restoreversion', 'wiki'));
1868     }
1870     protected function setup_tabs($options = array()) {
1871         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history'));
1872     }
1874     /**
1875      * Prints the restore version content
1876      *
1877      * @uses $CFG
1878      *
1879      * @param page $page The page whose version will be restored
1880      * @param int  $versionid The version to be restored
1881      * @param bool $confirm If false, shows a yes/no confirmation page.
1882      *     If true, restores the old version and redirects the user to the 'view' tab.
1883      */
1884     private function print_restoreversion() {
1885         global $OUTPUT;
1887         $version = wiki_get_version($this->version->id);
1889         $optionsyes = array('confirm'=>1, 'pageid'=>$this->page->id, 'versionid'=>$version->id, 'sesskey'=>sesskey());
1890         $restoreurl = new moodle_url('/mod/wiki/restoreversion.php', $optionsyes);
1891         $return = new moodle_url('/mod/wiki/viewversion.php', array('pageid'=>$this->page->id, 'versionid'=>$version->id));
1893         echo $OUTPUT->container_start();
1894         echo html_writer::tag('div', get_string('restoreconfirm', 'wiki', $version->version));
1895         echo $OUTPUT->container_start(false, 'wiki_restoreform');
1896         echo '<form class="wiki_restore_yes" action="' . $restoreurl . '" method="post" id="restoreversion">';
1897         echo '<div><input type="submit" name="confirm" value="' . get_string('yes') . '" /></div>';
1898         echo '</form>';
1899         echo '<form class="wiki_restore_no" action="' . $return . '" method="post">';
1900         echo '<div><input type="submit" name="norestore" value="' . get_string('no') . '" /></div>';
1901         echo '</form>';
1902         echo $OUTPUT->container_end();
1903         echo $OUTPUT->container_end();
1904     }
1906 /**
1907  * Class that models the behavior of wiki's delete comment confirmation page
1908  *
1909  */
1910 class page_wiki_deletecomment extends page_wiki {
1911     private $commentid;
1913     function print_header() {
1914         parent::print_header();
1915         $this->print_pagetitle();
1916     }
1918     function print_content() {
1919         $this->printconfirmdelete();
1920     }
1922     function set_url() {
1923         global $PAGE;
1924         $PAGE->set_url('/mod/wiki/instancecomments.php', array('pageid' => $this->page->id, 'commentid' => $this->commentid));
1925     }
1927     public function set_action($action, $commentid, $content) {
1928         $this->action = $action;
1929         $this->commentid = $commentid;
1930         $this->content = $content;
1931     }
1933     protected function create_navbar() {
1934         global $PAGE;
1936         parent::create_navbar();
1937         $PAGE->navbar->add(get_string('deletecommentcheck', 'wiki'));
1938     }
1940     protected function setup_tabs($options = array()) {
1941         parent::setup_tabs(array('linkedwhenactive' => 'comments', 'activetab' => 'comments'));
1942     }
1944     /**
1945      * Prints the comment deletion confirmation form
1946      *
1947      * @param page $page The page whose version will be restored
1948      * @param int  $versionid The version to be restored
1949      * @param bool $confirm If false, shows a yes/no confirmation page.
1950      *     If true, restores the old version and redirects the user to the 'view' tab.
1951      */
1952     private function printconfirmdelete() {
1953         global $OUTPUT;
1955         $strdeletecheck = get_string('deletecommentcheck', 'wiki');
1956         $strdeletecheckfull = get_string('deletecommentcheckfull', 'wiki');
1958         //ask confirmation
1959         $optionsyes = array('confirm'=>1, 'pageid'=>$this->page->id, 'action'=>'delete', 'commentid'=>$this->commentid, 'sesskey'=>sesskey());
1960         $deleteurl = new moodle_url('/mod/wiki/instancecomments.php', $optionsyes);
1961         $return = new moodle_url('/mod/wiki/comments.php', array('pageid'=>$this->page->id));
1963         echo $OUTPUT->container_start();
1964         echo html_writer::tag('p', $strdeletecheckfull);
1965         echo $OUTPUT->container_start(false, 'wiki_deletecommentform');
1966         echo '<form class="wiki_deletecomment_yes" action="' . $deleteurl . '" method="post" id="deletecomment">';
1967         echo '<div><input type="submit" name="confirmdeletecomment" value="' . get_string('yes') . '" /></div>';
1968         echo '</form>';
1969         echo '<form class="wiki_deletecomment_no" action="' . $return . '" method="post">';
1970         echo '<div><input type="submit" name="norestore" value="' . get_string('no') . '" /></div>';
1971         echo '</form>';
1972         echo $OUTPUT->container_end();
1973         echo $OUTPUT->container_end();
1974     }
1977 /**
1978  * Class that models the behavior of wiki's
1979  * save page
1980  *
1981  */
1982 class page_wiki_save extends page_wiki_edit {
1984     private $newcontent;
1986     function print_header() {
1987     }
1989     function print_content() {
1990         global $PAGE;
1992         $context = context_module::instance($this->cm->id);
1993         require_capability('mod/wiki:editpage', $context, NULL, true, 'noeditpermission', 'wiki');
1995         $this->print_save();
1996     }
1998     function set_newcontent($newcontent) {
1999         $this->newcontent = $newcontent;
2000     }
2002     protected function set_session_url() {
2003     }
2005     protected function print_save() {
2006         global $CFG, $USER, $OUTPUT, $PAGE;
2008         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
2009         if (!empty($this->section)) {
2010             $url .= "&section=" . urlencode($this->section);
2011         }
2013         $params = array(
2014             'attachmentoptions' => page_wiki_edit::$attachmentoptions,
2015             'format' => $this->format,
2016             'version' => $this->versionnumber,
2017             'contextid' => $this->modcontext->id
2018         );
2020         if ($this->format != 'html') {
2021             $params['fileitemid'] = $this->page->id;
2022             $params['component']  = 'mod_wiki';
2023             $params['filearea']   = 'attachments';
2024         }
2026         $form = new mod_wiki_edit_form($url, $params);
2028         $save = false;
2029         $data = false;
2030         if ($data = $form->get_data()) {
2031             if ($this->format == 'html') {
2032                 $data = file_postupdate_standard_editor($data, 'newcontent', page_wiki_edit::$attachmentoptions, $this->modcontext, 'mod_wiki', 'attachments', $this->subwiki->id);
2033             }
2035             if (isset($this->section)) {
2036                 $save = wiki_save_section($this->page, $this->section, $data->newcontent, $USER->id);
2037             } else {
2038                 $save = wiki_save_page($this->page, $data->newcontent, $USER->id);
2039             }
2040         }
2042         if ($save && $data) {
2043             core_tag_tag::set_item_tags('mod_wiki', 'wiki_pages', $this->page->id, $this->modcontext, $data->tags);
2045             $message = '<p>' . get_string('saving', 'wiki') . '</p>';
2047             if (!empty($save['sections'])) {
2048                 foreach ($save['sections'] as $s) {
2049                     $message .= '<p>' . get_string('repeatedsection', 'wiki', $s) . '</p>';
2050                 }
2051             }
2053             if ($this->versionnumber + 1 != $save['version']) {
2054                 $message .= '<p>' . get_string('wrongversionsave', 'wiki') . '</p>';
2055             }
2057             if (isset($errors) && !empty($errors)) {
2058                 foreach ($errors as $e) {
2059                     $message .= "<p>" . get_string('filenotuploadederror', 'wiki', $e->get_filename()) . "</p>";
2060                 }
2061             }
2063             //deleting old locks
2064             wiki_delete_locks($this->page->id, $USER->id, $this->section);
2065             $url = new moodle_url('/mod/wiki/view.php', array('pageid' => $this->page->id, 'group' => $this->subwiki->groupid));
2066             redirect($url);
2067         } else {
2068             print_error('savingerror', 'wiki');
2069         }
2070     }
2073 /**
2074  * Class that models the behavior of wiki's view an old version of a page
2075  *
2076  */
2077 class page_wiki_viewversion extends page_wiki {
2079     private $version;
2081     function print_header() {
2082         parent::print_header();
2083         $this->print_pagetitle();
2084     }
2086     function print_content() {
2087         global $PAGE;
2089         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2091         $this->print_version_view();
2092     }
2094     function set_url() {
2095         global $PAGE, $CFG;
2096         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2097     }
2099     function set_versionid($versionid) {
2100         $this->version = wiki_get_version($versionid);
2101     }
2103     protected function create_navbar() {
2104         global $PAGE, $CFG;
2106         parent::create_navbar();
2107         $PAGE->navbar->add(get_string('history', 'wiki'), $CFG->wwwroot . '/mod/wiki/history.php?pageid=' . $this->page->id);
2108         $PAGE->navbar->add(get_string('versionnum', 'wiki', $this->version->version));
2109     }
2111     protected function setup_tabs($options = array()) {
2112         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history', 'inactivetabs' => array('edit')));
2113     }
2115     /**
2116      * Given an old page version, output the version content
2117      *
2118      * @global object $CFG
2119      * @global object $OUTPUT
2120      * @global object $PAGE
2121      */
2122     private function print_version_view() {
2123         global $CFG, $OUTPUT, $PAGE;
2124         $pageversion = wiki_get_version($this->version->id);
2126         if ($pageversion) {
2127             $restorelink = new moodle_url('/mod/wiki/restoreversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2128             echo html_writer::tag('div', get_string('viewversion', 'wiki', $pageversion->version) . '<br />' .
2129                 html_writer::link($restorelink->out(false), '(' . get_string('restorethis', 'wiki') .
2130                 ')', array('class' => 'wiki_restore')) . '&nbsp;', array('class' => 'wiki_headingtitle'));
2131             $userinfo = wiki_get_user_info($pageversion->userid);
2132             $heading = '<p><strong>' . get_string('modified', 'wiki') . ':</strong>&nbsp;' . userdate($pageversion->timecreated, get_string('strftimedatetime', 'langconfig'));
2133             $viewlink = new moodle_url('/user/view.php', array('id' => $userinfo->id));
2134             $heading .= '&nbsp;&nbsp;&nbsp;<strong>' . get_string('user') . ':</strong>&nbsp;' . html_writer::link($viewlink->out(false), fullname($userinfo));
2135             $heading .= '&nbsp;&nbsp;&rarr;&nbsp;' . $OUTPUT->user_picture(wiki_get_user_info($pageversion->userid), array('popup' => true)) . '</p>';
2136             echo $OUTPUT->container($heading, 'wiki_headingtime', 'wiki_modifieduser');
2137             $options = array('swid' => $this->subwiki->id, 'pretty_print' => true, 'pageid' => $this->page->id);
2139             $pageversion->content = file_rewrite_pluginfile_urls($pageversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id);
2141             $parseroutput = wiki_parse_content($pageversion->contentformat, $pageversion->content, $options);
2142             $content = $OUTPUT->container(format_text($parseroutput['parsed_text'], FORMAT_HTML, array('overflowdiv'=>true)), false, '', '', true);
2143             echo $OUTPUT->box($content, 'generalbox wiki_contentbox');
2145         } else {
2146             print_error('versionerror', 'wiki');
2147         }
2148     }
2151 class page_wiki_confirmrestore extends page_wiki_save {
2153     private $version;
2155     function set_url() {
2156         global $PAGE, $CFG;
2157         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2158     }
2160     function print_header() {
2161         $this->set_url();
2162     }
2164     function print_content() {
2165         global $CFG, $PAGE;
2167         $version = wiki_get_version($this->version->id);
2168         $wiki = $PAGE->activityrecord;
2169         if (wiki_user_can_edit($this->subwiki, $wiki) &&
2170                 wiki_restore_page($this->page, $version, $this->modcontext)) {
2171             redirect($CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $this->page->id, get_string('restoring', 'wiki', $version->version), 3);
2172         } else {
2173             print_error('restoreerror', 'wiki', $version->version);
2174         }
2175     }
2177     function set_versionid($versionid) {
2178         $this->version = wiki_get_version($versionid);
2179     }
2182 class page_wiki_prettyview extends page_wiki {
2184     function __construct($wiki, $subwiki, $cm) {
2185         global $PAGE;
2186         $PAGE->set_pagelayout('embedded');
2187         parent::__construct($wiki, $subwiki, $cm);
2188     }
2190     function print_header() {
2191         global $OUTPUT;
2192         $this->set_url();
2194         echo $OUTPUT->header();
2195         // Print dialog link.
2196         $printtext = get_string('print', 'wiki');
2197         $printlinkatt = array('onclick' => 'window.print();return false;', 'class' => 'printicon');
2198         $printiconlink = html_writer::link('#', $printtext, $printlinkatt);
2199         echo html_writer::tag('div', $printiconlink, array('class' => 'displayprinticon'));
2200         echo html_writer::tag('h1', format_string($this->title), array('id' => 'wiki_printable_title'));
2201     }
2203     function print_content() {
2204         global $PAGE;
2206         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2208         $this->print_pretty_view();
2209     }
2211     function set_url() {
2212         global $PAGE, $CFG;
2214         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/prettyview.php', array('pageid' => $this->page->id));
2215     }
2217     private function print_pretty_view() {
2218         $version = wiki_get_current_version($this->page->id);
2220         $content = wiki_parse_content($version->contentformat, $version->content, array('printable' => true, 'swid' => $this->subwiki->id, 'pageid' => $this->page->id, 'pretty_print' => true));
2222         $html = $content['parsed_text'];
2223         $id = $this->subwiki->wikiid;
2224         if ($cm = get_coursemodule_from_instance("wiki", $id)) {
2225             $context = context_module::instance($cm->id);
2226             $html = file_rewrite_pluginfile_urls($html, 'pluginfile.php', $context->id, 'mod_wiki', 'attachments', $this->subwiki->id);
2227         }
2228         echo '<div id="wiki_printable_content">';
2229         echo format_text($html, FORMAT_HTML);
2230         echo '</div>';
2231     }
2234 class page_wiki_handlecomments extends page_wiki {
2235     private $action;
2236     private $content;
2237     private $commentid;
2238     private $format;
2240     function print_header() {
2241         $this->set_url();
2242     }
2244     public function print_content() {
2245         global $CFG, $PAGE, $USER;
2247         if ($this->action == 'add') {
2248             require_capability('mod/wiki:editcomment', $this->modcontext);
2249             $this->add_comment($this->content, $this->commentid);
2250         } else if ($this->action == 'edit') {
2251             require_capability('mod/wiki:editcomment', $this->modcontext);
2253             $comment = wiki_get_comment($this->commentid);
2254             $owner = ($comment->userid == $USER->id);
2256             if ($owner) {
2257                 $this->add_comment($this->content, $this->commentid);
2258             }
2259         } else if ($this->action == 'delete') {
2260             $comment = wiki_get_comment($this->commentid);
2262             $manage = has_capability('mod/wiki:managecomment', $this->modcontext);
2263             $edit = has_capability('mod/wiki:editcomment', $this->modcontext);
2264             $owner = ($comment->userid == $USER->id);
2266             if ($manage || ($owner && $edit)) {
2267                 $this->delete_comment($this->commentid);
2268                 redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $this->page->id, get_string('deletecomment', 'wiki'), 2);
2269             } else {
2270                 print_error('nopermissiontoeditcomment');
2271             }
2272         }
2274     }
2276     public function set_url() {
2277         global $PAGE, $CFG;
2278         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
2279     }
2281     public function set_action($action, $commentid, $content) {
2282         $this->action = $action;
2283         $this->commentid = $commentid;
2284         $this->content = $content;
2286         $version = wiki_get_current_version($this->page->id);
2287         $format = $version->contentformat;
2289         $this->format = $format;
2290     }
2292     private function add_comment($content, $idcomment) {
2293         global $CFG, $PAGE;
2294         require_once($CFG->dirroot . "/mod/wiki/locallib.php");
2296         $pageid = $this->page->id;
2298         wiki_add_comment($this->modcontext, $pageid, $content, $this->format);
2300         if (!$idcomment) {
2301             redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $pageid, get_string('createcomment', 'wiki'), 2);
2302         } else {
2303             $this->delete_comment($idcomment);
2304             redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $pageid, get_string('editingcomment', 'wiki'), 2);
2305         }
2306     }
2308     private function delete_comment($commentid) {
2309         global $CFG, $PAGE;
2311         $pageid = $this->page->id;
2313         wiki_delete_comment($commentid, $this->modcontext, $pageid);
2314     }
2318 class page_wiki_lock extends page_wiki_edit {
2320     public function print_header() {
2321         $this->set_url();
2322     }
2324     protected function set_url() {
2325         global $PAGE, $CFG;
2327         $params = array('pageid' => $this->page->id);
2329         if ($this->section) {
2330             $params['section'] = $this->section;
2331         }
2333         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/lock.php', $params);
2334     }
2336     protected function set_session_url() {
2337     }
2339     public function print_content() {
2340         global $USER, $PAGE;
2342         require_capability('mod/wiki:editpage', $this->modcontext, NULL, true, 'noeditpermission', 'wiki');
2344         wiki_set_lock($this->page->id, $USER->id, $this->section);
2345     }
2347     public function print_footer() {
2348     }
2351 class page_wiki_overridelocks extends page_wiki_edit {
2352     function print_header() {
2353         $this->set_url();
2354     }
2356     function print_content() {
2357         global $CFG, $PAGE;
2359         require_capability('mod/wiki:overridelock', $this->modcontext, NULL, true, 'nooverridelockpermission', 'wiki');
2361         wiki_delete_locks($this->page->id, null, $this->section, true, true);
2363         $args = "pageid=" . $this->page->id;
2365         if (!empty($this->section)) {
2366             $args .= "&section=" . urlencode($this->section);
2367         }
2369         redirect($CFG->wwwroot . '/mod/wiki/edit.php?' . $args, get_string('overridinglocks', 'wiki'), 2);
2370     }
2372     function set_url() {
2373         global $PAGE, $CFG;
2375         $params = array('pageid' => $this->page->id);
2377         if (!empty($this->section)) {
2378             $params['section'] = $this->section;
2379         }
2381         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/overridelocks.php', $params);
2382     }
2384     protected function set_session_url() {
2385     }
2387     private function print_overridelocks() {
2388         global $CFG;
2390         wiki_delete_locks($this->page->id, null, $this->section, true, true);
2392         $args = "pageid=" . $this->page->id;
2394         if (!empty($this->section)) {
2395             $args .= "&section=" . urlencode($this->section);
2396         }
2398         redirect($CFG->wwwroot . '/mod/wiki/edit.php?' . $args, get_string('overridinglocks', 'wiki'), 2);
2399     }
2403 /**
2404  * This class will let user to delete wiki pages and page versions
2405  *
2406  */
2407 class page_wiki_admin extends page_wiki {
2409     public $view, $action;
2410     public $listorphan = false;
2412     /**
2413      * Constructor
2414      *
2415      * @global object $PAGE
2416      * @param mixed $wiki instance of wiki
2417      * @param mixed $subwiki instance of subwiki
2418      * @param stdClass $cm course module
2419      */
2420     function __construct($wiki, $subwiki, $cm) {
2421         global $PAGE;
2422         parent::__construct($wiki, $subwiki, $cm);
2423         $PAGE->requires->js_init_call('M.mod_wiki.deleteversion', null, true);
2424     }
2426     /**
2427      * Prints header for wiki page
2428      */
2429     function print_header() {
2430         parent::print_header();
2431         $this->print_pagetitle();
2432     }
2434     /**
2435      * This function will display administration view to users with managewiki capability
2436      */
2437     function print_content() {
2438         //make sure anyone trying to access this page has managewiki capabilities
2439         require_capability('mod/wiki:managewiki', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2441         //update wiki cache if timedout
2442         $page = $this->page;
2443         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
2444             $fresh = wiki_refresh_cachedcontent($page);
2445             $page = $fresh['page'];
2446         }
2448         //dispaly admin menu
2449         echo $this->wikioutput->menu_admin($this->page->id, $this->view);
2451         //Display appropriate admin view
2452         switch ($this->view) {
2453             case 1: //delete page view
2454                 $this->print_delete_content($this->listorphan);
2455                 break;
2456             case 2: //delete version view
2457                 $this->print_delete_version();
2458                 break;
2459             default: //default is delete view
2460                 $this->print_delete_content($this->listorphan);
2461                 break;
2462         }
2463     }
2465     /**
2466      * Sets admin view option
2467      *
2468      * @param int $view page view id
2469      * @param bool $listorphan is only valid for view 1.
2470      */
2471     public function set_view($view, $listorphan = true) {
2472         $this->view = $view;
2473         $this->listorphan = $listorphan;
2474     }
2476     /**
2477      * Sets page url
2478      *
2479      * @global object $PAGE
2480      * @global object $CFG
2481      */
2482     function set_url() {
2483         global $PAGE, $CFG;
2484         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/admin.php', array('pageid' => $this->page->id));
2485     }
2487     /**
2488      * sets navigation bar for the page
2489      *
2490      * @global object $PAGE
2491      */
2492     protected function create_navbar() {
2493         global $PAGE;
2495         parent::create_navbar();
2496         $PAGE->navbar->add(get_string('admin', 'wiki'));
2497     }
2499     /**
2500      * Show wiki page delete options
2501      *
2502      * @param bool $showorphan
2503      */
2504     protected function print_delete_content($showorphan = true) {
2505         $contents = array();
2506         $table = new html_table();
2507         $table->head = array('', get_string('pagename','wiki'));
2508         $table->attributes['class'] = 'table generaltable';
2509         $swid = $this->subwiki->id;
2510         if ($showorphan) {
2511             if ($orphanedpages = wiki_get_orphaned_pages($swid)) {
2512                 $this->add_page_delete_options($orphanedpages, $swid, $table);
2513             } else {
2514                 $table->data[] = array('', get_string('noorphanedpages', 'wiki'));
2515             }
2516         } else {
2517             if ($pages = wiki_get_page_list($swid)) {
2518                 $this->add_page_delete_options($pages, $swid, $table);
2519             } else {
2520                 $table->data[] = array('', get_string('nopages', 'wiki'));
2521             }
2522         }
2524         ///Print the form
2525         echo html_writer::start_tag('form', array(
2526                                                 'action' => new moodle_url('/mod/wiki/admin.php'),
2527                                                 'method' => 'post'));
2528         echo html_writer::tag('div', html_writer::empty_tag('input', array(
2529                                                                          'type'  => 'hidden',
2530                                                                          'name'  => 'pageid',
2531                                                                          'value' => $this->page->id)));
2533         echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'option', 'value' => $this->view));
2534         echo html_writer::table($table);
2535         echo html_writer::start_tag('div');
2536         if (!$showorphan) {
2537             echo html_writer::empty_tag('input', array(
2538                                                      'type'    => 'submit',
2539                                                      'class'   => 'wiki_form-button',
2540                                                      'value'   => get_string('listorphan', 'wiki'),
2541                                                      'sesskey' => sesskey()));
2542         } else {
2543             echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'listall', 'value'=>'1'));
2544             echo html_writer::empty_tag('input', array(
2545                                                      'type'    => 'submit',
2546                                                      'class'   => 'wiki_form-button btn btn-secondary',
2547                                                      'value'   => get_string('listall', 'wiki'),
2548                                                      'sesskey' => sesskey()));
2549         }
2550         echo html_writer::end_tag('div');
2551         echo html_writer::end_tag('form');
2552     }
2554     /**
2555      * helper function for print_delete_content. This will add data to the table.
2556      *
2557      * @global object $OUTPUT
2558      * @param array $pages objects of wiki pages in subwiki
2559      * @param int $swid id of subwiki
2560      * @param object $table reference to the table in which data needs to be added
2561      */
2562     protected function add_page_delete_options($pages, $swid, &$table) {
2563         global $OUTPUT;
2564         foreach ($pages as $page) {
2565             $link = wiki_parser_link($page->title, array('swid' => $swid));
2566             $class = ($link['new']) ? 'class="wiki_newentry"' : '';
2567             $pagelink = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>';
2568             $urledit = new moodle_url('/mod/wiki/edit.php', array('pageid' => $page->id, 'sesskey' => sesskey()));
2569             $urldelete = new moodle_url('/mod/wiki/admin.php', array(
2570                                                                    'pageid'  => $this->page->id,
2571                                                                    'delete'  => $page->id,
2572                                                                    'option'  => $this->view,
2573                                                                    'listall' => !$this->listorphan?'1': '',
2574                                                                    'sesskey' => sesskey()));
2576             $editlinks = $OUTPUT->action_icon($urledit, new pix_icon('t/edit', get_string('edit')));
2577             $editlinks .= $OUTPUT->action_icon($urldelete, new pix_icon('t/delete', get_string('delete')));
2578             $table->data[] = array($editlinks, $pagelink);
2579         }
2580     }
2582     /**
2583      * Prints lists of versions which can be deleted
2584      *
2585      * @global core_renderer $OUTPUT
2586      * @global moodle_page $PAGE
2587      */
2588     private function print_delete_version() {
2589         global $OUTPUT, $PAGE;
2590         $pageid = $this->page->id;
2592         // versioncount is the latest version
2593         $versioncount = wiki_count_wiki_page_versions($pageid) - 1;
2594         $versions = wiki_get_wiki_page_versions($pageid, 0, $versioncount);
2596         // We don't want version 0 to be displayed
2597         // version 0 is blank page
2598         if (end($versions)->version == 0) {
2599             array_pop($versions);
2600         }
2602         $contents = array();
2603         $version0page = wiki_get_wiki_page_version($this->page->id, 0);
2604         $creator = wiki_get_user_info($version0page->userid);
2605         $a = new stdClass();
2606         $a->date = userdate($this->page->timecreated, get_string('strftimedaydatetime', 'langconfig'));
2607         $a->username = fullname($creator);
2608         echo $OUTPUT->heading(get_string('createddate', 'wiki', $a), 4);
2609         if ($versioncount > 0) {
2610             /// If there is only one version, we don't need radios nor forms
2611             if (count($versions) == 1) {
2612                 $row = array_shift($versions);
2613                 $username = wiki_get_user_info($row->userid);
2614                 $picture = $OUTPUT->user_picture($username);
2615                 $date = userdate($row->timecreated, get_string('strftimedate', 'langconfig'));
2616                 $time = userdate($row->timecreated, get_string('strftimetime', 'langconfig'));
2617                 $versionid = wiki_get_version($row->id);
2618                 $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
2619                 $userlink = new moodle_url('/user/view.php', array('id' => $username->id, 'course' => $this->cm->course));
2620                 $picturelink = $picture . html_writer::link($userlink->out(false), fullname($username));
2621                 $historydate = $OUTPUT->container($date, 'wiki_histdate');
2622                 $contents[] = array('', html_writer::link($versionlink->out(false), $row->version), $picturelink, $time, $historydate);
2624                 //Show current version
2625                 $table = new html_table();
2626                 $table->head = array('', get_string('version'), get_string('user'), get_string('modified'), '');
2627                 $table->data = $contents;
2629                 echo html_writer::table($table);
2630             } else {
2631                 $lastdate = '';
2632                 $rowclass = array();
2634                 foreach ($versions as $version) {
2635                     $user = wiki_get_user_info($version->userid);
2636                     $picture = $OUTPUT->user_picture($user, array('popup' => true));
2637                     $date = userdate($version->timecreated, get_string('strftimedate'));
2638                     if ($date == $lastdate) {
2639                         $date = '';
2640                         $rowclass[] = '';
2641                     } else {
2642                         $lastdate = $date;
2643                         $rowclass[] = 'wiki_histnewdate';
2644                     }
2646                     $time = userdate($version->timecreated, get_string('strftimetime', 'langconfig'));
2647                     $versionid = wiki_get_version($version->id);
2648                     if ($versionid) {
2649                         $url = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
2650                         $viewlink = html_writer::link($url->out(false), $version->version);
2651                     } else {
2652                         $viewlink = $version->version;
2653                     }
2655                     $userlink = new moodle_url('/user/view.php', array('id' => $version->userid, 'course' => $this->cm->course));
2656                     $picturelink = $picture . html_writer::link($userlink->out(false), fullname($user));
2657                     $historydate = $OUTPUT->container($date, 'wiki_histdate');
2658                     $radiofromelement = $this->choose_from_radio(array($version->version  => null), 'fromversion', 'M.mod_wiki.deleteversion()', $versioncount, true);
2659                     $radiotoelement = $this->choose_from_radio(array($version->version  => null), 'toversion', 'M.mod_wiki.deleteversion()', $versioncount, true);
2660                     $contents[] = array( $radiofromelement . $radiotoelement, $viewlink, $picturelink, $time, $historydate);
2661                 }
2663                 $table = new html_table();
2664                 $table->head = array(get_string('deleteversions', 'wiki'), get_string('version'), get_string('user'), get_string('modified'), '');
2665                 $table->data = $contents;
2666                 $table->attributes['class'] = 'table generaltable';
2667                 $table->rowclasses = $rowclass;
2669                 ///Print the form
2670                 echo html_writer::start_tag('form', array('action'=>new moodle_url('/mod/wiki/admin.php'), 'method' => 'post'));
2671                 echo html_writer::tag('div', html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'pageid', 'value' => $pageid)));
2672                 echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'option', 'value' => $this->view));
2673                 echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' =>  sesskey()));
2674                 echo html_writer::table($table);
2675                 echo html_writer::start_tag('div');
2676                 echo html_writer::empty_tag('input', array('type' => 'submit', 'class' => 'wiki_form-button btn btn-secondary', 'value' => get_string('deleteversions', 'wiki')));
2677                 echo html_writer::end_tag('div');
2678                 echo html_writer::end_tag('form');
2679             }
2680         } else {
2681             print_string('nohistory', 'wiki');
2682         }
2683     }
2685     /**
2686      * Given an array of values, creates a group of radio buttons to be part of a form
2687      * helper function for print_delete_version
2688      *
2689      * @param array  $options  An array of value-label pairs for the radio group (values as keys).
2690      * @param string $name     Name of the radiogroup (unique in the form).
2691      * @param string $onclick  Function to be executed when the radios are clicked.
2692      * @param string $checked  The value that is already checked.
2693      * @param bool   $return   If true, return the HTML as a string, otherwise print it.
2694      *
2695      * @return mixed If $return is false, returns nothing, otherwise returns a string of HTML.
2696      */
2697     private function choose_from_radio($options, $name, $onclick = '', $checked = '', $return = false) {
2699         static $idcounter = 0;
2701         if (!$name) {
2702             $name = 'unnamed';
2703         }
2705         $output = '<span class="radiogroup ' . $name . "\">\n";
2707         if (!empty($options)) {
2708             $currentradio = 0;
2709             foreach ($options as $value => $label) {
2710                 $htmlid = 'auto-rb' . sprintf('%04d', ++$idcounter);
2711                 $output .= ' <span class="radioelement ' . $name . ' rb' . $currentradio . "\">";
2712                 $output .= '<input name="' . $name . '" id="' . $htmlid . '" type="radio" value="' . $value . '"';
2713                 if ($value == $checked) {
2714                     $output .= ' checked="checked"';
2715                 }
2716                 if ($onclick) {
2717                     $output .= ' onclick="' . $onclick . '"';
2718                 }
2719                 if ($label === '') {
2720                     $output .= ' /> <label for="' . $htmlid . '">' . $value . '</label></span>' . "\n";
2721                 } else {
2722                     $output .= ' /> <label for="' . $htmlid . '">' . $label . '</label></span>' . "\n";
2723                 }
2724                 $currentradio = ($currentradio + 1) % 2;
2725             }
2726         }
2728         $output .= '</span>' . "\n";
2730         if ($return) {
2731             return $output;
2732         } else {
2733             echo $output;
2734         }
2735     }