59690f7aa50e7417d75cab65cbab71ec63d79d2e
[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 = get_context_instance(CONTEXT_MODULE, $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;
159         if (empty($CFG->usecomments) || !has_capability('mod/wiki:viewcomment', $PAGE->context)){
160             unset($this->tabs['comments']);
161         }
163         if (!has_capability('mod/wiki:editpage', $PAGE->context)){
164             unset($this->tabs['edit']);
165         }
168         if (empty($options)) {
169             $this->tabs_options = array('activetab' => substr(get_class($this), 10));
170         } else {
171             $this->tabs_options = $options;
172         }
174     }
176     /**
177      * This method must be overwritten to print the page content.
178      */
179     function print_content() {
180         throw new coding_exception('Page wiki class does not implement method print_content()');
181     }
183     /**
184      * Method to set the current page
185      *
186      * @param object $page Current page
187      */
188     function set_page($page) {
189         global $PAGE;
191         $this->page = $page;
192         $this->title = $page->title;
193         $PAGE->set_title($this->title);
194     }
196     /**
197      * Method to set the current page title.
198      * This method must be called when the current page is not created yet.
199      * @param string $title Current page title.
200      */
201     function set_title($title) {
202         global $PAGE;
204         $this->page = null;
205         $this->title = $title;
206         $PAGE->set_title($this->title);
207     }
209     /**
210      * Method to set current group id
211      * @param int $gid Current group id
212      */
213     function set_gid($gid) {
214         $this->gid = $gid;
215     }
217     /**
218      * Method to set current user id
219      * @param int $uid Current user id
220      */
221     function set_uid($uid) {
222         $this->uid = $uid;
223     }
225     /**
226      * Method to set the URL of the page.
227      * This method must be overwritten by every type of page.
228      */
229     protected function set_url() {
230         throw new coding_exception('Page wiki class does not implement method set_url()');
231     }
233     /**
234      * Protected method to create the common items of the navbar in every page type.
235      */
236     protected function create_navbar() {
237         global $PAGE, $CFG;
239         $PAGE->navbar->add(format_string($this->title), $CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $this->page->id);
240     }
242     /**
243      * This method print the footer of the page.
244      */
245     function print_footer() {
246         global $OUTPUT;
247         echo $OUTPUT->footer();
248     }
250     protected function process_session_url() {
251         global $USER, $SESSION;
253         //delete locks if edit
254         $url = $SESSION->wikipreviousurl;
255         switch ($url['page']) {
256         case 'edit':
257             wiki_delete_locks($url['params']['pageid'], $USER->id, $url['params']['section'], false);
258             break;
259         }
260     }
262     protected function set_session_url() {
263         global $SESSION;
264         unset($SESSION->wikipreviousurl);
265     }
269 /**
270  * View a wiki page
271  *
272  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
273  */
274 class page_wiki_view extends page_wiki {
275     /**
276      * @var int the coursemodule id
277      */
278     private $coursemodule;
280     function print_header() {
281         global $PAGE;
283         parent::print_header();
285         $this->wikioutput->wiki_print_subwiki_selector($PAGE->activityrecord, $this->subwiki, $this->page, 'view');
287         if (!empty($this->page)) {
288             echo $this->wikioutput->prettyview_link($this->page);
289         }
291         //echo $this->wikioutput->page_index();
293         $this->print_pagetitle();
294     }
296     function print_content() {
297         global $PAGE, $CFG;
299         if (wiki_user_can_view($this->subwiki)) {
301             if (!empty($this->page)) {
302                 wiki_print_page_content($this->page, $this->modcontext, $this->subwiki->id);
303                 $wiki = $PAGE->activityrecord;
304             } else {
305                 print_string('nocontent', 'wiki');
306                 // TODO: fix this part
307                 $swid = 0;
308                 if (!empty($this->subwiki)) {
309                     $swid = $this->subwiki->id;
310                 }
311             }
312         } else {
313             // @TODO: Tranlate it
314             echo "You can not view this page";
315         }
316     }
318     function set_url() {
319         global $PAGE, $CFG;
320         $params = array();
322         if (isset($this->coursemodule)) {
323             $params['id'] = $this->coursemodule;
324         } else if (!empty($this->page) and $this->page != null) {
325             $params['pageid'] = $this->page->id;
326         } else if (!empty($this->gid)) {
327             $params['wid'] = $PAGE->cm->instance;
328             $params['group'] = $this->gid;
329         } else if (!empty($this->title)) {
330             $params['swid'] = $this->subwiki->id;
331             $params['title'] = $this->title;
332         } else {
333             print_error(get_string('invalidparameters', 'wiki'));
334         }
336         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/view.php', $params);
337     }
339     function set_coursemodule($id) {
340         $this->coursemodule = $id;
341     }
343     protected function create_navbar() {
344         global $PAGE, $CFG;
346         $PAGE->navbar->add(format_string($this->title));
347         $PAGE->navbar->add(get_string('view', 'wiki'));
348     }
351 /**
352  * Wiki page editing page
353  *
354  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
355  */
356 class page_wiki_edit extends page_wiki {
358     public static $attachmentoptions;
360     protected $sectioncontent;
361     /** @var string the section name needed to be edited */
362     protected $section;
363     protected $overridelock = false;
364     protected $versionnumber = -1;
365     protected $upload = false;
366     protected $attachments = 0;
367     protected $deleteuploads = array();
368     protected $format;
370     function __construct($wiki, $subwiki, $cm) {
371         global $CFG, $PAGE;
372         parent::__construct($wiki, $subwiki, $cm);
373         self::$attachmentoptions = array('subdirs' => false, 'maxfiles' => - 1, 'maxbytes' => $CFG->maxbytes, 'accepted_types' => '*');
374         $PAGE->requires->js_init_call('M.mod_wiki.renew_lock', null, true);
375         $PAGE->requires->yui2_lib('connection');
376     }
378     protected function print_pagetitle() {
379         global $OUTPUT;
381         $title = $this->title;
382         if (isset($this->section)) {
383             $title .= ' : ' . $this->section;
384         }
385         echo $OUTPUT->container_start('wiki_clear');
386         echo $OUTPUT->heading(format_string($title), 2, 'wiki_headingtitle');
387         echo $OUTPUT->container_end();
388     }
390     function print_header() {
391         global $OUTPUT, $PAGE;
392         $PAGE->requires->data_for_js('wiki', array('renew_lock_timeout' => LOCK_TIMEOUT - 5, 'pageid' => $this->page->id, 'section' => $this->section));
394         parent::print_header();
396         $this->print_pagetitle();
398         print '<noscript>' . $OUTPUT->box(get_string('javascriptdisabledlocks', 'wiki'), 'errorbox') . '</noscript>';
399     }
401     function print_content() {
402         global $PAGE;
404         if (wiki_user_can_edit($this->subwiki)) {
405             $this->print_edit();
406         } else {
407             // @TODO: Translate it
408             echo "You can not edit this page";
409         }
410     }
412     protected function set_url() {
413         global $PAGE, $CFG;
415         $params = array('pageid' => $this->page->id);
417         if (isset($this->section)) {
418             $params['section'] = $this->section;
419         }
421         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/edit.php', $params);
422     }
424     protected function set_session_url() {
425         global $SESSION;
427         $SESSION->wikipreviousurl = array('page' => 'edit', 'params' => array('pageid' => $this->page->id, 'section' => $this->section));
428     }
430     protected function process_session_url() {
431     }
433     function set_section($sectioncontent, $section) {
434         $this->sectioncontent = $sectioncontent;
435         $this->section = $section;
436     }
438     public function set_versionnumber($versionnumber) {
439         $this->versionnumber = $versionnumber;
440     }
442     public function set_overridelock($override) {
443         $this->overridelock = $override;
444     }
446     function set_format($format) {
447         $this->format = $format;
448     }
450     public function set_upload($upload) {
451         $this->upload = $upload;
452     }
454     public function set_attachments($attachments) {
455         $this->attachments = $attachments;
456     }
458     public function set_deleteuploads($deleteuploads) {
459         $this->deleteuploads = $deleteuploads;
460     }
462     protected function create_navbar() {
463         global $PAGE, $CFG;
465         parent::create_navbar();
467         $PAGE->navbar->add(get_string('edit', 'wiki'));
468     }
470     protected function check_locks() {
471         global $OUTPUT, $USER, $CFG;
473         if (!wiki_set_lock($this->page->id, $USER->id, $this->section, true)) {
474             print $OUTPUT->box(get_string('pageislocked', 'wiki'), 'generalbox boxwidthnormal boxaligncenter');
476             if ($this->overridelock) {
477                 $params = 'pageid=' . $this->page->id;
479                 if ($this->section) {
480                     $params .= '&section=' . urlencode($this->section);
481                 }
483                 $form = '<form method="post" action="' . $CFG->wwwroot . '/mod/wiki/overridelocks.php?' . $params . '">';
484                 $form .= '<input type="hidden" name="sesskey" value="' . sesskey() . '" />';
485                 $form .= '<input type="submit" value="' . get_string('overridelocks', 'wiki') . '" />';
486                 $form .= '</form>';
488                 print $OUTPUT->box($form, 'generalbox boxwidthnormal boxaligncenter');
489             }
490             return false;
491         }
492         return true;
493     }
495     protected function print_edit($content = null) {
496         global $CFG, $OUTPUT, $USER, $PAGE;
498         if (!$this->check_locks()) {
499             return;
500         }
502         //delete old locks (> 1 hour)
503         wiki_delete_old_locks();
505         $version = wiki_get_current_version($this->page->id);
506         $format = $version->contentformat;
508         if ($content == null) {
509             if (empty($this->section)) {
510                 $content = $version->content;
511             } else {
512                 $content = $this->sectioncontent;
513             }
514         }
516         $versionnumber = $version->version;
517         if ($this->versionnumber >= 0) {
518             if ($version->version != $this->versionnumber) {
519                 print $OUTPUT->box(get_string('wrongversionlock', 'wiki'), 'errorbox');
520                 $versionnumber = $this->versionnumber;
521             }
522         }
524         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
525         if (!empty($this->section)) {
526             $url .= "&section=" . urlencode($this->section);
527         }
529         $params = array('attachmentoptions' => page_wiki_edit::$attachmentoptions, 'format' => $version->contentformat, 'version' => $versionnumber, 'pagetitle'=>$this->page->title);
531         $data = new StdClass();
532         $data->newcontent = $content;
533         $data->version = $versionnumber;
534         $data->format = $format;
536         switch ($format) {
537         case 'html':
538             $data->newcontentformat = FORMAT_HTML;
539             // Append editor context to editor options, giving preference to existing context.
540             page_wiki_edit::$attachmentoptions = array_merge(array('context' => $this->modcontext), page_wiki_edit::$attachmentoptions);
541             $data = file_prepare_standard_editor($data, 'newcontent', page_wiki_edit::$attachmentoptions, $this->modcontext, 'mod_wiki', 'attachments', $this->subwiki->id);
542             break;
543         default:
544             break;
545             }
547         if ($version->contentformat != 'html') {
548             $params['fileitemid'] = $this->subwiki->id;
549             $params['contextid']  = $this->modcontext->id;
550             $params['component']  = 'mod_wiki';
551             $params['filearea']   = 'attachments';
552         }
554         if (!empty($CFG->usetags)) {
555             $params['tags'] = tag_get_tags_csv('wiki_pages', $this->page->id, TAG_RETURN_TEXT);
556         }
558         $form = new mod_wiki_edit_form($url, $params);
560         if ($formdata = $form->get_data()) {
561             if (!empty($CFG->usetags)) {
562                 $data->tags = $formdata->tags;
563             }
564         } else {
565             if (!empty($CFG->usetags)) {
566                 $data->tags = tag_get_tags_array('wiki', $this->page->id);
567             }
568         }
570         $form->set_data($data);
571         $form->display();
572     }
576 /**
577  * Class that models the behavior of wiki's view comments page
578  *
579  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
580  */
581 class page_wiki_comments extends page_wiki {
583     function print_header() {
585         parent::print_header();
587         $this->print_pagetitle();
589     }
591     function print_content() {
592         global $CFG, $OUTPUT, $USER, $PAGE;
593         require_once($CFG->dirroot . '/mod/wiki/locallib.php');
595         $page = $this->page;
596         $subwiki = $this->subwiki;
597         $wiki = $PAGE->activityrecord;
598         list($context, $course, $cm) = get_context_info_array($this->modcontext->id);
600         require_capability('mod/wiki:viewcomment', $this->modcontext, NULL, true, 'noviewcommentpermission', 'wiki');
602         $comments = wiki_get_comments($this->modcontext->id, $page->id);
604         if (has_capability('mod/wiki:editcomment', $this->modcontext)) {
605             echo '<div class="midpad"><a href="' . $CFG->wwwroot . '/mod/wiki/editcomments.php?action=add&amp;pageid=' . $page->id . '">' . get_string('addcomment', 'wiki') . '</a></div>';
606         }
608         $options = array('swid' => $this->page->subwikiid, 'pageid' => $page->id);
609         $version = wiki_get_current_version($this->page->id);
610         $format = $version->contentformat;
612         if (empty($comments)) {
613             echo $OUTPUT->heading(get_string('nocomments', 'wiki'));
614         }
616         foreach ($comments as $comment) {
618             $user = wiki_get_user_info($comment->userid);
620             $fullname = fullname($user, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
621             $by = new stdclass();
622             $by->name = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $user->id . '&amp;course=' . $course->id . '">' . $fullname . '</a>';
623             $by->date = userdate($comment->timecreated);
625             $t = new html_table();
626             $cell1 = new html_table_cell($OUTPUT->user_picture($user, array('popup' => true)));
627             $cell2 = new html_table_cell(get_string('bynameondate', 'forum', $by));
628             $cell3 = new html_table_cell();
629             $cell3->atributtes ['width'] = "80%";
630             $cell4 = new html_table_cell();
631             $cell5 = new html_table_cell();
633             $row1 = new html_table_row();
634             $row1->cells[] = $cell1;
635             $row1->cells[] = $cell2;
636             $row2 = new html_table_row();
637             $row2->cells[] = $cell3;
639             if ($format != 'html') {
640                 if ($format == 'creole') {
641                     $parsedcontent = wiki_parse_content('creole', $comment->content, $options);
642                 } else if ($format == 'nwiki') {
643                     $parsedcontent = wiki_parse_content('nwiki', $comment->content, $options);
644                 }
646                 $cell4->text = format_text(html_entity_decode($parsedcontent['parsed_text']), FORMAT_HTML);
647             } else {
648                 $cell4->text = format_text($comment->content, FORMAT_HTML);
649             }
651             $row2->cells[] = $cell4;
653             $t->data = array($row1, $row2);
655             $actionicons = false;
656             if ((has_capability('mod/wiki:managecomment', $this->modcontext))) {
657                 $urledit = new moodle_url('/mod/wiki/editcomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'edit'));
658                 $urldelet = new moodle_url('/mod/wiki/instancecomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'delete'));
659                 $actionicons = true;
660             } else if ((has_capability('mod/wiki:editcomment', $this->modcontext)) and ($USER->id == $user->id)) {
661                 $urledit = new moodle_url('/mod/wiki/editcomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'edit'));
662                 $urldelet = new moodle_url('/mod/wiki/instancecomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'delete'));
663                 $actionicons = true;
664             }
666             if ($actionicons) {
667                 $cell6 = new html_table_cell($OUTPUT->action_icon($urledit, new pix_icon('t/edit', get_string('edit'))) . $OUTPUT->action_icon($urldelet, new pix_icon('t/delete', get_string('delete'))));
668                 $row3 = new html_table_row();
669                 $row3->cells[] = $cell5;
670                 $row3->cells[] = $cell6;
671                 $t->data[] = $row3;
672             }
674             echo html_writer::tag('div', html_writer::table($t), array('class'=>'no-overflow'));
676         }
677     }
679     function set_url() {
680         global $PAGE, $CFG;
681         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
682     }
684     protected function create_navbar() {
685         global $PAGE, $CFG;
687         parent::create_navbar();
688         $PAGE->navbar->add(get_string('comments', 'wiki'));
689     }
693 /**
694  * Class that models the behavior of wiki's edit comment
695  *
696  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
697  */
698 class page_wiki_editcomment extends page_wiki {
699     private $comment;
700     private $action;
701     private $form;
702     private $format;
704     function set_url() {
705         global $PAGE, $CFG;
706         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
707     }
709     function print_header() {
710         parent::print_header();
711         $this->print_pagetitle();
712     }
714     function print_content() {
715         global $PAGE;
717         require_capability('mod/wiki:editcomment', $this->modcontext, NULL, true, 'noeditcommentpermission', 'wiki');
719         if ($this->action == 'add') {
720             $this->add_comment_form();
721         } else if ($this->action == 'edit') {
722             $this->edit_comment_form($this->comment);
723         }
724     }
726     function set_action($action, $comment) {
727         global $CFG;
728         require_once($CFG->dirroot . '/mod/wiki/comments_form.php');
730         $this->action = $action;
731         $this->comment = $comment;
732         $version = wiki_get_current_version($this->page->id);
733         $this->format = $version->contentformat;
735         if ($this->format == 'html') {
736             $destination = $CFG->wwwroot . '/mod/wiki/instancecomments.php?pageid=' . $this->page->id;
737             $this->form = new mod_wiki_comments_form($destination);
738         }
739     }
741     protected function create_navbar() {
742         global $PAGE, $CFG;
744         $PAGE->navbar->add(get_string('comments', 'wiki'), $CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $this->page->id);
746         if ($this->action == 'add') {
747             $PAGE->navbar->add(get_string('insertcomment', 'wiki'));
748         } else {
749             $PAGE->navbar->add(get_string('editcomment', 'wiki'));
750         }
751     }
753     protected function setup_tabs() {
754         parent::setup_tabs(array('linkedwhenactive' => 'comments', 'activetab' => 'comments'));
755     }
757     private function add_comment_form() {
758         global $CFG;
759         require_once($CFG->dirroot . '/mod/wiki/editors/wiki_editor.php');
761         $pageid = $this->page->id;
763         if ($this->format == 'html') {
764             $com = new stdClass();
765             $com->action = 'add';
766             $com->commentoptions = array('trusttext' => true, 'maxfiles' => 0);
767             $this->form->set_data($com);
768             $this->form->display();
769         } else {
770             wiki_print_editor_wiki($this->page->id, null, $this->format, -1, null, false, null, 'addcomments');
771         }
772     }
774     private function edit_comment_form($com) {
775         global $CFG;
776         require_once($CFG->dirroot . '/mod/wiki/comments_form.php');
777         require_once($CFG->dirroot . '/mod/wiki/editors/wiki_editor.php');
779         if ($this->format == 'html') {
780             $com->action = 'edit';
781             $com->entrycomment_editor['text'] = $com->content;
782             $com->commentoptions = array('trusttext' => true, 'maxfiles' => 0);
784             $this->form->set_data($com);
785             $this->form->display();
786         } else {
787             wiki_print_editor_wiki($this->page->id, $com->content, $this->format, -1, null, false, array(), 'editcomments', $com->id);
788         }
790     }
794 /**
795  * Wiki page search page
796  *
797  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
798  */
799 class page_wiki_search extends page_wiki {
800     private $search_result;
802     protected function create_navbar() {
803         global $PAGE, $CFG;
805         $PAGE->navbar->add(format_string($this->title));
806     }
808     function set_search_string($search, $searchcontent) {
809         $swid = $this->subwiki->id;
810         if ($searchcontent) {
811             $this->search_result = wiki_search_all($swid, $search);
812         } else {
813             $this->search_result = wiki_search_title($swid, $search);
814         }
816     }
818     function set_url() {
819         global $PAGE, $CFG;
820         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/search.php');
821     }
822     function print_content() {
823         global $PAGE;
825         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
827         echo $this->wikioutput->search_result($this->search_result, $this->subwiki);
828     }
831 /**
832  *
833  * Class that models the behavior of wiki's
834  * create page
835  *
836  */
837 class page_wiki_create extends page_wiki {
839     private $format;
840     private $swid;
841     private $wid;
842     private $action;
843     private $mform;
845     function print_header() {
846         $this->set_url();
847         parent::print_header();
848     }
850     function set_url() {
851         global $PAGE, $CFG;
853         $params = array();
854         if ($this->action == 'new') {
855             $params['action'] = 'new';
856             $params['swid'] = $this->swid;
857             $params['wid'] = $this->wid;
858             if ($this->title != get_string('newpage', 'wiki')) {
859                 $params['title'] = $this->title;
860             }
861             $PAGE->set_url($CFG->wwwroot . '/mod/wiki/create.php', $params);
862         } else {
863             $params['action'] = 'create';
864             $params['swid'] = $this->swid;
865             $PAGE->set_url($CFG->wwwroot . '/mod/wiki/create.php', $params);
866         }
867     }
869     function set_format($format) {
870         $this->format = $format;
871     }
873     function set_wid($wid) {
874         $this->wid = $wid;
875     }
877     function set_swid($swid) {
878         $this->swid = $swid;
879     }
881     function set_action($action) {
882         global $PAGE;
883         $this->action = $action;
885         require_once(dirname(__FILE__) . '/create_form.php');
886         $url = new moodle_url('/mod/wiki/create.php', array('action' => 'create', 'wid' => $PAGE->activityrecord->id, 'gid' => $this->gid, 'uid' => $this->uid));
887         $formats = wiki_get_formats();
888         $options = array('formats' => $formats, 'defaultformat' => $PAGE->activityrecord->defaultformat, 'forceformat' => $PAGE->activityrecord->forceformat);
889         if ($this->title != get_string('newpage', 'wiki')) {
890             $options['disable_pagetitle'] = true;
891         }
892         $this->mform = new mod_wiki_create_form($url->out(false), $options);
893     }
895     protected function create_navbar() {
896         global $PAGE;
898         $PAGE->navbar->add($this->title);
899     }
901     function print_content($pagetitle = '') {
902         global $PAGE;
904         // @TODO: Change this to has_capability and show an alternative interface.
905         require_capability('mod/wiki:createpage', $this->modcontext, NULL, true, 'nocreatepermission', 'wiki');
906         $data = new stdClass();
907         if (!empty($pagetitle)) {
908             $data->pagetitle = $pagetitle;
909         }
910         $data->pageformat = $PAGE->activityrecord->defaultformat;
912         $this->mform->set_data($data);
913         $this->mform->display();
914     }
916     function create_page($pagetitle) {
917         global $USER, $CFG, $PAGE;
918         $data = $this->mform->get_data();
919         if (empty($this->subwiki)) {
920             $swid = wiki_add_subwiki($PAGE->activityrecord->id, $this->gid, $this->uid);
921             $this->subwiki = wiki_get_subwiki($swid);
922         }
923         if ($data) {
924             $id = wiki_create_page($this->subwiki->id, $data->pagetitle, $data->pageformat, $USER->id);
925         } else {
926             $id = wiki_create_page($this->subwiki->id, $pagetitle, $PAGE->activityrecord->defaultformat, $USER->id);
927         }
928         redirect($CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $id);
929     }
932 class page_wiki_preview extends page_wiki_edit {
934     private $newcontent;
936     function __construct($wiki, $subwiki, $cm) {
937         global $PAGE, $CFG, $OUTPUT;
938         parent::__construct($wiki, $subwiki, $cm);
939         $buttons = $OUTPUT->update_module_button($cm->id, 'wiki');
940         $PAGE->set_button($buttons);
942     }
944     function print_header() {
945         global $PAGE, $CFG;
947         parent::print_header();
949     }
951     function print_content() {
952         global $PAGE;
954         require_capability('mod/wiki:editpage', $this->modcontext, NULL, true, 'noeditpermission', 'wiki');
956         $this->print_preview();
957     }
959     function set_newcontent($newcontent) {
960         $this->newcontent = $newcontent;
961     }
963     function set_url() {
964         global $PAGE, $CFG;
966         $params = array('pageid' => $this->page->id
967         );
969         if (isset($this->section)) {
970             $params['section'] = $this->section;
971         }
973         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/edit.php', $params);
974     }
976     protected function setup_tabs() {
977         parent::setup_tabs(array('linkedwhenactive' => 'view', 'activetab' => 'view'));
978     }
980     protected function check_locks() {
981         return true;
982     }
984     protected function print_preview() {
985         global $CFG, $PAGE, $OUTPUT;
987         $version = wiki_get_current_version($this->page->id);
988         $format = $version->contentformat;
989         $content = $version->content;
991         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
992         if (!empty($this->section)) {
993             $url .= "&section=" . urlencode($this->section);
994         }
995         $params = array('attachmentoptions' => page_wiki_edit::$attachmentoptions, 'format' => $this->format, 'version' => $this->versionnumber);
997         if ($this->format != 'html') {
998             $params['contextid'] = $this->modcontext->id;
999             $params['component'] = 'mod_wiki';
1000             $params['filearea'] = 'attachments';
1001             $params['fileitemid'] = $this->page->id;
1002         }
1003         $form = new mod_wiki_edit_form($url, $params);
1006         $options = array('swid' => $this->page->subwikiid, 'pageid' => $this->page->id, 'pretty_print' => true);
1008         if ($data = $form->get_data()) {
1009             if (isset($data->newcontent)) {
1010                 // wiki fromat
1011                 $text = $data->newcontent;
1012             } else {
1013                 // html format
1014                 $text = $data->newcontent_editor['text'];
1015             }
1016             $parseroutput = wiki_parse_content($data->contentformat, $text, $options);
1017             $this->set_newcontent($text);
1018             echo $OUTPUT->notification(get_string('previewwarning', 'wiki'), 'notifyproblem wiki_info');
1019             $content = format_text($parseroutput['parsed_text'], FORMAT_HTML, array('overflowdiv'=>true, 'filter'=>false));
1020             echo $OUTPUT->box($content, 'generalbox wiki_previewbox');
1021             $content = $this->newcontent;
1022         }
1024         $this->print_edit($content);
1025     }
1029 /**
1030  *
1031  * Class that models the behavior of wiki's
1032  * view differences
1033  *
1034  */
1035 class page_wiki_diff extends page_wiki {
1037     private $compare;
1038     private $comparewith;
1040     function print_header() {
1041         global $OUTPUT;
1043         parent::print_header();
1045         $this->print_pagetitle();
1046         $vstring = new stdClass();
1047         $vstring->old = $this->compare;
1048         $vstring->new = $this->comparewith;
1049         echo $OUTPUT->heading(get_string('comparewith', 'wiki', $vstring));
1050     }
1052     /**
1053      * Print the diff view
1054      */
1055     function print_content() {
1056         global $PAGE;
1058         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1060         $this->print_diff_content();
1061     }
1063     function set_url() {
1064         global $PAGE, $CFG;
1066         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/diff.php', array('pageid' => $this->page->id, 'comparewith' => $this->comparewith, 'compare' => $this->compare));
1067     }
1069     function set_comparison($compare, $comparewith) {
1070         $this->compare = $compare;
1071         $this->comparewith = $comparewith;
1072     }
1074     protected function create_navbar() {
1075         global $PAGE, $CFG;
1077         parent::create_navbar();
1078         $PAGE->navbar->add(get_string('history', 'wiki'), $CFG->wwwroot . '/mod/wiki/history.php?pageid' . $this->page->id);
1079         $PAGE->navbar->add(get_string('diff', 'wiki'));
1080     }
1082     protected function setup_tabs() {
1083         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history'));
1084     }
1086     /**
1087      * Given two versions of a page, prints a page displaying the differences between them.
1088      *
1089      * @global object $CFG
1090      * @global object $OUTPUT
1091      * @global object $PAGE
1092      */
1093     private function print_diff_content() {
1094         global $CFG, $OUTPUT, $PAGE;
1096         $pageid = $this->page->id;
1097         $total = wiki_count_wiki_page_versions($pageid) - 1;
1099         $oldversion = wiki_get_wiki_page_version($pageid, $this->compare);
1101         $newversion = wiki_get_wiki_page_version($pageid, $this->comparewith);
1103         if ($oldversion && $newversion) {
1105             $oldtext = format_text(file_rewrite_pluginfile_urls($oldversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id));
1106             $newtext = format_text(file_rewrite_pluginfile_urls($newversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id));
1107             list($diff1, $diff2) = ouwiki_diff_html($oldtext, $newtext);
1108             $oldversion->diff = $diff1;
1109             $oldversion->user = wiki_get_user_info($oldversion->userid);
1110             $newversion->diff = $diff2;
1111             $newversion->user = wiki_get_user_info($newversion->userid);
1113             echo $this->wikioutput->diff($pageid, $oldversion, $newversion, array('total' => $total));
1114         } else {
1115             print_error('versionerror', 'wiki');
1116         }
1117     }
1120 /**
1121  *
1122  * Class that models the behavior of wiki's history page
1123  *
1124  */
1125 class page_wiki_history extends page_wiki {
1126     /**
1127      * @var int $paging current page
1128      */
1129     private $paging;
1131     /**
1132      * @var int @rowsperpage Items per page
1133      */
1134     private $rowsperpage = 10;
1136     /**
1137      * @var int $allversion if $allversion != 0, all versions will be printed in a signle table
1138      */
1139     private $allversion;
1141     function __construct($wiki, $subwiki, $cm) {
1142         global $PAGE;
1143         parent::__construct($wiki, $subwiki, $cm);
1144         $PAGE->requires->js_init_call('M.mod_wiki.history', null, true);
1145     }
1147     function print_header() {
1148         parent::print_header();
1149         $this->print_pagetitle();
1150     }
1152     function print_pagetitle() {
1153         global $OUTPUT;
1154         $html = '';
1156         $html .= $OUTPUT->container_start();
1157         $html .= $OUTPUT->heading_with_help(format_string($this->title), 'history', 'wiki');
1158         $html .= $OUTPUT->container_end();
1159         echo $html;
1160     }
1162     function print_content() {
1163         global $PAGE;
1165         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1167         $this->print_history_content();
1168     }
1170     function set_url() {
1171         global $PAGE, $CFG;
1172         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/history.php', array('pageid' => $this->page->id));
1173     }
1175     function set_paging($paging) {
1176         $this->paging = $paging;
1177     }
1179     function set_allversion($allversion) {
1180         $this->allversion = $allversion;
1181     }
1183     protected function create_navbar() {
1184         global $PAGE, $CFG;
1186         parent::create_navbar();
1187         $PAGE->navbar->add(get_string('history', 'wiki'));
1188     }
1190     /**
1191      * Prints the history for a given wiki page
1192      *
1193      * @global object $CFG
1194      * @global object $OUTPUT
1195      * @global object $PAGE
1196      */
1197     private function print_history_content() {
1198         global $CFG, $OUTPUT, $PAGE;
1200         $pageid = $this->page->id;
1201         $offset = $this->paging * $this->rowsperpage;
1202         // vcount is the latest version
1203         $vcount = wiki_count_wiki_page_versions($pageid) - 1;
1204         if ($this->allversion) {
1205             $versions = wiki_get_wiki_page_versions($pageid, 0, $vcount);
1206         } else {
1207             $versions = wiki_get_wiki_page_versions($pageid, $offset, $this->rowsperpage);
1208         }
1209         // We don't want version 0 to be displayed
1210         // version 0 is blank page
1211         if (end($versions)->version == 0) {
1212             array_pop($versions);
1213         }
1215         $contents = array();
1217         $version0page = wiki_get_wiki_page_version($this->page->id, 0);
1218         $creator = wiki_get_user_info($version0page->userid);
1219         $a = new StdClass;
1220         $a->date = userdate($this->page->timecreated, get_string('strftimedaydatetime', 'langconfig'));
1221         $a->username = $creator->username;
1222         echo $OUTPUT->heading(get_string('createddate', 'wiki', $a), 4, 'wiki_headingtime');
1223         if ($vcount > 0) {
1225             /// If there is only one version, we don't need radios nor forms
1226             if (count($versions) == 1) {
1228                 $row = array_shift($versions);
1230                 $username = wiki_get_user_info($row->userid);
1231                 $picture = $OUTPUT->user_picture($username);
1232                 $date = userdate($row->timecreated, get_string('strftimedate', 'langconfig'));
1233                 $time = userdate($row->timecreated, get_string('strftimetime', 'langconfig'));
1234                 $versionid = wiki_get_version($row->id);
1235                 $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
1236                 $userlink = new moodle_url('/user/view.php', array('id' => $username->id));
1237                 $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'));
1239                 $table = new html_table();
1240                 $table->head = array('', get_string('version'), get_string('user'), get_string('modified'), '');
1241                 $table->data = $contents;
1242                 $table->attributes['class'] = 'mdl-align';
1244                 echo html_writer::table($table);
1246             } else {
1248                 $checked = $vcount - $offset;
1249                 $lastdate = '';
1250                 $rowclass = array();
1252                 foreach ($versions as $version) {
1253                     $user = wiki_get_user_info($version->userid);
1254                     $picture = $OUTPUT->user_picture($user, array('popup' => true));
1255                     $date = userdate($version->timecreated, get_string('strftimedate'));
1256                     if ($date == $lastdate) {
1257                         $date = '';
1258                         $rowclass[] = '';
1259                     } else {
1260                         $lastdate = $date;
1261                         $rowclass[] = 'wiki_histnewdate';
1262                     }
1263                     $time = userdate($version->timecreated, get_string('strftimetime', 'langconfig'));
1264                     $versionid = wiki_get_version($version->id);
1265                     if ($versionid) {
1266                         $url = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
1267                         $viewlink = html_writer::link($url->out(false), $version->version);
1268                     } else {
1269                         $viewlink = $version->version;
1270                     }
1271                     $userlink = new moodle_url('/user/view.php', array('id' => $version->userid));
1272                     $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'));
1273                 }
1275                 $table = new html_table();
1277                 $icon = $OUTPUT->help_icon('diff', 'wiki');
1279                 $table->head = array(get_string('diff', 'wiki') . $icon, get_string('version'), get_string('user'), get_string('modified'), '');
1280                 $table->data = $contents;
1281                 $table->attributes['class'] = 'generaltable mdl-align';
1282                 $table->rowclasses = $rowclass;
1284                 /*$table = new StdClass();
1285                  $table->head = array(helpbutton('diff', 'diff', 'wiki', true, false, '', true, ''),
1286                  get_string('version'),
1287                  get_string('user'),
1288                  get_string('modified'),
1289                  '');
1290                  $table->data = $contents;
1291                  $table->class = 'mdl-align';
1292                  $table->rowclass = $rowclass;*/
1294                 ///Print the form
1295                 echo html_writer::start_tag('form', array('action'=>new moodle_url('/mod/wiki/diff.php'), 'method'=>'get', 'id'=>'diff'));
1296                 echo html_writer::tag('div', html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'pageid', 'value'=>$pageid)));
1297                 echo html_writer::table($table);
1298                 echo html_writer::start_tag('div', array('class'=>'mdl-align'));
1299                 echo html_writer::empty_tag('input', array('type'=>'submit', 'class'=>'wiki_form-button', 'value'=>get_string('comparesel', 'wiki')));
1300                 echo html_writer::end_tag('div');
1301                 echo html_writer::end_tag('form');
1302             }
1303         } else {
1304             print_string('nohistory', 'wiki');
1305         }
1306         if (!$this->allversion) {
1307             //$pagingbar = moodle_paging_bar::make($vcount, $this->paging, $this->rowsperpage, $CFG->wwwroot.'/mod/wiki/history.php?pageid='.$pageid.'&amp;');
1308             // $pagingbar->pagevar = $pagevar;
1309             echo $OUTPUT->paging_bar($vcount, $this->paging, $this->rowsperpage, $CFG->wwwroot . '/mod/wiki/history.php?pageid=' . $pageid . '&amp;');
1310             //print_paging_bar($vcount, $paging, $rowsperpage,$CFG->wwwroot.'/mod/wiki/history.php?pageid='.$pageid.'&amp;','paging');
1311             } else {
1312             $link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid));
1313             $OUTPUT->container(html_writer::link($link->out(false), get_string('viewperpage', 'wiki', $this->rowsperpage)), 'mdl-align');
1314         }
1315         if ($vcount > $this->rowsperpage && !$this->allversion) {
1316             $link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid, 'allversion' => 1));
1317             $OUTPUT->container(html_writer::link($link->out(false), get_string('viewallhistory', 'wiki')), 'mdl-align');
1318         }
1319     }
1321     /**
1322      * Given an array of values, creates a group of radio buttons to be part of a form
1323      *
1324      * @param array  $options  An array of value-label pairs for the radio group (values as keys).
1325      * @param string $name     Name of the radiogroup (unique in the form).
1326      * @param string $onclick  Function to be executed when the radios are clicked.
1327      * @param string $checked  The value that is already checked.
1328      * @param bool   $return   If true, return the HTML as a string, otherwise print it.
1329      *
1330      * @return mixed If $return is false, returns nothing, otherwise returns a string of HTML.
1331      */
1332     private function choose_from_radio($options, $name, $onclick = '', $checked = '', $return = false) {
1334         static $idcounter = 0;
1336         if (!$name) {
1337             $name = 'unnamed';
1338         }
1340         $output = '<span class="radiogroup ' . $name . "\">\n";
1342         if (!empty($options)) {
1343             $currentradio = 0;
1344             foreach ($options as $value => $label) {
1345                 $htmlid = 'auto-rb' . sprintf('%04d', ++$idcounter);
1346                 $output .= ' <span class="radioelement ' . $name . ' rb' . $currentradio . "\">";
1347                 $output .= '<input name="' . $name . '" id="' . $htmlid . '" type="radio" value="' . $value . '"';
1348                 if ($value == $checked) {
1349                     $output .= ' checked="checked"';
1350                 }
1351                 if ($onclick) {
1352                     $output .= ' onclick="' . $onclick . '"';
1353                 }
1354                 if ($label === '') {
1355                     $output .= ' /> <label for="' . $htmlid . '">' . $value . '</label></span>' . "\n";
1356                 } else {
1357                     $output .= ' /> <label for="' . $htmlid . '">' . $label . '</label></span>' . "\n";
1358                 }
1359                 $currentradio = ($currentradio + 1) % 2;
1360             }
1361         }
1363         $output .= '</span>' . "\n";
1365         if ($return) {
1366             return $output;
1367         } else {
1368             echo $output;
1369         }
1370     }
1373 /**
1374  * Class that models the behavior of wiki's map page
1375  *
1376  */
1377 class page_wiki_map extends page_wiki {
1379     /**
1380      * @var int wiki view option
1381      */
1382     private $view;
1384     function print_header() {
1385         parent::print_header();
1386         $this->print_pagetitle();
1387     }
1389     function print_content() {
1390         global $CFG, $PAGE;
1392         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1394         if ($this->view > 0) {
1395             //echo '<div><a href="' . $CFG->wwwroot . '/mod/wiki/map.php?pageid=' . $this->page->id . '">' . get_string('backtomapmenu', 'wiki') . '</a></div>';
1396         }
1398         switch ($this->view) {
1399         case 1:
1400             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1401             $this->print_contributions_content();
1402             break;
1403         case 2:
1404             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1405             $this->print_navigation_content();
1406             break;
1407         case 3:
1408             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1409             $this->print_orphaned_content();
1410             break;
1411         case 4:
1412             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1413             $this->print_index_content();
1414             break;
1415         case 5:
1416             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1417             $this->print_page_list_content();
1418             break;
1419         case 6:
1420             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1421             $this->print_updated_content();
1422             break;
1423         default:
1424             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1425             $this->print_page_list_content();
1426         }
1427     }
1429     function set_view($option) {
1430         $this->view = $option;
1431     }
1433     function set_url() {
1434         global $PAGE, $CFG;
1435         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/map.php', array('pageid' => $this->page->id));
1436     }
1438     protected function create_navbar() {
1439         global $PAGE;
1441         parent::create_navbar();
1442         $PAGE->navbar->add(get_string('map', 'wiki'));
1443     }
1445     /**
1446      * Prints the contributions tab content
1447      *
1448      * @uses $OUTPUT, $USER
1449      *
1450      */
1451     private function print_contributions_content() {
1452         global $CFG, $OUTPUT, $USER;
1453         $page = $this->page;
1455         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1456             $fresh = wiki_refresh_cachedcontent($page);
1457             $page = $fresh['page'];
1458         }
1460         $swid = $this->subwiki->id;
1462         $table = new html_table();
1463         $table->head = array(get_string('contributions', 'wiki') . $OUTPUT->help_icon('contributions', 'wiki'));
1464         $table->attributes['class'] = 'wiki_editor generalbox';
1465         $table->data = array();
1466         $table->rowclasses = array();
1468         $lastversions = array();
1469         $pages = array();
1470         $users = array();
1472         if ($contribs = wiki_get_contributions($swid, $USER->id)) {
1473             foreach ($contribs as $contrib) {
1474                 if (!array_key_exists($contrib->pageid, $pages)) {
1475                     $page = wiki_get_page($contrib->pageid);
1476                     $pages[$contrib->pageid] = $page;
1477                 } else {
1478                     continue;
1479                 }
1481                 if (!array_key_exists($page->id, $lastversions)) {
1482                     $version = wiki_get_last_version($page->id);
1483                     $lastversions[$page->id] = $version;
1484                 } else {
1485                     $version = $lastversions[$page->id];
1486                 }
1488                 if (!array_key_exists($version->userid, $users)) {
1489                     $user = wiki_get_user_info($version->userid);
1490                     $users[$version->userid] = $user;
1491                 } else {
1492                     $user = $users[$version->userid];
1493                 }
1495                 $link = wiki_parser_link(format_string($page->title), array('swid' => $swid));
1496                 $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1498                 $linkpage = '<a href="' . $link['url'] . '"' . $class . '>' . $link['content'] . '</a>';
1499                 $icon = $OUTPUT->user_picture($user, array('popup' => true));
1501                 $table->data[] = array("$icon&nbsp;$linkpage");
1502             }
1503         } else {
1504             $table->data[] = array(get_string('nocontribs', 'wiki'));
1505         }
1506         echo html_writer::table($table);
1507     }
1509     /**
1510      * Prints the navigation tab content
1511      *
1512      * @uses $OUTPUT
1513      *
1514      */
1515     private function print_navigation_content() {
1516         global $OUTPUT;
1517         $page = $this->page;
1519         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1520             $fresh = wiki_refresh_cachedcontent($page);
1521             $page = $fresh['page'];
1522         }
1524         $tolinks = wiki_get_linked_to_pages($page->id);
1525         $fromlinks = wiki_get_linked_from_pages($page->id);
1527         $table = new html_table();
1528         $table->attributes['class'] = 'wiki_navigation_from';
1529         $table->head = array(get_string('navigationfrom', 'wiki') . $OUTPUT->help_icon('navigationfrom', 'wiki') . ':');
1530         $table->data = array();
1531         $table->rowclasses = array();
1532         foreach ($fromlinks as $link) {
1533             $lpage = wiki_get_page($link->frompageid);
1534             $link = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
1535             $table->data[] = array(html_writer::link($link->out(false), format_string($lpage->title)));
1536             $table->rowclasses[] = 'mdl-align';
1537         }
1539         $table_left = html_writer::table($table);
1541         $table = new html_table();
1542         $table->attributes['class'] = 'wiki_navigation_to';
1543         $table->head = array(get_string('navigationto', 'wiki') . $OUTPUT->help_icon('navigationto', 'wiki') . ':');
1544         $table->data = array();
1545         $table->rowclasses = array();
1546         foreach ($tolinks as $link) {
1547             if ($link->tomissingpage) {
1548                 $viewlink = new moodle_url('/mod/wiki/create.php', array('swid' => $page->subwikiid, 'title' => $link->tomissingpage, 'action' => 'new'));
1549                 $table->data[] = array(html_writer::link($viewlink->out(false), format_string($link->tomissingpage), array('class' => 'wiki_newentry')));
1550             } else {
1551                 $lpage = wiki_get_page($link->topageid);
1552                 $viewlink = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
1553                 $table->data[] = array(html_writer::link($viewlink->out(false), format_string($lpage->title)));
1554             }
1555             $table->rowclasses[] = 'mdl-align';
1556         }
1557         $table_right = html_writer::table($table);
1558         echo $OUTPUT->container($table_left . $table_right, 'wiki_navigation_container');
1559     }
1561     /**
1562      * Prints the index page tab content
1563      *
1564      *
1565      */
1566     private function print_index_content() {
1567         global $OUTPUT;
1568         $page = $this->page;
1570         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1571             $fresh = wiki_refresh_cachedcontent($page);
1572             $page = $fresh['page'];
1573         }
1575         $node = new navigation_node($page->title);
1577         $keys = array();
1578         $tree = array();
1579         $tree = wiki_build_tree($page, $node, $keys);
1581         $table = new html_table();
1582         $table->head = array(get_string('pageindex', 'wiki') . $OUTPUT->help_icon('pageindex', 'wiki'));
1583         $table->attributes['class'] = 'wiki_editor generalbox';
1584         $table->data[] = array($this->render_navigation_node($tree));
1586         echo html_writer::table($table);
1587     }
1589     /**
1590      * Prints the page list tab content
1591      *
1592      *
1593      */
1594     private function print_page_list_content() {
1595         global $OUTPUT;
1596         $page = $this->page;
1598         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1599             $fresh = wiki_refresh_cachedcontent($page);
1600             $page = $fresh['page'];
1601         }
1603         $pages = wiki_get_page_list($this->subwiki->id);
1605         $stdaux = new stdClass();
1606         $strspecial = get_string('special', 'wiki');
1608         foreach ($pages as $page) {
1609             $letter = textlib::strtoupper(textlib::substr($page->title, 0, 1));
1610             if (preg_match('/[A-Z]/', $letter)) {
1611                 $stdaux->{
1612                     $letter}
1613                 [] = wiki_parser_link($page);
1614             } else {
1615                 $stdaux->{
1616                     $strspecial}
1617                 [] = wiki_parser_link($page);
1618             }
1619         }
1621         $table = new html_table();
1622         $table->head = array(get_string('pagelist', 'wiki') . $OUTPUT->help_icon('pagelist', 'wiki'));
1623         $table->attributes['class'] = 'wiki_editor generalbox';
1624         $table->align = array('center');
1625         foreach ($stdaux as $key => $elem) {
1626             $table->data[] = array($key);
1627             foreach ($elem as $e) {
1628                 $table->data[] = array(html_writer::link($e['url'], $e['content']));
1629             }
1630         }
1631         echo html_writer::table($table);
1632     }
1634     /**
1635      * Prints the orphaned tab content
1636      *
1637      *
1638      */
1639     private function print_orphaned_content() {
1640         global $OUTPUT;
1642         $page = $this->page;
1644         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1645             $fresh = wiki_refresh_cachedcontent($page);
1646             $page = $fresh['page'];
1647         }
1649         $swid = $this->subwiki->id;
1651         $table = new html_table();
1652         $table->head = array(get_string('orphaned', 'wiki') . $OUTPUT->help_icon('orphaned', 'wiki'));
1653         $table->attributes['class'] = 'wiki_editor generalbox';
1654         $table->data = array();
1655         $table->rowclasses = array();
1657         if ($orphanedpages = wiki_get_orphaned_pages($swid)) {
1658             foreach ($orphanedpages as $page) {
1659                 $link = wiki_parser_link($page->title, array('swid' => $swid));
1660                 $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1661                 $table->data[] = array('<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>');
1662             }
1663         } else {
1664             $table->data[] = array(get_string('noorphanedpages', 'wiki'));
1665         }
1667         echo html_writer::table($table);
1668     }
1670     /**
1671      * Prints the updated tab content
1672      *
1673      * @uses $COURSE, $OUTPUT
1674      *
1675      */
1676     private function print_updated_content() {
1677         global $COURSE, $OUTPUT;
1678         $page = $this->page;
1680         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1681             $fresh = wiki_refresh_cachedcontent($page);
1682             $page = $fresh['page'];
1683         }
1685         $swid = $this->subwiki->id;
1687         $table = new html_table();
1688         $table->head = array(get_string('updatedpages', 'wiki') . $OUTPUT->help_icon('updatedpages', 'wiki'));
1689         $table->attributes['class'] = 'wiki_editor generalbox';
1690         $table->data = array();
1691         $table->rowclasses = array();
1693         if ($pages = wiki_get_updated_pages_by_subwiki($swid)) {
1694             $strdataux = '';
1695             foreach ($pages as $page) {
1696                 $user = wiki_get_user_info($page->userid);
1697                 $strdata = strftime('%d %b %Y', $page->timemodified);
1698                 if ($strdata != $strdataux) {
1699                     $table->data[] = array($OUTPUT->heading($strdata, 4));
1700                     $strdataux = $strdata;
1701                 }
1702                 $link = wiki_parser_link($page->title, array('swid' => $swid));
1703                 $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1705                 $linkpage = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>';
1706                 $icon = $OUTPUT->user_picture($user, array($COURSE->id));
1707                 $table->data[] = array("$icon&nbsp;$linkpage");
1708             }
1709         } else {
1710             $table->data[] = array(get_string('noupdatedpages', 'wiki'));
1711         }
1713         echo html_writer::table($table);
1714     }
1716     protected function render_navigation_node($items, $attrs = array(), $expansionlimit = null, $depth = 1) {
1718         // exit if empty, we don't want an empty ul element
1719         if (count($items) == 0) {
1720             return '';
1721         }
1723         // array of nested li elements
1724         $lis = array();
1725         foreach ($items as $item) {
1726             if (!$item->display) {
1727                 continue;
1728             }
1729             $content = $item->get_content();
1730             $title = $item->get_title();
1731             if ($item->icon instanceof renderable) {
1732                 $icon = $this->wikioutput->render($item->icon);
1733                 $content = $icon . '&nbsp;' . $content; // use CSS for spacing of icons
1734                 }
1735             if ($item->helpbutton !== null) {
1736                 $content = trim($item->helpbutton) . html_writer::tag('span', $content, array('class' => 'clearhelpbutton'));
1737             }
1739             if ($content === '') {
1740                 continue;
1741             }
1743             if ($item->action instanceof action_link) {
1744                 //TODO: to be replaced with something else
1745                 $link = $item->action;
1746                 if ($item->hidden) {
1747                     $link->add_class('dimmed');
1748                 }
1749                 $content = $this->output->render($link);
1750             } else if ($item->action instanceof moodle_url) {
1751                 $attributes = array();
1752                 if ($title !== '') {
1753                     $attributes['title'] = $title;
1754                 }
1755                 if ($item->hidden) {
1756                     $attributes['class'] = 'dimmed_text';
1757                 }
1758                 $content = html_writer::link($item->action, $content, $attributes);
1760             } else if (is_string($item->action) || empty($item->action)) {
1761                 $attributes = array();
1762                 if ($title !== '') {
1763                     $attributes['title'] = $title;
1764                 }
1765                 if ($item->hidden) {
1766                     $attributes['class'] = 'dimmed_text';
1767                 }
1768                 $content = html_writer::tag('span', $content, $attributes);
1769             }
1771             // this applies to the li item which contains all child lists too
1772             $liclasses = array($item->get_css_type(), 'depth_' . $depth);
1773             if ($item->has_children() && (!$item->forceopen || $item->collapse)) {
1774                 $liclasses[] = 'collapsed';
1775             }
1776             if ($item->isactive === true) {
1777                 $liclasses[] = 'current_branch';
1778             }
1779             $liattr = array('class' => join(' ', $liclasses));
1780             // class attribute on the div item which only contains the item content
1781             $divclasses = array('tree_item');
1782             if ((empty($expansionlimit) || $item->type != $expansionlimit) && ($item->children->count() > 0 || ($item->nodetype == navigation_node::NODETYPE_BRANCH && $item->children->count() == 0 && isloggedin()))) {
1783                 $divclasses[] = 'branch';
1784             } else {
1785                 $divclasses[] = 'leaf';
1786             }
1787             if (!empty($item->classes) && count($item->classes) > 0) {
1788                 $divclasses[] = join(' ', $item->classes);
1789             }
1790             $divattr = array('class' => join(' ', $divclasses));
1791             if (!empty($item->id)) {
1792                 $divattr['id'] = $item->id;
1793             }
1794             $content = html_writer::tag('p', $content, $divattr) . $this->render_navigation_node($item->children, array(), $expansionlimit, $depth + 1);
1795             if (!empty($item->preceedwithhr) && $item->preceedwithhr === true) {
1796                 $content = html_writer::empty_tag('hr') . $content;
1797             }
1798             $content = html_writer::tag('li', $content, $liattr);
1799             $lis[] = $content;
1800         }
1802         if (count($lis)) {
1803             return html_writer::tag('ul', implode("\n", $lis), $attrs);
1804         } else {
1805             return '';
1806         }
1807     }
1811 /**
1812  * Class that models the behavior of wiki's restore version page
1813  *
1814  */
1815 class page_wiki_restoreversion extends page_wiki {
1816     private $version;
1818     function print_header() {
1819         parent::print_header();
1820         $this->print_pagetitle();
1821     }
1823     function print_content() {
1824         global $CFG, $PAGE;
1826         require_capability('mod/wiki:managewiki', $this->modcontext, NULL, true, 'nomanagewikipermission', 'wiki');
1828         $this->print_restoreversion();
1829     }
1831     function set_url() {
1832         global $PAGE, $CFG;
1833         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
1834     }
1836     function set_versionid($versionid) {
1837         $this->version = wiki_get_version($versionid);
1838     }
1840     protected function create_navbar() {
1841         global $PAGE, $CFG;
1843         parent::create_navbar();
1844         $PAGE->navbar->add(get_string('restoreversion', 'wiki'));
1845     }
1847     protected function setup_tabs() {
1848         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history'));
1849     }
1851     /**
1852      * Prints the restore version content
1853      *
1854      * @uses $CFG
1855      *
1856      * @param page $page The page whose version will be restored
1857      * @param int  $versionid The version to be restored
1858      * @param bool $confirm If false, shows a yes/no confirmation page.
1859      *     If true, restores the old version and redirects the user to the 'view' tab.
1860      */
1861     private function print_restoreversion() {
1862         global $OUTPUT;
1864         $version = wiki_get_version($this->version->id);
1866         $optionsyes = array('confirm'=>1, 'pageid'=>$this->page->id, 'versionid'=>$version->id, 'sesskey'=>sesskey());
1867         $restoreurl = new moodle_url('/mod/wiki/restoreversion.php', $optionsyes);
1868         $return = new moodle_url('/mod/wiki/viewversion.php', array('pageid'=>$this->page->id, 'versionid'=>$version->id));
1870         echo $OUTPUT->heading(get_string('restoreconfirm', 'wiki', $version->version), 2);
1871         print_container_start(false, 'wiki_restoreform');
1872         echo '<form class="wiki_restore_yes" action="' . $restoreurl . '" method="post" id="restoreversion">';
1873         echo '<div><input type="submit" name="confirm" value="' . get_string('yes') . '" /></div>';
1874         echo '</form>';
1875         echo '<form class="wiki_restore_no" action="' . $return . '" method="post">';
1876         echo '<div><input type="submit" name="norestore" value="' . get_string('no') . '" /></div>';
1877         echo '</form>';
1878         print_container_end();
1879     }
1881 /**
1882  * Class that models the behavior of wiki's delete comment confirmation page
1883  *
1884  */
1885 class page_wiki_deletecomment extends page_wiki {
1886     private $commentid;
1888     function print_header() {
1889         parent::print_header();
1890         $this->print_pagetitle();
1891     }
1893     function print_content() {
1894         $this->printconfirmdelete();
1895     }
1897     function set_url() {
1898         global $PAGE;
1899         $PAGE->set_url('/mod/wiki/instancecomments.php', array('pageid' => $this->page->id, 'commentid' => $this->commentid));
1900     }
1902     public function set_action($action, $commentid, $content) {
1903         $this->action = $action;
1904         $this->commentid = $commentid;
1905         $this->content = $content;
1906     }
1908     protected function create_navbar() {
1909         global $PAGE;
1911         parent::create_navbar();
1912         $PAGE->navbar->add(get_string('deletecommentcheck', 'wiki'));
1913     }
1915     protected function setup_tabs() {
1916         parent::setup_tabs(array('linkedwhenactive' => 'comments', 'activetab' => 'comments'));
1917     }
1919     /**
1920      * Prints the comment deletion confirmation form
1921      *
1922      * @param page $page The page whose version will be restored
1923      * @param int  $versionid The version to be restored
1924      * @param bool $confirm If false, shows a yes/no confirmation page.
1925      *     If true, restores the old version and redirects the user to the 'view' tab.
1926      */
1927     private function printconfirmdelete() {
1928         global $OUTPUT;
1930         $strdeletecheck = get_string('deletecommentcheck', 'wiki');
1931         $strdeletecheckfull = get_string('deletecommentcheckfull', 'wiki');
1933         //ask confirmation
1934         $optionsyes = array('confirm'=>1, 'pageid'=>$this->page->id, 'action'=>'delete', 'commentid'=>$this->commentid, 'sesskey'=>sesskey());
1935         $deleteurl = new moodle_url('/mod/wiki/instancecomments.php', $optionsyes);
1936         $return = new moodle_url('/mod/wiki/comments.php', array('pageid'=>$this->page->id));
1938         echo $OUTPUT->heading($strdeletecheckfull);
1939         print_container_start(false, 'wiki_deletecommentform');
1940         echo '<form class="wiki_deletecomment_yes" action="' . $deleteurl . '" method="post" id="deletecomment">';
1941         echo '<div><input type="submit" name="confirmdeletecomment" value="' . get_string('yes') . '" /></div>';
1942         echo '</form>';
1943         echo '<form class="wiki_deletecomment_no" action="' . $return . '" method="post">';
1944         echo '<div><input type="submit" name="norestore" value="' . get_string('no') . '" /></div>';
1945         echo '</form>';
1946         print_container_end();
1947     }
1950 /**
1951  * Class that models the behavior of wiki's
1952  * save page
1953  *
1954  */
1955 class page_wiki_save extends page_wiki_edit {
1957     private $newcontent;
1959     function print_header() {
1960     }
1962     function print_content() {
1963         global $PAGE;
1965         $context = get_context_instance(CONTEXT_MODULE, $PAGE->cm->id);
1966         require_capability('mod/wiki:editpage', $context, NULL, true, 'noeditpermission', 'wiki');
1968         $this->print_save();
1969     }
1971     function set_newcontent($newcontent) {
1972         $this->newcontent = $newcontent;
1973     }
1975     protected function set_session_url() {
1976     }
1978     protected function print_save() {
1979         global $CFG, $USER, $OUTPUT, $PAGE;
1981         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
1982         if (!empty($this->section)) {
1983             $url .= "&section=" . urlencode($this->section);
1984         }
1986         $params = array('attachmentoptions' => page_wiki_edit::$attachmentoptions, 'format' => $this->format, 'version' => $this->versionnumber);
1988         if ($this->format != 'html') {
1989             $params['fileitemid'] = $this->page->id;
1990             $params['contextid']  = $this->modcontext->id;
1991             $params['component']  = 'mod_wiki';
1992             $params['filearea']   = 'attachments';
1993         }
1995         $form = new mod_wiki_edit_form($url, $params);
1997         $save = false;
1998         $data = false;
1999         if ($data = $form->get_data()) {
2000             if ($this->format == 'html') {
2001                 $data = file_postupdate_standard_editor($data, 'newcontent', page_wiki_edit::$attachmentoptions, $this->modcontext, 'mod_wiki', 'attachments', $this->subwiki->id);
2002             }
2004             if (isset($this->section)) {
2005                 $save = wiki_save_section($this->page, $this->section, $data->newcontent, $USER->id);
2006             } else {
2007                 $save = wiki_save_page($this->page, $data->newcontent, $USER->id);
2008             }
2009         }
2011         if ($save && $data) {
2012             if (!empty($CFG->usetags)) {
2013                 tag_set('wiki_pages', $this->page->id, $data->tags);
2014             }
2016             $message = '<p>' . get_string('saving', 'wiki') . '</p>';
2018             if (!empty($save['sections'])) {
2019                 foreach ($save['sections'] as $s) {
2020                     $message .= '<p>' . get_string('repeatedsection', 'wiki', $s) . '</p>';
2021                 }
2022             }
2024             if ($this->versionnumber + 1 != $save['version']) {
2025                 $message .= '<p>' . get_string('wrongversionsave', 'wiki') . '</p>';
2026             }
2028             if (isset($errors) && !empty($errors)) {
2029                 foreach ($errors as $e) {
2030                     $message .= "<p>" . get_string('filenotuploadederror', 'wiki', $e->get_filename()) . "</p>";
2031                 }
2032             }
2034             //deleting old locks
2035             wiki_delete_locks($this->page->id, $USER->id, $this->section);
2037             redirect($CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $this->page->id);
2038         } else {
2039             print_error('savingerror', 'wiki');
2040         }
2041     }
2044 /**
2045  * Class that models the behavior of wiki's view an old version of a page
2046  *
2047  */
2048 class page_wiki_viewversion extends page_wiki {
2050     private $version;
2052     function print_header() {
2053         parent::print_header();
2054         $this->print_pagetitle();
2055     }
2057     function print_content() {
2058         global $PAGE;
2060         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2062         $this->print_version_view();
2063     }
2065     function set_url() {
2066         global $PAGE, $CFG;
2067         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2068     }
2070     function set_versionid($versionid) {
2071         $this->version = wiki_get_version($versionid);
2072     }
2074     protected function create_navbar() {
2075         global $PAGE, $CFG;
2077         parent::create_navbar();
2078         $PAGE->navbar->add(get_string('history', 'wiki'), $CFG->wwwroot . '/mod/wiki/history.php?pageid' . $this->page->id);
2079         $PAGE->navbar->add(get_string('versionnum', 'wiki', $this->version->version));
2080     }
2082     protected function setup_tabs() {
2083         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history', 'inactivetabs' => array('edit')));
2084     }
2086     /**
2087      * Given an old page version, output the version content
2088      *
2089      * @global object $CFG
2090      * @global object $OUTPUT
2091      * @global object $PAGE
2092      */
2093     private function print_version_view() {
2094         global $CFG, $OUTPUT, $PAGE;
2095         $pageversion = wiki_get_version($this->version->id);
2097         if ($pageversion) {
2098             $restorelink = new moodle_url('/mod/wiki/restoreversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2099             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);
2100             $userinfo = wiki_get_user_info($pageversion->userid);
2101             $heading = '<p><strong>' . get_string('modified', 'wiki') . ':</strong>&nbsp;' . userdate($pageversion->timecreated, get_string('strftimedatetime', 'langconfig'));
2102             $viewlink = new moodle_url('/user/view.php', array('id' => $userinfo->id));
2103             $heading .= '&nbsp;&nbsp;&nbsp;<strong>' . get_string('user') . ':</strong>&nbsp;' . html_writer::link($viewlink->out(false), fullname($userinfo));
2104             $heading .= '&nbsp;&nbsp;&rarr;&nbsp;' . $OUTPUT->user_picture(wiki_get_user_info($pageversion->userid), array('popup' => true)) . '</p>';
2105             print_container($heading, false, 'mdl-align wiki_modifieduser wiki_headingtime');
2106             $options = array('swid' => $this->subwiki->id, 'pretty_print' => true, 'pageid' => $this->page->id);
2108             $pageversion->content = file_rewrite_pluginfile_urls($pageversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id);
2110             $parseroutput = wiki_parse_content($pageversion->contentformat, $pageversion->content, $options);
2111             $content = print_container(format_text($parseroutput['parsed_text'], FORMAT_HTML, array('overflowdiv'=>true)), false, '', '', true);
2112             echo $OUTPUT->box($content, 'generalbox wiki_contentbox');
2114         } else {
2115             print_error('versionerror', 'wiki');
2116         }
2117     }
2120 class page_wiki_confirmrestore extends page_wiki_save {
2122     private $version;
2124     function set_url() {
2125         global $PAGE, $CFG;
2126         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2127     }
2129     function print_content() {
2130         global $CFG, $PAGE;
2132         require_capability('mod/wiki:managewiki', $this->modcontext, NULL, true, 'nomanagewikipermission', 'wiki');
2134         $version = wiki_get_version($this->version->id);
2135         if (wiki_restore_page($this->page, $version->content, $version->userid)) {
2136             redirect($CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $this->page->id, get_string('restoring', 'wiki', $version->version), 3);
2137         } else {
2138             print_error('restoreerror', 'wiki', $version->version);
2139         }
2140     }
2142     function set_versionid($versionid) {
2143         $this->version = wiki_get_version($versionid);
2144     }
2147 class page_wiki_prettyview extends page_wiki {
2149     function print_header() {
2150         global $CFG, $PAGE, $OUTPUT;
2151         $PAGE->set_pagelayout('embedded');
2152         echo $OUTPUT->header();
2154         echo '<h1 id="wiki_printable_title">' . format_string($this->title) . '</h1>';
2155     }
2157     function print_content() {
2158         global $PAGE;
2160         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2162         $this->print_pretty_view();
2163     }
2165     function set_url() {
2166         global $PAGE, $CFG;
2168         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/prettyview.php', array('pageid' => $this->page->id));
2169     }
2171     private function print_pretty_view() {
2172         $version = wiki_get_current_version($this->page->id);
2174         $content = wiki_parse_content($version->contentformat, $version->content, array('printable' => true, 'swid' => $this->subwiki->id, 'pageid' => $this->page->id, 'pretty_print' => true));
2176         echo '<div id="wiki_printable_content">';
2177         echo format_text($content['parsed_text'], FORMAT_HTML);
2178         echo '</div>';
2179     }
2182 class page_wiki_handlecomments extends page_wiki {
2183     private $action;
2184     private $content;
2185     private $commentid;
2186     private $format;
2188     function print_header() {
2189         $this->set_url();
2190     }
2192     public function print_content() {
2193         global $CFG, $PAGE, $USER;
2195         if ($this->action == 'add') {
2196             if (has_capability('mod/wiki:editcomment', $this->modcontext)) {
2197                 $this->add_comment($this->content, $this->commentid);
2198             }
2199         } else if ($this->action == 'edit') {
2200             $comment = wiki_get_comment($this->commentid);
2201             $edit = has_capability('mod/wiki:editcomment', $this->modcontext);
2202             $owner = ($comment->userid == $USER->id);
2203             if ($owner && $edit) {
2204                 $this->add_comment($this->content, $this->commentid);
2205             }
2206         } else if ($this->action == 'delete') {
2207             $comment = wiki_get_comment($this->commentid);
2208             $manage = has_capability('mod/wiki:managecomment', $this->modcontext);
2209             $owner = ($comment->userid == $USER->id);
2210             if ($owner || $manage) {
2211                 $this->delete_comment($this->commentid);
2212                 redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $this->page->id, get_string('deletecomment', 'wiki'), 2);
2213             }
2214         }
2216     }
2218     public function set_url() {
2219         global $PAGE, $CFG;
2220         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
2221     }
2223     public function set_action($action, $commentid, $content) {
2224         $this->action = $action;
2225         $this->commentid = $commentid;
2226         $this->content = $content;
2228         $version = wiki_get_current_version($this->page->id);
2229         $format = $version->contentformat;
2231         $this->format = $format;
2232     }
2234     private function add_comment($content, $idcomment) {
2235         global $CFG, $PAGE;
2236         require_once($CFG->dirroot . "/mod/wiki/locallib.php");
2238         $pageid = $this->page->id;
2240         wiki_add_comment($this->modcontext, $pageid, $content, $this->format);
2242         if (!$idcomment) {
2243             redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $pageid, get_string('createcomment', 'wiki'), 2);
2244         } else {
2245             $this->delete_comment($idcomment);
2246             redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $pageid, get_string('editingcomment', 'wiki'), 2);
2247         }
2248     }
2250     private function delete_comment($commentid) {
2251         global $CFG, $PAGE;
2253         $pageid = $this->page->id;
2255         wiki_delete_comment($commentid, $this->modcontext, $pageid);
2256     }
2260 class page_wiki_lock extends page_wiki_edit {
2262     public function print_header() {
2263         $this->set_url();
2264     }
2266     protected function set_url() {
2267         global $PAGE, $CFG;
2269         $params = array('pageid' => $this->page->id);
2271         if ($this->section) {
2272             $params['section'] = $this->section;
2273         }
2275         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/lock.php', $params);
2276     }
2278     protected function set_session_url() {
2279     }
2281     public function print_content() {
2282         global $USER, $PAGE;
2284         require_capability('mod/wiki:editpage', $this->modcontext, NULL, true, 'noeditpermission', 'wiki');
2286         wiki_set_lock($this->page->id, $USER->id, $this->section);
2287     }
2289     public function print_footer() {
2290     }
2293 class page_wiki_overridelocks extends page_wiki_edit {
2294     function print_header() {
2295         $this->set_url();
2296     }
2298     function print_content() {
2299         global $CFG, $PAGE;
2301         require_capability('mod/wiki:overridelock', $this->modcontext, NULL, true, 'nooverridelockpermission', 'wiki');
2303         wiki_delete_locks($this->page->id, null, $this->section, true, true);
2305         $args = "pageid=" . $this->page->id;
2307         if (!empty($this->section)) {
2308             $args .= "&section=" . urlencode($this->section);
2309         }
2311         redirect($CFG->wwwroot . '/mod/wiki/edit.php?' . $args, get_string('overridinglocks', 'wiki'), 2);
2312     }
2314     function set_url() {
2315         global $PAGE, $CFG;
2317         $params = array('pageid' => $this->page->id);
2319         if (!empty($this->section)) {
2320             $params['section'] = $this->section;
2321         }
2323         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/overridelocks.php', $params);
2324     }
2326     protected function set_session_url() {
2327     }
2329     private function print_overridelocks() {
2330         global $CFG;
2332         wiki_delete_locks($this->page->id, null, $this->section, true, true);
2334         $args = "pageid=" . $this->page->id;
2336         if (!empty($this->section)) {
2337             $args .= "&section=" . urlencode($this->section);
2338         }
2340         redirect($CFG->wwwroot . '/mod/wiki/edit.php?' . $args, get_string('overridinglocks', 'wiki'), 2);
2341     }
2345 /**
2346  * This class will let user to delete wiki pages and page versions
2347  *
2348  */
2349 class page_wiki_admin extends page_wiki {
2351     public $view, $action;
2352     public $listorphan = false;
2354     /**
2355      * Constructor
2356      *
2357      * @global object $PAGE
2358      * @param mixed $wiki instance of wiki
2359      * @param mixed $subwiki instance of subwiki
2360      * @param stdClass $cm course module
2361      */
2362     function __construct($wiki, $subwiki, $cm) {
2363         global $PAGE;
2364         parent::__construct($wiki, $subwiki, $cm);
2365         $PAGE->requires->js_init_call('M.mod_wiki.deleteversion', null, true);
2366     }
2368     /**
2369      * Prints header for wiki page
2370      */
2371     function print_header() {
2372         parent::print_header();
2373         $this->print_pagetitle();
2374     }
2376     /**
2377      * This function will display administration view to users with managewiki capability
2378      */
2379     function print_content() {
2380         //make sure anyone trying to access this page has managewiki capabilities
2381         require_capability('mod/wiki:managewiki', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2383         //update wiki cache if timedout
2384         $page = $this->page;
2385         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
2386             $fresh = wiki_refresh_cachedcontent($page);
2387             $page = $fresh['page'];
2388         }
2390         //dispaly admin menu
2391         echo $this->wikioutput->menu_admin($this->page->id, $this->view);
2393         //Display appropriate admin view
2394         switch ($this->view) {
2395             case 1: //delete page view
2396                 $this->print_delete_content($this->listorphan);
2397                 break;
2398             case 2: //delete version view
2399                 $this->print_delete_version();
2400                 break;
2401             default: //default is delete view
2402                 $this->print_delete_content($this->listorphan);
2403                 break;
2404         }
2405     }
2407     /**
2408      * Sets admin view option
2409      *
2410      * @param int $view page view id
2411      * @param bool $listorphan is only valid for view 1.
2412      */
2413     public function set_view($view, $listorphan = true) {
2414         $this->view = $view;
2415         $this->listorphan = $listorphan;
2416     }
2418     /**
2419      * Sets page url
2420      *
2421      * @global object $PAGE
2422      * @global object $CFG
2423      */
2424     function set_url() {
2425         global $PAGE, $CFG;
2426         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/admin.php', array('pageid' => $this->page->id));
2427     }
2429     /**
2430      * sets navigation bar for the page
2431      *
2432      * @global object $PAGE
2433      */
2434     protected function create_navbar() {
2435         global $PAGE;
2437         parent::create_navbar();
2438         $PAGE->navbar->add(get_string('admin', 'wiki'));
2439     }
2441     /**
2442      * Show wiki page delete options
2443      *
2444      * @param bool $showorphan
2445      */
2446     protected function print_delete_content($showorphan = true) {
2447         $contents = array();
2448         $table = new html_table();
2449         $table->head = array('','Page name');
2450         $table->attributes['class'] = 'generaltable mdl-align';
2451         $swid = $this->subwiki->id;
2452         if ($showorphan) {
2453             if ($orphanedpages = wiki_get_orphaned_pages($swid)) {
2454                 $this->add_page_delete_options($orphanedpages, $swid, $table);
2455             } else {
2456                 $table->data[] = array('', get_string('noorphanedpages', 'wiki'));
2457             }
2458         } else {
2459             if ($pages = wiki_get_page_list($swid)) {
2460                 $this->add_page_delete_options($pages, $swid, $table);
2461             } else {
2462                 $table->data[] = array('', get_string('nopages', 'wiki'));
2463             }
2464         }
2466         ///Print the form
2467         echo html_writer::start_tag('form', array(
2468                                                 'action' => new moodle_url('/mod/wiki/admin.php'),
2469                                                 'method' => 'post'));
2470         echo html_writer::tag('div', html_writer::empty_tag('input', array(
2471                                                                          'type'  => 'hidden',
2472                                                                          'name'  => 'pageid',
2473                                                                          'value' => $this->page->id)));
2475         echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'option', 'value' => $this->view));
2476         echo html_writer::table($table);
2477         echo html_writer::start_tag('div', array('class' => 'mdl-align'));
2478         if (!$showorphan) {
2479             echo html_writer::empty_tag('input', array(
2480                                                      'type'    => 'submit',
2481                                                      'class'   => 'wiki_form-button',
2482                                                      'value'   => get_string('listorphan', 'wiki'),
2483                                                      'sesskey' => sesskey()));
2484         } else {
2485             echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'listall', 'value'=>'1'));
2486             echo html_writer::empty_tag('input', array(
2487                                                      'type'    => 'submit',
2488                                                      'class'   => 'wiki_form-button',
2489                                                      'value'   => get_string('listall', 'wiki'),
2490                                                      'sesskey' => sesskey()));
2491         }
2492         echo html_writer::end_tag('div');
2493         echo html_writer::end_tag('form');
2494     }
2496     /**
2497      * helper function for print_delete_content. This will add data to the table.
2498      *
2499      * @global object $OUTPUT
2500      * @param array $pages objects of wiki pages in subwiki
2501      * @param int $swid id of subwiki
2502      * @param object $table reference to the table in which data needs to be added
2503      */
2504     protected function add_page_delete_options($pages, $swid, &$table) {
2505         global $OUTPUT;
2506         foreach ($pages as $page) {
2507             $link = wiki_parser_link($page->title, array('swid' => $swid));
2508             $class = ($link['new']) ? 'class="wiki_newentry"' : '';
2509             $pagelink = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>';
2510             $urledit = new moodle_url('/mod/wiki/edit.php', array('pageid' => $page->id, 'sesskey' => sesskey()));
2511             $urldelete = new moodle_url('/mod/wiki/admin.php', array(
2512                                                                    'pageid'  => $this->page->id,
2513                                                                    'delete'  => $page->id,
2514                                                                    'option'  => $this->view,
2515                                                                    'listall' => !$this->listorphan?'1': '',
2516                                                                    'sesskey' => sesskey()));
2518             $editlinks = $OUTPUT->action_icon($urledit, new pix_icon('t/edit', get_string('edit')));
2519             $editlinks .= $OUTPUT->action_icon($urldelete, new pix_icon('t/delete', get_string('delete')));
2520             $table->data[] = array($editlinks, $pagelink);
2521         }
2522     }
2524     /**
2525      * Prints lists of versions which can be deleted
2526      *
2527      * @global object $OUTPUT
2528      */
2529     private function print_delete_version() {
2530         global $OUTPUT;
2531         $pageid = $this->page->id;
2533         // versioncount is the latest version
2534         $versioncount = wiki_count_wiki_page_versions($pageid) - 1;
2535         $versions = wiki_get_wiki_page_versions($pageid, 0, $versioncount);
2537         // We don't want version 0 to be displayed
2538         // version 0 is blank page
2539         if (end($versions)->version == 0) {
2540             array_pop($versions);
2541         }
2543         $contents = array();
2544         $version0page = wiki_get_wiki_page_version($this->page->id, 0);
2545         $creator = wiki_get_user_info($version0page->userid);
2546         $a = new stdClass();
2547         $a->date = userdate($this->page->timecreated, get_string('strftimedaydatetime', 'langconfig'));
2548         $a->username = $creator->username;
2549         echo $OUTPUT->heading(get_string('createddate', 'wiki', $a), 4, 'wiki_headingtime');
2550         if ($versioncount > 0) {
2551             /// If there is only one version, we don't need radios nor forms
2552             if (count($versions) == 1) {
2553                 $row = array_shift($versions);
2554                 $username = wiki_get_user_info($row->userid);
2555                 $picture = $OUTPUT->user_picture($username);
2556                 $date = userdate($row->timecreated, get_string('strftimedate', 'langconfig'));
2557                 $time = userdate($row->timecreated, get_string('strftimetime', 'langconfig'));
2558                 $versionid = wiki_get_version($row->id);
2559                 $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
2560                 $userlink = new moodle_url('/user/view.php', array('id' => $username->id));
2561                 $picturelink = $picture . html_writer::link($userlink->out(false), fullname($username));
2562                 $historydate = $OUTPUT->container($date, 'wiki_histdate');
2563                 $contents[] = array('', html_writer::link($versionlink->out(false), $row->version), $picturelink, $time, $historydate);
2565                 //Show current version
2566                 $table = new html_table();
2567                 $table->head = array('', get_string('version'), get_string('user'), get_string('modified'), '');
2568                 $table->data = $contents;
2569                 $table->attributes['class'] = 'mdl-align';
2571                 echo html_writer::table($table);
2572             } else {
2573                 $lastdate = '';
2574                 $rowclass = array();
2576                 foreach ($versions as $version) {
2577                     $user = wiki_get_user_info($version->userid);
2578                     $picture = $OUTPUT->user_picture($user, array('popup' => true));
2579                     $date = userdate($version->timecreated, get_string('strftimedate'));
2580                     if ($date == $lastdate) {
2581                         $date = '';
2582                         $rowclass[] = '';
2583                     } else {
2584                         $lastdate = $date;
2585                         $rowclass[] = 'wiki_histnewdate';
2586                     }
2588                     $time = userdate($version->timecreated, get_string('strftimetime', 'langconfig'));
2589                     $versionid = wiki_get_version($version->id);
2590                     if ($versionid) {
2591                         $url = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
2592                         $viewlink = html_writer::link($url->out(false), $version->version);
2593                     } else {
2594                         $viewlink = $version->version;
2595                     }
2597                     $userlink = new moodle_url('/user/view.php', array('id' => $version->userid));
2598                     $picturelink = $picture . html_writer::link($userlink->out(false), fullname($user));
2599                     $historydate = $OUTPUT->container($date, 'wiki_histdate');
2600                     $radiofromelement = $this->choose_from_radio(array($version->version  => null), 'fromversion', 'M.mod_wiki.deleteversion()', $versioncount, true);
2601                     $radiotoelement = $this->choose_from_radio(array($version->version  => null), 'toversion', 'M.mod_wiki.deleteversion()', $versioncount, true);
2602                     $contents[] = array( $radiofromelement . $radiotoelement, $viewlink, $picturelink, $time, $historydate);
2603                 }
2605                 $table = new html_table();
2606                 $table->head = array(get_string('deleteversions', 'wiki'), get_string('version'), get_string('user'), get_string('modified'), '');
2607                 $table->data = $contents;
2608                 $table->attributes['class'] = 'generaltable mdl-align';
2609                 $table->rowclasses = $rowclass;
2611                 ///Print the form
2612                 echo html_writer::start_tag('form', array('action'=>new moodle_url('/mod/wiki/admin.php'), 'method' => 'post'));
2613                 echo html_writer::tag('div', html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'pageid', 'value' => $pageid)));
2614                 echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'option', 'value' => $this->view));
2615                 echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' =>  sesskey()));
2616                 echo html_writer::table($table);
2617                 echo html_writer::start_tag('div', array('class' => 'mdl-align'));
2618                 echo html_writer::empty_tag('input', array('type' => 'submit', 'class' => 'wiki_form-button', 'value' => get_string('deleteversions', 'wiki')));
2619                 echo html_writer::end_tag('div');
2620                 echo html_writer::end_tag('form');
2621             }
2622         } else {
2623             print_string('nohistory', 'wiki');
2624         }
2625     }
2627     /**
2628      * Given an array of values, creates a group of radio buttons to be part of a form
2629      * helper function for print_delete_version
2630      *
2631      * @param array  $options  An array of value-label pairs for the radio group (values as keys).
2632      * @param string $name     Name of the radiogroup (unique in the form).
2633      * @param string $onclick  Function to be executed when the radios are clicked.
2634      * @param string $checked  The value that is already checked.
2635      * @param bool   $return   If true, return the HTML as a string, otherwise print it.
2636      *
2637      * @return mixed If $return is false, returns nothing, otherwise returns a string of HTML.
2638      */
2639     private function choose_from_radio($options, $name, $onclick = '', $checked = '', $return = false) {
2641         static $idcounter = 0;
2643         if (!$name) {
2644             $name = 'unnamed';
2645         }
2647         $output = '<span class="radiogroup ' . $name . "\">\n";
2649         if (!empty($options)) {
2650             $currentradio = 0;
2651             foreach ($options as $value => $label) {
2652                 $htmlid = 'auto-rb' . sprintf('%04d', ++$idcounter);
2653                 $output .= ' <span class="radioelement ' . $name . ' rb' . $currentradio . "\">";
2654                 $output .= '<input name="' . $name . '" id="' . $htmlid . '" type="radio" value="' . $value . '"';
2655                 if ($value == $checked) {
2656                     $output .= ' checked="checked"';
2657                 }
2658                 if ($onclick) {
2659                     $output .= ' onclick="' . $onclick . '"';
2660                 }
2661                 if ($label === '') {
2662                     $output .= ' /> <label for="' . $htmlid . '">' . $value . '</label></span>' . "\n";
2663                 } else {
2664                     $output .= ' /> <label for="' . $htmlid . '">' . $label . '</label></span>' . "\n";
2665                 }
2666                 $currentradio = ($currentradio + 1) % 2;
2667             }
2668         }
2670         $output .= '</span>' . "\n";
2672         if ($return) {
2673             return $output;
2674         } else {
2675             echo $output;
2676         }
2677     }