MDL-53765 mod_resource/mod_wiki: Removed update_module_button()
[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 print_header() {
982         global $PAGE, $CFG;
984         parent::print_header();
986     }
988     function print_content() {
989         global $PAGE;
991         require_capability('mod/wiki:editpage', $this->modcontext, NULL, true, 'noeditpermission', 'wiki');
993         $this->print_preview();
994     }
996     function set_newcontent($newcontent) {
997         $this->newcontent = $newcontent;
998     }
1000     function set_url() {
1001         global $PAGE, $CFG;
1003         $params = array('pageid' => $this->page->id
1004         );
1006         if (isset($this->section)) {
1007             $params['section'] = $this->section;
1008         }
1010         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/edit.php', $params);
1011     }
1013     protected function setup_tabs($options = array()) {
1014         parent::setup_tabs(array('linkedwhenactive' => 'view', 'activetab' => 'view'));
1015     }
1017     protected function check_locks() {
1018         return true;
1019     }
1021     protected function print_preview() {
1022         global $CFG, $PAGE, $OUTPUT;
1024         $version = wiki_get_current_version($this->page->id);
1025         $format = $version->contentformat;
1026         $content = $version->content;
1028         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
1029         if (!empty($this->section)) {
1030             $url .= "&section=" . urlencode($this->section);
1031         }
1032         $params = array(
1033             'attachmentoptions' => page_wiki_edit::$attachmentoptions,
1034             'format' => $this->format,
1035             'version' => $this->versionnumber,
1036             'contextid' => $this->modcontext->id
1037         );
1039         if ($this->format != 'html') {
1040             $params['component'] = 'mod_wiki';
1041             $params['filearea'] = 'attachments';
1042             $params['fileitemid'] = $this->page->id;
1043         }
1044         $form = new mod_wiki_edit_form($url, $params);
1047         $options = array('swid' => $this->page->subwikiid, 'pageid' => $this->page->id, 'pretty_print' => true);
1049         if ($data = $form->get_data()) {
1050             if (isset($data->newcontent)) {
1051                 // wiki fromat
1052                 $text = $data->newcontent;
1053             } else {
1054                 // html format
1055                 $text = $data->newcontent_editor['text'];
1056             }
1057             $parseroutput = wiki_parse_content($data->contentformat, $text, $options);
1058             $this->set_newcontent($text);
1059             echo $OUTPUT->notification(get_string('previewwarning', 'wiki'), 'notifyproblem');
1060             $content = format_text($parseroutput['parsed_text'], FORMAT_HTML, array('overflowdiv'=>true, 'filter'=>false));
1061             echo $OUTPUT->box($content, 'generalbox wiki_previewbox');
1062             $content = $this->newcontent;
1063         }
1065         $this->print_edit($content);
1066     }
1070 /**
1071  *
1072  * Class that models the behavior of wiki's
1073  * view differences
1074  *
1075  */
1076 class page_wiki_diff extends page_wiki {
1078     private $compare;
1079     private $comparewith;
1081     function print_header() {
1082         global $OUTPUT;
1084         parent::print_header();
1086         $this->print_pagetitle();
1087         $vstring = new stdClass();
1088         $vstring->old = $this->compare;
1089         $vstring->new = $this->comparewith;
1090         echo html_writer::tag('div', get_string('comparewith', 'wiki', $vstring), array('class' => 'wiki_headingtitle'));
1091     }
1093     /**
1094      * Print the diff view
1095      */
1096     function print_content() {
1097         global $PAGE;
1099         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1101         $this->print_diff_content();
1102     }
1104     function set_url() {
1105         global $PAGE, $CFG;
1107         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/diff.php', array('pageid' => $this->page->id, 'comparewith' => $this->comparewith, 'compare' => $this->compare));
1108     }
1110     function set_comparison($compare, $comparewith) {
1111         $this->compare = $compare;
1112         $this->comparewith = $comparewith;
1113     }
1115     protected function create_navbar() {
1116         global $PAGE, $CFG;
1118         parent::create_navbar();
1119         $PAGE->navbar->add(get_string('history', 'wiki'), $CFG->wwwroot . '/mod/wiki/history.php?pageid=' . $this->page->id);
1120         $PAGE->navbar->add(get_string('diff', 'wiki'));
1121     }
1123     protected function setup_tabs($options = array()) {
1124         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history'));
1125     }
1127     /**
1128      * Given two versions of a page, prints a page displaying the differences between them.
1129      *
1130      * @global object $CFG
1131      * @global object $OUTPUT
1132      * @global object $PAGE
1133      */
1134     private function print_diff_content() {
1135         global $CFG, $OUTPUT, $PAGE;
1137         $pageid = $this->page->id;
1138         $total = wiki_count_wiki_page_versions($pageid) - 1;
1140         $oldversion = wiki_get_wiki_page_version($pageid, $this->compare);
1142         $newversion = wiki_get_wiki_page_version($pageid, $this->comparewith);
1144         if ($oldversion && $newversion) {
1146             $oldtext = format_text(file_rewrite_pluginfile_urls($oldversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id));
1147             $newtext = format_text(file_rewrite_pluginfile_urls($newversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id));
1148             list($diff1, $diff2) = ouwiki_diff_html($oldtext, $newtext);
1149             $oldversion->diff = $diff1;
1150             $oldversion->user = wiki_get_user_info($oldversion->userid);
1151             $newversion->diff = $diff2;
1152             $newversion->user = wiki_get_user_info($newversion->userid);
1154             echo $this->wikioutput->diff($pageid, $oldversion, $newversion, array('total' => $total));
1155         } else {
1156             print_error('versionerror', 'wiki');
1157         }
1158     }
1161 /**
1162  *
1163  * Class that models the behavior of wiki's history page
1164  *
1165  */
1166 class page_wiki_history extends page_wiki {
1167     /**
1168      * @var int $paging current page
1169      */
1170     private $paging;
1172     /**
1173      * @var int @rowsperpage Items per page
1174      */
1175     private $rowsperpage = 10;
1177     /**
1178      * @var int $allversion if $allversion != 0, all versions will be printed in a signle table
1179      */
1180     private $allversion;
1182     function __construct($wiki, $subwiki, $cm) {
1183         global $PAGE;
1184         parent::__construct($wiki, $subwiki, $cm);
1185         $PAGE->requires->js_init_call('M.mod_wiki.history', null, true);
1186     }
1188     function print_header() {
1189         parent::print_header();
1190         $this->print_pagetitle();
1191     }
1193     function print_pagetitle() {
1194         global $OUTPUT;
1195         $html = '';
1197         $html .= $OUTPUT->container_start('wiki_headingtitle');
1198         $html .= $OUTPUT->heading_with_help(format_string($this->title), 'history', 'wiki', '', '', 3);
1199         $html .= $OUTPUT->container_end();
1200         echo $html;
1201     }
1203     function print_content() {
1204         global $PAGE;
1206         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1208         $this->print_history_content();
1209     }
1211     function set_url() {
1212         global $PAGE, $CFG;
1213         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/history.php', array('pageid' => $this->page->id));
1214     }
1216     function set_paging($paging) {
1217         $this->paging = $paging;
1218     }
1220     function set_allversion($allversion) {
1221         $this->allversion = $allversion;
1222     }
1224     protected function create_navbar() {
1225         global $PAGE, $CFG;
1227         parent::create_navbar();
1228         $PAGE->navbar->add(get_string('history', 'wiki'));
1229     }
1231     /**
1232      * Prints the history for a given wiki page
1233      *
1234      * @global object $CFG
1235      * @global object $OUTPUT
1236      * @global object $PAGE
1237      */
1238     private function print_history_content() {
1239         global $CFG, $OUTPUT, $PAGE;
1241         $pageid = $this->page->id;
1242         $offset = $this->paging * $this->rowsperpage;
1243         // vcount is the latest version
1244         $vcount = wiki_count_wiki_page_versions($pageid) - 1;
1245         if ($this->allversion) {
1246             $versions = wiki_get_wiki_page_versions($pageid, 0, $vcount);
1247         } else {
1248             $versions = wiki_get_wiki_page_versions($pageid, $offset, $this->rowsperpage);
1249         }
1250         // We don't want version 0 to be displayed
1251         // version 0 is blank page
1252         if (end($versions)->version == 0) {
1253             array_pop($versions);
1254         }
1256         $contents = array();
1258         $version0page = wiki_get_wiki_page_version($this->page->id, 0);
1259         $creator = wiki_get_user_info($version0page->userid);
1260         $a = new StdClass;
1261         $a->date = userdate($this->page->timecreated, get_string('strftimedaydatetime', 'langconfig'));
1262         $a->username = fullname($creator);
1263         echo html_writer::tag ('div', get_string('createddate', 'wiki', $a), array('class' => 'wiki_headingtime'));
1264         if ($vcount > 0) {
1266             /// If there is only one version, we don't need radios nor forms
1267             if (count($versions) == 1) {
1269                 $row = array_shift($versions);
1271                 $username = wiki_get_user_info($row->userid);
1272                 $picture = $OUTPUT->user_picture($username);
1273                 $date = userdate($row->timecreated, get_string('strftimedate', 'langconfig'));
1274                 $time = userdate($row->timecreated, get_string('strftimetime', 'langconfig'));
1275                 $versionid = wiki_get_version($row->id);
1276                 $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
1277                 $userlink = new moodle_url('/user/view.php', array('id' => $username->id, 'course' => $this->cm->course));
1278                 $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'));
1280                 $table = new html_table();
1281                 $table->head = array('', get_string('version'), get_string('user'), get_string('modified'), '');
1282                 $table->data = $contents;
1283                 $table->attributes['class'] = 'mdl-align';
1285                 echo html_writer::table($table);
1287             } else {
1289                 $checked = $vcount - $offset;
1290                 $rowclass = array();
1292                 foreach ($versions as $version) {
1293                     $user = wiki_get_user_info($version->userid);
1294                     $picture = $OUTPUT->user_picture($user, array('popup' => true));
1295                     $date = userdate($version->timecreated, get_string('strftimedate'));
1296                     $rowclass[] = 'wiki_histnewdate';
1297                     $time = userdate($version->timecreated, get_string('strftimetime', 'langconfig'));
1298                     $versionid = wiki_get_version($version->id);
1299                     if ($versionid) {
1300                         $url = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
1301                         $viewlink = html_writer::link($url->out(false), $version->version);
1302                     } else {
1303                         $viewlink = $version->version;
1304                     }
1305                     $userlink = new moodle_url('/user/view.php', array('id' => $version->userid, 'course' => $this->cm->course));
1306                     $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'));
1307                 }
1309                 $table = new html_table();
1311                 $icon = $OUTPUT->help_icon('diff', 'wiki');
1313                 $table->head = array(get_string('diff', 'wiki') . $icon, get_string('version'), get_string('user'), get_string('modified'), '');
1314                 $table->data = $contents;
1315                 $table->attributes['class'] = 'generaltable mdl-align';
1316                 $table->rowclasses = $rowclass;
1318                 // Print the form.
1319                 echo html_writer::start_tag('form', array('action'=>new moodle_url('/mod/wiki/diff.php'), 'method'=>'get', 'id'=>'diff'));
1320                 echo html_writer::tag('div', html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'pageid', 'value'=>$pageid)));
1321                 echo html_writer::table($table);
1322                 echo html_writer::start_tag('div', array('class'=>'mdl-align'));
1323                 echo html_writer::empty_tag('input', array('type'=>'submit', 'class'=>'wiki_form-button', 'value'=>get_string('comparesel', 'wiki')));
1324                 echo html_writer::end_tag('div');
1325                 echo html_writer::end_tag('form');
1326             }
1327         } else {
1328             print_string('nohistory', 'wiki');
1329         }
1330         if (!$this->allversion) {
1331             //$pagingbar = moodle_paging_bar::make($vcount, $this->paging, $this->rowsperpage, $CFG->wwwroot.'/mod/wiki/history.php?pageid='.$pageid.'&amp;');
1332             // $pagingbar->pagevar = $pagevar;
1333             echo $OUTPUT->paging_bar($vcount, $this->paging, $this->rowsperpage, $CFG->wwwroot . '/mod/wiki/history.php?pageid=' . $pageid . '&amp;');
1334             //print_paging_bar($vcount, $paging, $rowsperpage,$CFG->wwwroot.'/mod/wiki/history.php?pageid='.$pageid.'&amp;','paging');
1335             } else {
1336             $link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid));
1337             $OUTPUT->container(html_writer::link($link->out(false), get_string('viewperpage', 'wiki', $this->rowsperpage)), 'mdl-align');
1338         }
1339         if ($vcount > $this->rowsperpage && !$this->allversion) {
1340             $link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid, 'allversion' => 1));
1341             $OUTPUT->container(html_writer::link($link->out(false), get_string('viewallhistory', 'wiki')), 'mdl-align');
1342         }
1343     }
1345     /**
1346      * Given an array of values, creates a group of radio buttons to be part of a form
1347      *
1348      * @param array  $options  An array of value-label pairs for the radio group (values as keys).
1349      * @param string $name     Name of the radiogroup (unique in the form).
1350      * @param string $onclick  Function to be executed when the radios are clicked.
1351      * @param string $checked  The value that is already checked.
1352      * @param bool   $return   If true, return the HTML as a string, otherwise print it.
1353      *
1354      * @return mixed If $return is false, returns nothing, otherwise returns a string of HTML.
1355      */
1356     private function choose_from_radio($options, $name, $onclick = '', $checked = '', $return = false) {
1358         static $idcounter = 0;
1360         if (!$name) {
1361             $name = 'unnamed';
1362         }
1364         $output = '<span class="radiogroup ' . $name . "\">\n";
1366         if (!empty($options)) {
1367             $currentradio = 0;
1368             foreach ($options as $value => $label) {
1369                 $htmlid = 'auto-rb' . sprintf('%04d', ++$idcounter);
1370                 $output .= ' <span class="radioelement ' . $name . ' rb' . $currentradio . "\">";
1371                 $output .= '<input name="' . $name . '" id="' . $htmlid . '" type="radio" value="' . $value . '"';
1372                 if ($value == $checked) {
1373                     $output .= ' checked="checked"';
1374                 }
1375                 if ($onclick) {
1376                     $output .= ' onclick="' . $onclick . '"';
1377                 }
1378                 if ($label === '') {
1379                     $output .= ' /> <label for="' . $htmlid . '">' . $value . '</label></span>' . "\n";
1380                 } else {
1381                     $output .= ' /> <label for="' . $htmlid . '">' . $label . '</label></span>' . "\n";
1382                 }
1383                 $currentradio = ($currentradio + 1) % 2;
1384             }
1385         }
1387         $output .= '</span>' . "\n";
1389         if ($return) {
1390             return $output;
1391         } else {
1392             echo $output;
1393         }
1394     }
1397 /**
1398  * Class that models the behavior of wiki's map page
1399  *
1400  */
1401 class page_wiki_map extends page_wiki {
1403     /**
1404      * @var int wiki view option
1405      */
1406     private $view;
1408     function print_header() {
1409         parent::print_header();
1410         $this->print_pagetitle();
1411     }
1413     function print_content() {
1414         global $CFG, $PAGE;
1416         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1418         if ($this->view > 0) {
1419             //echo '<div><a href="' . $CFG->wwwroot . '/mod/wiki/map.php?pageid=' . $this->page->id . '">' . get_string('backtomapmenu', 'wiki') . '</a></div>';
1420         }
1422         switch ($this->view) {
1423         case 1:
1424             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1425             $this->print_contributions_content();
1426             break;
1427         case 2:
1428             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1429             $this->print_navigation_content();
1430             break;
1431         case 3:
1432             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1433             $this->print_orphaned_content();
1434             break;
1435         case 4:
1436             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1437             $this->print_index_content();
1438             break;
1439         case 6:
1440             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1441             $this->print_updated_content();
1442             break;
1443         case 5:
1444         default:
1445             echo $this->wikioutput->menu_map($this->page->id, $this->view);
1446             $this->print_page_list_content();
1447         }
1448     }
1450     function set_view($option) {
1451         $this->view = $option;
1452     }
1454     function set_url() {
1455         global $PAGE, $CFG;
1456         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/map.php', array('pageid' => $this->page->id));
1457     }
1459     protected function create_navbar() {
1460         global $PAGE;
1462         parent::create_navbar();
1463         $PAGE->navbar->add(get_string('map', 'wiki'));
1464     }
1466     /**
1467      * Prints the contributions tab content
1468      *
1469      * @uses $OUTPUT, $USER
1470      *
1471      */
1472     private function print_contributions_content() {
1473         global $CFG, $OUTPUT, $USER;
1474         $page = $this->page;
1476         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1477             $fresh = wiki_refresh_cachedcontent($page);
1478             $page = $fresh['page'];
1479         }
1481         $swid = $this->subwiki->id;
1483         $table = new html_table();
1484         $table->head = array(get_string('contributions', 'wiki') . $OUTPUT->help_icon('contributions', 'wiki'));
1485         $table->attributes['class'] = 'wiki_editor generalbox';
1486         $table->data = array();
1487         $table->rowclasses = array();
1489         $lastversions = array();
1490         $pages = array();
1491         $users = array();
1493         if ($contribs = wiki_get_contributions($swid, $USER->id)) {
1494             foreach ($contribs as $contrib) {
1495                 if (!array_key_exists($contrib->pageid, $pages)) {
1496                     $page = wiki_get_page($contrib->pageid);
1497                     $pages[$contrib->pageid] = $page;
1498                 } else {
1499                     continue;
1500                 }
1502                 if (!array_key_exists($page->id, $lastversions)) {
1503                     $version = wiki_get_last_version($page->id);
1504                     $lastversions[$page->id] = $version;
1505                 } else {
1506                     $version = $lastversions[$page->id];
1507                 }
1509                 if (!array_key_exists($version->userid, $users)) {
1510                     $user = wiki_get_user_info($version->userid);
1511                     $users[$version->userid] = $user;
1512                 } else {
1513                     $user = $users[$version->userid];
1514                 }
1516                 $link = wiki_parser_link($page->title, array('swid' => $swid));
1517                 $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1519                 $linkpage = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content'], true, array('context' => $this->modcontext)) . '</a>';
1520                 $icon = $OUTPUT->user_picture($user, array('popup' => true));
1522                 $table->data[] = array("$icon&nbsp;$linkpage");
1523             }
1524         } else {
1525             $table->data[] = array(get_string('nocontribs', 'wiki'));
1526         }
1527         echo html_writer::table($table);
1528     }
1530     /**
1531      * Prints the navigation tab content
1532      *
1533      * @uses $OUTPUT
1534      *
1535      */
1536     private function print_navigation_content() {
1537         global $OUTPUT;
1538         $page = $this->page;
1540         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1541             $fresh = wiki_refresh_cachedcontent($page);
1542             $page = $fresh['page'];
1543         }
1545         $tolinks = wiki_get_linked_to_pages($page->id);
1546         $fromlinks = wiki_get_linked_from_pages($page->id);
1548         $table = new html_table();
1549         $table->attributes['class'] = 'wiki_navigation_from';
1550         $table->head = array(get_string('navigationfrom', 'wiki') . $OUTPUT->help_icon('navigationfrom', 'wiki') . ':');
1551         $table->data = array();
1552         $table->rowclasses = array();
1553         foreach ($fromlinks as $link) {
1554             $lpage = wiki_get_page($link->frompageid);
1555             $link = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
1556             $table->data[] = array(html_writer::link($link->out(false), format_string($lpage->title)));
1557             $table->rowclasses[] = 'mdl-align';
1558         }
1560         $table_left = html_writer::table($table);
1562         $table = new html_table();
1563         $table->attributes['class'] = 'wiki_navigation_to';
1564         $table->head = array(get_string('navigationto', 'wiki') . $OUTPUT->help_icon('navigationto', 'wiki') . ':');
1565         $table->data = array();
1566         $table->rowclasses = array();
1567         foreach ($tolinks as $link) {
1568             if ($link->tomissingpage) {
1569                 $viewlink = new moodle_url('/mod/wiki/create.php', array('swid' => $page->subwikiid, 'title' => $link->tomissingpage, 'action' => 'new'));
1570                 $table->data[] = array(html_writer::link($viewlink->out(false), format_string($link->tomissingpage), array('class' => 'wiki_newentry')));
1571             } else {
1572                 $lpage = wiki_get_page($link->topageid);
1573                 $viewlink = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
1574                 $table->data[] = array(html_writer::link($viewlink->out(false), format_string($lpage->title)));
1575             }
1576             $table->rowclasses[] = 'mdl-align';
1577         }
1578         $table_right = html_writer::table($table);
1579         echo $OUTPUT->container($table_left . $table_right, 'wiki_navigation_container');
1580     }
1582     /**
1583      * Prints the index page tab content
1584      *
1585      *
1586      */
1587     private function print_index_content() {
1588         global $OUTPUT;
1589         $page = $this->page;
1591         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1592             $fresh = wiki_refresh_cachedcontent($page);
1593             $page = $fresh['page'];
1594         }
1596         // navigation_node get_content calls format string for us
1597         $node = new navigation_node($page->title);
1599         $keys = array();
1600         $tree = array();
1601         $tree = wiki_build_tree($page, $node, $keys);
1603         $table = new html_table();
1604         $table->head = array(get_string('pageindex', 'wiki') . $OUTPUT->help_icon('pageindex', 'wiki'));
1605         $table->attributes['class'] = 'wiki_editor generalbox';
1606         $table->data[] = array($this->render_navigation_node($tree));
1608         echo html_writer::table($table);
1609     }
1611     /**
1612      * Prints the page list tab content
1613      *
1614      *
1615      */
1616     private function print_page_list_content() {
1617         global $OUTPUT;
1618         $page = $this->page;
1620         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1621             $fresh = wiki_refresh_cachedcontent($page);
1622             $page = $fresh['page'];
1623         }
1625         $pages = wiki_get_page_list($this->subwiki->id);
1627         $stdaux = new stdClass();
1628         $strspecial = get_string('special', 'wiki');
1630         foreach ($pages as $page) {
1631             // We need to format the title here to account for any filtering
1632             $letter = format_string($page->title, true, array('context' => $this->modcontext));
1633             $letter = core_text::substr($letter, 0, 1);
1634             if (preg_match('/^[a-zA-Z]$/', $letter)) {
1635                 $letter = core_text::strtoupper($letter);
1636                 $stdaux->{$letter}[] = wiki_parser_link($page);
1637             } else {
1638                 $stdaux->{$strspecial}[] = wiki_parser_link($page);
1639             }
1640         }
1642         $table = new html_table();
1643         $table->head = array(get_string('pagelist', 'wiki') . $OUTPUT->help_icon('pagelist', 'wiki'));
1644         $table->attributes['class'] = 'wiki_editor generalbox';
1645         $table->align = array('center');
1646         foreach ($stdaux as $key => $elem) {
1647             $table->data[] = array($key);
1648             foreach ($elem as $e) {
1649                 $table->data[] = array(html_writer::link($e['url'], format_string($e['content'], true, array('context' => $this->modcontext))));
1650             }
1651         }
1652         echo html_writer::table($table);
1653     }
1655     /**
1656      * Prints the orphaned tab content
1657      *
1658      *
1659      */
1660     private function print_orphaned_content() {
1661         global $OUTPUT;
1663         $page = $this->page;
1665         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1666             $fresh = wiki_refresh_cachedcontent($page);
1667             $page = $fresh['page'];
1668         }
1670         $swid = $this->subwiki->id;
1672         $table = new html_table();
1673         $table->head = array(get_string('orphaned', 'wiki') . $OUTPUT->help_icon('orphaned', 'wiki'));
1674         $table->attributes['class'] = 'wiki_editor generalbox';
1675         $table->data = array();
1676         $table->rowclasses = array();
1678         if ($orphanedpages = wiki_get_orphaned_pages($swid)) {
1679             foreach ($orphanedpages as $page) {
1680                 $link = wiki_parser_link($page->title, array('swid' => $swid));
1681                 $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1682                 $table->data[] = array('<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>');
1683             }
1684         } else {
1685             $table->data[] = array(get_string('noorphanedpages', 'wiki'));
1686         }
1688         echo html_writer::table($table);
1689     }
1691     /**
1692      * Prints the updated tab content
1693      *
1694      * @uses $COURSE, $OUTPUT
1695      *
1696      */
1697     private function print_updated_content() {
1698         global $COURSE, $OUTPUT;
1699         $page = $this->page;
1701         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1702             $fresh = wiki_refresh_cachedcontent($page);
1703             $page = $fresh['page'];
1704         }
1706         $swid = $this->subwiki->id;
1708         $table = new html_table();
1709         $table->head = array(get_string('updatedpages', 'wiki') . $OUTPUT->help_icon('updatedpages', 'wiki'));
1710         $table->attributes['class'] = 'wiki_editor generalbox';
1711         $table->data = array();
1712         $table->rowclasses = array();
1714         if ($pages = wiki_get_updated_pages_by_subwiki($swid)) {
1715             $strdataux = '';
1716             foreach ($pages as $page) {
1717                 $user = wiki_get_user_info($page->userid);
1718                 $strdata = strftime('%d %b %Y', $page->timemodified);
1719                 if ($strdata != $strdataux) {
1720                     $table->data[] = array($OUTPUT->heading($strdata, 4));
1721                     $strdataux = $strdata;
1722                 }
1723                 $link = wiki_parser_link($page->title, array('swid' => $swid));
1724                 $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1726                 $linkpage = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>';
1727                 $icon = $OUTPUT->user_picture($user, array($COURSE->id));
1728                 $table->data[] = array("$icon&nbsp;$linkpage");
1729             }
1730         } else {
1731             $table->data[] = array(get_string('noupdatedpages', 'wiki'));
1732         }
1734         echo html_writer::table($table);
1735     }
1737     protected function render_navigation_node($items, $attrs = array(), $expansionlimit = null, $depth = 1) {
1739         // exit if empty, we don't want an empty ul element
1740         if (count($items) == 0) {
1741             return '';
1742         }
1744         // array of nested li elements
1745         $lis = array();
1746         foreach ($items as $item) {
1747             if (!$item->display) {
1748                 continue;
1749             }
1750             $content = $item->get_content();
1751             $title = $item->get_title();
1752             if ($item->icon instanceof renderable) {
1753                 $icon = $this->wikioutput->render($item->icon);
1754                 $content = $icon . '&nbsp;' . $content; // use CSS for spacing of icons
1755                 }
1756             if ($item->helpbutton !== null) {
1757                 $content = trim($item->helpbutton) . html_writer::tag('span', $content, array('class' => 'clearhelpbutton'));
1758             }
1760             if ($content === '') {
1761                 continue;
1762             }
1764             if ($item->action instanceof action_link) {
1765                 //TODO: to be replaced with something else
1766                 $link = $item->action;
1767                 if ($item->hidden) {
1768                     $link->add_class('dimmed');
1769                 }
1770                 $content = $this->output->render($link);
1771             } else if ($item->action instanceof moodle_url) {
1772                 $attributes = array();
1773                 if ($title !== '') {
1774                     $attributes['title'] = $title;
1775                 }
1776                 if ($item->hidden) {
1777                     $attributes['class'] = 'dimmed_text';
1778                 }
1779                 $content = html_writer::link($item->action, $content, $attributes);
1781             } else if (is_string($item->action) || empty($item->action)) {
1782                 $attributes = array();
1783                 if ($title !== '') {
1784                     $attributes['title'] = $title;
1785                 }
1786                 if ($item->hidden) {
1787                     $attributes['class'] = 'dimmed_text';
1788                 }
1789                 $content = html_writer::tag('span', $content, $attributes);
1790             }
1792             // this applies to the li item which contains all child lists too
1793             $liclasses = array($item->get_css_type(), 'depth_' . $depth);
1794             if ($item->has_children() && (!$item->forceopen || $item->collapse)) {
1795                 $liclasses[] = 'collapsed';
1796             }
1797             if ($item->isactive === true) {
1798                 $liclasses[] = 'current_branch';
1799             }
1800             $liattr = array('class' => join(' ', $liclasses));
1801             // class attribute on the div item which only contains the item content
1802             $divclasses = array('tree_item');
1803             if ((empty($expansionlimit) || $item->type != $expansionlimit) && ($item->children->count() > 0 || ($item->nodetype == navigation_node::NODETYPE_BRANCH && $item->children->count() == 0 && isloggedin()))) {
1804                 $divclasses[] = 'branch';
1805             } else {
1806                 $divclasses[] = 'leaf';
1807             }
1808             if (!empty($item->classes) && count($item->classes) > 0) {
1809                 $divclasses[] = join(' ', $item->classes);
1810             }
1811             $divattr = array('class' => join(' ', $divclasses));
1812             if (!empty($item->id)) {
1813                 $divattr['id'] = $item->id;
1814             }
1815             $content = html_writer::tag('p', $content, $divattr) . $this->render_navigation_node($item->children, array(), $expansionlimit, $depth + 1);
1816             if (!empty($item->preceedwithhr) && $item->preceedwithhr === true) {
1817                 $content = html_writer::empty_tag('hr') . $content;
1818             }
1819             $content = html_writer::tag('li', $content, $liattr);
1820             $lis[] = $content;
1821         }
1823         if (count($lis)) {
1824             return html_writer::tag('ul', implode("\n", $lis), $attrs);
1825         } else {
1826             return '';
1827         }
1828     }
1832 /**
1833  * Class that models the behavior of wiki's restore version page
1834  *
1835  */
1836 class page_wiki_restoreversion extends page_wiki {
1837     private $version;
1839     function print_header() {
1840         parent::print_header();
1841         $this->print_pagetitle();
1842     }
1844     function print_content() {
1845         global $PAGE;
1847         $wiki = $PAGE->activityrecord;
1848         if (wiki_user_can_edit($this->subwiki, $wiki)) {
1849             $this->print_restoreversion();
1850         } else {
1851             echo get_string('cannoteditpage', 'wiki');
1852         }
1854     }
1856     function set_url() {
1857         global $PAGE, $CFG;
1858         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
1859     }
1861     function set_versionid($versionid) {
1862         $this->version = wiki_get_version($versionid);
1863     }
1865     protected function create_navbar() {
1866         global $PAGE, $CFG;
1868         parent::create_navbar();
1869         $PAGE->navbar->add(get_string('restoreversion', 'wiki'));
1870     }
1872     protected function setup_tabs($options = array()) {
1873         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history'));
1874     }
1876     /**
1877      * Prints the restore version content
1878      *
1879      * @uses $CFG
1880      *
1881      * @param page $page The page whose version will be restored
1882      * @param int  $versionid The version to be restored
1883      * @param bool $confirm If false, shows a yes/no confirmation page.
1884      *     If true, restores the old version and redirects the user to the 'view' tab.
1885      */
1886     private function print_restoreversion() {
1887         global $OUTPUT;
1889         $version = wiki_get_version($this->version->id);
1891         $optionsyes = array('confirm'=>1, 'pageid'=>$this->page->id, 'versionid'=>$version->id, 'sesskey'=>sesskey());
1892         $restoreurl = new moodle_url('/mod/wiki/restoreversion.php', $optionsyes);
1893         $return = new moodle_url('/mod/wiki/viewversion.php', array('pageid'=>$this->page->id, 'versionid'=>$version->id));
1895         echo $OUTPUT->container_start('wiki-form-center');
1896         echo html_writer::tag('div', get_string('restoreconfirm', 'wiki', $version->version));
1897         echo $OUTPUT->container_start(false, 'wiki_restoreform');
1898         echo '<form class="wiki_restore_yes" action="' . $restoreurl . '" method="post" id="restoreversion">';
1899         echo '<div><input type="submit" name="confirm" value="' . get_string('yes') . '" /></div>';
1900         echo '</form>';
1901         echo '<form class="wiki_restore_no" action="' . $return . '" method="post">';
1902         echo '<div><input type="submit" name="norestore" value="' . get_string('no') . '" /></div>';
1903         echo '</form>';
1904         echo $OUTPUT->container_end();
1905         echo $OUTPUT->container_end();
1906     }
1908 /**
1909  * Class that models the behavior of wiki's delete comment confirmation page
1910  *
1911  */
1912 class page_wiki_deletecomment extends page_wiki {
1913     private $commentid;
1915     function print_header() {
1916         parent::print_header();
1917         $this->print_pagetitle();
1918     }
1920     function print_content() {
1921         $this->printconfirmdelete();
1922     }
1924     function set_url() {
1925         global $PAGE;
1926         $PAGE->set_url('/mod/wiki/instancecomments.php', array('pageid' => $this->page->id, 'commentid' => $this->commentid));
1927     }
1929     public function set_action($action, $commentid, $content) {
1930         $this->action = $action;
1931         $this->commentid = $commentid;
1932         $this->content = $content;
1933     }
1935     protected function create_navbar() {
1936         global $PAGE;
1938         parent::create_navbar();
1939         $PAGE->navbar->add(get_string('deletecommentcheck', 'wiki'));
1940     }
1942     protected function setup_tabs($options = array()) {
1943         parent::setup_tabs(array('linkedwhenactive' => 'comments', 'activetab' => 'comments'));
1944     }
1946     /**
1947      * Prints the comment deletion confirmation form
1948      *
1949      * @param page $page The page whose version will be restored
1950      * @param int  $versionid The version to be restored
1951      * @param bool $confirm If false, shows a yes/no confirmation page.
1952      *     If true, restores the old version and redirects the user to the 'view' tab.
1953      */
1954     private function printconfirmdelete() {
1955         global $OUTPUT;
1957         $strdeletecheck = get_string('deletecommentcheck', 'wiki');
1958         $strdeletecheckfull = get_string('deletecommentcheckfull', 'wiki');
1960         //ask confirmation
1961         $optionsyes = array('confirm'=>1, 'pageid'=>$this->page->id, 'action'=>'delete', 'commentid'=>$this->commentid, 'sesskey'=>sesskey());
1962         $deleteurl = new moodle_url('/mod/wiki/instancecomments.php', $optionsyes);
1963         $return = new moodle_url('/mod/wiki/comments.php', array('pageid'=>$this->page->id));
1965         echo $OUTPUT->container_start('wiki-form-center');
1966         echo html_writer::tag('p', $strdeletecheckfull);
1967         echo $OUTPUT->container_start(false, 'wiki_deletecommentform');
1968         echo '<form class="wiki_deletecomment_yes" action="' . $deleteurl . '" method="post" id="deletecomment">';
1969         echo '<div><input type="submit" name="confirmdeletecomment" value="' . get_string('yes') . '" /></div>';
1970         echo '</form>';
1971         echo '<form class="wiki_deletecomment_no" action="' . $return . '" method="post">';
1972         echo '<div><input type="submit" name="norestore" value="' . get_string('no') . '" /></div>';
1973         echo '</form>';
1974         echo $OUTPUT->container_end();
1975         echo $OUTPUT->container_end();
1976     }
1979 /**
1980  * Class that models the behavior of wiki's
1981  * save page
1982  *
1983  */
1984 class page_wiki_save extends page_wiki_edit {
1986     private $newcontent;
1988     function print_header() {
1989     }
1991     function print_content() {
1992         global $PAGE;
1994         $context = context_module::instance($this->cm->id);
1995         require_capability('mod/wiki:editpage', $context, NULL, true, 'noeditpermission', 'wiki');
1997         $this->print_save();
1998     }
2000     function set_newcontent($newcontent) {
2001         $this->newcontent = $newcontent;
2002     }
2004     protected function set_session_url() {
2005     }
2007     protected function print_save() {
2008         global $CFG, $USER, $OUTPUT, $PAGE;
2010         $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
2011         if (!empty($this->section)) {
2012             $url .= "&section=" . urlencode($this->section);
2013         }
2015         $params = array(
2016             'attachmentoptions' => page_wiki_edit::$attachmentoptions,
2017             'format' => $this->format,
2018             'version' => $this->versionnumber,
2019             'contextid' => $this->modcontext->id
2020         );
2022         if ($this->format != 'html') {
2023             $params['fileitemid'] = $this->page->id;
2024             $params['component']  = 'mod_wiki';
2025             $params['filearea']   = 'attachments';
2026         }
2028         $form = new mod_wiki_edit_form($url, $params);
2030         $save = false;
2031         $data = false;
2032         if ($data = $form->get_data()) {
2033             if ($this->format == 'html') {
2034                 $data = file_postupdate_standard_editor($data, 'newcontent', page_wiki_edit::$attachmentoptions, $this->modcontext, 'mod_wiki', 'attachments', $this->subwiki->id);
2035             }
2037             if (isset($this->section)) {
2038                 $save = wiki_save_section($this->page, $this->section, $data->newcontent, $USER->id);
2039             } else {
2040                 $save = wiki_save_page($this->page, $data->newcontent, $USER->id);
2041             }
2042         }
2044         if ($save && $data) {
2045             core_tag_tag::set_item_tags('mod_wiki', 'wiki_pages', $this->page->id, $this->modcontext, $data->tags);
2047             $message = '<p>' . get_string('saving', 'wiki') . '</p>';
2049             if (!empty($save['sections'])) {
2050                 foreach ($save['sections'] as $s) {
2051                     $message .= '<p>' . get_string('repeatedsection', 'wiki', $s) . '</p>';
2052                 }
2053             }
2055             if ($this->versionnumber + 1 != $save['version']) {
2056                 $message .= '<p>' . get_string('wrongversionsave', 'wiki') . '</p>';
2057             }
2059             if (isset($errors) && !empty($errors)) {
2060                 foreach ($errors as $e) {
2061                     $message .= "<p>" . get_string('filenotuploadederror', 'wiki', $e->get_filename()) . "</p>";
2062                 }
2063             }
2065             //deleting old locks
2066             wiki_delete_locks($this->page->id, $USER->id, $this->section);
2067             $url = new moodle_url('/mod/wiki/view.php', array('pageid' => $this->page->id, 'group' => $this->subwiki->groupid));
2068             redirect($url);
2069         } else {
2070             print_error('savingerror', 'wiki');
2071         }
2072     }
2075 /**
2076  * Class that models the behavior of wiki's view an old version of a page
2077  *
2078  */
2079 class page_wiki_viewversion extends page_wiki {
2081     private $version;
2083     function print_header() {
2084         parent::print_header();
2085         $this->print_pagetitle();
2086     }
2088     function print_content() {
2089         global $PAGE;
2091         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2093         $this->print_version_view();
2094     }
2096     function set_url() {
2097         global $PAGE, $CFG;
2098         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2099     }
2101     function set_versionid($versionid) {
2102         $this->version = wiki_get_version($versionid);
2103     }
2105     protected function create_navbar() {
2106         global $PAGE, $CFG;
2108         parent::create_navbar();
2109         $PAGE->navbar->add(get_string('history', 'wiki'), $CFG->wwwroot . '/mod/wiki/history.php?pageid=' . $this->page->id);
2110         $PAGE->navbar->add(get_string('versionnum', 'wiki', $this->version->version));
2111     }
2113     protected function setup_tabs($options = array()) {
2114         parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history', 'inactivetabs' => array('edit')));
2115     }
2117     /**
2118      * Given an old page version, output the version content
2119      *
2120      * @global object $CFG
2121      * @global object $OUTPUT
2122      * @global object $PAGE
2123      */
2124     private function print_version_view() {
2125         global $CFG, $OUTPUT, $PAGE;
2126         $pageversion = wiki_get_version($this->version->id);
2128         if ($pageversion) {
2129             $restorelink = new moodle_url('/mod/wiki/restoreversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2130             echo html_writer::tag('div', get_string('viewversion', 'wiki', $pageversion->version) . '<br />' .
2131                 html_writer::link($restorelink->out(false), '(' . get_string('restorethis', 'wiki') .
2132                 ')', array('class' => 'wiki_restore')) . '&nbsp;', array('class' => 'wiki_headingtitle'));
2133             $userinfo = wiki_get_user_info($pageversion->userid);
2134             $heading = '<p><strong>' . get_string('modified', 'wiki') . ':</strong>&nbsp;' . userdate($pageversion->timecreated, get_string('strftimedatetime', 'langconfig'));
2135             $viewlink = new moodle_url('/user/view.php', array('id' => $userinfo->id));
2136             $heading .= '&nbsp;&nbsp;&nbsp;<strong>' . get_string('user') . ':</strong>&nbsp;' . html_writer::link($viewlink->out(false), fullname($userinfo));
2137             $heading .= '&nbsp;&nbsp;&rarr;&nbsp;' . $OUTPUT->user_picture(wiki_get_user_info($pageversion->userid), array('popup' => true)) . '</p>';
2138             echo $OUTPUT->container($heading, 'wiki_headingtime', 'mdl-align wiki_modifieduser');
2139             $options = array('swid' => $this->subwiki->id, 'pretty_print' => true, 'pageid' => $this->page->id);
2141             $pageversion->content = file_rewrite_pluginfile_urls($pageversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id);
2143             $parseroutput = wiki_parse_content($pageversion->contentformat, $pageversion->content, $options);
2144             $content = $OUTPUT->container(format_text($parseroutput['parsed_text'], FORMAT_HTML, array('overflowdiv'=>true)), false, '', '', true);
2145             echo $OUTPUT->box($content, 'generalbox wiki_contentbox');
2147         } else {
2148             print_error('versionerror', 'wiki');
2149         }
2150     }
2153 class page_wiki_confirmrestore extends page_wiki_save {
2155     private $version;
2157     function set_url() {
2158         global $PAGE, $CFG;
2159         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
2160     }
2162     function print_header() {
2163         $this->set_url();
2164     }
2166     function print_content() {
2167         global $CFG, $PAGE;
2169         $version = wiki_get_version($this->version->id);
2170         $wiki = $PAGE->activityrecord;
2171         if (wiki_user_can_edit($this->subwiki, $wiki) &&
2172                 wiki_restore_page($this->page, $version, $this->modcontext)) {
2173             redirect($CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $this->page->id, get_string('restoring', 'wiki', $version->version), 3);
2174         } else {
2175             print_error('restoreerror', 'wiki', $version->version);
2176         }
2177     }
2179     function set_versionid($versionid) {
2180         $this->version = wiki_get_version($versionid);
2181     }
2184 class page_wiki_prettyview extends page_wiki {
2186     function __construct($wiki, $subwiki, $cm) {
2187         global $PAGE;
2188         $PAGE->set_pagelayout('embedded');
2189         parent::__construct($wiki, $subwiki, $cm);
2190     }
2192     function print_header() {
2193         global $OUTPUT;
2194         $this->set_url();
2196         echo $OUTPUT->header();
2197         // Print dialog link.
2198         $printtext = get_string('print', 'wiki');
2199         $printlinkatt = array('onclick' => 'window.print();return false;', 'class' => 'printicon');
2200         $printiconlink = html_writer::link('#', $printtext, $printlinkatt);
2201         echo html_writer::tag('div', $printiconlink, array('class' => 'displayprinticon'));
2202         echo html_writer::tag('h1', format_string($this->title), array('id' => 'wiki_printable_title'));
2203     }
2205     function print_content() {
2206         global $PAGE;
2208         require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2210         $this->print_pretty_view();
2211     }
2213     function set_url() {
2214         global $PAGE, $CFG;
2216         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/prettyview.php', array('pageid' => $this->page->id));
2217     }
2219     private function print_pretty_view() {
2220         $version = wiki_get_current_version($this->page->id);
2222         $content = wiki_parse_content($version->contentformat, $version->content, array('printable' => true, 'swid' => $this->subwiki->id, 'pageid' => $this->page->id, 'pretty_print' => true));
2224         $html = $content['parsed_text'];
2225         $id = $this->subwiki->wikiid;
2226         if ($cm = get_coursemodule_from_instance("wiki", $id)) {
2227             $context = context_module::instance($cm->id);
2228             $html = file_rewrite_pluginfile_urls($html, 'pluginfile.php', $context->id, 'mod_wiki', 'attachments', $this->subwiki->id);
2229         }
2230         echo '<div id="wiki_printable_content">';
2231         echo format_text($html, FORMAT_HTML);
2232         echo '</div>';
2233     }
2236 class page_wiki_handlecomments extends page_wiki {
2237     private $action;
2238     private $content;
2239     private $commentid;
2240     private $format;
2242     function print_header() {
2243         $this->set_url();
2244     }
2246     public function print_content() {
2247         global $CFG, $PAGE, $USER;
2249         if ($this->action == 'add') {
2250             require_capability('mod/wiki:editcomment', $this->modcontext);
2251             $this->add_comment($this->content, $this->commentid);
2252         } else if ($this->action == 'edit') {
2253             require_capability('mod/wiki:editcomment', $this->modcontext);
2255             $comment = wiki_get_comment($this->commentid);
2256             $owner = ($comment->userid == $USER->id);
2258             if ($owner) {
2259                 $this->add_comment($this->content, $this->commentid);
2260             }
2261         } else if ($this->action == 'delete') {
2262             $comment = wiki_get_comment($this->commentid);
2264             $manage = has_capability('mod/wiki:managecomment', $this->modcontext);
2265             $edit = has_capability('mod/wiki:editcomment', $this->modcontext);
2266             $owner = ($comment->userid == $USER->id);
2268             if ($manage || ($owner && $edit)) {
2269                 $this->delete_comment($this->commentid);
2270                 redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $this->page->id, get_string('deletecomment', 'wiki'), 2);
2271             } else {
2272                 print_error('nopermissiontoeditcomment');
2273             }
2274         }
2276     }
2278     public function set_url() {
2279         global $PAGE, $CFG;
2280         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
2281     }
2283     public function set_action($action, $commentid, $content) {
2284         $this->action = $action;
2285         $this->commentid = $commentid;
2286         $this->content = $content;
2288         $version = wiki_get_current_version($this->page->id);
2289         $format = $version->contentformat;
2291         $this->format = $format;
2292     }
2294     private function add_comment($content, $idcomment) {
2295         global $CFG, $PAGE;
2296         require_once($CFG->dirroot . "/mod/wiki/locallib.php");
2298         $pageid = $this->page->id;
2300         wiki_add_comment($this->modcontext, $pageid, $content, $this->format);
2302         if (!$idcomment) {
2303             redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $pageid, get_string('createcomment', 'wiki'), 2);
2304         } else {
2305             $this->delete_comment($idcomment);
2306             redirect($CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $pageid, get_string('editingcomment', 'wiki'), 2);
2307         }
2308     }
2310     private function delete_comment($commentid) {
2311         global $CFG, $PAGE;
2313         $pageid = $this->page->id;
2315         wiki_delete_comment($commentid, $this->modcontext, $pageid);
2316     }
2320 class page_wiki_lock extends page_wiki_edit {
2322     public function print_header() {
2323         $this->set_url();
2324     }
2326     protected function set_url() {
2327         global $PAGE, $CFG;
2329         $params = array('pageid' => $this->page->id);
2331         if ($this->section) {
2332             $params['section'] = $this->section;
2333         }
2335         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/lock.php', $params);
2336     }
2338     protected function set_session_url() {
2339     }
2341     public function print_content() {
2342         global $USER, $PAGE;
2344         require_capability('mod/wiki:editpage', $this->modcontext, NULL, true, 'noeditpermission', 'wiki');
2346         wiki_set_lock($this->page->id, $USER->id, $this->section);
2347     }
2349     public function print_footer() {
2350     }
2353 class page_wiki_overridelocks extends page_wiki_edit {
2354     function print_header() {
2355         $this->set_url();
2356     }
2358     function print_content() {
2359         global $CFG, $PAGE;
2361         require_capability('mod/wiki:overridelock', $this->modcontext, NULL, true, 'nooverridelockpermission', 'wiki');
2363         wiki_delete_locks($this->page->id, null, $this->section, true, true);
2365         $args = "pageid=" . $this->page->id;
2367         if (!empty($this->section)) {
2368             $args .= "&section=" . urlencode($this->section);
2369         }
2371         redirect($CFG->wwwroot . '/mod/wiki/edit.php?' . $args, get_string('overridinglocks', 'wiki'), 2);
2372     }
2374     function set_url() {
2375         global $PAGE, $CFG;
2377         $params = array('pageid' => $this->page->id);
2379         if (!empty($this->section)) {
2380             $params['section'] = $this->section;
2381         }
2383         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/overridelocks.php', $params);
2384     }
2386     protected function set_session_url() {
2387     }
2389     private function print_overridelocks() {
2390         global $CFG;
2392         wiki_delete_locks($this->page->id, null, $this->section, true, true);
2394         $args = "pageid=" . $this->page->id;
2396         if (!empty($this->section)) {
2397             $args .= "&section=" . urlencode($this->section);
2398         }
2400         redirect($CFG->wwwroot . '/mod/wiki/edit.php?' . $args, get_string('overridinglocks', 'wiki'), 2);
2401     }
2405 /**
2406  * This class will let user to delete wiki pages and page versions
2407  *
2408  */
2409 class page_wiki_admin extends page_wiki {
2411     public $view, $action;
2412     public $listorphan = false;
2414     /**
2415      * Constructor
2416      *
2417      * @global object $PAGE
2418      * @param mixed $wiki instance of wiki
2419      * @param mixed $subwiki instance of subwiki
2420      * @param stdClass $cm course module
2421      */
2422     function __construct($wiki, $subwiki, $cm) {
2423         global $PAGE;
2424         parent::__construct($wiki, $subwiki, $cm);
2425         $PAGE->requires->js_init_call('M.mod_wiki.deleteversion', null, true);
2426     }
2428     /**
2429      * Prints header for wiki page
2430      */
2431     function print_header() {
2432         parent::print_header();
2433         $this->print_pagetitle();
2434     }
2436     /**
2437      * This function will display administration view to users with managewiki capability
2438      */
2439     function print_content() {
2440         //make sure anyone trying to access this page has managewiki capabilities
2441         require_capability('mod/wiki:managewiki', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
2443         //update wiki cache if timedout
2444         $page = $this->page;
2445         if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
2446             $fresh = wiki_refresh_cachedcontent($page);
2447             $page = $fresh['page'];
2448         }
2450         //dispaly admin menu
2451         echo $this->wikioutput->menu_admin($this->page->id, $this->view);
2453         //Display appropriate admin view
2454         switch ($this->view) {
2455             case 1: //delete page view
2456                 $this->print_delete_content($this->listorphan);
2457                 break;
2458             case 2: //delete version view
2459                 $this->print_delete_version();
2460                 break;
2461             default: //default is delete view
2462                 $this->print_delete_content($this->listorphan);
2463                 break;
2464         }
2465     }
2467     /**
2468      * Sets admin view option
2469      *
2470      * @param int $view page view id
2471      * @param bool $listorphan is only valid for view 1.
2472      */
2473     public function set_view($view, $listorphan = true) {
2474         $this->view = $view;
2475         $this->listorphan = $listorphan;
2476     }
2478     /**
2479      * Sets page url
2480      *
2481      * @global object $PAGE
2482      * @global object $CFG
2483      */
2484     function set_url() {
2485         global $PAGE, $CFG;
2486         $PAGE->set_url($CFG->wwwroot . '/mod/wiki/admin.php', array('pageid' => $this->page->id));
2487     }
2489     /**
2490      * sets navigation bar for the page
2491      *
2492      * @global object $PAGE
2493      */
2494     protected function create_navbar() {
2495         global $PAGE;
2497         parent::create_navbar();
2498         $PAGE->navbar->add(get_string('admin', 'wiki'));
2499     }
2501     /**
2502      * Show wiki page delete options
2503      *
2504      * @param bool $showorphan
2505      */
2506     protected function print_delete_content($showorphan = true) {
2507         $contents = array();
2508         $table = new html_table();
2509         $table->head = array('', get_string('pagename','wiki'));
2510         $table->attributes['class'] = 'generaltable mdl-align';
2511         $swid = $this->subwiki->id;
2512         if ($showorphan) {
2513             if ($orphanedpages = wiki_get_orphaned_pages($swid)) {
2514                 $this->add_page_delete_options($orphanedpages, $swid, $table);
2515             } else {
2516                 $table->data[] = array('', get_string('noorphanedpages', 'wiki'));
2517             }
2518         } else {
2519             if ($pages = wiki_get_page_list($swid)) {
2520                 $this->add_page_delete_options($pages, $swid, $table);
2521             } else {
2522                 $table->data[] = array('', get_string('nopages', 'wiki'));
2523             }
2524         }
2526         ///Print the form
2527         echo html_writer::start_tag('form', array(
2528                                                 'action' => new moodle_url('/mod/wiki/admin.php'),
2529                                                 'method' => 'post'));
2530         echo html_writer::tag('div', html_writer::empty_tag('input', array(
2531                                                                          'type'  => 'hidden',
2532                                                                          'name'  => 'pageid',
2533                                                                          'value' => $this->page->id)));
2535         echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'option', 'value' => $this->view));
2536         echo html_writer::table($table);
2537         echo html_writer::start_tag('div', array('class' => 'mdl-align'));
2538         if (!$showorphan) {
2539             echo html_writer::empty_tag('input', array(
2540                                                      'type'    => 'submit',
2541                                                      'class'   => 'wiki_form-button',
2542                                                      'value'   => get_string('listorphan', 'wiki'),
2543                                                      'sesskey' => sesskey()));
2544         } else {
2545             echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'listall', 'value'=>'1'));
2546             echo html_writer::empty_tag('input', array(
2547                                                      'type'    => 'submit',
2548                                                      'class'   => 'wiki_form-button',
2549                                                      'value'   => get_string('listall', 'wiki'),
2550                                                      'sesskey' => sesskey()));
2551         }
2552         echo html_writer::end_tag('div');
2553         echo html_writer::end_tag('form');
2554     }
2556     /**
2557      * helper function for print_delete_content. This will add data to the table.
2558      *
2559      * @global object $OUTPUT
2560      * @param array $pages objects of wiki pages in subwiki
2561      * @param int $swid id of subwiki
2562      * @param object $table reference to the table in which data needs to be added
2563      */
2564     protected function add_page_delete_options($pages, $swid, &$table) {
2565         global $OUTPUT;
2566         foreach ($pages as $page) {
2567             $link = wiki_parser_link($page->title, array('swid' => $swid));
2568             $class = ($link['new']) ? 'class="wiki_newentry"' : '';
2569             $pagelink = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>';
2570             $urledit = new moodle_url('/mod/wiki/edit.php', array('pageid' => $page->id, 'sesskey' => sesskey()));
2571             $urldelete = new moodle_url('/mod/wiki/admin.php', array(
2572                                                                    'pageid'  => $this->page->id,
2573                                                                    'delete'  => $page->id,
2574                                                                    'option'  => $this->view,
2575                                                                    'listall' => !$this->listorphan?'1': '',
2576                                                                    'sesskey' => sesskey()));
2578             $editlinks = $OUTPUT->action_icon($urledit, new pix_icon('t/edit', get_string('edit')));
2579             $editlinks .= $OUTPUT->action_icon($urldelete, new pix_icon('t/delete', get_string('delete')));
2580             $table->data[] = array($editlinks, $pagelink);
2581         }
2582     }
2584     /**
2585      * Prints lists of versions which can be deleted
2586      *
2587      * @global core_renderer $OUTPUT
2588      * @global moodle_page $PAGE
2589      */
2590     private function print_delete_version() {
2591         global $OUTPUT, $PAGE;
2592         $pageid = $this->page->id;
2594         // versioncount is the latest version
2595         $versioncount = wiki_count_wiki_page_versions($pageid) - 1;
2596         $versions = wiki_get_wiki_page_versions($pageid, 0, $versioncount);
2598         // We don't want version 0 to be displayed
2599         // version 0 is blank page
2600         if (end($versions)->version == 0) {
2601             array_pop($versions);
2602         }
2604         $contents = array();
2605         $version0page = wiki_get_wiki_page_version($this->page->id, 0);
2606         $creator = wiki_get_user_info($version0page->userid);
2607         $a = new stdClass();
2608         $a->date = userdate($this->page->timecreated, get_string('strftimedaydatetime', 'langconfig'));
2609         $a->username = fullname($creator);
2610         echo $OUTPUT->heading(get_string('createddate', 'wiki', $a), 4);
2611         if ($versioncount > 0) {
2612             /// If there is only one version, we don't need radios nor forms
2613             if (count($versions) == 1) {
2614                 $row = array_shift($versions);
2615                 $username = wiki_get_user_info($row->userid);
2616                 $picture = $OUTPUT->user_picture($username);
2617                 $date = userdate($row->timecreated, get_string('strftimedate', 'langconfig'));
2618                 $time = userdate($row->timecreated, get_string('strftimetime', 'langconfig'));
2619                 $versionid = wiki_get_version($row->id);
2620                 $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
2621                 $userlink = new moodle_url('/user/view.php', array('id' => $username->id, 'course' => $this->cm->course));
2622                 $picturelink = $picture . html_writer::link($userlink->out(false), fullname($username));
2623                 $historydate = $OUTPUT->container($date, 'wiki_histdate');
2624                 $contents[] = array('', html_writer::link($versionlink->out(false), $row->version), $picturelink, $time, $historydate);
2626                 //Show current version
2627                 $table = new html_table();
2628                 $table->head = array('', get_string('version'), get_string('user'), get_string('modified'), '');
2629                 $table->data = $contents;
2630                 $table->attributes['class'] = 'mdl-align';
2632                 echo html_writer::table($table);
2633             } else {
2634                 $lastdate = '';
2635                 $rowclass = array();
2637                 foreach ($versions as $version) {
2638                     $user = wiki_get_user_info($version->userid);
2639                     $picture = $OUTPUT->user_picture($user, array('popup' => true));
2640                     $date = userdate($version->timecreated, get_string('strftimedate'));
2641                     if ($date == $lastdate) {
2642                         $date = '';
2643                         $rowclass[] = '';
2644                     } else {
2645                         $lastdate = $date;
2646                         $rowclass[] = 'wiki_histnewdate';
2647                     }
2649                     $time = userdate($version->timecreated, get_string('strftimetime', 'langconfig'));
2650                     $versionid = wiki_get_version($version->id);
2651                     if ($versionid) {
2652                         $url = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
2653                         $viewlink = html_writer::link($url->out(false), $version->version);
2654                     } else {
2655                         $viewlink = $version->version;
2656                     }
2658                     $userlink = new moodle_url('/user/view.php', array('id' => $version->userid, 'course' => $this->cm->course));
2659                     $picturelink = $picture . html_writer::link($userlink->out(false), fullname($user));
2660                     $historydate = $OUTPUT->container($date, 'wiki_histdate');
2661                     $radiofromelement = $this->choose_from_radio(array($version->version  => null), 'fromversion', 'M.mod_wiki.deleteversion()', $versioncount, true);
2662                     $radiotoelement = $this->choose_from_radio(array($version->version  => null), 'toversion', 'M.mod_wiki.deleteversion()', $versioncount, true);
2663                     $contents[] = array( $radiofromelement . $radiotoelement, $viewlink, $picturelink, $time, $historydate);
2664                 }
2666                 $table = new html_table();
2667                 $table->head = array(get_string('deleteversions', 'wiki'), get_string('version'), get_string('user'), get_string('modified'), '');
2668                 $table->data = $contents;
2669                 $table->attributes['class'] = 'generaltable mdl-align';
2670                 $table->rowclasses = $rowclass;
2672                 ///Print the form
2673                 echo html_writer::start_tag('form', array('action'=>new moodle_url('/mod/wiki/admin.php'), 'method' => 'post'));
2674                 echo html_writer::tag('div', html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'pageid', 'value' => $pageid)));
2675                 echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'option', 'value' => $this->view));
2676                 echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' =>  sesskey()));
2677                 echo html_writer::table($table);
2678                 echo html_writer::start_tag('div', array('class' => 'mdl-align'));
2679                 echo html_writer::empty_tag('input', array('type' => 'submit', 'class' => 'wiki_form-button', 'value' => get_string('deleteversions', 'wiki')));
2680                 echo html_writer::end_tag('div');
2681                 echo html_writer::end_tag('form');
2682             }
2683         } else {
2684             print_string('nohistory', 'wiki');
2685         }
2686     }
2688     /**
2689      * Given an array of values, creates a group of radio buttons to be part of a form
2690      * helper function for print_delete_version
2691      *
2692      * @param array  $options  An array of value-label pairs for the radio group (values as keys).
2693      * @param string $name     Name of the radiogroup (unique in the form).
2694      * @param string $onclick  Function to be executed when the radios are clicked.
2695      * @param string $checked  The value that is already checked.
2696      * @param bool   $return   If true, return the HTML as a string, otherwise print it.
2697      *
2698      * @return mixed If $return is false, returns nothing, otherwise returns a string of HTML.
2699      */
2700     private function choose_from_radio($options, $name, $onclick = '', $checked = '', $return = false) {
2702         static $idcounter = 0;
2704         if (!$name) {
2705             $name = 'unnamed';
2706         }
2708         $output = '<span class="radiogroup ' . $name . "\">\n";
2710         if (!empty($options)) {
2711             $currentradio = 0;
2712             foreach ($options as $value => $label) {
2713                 $htmlid = 'auto-rb' . sprintf('%04d', ++$idcounter);
2714                 $output .= ' <span class="radioelement ' . $name . ' rb' . $currentradio . "\">";
2715                 $output .= '<input name="' . $name . '" id="' . $htmlid . '" type="radio" value="' . $value . '"';
2716                 if ($value == $checked) {
2717                     $output .= ' checked="checked"';
2718                 }
2719                 if ($onclick) {
2720                     $output .= ' onclick="' . $onclick . '"';
2721                 }
2722                 if ($label === '') {
2723                     $output .= ' /> <label for="' . $htmlid . '">' . $value . '</label></span>' . "\n";
2724                 } else {
2725                     $output .= ' /> <label for="' . $htmlid . '">' . $label . '</label></span>' . "\n";
2726                 }
2727                 $currentradio = ($currentradio + 1) % 2;
2728             }
2729         }
2731         $output .= '</span>' . "\n";
2733         if ($return) {
2734             return $output;
2735         } else {
2736             echo $output;
2737         }
2738     }