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