76c597315e65b550a2b0766e1fdc008ee0831d71
[moodle.git] / mod / wiki / pagelib.php
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * This file contains several classes uses to render the diferent pages
20  * of the wiki module
21  *
22  * @package mod_wiki
23  * @copyright 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu
24  * @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu
25  *
26  * @author Jordi Piguillem
27  * @author Marc Alier
28  * @author David Jimenez
29  * @author Josep Arus
30  * @author Daniel Serrano
31  * @author Kenneth Riba
32  *
33  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34  */
36 require_once($CFG->dirroot . '/mod/wiki/edit_form.php');
38 /**
39  * Class page_wiki contains the common code between all pages
40  *
41  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42  */
43 abstract class page_wiki {
45     /**
46      * @var object Current subwiki
47      */
48     protected $subwiki;
50     /**
51      * @var int Current page
52      */
53     protected $page;
55     /**
56      * @var string Current page title
57      */
58     protected $title;
60     /**
61      * @var int Current group ID
62      */
63     protected $gid;
65     /**
66      * @var object module context object
67      */
68     protected $modcontext;
70     /**
71      * @var int Current user ID
72      */
73     protected $uid;
74     /**
75      * @var array The tabs set used in wiki module
76      */
77     protected $tabs = array('view' => 'view', 'edit' => 'edit', 'comments' => 'comments',
78                             'history' => 'history', 'map' => 'map', 'files' => 'files',
79                             'admin' => 'admin');
80     /**
81      * @var array tabs options
82      */
83     protected $tabs_options = array();
84     /**
85      * @var object wiki renderer
86      */
87     protected $wikioutput;
88     /**
89      * @var stdClass course module.
90      */
91     protected $cm;
93     /**
94      * page_wiki constructor
95      *
96      * @param $wiki. Current wiki
97      * @param $subwiki. Current subwiki.
98      * @param $cm. Current course_module.
99      */
100     function __construct($wiki, $subwiki, $cm) {
101         global $PAGE, $CFG;
102         $this->subwiki = $subwiki;
103         $this->cm = $cm;
104         $this->modcontext = context_module::instance($this->cm->id);
106         // initialise wiki renderer
107         $this->wikioutput = $PAGE->get_renderer('mod_wiki');
108         $PAGE->set_cacheable(true);
109         $PAGE->set_cm($cm);
110         $PAGE->set_activity_record($wiki);
111         // the search box
112         if (!empty($subwiki->id)) {
113             $search = optional_param('searchstring', null, PARAM_TEXT);
114             $PAGE->set_button(wiki_search_form($cm, $search, $subwiki));
115         }
116     }
118     /**
119      * This method prints the top of the page.
120      */
121     function print_header() {
122         global $OUTPUT, $PAGE, $CFG, $USER, $SESSION;
124         $PAGE->set_heading($PAGE->course->fullname);
126         $this->set_url();
128         if (isset($SESSION->wikipreviousurl) && is_array($SESSION->wikipreviousurl)) {
129             $this->process_session_url();
130         }
131         $this->set_session_url();
133         $this->create_navbar();
134         $this->setup_tabs();
136         echo $OUTPUT->header();
137         $wiki = $PAGE->activityrecord;
138         echo $OUTPUT->heading(format_string($wiki->name));
140         echo $this->wikioutput->wiki_info();
142         // tabs are associated with pageid, so if page is empty, tabs should be disabled
143         if (!empty($this->page) && !empty($this->tabs)) {
144             echo $this->wikioutput->tabs($this->page, $this->tabs, $this->tabs_options);
145         }
146     }
148     /**
149      * Protected method to print current page title.
150      */
151     protected function print_pagetitle() {
152         global $OUTPUT;
153         $html = '';
155         $html .= $OUTPUT->container_start('wiki_headingtitle');
156         $html .= $OUTPUT->heading(format_string($this->title), 3);
157         $html .= $OUTPUT->container_end();
158         echo $html;
159     }
161     /**
162      * Setup page tabs, if options is empty, will set up active tab automatically
163      * @param array $options, tabs options
164      */
165     protected function setup_tabs($options = array()) {
166         global $CFG, $PAGE;
167         $groupmode = groups_get_activity_groupmode($this->cm);
169         if (empty($CFG->usecomments) || !has_capability('mod/wiki:viewcomment', $PAGE->context)){
170             unset($this->tabs['comments']);
171         }
173         if (!has_capability('mod/wiki:editpage', $PAGE->context)){
174             unset($this->tabs['edit']);
175         }
177         if ($groupmode and $groupmode == VISIBLEGROUPS) {
178             $currentgroup = groups_get_activity_group($this->cm);
179             $manage = has_capability('mod/wiki:managewiki', $this->modcontext);
180             $edit = has_capability('mod/wiki:editpage', $PAGE->context);
181             if (!$manage and !($edit and groups_is_member($currentgroup))) {
182                 unset($this->tabs['edit']);
183             }
184         }
186         if (empty($options)) {
187             $this->tabs_options = array('activetab' => substr(get_class($this), 10));
188         } else {
189             $this->tabs_options = $options;
190         }
192     }
194     /**
195      * This method must be overwritten to print the page content.
196      */
197     function print_content() {
198         throw new coding_exception('Page wiki class does not implement method print_content()');
199     }
201     /**
202      * Method to set the current page
203      *
204      * @param object $page Current page
205      */
206     function set_page($page) {
207         global $PAGE;
209         $this->page = $page;
210         $this->title = $page->title;
211         // set_title calls format_string itself so no probs there
212         $PAGE->set_title($this->title);
213     }
215     /**
216      * Method to set the current page title.
217      * This method must be called when the current page is not created yet.
218      * @param string $title Current page title.
219      */
220     function set_title($title) {
221         global $PAGE;
223         $this->page = null;
224         $this->title = $title;
225         // set_title calls format_string itself so no probs there
226         $PAGE->set_title($this->title);
227     }
229     /**
230      * Method to set current group id
231      * @param int $gid Current group id
232      */
233     function set_gid($gid) {
234         $this->gid = $gid;
235     }
237     /**
238      * Method to set current user id
239      * @param int $uid Current user id
240      */
241     function set_uid($uid) {
242         $this->uid = $uid;
243     }
245     /**
246      * Method to set the URL of the page.
247      * This method must be overwritten by every type of page.
248      */
249     protected function set_url() {
250         throw new coding_exception('Page wiki class does not implement method set_url()');
251     }
253     /**
254      * Protected method to create the common items of the navbar in every page type.
255      */
256     protected function create_navbar() {
257         global $PAGE, $CFG;
259         $PAGE->navbar->add(format_string($this->title), $CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $this->page->id);
260     }
262     /**
263      * This method print the footer of the page.
264      */
265     function print_footer() {
266         global $OUTPUT;
267         echo $OUTPUT->footer();
268     }
270     protected function process_session_url() {
271         global $USER, $SESSION;
273         //delete locks if edit
274         $url = $SESSION->wikipreviousurl;
275         switch ($url['page']) {
276         case 'edit':
277             wiki_delete_locks($url['params']['pageid'], $USER->id, $url['params']['section'], false);
278             break;
279         }
280     }
282     protected function set_session_url() {
283         global $SESSION;
284         unset($SESSION->wikipreviousurl);
285     }
289 /**
290  * View a wiki page
291  *
292  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
293  */
294 class page_wiki_view extends page_wiki {
296     function print_header() {
297         global $PAGE;
299         parent::print_header();
301         $this->wikioutput->wiki_print_subwiki_selector($PAGE->activityrecord, $this->subwiki, $this->page, 'view');
303         if (!empty($this->page)) {
304             echo $this->wikioutput->prettyview_link($this->page);
305         }
307         //echo $this->wikioutput->page_index();
309         $this->print_pagetitle();
310     }
312     function print_content() {
313         global $PAGE, $CFG;
315         if (wiki_user_can_view($this->subwiki)) {
317             if (!empty($this->page)) {
318                 wiki_print_page_content($this->page, $this->modcontext, $this->subwiki->id);
319                 $wiki = $PAGE->activityrecord;
320             } else {
321                 print_string('nocontent', 'wiki');
322                 // TODO: fix this part
323                 $swid = 0;
324                 if (!empty($this->subwiki)) {
325                     $swid = $this->subwiki->id;
326                 }
327             }
328         } else {
329             echo get_string('cannotviewpage', 'wiki');
330         }
331     }
333     function set_url() {
334         global $PAGE, $CFG;
335         $params = array();
337         if (isset($this->cm->id)) {
338             $params['id'] = $this->cm->id;
339         } else if (!empty($this->page) and $this->page != null) {
340             $params['pageid'] = $this->page->id;
341         } else if (!empty($this->gid)) {
342             $params['wid'] = $this->cm->instance;
343             $params['group'] = $this->gid;
344         } else if (!empty($this->title)) {
345             $params['swid'] = $this->subwiki->id;
346             $params['title'] = $this->title;
347         } else {
348             print_error(get_string('invalidparameters', 'wiki'));
349         }
350         $PAGE->set_url(new moodle_url($CFG->wwwroot . '/mod/wiki/view.php', $params));
351     }
353     protected function create_navbar() {
354         global $PAGE;
356         $PAGE->navbar->add(format_string($this->title));
357         $PAGE->navbar->add(get_string('view', 'wiki'));
358     }
361 /**
362  * Wiki page editing page
363  *
364  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
365  */
366 class page_wiki_edit extends page_wiki {
368     public static $attachmentoptions;
370     protected $sectioncontent;
371     /** @var string the section name needed to be edited */
372     protected $section;
373     protected $overridelock = false;
374     protected $versionnumber = -1;
375     protected $upload = false;
376     protected $attachments = 0;
377     protected $deleteuploads = array();
378     protected $format;
380     function __construct($wiki, $subwiki, $cm) {
381         global $CFG, $PAGE;
382         parent::__construct($wiki, $subwiki, $cm);
383         $showfilemanager = false;
384         if (has_capability('mod/wiki:managefiles', context_module::instance($cm->id))) {
385             $showfilemanager = true;
386         }
387         self::$attachmentoptions = array('subdirs' => false, 'maxfiles' => - 1, 'maxbytes' => $CFG->maxbytes,
388                 'accepted_types' => '*', 'enable_filemanagement' => $showfilemanager);
389         $PAGE->requires->js_init_call('M.mod_wiki.renew_lock', null, true);
390     }
392     protected function print_pagetitle() {
393         global $OUTPUT;
395         $title = $this->title;
396         if (isset($this->section)) {
397             $title .= ' : ' . $this->section;
398         }
399         echo $OUTPUT->container_start('wiki_clear wiki_headingtitle');
400         echo $OUTPUT->heading(format_string($title), 3);
401         echo $OUTPUT->container_end();
402     }
404     function print_header() {
405         global $OUTPUT, $PAGE;
406         $PAGE->requires->data_for_js('wiki', array('renew_lock_timeout' => LOCK_TIMEOUT - 5, 'pageid' => $this->page->id, 'section' => $this->section));
408         parent::print_header();
410         $this->print_pagetitle();
412         print '<noscript>' . $OUTPUT->box(get_string('javascriptdisabledlocks', 'wiki'), 'errorbox') . '</noscript>';
413     }
415     function print_content() {
416         global $PAGE;
418         if (wiki_user_can_edit($this->subwiki)) {
419             $this->print_edit();
420         } else {
421             echo get_string('cannoteditpage', 'wiki');
422         }
423     }
425     protected function set_url() {
426         global $PAGE, $CFG;
428         $params = array('pageid' => $this->page->id);
430         if (isset($this->section)) {
431             $params['section'] = $this->section;
432         }
434         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/edit.php', $params);
435     }
437     protected function set_session_url() {
438         global $SESSION;
440         $SESSION->wikipreviousurl = array('page' => 'edit', 'params' => array('pageid' => $this->page->id, 'section' => $this->section));
441     }
443     protected function process_session_url() {
444     }
446     function set_section($sectioncontent, $section) {
447         $this->sectioncontent = $sectioncontent;
448         $this->section = $section;
449     }
451     public function set_versionnumber($versionnumber) {
452         $this->versionnumber = $versionnumber;
453     }
455     public function set_overridelock($override) {
456         $this->overridelock = $override;
457     }
459     function set_format($format) {
460         $this->format = $format;
461     }
463     public function set_upload($upload) {
464         $this->upload = $upload;
465     }
467     public function set_attachments($attachments) {
468         $this->attachments = $attachments;
469     }
471     public function set_deleteuploads($deleteuploads) {
472         $this->deleteuploads = $deleteuploads;
473     }
475     protected function create_navbar() {
476         global $PAGE, $CFG;
478         parent::create_navbar();
480         $PAGE->navbar->add(get_string('edit', 'wiki'));
481     }
483     protected function check_locks() {
484         global $OUTPUT, $USER, $CFG;
486         if (!wiki_set_lock($this->page->id, $USER->id, $this->section, true)) {
487             print $OUTPUT->box(get_string('pageislocked', 'wiki'), 'generalbox boxwidthnormal boxaligncenter');
489             if ($this->overridelock) {
490                 $params = 'pageid=' . $this->page->id;
492                 if ($this->section) {
493                     $params .= '&section=' . urlencode($this->section);
494                 }
496                 $form = '<form method="post" action="' . $CFG->wwwroot . '/mod/wiki/overridelocks.php?' . $params . '">';
497                 $form .= '<input type="hidden" name="sesskey" value="' . sesskey() . '" />';
498                 $form .= '<input type="submit" value="' . get_string('overridelocks', 'wiki') . '" />';
499                 $form .= '</form>';
501                 print $OUTPUT->box($form, 'generalbox boxwidthnormal boxaligncenter');
502             }
503             return false;
504         }
505         return true;
506     }
508     protected function print_edit($content = null) {
509         global $CFG, $OUTPUT, $USER, $PAGE;
511         if (!$this->check_locks()) {
512             return;
513         }
515         //delete old locks (> 1 hour)
516         wiki_delete_old_locks();
518         $version = wiki_get_current_version($this->page->id);
519         $format = $version->contentformat;
521         if ($content == null) {
522             if (empty($this->section)) {
523                 $content = $version->content;
524             } else {
525                 $content = $this->sectioncontent;
526             }
527         }
529         $versionnumber = $version->version;
530         if ($this->versionnumber >= 0) {
531             if ($version->version != $this->versionnumber) {
532                 print $OUTPUT->box(get_string('wrongversionlock', 'wiki'), 'errorbox');
533                 $versionnumber = $this->versionnumber;
534             }
535         }
537         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
538         if (!empty($this->section)) {
539             $url .= "&section=" . urlencode($this->section);
540         }
542         $params = array(
543             'attachmentoptions' => page_wiki_edit::$attachmentoptions,
544             'format' => $version->contentformat,
545             'version' => $versionnumber,
546             'pagetitle' => $this->page->title,
547             'contextid' => $this->modcontext->id
548         );
550         $data = new StdClass();
551         $data->newcontent = $content;
552         $data->version = $versionnumber;
553         $data->format = $format;
555         switch ($format) {
556         case 'html':
557             $data->newcontentformat = FORMAT_HTML;
558             // Append editor context to editor options, giving preference to existing context.
559             page_wiki_edit::$attachmentoptions = array_merge(array('context' => $this->modcontext), page_wiki_edit::$attachmentoptions);
560             $data = file_prepare_standard_editor($data, 'newcontent', page_wiki_edit::$attachmentoptions, $this->modcontext, 'mod_wiki', 'attachments', $this->subwiki->id);
561             break;
562         default:
563             break;
564         }
566         if ($version->contentformat != 'html') {
567             $params['fileitemid'] = $this->subwiki->id;
568             $params['component']  = 'mod_wiki';
569             $params['filearea']   = 'attachments';
570         }
572         $data->tags = core_tag_tag::get_item_tags_array('mod_wiki', 'wiki_pages', $this->page->id);
574         $form = new mod_wiki_edit_form($url, $params);
575         $form->set_data($data);
576         $form->display();
577     }
581 /**
582  * Class that models the behavior of wiki's view comments page
583  *
584  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
585  */
586 class page_wiki_comments extends page_wiki {
588     function print_header() {
590         parent::print_header();
592         $this->print_pagetitle();
594     }
596     function print_content() {
597         global $CFG, $OUTPUT, $USER, $PAGE;
598         require_once($CFG->dirroot . '/mod/wiki/locallib.php');
600         $page = $this->page;
601         $subwiki = $this->subwiki;
602         $wiki = $PAGE->activityrecord;
603         list($context, $course, $cm) = get_context_info_array($this->modcontext->id);
605         require_capability('mod/wiki:viewcomment', $this->modcontext, NULL, true, 'noviewcommentpermission', 'wiki');
607         $comments = wiki_get_comments($this->modcontext->id, $page->id);
609         if (has_capability('mod/wiki:editcomment', $this->modcontext)) {
610             echo '<div class="midpad"><a href="' . $CFG->wwwroot . '/mod/wiki/editcomments.php?action=add&amp;pageid=' . $page->id . '">' . get_string('addcomment', 'wiki') . '</a></div>';
611         }
613         $options = array('swid' => $this->page->subwikiid, 'pageid' => $page->id);
614         $version = wiki_get_current_version($this->page->id);
615         $format = $version->contentformat;
617         if (empty($comments)) {
618             echo html_writer::tag('p', get_string('nocomments', 'wiki'), array('class' => 'bold'));
619         }
621         foreach ($comments as $comment) {
623             $user = wiki_get_user_info($comment->userid);
625             $fullname = fullname($user, has_capability('moodle/site:viewfullnames', context_course::instance($course->id)));
626             $by = new stdclass();
627             $by->name = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $user->id . '&amp;course=' . $course->id . '">' . $fullname . '</a>';
628             $by->date = userdate($comment->timecreated);
630             $t = new html_table();
631             $t->id = 'wiki-comments';
632             $cell1 = new html_table_cell($OUTPUT->user_picture($user, array('popup' => true)));
633             $cell2 = new html_table_cell(get_string('bynameondate', 'forum', $by));
634             $cell3 = new html_table_cell();
635             $cell3->atributtes ['width'] = "80%";
636             $cell4 = new html_table_cell();
637             $cell5 = new html_table_cell();
639             $row1 = new html_table_row();
640             $row1->cells[] = $cell1;
641             $row1->cells[] = $cell2;
642             $row2 = new html_table_row();
643             $row2->cells[] = $cell3;
645             if ($format != 'html') {
646                 if ($format == 'creole') {
647                     $parsedcontent = wiki_parse_content('creole', $comment->content, $options);
648                 } else if ($format == 'nwiki') {
649                     $parsedcontent = wiki_parse_content('nwiki', $comment->content, $options);
650                 }
652                 $cell4->text = format_text(html_entity_decode($parsedcontent['parsed_text'], ENT_QUOTES, 'UTF-8'), FORMAT_HTML);
653             } else {
654                 $cell4->text = format_text($comment->content, FORMAT_HTML);
655             }
657             $row2->cells[] = $cell4;
659             $t->data = array($row1, $row2);
661             $canedit = $candelete = false;
662             if ((has_capability('mod/wiki:editcomment', $this->modcontext)) and ($USER->id == $user->id)) {
663                 $candelete = $canedit = true;
664             }
665             if ((has_capability('mod/wiki:managecomment', $this->modcontext))) {
666                 $candelete = true;
667             }
669             $editicon = $deleteicon = '';
670             if ($canedit) {
671                 $urledit = new moodle_url('/mod/wiki/editcomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'edit'));
672                 $editicon = $OUTPUT->action_icon($urledit, new pix_icon('t/edit', get_string('edit'), '', array('class' => 'iconsmall')));
673             }
674             if ($candelete) {
675                 $urldelete = new moodle_url('/mod/wiki/instancecomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'delete'));
676                 $deleteicon = $OUTPUT->action_icon($urldelete,
677                                                   new pix_icon('t/delete',
678                                                                get_string('delete'),
679                                                                '',
680                                                                array('class' => 'iconsmall')));
681             }
683             if ($candelete || $canedit) {
684                 $cell6 = new html_table_cell($editicon.$deleteicon);
685                 $row3 = new html_table_row();
686                 $row3->cells[] = $cell5;
687                 $row3->cells[] = $cell6;
688                 $t->data[] = $row3;
689             }
691             echo html_writer::tag('div', html_writer::table($t), array('class'=>'no-overflow'));
693         }
694     }
696     function set_url() {
697         global $PAGE, $CFG;
698         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
699     }
701     protected function create_navbar() {
702         global $PAGE, $CFG;
704         parent::create_navbar();
705         $PAGE->navbar->add(get_string('comments', 'wiki'));
706     }
710 /**
711  * Class that models the behavior of wiki's edit comment
712  *
713  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
714  */
715 class page_wiki_editcomment extends page_wiki {
716     private $comment;
717     private $action;
718     private $form;
719     private $format;
721     function set_url() {
722         global $PAGE, $CFG;
723         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
724     }
726     function print_header() {
727         parent::print_header();
728         $this->print_pagetitle();
729     }
731     function print_content() {
732         global $PAGE;
734         require_capability('mod/wiki:editcomment', $this->modcontext, NULL, true, 'noeditcommentpermission', 'wiki');
736         if ($this->action == 'add') {
737             $this->add_comment_form();
738         } else if ($this->action == 'edit') {
739             $this->edit_comment_form($this->comment);
740         }
741     }
743     function set_action($action, $comment) {
744         global $CFG;
745         require_once($CFG->dirroot . '/mod/wiki/comments_form.php');
747         $this->action = $action;
748         $this->comment = $comment;
749         $version = wiki_get_current_version($this->page->id);
750         $this->format = $version->contentformat;
752         if ($this->format == 'html') {
753             $destination = $CFG->wwwroot . '/mod/wiki/instancecomments.php?pageid=' . $this->page->id;
754             $this->form = new mod_wiki_comments_form($destination);
755         }
756     }
758     protected function create_navbar() {
759         global $PAGE, $CFG;
761         $PAGE->navbar->add(get_string('comments', 'wiki'), $CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $this->page->id);
763         if ($this->action == 'add') {
764             $PAGE->navbar->add(get_string('insertcomment', 'wiki'));
765         } else {
766             $PAGE->navbar->add(get_string('editcomment', 'wiki'));
767         }
768     }
770     protected function setup_tabs($options = array()) {
771         parent::setup_tabs(array('linkedwhenactive' => 'comments', 'activetab' => 'comments'));
772     }
774     private function add_comment_form() {
775         global $CFG;
776         require_once($CFG->dirroot . '/mod/wiki/editors/wiki_editor.php');
778         $pageid = $this->page->id;
780         if ($this->format == 'html') {
781             $com = new stdClass();
782             $com->action = 'add';
783             $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, null, $this->format, -1, null, false, null, 'addcomments');
788         }
789     }
791     private function edit_comment_form($com) {
792         global $CFG;
793         require_once($CFG->dirroot . '/mod/wiki/comments_form.php');
794         require_once($CFG->dirroot . '/mod/wiki/editors/wiki_editor.php');
796         if ($this->format == 'html') {
797             $com->action = 'edit';
798             $com->entrycomment_editor['text'] = $com->content;
799             $com->commentoptions = array('trusttext' => true, 'maxfiles' => 0);
801             $this->form->set_data($com);
802             $this->form->display();
803         } else {
804             wiki_print_editor_wiki($this->page->id, $com->content, $this->format, -1, null, false, array(), 'editcomments', $com->id);
805         }
807     }
811 /**
812  * Wiki page search page
813  *
814  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
815  */
816 class page_wiki_search extends page_wiki {
817     private $search_result;
819     protected function create_navbar() {
820         global $PAGE, $CFG;
822         $PAGE->navbar->add(format_string($this->title));
823     }
825     function set_search_string($search, $searchcontent) {
826         $swid = $this->subwiki->id;
827         if ($searchcontent) {
828             $this->search_result = wiki_search_all($swid, $search);
829         } else {
830             $this->search_result = wiki_search_title($swid, $search);
831         }
833     }
835     function set_url() {
836         global $PAGE, $CFG;
837         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/search.php');
838     }
840     function print_header() {
841         global $PAGE;
843         parent::print_header();
845         $wiki = $PAGE->activityrecord;
846         $page = (object)array('title' => $wiki->firstpagetitle);
847         $this->wikioutput->wiki_print_subwiki_selector($wiki, $this->subwiki, $page, 'search');
848     }
850     function print_content() {
851         global $PAGE;
853         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
855         echo $this->wikioutput->search_result($this->search_result, $this->subwiki);
856     }
859 /**
860  *
861  * Class that models the behavior of wiki's
862  * create page
863  *
864  */
865 class page_wiki_create extends page_wiki {
867     private $format;
868     private $swid;
869     private $wid;
870     private $action;
871     private $mform;
872     private $groups;
874     function print_header() {
875         $this->set_url();
876         parent::print_header();
877     }
879     function set_url() {
880         global $PAGE, $CFG;
882         $params = array();
883         $params['swid'] = $this->swid;
884         if ($this->action == 'new') {
885             $params['action'] = 'new';
886             $params['wid'] = $this->wid;
887             if ($this->title != get_string('newpage', 'wiki')) {
888                 $params['title'] = $this->title;
889             }
890         } else {
891             $params['action'] = 'create';
892         }
893         $PAGE->set_url(new moodle_url('/mod/wiki/create.php', $params));
894     }
896     function set_format($format) {
897         $this->format = $format;
898     }
900     function set_wid($wid) {
901         $this->wid = $wid;
902     }
904     function set_swid($swid) {
905         $this->swid = $swid;
906     }
908     function set_availablegroups($group) {
909         $this->groups = $group;
910     }
912     function set_action($action) {
913         global $PAGE;
914         $this->action = $action;
916         require_once(__DIR__ . '/create_form.php');
917         $url = new moodle_url('/mod/wiki/create.php', array('action' => 'create', 'wid' => $PAGE->activityrecord->id, 'group' => $this->gid, 'uid' => $this->uid));
918         $formats = wiki_get_formats();
919         $options = array('formats' => $formats, 'defaultformat' => $PAGE->activityrecord->defaultformat, 'forceformat' => $PAGE->activityrecord->forceformat, 'groups' => $this->groups);
920         if ($this->title != get_string('newpage', 'wiki')) {
921             $options['disable_pagetitle'] = true;
922         }
923         $this->mform = new mod_wiki_create_form($url->out(false), $options);
924     }
926     protected function create_navbar() {
927         global $PAGE;
928         // navigation_node::get_content formats this before printing.
929         $PAGE->navbar->add($this->title);
930     }
932     function print_content($pagetitle = '') {
933         global $PAGE;
935         // @TODO: Change this to has_capability and show an alternative interface.
936         require_capability('mod/wiki:createpage', $this->modcontext, NULL, true, 'nocreatepermission', 'wiki');
937         $data = new stdClass();
938         if (!empty($pagetitle)) {
939             $data->pagetitle = $pagetitle;
940         }
941         $data->pageformat = $PAGE->activityrecord->defaultformat;
943         $this->mform->set_data($data);
944         $this->mform->display();
945     }
947     function create_page($pagetitle) {
948         global $USER, $PAGE;
950         $data = $this->mform->get_data();
951         if (isset($data->groupinfo)) {
952             $groupid = $data->groupinfo;
953         } else if (!empty($this->gid)) {
954             $groupid = $this->gid;
955         } else {
956             $groupid = '0';
957         }
958         if (empty($this->subwiki)) {
959             // If subwiki is not set then try find one and set else create one.
960             if (!$this->subwiki = wiki_get_subwiki_by_group($this->wid, $groupid, $this->uid)) {
961                 $swid = wiki_add_subwiki($PAGE->activityrecord->id, $groupid, $this->uid);
962                 $this->subwiki = wiki_get_subwiki($swid);
963             }
964         }
965         if ($data) {
966             $this->set_title($data->pagetitle);
967             $id = wiki_create_page($this->subwiki->id, $data->pagetitle, $data->pageformat, $USER->id);
968         } else {
969             $this->set_title($pagetitle);
970             $id = wiki_create_page($this->subwiki->id, $pagetitle, $PAGE->activityrecord->defaultformat, $USER->id);
971         }
972         $this->page = $id;
973         return $id;
974     }
977 class page_wiki_preview extends page_wiki_edit {
979     private $newcontent;
981     function __construct($wiki, $subwiki, $cm) {
982         global $PAGE, $CFG, $OUTPUT;
983         parent::__construct($wiki, $subwiki, $cm);
984         $buttons = $OUTPUT->update_module_button($cm->id, 'wiki');
985         $PAGE->set_button($buttons);
987     }
989     function print_header() {
990         global $PAGE, $CFG;
992         parent::print_header();
994     }
996     function print_content() {
997         global $PAGE;
999         require_capability('mod/wiki:editpage', $this->modcontext, NULL, true, 'noeditpermission', 'wiki');
1001         $this->print_preview();
1002     }
1004     function set_newcontent($newcontent) {
1005         $this->newcontent = $newcontent;
1006     }
1008     function set_url() {
1009         global $PAGE, $CFG;
1011         $params = array('pageid' => $this->page->id
1012         );
1014         if (isset($this->section)) {
1015             $params['section'] = $this->section;
1016         }
1018         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/edit.php', $params);
1019     }
1021     protected function setup_tabs($options = array()) {
1022         parent::setup_tabs(array('linkedwhenactive' => 'view', 'activetab' => 'view'));
1023     }
1025     protected function check_locks() {
1026         return true;
1027     }
1029     protected function print_preview() {
1030         global $CFG, $PAGE, $OUTPUT;
1032         $version = wiki_get_current_version($this->page->id);
1033         $format = $version->contentformat;
1034         $content = $version->content;
1036         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
1037         if (!empty($this->section)) {
1038             $url .= "&section=" . urlencode($this->section);
1039         }
1040         $params = array(
1041             'attachmentoptions' => page_wiki_edit::$attachmentoptions,
1042             'format' => $this->format,
1043             'version' => $this->versionnumber,
1044             'contextid' => $this->modcontext->id
1045         );
1047         if ($this->format != 'html') {
1048             $params['component'] = 'mod_wiki';
1049             $params['filearea'] = 'attachments';
1050             $params['fileitemid'] = $this->page->id;
1051         }
1052         $form = new mod_wiki_edit_form($url, $params);
1055         $options = array('swid' => $this->page->subwikiid, 'pageid' => $this->page->id, 'pretty_print' => true);
1057         if ($data = $form->get_data()) {
1058             if (isset($data->newcontent)) {
1059                 // wiki fromat
1060                 $text = $data->newcontent;
1061             } else {
1062                 // html format
1063                 $text = $data->newcontent_editor['text'];
1064             }
1065             $parseroutput = wiki_parse_content($data->contentformat, $text, $options);
1066             $this->set_newcontent($text);
1067             echo $OUTPUT->notification(get_string('previewwarning', 'wiki'), 'notifyproblem');
1068             $content = format_text($parseroutput['parsed_text'], FORMAT_HTML, array('overflowdiv'=>true, 'filter'=>false));
1069             echo $OUTPUT->box($content, 'generalbox wiki_previewbox');
1070             $content = $this->newcontent;
1071         }
1073         $this->print_edit($content);
1074     }
1078 /**
1079  *
1080  * Class that models the behavior of wiki's
1081  * view differences
1082  *
1083  */
1084 class page_wiki_diff extends page_wiki {
1086     private $compare;
1087     private $comparewith;
1089     function print_header() {
1090         global $OUTPUT;
1092         parent::print_header();
1094         $this->print_pagetitle();
1095         $vstring = new stdClass();
1096         $vstring->old = $this->compare;
1097         $vstring->new = $this->comparewith;
1098         echo html_writer::tag('div', get_string('comparewith', 'wiki', $vstring), array('class' => 'wiki_headingtitle'));
1099     }
1101     /**
1102      * Print the diff view
1103      */
1104     function print_content() {
1105         global $PAGE;
1107         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1109         $this->print_diff_content();
1110     }
1112     function set_url() {
1113         global $PAGE, $CFG;
1115         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/diff.php', array('pageid' => $this->page->id, 'comparewith' => $this->comparewith, 'compare' => $this->compare));
1116     }
1118     function set_comparison($compare, $comparewith) {
1119         $this->compare = $compare;
1120         $this->comparewith = $comparewith;
1121     }
1123     protected function create_navbar() {
1124         global $PAGE, $CFG;
1126         parent::create_navbar();
1127         $PAGE->navbar->add(get_string('history', 'wiki'), $CFG->wwwroot . '/mod/wiki/history.php?pageid=' . $this->page->id);
1128         $PAGE->navbar->add(get_string('diff', 'wiki'));
1129     }
1131     protected function setup_tabs($options = array()) {
1132         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history'));
1133     }
1135     /**
1136      * Given two versions of a page, prints a page displaying the differences between them.
1137      *
1138      * @global object $CFG
1139      * @global object $OUTPUT
1140      * @global object $PAGE
1141      */
1142     private function print_diff_content() {
1143         global $CFG, $OUTPUT, $PAGE;
1145         $pageid = $this->page->id;
1146         $total = wiki_count_wiki_page_versions($pageid) - 1;
1148         $oldversion = wiki_get_wiki_page_version($pageid, $this->compare);
1150         $newversion = wiki_get_wiki_page_version($pageid, $this->comparewith);
1152         if ($oldversion && $newversion) {
1154             $oldtext = format_text(file_rewrite_pluginfile_urls($oldversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id));
1155             $newtext = format_text(file_rewrite_pluginfile_urls($newversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id));
1156             list($diff1, $diff2) = ouwiki_diff_html($oldtext, $newtext);
1157             $oldversion->diff = $diff1;
1158             $oldversion->user = wiki_get_user_info($oldversion->userid);
1159             $newversion->diff = $diff2;
1160             $newversion->user = wiki_get_user_info($newversion->userid);
1162             echo $this->wikioutput->diff($pageid, $oldversion, $newversion, array('total' => $total));
1163         } else {
1164             print_error('versionerror', 'wiki');
1165         }
1166     }
1169 /**
1170  *
1171  * Class that models the behavior of wiki's history page
1172  *
1173  */
1174 class page_wiki_history extends page_wiki {
1175     /**
1176      * @var int $paging current page
1177      */
1178     private $paging;
1180     /**
1181      * @var int @rowsperpage Items per page
1182      */
1183     private $rowsperpage = 10;
1185     /**
1186      * @var int $allversion if $allversion != 0, all versions will be printed in a signle table
1187      */
1188     private $allversion;
1190     function __construct($wiki, $subwiki, $cm) {
1191         global $PAGE;
1192         parent::__construct($wiki, $subwiki, $cm);
1193         $PAGE->requires->js_init_call('M.mod_wiki.history', null, true);
1194     }
1196     function print_header() {
1197         parent::print_header();
1198         $this->print_pagetitle();
1199     }
1201     function print_pagetitle() {
1202         global $OUTPUT;
1203         $html = '';
1205         $html .= $OUTPUT->container_start('wiki_headingtitle');
1206         $html .= $OUTPUT->heading_with_help(format_string($this->title), 'history', 'wiki', '', '', 3);
1207         $html .= $OUTPUT->container_end();
1208         echo $html;
1209     }
1211     function print_content() {
1212         global $PAGE;
1214         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1216         $this->print_history_content();
1217     }
1219     function set_url() {
1220         global $PAGE, $CFG;
1221         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/history.php', array('pageid' => $this->page->id));
1222     }
1224     function set_paging($paging) {
1225         $this->paging = $paging;
1226     }
1228     function set_allversion($allversion) {
1229         $this->allversion = $allversion;
1230     }
1232     protected function create_navbar() {
1233         global $PAGE, $CFG;
1235         parent::create_navbar();
1236         $PAGE->navbar->add(get_string('history', 'wiki'));
1237     }
1239     /**
1240      * Prints the history for a given wiki page
1241      *
1242      * @global object $CFG
1243      * @global object $OUTPUT
1244      * @global object $PAGE
1245      */
1246     private function print_history_content() {
1247         global $CFG, $OUTPUT, $PAGE;
1249         $pageid = $this->page->id;
1250         $offset = $this->paging * $this->rowsperpage;
1251         // vcount is the latest version
1252         $vcount = wiki_count_wiki_page_versions($pageid) - 1;
1253         if ($this->allversion) {
1254             $versions = wiki_get_wiki_page_versions($pageid, 0, $vcount);
1255         } else {
1256             $versions = wiki_get_wiki_page_versions($pageid, $offset, $this->rowsperpage);
1257         }
1258         // We don't want version 0 to be displayed
1259         // version 0 is blank page
1260         if (end($versions)->version == 0) {
1261             array_pop($versions);
1262         }
1264         $contents = array();
1266         $version0page = wiki_get_wiki_page_version($this->page->id, 0);
1267         $creator = wiki_get_user_info($version0page->userid);
1268         $a = new StdClass;
1269         $a->date = userdate($this->page->timecreated, get_string('strftimedaydatetime', 'langconfig'));
1270         $a->username = fullname($creator);
1271         echo html_writer::tag ('div', get_string('createddate', 'wiki', $a), array('class' => 'wiki_headingtime'));
1272         if ($vcount > 0) {
1274             /// If there is only one version, we don't need radios nor forms
1275             if (count($versions) == 1) {
1277                 $row = array_shift($versions);
1279                 $username = wiki_get_user_info($row->userid);
1280                 $picture = $OUTPUT->user_picture($username);
1281                 $date = userdate($row->timecreated, get_string('strftimedate', 'langconfig'));
1282                 $time = userdate($row->timecreated, get_string('strftimetime', 'langconfig'));
1283                 $versionid = wiki_get_version($row->id);
1284                 $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
1285                 $userlink = new moodle_url('/user/view.php', array('id' => $username->id, 'course' => $this->cm->course));
1286                 $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'));
1288                 $table = new html_table();
1289                 $table->head = array('', get_string('version'), get_string('user'), get_string('modified'), '');
1290                 $table->data = $contents;
1291                 $table->attributes['class'] = 'mdl-align';
1293                 echo html_writer::table($table);
1295             } else {
1297                 $checked = $vcount - $offset;
1298                 $rowclass = array();
1300                 foreach ($versions as $version) {
1301                     $user = wiki_get_user_info($version->userid);
1302                     $picture = $OUTPUT->user_picture($user, array('popup' => true));
1303                     $date = userdate($version->timecreated, get_string('strftimedate'));
1304                     $rowclass[] = 'wiki_histnewdate';
1305                     $time = userdate($version->timecreated, get_string('strftimetime', 'langconfig'));
1306                     $versionid = wiki_get_version($version->id);
1307                     if ($versionid) {
1308                         $url = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
1309                         $viewlink = html_writer::link($url->out(false), $version->version);
1310                     } else {
1311                         $viewlink = $version->version;
1312                     }
1313                     $userlink = new moodle_url('/user/view.php', array('id' => $version->userid, 'course' => $this->cm->course));
1314                     $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'));
1315                 }
1317                 $table = new html_table();
1319                 $icon = $OUTPUT->help_icon('diff', 'wiki');
1321                 $table->head = array(get_string('diff', 'wiki') . $icon, get_string('version'), get_string('user'), get_string('modified'), '');
1322                 $table->data = $contents;
1323                 $table->attributes['class'] = 'generaltable mdl-align';
1324                 $table->rowclasses = $rowclass;
1326                 // Print the form.
1327                 echo html_writer::start_tag('form', array('action'=>new moodle_url('/mod/wiki/diff.php'), 'method'=>'get', 'id'=>'diff'));
1328                 echo html_writer::tag('div', html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'pageid', 'value'=>$pageid)));
1329                 echo html_writer::table($table);
1330                 echo html_writer::start_tag('div', array('class'=>'mdl-align'));
1331                 echo html_writer::empty_tag('input', array('type'=>'submit', 'class'=>'wiki_form-button', 'value'=>get_string('comparesel', 'wiki')));
1332                 echo html_writer::end_tag('div');
1333                 echo html_writer::end_tag('form');
1334             }
1335         } else {
1336             print_string('nohistory', 'wiki');
1337         }
1338         if (!$this->allversion) {
1339             //$pagingbar = moodle_paging_bar::make($vcount, $this->paging, $this->rowsperpage, $CFG->wwwroot.'/mod/wiki/history.php?pageid='.$pageid.'&amp;');
1340             // $pagingbar->pagevar = $pagevar;
1341             echo $OUTPUT->paging_bar($vcount, $this->paging, $this->rowsperpage, $CFG->wwwroot . '/mod/wiki/history.php?pageid=' . $pageid . '&amp;');
1342             //print_paging_bar($vcount, $paging, $rowsperpage,$CFG->wwwroot.'/mod/wiki/history.php?pageid='.$pageid.'&amp;','paging');
1343             } else {
1344             $link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid));
1345             $OUTPUT->container(html_writer::link($link->out(false), get_string('viewperpage', 'wiki', $this->rowsperpage)), 'mdl-align');
1346         }
1347         if ($vcount > $this->rowsperpage && !$this->allversion) {
1348             $link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid, 'allversion' => 1));
1349             $OUTPUT->container(html_writer::link($link->out(false), get_string('viewallhistory', 'wiki')), 'mdl-align');
1350         }
1351     }
1353     /**
1354      * Given an array of values, creates a group of radio buttons to be part of a form
1355      *
1356      * @param array  $options  An array of value-label pairs for the radio group (values as keys).
1357      * @param string $name     Name of the radiogroup (unique in the form).
1358      * @param string $onclick  Function to be executed when the radios are clicked.
1359      * @param string $checked  The value that is already checked.
1360      * @param bool   $return   If true, return the HTML as a string, otherwise print it.
1361      *
1362      * @return mixed If $return is false, returns nothing, otherwise returns a string of HTML.
1363      */
1364     private function choose_from_radio($options, $name, $onclick = '', $checked = '', $return = false) {
1366         static $idcounter = 0;
1368         if (!$name) {
1369             $name = 'unnamed';
1370         }
1372         $output = '<span class="radiogroup ' . $name . "\">\n";
1374         if (!empty($options)) {
1375             $currentradio = 0;
1376             foreach ($options as $value => $label) {
1377                 $htmlid = 'auto-rb' . sprintf('%04d', ++$idcounter);
1378                 $output .= ' <span class="radioelement ' . $name . ' rb' . $currentradio . "\">";
1379                 $output .= '<input name="' . $name . '" id="' . $htmlid . '" type="radio" value="' . $value . '"';
1380                 if ($value == $checked) {
1381                     $output .= ' checked="checked"';
1382                 }
1383                 if ($onclick) {
1384                     $output .= ' onclick="' . $onclick . '"';
1385                 }
1386                 if ($label === '') {
1387                     $output .= ' /> <label for="' . $htmlid . '">' . $value . '</label></span>' . "\n";
1388                 } else {
1389                     $output .= ' /> <label for="' . $htmlid . '">' . $label . '</label></span>' . "\n";
1390                 }
1391                 $currentradio = ($currentradio + 1) % 2;
1392             }
1393         }
1395         $output .= '</span>' . "\n";
1397         if ($return) {
1398             return $output;
1399         } else {
1400             echo $output;
1401         }
1402     }
1405 /**
1406  * Class that models the behavior of wiki's map page
1407  *
1408  */
1409 class page_wiki_map extends page_wiki {
1411     /**
1412      * @var int wiki view option
1413      */
1414     private $view;
1416     function print_header() {
1417         parent::print_header();
1418         $this->print_pagetitle();
1419     }
1421     function print_content() {
1422         global $CFG, $PAGE;
1424         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1426         if ($this->view > 0) {
1427             //echo '<div><a href="' . $CFG->wwwroot . '/mod/wiki/map.php?pageid=' . $this->page->id . '">' . get_string('backtomapmenu', 'wiki') . '</a></div>';
1428         }
1430         switch ($this->view) {
1431         case 1:
1432             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1433             $this->print_contributions_content();
1434             break;
1435         case 2:
1436             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1437             $this->print_navigation_content();
1438             break;
1439         case 3:
1440             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1441             $this->print_orphaned_content();
1442             break;
1443         case 4:
1444             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1445             $this->print_index_content();
1446             break;
1447         case 6:
1448             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1449             $this->print_updated_content();
1450             break;
1451         case 5:
1452         default:
1453             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1454             $this->print_page_list_content();
1455         }
1456     }
1458     function set_view($option) {
1459         $this->view = $option;
1460     }
1462     function set_url() {
1463         global $PAGE, $CFG;
1464         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/map.php', array('pageid' => $this->page->id));
1465     }
1467     protected function create_navbar() {
1468         global $PAGE;
1470         parent::create_navbar();
1471         $PAGE->navbar->add(get_string('map', 'wiki'));
1472     }
1474     /**
1475      * Prints the contributions tab content
1476      *
1477      * @uses $OUTPUT, $USER
1478      *
1479      */
1480     private function print_contributions_content() {
1481         global $CFG, $OUTPUT, $USER;
1482         $page = $this->page;
1484         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1485             $fresh = wiki_refresh_cachedcontent($page);
1486             $page = $fresh['page'];
1487         }
1489         $swid = $this->subwiki->id;
1491         $table = new html_table();
1492         $table->head = array(get_string('contributions', 'wiki') . $OUTPUT->help_icon('contributions', 'wiki'));
1493         $table->attributes['class'] = 'wiki_editor generalbox';
1494         $table->data = array();
1495         $table->rowclasses = array();
1497         $lastversions = array();
1498         $pages = array();
1499         $users = array();
1501         if ($contribs = wiki_get_contributions($swid, $USER->id)) {
1502             foreach ($contribs as $contrib) {
1503                 if (!array_key_exists($contrib->pageid, $pages)) {
1504                     $page = wiki_get_page($contrib->pageid);
1505                     $pages[$contrib->pageid] = $page;
1506                 } else {
1507                     continue;
1508                 }
1510                 if (!array_key_exists($page->id, $lastversions)) {
1511                     $version = wiki_get_last_version($page->id);
1512                     $lastversions[$page->id] = $version;
1513                 } else {
1514                     $version = $lastversions[$page->id];
1515                 }
1517                 if (!array_key_exists($version->userid, $users)) {
1518                     $user = wiki_get_user_info($version->userid);
1519                     $users[$version->userid] = $user;
1520                 } else {
1521                     $user = $users[$version->userid];
1522                 }
1524                 $link = wiki_parser_link($page->title, array('swid' => $swid));
1525                 $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1527                 $linkpage = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content'], true, array('context' => $this->modcontext)) . '</a>';
1528                 $icon = $OUTPUT->user_picture($user, array('popup' => true));
1530                 $table->data[] = array("$icon&nbsp;$linkpage");
1531             }
1532         } else {
1533             $table->data[] = array(get_string('nocontribs', 'wiki'));
1534         }
1535         echo html_writer::table($table);
1536     }
1538     /**
1539      * Prints the navigation tab content
1540      *
1541      * @uses $OUTPUT
1542      *
1543      */
1544     private function print_navigation_content() {
1545         global $OUTPUT;
1546         $page = $this->page;
1548         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1549             $fresh = wiki_refresh_cachedcontent($page);
1550             $page = $fresh['page'];
1551         }
1553         $tolinks = wiki_get_linked_to_pages($page->id);
1554         $fromlinks = wiki_get_linked_from_pages($page->id);
1556         $table = new html_table();
1557         $table->attributes['class'] = 'wiki_navigation_from';
1558         $table->head = array(get_string('navigationfrom', 'wiki') . $OUTPUT->help_icon('navigationfrom', 'wiki') . ':');
1559         $table->data = array();
1560         $table->rowclasses = array();
1561         foreach ($fromlinks as $link) {
1562             $lpage = wiki_get_page($link->frompageid);
1563             $link = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
1564             $table->data[] = array(html_writer::link($link->out(false), format_string($lpage->title)));
1565             $table->rowclasses[] = 'mdl-align';
1566         }
1568         $table_left = html_writer::table($table);
1570         $table = new html_table();
1571         $table->attributes['class'] = 'wiki_navigation_to';
1572         $table->head = array(get_string('navigationto', 'wiki') . $OUTPUT->help_icon('navigationto', 'wiki') . ':');
1573         $table->data = array();
1574         $table->rowclasses = array();
1575         foreach ($tolinks as $link) {
1576             if ($link->tomissingpage) {
1577                 $viewlink = new moodle_url('/mod/wiki/create.php', array('swid' => $page->subwikiid, 'title' => $link->tomissingpage, 'action' => 'new'));
1578                 $table->data[] = array(html_writer::link($viewlink->out(false), format_string($link->tomissingpage), array('class' => 'wiki_newentry')));
1579             } else {
1580                 $lpage = wiki_get_page($link->topageid);
1581                 $viewlink = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
1582                 $table->data[] = array(html_writer::link($viewlink->out(false), format_string($lpage->title)));
1583             }
1584             $table->rowclasses[] = 'mdl-align';
1585         }
1586         $table_right = html_writer::table($table);
1587         echo $OUTPUT->container($table_left . $table_right, 'wiki_navigation_container');
1588     }
1590     /**
1591      * Prints the index page tab content
1592      *
1593      *
1594      */
1595     private function print_index_content() {
1596         global $OUTPUT;
1597         $page = $this->page;
1599         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1600             $fresh = wiki_refresh_cachedcontent($page);
1601             $page = $fresh['page'];
1602         }
1604         // navigation_node get_content calls format string for us
1605         $node = new navigation_node($page->title);
1607         $keys = array();
1608         $tree = array();
1609         $tree = wiki_build_tree($page, $node, $keys);
1611         $table = new html_table();
1612         $table->head = array(get_string('pageindex', 'wiki') . $OUTPUT->help_icon('pageindex', 'wiki'));
1613         $table->attributes['class'] = 'wiki_editor generalbox';
1614         $table->data[] = array($this->render_navigation_node($tree));
1616         echo html_writer::table($table);
1617     }
1619     /**
1620      * Prints the page list tab content
1621      *
1622      *
1623      */
1624     private function print_page_list_content() {
1625         global $OUTPUT;
1626         $page = $this->page;
1628         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1629             $fresh = wiki_refresh_cachedcontent($page);
1630             $page = $fresh['page'];
1631         }
1633         $pages = wiki_get_page_list($this->subwiki->id);
1635         $stdaux = new stdClass();
1636         $strspecial = get_string('special', 'wiki');
1638         foreach ($pages as $page) {
1639             // We need to format the title here to account for any filtering
1640             $letter = format_string($page->title, true, array('context' => $this->modcontext));
1641             $letter = core_text::substr($letter, 0, 1);
1642             if (preg_match('/^[a-zA-Z]$/', $letter)) {
1643                 $letter = core_text::strtoupper($letter);
1644                 $stdaux->{$letter}[] = wiki_parser_link($page);
1645             } else {
1646                 $stdaux->{$strspecial}[] = wiki_parser_link($page);
1647             }
1648         }
1650         $table = new html_table();
1651         $table->head = array(get_string('pagelist', 'wiki') . $OUTPUT->help_icon('pagelist', 'wiki'));
1652         $table->attributes['class'] = 'wiki_editor generalbox';
1653         $table->align = array('center');
1654         foreach ($stdaux as $key => $elem) {
1655             $table->data[] = array($key);
1656             foreach ($elem as $e) {
1657                 $table->data[] = array(html_writer::link($e['url'], format_string($e['content'], true, array('context' => $this->modcontext))));
1658             }
1659         }
1660         echo html_writer::table($table);
1661     }
1663     /**
1664      * Prints the orphaned tab content
1665      *
1666      *
1667      */
1668     private function print_orphaned_content() {
1669         global $OUTPUT;
1671         $page = $this->page;
1673         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1674             $fresh = wiki_refresh_cachedcontent($page);
1675             $page = $fresh['page'];
1676         }
1678         $swid = $this->subwiki->id;
1680         $table = new html_table();
1681         $table->head = array(get_string('orphaned', 'wiki') . $OUTPUT->help_icon('orphaned', 'wiki'));
1682         $table->attributes['class'] = 'wiki_editor generalbox';
1683         $table->data = array();
1684         $table->rowclasses = array();
1686         if ($orphanedpages = wiki_get_orphaned_pages($swid)) {
1687             foreach ($orphanedpages as $page) {
1688                 $link = wiki_parser_link($page->title, array('swid' => $swid));
1689                 $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1690                 $table->data[] = array('<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>');
1691             }
1692         } else {
1693             $table->data[] = array(get_string('noorphanedpages', 'wiki'));
1694         }
1696         echo html_writer::table($table);
1697     }
1699     /**
1700      * Prints the updated tab content
1701      *
1702      * @uses $COURSE, $OUTPUT
1703      *
1704      */
1705     private function print_updated_content() {
1706         global $COURSE, $OUTPUT;
1707         $page = $this->page;
1709         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1710             $fresh = wiki_refresh_cachedcontent($page);
1711             $page = $fresh['page'];
1712         }
1714         $swid = $this->subwiki->id;
1716         $table = new html_table();
1717         $table->head = array(get_string('updatedpages', 'wiki') . $OUTPUT->help_icon('updatedpages', 'wiki'));
1718         $table->attributes['class'] = 'wiki_editor generalbox';
1719         $table->data = array();
1720         $table->rowclasses = array();
1722         if ($pages = wiki_get_updated_pages_by_subwiki($swid)) {
1723             $strdataux = '';
1724             foreach ($pages as $page) {
1725                 $user = wiki_get_user_info($page->userid);
1726                 $strdata = strftime('%d %b %Y', $page->timemodified);
1727                 if ($strdata != $strdataux) {
1728                     $table->data[] = array($OUTPUT->heading($strdata, 4));
1729                     $strdataux = $strdata;
1730                 }
1731                 $link = wiki_parser_link($page->title, array('swid' => $swid));
1732                 $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1734                 $linkpage = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>';
1735                 $icon = $OUTPUT->user_picture($user, array($COURSE->id));
1736                 $table->data[] = array("$icon&nbsp;$linkpage");
1737             }
1738         } else {
1739             $table->data[] = array(get_string('noupdatedpages', 'wiki'));
1740         }
1742         echo html_writer::table($table);
1743     }
1745     protected function render_navigation_node($items, $attrs = array(), $expansionlimit = null, $depth = 1) {
1747         // exit if empty, we don't want an empty ul element
1748         if (count($items) == 0) {
1749             return '';
1750         }
1752         // array of nested li elements
1753         $lis = array();
1754         foreach ($items as $item) {
1755             if (!$item->display) {
1756                 continue;
1757             }
1758             $content = $item->get_content();
1759             $title = $item->get_title();
1760             if ($item->icon instanceof renderable) {
1761                 $icon = $this->wikioutput->render($item->icon);
1762                 $content = $icon . '&nbsp;' . $content; // use CSS for spacing of icons
1763                 }
1764             if ($item->helpbutton !== null) {
1765                 $content = trim($item->helpbutton) . html_writer::tag('span', $content, array('class' => 'clearhelpbutton'));
1766             }
1768             if ($content === '') {
1769                 continue;
1770             }
1772             if ($item->action instanceof action_link) {
1773                 //TODO: to be replaced with something else
1774                 $link = $item->action;
1775                 if ($item->hidden) {
1776                     $link->add_class('dimmed');
1777                 }
1778                 $content = $this->output->render($link);
1779             } else if ($item->action instanceof moodle_url) {
1780                 $attributes = array();
1781                 if ($title !== '') {
1782                     $attributes['title'] = $title;
1783                 }
1784                 if ($item->hidden) {
1785                     $attributes['class'] = 'dimmed_text';
1786                 }
1787                 $content = html_writer::link($item->action, $content, $attributes);
1789             } else if (is_string($item->action) || empty($item->action)) {
1790                 $attributes = array();
1791                 if ($title !== '') {
1792                     $attributes['title'] = $title;
1793                 }
1794                 if ($item->hidden) {
1795                     $attributes['class'] = 'dimmed_text';
1796                 }
1797                 $content = html_writer::tag('span', $content, $attributes);
1798             }
1800             // this applies to the li item which contains all child lists too
1801             $liclasses = array($item->get_css_type(), 'depth_' . $depth);
1802             if ($item->has_children() && (!$item->forceopen || $item->collapse)) {
1803                 $liclasses[] = 'collapsed';
1804             }
1805             if ($item->isactive === true) {
1806                 $liclasses[] = 'current_branch';
1807             }
1808             $liattr = array('class' => join(' ', $liclasses));
1809             // class attribute on the div item which only contains the item content
1810             $divclasses = array('tree_item');
1811             if ((empty($expansionlimit) || $item->type != $expansionlimit) && ($item->children->count() > 0 || ($item->nodetype == navigation_node::NODETYPE_BRANCH && $item->children->count() == 0 && isloggedin()))) {
1812                 $divclasses[] = 'branch';
1813             } else {
1814                 $divclasses[] = 'leaf';
1815             }
1816             if (!empty($item->classes) && count($item->classes) > 0) {
1817                 $divclasses[] = join(' ', $item->classes);
1818             }
1819             $divattr = array('class' => join(' ', $divclasses));
1820             if (!empty($item->id)) {
1821                 $divattr['id'] = $item->id;
1822             }
1823             $content = html_writer::tag('p', $content, $divattr) . $this->render_navigation_node($item->children, array(), $expansionlimit, $depth + 1);
1824             if (!empty($item->preceedwithhr) && $item->preceedwithhr === true) {
1825                 $content = html_writer::empty_tag('hr') . $content;
1826             }
1827             $content = html_writer::tag('li', $content, $liattr);
1828             $lis[] = $content;
1829         }
1831         if (count($lis)) {
1832             return html_writer::tag('ul', implode("\n", $lis), $attrs);
1833         } else {
1834             return '';
1835         }
1836     }
1840 /**
1841  * Class that models the behavior of wiki's restore version page
1842  *
1843  */
1844 class page_wiki_restoreversion extends page_wiki {
1845     private $version;
1847     function print_header() {
1848         parent::print_header();
1849         $this->print_pagetitle();
1850     }
1852     function print_content() {
1853         global $PAGE;
1855         $wiki = $PAGE->activityrecord;
1856         if (wiki_user_can_edit($this->subwiki, $wiki)) {
1857             $this->print_restoreversion();
1858         } else {
1859             echo get_string('cannoteditpage', 'wiki');
1860         }
1862     }
1864     function set_url() {
1865         global $PAGE, $CFG;
1866         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
1867     }
1869     function set_versionid($versionid) {
1870         $this->version = wiki_get_version($versionid);
1871     }
1873     protected function create_navbar() {
1874         global $PAGE, $CFG;
1876         parent::create_navbar();
1877         $PAGE->navbar->add(get_string('restoreversion', 'wiki'));
1878     }
1880     protected function setup_tabs($options = array()) {
1881         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history'));
1882     }
1884     /**
1885      * Prints the restore version content
1886      *
1887      * @uses $CFG
1888      *
1889      * @param page $page The page whose version will be restored
1890      * @param int  $versionid The version to be restored
1891      * @param bool $confirm If false, shows a yes/no confirmation page.
1892      *     If true, restores the old version and redirects the user to the 'view' tab.
1893      */
1894     private function print_restoreversion() {
1895         global $OUTPUT;
1897         $version = wiki_get_version($this->version->id);
1899         $optionsyes = array('confirm'=>1, 'pageid'=>$this->page->id, 'versionid'=>$version->id, 'sesskey'=>sesskey());
1900         $restoreurl = new moodle_url('/mod/wiki/restoreversion.php', $optionsyes);
1901         $return = new moodle_url('/mod/wiki/viewversion.php', array('pageid'=>$this->page->id, 'versionid'=>$version->id));
1903         echo $OUTPUT->container_start('wiki-form-center');
1904         echo html_writer::tag('div', get_string('restoreconfirm', 'wiki', $version->version));
1905         echo $OUTPUT->container_start(false, 'wiki_restoreform');
1906         echo '<form class="wiki_restore_yes" action="' . $restoreurl . '" method="post" id="restoreversion">';
1907         echo '<div><input type="submit" name="confirm" value="' . get_string('yes') . '" /></div>';
1908         echo '</form>';
1909         echo '<form class="wiki_restore_no" action="' . $return . '" method="post">';
1910         echo '<div><input type="submit" name="norestore" value="' . get_string('no') . '" /></div>';
1911         echo '</form>';
1912         echo $OUTPUT->container_end();
1913         echo $OUTPUT->container_end();
1914     }
1916 /**
1917  * Class that models the behavior of wiki's delete comment confirmation page
1918  *
1919  */
1920 class page_wiki_deletecomment extends page_wiki {
1921     private $commentid;
1923     function print_header() {
1924         parent::print_header();
1925         $this->print_pagetitle();
1926     }
1928     function print_content() {
1929         $this->printconfirmdelete();
1930     }
1932     function set_url() {
1933         global $PAGE;
1934         $PAGE->set_url('/mod/wiki/instancecomments.php', array('pageid' => $this->page->id, 'commentid' => $this->commentid));
1935     }
1937     public function set_action($action, $commentid, $content) {
1938         $this->action = $action;
1939         $this->commentid = $commentid;
1940         $this->content = $content;
1941     }
1943     protected function create_navbar() {
1944         global $PAGE;
1946         parent::create_navbar();
1947         $PAGE->navbar->add(get_string('deletecommentcheck', 'wiki'));
1948     }
1950     protected function setup_tabs($options = array()) {
1951         parent::setup_tabs(array('linkedwhenactive' => 'comments', 'activetab' => 'comments'));
1952     }
1954     /**
1955      * Prints the comment deletion confirmation form
1956      *
1957      * @param page $page The page whose version will be restored
1958      * @param int  $versionid The version to be restored
1959      * @param bool $confirm If false, shows a yes/no confirmation page.
1960      *     If true, restores the old version and redirects the user to the 'view' tab.
1961      */
1962     private function printconfirmdelete() {
1963         global $OUTPUT;
1965         $strdeletecheck = get_string('deletecommentcheck', 'wiki');
1966         $strdeletecheckfull = get_string('deletecommentcheckfull', 'wiki');
1968         //ask confirmation
1969         $optionsyes = array('confirm'=>1, 'pageid'=>$this->page->id, 'action'=>'delete', 'commentid'=>$this->commentid, 'sesskey'=>sesskey());
1970         $deleteurl = new moodle_url('/mod/wiki/instancecomments.php', $optionsyes);
1971         $return = new moodle_url('/mod/wiki/comments.php', array('pageid'=>$this->page->id));
1973         echo $OUTPUT->container_start('wiki-form-center');
1974         echo html_writer::tag('p', $strdeletecheckfull);
1975         echo $OUTPUT->container_start(false, 'wiki_deletecommentform');
1976         echo '<form class="wiki_deletecomment_yes" action="' . $deleteurl . '" method="post" id="deletecomment">';
1977         echo '<div><input type="submit" name="confirmdeletecomment" value="' . get_string('yes') . '" /></div>';
1978         echo '</form>';
1979         echo '<form class="wiki_deletecomment_no" action="' . $return . '" method="post">';
1980         echo '<div><input type="submit" name="norestore" value="' . get_string('no') . '" /></div>';
1981         echo '</form>';
1982         echo $OUTPUT->container_end();
1983         echo $OUTPUT->container_end();
1984     }
1987 /**
1988  * Class that models the behavior of wiki's
1989  * save page
1990  *
1991  */
1992 class page_wiki_save extends page_wiki_edit {
1994     private $newcontent;
1996     function print_header() {
1997     }
1999     function print_content() {
2000         global $PAGE;
2002         $context = context_module::instance($this->cm->id);
2003         require_capability('mod/wiki:editpage', $context, NULL, true, 'noeditpermission', 'wiki');
2005         $this->print_save();
2006     }
2008     function set_newcontent($newcontent) {
2009         $this->newcontent = $newcontent;
2010     }
2012     protected function set_session_url() {
2013     }
2015     protected function print_save() {
2016         global $CFG, $USER, $OUTPUT, $PAGE;
2018         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
2019         if (!empty($this->section)) {
2020             $url .= "&section=" . urlencode($this->section);
2021         }
2023         $params = array(
2024             'attachmentoptions' => page_wiki_edit::$attachmentoptions,
2025             'format' => $this->format,
2026             'version' => $this->versionnumber,
2027             'contextid' => $this->modcontext->id
2028         );
2030         if ($this->format != 'html') {
2031             $params['fileitemid'] = $this->page->id;
2032             $params['component']  = 'mod_wiki';
2033             $params['filearea']   = 'attachments';
2034         }
2036         $form = new mod_wiki_edit_form($url, $params);
2038         $save = false;
2039         $data = false;
2040         if ($data = $form->get_data()) {
2041             if ($this->format == 'html') {
2042                 $data = file_postupdate_standard_editor($data, 'newcontent', page_wiki_edit::$attachmentoptions, $this->modcontext, 'mod_wiki', 'attachments', $this->subwiki->id);
2043             }
2045             if (isset($this->section)) {
2046                 $save = wiki_save_section($this->page, $this->section, $data->newcontent, $USER->id);
2047             } else {
2048                 $save = wiki_save_page($this->page, $data->newcontent, $USER->id);
2049             }
2050         }
2052         if ($save && $data) {
2053             core_tag_tag::set_item_tags('mod_wiki', 'wiki_pages', $this->page->id, $this->modcontext, $data->tags);
2055             $message = '<p>' . get_string('saving', 'wiki') . '</p>';
2057             if (!empty($save['sections'])) {
2058                 foreach ($save['sections'] as $s) {
2059                     $message .= '<p>' . get_string('repeatedsection', 'wiki', $s) . '</p>';
2060                 }
2061             }
2063             if ($this->versionnumber + 1 != $save['version']) {
2064                 $message .= '<p>' . get_string('wrongversionsave', 'wiki') . '</p>';
2065             }
2067             if (isset($errors) && !empty($errors)) {
2068                 foreach ($errors as $e) {
2069                     $message .= "<p>" . get_string('filenotuploadederror', 'wiki', $e->get_filename()) . "</p>";
2070                 }
2071             }
2073             //deleting old locks
2074             wiki_delete_locks($this->page->id, $USER->id, $this->section);
2075             $url = new moodle_url('/mod/wiki/view.php', array('pageid' => $this->page->id, 'group' => $this->subwiki->groupid));
2076             redirect($url);
2077         } else {
2078             print_error('savingerror', 'wiki');
2079         }
2080     }
2083 /**
2084  * Class that models the behavior of wiki's view an old version of a page
2085  *
2086  */
2087 class page_wiki_viewversion extends page_wiki {
2089     private $version;
2091     function print_header() {
2092         parent::print_header();
2093         $this->print_pagetitle();
2094     }
2096     function print_content() {
2097         global $PAGE;
2099         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2101         $this->print_version_view();
2102     }
2104     function set_url() {
2105         global $PAGE, $CFG;
2106         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2107     }
2109     function set_versionid($versionid) {
2110         $this->version = wiki_get_version($versionid);
2111     }
2113     protected function create_navbar() {
2114         global $PAGE, $CFG;
2116         parent::create_navbar();
2117         $PAGE->navbar->add(get_string('history', 'wiki'), $CFG->wwwroot . '/mod/wiki/history.php?pageid=' . $this->page->id);
2118         $PAGE->navbar->add(get_string('versionnum', 'wiki', $this->version->version));
2119     }
2121     protected function setup_tabs($options = array()) {
2122         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history', 'inactivetabs' => array('edit')));
2123     }
2125     /**
2126      * Given an old page version, output the version content
2127      *
2128      * @global object $CFG
2129      * @global object $OUTPUT
2130      * @global object $PAGE
2131      */
2132     private function print_version_view() {
2133         global $CFG, $OUTPUT, $PAGE;
2134         $pageversion = wiki_get_version($this->version->id);
2136         if ($pageversion) {
2137             $restorelink = new moodle_url('/mod/wiki/restoreversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2138             echo html_writer::tag('div', get_string('viewversion', 'wiki', $pageversion->version) . '<br />' .
2139                 html_writer::link($restorelink->out(false), '(' . get_string('restorethis', 'wiki') .
2140                 ')', array('class' => 'wiki_restore')) . '&nbsp;', array('class' => 'wiki_headingtitle'));
2141             $userinfo = wiki_get_user_info($pageversion->userid);
2142             $heading = '<p><strong>' . get_string('modified', 'wiki') . ':</strong>&nbsp;' . userdate($pageversion->timecreated, get_string('strftimedatetime', 'langconfig'));
2143             $viewlink = new moodle_url('/user/view.php', array('id' => $userinfo->id));
2144             $heading .= '&nbsp;&nbsp;&nbsp;<strong>' . get_string('user') . ':</strong>&nbsp;' . html_writer::link($viewlink->out(false), fullname($userinfo));
2145             $heading .= '&nbsp;&nbsp;&rarr;&nbsp;' . $OUTPUT->user_picture(wiki_get_user_info($pageversion->userid), array('popup' => true)) . '</p>';
2146             echo $OUTPUT->container($heading, 'wiki_headingtime', 'mdl-align wiki_modifieduser');
2147             $options = array('swid' => $this->subwiki->id, 'pretty_print' => true, 'pageid' => $this->page->id);
2149             $pageversion->content = file_rewrite_pluginfile_urls($pageversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id);
2151             $parseroutput = wiki_parse_content($pageversion->contentformat, $pageversion->content, $options);
2152             $content = $OUTPUT->container(format_text($parseroutput['parsed_text'], FORMAT_HTML, array('overflowdiv'=>true)), false, '', '', true);
2153             echo $OUTPUT->box($content, 'generalbox wiki_contentbox');
2155         } else {
2156             print_error('versionerror', 'wiki');
2157         }
2158     }
2161 class page_wiki_confirmrestore extends page_wiki_save {
2163     private $version;
2165     function set_url() {
2166         global $PAGE, $CFG;
2167         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2168     }
2170     function print_header() {
2171         $this->set_url();
2172     }
2174     function print_content() {
2175         global $CFG, $PAGE;
2177         $version = wiki_get_version($this->version->id);
2178         $wiki = $PAGE->activityrecord;
2179         if (wiki_user_can_edit($this->subwiki, $wiki) &&
2180                 wiki_restore_page($this->page, $version, $this->modcontext)) {
2181             redirect($CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $this->page->id, get_string('restoring', 'wiki', $version->version), 3);
2182         } else {
2183             print_error('restoreerror', 'wiki', $version->version);
2184         }
2185     }
2187     function set_versionid($versionid) {
2188         $this->version = wiki_get_version($versionid);
2189     }
2192 class page_wiki_prettyview extends page_wiki {
2194     function __construct($wiki, $subwiki, $cm) {
2195         global $PAGE;
2196         $PAGE->set_pagelayout('embedded');
2197         parent::__construct($wiki, $subwiki, $cm);
2198     }
2200     function print_header() {
2201         global $OUTPUT;
2202         $this->set_url();
2204         echo $OUTPUT->header();
2205         // Print dialog link.
2206         $printtext = get_string('print', 'wiki');
2207         $printlinkatt = array('onclick' => 'window.print();return false;', 'class' => 'printicon');
2208         $printiconlink = html_writer::link('#', $printtext, $printlinkatt);
2209         echo html_writer::tag('div', $printiconlink, array('class' => 'displayprinticon'));
2210         echo html_writer::tag('h1', format_string($this->title), array('id' => 'wiki_printable_title'));
2211     }
2213     function print_content() {
2214         global $PAGE;
2216         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2218         $this->print_pretty_view();
2219     }
2221     function set_url() {
2222         global $PAGE, $CFG;
2224         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/prettyview.php', array('pageid' => $this->page->id));
2225     }
2227     private function print_pretty_view() {
2228         $version = wiki_get_current_version($this->page->id);
2230         $content = wiki_parse_content($version->contentformat, $version->content, array('printable' => true, 'swid' => $this->subwiki->id, 'pageid' => $this->page->id, 'pretty_print' => true));
2232         $html = $content['parsed_text'];
2233         $id = $this->subwiki->wikiid;
2234         if ($cm = get_coursemodule_from_instance("wiki", $id)) {
2235             $context = context_module::instance($cm->id);
2236             $html = file_rewrite_pluginfile_urls($html, 'pluginfile.php', $context->id, 'mod_wiki', 'attachments', $this->subwiki->id);
2237         }
2238         echo '<div id="wiki_printable_content">';
2239         echo format_text($html, FORMAT_HTML);
2240         echo '</div>';
2241     }
2244 class page_wiki_handlecomments extends page_wiki {
2245     private $action;
2246     private $content;
2247     private $commentid;
2248     private $format;
2250     function print_header() {
2251         $this->set_url();
2252     }
2254     public function print_content() {
2255         global $CFG, $PAGE, $USER;
2257         if ($this->action == 'add') {
2258             require_capability('mod/wiki:editcomment', $this->modcontext);
2259             $this->add_comment($this->content, $this->commentid);
2260         } else if ($this->action == 'edit') {
2261             require_capability('mod/wiki:editcomment', $this->modcontext);
2263             $comment = wiki_get_comment($this->commentid);
2264             $owner = ($comment->userid == $USER->id);
2266             if ($owner) {
2267                 $this->add_comment($this->content, $this->commentid);
2268             }
2269         } else if ($this->action == 'delete') {
2270             $comment = wiki_get_comment($this->commentid);
2272             $manage = has_capability('mod/wiki:managecomment', $this->modcontext);
2273             $edit = has_capability('mod/wiki:editcomment', $this->modcontext);
2274             $owner = ($comment->userid == $USER->id);
2276             if ($manage || ($owner && $edit)) {
2277                 $this->delete_comment($this->commentid);
2278                 redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $this->page->id, get_string('deletecomment', 'wiki'), 2);
2279             } else {
2280                 print_error('nopermissiontoeditcomment');
2281             }
2282         }
2284     }
2286     public function set_url() {
2287         global $PAGE, $CFG;
2288         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
2289     }
2291     public function set_action($action, $commentid, $content) {
2292         $this->action = $action;
2293         $this->commentid = $commentid;
2294         $this->content = $content;
2296         $version = wiki_get_current_version($this->page->id);
2297         $format = $version->contentformat;
2299         $this->format = $format;
2300     }
2302     private function add_comment($content, $idcomment) {
2303         global $CFG, $PAGE;
2304         require_once($CFG->dirroot . "/mod/wiki/locallib.php");
2306         $pageid = $this->page->id;
2308         wiki_add_comment($this->modcontext, $pageid, $content, $this->format);
2310         if (!$idcomment) {
2311             redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $pageid, get_string('createcomment', 'wiki'), 2);
2312         } else {
2313             $this->delete_comment($idcomment);
2314             redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $pageid, get_string('editingcomment', 'wiki'), 2);
2315         }
2316     }
2318     private function delete_comment($commentid) {
2319         global $CFG, $PAGE;
2321         $pageid = $this->page->id;
2323         wiki_delete_comment($commentid, $this->modcontext, $pageid);
2324     }
2328 class page_wiki_lock extends page_wiki_edit {
2330     public function print_header() {
2331         $this->set_url();
2332     }
2334     protected function set_url() {
2335         global $PAGE, $CFG;
2337         $params = array('pageid' => $this->page->id);
2339         if ($this->section) {
2340             $params['section'] = $this->section;
2341         }
2343         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/lock.php', $params);
2344     }
2346     protected function set_session_url() {
2347     }
2349     public function print_content() {
2350         global $USER, $PAGE;
2352         require_capability('mod/wiki:editpage', $this->modcontext, NULL, true, 'noeditpermission', 'wiki');
2354         wiki_set_lock($this->page->id, $USER->id, $this->section);
2355     }
2357     public function print_footer() {
2358     }
2361 class page_wiki_overridelocks extends page_wiki_edit {
2362     function print_header() {
2363         $this->set_url();
2364     }
2366     function print_content() {
2367         global $CFG, $PAGE;
2369         require_capability('mod/wiki:overridelock', $this->modcontext, NULL, true, 'nooverridelockpermission', 'wiki');
2371         wiki_delete_locks($this->page->id, null, $this->section, true, true);
2373         $args = "pageid=" . $this->page->id;
2375         if (!empty($this->section)) {
2376             $args .= "&section=" . urlencode($this->section);
2377         }
2379         redirect($CFG->wwwroot . '/mod/wiki/edit.php?' . $args, get_string('overridinglocks', 'wiki'), 2);
2380     }
2382     function set_url() {
2383         global $PAGE, $CFG;
2385         $params = array('pageid' => $this->page->id);
2387         if (!empty($this->section)) {
2388             $params['section'] = $this->section;
2389         }
2391         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/overridelocks.php', $params);
2392     }
2394     protected function set_session_url() {
2395     }
2397     private function print_overridelocks() {
2398         global $CFG;
2400         wiki_delete_locks($this->page->id, null, $this->section, true, true);
2402         $args = "pageid=" . $this->page->id;
2404         if (!empty($this->section)) {
2405             $args .= "&section=" . urlencode($this->section);
2406         }
2408         redirect($CFG->wwwroot . '/mod/wiki/edit.php?' . $args, get_string('overridinglocks', 'wiki'), 2);
2409     }
2413 /**
2414  * This class will let user to delete wiki pages and page versions
2415  *
2416  */
2417 class page_wiki_admin extends page_wiki {
2419     public $view, $action;
2420     public $listorphan = false;
2422     /**
2423      * Constructor
2424      *
2425      * @global object $PAGE
2426      * @param mixed $wiki instance of wiki
2427      * @param mixed $subwiki instance of subwiki
2428      * @param stdClass $cm course module
2429      */
2430     function __construct($wiki, $subwiki, $cm) {
2431         global $PAGE;
2432         parent::__construct($wiki, $subwiki, $cm);
2433         $PAGE->requires->js_init_call('M.mod_wiki.deleteversion', null, true);
2434     }
2436     /**
2437      * Prints header for wiki page
2438      */
2439     function print_header() {
2440         parent::print_header();
2441         $this->print_pagetitle();
2442     }
2444     /**
2445      * This function will display administration view to users with managewiki capability
2446      */
2447     function print_content() {
2448         //make sure anyone trying to access this page has managewiki capabilities
2449         require_capability('mod/wiki:managewiki', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2451         //update wiki cache if timedout
2452         $page = $this->page;
2453         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
2454             $fresh = wiki_refresh_cachedcontent($page);
2455             $page = $fresh['page'];
2456         }
2458         //dispaly admin menu
2459         echo $this->wikioutput->menu_admin($this->page->id, $this->view);
2461         //Display appropriate admin view
2462         switch ($this->view) {
2463             case 1: //delete page view
2464                 $this->print_delete_content($this->listorphan);
2465                 break;
2466             case 2: //delete version view
2467                 $this->print_delete_version();
2468                 break;
2469             default: //default is delete view
2470                 $this->print_delete_content($this->listorphan);
2471                 break;
2472         }
2473     }
2475     /**
2476      * Sets admin view option
2477      *
2478      * @param int $view page view id
2479      * @param bool $listorphan is only valid for view 1.
2480      */
2481     public function set_view($view, $listorphan = true) {
2482         $this->view = $view;
2483         $this->listorphan = $listorphan;
2484     }
2486     /**
2487      * Sets page url
2488      *
2489      * @global object $PAGE
2490      * @global object $CFG
2491      */
2492     function set_url() {
2493         global $PAGE, $CFG;
2494         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/admin.php', array('pageid' => $this->page->id));
2495     }
2497     /**
2498      * sets navigation bar for the page
2499      *
2500      * @global object $PAGE
2501      */
2502     protected function create_navbar() {
2503         global $PAGE;
2505         parent::create_navbar();
2506         $PAGE->navbar->add(get_string('admin', 'wiki'));
2507     }
2509     /**
2510      * Show wiki page delete options
2511      *
2512      * @param bool $showorphan
2513      */
2514     protected function print_delete_content($showorphan = true) {
2515         $contents = array();
2516         $table = new html_table();
2517         $table->head = array('', get_string('pagename','wiki'));
2518         $table->attributes['class'] = 'generaltable mdl-align';
2519         $swid = $this->subwiki->id;
2520         if ($showorphan) {
2521             if ($orphanedpages = wiki_get_orphaned_pages($swid)) {
2522                 $this->add_page_delete_options($orphanedpages, $swid, $table);
2523             } else {
2524                 $table->data[] = array('', get_string('noorphanedpages', 'wiki'));
2525             }
2526         } else {
2527             if ($pages = wiki_get_page_list($swid)) {
2528                 $this->add_page_delete_options($pages, $swid, $table);
2529             } else {
2530                 $table->data[] = array('', get_string('nopages', 'wiki'));
2531             }
2532         }
2534         ///Print the form
2535         echo html_writer::start_tag('form', array(
2536                                                 'action' => new moodle_url('/mod/wiki/admin.php'),
2537                                                 'method' => 'post'));
2538         echo html_writer::tag('div', html_writer::empty_tag('input', array(
2539                                                                          'type'  => 'hidden',
2540                                                                          'name'  => 'pageid',
2541                                                                          'value' => $this->page->id)));
2543         echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'option', 'value' => $this->view));
2544         echo html_writer::table($table);
2545         echo html_writer::start_tag('div', array('class' => 'mdl-align'));
2546         if (!$showorphan) {
2547             echo html_writer::empty_tag('input', array(
2548                                                      'type'    => 'submit',
2549                                                      'class'   => 'wiki_form-button',
2550                                                      'value'   => get_string('listorphan', 'wiki'),
2551                                                      'sesskey' => sesskey()));
2552         } else {
2553             echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'listall', 'value'=>'1'));
2554             echo html_writer::empty_tag('input', array(
2555                                                      'type'    => 'submit',
2556                                                      'class'   => 'wiki_form-button',
2557                                                      'value'   => get_string('listall', 'wiki'),
2558                                                      'sesskey' => sesskey()));
2559         }
2560         echo html_writer::end_tag('div');
2561         echo html_writer::end_tag('form');
2562     }
2564     /**
2565      * helper function for print_delete_content. This will add data to the table.
2566      *
2567      * @global object $OUTPUT
2568      * @param array $pages objects of wiki pages in subwiki
2569      * @param int $swid id of subwiki
2570      * @param object $table reference to the table in which data needs to be added
2571      */
2572     protected function add_page_delete_options($pages, $swid, &$table) {
2573         global $OUTPUT;
2574         foreach ($pages as $page) {
2575             $link = wiki_parser_link($page->title, array('swid' => $swid));
2576             $class = ($link['new']) ? 'class="wiki_newentry"' : '';
2577             $pagelink = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>';
2578             $urledit = new moodle_url('/mod/wiki/edit.php', array('pageid' => $page->id, 'sesskey' => sesskey()));
2579             $urldelete = new moodle_url('/mod/wiki/admin.php', array(
2580                                                                    'pageid'  => $this->page->id,
2581                                                                    'delete'  => $page->id,
2582                                                                    'option'  => $this->view,
2583                                                                    'listall' => !$this->listorphan?'1': '',
2584                                                                    'sesskey' => sesskey()));
2586             $editlinks = $OUTPUT->action_icon($urledit, new pix_icon('t/edit', get_string('edit')));
2587             $editlinks .= $OUTPUT->action_icon($urldelete, new pix_icon('t/delete', get_string('delete')));
2588             $table->data[] = array($editlinks, $pagelink);
2589         }
2590     }
2592     /**
2593      * Prints lists of versions which can be deleted
2594      *
2595      * @global core_renderer $OUTPUT
2596      * @global moodle_page $PAGE
2597      */
2598     private function print_delete_version() {
2599         global $OUTPUT, $PAGE;
2600         $pageid = $this->page->id;
2602         // versioncount is the latest version
2603         $versioncount = wiki_count_wiki_page_versions($pageid) - 1;
2604         $versions = wiki_get_wiki_page_versions($pageid, 0, $versioncount);
2606         // We don't want version 0 to be displayed
2607         // version 0 is blank page
2608         if (end($versions)->version == 0) {
2609             array_pop($versions);
2610         }
2612         $contents = array();
2613         $version0page = wiki_get_wiki_page_version($this->page->id, 0);
2614         $creator = wiki_get_user_info($version0page->userid);
2615         $a = new stdClass();
2616         $a->date = userdate($this->page->timecreated, get_string('strftimedaydatetime', 'langconfig'));
2617         $a->username = fullname($creator);
2618         echo $OUTPUT->heading(get_string('createddate', 'wiki', $a), 4);
2619         if ($versioncount > 0) {
2620             /// If there is only one version, we don't need radios nor forms
2621             if (count($versions) == 1) {
2622                 $row = array_shift($versions);
2623                 $username = wiki_get_user_info($row->userid);
2624                 $picture = $OUTPUT->user_picture($username);
2625                 $date = userdate($row->timecreated, get_string('strftimedate', 'langconfig'));
2626                 $time = userdate($row->timecreated, get_string('strftimetime', 'langconfig'));
2627                 $versionid = wiki_get_version($row->id);
2628                 $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
2629                 $userlink = new moodle_url('/user/view.php', array('id' => $username->id, 'course' => $this->cm->course));
2630                 $picturelink = $picture . html_writer::link($userlink->out(false), fullname($username));
2631                 $historydate = $OUTPUT->container($date, 'wiki_histdate');
2632                 $contents[] = array('', html_writer::link($versionlink->out(false), $row->version), $picturelink, $time, $historydate);
2634                 //Show current version
2635                 $table = new html_table();
2636                 $table->head = array('', get_string('version'), get_string('user'), get_string('modified'), '');
2637                 $table->data = $contents;
2638                 $table->attributes['class'] = 'mdl-align';
2640                 echo html_writer::table($table);
2641             } else {
2642                 $lastdate = '';
2643                 $rowclass = array();
2645                 foreach ($versions as $version) {
2646                     $user = wiki_get_user_info($version->userid);
2647                     $picture = $OUTPUT->user_picture($user, array('popup' => true));
2648                     $date = userdate($version->timecreated, get_string('strftimedate'));
2649                     if ($date == $lastdate) {
2650                         $date = '';
2651                         $rowclass[] = '';
2652                     } else {
2653                         $lastdate = $date;
2654                         $rowclass[] = 'wiki_histnewdate';
2655                     }
2657                     $time = userdate($version->timecreated, get_string('strftimetime', 'langconfig'));
2658                     $versionid = wiki_get_version($version->id);
2659                     if ($versionid) {
2660                         $url = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
2661                         $viewlink = html_writer::link($url->out(false), $version->version);
2662                     } else {
2663                         $viewlink = $version->version;
2664                     }
2666                     $userlink = new moodle_url('/user/view.php', array('id' => $version->userid, 'course' => $this->cm->course));
2667                     $picturelink = $picture . html_writer::link($userlink->out(false), fullname($user));
2668                     $historydate = $OUTPUT->container($date, 'wiki_histdate');
2669                     $radiofromelement = $this->choose_from_radio(array($version->version  => null), 'fromversion', 'M.mod_wiki.deleteversion()', $versioncount, true);
2670                     $radiotoelement = $this->choose_from_radio(array($version->version  => null), 'toversion', 'M.mod_wiki.deleteversion()', $versioncount, true);
2671                     $contents[] = array( $radiofromelement . $radiotoelement, $viewlink, $picturelink, $time, $historydate);
2672                 }
2674                 $table = new html_table();
2675                 $table->head = array(get_string('deleteversions', 'wiki'), get_string('version'), get_string('user'), get_string('modified'), '');
2676                 $table->data = $contents;
2677                 $table->attributes['class'] = 'generaltable mdl-align';
2678                 $table->rowclasses = $rowclass;
2680                 ///Print the form
2681                 echo html_writer::start_tag('form', array('action'=>new moodle_url('/mod/wiki/admin.php'), 'method' => 'post'));
2682                 echo html_writer::tag('div', html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'pageid', 'value' => $pageid)));
2683                 echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'option', 'value' => $this->view));
2684                 echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' =>  sesskey()));
2685                 echo html_writer::table($table);
2686                 echo html_writer::start_tag('div', array('class' => 'mdl-align'));
2687                 echo html_writer::empty_tag('input', array('type' => 'submit', 'class' => 'wiki_form-button', 'value' => get_string('deleteversions', 'wiki')));
2688                 echo html_writer::end_tag('div');
2689                 echo html_writer::end_tag('form');
2690             }
2691         } else {
2692             print_string('nohistory', 'wiki');
2693         }
2694     }
2696     /**
2697      * Given an array of values, creates a group of radio buttons to be part of a form
2698      * helper function for print_delete_version
2699      *
2700      * @param array  $options  An array of value-label pairs for the radio group (values as keys).
2701      * @param string $name     Name of the radiogroup (unique in the form).
2702      * @param string $onclick  Function to be executed when the radios are clicked.
2703      * @param string $checked  The value that is already checked.
2704      * @param bool   $return   If true, return the HTML as a string, otherwise print it.
2705      *
2706      * @return mixed If $return is false, returns nothing, otherwise returns a string of HTML.
2707      */
2708     private function choose_from_radio($options, $name, $onclick = '', $checked = '', $return = false) {
2710         static $idcounter = 0;
2712         if (!$name) {
2713             $name = 'unnamed';
2714         }
2716         $output = '<span class="radiogroup ' . $name . "\">\n";
2718         if (!empty($options)) {
2719             $currentradio = 0;
2720             foreach ($options as $value => $label) {
2721                 $htmlid = 'auto-rb' . sprintf('%04d', ++$idcounter);
2722                 $output .= ' <span class="radioelement ' . $name . ' rb' . $currentradio . "\">";
2723                 $output .= '<input name="' . $name . '" id="' . $htmlid . '" type="radio" value="' . $value . '"';
2724                 if ($value == $checked) {
2725                     $output .= ' checked="checked"';
2726                 }
2727                 if ($onclick) {
2728                     $output .= ' onclick="' . $onclick . '"';
2729                 }
2730                 if ($label === '') {
2731                     $output .= ' /> <label for="' . $htmlid . '">' . $value . '</label></span>' . "\n";
2732                 } else {
2733                     $output .= ' /> <label for="' . $htmlid . '">' . $label . '</label></span>' . "\n";
2734                 }
2735                 $currentradio = ($currentradio + 1) % 2;
2736             }
2737         }
2739         $output .= '</span>' . "\n";
2741         if ($return) {
2742             return $output;
2743         } else {
2744             echo $output;
2745         }
2746     }