Merge branch 'MDL-38766/master' of github.com:kemitix/moodle
[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-2.0
23  * @copyrigth 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu
24  * @copyrigth 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 require_once($CFG->dirroot . '/mod/wiki/edit_form.php');
37 require_once($CFG->dirroot . '/tag/lib.php');
39 /**
40  * Class page_wiki contains the common code between all pages
41  *
42  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43  */
44 abstract class page_wiki {
46     /**
47      * @var object Current subwiki
48      */
49     protected $subwiki;
51     /**
52      * @var int Current page
53      */
54     protected $page;
56     /**
57      * @var string Current page title
58      */
59     protected $title;
61     /**
62      * @var int Current group ID
63      */
64     protected $gid;
66     /**
67      * @var object module context object
68      */
69     protected $modcontext;
71     /**
72      * @var int Current user ID
73      */
74     protected $uid;
75     /**
76      * @var array The tabs set used in wiki module
77      */
78     protected $tabs = array('view' => 'view', 'edit' => 'edit', 'comments' => 'comments',
79                             'history' => 'history', 'map' => 'map', 'files' => 'files',
80                             'admin' => 'admin');
81     /**
82      * @var array tabs options
83      */
84     protected $tabs_options = array();
85     /**
86      * @var object wiki renderer
87      */
88     protected $wikioutput;
90     /**
91      * page_wiki constructor
92      *
93      * @param $wiki. Current wiki
94      * @param $subwiki. Current subwiki.
95      * @param $cm. Current course_module.
96      */
97     function __construct($wiki, $subwiki, $cm) {
98         global $PAGE, $CFG;
99         $this->subwiki = $subwiki;
100         $this->modcontext = context_module::instance($PAGE->cm->id);
102         // initialise wiki renderer
103         $this->wikioutput = $PAGE->get_renderer('mod_wiki');
104         $PAGE->set_cacheable(true);
105         $PAGE->set_cm($cm);
106         $PAGE->set_activity_record($wiki);
107         // the search box
108         $PAGE->set_button(wiki_search_form($cm));
109     }
111     /**
112      * This method prints the top of the page.
113      */
114     function print_header() {
115         global $OUTPUT, $PAGE, $CFG, $USER, $SESSION;
117         $PAGE->set_heading(format_string($PAGE->course->fullname));
119         $this->set_url();
121         if (isset($SESSION->wikipreviousurl) && is_array($SESSION->wikipreviousurl)) {
122             $this->process_session_url();
123         }
124         $this->set_session_url();
126         $this->create_navbar();
127         $this->setup_tabs();
129         echo $OUTPUT->header();
131         echo $this->wikioutput->wiki_info();
133         // tabs are associated with pageid, so if page is empty, tabs should be disabled
134         if (!empty($this->page) && !empty($this->tabs)) {
135             echo $this->wikioutput->tabs($this->page, $this->tabs, $this->tabs_options);
136         }
137     }
139     /**
140      * Protected method to print current page title.
141      */
142     protected function print_pagetitle() {
143         global $OUTPUT;
144         $html = '';
146         $html .= $OUTPUT->container_start();
147         $html .= $OUTPUT->heading(format_string($this->title), 2, 'wiki_headingtitle');
148         $html .= $OUTPUT->container_end();
149         echo $html;
150     }
152     /**
153      * Setup page tabs, if options is empty, will set up active tab automatically
154      * @param array $options, tabs options
155      */
156     protected function setup_tabs($options = array()) {
157         global $CFG, $PAGE;
158         $groupmode = groups_get_activity_groupmode($PAGE->cm);
160         if (empty($CFG->usecomments) || !has_capability('mod/wiki:viewcomment', $PAGE->context)){
161             unset($this->tabs['comments']);
162         }
164         if (!has_capability('mod/wiki:editpage', $PAGE->context)){
165             unset($this->tabs['edit']);
166         }
168         if ($groupmode and $groupmode == VISIBLEGROUPS) {
169             $currentgroup = groups_get_activity_group($PAGE->cm);
170             $manage = has_capability('mod/wiki:managewiki', $PAGE->cm->context);
171             $edit = has_capability('mod/wiki:editpage', $PAGE->context);
172             if (!$manage and !($edit and groups_is_member($currentgroup))) {
173                 unset($this->tabs['edit']);
174             }
175         }
177         if (empty($options)) {
178             $this->tabs_options = array('activetab' => substr(get_class($this), 10));
179         } else {
180             $this->tabs_options = $options;
181         }
183     }
185     /**
186      * This method must be overwritten to print the page content.
187      */
188     function print_content() {
189         throw new coding_exception('Page wiki class does not implement method print_content()');
190     }
192     /**
193      * Method to set the current page
194      *
195      * @param object $page Current page
196      */
197     function set_page($page) {
198         global $PAGE;
200         $this->page = $page;
201         $this->title = $page->title;
202         // set_title calls format_string itself so no probs there
203         $PAGE->set_title($this->title);
204     }
206     /**
207      * Method to set the current page title.
208      * This method must be called when the current page is not created yet.
209      * @param string $title Current page title.
210      */
211     function set_title($title) {
212         global $PAGE;
214         $this->page = null;
215         $this->title = $title;
216         // set_title calls format_string itself so no probs there
217         $PAGE->set_title($this->title);
218     }
220     /**
221      * Method to set current group id
222      * @param int $gid Current group id
223      */
224     function set_gid($gid) {
225         $this->gid = $gid;
226     }
228     /**
229      * Method to set current user id
230      * @param int $uid Current user id
231      */
232     function set_uid($uid) {
233         $this->uid = $uid;
234     }
236     /**
237      * Method to set the URL of the page.
238      * This method must be overwritten by every type of page.
239      */
240     protected function set_url() {
241         throw new coding_exception('Page wiki class does not implement method set_url()');
242     }
244     /**
245      * Protected method to create the common items of the navbar in every page type.
246      */
247     protected function create_navbar() {
248         global $PAGE, $CFG;
250         $PAGE->navbar->add(format_string($this->title), $CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $this->page->id);
251     }
253     /**
254      * This method print the footer of the page.
255      */
256     function print_footer() {
257         global $OUTPUT;
258         echo $OUTPUT->footer();
259     }
261     protected function process_session_url() {
262         global $USER, $SESSION;
264         //delete locks if edit
265         $url = $SESSION->wikipreviousurl;
266         switch ($url['page']) {
267         case 'edit':
268             wiki_delete_locks($url['params']['pageid'], $USER->id, $url['params']['section'], false);
269             break;
270         }
271     }
273     protected function set_session_url() {
274         global $SESSION;
275         unset($SESSION->wikipreviousurl);
276     }
280 /**
281  * View a wiki page
282  *
283  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
284  */
285 class page_wiki_view extends page_wiki {
286     /**
287      * @var int the coursemodule id
288      */
289     private $coursemodule;
291     function print_header() {
292         global $PAGE;
294         parent::print_header();
296         $this->wikioutput->wiki_print_subwiki_selector($PAGE->activityrecord, $this->subwiki, $this->page, 'view');
298         if (!empty($this->page)) {
299             echo $this->wikioutput->prettyview_link($this->page);
300         }
302         //echo $this->wikioutput->page_index();
304         $this->print_pagetitle();
305     }
307     function print_content() {
308         global $PAGE, $CFG;
310         if (wiki_user_can_view($this->subwiki)) {
312             if (!empty($this->page)) {
313                 wiki_print_page_content($this->page, $this->modcontext, $this->subwiki->id);
314                 $wiki = $PAGE->activityrecord;
315             } else {
316                 print_string('nocontent', 'wiki');
317                 // TODO: fix this part
318                 $swid = 0;
319                 if (!empty($this->subwiki)) {
320                     $swid = $this->subwiki->id;
321                 }
322             }
323         } else {
324             echo get_string('cannotviewpage', 'wiki');
325         }
326     }
328     function set_url() {
329         global $PAGE, $CFG;
330         $params = array();
332         if (isset($this->coursemodule)) {
333             $params['id'] = $this->coursemodule;
334         } else if (!empty($this->page) and $this->page != null) {
335             $params['pageid'] = $this->page->id;
336         } else if (!empty($this->gid)) {
337             $params['wid'] = $PAGE->cm->instance;
338             $params['group'] = $this->gid;
339         } else if (!empty($this->title)) {
340             $params['swid'] = $this->subwiki->id;
341             $params['title'] = $this->title;
342         } else {
343             print_error(get_string('invalidparameters', 'wiki'));
344         }
346         $PAGE->set_url(new moodle_url($CFG->wwwroot . '/mod/wiki/view.php', $params));
347     }
349     function set_coursemodule($id) {
350         $this->coursemodule = $id;
351     }
353     protected function create_navbar() {
354         global $PAGE;
356         $PAGE->navbar->add(format_string($this->title));
357         $PAGE->navbar->add(get_string('view', 'wiki'));
358     }
361 /**
362  * Wiki page editing page
363  *
364  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
365  */
366 class page_wiki_edit extends page_wiki {
368     public static $attachmentoptions;
370     protected $sectioncontent;
371     /** @var string the section name needed to be edited */
372     protected $section;
373     protected $overridelock = false;
374     protected $versionnumber = -1;
375     protected $upload = false;
376     protected $attachments = 0;
377     protected $deleteuploads = array();
378     protected $format;
380     function __construct($wiki, $subwiki, $cm) {
381         global $CFG, $PAGE;
382         parent::__construct($wiki, $subwiki, $cm);
383         self::$attachmentoptions = array('subdirs' => false, 'maxfiles' => - 1, 'maxbytes' => $CFG->maxbytes, 'accepted_types' => '*');
384         $PAGE->requires->js_init_call('M.mod_wiki.renew_lock', null, true);
385     }
387     protected function print_pagetitle() {
388         global $OUTPUT;
390         $title = $this->title;
391         if (isset($this->section)) {
392             $title .= ' : ' . $this->section;
393         }
394         echo $OUTPUT->container_start('wiki_clear');
395         echo $OUTPUT->heading(format_string($title), 2, 'wiki_headingtitle');
396         echo $OUTPUT->container_end();
397     }
399     function print_header() {
400         global $OUTPUT, $PAGE;
401         $PAGE->requires->data_for_js('wiki', array('renew_lock_timeout' => LOCK_TIMEOUT - 5, 'pageid' => $this->page->id, 'section' => $this->section));
403         parent::print_header();
405         $this->print_pagetitle();
407         print '<noscript>' . $OUTPUT->box(get_string('javascriptdisabledlocks', 'wiki'), 'errorbox') . '</noscript>';
408     }
410     function print_content() {
411         global $PAGE;
413         if (wiki_user_can_edit($this->subwiki)) {
414             $this->print_edit();
415         } else {
416             echo get_string('cannoteditpage', 'wiki');
417         }
418     }
420     protected function set_url() {
421         global $PAGE, $CFG;
423         $params = array('pageid' => $this->page->id);
425         if (isset($this->section)) {
426             $params['section'] = $this->section;
427         }
429         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/edit.php', $params);
430     }
432     protected function set_session_url() {
433         global $SESSION;
435         $SESSION->wikipreviousurl = array('page' => 'edit', 'params' => array('pageid' => $this->page->id, 'section' => $this->section));
436     }
438     protected function process_session_url() {
439     }
441     function set_section($sectioncontent, $section) {
442         $this->sectioncontent = $sectioncontent;
443         $this->section = $section;
444     }
446     public function set_versionnumber($versionnumber) {
447         $this->versionnumber = $versionnumber;
448     }
450     public function set_overridelock($override) {
451         $this->overridelock = $override;
452     }
454     function set_format($format) {
455         $this->format = $format;
456     }
458     public function set_upload($upload) {
459         $this->upload = $upload;
460     }
462     public function set_attachments($attachments) {
463         $this->attachments = $attachments;
464     }
466     public function set_deleteuploads($deleteuploads) {
467         $this->deleteuploads = $deleteuploads;
468     }
470     protected function create_navbar() {
471         global $PAGE, $CFG;
473         parent::create_navbar();
475         $PAGE->navbar->add(get_string('edit', 'wiki'));
476     }
478     protected function check_locks() {
479         global $OUTPUT, $USER, $CFG;
481         if (!wiki_set_lock($this->page->id, $USER->id, $this->section, true)) {
482             print $OUTPUT->box(get_string('pageislocked', 'wiki'), 'generalbox boxwidthnormal boxaligncenter');
484             if ($this->overridelock) {
485                 $params = 'pageid=' . $this->page->id;
487                 if ($this->section) {
488                     $params .= '&section=' . urlencode($this->section);
489                 }
491                 $form = '<form method="post" action="' . $CFG->wwwroot . '/mod/wiki/overridelocks.php?' . $params . '">';
492                 $form .= '<input type="hidden" name="sesskey" value="' . sesskey() . '" />';
493                 $form .= '<input type="submit" value="' . get_string('overridelocks', 'wiki') . '" />';
494                 $form .= '</form>';
496                 print $OUTPUT->box($form, 'generalbox boxwidthnormal boxaligncenter');
497             }
498             return false;
499         }
500         return true;
501     }
503     protected function print_edit($content = null) {
504         global $CFG, $OUTPUT, $USER, $PAGE;
506         if (!$this->check_locks()) {
507             return;
508         }
510         //delete old locks (> 1 hour)
511         wiki_delete_old_locks();
513         $version = wiki_get_current_version($this->page->id);
514         $format = $version->contentformat;
516         if ($content == null) {
517             if (empty($this->section)) {
518                 $content = $version->content;
519             } else {
520                 $content = $this->sectioncontent;
521             }
522         }
524         $versionnumber = $version->version;
525         if ($this->versionnumber >= 0) {
526             if ($version->version != $this->versionnumber) {
527                 print $OUTPUT->box(get_string('wrongversionlock', 'wiki'), 'errorbox');
528                 $versionnumber = $this->versionnumber;
529             }
530         }
532         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
533         if (!empty($this->section)) {
534             $url .= "&section=" . urlencode($this->section);
535         }
537         $params = array(
538             'attachmentoptions' => page_wiki_edit::$attachmentoptions,
539             'format' => $version->contentformat,
540             'version' => $versionnumber,
541             'pagetitle' => $this->page->title,
542             'contextid' => $this->modcontext->id
543         );
545         $data = new StdClass();
546         $data->newcontent = $content;
547         $data->version = $versionnumber;
548         $data->format = $format;
550         switch ($format) {
551         case 'html':
552             $data->newcontentformat = FORMAT_HTML;
553             // Append editor context to editor options, giving preference to existing context.
554             page_wiki_edit::$attachmentoptions = array_merge(array('context' => $this->modcontext), page_wiki_edit::$attachmentoptions);
555             $data = file_prepare_standard_editor($data, 'newcontent', page_wiki_edit::$attachmentoptions, $this->modcontext, 'mod_wiki', 'attachments', $this->subwiki->id);
556             break;
557         default:
558             break;
559         }
561         if ($version->contentformat != 'html') {
562             $params['fileitemid'] = $this->subwiki->id;
563             $params['component']  = 'mod_wiki';
564             $params['filearea']   = 'attachments';
565         }
567         if (!empty($CFG->usetags)) {
568             $params['tags'] = tag_get_tags_csv('wiki_pages', $this->page->id, TAG_RETURN_TEXT);
569         }
571         $form = new mod_wiki_edit_form($url, $params);
573         if ($formdata = $form->get_data()) {
574             if (!empty($CFG->usetags)) {
575                 $data->tags = $formdata->tags;
576             }
577         } else {
578             if (!empty($CFG->usetags)) {
579                 $data->tags = tag_get_tags_array('wiki', $this->page->id);
580             }
581         }
583         $form->set_data($data);
584         $form->display();
585     }
589 /**
590  * Class that models the behavior of wiki's view comments page
591  *
592  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
593  */
594 class page_wiki_comments extends page_wiki {
596     function print_header() {
598         parent::print_header();
600         $this->print_pagetitle();
602     }
604     function print_content() {
605         global $CFG, $OUTPUT, $USER, $PAGE;
606         require_once($CFG->dirroot . '/mod/wiki/locallib.php');
608         $page = $this->page;
609         $subwiki = $this->subwiki;
610         $wiki = $PAGE->activityrecord;
611         list($context, $course, $cm) = get_context_info_array($this->modcontext->id);
613         require_capability('mod/wiki:viewcomment', $this->modcontext, NULL, true, 'noviewcommentpermission', 'wiki');
615         $comments = wiki_get_comments($this->modcontext->id, $page->id);
617         if (has_capability('mod/wiki:editcomment', $this->modcontext)) {
618             echo '<div class="midpad"><a href="' . $CFG->wwwroot . '/mod/wiki/editcomments.php?action=add&amp;pageid=' . $page->id . '">' . get_string('addcomment', 'wiki') . '</a></div>';
619         }
621         $options = array('swid' => $this->page->subwikiid, 'pageid' => $page->id);
622         $version = wiki_get_current_version($this->page->id);
623         $format = $version->contentformat;
625         if (empty($comments)) {
626             echo $OUTPUT->heading(get_string('nocomments', 'wiki'));
627         }
629         foreach ($comments as $comment) {
631             $user = wiki_get_user_info($comment->userid);
633             $fullname = fullname($user, has_capability('moodle/site:viewfullnames', context_course::instance($course->id)));
634             $by = new stdclass();
635             $by->name = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $user->id . '&amp;course=' . $course->id . '">' . $fullname . '</a>';
636             $by->date = userdate($comment->timecreated);
638             $t = new html_table();
639             $cell1 = new html_table_cell($OUTPUT->user_picture($user, array('popup' => true)));
640             $cell2 = new html_table_cell(get_string('bynameondate', 'forum', $by));
641             $cell3 = new html_table_cell();
642             $cell3->atributtes ['width'] = "80%";
643             $cell4 = new html_table_cell();
644             $cell5 = new html_table_cell();
646             $row1 = new html_table_row();
647             $row1->cells[] = $cell1;
648             $row1->cells[] = $cell2;
649             $row2 = new html_table_row();
650             $row2->cells[] = $cell3;
652             if ($format != 'html') {
653                 if ($format == 'creole') {
654                     $parsedcontent = wiki_parse_content('creole', $comment->content, $options);
655                 } else if ($format == 'nwiki') {
656                     $parsedcontent = wiki_parse_content('nwiki', $comment->content, $options);
657                 }
659                 $cell4->text = format_text(html_entity_decode($parsedcontent['parsed_text'], ENT_QUOTES, 'UTF-8'), FORMAT_HTML);
660             } else {
661                 $cell4->text = format_text($comment->content, FORMAT_HTML);
662             }
664             $row2->cells[] = $cell4;
666             $t->data = array($row1, $row2);
668             $actionicons = false;
669             if ((has_capability('mod/wiki:managecomment', $this->modcontext))) {
670                 $urledit = new moodle_url('/mod/wiki/editcomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'edit'));
671                 $urldelet = new moodle_url('/mod/wiki/instancecomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'delete'));
672                 $actionicons = true;
673             } else if ((has_capability('mod/wiki:editcomment', $this->modcontext)) and ($USER->id == $user->id)) {
674                 $urledit = new moodle_url('/mod/wiki/editcomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'edit'));
675                 $urldelet = new moodle_url('/mod/wiki/instancecomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'delete'));
676                 $actionicons = true;
677             }
679             if ($actionicons) {
680                 $cell6 = new html_table_cell($OUTPUT->action_icon($urledit, new pix_icon('t/edit', get_string('edit'),
681                         '', array('class' => 'iconsmall'))) . $OUTPUT->action_icon($urldelet, new pix_icon('t/delete',
682                         get_string('delete'), '', array('class' => 'iconsmall'))));
683                 $row3 = new html_table_row();
684                 $row3->cells[] = $cell5;
685                 $row3->cells[] = $cell6;
686                 $t->data[] = $row3;
687             }
689             echo html_writer::tag('div', html_writer::table($t), array('class'=>'no-overflow'));
691         }
692     }
694     function set_url() {
695         global $PAGE, $CFG;
696         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
697     }
699     protected function create_navbar() {
700         global $PAGE, $CFG;
702         parent::create_navbar();
703         $PAGE->navbar->add(get_string('comments', 'wiki'));
704     }
708 /**
709  * Class that models the behavior of wiki's edit comment
710  *
711  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
712  */
713 class page_wiki_editcomment extends page_wiki {
714     private $comment;
715     private $action;
716     private $form;
717     private $format;
719     function set_url() {
720         global $PAGE, $CFG;
721         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
722     }
724     function print_header() {
725         parent::print_header();
726         $this->print_pagetitle();
727     }
729     function print_content() {
730         global $PAGE;
732         require_capability('mod/wiki:editcomment', $this->modcontext, NULL, true, 'noeditcommentpermission', 'wiki');
734         if ($this->action == 'add') {
735             $this->add_comment_form();
736         } else if ($this->action == 'edit') {
737             $this->edit_comment_form($this->comment);
738         }
739     }
741     function set_action($action, $comment) {
742         global $CFG;
743         require_once($CFG->dirroot . '/mod/wiki/comments_form.php');
745         $this->action = $action;
746         $this->comment = $comment;
747         $version = wiki_get_current_version($this->page->id);
748         $this->format = $version->contentformat;
750         if ($this->format == 'html') {
751             $destination = $CFG->wwwroot . '/mod/wiki/instancecomments.php?pageid=' . $this->page->id;
752             $this->form = new mod_wiki_comments_form($destination);
753         }
754     }
756     protected function create_navbar() {
757         global $PAGE, $CFG;
759         $PAGE->navbar->add(get_string('comments', 'wiki'), $CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $this->page->id);
761         if ($this->action == 'add') {
762             $PAGE->navbar->add(get_string('insertcomment', 'wiki'));
763         } else {
764             $PAGE->navbar->add(get_string('editcomment', 'wiki'));
765         }
766     }
768     protected function setup_tabs($options = array()) {
769         parent::setup_tabs(array('linkedwhenactive' => 'comments', 'activetab' => 'comments'));
770     }
772     private function add_comment_form() {
773         global $CFG;
774         require_once($CFG->dirroot . '/mod/wiki/editors/wiki_editor.php');
776         $pageid = $this->page->id;
778         if ($this->format == 'html') {
779             $com = new stdClass();
780             $com->action = 'add';
781             $com->commentoptions = array('trusttext' => true, 'maxfiles' => 0);
782             $this->form->set_data($com);
783             $this->form->display();
784         } else {
785             wiki_print_editor_wiki($this->page->id, null, $this->format, -1, null, false, null, 'addcomments');
786         }
787     }
789     private function edit_comment_form($com) {
790         global $CFG;
791         require_once($CFG->dirroot . '/mod/wiki/comments_form.php');
792         require_once($CFG->dirroot . '/mod/wiki/editors/wiki_editor.php');
794         if ($this->format == 'html') {
795             $com->action = 'edit';
796             $com->entrycomment_editor['text'] = $com->content;
797             $com->commentoptions = array('trusttext' => true, 'maxfiles' => 0);
799             $this->form->set_data($com);
800             $this->form->display();
801         } else {
802             wiki_print_editor_wiki($this->page->id, $com->content, $this->format, -1, null, false, array(), 'editcomments', $com->id);
803         }
805     }
809 /**
810  * Wiki page search page
811  *
812  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
813  */
814 class page_wiki_search extends page_wiki {
815     private $search_result;
817     protected function create_navbar() {
818         global $PAGE, $CFG;
820         $PAGE->navbar->add(format_string($this->title));
821     }
823     function set_search_string($search, $searchcontent) {
824         $swid = $this->subwiki->id;
825         if ($searchcontent) {
826             $this->search_result = wiki_search_all($swid, $search);
827         } else {
828             $this->search_result = wiki_search_title($swid, $search);
829         }
831     }
833     function set_url() {
834         global $PAGE, $CFG;
835         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/search.php');
836     }
837     function print_content() {
838         global $PAGE;
840         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
842         echo $this->wikioutput->search_result($this->search_result, $this->subwiki);
843     }
846 /**
847  *
848  * Class that models the behavior of wiki's
849  * create page
850  *
851  */
852 class page_wiki_create extends page_wiki {
854     private $format;
855     private $swid;
856     private $wid;
857     private $action;
858     private $mform;
859     private $groups;
861     function print_header() {
862         $this->set_url();
863         parent::print_header();
864     }
866     function set_url() {
867         global $PAGE, $CFG;
869         $params = array();
870         $params['swid'] = $this->swid;
871         if ($this->action == 'new') {
872             $params['action'] = 'new';
873             $params['wid'] = $this->wid;
874             if ($this->title != get_string('newpage', 'wiki')) {
875                 $params['title'] = $this->title;
876             }
877         } else {
878             $params['action'] = 'create';
879         }
880         $PAGE->set_url(new moodle_url('/mod/wiki/create.php', $params));
881     }
883     function set_format($format) {
884         $this->format = $format;
885     }
887     function set_wid($wid) {
888         $this->wid = $wid;
889     }
891     function set_swid($swid) {
892         $this->swid = $swid;
893     }
895     function set_availablegroups($group) {
896         $this->groups = $group;
897     }
899     function set_action($action) {
900         global $PAGE;
901         $this->action = $action;
903         require_once(dirname(__FILE__) . '/create_form.php');
904         $url = new moodle_url('/mod/wiki/create.php', array('action' => 'create', 'wid' => $PAGE->activityrecord->id, 'group' => $this->gid, 'uid' => $this->uid));
905         $formats = wiki_get_formats();
906         $options = array('formats' => $formats, 'defaultformat' => $PAGE->activityrecord->defaultformat, 'forceformat' => $PAGE->activityrecord->forceformat, 'groups' => $this->groups);
907         if ($this->title != get_string('newpage', 'wiki')) {
908             $options['disable_pagetitle'] = true;
909         }
910         $this->mform = new mod_wiki_create_form($url->out(false), $options);
911     }
913     protected function create_navbar() {
914         global $PAGE;
915         // navigation_node::get_content formats this before printing.
916         $PAGE->navbar->add($this->title);
917     }
919     function print_content($pagetitle = '') {
920         global $PAGE;
922         // @TODO: Change this to has_capability and show an alternative interface.
923         require_capability('mod/wiki:createpage', $this->modcontext, NULL, true, 'nocreatepermission', 'wiki');
924         $data = new stdClass();
925         if (!empty($pagetitle)) {
926             $data->pagetitle = $pagetitle;
927         }
928         $data->pageformat = $PAGE->activityrecord->defaultformat;
930         $this->mform->set_data($data);
931         $this->mform->display();
932     }
934     function create_page($pagetitle) {
935         global $USER, $PAGE;
937         $data = $this->mform->get_data();
938         if (isset($data->groupinfo)) {
939             $groupid = $data->groupinfo;
940         } else if (!empty($this->gid)) {
941             $groupid = $this->gid;
942         } else {
943             $groupid = '0';
944         }
945         if (empty($this->subwiki)) {
946             // If subwiki is not set then try find one and set else create one.
947             if (!$this->subwiki = wiki_get_subwiki_by_group($this->wid, $groupid, $this->uid)) {
948                 $swid = wiki_add_subwiki($PAGE->activityrecord->id, $groupid, $this->uid);
949                 $this->subwiki = wiki_get_subwiki($swid);
950             }
951         }
952         if ($data) {
953             $this->set_title($data->pagetitle);
954             $id = wiki_create_page($this->subwiki->id, $data->pagetitle, $data->pageformat, $USER->id);
955         } else {
956             $this->set_title($pagetitle);
957             $id = wiki_create_page($this->subwiki->id, $pagetitle, $PAGE->activityrecord->defaultformat, $USER->id);
958         }
959         $this->page = $id;
960         return $id;
961     }
964 class page_wiki_preview extends page_wiki_edit {
966     private $newcontent;
968     function __construct($wiki, $subwiki, $cm) {
969         global $PAGE, $CFG, $OUTPUT;
970         parent::__construct($wiki, $subwiki, $cm);
971         $buttons = $OUTPUT->update_module_button($cm->id, 'wiki');
972         $PAGE->set_button($buttons);
974     }
976     function print_header() {
977         global $PAGE, $CFG;
979         parent::print_header();
981     }
983     function print_content() {
984         global $PAGE;
986         require_capability('mod/wiki:editpage', $this->modcontext, NULL, true, 'noeditpermission', 'wiki');
988         $this->print_preview();
989     }
991     function set_newcontent($newcontent) {
992         $this->newcontent = $newcontent;
993     }
995     function set_url() {
996         global $PAGE, $CFG;
998         $params = array('pageid' => $this->page->id
999         );
1001         if (isset($this->section)) {
1002             $params['section'] = $this->section;
1003         }
1005         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/edit.php', $params);
1006     }
1008     protected function setup_tabs($options = array()) {
1009         parent::setup_tabs(array('linkedwhenactive' => 'view', 'activetab' => 'view'));
1010     }
1012     protected function check_locks() {
1013         return true;
1014     }
1016     protected function print_preview() {
1017         global $CFG, $PAGE, $OUTPUT;
1019         $version = wiki_get_current_version($this->page->id);
1020         $format = $version->contentformat;
1021         $content = $version->content;
1023         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
1024         if (!empty($this->section)) {
1025             $url .= "&section=" . urlencode($this->section);
1026         }
1027         $params = array(
1028             'attachmentoptions' => page_wiki_edit::$attachmentoptions,
1029             'format' => $this->format,
1030             'version' => $this->versionnumber,
1031             'contextid' => $this->modcontext->id
1032         );
1034         if ($this->format != 'html') {
1035             $params['component'] = 'mod_wiki';
1036             $params['filearea'] = 'attachments';
1037             $params['fileitemid'] = $this->page->id;
1038         }
1039         $form = new mod_wiki_edit_form($url, $params);
1042         $options = array('swid' => $this->page->subwikiid, 'pageid' => $this->page->id, 'pretty_print' => true);
1044         if ($data = $form->get_data()) {
1045             if (isset($data->newcontent)) {
1046                 // wiki fromat
1047                 $text = $data->newcontent;
1048             } else {
1049                 // html format
1050                 $text = $data->newcontent_editor['text'];
1051             }
1052             $parseroutput = wiki_parse_content($data->contentformat, $text, $options);
1053             $this->set_newcontent($text);
1054             echo $OUTPUT->notification(get_string('previewwarning', 'wiki'), 'notifyproblem wiki_info');
1055             $content = format_text($parseroutput['parsed_text'], FORMAT_HTML, array('overflowdiv'=>true, 'filter'=>false));
1056             echo $OUTPUT->box($content, 'generalbox wiki_previewbox');
1057             $content = $this->newcontent;
1058         }
1060         $this->print_edit($content);
1061     }
1065 /**
1066  *
1067  * Class that models the behavior of wiki's
1068  * view differences
1069  *
1070  */
1071 class page_wiki_diff extends page_wiki {
1073     private $compare;
1074     private $comparewith;
1076     function print_header() {
1077         global $OUTPUT;
1079         parent::print_header();
1081         $this->print_pagetitle();
1082         $vstring = new stdClass();
1083         $vstring->old = $this->compare;
1084         $vstring->new = $this->comparewith;
1085         echo $OUTPUT->heading(get_string('comparewith', 'wiki', $vstring));
1086     }
1088     /**
1089      * Print the diff view
1090      */
1091     function print_content() {
1092         global $PAGE;
1094         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1096         $this->print_diff_content();
1097     }
1099     function set_url() {
1100         global $PAGE, $CFG;
1102         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/diff.php', array('pageid' => $this->page->id, 'comparewith' => $this->comparewith, 'compare' => $this->compare));
1103     }
1105     function set_comparison($compare, $comparewith) {
1106         $this->compare = $compare;
1107         $this->comparewith = $comparewith;
1108     }
1110     protected function create_navbar() {
1111         global $PAGE, $CFG;
1113         parent::create_navbar();
1114         $PAGE->navbar->add(get_string('history', 'wiki'), $CFG->wwwroot . '/mod/wiki/history.php?pageid' . $this->page->id);
1115         $PAGE->navbar->add(get_string('diff', 'wiki'));
1116     }
1118     protected function setup_tabs($options = array()) {
1119         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history'));
1120     }
1122     /**
1123      * Given two versions of a page, prints a page displaying the differences between them.
1124      *
1125      * @global object $CFG
1126      * @global object $OUTPUT
1127      * @global object $PAGE
1128      */
1129     private function print_diff_content() {
1130         global $CFG, $OUTPUT, $PAGE;
1132         $pageid = $this->page->id;
1133         $total = wiki_count_wiki_page_versions($pageid) - 1;
1135         $oldversion = wiki_get_wiki_page_version($pageid, $this->compare);
1137         $newversion = wiki_get_wiki_page_version($pageid, $this->comparewith);
1139         if ($oldversion && $newversion) {
1141             $oldtext = format_text(file_rewrite_pluginfile_urls($oldversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id));
1142             $newtext = format_text(file_rewrite_pluginfile_urls($newversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id));
1143             list($diff1, $diff2) = ouwiki_diff_html($oldtext, $newtext);
1144             $oldversion->diff = $diff1;
1145             $oldversion->user = wiki_get_user_info($oldversion->userid);
1146             $newversion->diff = $diff2;
1147             $newversion->user = wiki_get_user_info($newversion->userid);
1149             echo $this->wikioutput->diff($pageid, $oldversion, $newversion, array('total' => $total));
1150         } else {
1151             print_error('versionerror', 'wiki');
1152         }
1153     }
1156 /**
1157  *
1158  * Class that models the behavior of wiki's history page
1159  *
1160  */
1161 class page_wiki_history extends page_wiki {
1162     /**
1163      * @var int $paging current page
1164      */
1165     private $paging;
1167     /**
1168      * @var int @rowsperpage Items per page
1169      */
1170     private $rowsperpage = 10;
1172     /**
1173      * @var int $allversion if $allversion != 0, all versions will be printed in a signle table
1174      */
1175     private $allversion;
1177     function __construct($wiki, $subwiki, $cm) {
1178         global $PAGE;
1179         parent::__construct($wiki, $subwiki, $cm);
1180         $PAGE->requires->js_init_call('M.mod_wiki.history', null, true);
1181     }
1183     function print_header() {
1184         parent::print_header();
1185         $this->print_pagetitle();
1186     }
1188     function print_pagetitle() {
1189         global $OUTPUT;
1190         $html = '';
1192         $html .= $OUTPUT->container_start();
1193         $html .= $OUTPUT->heading_with_help(format_string($this->title), 'history', 'wiki');
1194         $html .= $OUTPUT->container_end();
1195         echo $html;
1196     }
1198     function print_content() {
1199         global $PAGE;
1201         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1203         $this->print_history_content();
1204     }
1206     function set_url() {
1207         global $PAGE, $CFG;
1208         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/history.php', array('pageid' => $this->page->id));
1209     }
1211     function set_paging($paging) {
1212         $this->paging = $paging;
1213     }
1215     function set_allversion($allversion) {
1216         $this->allversion = $allversion;
1217     }
1219     protected function create_navbar() {
1220         global $PAGE, $CFG;
1222         parent::create_navbar();
1223         $PAGE->navbar->add(get_string('history', 'wiki'));
1224     }
1226     /**
1227      * Prints the history for a given wiki page
1228      *
1229      * @global object $CFG
1230      * @global object $OUTPUT
1231      * @global object $PAGE
1232      */
1233     private function print_history_content() {
1234         global $CFG, $OUTPUT, $PAGE;
1236         $pageid = $this->page->id;
1237         $offset = $this->paging * $this->rowsperpage;
1238         // vcount is the latest version
1239         $vcount = wiki_count_wiki_page_versions($pageid) - 1;
1240         if ($this->allversion) {
1241             $versions = wiki_get_wiki_page_versions($pageid, 0, $vcount);
1242         } else {
1243             $versions = wiki_get_wiki_page_versions($pageid, $offset, $this->rowsperpage);
1244         }
1245         // We don't want version 0 to be displayed
1246         // version 0 is blank page
1247         if (end($versions)->version == 0) {
1248             array_pop($versions);
1249         }
1251         $contents = array();
1253         $version0page = wiki_get_wiki_page_version($this->page->id, 0);
1254         $creator = wiki_get_user_info($version0page->userid);
1255         $a = new StdClass;
1256         $a->date = userdate($this->page->timecreated, get_string('strftimedaydatetime', 'langconfig'));
1257         $a->username = fullname($creator);
1258         echo $OUTPUT->heading(get_string('createddate', 'wiki', $a), 4, 'wiki_headingtime');
1259         if ($vcount > 0) {
1261             /// If there is only one version, we don't need radios nor forms
1262             if (count($versions) == 1) {
1264                 $row = array_shift($versions);
1266                 $username = wiki_get_user_info($row->userid);
1267                 $picture = $OUTPUT->user_picture($username);
1268                 $date = userdate($row->timecreated, get_string('strftimedate', 'langconfig'));
1269                 $time = userdate($row->timecreated, get_string('strftimetime', 'langconfig'));
1270                 $versionid = wiki_get_version($row->id);
1271                 $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
1272                 $userlink = new moodle_url('/user/view.php', array('id' => $username->id, 'course' => $PAGE->cm->course));
1273                 $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'));
1275                 $table = new html_table();
1276                 $table->head = array('', get_string('version'), get_string('user'), get_string('modified'), '');
1277                 $table->data = $contents;
1278                 $table->attributes['class'] = 'mdl-align';
1280                 echo html_writer::table($table);
1282             } else {
1284                 $checked = $vcount - $offset;
1285                 $rowclass = array();
1287                 foreach ($versions as $version) {
1288                     $user = wiki_get_user_info($version->userid);
1289                     $picture = $OUTPUT->user_picture($user, array('popup' => true));
1290                     $date = userdate($version->timecreated, get_string('strftimedate'));
1291                     $rowclass[] = 'wiki_histnewdate';
1292                     $time = userdate($version->timecreated, get_string('strftimetime', 'langconfig'));
1293                     $versionid = wiki_get_version($version->id);
1294                     if ($versionid) {
1295                         $url = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
1296                         $viewlink = html_writer::link($url->out(false), $version->version);
1297                     } else {
1298                         $viewlink = $version->version;
1299                     }
1300                     $userlink = new moodle_url('/user/view.php', array('id' => $version->userid, 'course' => $PAGE->cm->course));
1301                     $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'));
1302                 }
1304                 $table = new html_table();
1306                 $icon = $OUTPUT->help_icon('diff', 'wiki');
1308                 $table->head = array(get_string('diff', 'wiki') . $icon, get_string('version'), get_string('user'), get_string('modified'), '');
1309                 $table->data = $contents;
1310                 $table->attributes['class'] = 'generaltable mdl-align';
1311                 $table->rowclasses = $rowclass;
1313                 // Print the form.
1314                 echo html_writer::start_tag('form', array('action'=>new moodle_url('/mod/wiki/diff.php'), 'method'=>'get', 'id'=>'diff'));
1315                 echo html_writer::tag('div', html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'pageid', 'value'=>$pageid)));
1316                 echo html_writer::table($table);
1317                 echo html_writer::start_tag('div', array('class'=>'mdl-align'));
1318                 echo html_writer::empty_tag('input', array('type'=>'submit', 'class'=>'wiki_form-button', 'value'=>get_string('comparesel', 'wiki')));
1319                 echo html_writer::end_tag('div');
1320                 echo html_writer::end_tag('form');
1321             }
1322         } else {
1323             print_string('nohistory', 'wiki');
1324         }
1325         if (!$this->allversion) {
1326             //$pagingbar = moodle_paging_bar::make($vcount, $this->paging, $this->rowsperpage, $CFG->wwwroot.'/mod/wiki/history.php?pageid='.$pageid.'&amp;');
1327             // $pagingbar->pagevar = $pagevar;
1328             echo $OUTPUT->paging_bar($vcount, $this->paging, $this->rowsperpage, $CFG->wwwroot . '/mod/wiki/history.php?pageid=' . $pageid . '&amp;');
1329             //print_paging_bar($vcount, $paging, $rowsperpage,$CFG->wwwroot.'/mod/wiki/history.php?pageid='.$pageid.'&amp;','paging');
1330             } else {
1331             $link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid));
1332             $OUTPUT->container(html_writer::link($link->out(false), get_string('viewperpage', 'wiki', $this->rowsperpage)), 'mdl-align');
1333         }
1334         if ($vcount > $this->rowsperpage && !$this->allversion) {
1335             $link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid, 'allversion' => 1));
1336             $OUTPUT->container(html_writer::link($link->out(false), get_string('viewallhistory', 'wiki')), 'mdl-align');
1337         }
1338     }
1340     /**
1341      * Given an array of values, creates a group of radio buttons to be part of a form
1342      *
1343      * @param array  $options  An array of value-label pairs for the radio group (values as keys).
1344      * @param string $name     Name of the radiogroup (unique in the form).
1345      * @param string $onclick  Function to be executed when the radios are clicked.
1346      * @param string $checked  The value that is already checked.
1347      * @param bool   $return   If true, return the HTML as a string, otherwise print it.
1348      *
1349      * @return mixed If $return is false, returns nothing, otherwise returns a string of HTML.
1350      */
1351     private function choose_from_radio($options, $name, $onclick = '', $checked = '', $return = false) {
1353         static $idcounter = 0;
1355         if (!$name) {
1356             $name = 'unnamed';
1357         }
1359         $output = '<span class="radiogroup ' . $name . "\">\n";
1361         if (!empty($options)) {
1362             $currentradio = 0;
1363             foreach ($options as $value => $label) {
1364                 $htmlid = 'auto-rb' . sprintf('%04d', ++$idcounter);
1365                 $output .= ' <span class="radioelement ' . $name . ' rb' . $currentradio . "\">";
1366                 $output .= '<input name="' . $name . '" id="' . $htmlid . '" type="radio" value="' . $value . '"';
1367                 if ($value == $checked) {
1368                     $output .= ' checked="checked"';
1369                 }
1370                 if ($onclick) {
1371                     $output .= ' onclick="' . $onclick . '"';
1372                 }
1373                 if ($label === '') {
1374                     $output .= ' /> <label for="' . $htmlid . '">' . $value . '</label></span>' . "\n";
1375                 } else {
1376                     $output .= ' /> <label for="' . $htmlid . '">' . $label . '</label></span>' . "\n";
1377                 }
1378                 $currentradio = ($currentradio + 1) % 2;
1379             }
1380         }
1382         $output .= '</span>' . "\n";
1384         if ($return) {
1385             return $output;
1386         } else {
1387             echo $output;
1388         }
1389     }
1392 /**
1393  * Class that models the behavior of wiki's map page
1394  *
1395  */
1396 class page_wiki_map extends page_wiki {
1398     /**
1399      * @var int wiki view option
1400      */
1401     private $view;
1403     function print_header() {
1404         parent::print_header();
1405         $this->print_pagetitle();
1406     }
1408     function print_content() {
1409         global $CFG, $PAGE;
1411         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1413         if ($this->view > 0) {
1414             //echo '<div><a href="' . $CFG->wwwroot . '/mod/wiki/map.php?pageid=' . $this->page->id . '">' . get_string('backtomapmenu', 'wiki') . '</a></div>';
1415         }
1417         switch ($this->view) {
1418         case 1:
1419             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1420             $this->print_contributions_content();
1421             break;
1422         case 2:
1423             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1424             $this->print_navigation_content();
1425             break;
1426         case 3:
1427             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1428             $this->print_orphaned_content();
1429             break;
1430         case 4:
1431             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1432             $this->print_index_content();
1433             break;
1434         case 5:
1435             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1436             $this->print_page_list_content();
1437             break;
1438         case 6:
1439             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1440             $this->print_updated_content();
1441             break;
1442         default:
1443             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1444             $this->print_page_list_content();
1445         }
1446     }
1448     function set_view($option) {
1449         $this->view = $option;
1450     }
1452     function set_url() {
1453         global $PAGE, $CFG;
1454         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/map.php', array('pageid' => $this->page->id));
1455     }
1457     protected function create_navbar() {
1458         global $PAGE;
1460         parent::create_navbar();
1461         $PAGE->navbar->add(get_string('map', 'wiki'));
1462     }
1464     /**
1465      * Prints the contributions tab content
1466      *
1467      * @uses $OUTPUT, $USER
1468      *
1469      */
1470     private function print_contributions_content() {
1471         global $CFG, $OUTPUT, $USER;
1472         $page = $this->page;
1474         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1475             $fresh = wiki_refresh_cachedcontent($page);
1476             $page = $fresh['page'];
1477         }
1479         $swid = $this->subwiki->id;
1481         $table = new html_table();
1482         $table->head = array(get_string('contributions', 'wiki') . $OUTPUT->help_icon('contributions', 'wiki'));
1483         $table->attributes['class'] = 'wiki_editor generalbox';
1484         $table->data = array();
1485         $table->rowclasses = array();
1487         $lastversions = array();
1488         $pages = array();
1489         $users = array();
1491         if ($contribs = wiki_get_contributions($swid, $USER->id)) {
1492             foreach ($contribs as $contrib) {
1493                 if (!array_key_exists($contrib->pageid, $pages)) {
1494                     $page = wiki_get_page($contrib->pageid);
1495                     $pages[$contrib->pageid] = $page;
1496                 } else {
1497                     continue;
1498                 }
1500                 if (!array_key_exists($page->id, $lastversions)) {
1501                     $version = wiki_get_last_version($page->id);
1502                     $lastversions[$page->id] = $version;
1503                 } else {
1504                     $version = $lastversions[$page->id];
1505                 }
1507                 if (!array_key_exists($version->userid, $users)) {
1508                     $user = wiki_get_user_info($version->userid);
1509                     $users[$version->userid] = $user;
1510                 } else {
1511                     $user = $users[$version->userid];
1512                 }
1514                 $link = wiki_parser_link($page->title, array('swid' => $swid));
1515                 $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1517                 $linkpage = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content'], true, array('context' => $this->modcontext)) . '</a>';
1518                 $icon = $OUTPUT->user_picture($user, array('popup' => true));
1520                 $table->data[] = array("$icon&nbsp;$linkpage");
1521             }
1522         } else {
1523             $table->data[] = array(get_string('nocontribs', 'wiki'));
1524         }
1525         echo html_writer::table($table);
1526     }
1528     /**
1529      * Prints the navigation tab content
1530      *
1531      * @uses $OUTPUT
1532      *
1533      */
1534     private function print_navigation_content() {
1535         global $OUTPUT;
1536         $page = $this->page;
1538         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1539             $fresh = wiki_refresh_cachedcontent($page);
1540             $page = $fresh['page'];
1541         }
1543         $tolinks = wiki_get_linked_to_pages($page->id);
1544         $fromlinks = wiki_get_linked_from_pages($page->id);
1546         $table = new html_table();
1547         $table->attributes['class'] = 'wiki_navigation_from';
1548         $table->head = array(get_string('navigationfrom', 'wiki') . $OUTPUT->help_icon('navigationfrom', 'wiki') . ':');
1549         $table->data = array();
1550         $table->rowclasses = array();
1551         foreach ($fromlinks as $link) {
1552             $lpage = wiki_get_page($link->frompageid);
1553             $link = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
1554             $table->data[] = array(html_writer::link($link->out(false), format_string($lpage->title)));
1555             $table->rowclasses[] = 'mdl-align';
1556         }
1558         $table_left = html_writer::table($table);
1560         $table = new html_table();
1561         $table->attributes['class'] = 'wiki_navigation_to';
1562         $table->head = array(get_string('navigationto', 'wiki') . $OUTPUT->help_icon('navigationto', 'wiki') . ':');
1563         $table->data = array();
1564         $table->rowclasses = array();
1565         foreach ($tolinks as $link) {
1566             if ($link->tomissingpage) {
1567                 $viewlink = new moodle_url('/mod/wiki/create.php', array('swid' => $page->subwikiid, 'title' => $link->tomissingpage, 'action' => 'new'));
1568                 $table->data[] = array(html_writer::link($viewlink->out(false), format_string($link->tomissingpage), array('class' => 'wiki_newentry')));
1569             } else {
1570                 $lpage = wiki_get_page($link->topageid);
1571                 $viewlink = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
1572                 $table->data[] = array(html_writer::link($viewlink->out(false), format_string($lpage->title)));
1573             }
1574             $table->rowclasses[] = 'mdl-align';
1575         }
1576         $table_right = html_writer::table($table);
1577         echo $OUTPUT->container($table_left . $table_right, 'wiki_navigation_container');
1578     }
1580     /**
1581      * Prints the index page tab content
1582      *
1583      *
1584      */
1585     private function print_index_content() {
1586         global $OUTPUT;
1587         $page = $this->page;
1589         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1590             $fresh = wiki_refresh_cachedcontent($page);
1591             $page = $fresh['page'];
1592         }
1594         // navigation_node get_content calls format string for us
1595         $node = new navigation_node($page->title);
1597         $keys = array();
1598         $tree = array();
1599         $tree = wiki_build_tree($page, $node, $keys);
1601         $table = new html_table();
1602         $table->head = array(get_string('pageindex', 'wiki') . $OUTPUT->help_icon('pageindex', 'wiki'));
1603         $table->attributes['class'] = 'wiki_editor generalbox';
1604         $table->data[] = array($this->render_navigation_node($tree));
1606         echo html_writer::table($table);
1607     }
1609     /**
1610      * Prints the page list tab content
1611      *
1612      *
1613      */
1614     private function print_page_list_content() {
1615         global $OUTPUT;
1616         $page = $this->page;
1618         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1619             $fresh = wiki_refresh_cachedcontent($page);
1620             $page = $fresh['page'];
1621         }
1623         $pages = wiki_get_page_list($this->subwiki->id);
1625         $stdaux = new stdClass();
1626         $strspecial = get_string('special', 'wiki');
1628         foreach ($pages as $page) {
1629             // We need to format the title here to account for any filtering
1630             $letter = format_string($page->title, true, array('context' => $this->modcontext));
1631             $letter = textlib::substr($letter, 0, 1);
1632             if (preg_match('/^[a-zA-Z]$/', $letter)) {
1633                 $letter = textlib::strtoupper($letter);
1634                 $stdaux->{$letter}[] = wiki_parser_link($page);
1635             } else {
1636                 $stdaux->{$strspecial}[] = wiki_parser_link($page);
1637             }
1638         }
1640         $table = new html_table();
1641         $table->head = array(get_string('pagelist', 'wiki') . $OUTPUT->help_icon('pagelist', 'wiki'));
1642         $table->attributes['class'] = 'wiki_editor generalbox';
1643         $table->align = array('center');
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'] = 'wiki_editor generalbox';
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'] = 'wiki_editor generalbox';
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 $CFG, $PAGE;
1845         require_capability('mod/wiki:managewiki', $this->modcontext, NULL, true, 'nomanagewikipermission', 'wiki');
1847         $this->print_restoreversion();
1848     }
1850     function set_url() {
1851         global $PAGE, $CFG;
1852         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
1853     }
1855     function set_versionid($versionid) {
1856         $this->version = wiki_get_version($versionid);
1857     }
1859     protected function create_navbar() {
1860         global $PAGE, $CFG;
1862         parent::create_navbar();
1863         $PAGE->navbar->add(get_string('restoreversion', 'wiki'));
1864     }
1866     protected function setup_tabs($options = array()) {
1867         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history'));
1868     }
1870     /**
1871      * Prints the restore version content
1872      *
1873      * @uses $CFG
1874      *
1875      * @param page $page The page whose version will be restored
1876      * @param int  $versionid The version to be restored
1877      * @param bool $confirm If false, shows a yes/no confirmation page.
1878      *     If true, restores the old version and redirects the user to the 'view' tab.
1879      */
1880     private function print_restoreversion() {
1881         global $OUTPUT;
1883         $version = wiki_get_version($this->version->id);
1885         $optionsyes = array('confirm'=>1, 'pageid'=>$this->page->id, 'versionid'=>$version->id, 'sesskey'=>sesskey());
1886         $restoreurl = new moodle_url('/mod/wiki/restoreversion.php', $optionsyes);
1887         $return = new moodle_url('/mod/wiki/viewversion.php', array('pageid'=>$this->page->id, 'versionid'=>$version->id));
1889         echo $OUTPUT->heading(get_string('restoreconfirm', 'wiki', $version->version), 2);
1890         print_container_start(false, 'wiki_restoreform');
1891         echo '<form class="wiki_restore_yes" action="' . $restoreurl . '" method="post" id="restoreversion">';
1892         echo '<div><input type="submit" name="confirm" value="' . get_string('yes') . '" /></div>';
1893         echo '</form>';
1894         echo '<form class="wiki_restore_no" action="' . $return . '" method="post">';
1895         echo '<div><input type="submit" name="norestore" value="' . get_string('no') . '" /></div>';
1896         echo '</form>';
1897         print_container_end();
1898     }
1900 /**
1901  * Class that models the behavior of wiki's delete comment confirmation page
1902  *
1903  */
1904 class page_wiki_deletecomment extends page_wiki {
1905     private $commentid;
1907     function print_header() {
1908         parent::print_header();
1909         $this->print_pagetitle();
1910     }
1912     function print_content() {
1913         $this->printconfirmdelete();
1914     }
1916     function set_url() {
1917         global $PAGE;
1918         $PAGE->set_url('/mod/wiki/instancecomments.php', array('pageid' => $this->page->id, 'commentid' => $this->commentid));
1919     }
1921     public function set_action($action, $commentid, $content) {
1922         $this->action = $action;
1923         $this->commentid = $commentid;
1924         $this->content = $content;
1925     }
1927     protected function create_navbar() {
1928         global $PAGE;
1930         parent::create_navbar();
1931         $PAGE->navbar->add(get_string('deletecommentcheck', 'wiki'));
1932     }
1934     protected function setup_tabs($options = array()) {
1935         parent::setup_tabs(array('linkedwhenactive' => 'comments', 'activetab' => 'comments'));
1936     }
1938     /**
1939      * Prints the comment deletion confirmation form
1940      *
1941      * @param page $page The page whose version will be restored
1942      * @param int  $versionid The version to be restored
1943      * @param bool $confirm If false, shows a yes/no confirmation page.
1944      *     If true, restores the old version and redirects the user to the 'view' tab.
1945      */
1946     private function printconfirmdelete() {
1947         global $OUTPUT;
1949         $strdeletecheck = get_string('deletecommentcheck', 'wiki');
1950         $strdeletecheckfull = get_string('deletecommentcheckfull', 'wiki');
1952         //ask confirmation
1953         $optionsyes = array('confirm'=>1, 'pageid'=>$this->page->id, 'action'=>'delete', 'commentid'=>$this->commentid, 'sesskey'=>sesskey());
1954         $deleteurl = new moodle_url('/mod/wiki/instancecomments.php', $optionsyes);
1955         $return = new moodle_url('/mod/wiki/comments.php', array('pageid'=>$this->page->id));
1957         echo $OUTPUT->heading($strdeletecheckfull);
1958         print_container_start(false, 'wiki_deletecommentform');
1959         echo '<form class="wiki_deletecomment_yes" action="' . $deleteurl . '" method="post" id="deletecomment">';
1960         echo '<div><input type="submit" name="confirmdeletecomment" value="' . get_string('yes') . '" /></div>';
1961         echo '</form>';
1962         echo '<form class="wiki_deletecomment_no" action="' . $return . '" method="post">';
1963         echo '<div><input type="submit" name="norestore" value="' . get_string('no') . '" /></div>';
1964         echo '</form>';
1965         print_container_end();
1966     }
1969 /**
1970  * Class that models the behavior of wiki's
1971  * save page
1972  *
1973  */
1974 class page_wiki_save extends page_wiki_edit {
1976     private $newcontent;
1978     function print_header() {
1979     }
1981     function print_content() {
1982         global $PAGE;
1984         $context = context_module::instance($PAGE->cm->id);
1985         require_capability('mod/wiki:editpage', $context, NULL, true, 'noeditpermission', 'wiki');
1987         $this->print_save();
1988     }
1990     function set_newcontent($newcontent) {
1991         $this->newcontent = $newcontent;
1992     }
1994     protected function set_session_url() {
1995     }
1997     protected function print_save() {
1998         global $CFG, $USER, $OUTPUT, $PAGE;
2000         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
2001         if (!empty($this->section)) {
2002             $url .= "&section=" . urlencode($this->section);
2003         }
2005         $params = array(
2006             'attachmentoptions' => page_wiki_edit::$attachmentoptions,
2007             'format' => $this->format,
2008             'version' => $this->versionnumber,
2009             'contextid' => $this->modcontext->id
2010         );
2012         if ($this->format != 'html') {
2013             $params['fileitemid'] = $this->page->id;
2014             $params['component']  = 'mod_wiki';
2015             $params['filearea']   = 'attachments';
2016         }
2018         $form = new mod_wiki_edit_form($url, $params);
2020         $save = false;
2021         $data = false;
2022         if ($data = $form->get_data()) {
2023             if ($this->format == 'html') {
2024                 $data = file_postupdate_standard_editor($data, 'newcontent', page_wiki_edit::$attachmentoptions, $this->modcontext, 'mod_wiki', 'attachments', $this->subwiki->id);
2025             }
2027             if (isset($this->section)) {
2028                 $save = wiki_save_section($this->page, $this->section, $data->newcontent, $USER->id);
2029             } else {
2030                 $save = wiki_save_page($this->page, $data->newcontent, $USER->id);
2031             }
2032         }
2034         if ($save && $data) {
2035             if (!empty($CFG->usetags)) {
2036                 tag_set('wiki_pages', $this->page->id, $data->tags);
2037             }
2039             $message = '<p>' . get_string('saving', 'wiki') . '</p>';
2041             if (!empty($save['sections'])) {
2042                 foreach ($save['sections'] as $s) {
2043                     $message .= '<p>' . get_string('repeatedsection', 'wiki', $s) . '</p>';
2044                 }
2045             }
2047             if ($this->versionnumber + 1 != $save['version']) {
2048                 $message .= '<p>' . get_string('wrongversionsave', 'wiki') . '</p>';
2049             }
2051             if (isset($errors) && !empty($errors)) {
2052                 foreach ($errors as $e) {
2053                     $message .= "<p>" . get_string('filenotuploadederror', 'wiki', $e->get_filename()) . "</p>";
2054                 }
2055             }
2057             //deleting old locks
2058             wiki_delete_locks($this->page->id, $USER->id, $this->section);
2059             $url = new moodle_url('/mod/wiki/view.php', array('pageid' => $this->page->id, 'group' => $this->subwiki->groupid));
2060             redirect($url);
2061         } else {
2062             print_error('savingerror', 'wiki');
2063         }
2064     }
2067 /**
2068  * Class that models the behavior of wiki's view an old version of a page
2069  *
2070  */
2071 class page_wiki_viewversion extends page_wiki {
2073     private $version;
2075     function print_header() {
2076         parent::print_header();
2077         $this->print_pagetitle();
2078     }
2080     function print_content() {
2081         global $PAGE;
2083         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2085         $this->print_version_view();
2086     }
2088     function set_url() {
2089         global $PAGE, $CFG;
2090         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2091     }
2093     function set_versionid($versionid) {
2094         $this->version = wiki_get_version($versionid);
2095     }
2097     protected function create_navbar() {
2098         global $PAGE, $CFG;
2100         parent::create_navbar();
2101         $PAGE->navbar->add(get_string('history', 'wiki'), $CFG->wwwroot . '/mod/wiki/history.php?pageid' . $this->page->id);
2102         $PAGE->navbar->add(get_string('versionnum', 'wiki', $this->version->version));
2103     }
2105     protected function setup_tabs($options = array()) {
2106         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history', 'inactivetabs' => array('edit')));
2107     }
2109     /**
2110      * Given an old page version, output the version content
2111      *
2112      * @global object $CFG
2113      * @global object $OUTPUT
2114      * @global object $PAGE
2115      */
2116     private function print_version_view() {
2117         global $CFG, $OUTPUT, $PAGE;
2118         $pageversion = wiki_get_version($this->version->id);
2120         if ($pageversion) {
2121             $restorelink = new moodle_url('/mod/wiki/restoreversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2122             echo $OUTPUT->heading(get_string('viewversion', 'wiki', $pageversion->version) . '<br />' . html_writer::link($restorelink->out(false), '(' . get_string('restorethis', 'wiki') . ')', array('class' => 'wiki_restore')) . '&nbsp;', 4);
2123             $userinfo = wiki_get_user_info($pageversion->userid);
2124             $heading = '<p><strong>' . get_string('modified', 'wiki') . ':</strong>&nbsp;' . userdate($pageversion->timecreated, get_string('strftimedatetime', 'langconfig'));
2125             $viewlink = new moodle_url('/user/view.php', array('id' => $userinfo->id));
2126             $heading .= '&nbsp;&nbsp;&nbsp;<strong>' . get_string('user') . ':</strong>&nbsp;' . html_writer::link($viewlink->out(false), fullname($userinfo));
2127             $heading .= '&nbsp;&nbsp;&rarr;&nbsp;' . $OUTPUT->user_picture(wiki_get_user_info($pageversion->userid), array('popup' => true)) . '</p>';
2128             print_container($heading, false, 'mdl-align wiki_modifieduser wiki_headingtime');
2129             $options = array('swid' => $this->subwiki->id, 'pretty_print' => true, 'pageid' => $this->page->id);
2131             $pageversion->content = file_rewrite_pluginfile_urls($pageversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id);
2133             $parseroutput = wiki_parse_content($pageversion->contentformat, $pageversion->content, $options);
2134             $content = print_container(format_text($parseroutput['parsed_text'], FORMAT_HTML, array('overflowdiv'=>true)), false, '', '', true);
2135             echo $OUTPUT->box($content, 'generalbox wiki_contentbox');
2137         } else {
2138             print_error('versionerror', 'wiki');
2139         }
2140     }
2143 class page_wiki_confirmrestore extends page_wiki_save {
2145     private $version;
2147     function set_url() {
2148         global $PAGE, $CFG;
2149         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2150     }
2152     function print_content() {
2153         global $CFG, $PAGE;
2155         require_capability('mod/wiki:managewiki', $this->modcontext, NULL, true, 'nomanagewikipermission', 'wiki');
2157         $version = wiki_get_version($this->version->id);
2158         if (wiki_restore_page($this->page, $version->content, $version->userid)) {
2159             redirect($CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $this->page->id, get_string('restoring', 'wiki', $version->version), 3);
2160         } else {
2161             print_error('restoreerror', 'wiki', $version->version);
2162         }
2163     }
2165     function set_versionid($versionid) {
2166         $this->version = wiki_get_version($versionid);
2167     }
2170 class page_wiki_prettyview extends page_wiki {
2172     function print_header() {
2173         global $CFG, $PAGE, $OUTPUT;
2174         $PAGE->set_pagelayout('embedded');
2175         echo $OUTPUT->header();
2177         echo '<h1 id="wiki_printable_title">' . format_string($this->title) . '</h1>';
2178     }
2180     function print_content() {
2181         global $PAGE;
2183         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2185         $this->print_pretty_view();
2186     }
2188     function set_url() {
2189         global $PAGE, $CFG;
2191         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/prettyview.php', array('pageid' => $this->page->id));
2192     }
2194     private function print_pretty_view() {
2195         $version = wiki_get_current_version($this->page->id);
2197         $content = wiki_parse_content($version->contentformat, $version->content, array('printable' => true, 'swid' => $this->subwiki->id, 'pageid' => $this->page->id, 'pretty_print' => true));
2199         echo '<div id="wiki_printable_content">';
2200         echo format_text($content['parsed_text'], FORMAT_HTML);
2201         echo '</div>';
2202     }
2205 class page_wiki_handlecomments extends page_wiki {
2206     private $action;
2207     private $content;
2208     private $commentid;
2209     private $format;
2211     function print_header() {
2212         $this->set_url();
2213     }
2215     public function print_content() {
2216         global $CFG, $PAGE, $USER;
2218         if ($this->action == 'add') {
2219             if (has_capability('mod/wiki:editcomment', $this->modcontext)) {
2220                 $this->add_comment($this->content, $this->commentid);
2221             }
2222         } else if ($this->action == 'edit') {
2223             $comment = wiki_get_comment($this->commentid);
2224             $edit = has_capability('mod/wiki:editcomment', $this->modcontext);
2225             $owner = ($comment->userid == $USER->id);
2226             if ($owner && $edit) {
2227                 $this->add_comment($this->content, $this->commentid);
2228             }
2229         } else if ($this->action == 'delete') {
2230             $comment = wiki_get_comment($this->commentid);
2231             $manage = has_capability('mod/wiki:managecomment', $this->modcontext);
2232             $owner = ($comment->userid == $USER->id);
2233             if ($owner || $manage) {
2234                 $this->delete_comment($this->commentid);
2235                 redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $this->page->id, get_string('deletecomment', 'wiki'), 2);
2236             }
2237         }
2239     }
2241     public function set_url() {
2242         global $PAGE, $CFG;
2243         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
2244     }
2246     public function set_action($action, $commentid, $content) {
2247         $this->action = $action;
2248         $this->commentid = $commentid;
2249         $this->content = $content;
2251         $version = wiki_get_current_version($this->page->id);
2252         $format = $version->contentformat;
2254         $this->format = $format;
2255     }
2257     private function add_comment($content, $idcomment) {
2258         global $CFG, $PAGE;
2259         require_once($CFG->dirroot . "/mod/wiki/locallib.php");
2261         $pageid = $this->page->id;
2263         wiki_add_comment($this->modcontext, $pageid, $content, $this->format);
2265         if (!$idcomment) {
2266             redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $pageid, get_string('createcomment', 'wiki'), 2);
2267         } else {
2268             $this->delete_comment($idcomment);
2269             redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $pageid, get_string('editingcomment', 'wiki'), 2);
2270         }
2271     }
2273     private function delete_comment($commentid) {
2274         global $CFG, $PAGE;
2276         $pageid = $this->page->id;
2278         wiki_delete_comment($commentid, $this->modcontext, $pageid);
2279     }
2283 class page_wiki_lock extends page_wiki_edit {
2285     public function print_header() {
2286         $this->set_url();
2287     }
2289     protected function set_url() {
2290         global $PAGE, $CFG;
2292         $params = array('pageid' => $this->page->id);
2294         if ($this->section) {
2295             $params['section'] = $this->section;
2296         }
2298         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/lock.php', $params);
2299     }
2301     protected function set_session_url() {
2302     }
2304     public function print_content() {
2305         global $USER, $PAGE;
2307         require_capability('mod/wiki:editpage', $this->modcontext, NULL, true, 'noeditpermission', 'wiki');
2309         wiki_set_lock($this->page->id, $USER->id, $this->section);
2310     }
2312     public function print_footer() {
2313     }
2316 class page_wiki_overridelocks extends page_wiki_edit {
2317     function print_header() {
2318         $this->set_url();
2319     }
2321     function print_content() {
2322         global $CFG, $PAGE;
2324         require_capability('mod/wiki:overridelock', $this->modcontext, NULL, true, 'nooverridelockpermission', 'wiki');
2326         wiki_delete_locks($this->page->id, null, $this->section, true, true);
2328         $args = "pageid=" . $this->page->id;
2330         if (!empty($this->section)) {
2331             $args .= "&section=" . urlencode($this->section);
2332         }
2334         redirect($CFG->wwwroot . '/mod/wiki/edit.php?' . $args, get_string('overridinglocks', 'wiki'), 2);
2335     }
2337     function set_url() {
2338         global $PAGE, $CFG;
2340         $params = array('pageid' => $this->page->id);
2342         if (!empty($this->section)) {
2343             $params['section'] = $this->section;
2344         }
2346         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/overridelocks.php', $params);
2347     }
2349     protected function set_session_url() {
2350     }
2352     private function print_overridelocks() {
2353         global $CFG;
2355         wiki_delete_locks($this->page->id, null, $this->section, true, true);
2357         $args = "pageid=" . $this->page->id;
2359         if (!empty($this->section)) {
2360             $args .= "&section=" . urlencode($this->section);
2361         }
2363         redirect($CFG->wwwroot . '/mod/wiki/edit.php?' . $args, get_string('overridinglocks', 'wiki'), 2);
2364     }
2368 /**
2369  * This class will let user to delete wiki pages and page versions
2370  *
2371  */
2372 class page_wiki_admin extends page_wiki {
2374     public $view, $action;
2375     public $listorphan = false;
2377     /**
2378      * Constructor
2379      *
2380      * @global object $PAGE
2381      * @param mixed $wiki instance of wiki
2382      * @param mixed $subwiki instance of subwiki
2383      * @param stdClass $cm course module
2384      */
2385     function __construct($wiki, $subwiki, $cm) {
2386         global $PAGE;
2387         parent::__construct($wiki, $subwiki, $cm);
2388         $PAGE->requires->js_init_call('M.mod_wiki.deleteversion', null, true);
2389     }
2391     /**
2392      * Prints header for wiki page
2393      */
2394     function print_header() {
2395         parent::print_header();
2396         $this->print_pagetitle();
2397     }
2399     /**
2400      * This function will display administration view to users with managewiki capability
2401      */
2402     function print_content() {
2403         //make sure anyone trying to access this page has managewiki capabilities
2404         require_capability('mod/wiki:managewiki', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2406         //update wiki cache if timedout
2407         $page = $this->page;
2408         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
2409             $fresh = wiki_refresh_cachedcontent($page);
2410             $page = $fresh['page'];
2411         }
2413         //dispaly admin menu
2414         echo $this->wikioutput->menu_admin($this->page->id, $this->view);
2416         //Display appropriate admin view
2417         switch ($this->view) {
2418             case 1: //delete page view
2419                 $this->print_delete_content($this->listorphan);
2420                 break;
2421             case 2: //delete version view
2422                 $this->print_delete_version();
2423                 break;
2424             default: //default is delete view
2425                 $this->print_delete_content($this->listorphan);
2426                 break;
2427         }
2428     }
2430     /**
2431      * Sets admin view option
2432      *
2433      * @param int $view page view id
2434      * @param bool $listorphan is only valid for view 1.
2435      */
2436     public function set_view($view, $listorphan = true) {
2437         $this->view = $view;
2438         $this->listorphan = $listorphan;
2439     }
2441     /**
2442      * Sets page url
2443      *
2444      * @global object $PAGE
2445      * @global object $CFG
2446      */
2447     function set_url() {
2448         global $PAGE, $CFG;
2449         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/admin.php', array('pageid' => $this->page->id));
2450     }
2452     /**
2453      * sets navigation bar for the page
2454      *
2455      * @global object $PAGE
2456      */
2457     protected function create_navbar() {
2458         global $PAGE;
2460         parent::create_navbar();
2461         $PAGE->navbar->add(get_string('admin', 'wiki'));
2462     }
2464     /**
2465      * Show wiki page delete options
2466      *
2467      * @param bool $showorphan
2468      */
2469     protected function print_delete_content($showorphan = true) {
2470         $contents = array();
2471         $table = new html_table();
2472         $table->head = array('', get_string('pagename','wiki'));
2473         $table->attributes['class'] = 'generaltable mdl-align';
2474         $swid = $this->subwiki->id;
2475         if ($showorphan) {
2476             if ($orphanedpages = wiki_get_orphaned_pages($swid)) {
2477                 $this->add_page_delete_options($orphanedpages, $swid, $table);
2478             } else {
2479                 $table->data[] = array('', get_string('noorphanedpages', 'wiki'));
2480             }
2481         } else {
2482             if ($pages = wiki_get_page_list($swid)) {
2483                 $this->add_page_delete_options($pages, $swid, $table);
2484             } else {
2485                 $table->data[] = array('', get_string('nopages', 'wiki'));
2486             }
2487         }
2489         ///Print the form
2490         echo html_writer::start_tag('form', array(
2491                                                 'action' => new moodle_url('/mod/wiki/admin.php'),
2492                                                 'method' => 'post'));
2493         echo html_writer::tag('div', html_writer::empty_tag('input', array(
2494                                                                          'type'  => 'hidden',
2495                                                                          'name'  => 'pageid',
2496                                                                          'value' => $this->page->id)));
2498         echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'option', 'value' => $this->view));
2499         echo html_writer::table($table);
2500         echo html_writer::start_tag('div', array('class' => 'mdl-align'));
2501         if (!$showorphan) {
2502             echo html_writer::empty_tag('input', array(
2503                                                      'type'    => 'submit',
2504                                                      'class'   => 'wiki_form-button',
2505                                                      'value'   => get_string('listorphan', 'wiki'),
2506                                                      'sesskey' => sesskey()));
2507         } else {
2508             echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'listall', 'value'=>'1'));
2509             echo html_writer::empty_tag('input', array(
2510                                                      'type'    => 'submit',
2511                                                      'class'   => 'wiki_form-button',
2512                                                      'value'   => get_string('listall', 'wiki'),
2513                                                      'sesskey' => sesskey()));
2514         }
2515         echo html_writer::end_tag('div');
2516         echo html_writer::end_tag('form');
2517     }
2519     /**
2520      * helper function for print_delete_content. This will add data to the table.
2521      *
2522      * @global object $OUTPUT
2523      * @param array $pages objects of wiki pages in subwiki
2524      * @param int $swid id of subwiki
2525      * @param object $table reference to the table in which data needs to be added
2526      */
2527     protected function add_page_delete_options($pages, $swid, &$table) {
2528         global $OUTPUT;
2529         foreach ($pages as $page) {
2530             $link = wiki_parser_link($page->title, array('swid' => $swid));
2531             $class = ($link['new']) ? 'class="wiki_newentry"' : '';
2532             $pagelink = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>';
2533             $urledit = new moodle_url('/mod/wiki/edit.php', array('pageid' => $page->id, 'sesskey' => sesskey()));
2534             $urldelete = new moodle_url('/mod/wiki/admin.php', array(
2535                                                                    'pageid'  => $this->page->id,
2536                                                                    'delete'  => $page->id,
2537                                                                    'option'  => $this->view,
2538                                                                    'listall' => !$this->listorphan?'1': '',
2539                                                                    'sesskey' => sesskey()));
2541             $editlinks = $OUTPUT->action_icon($urledit, new pix_icon('t/edit', get_string('edit')));
2542             $editlinks .= $OUTPUT->action_icon($urldelete, new pix_icon('t/delete', get_string('delete')));
2543             $table->data[] = array($editlinks, $pagelink);
2544         }
2545     }
2547     /**
2548      * Prints lists of versions which can be deleted
2549      *
2550      * @global core_renderer $OUTPUT
2551      * @global moodle_page $PAGE
2552      */
2553     private function print_delete_version() {
2554         global $OUTPUT, $PAGE;
2555         $pageid = $this->page->id;
2557         // versioncount is the latest version
2558         $versioncount = wiki_count_wiki_page_versions($pageid) - 1;
2559         $versions = wiki_get_wiki_page_versions($pageid, 0, $versioncount);
2561         // We don't want version 0 to be displayed
2562         // version 0 is blank page
2563         if (end($versions)->version == 0) {
2564             array_pop($versions);
2565         }
2567         $contents = array();
2568         $version0page = wiki_get_wiki_page_version($this->page->id, 0);
2569         $creator = wiki_get_user_info($version0page->userid);
2570         $a = new stdClass();
2571         $a->date = userdate($this->page->timecreated, get_string('strftimedaydatetime', 'langconfig'));
2572         $a->username = fullname($creator);
2573         echo $OUTPUT->heading(get_string('createddate', 'wiki', $a), 4, 'wiki_headingtime');
2574         if ($versioncount > 0) {
2575             /// If there is only one version, we don't need radios nor forms
2576             if (count($versions) == 1) {
2577                 $row = array_shift($versions);
2578                 $username = wiki_get_user_info($row->userid);
2579                 $picture = $OUTPUT->user_picture($username);
2580                 $date = userdate($row->timecreated, get_string('strftimedate', 'langconfig'));
2581                 $time = userdate($row->timecreated, get_string('strftimetime', 'langconfig'));
2582                 $versionid = wiki_get_version($row->id);
2583                 $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
2584                 $userlink = new moodle_url('/user/view.php', array('id' => $username->id, 'course' => $PAGE->cm->course));
2585                 $picturelink = $picture . html_writer::link($userlink->out(false), fullname($username));
2586                 $historydate = $OUTPUT->container($date, 'wiki_histdate');
2587                 $contents[] = array('', html_writer::link($versionlink->out(false), $row->version), $picturelink, $time, $historydate);
2589                 //Show current version
2590                 $table = new html_table();
2591                 $table->head = array('', get_string('version'), get_string('user'), get_string('modified'), '');
2592                 $table->data = $contents;
2593                 $table->attributes['class'] = 'mdl-align';
2595                 echo html_writer::table($table);
2596             } else {
2597                 $lastdate = '';
2598                 $rowclass = array();
2600                 foreach ($versions as $version) {
2601                     $user = wiki_get_user_info($version->userid);
2602                     $picture = $OUTPUT->user_picture($user, array('popup' => true));
2603                     $date = userdate($version->timecreated, get_string('strftimedate'));
2604                     if ($date == $lastdate) {
2605                         $date = '';
2606                         $rowclass[] = '';
2607                     } else {
2608                         $lastdate = $date;
2609                         $rowclass[] = 'wiki_histnewdate';
2610                     }
2612                     $time = userdate($version->timecreated, get_string('strftimetime', 'langconfig'));
2613                     $versionid = wiki_get_version($version->id);
2614                     if ($versionid) {
2615                         $url = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
2616                         $viewlink = html_writer::link($url->out(false), $version->version);
2617                     } else {
2618                         $viewlink = $version->version;
2619                     }
2621                     $userlink = new moodle_url('/user/view.php', array('id' => $version->userid, 'course' => $PAGE->cm->course));
2622                     $picturelink = $picture . html_writer::link($userlink->out(false), fullname($user));
2623                     $historydate = $OUTPUT->container($date, 'wiki_histdate');
2624                     $radiofromelement = $this->choose_from_radio(array($version->version  => null), 'fromversion', 'M.mod_wiki.deleteversion()', $versioncount, true);
2625                     $radiotoelement = $this->choose_from_radio(array($version->version  => null), 'toversion', 'M.mod_wiki.deleteversion()', $versioncount, true);
2626                     $contents[] = array( $radiofromelement . $radiotoelement, $viewlink, $picturelink, $time, $historydate);
2627                 }
2629                 $table = new html_table();
2630                 $table->head = array(get_string('deleteversions', 'wiki'), get_string('version'), get_string('user'), get_string('modified'), '');
2631                 $table->data = $contents;
2632                 $table->attributes['class'] = 'generaltable mdl-align';
2633                 $table->rowclasses = $rowclass;
2635                 ///Print the form
2636                 echo html_writer::start_tag('form', array('action'=>new moodle_url('/mod/wiki/admin.php'), 'method' => 'post'));
2637                 echo html_writer::tag('div', html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'pageid', 'value' => $pageid)));
2638                 echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'option', 'value' => $this->view));
2639                 echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' =>  sesskey()));
2640                 echo html_writer::table($table);
2641                 echo html_writer::start_tag('div', array('class' => 'mdl-align'));
2642                 echo html_writer::empty_tag('input', array('type' => 'submit', 'class' => 'wiki_form-button', 'value' => get_string('deleteversions', 'wiki')));
2643                 echo html_writer::end_tag('div');
2644                 echo html_writer::end_tag('form');
2645             }
2646         } else {
2647             print_string('nohistory', 'wiki');
2648         }
2649     }
2651     /**
2652      * Given an array of values, creates a group of radio buttons to be part of a form
2653      * helper function for print_delete_version
2654      *
2655      * @param array  $options  An array of value-label pairs for the radio group (values as keys).
2656      * @param string $name     Name of the radiogroup (unique in the form).
2657      * @param string $onclick  Function to be executed when the radios are clicked.
2658      * @param string $checked  The value that is already checked.
2659      * @param bool   $return   If true, return the HTML as a string, otherwise print it.
2660      *
2661      * @return mixed If $return is false, returns nothing, otherwise returns a string of HTML.
2662      */
2663     private function choose_from_radio($options, $name, $onclick = '', $checked = '', $return = false) {
2665         static $idcounter = 0;
2667         if (!$name) {
2668             $name = 'unnamed';
2669         }
2671         $output = '<span class="radiogroup ' . $name . "\">\n";
2673         if (!empty($options)) {
2674             $currentradio = 0;
2675             foreach ($options as $value => $label) {
2676                 $htmlid = 'auto-rb' . sprintf('%04d', ++$idcounter);
2677                 $output .= ' <span class="radioelement ' . $name . ' rb' . $currentradio . "\">";
2678                 $output .= '<input name="' . $name . '" id="' . $htmlid . '" type="radio" value="' . $value . '"';
2679                 if ($value == $checked) {
2680                     $output .= ' checked="checked"';
2681                 }
2682                 if ($onclick) {
2683                     $output .= ' onclick="' . $onclick . '"';
2684                 }
2685                 if ($label === '') {
2686                     $output .= ' /> <label for="' . $htmlid . '">' . $value . '</label></span>' . "\n";
2687                 } else {
2688                     $output .= ' /> <label for="' . $htmlid . '">' . $label . '</label></span>' . "\n";
2689                 }
2690                 $currentradio = ($currentradio + 1) % 2;
2691             }
2692         }
2694         $output .= '</span>' . "\n";
2696         if ($return) {
2697             return $output;
2698         } else {
2699             echo $output;
2700         }
2701     }