Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403]

   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  
  36  defined('MOODLE_INTERNAL') || die();
  37  
  38  require_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   */
  45  abstract 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   */
 296  class 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   */
 368  class 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   */
 588  class 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   */
 717  class 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'] = clean_text($com->content, $this->format);
 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   */
 818  class 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   */
 867  class 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  
 979  class 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   */
1078  class 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   */
1168  class 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   */
1402  class 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   */
1834  class 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   */
1910  class 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   */
1983  class 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   */
2078  class 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  
2152  class 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  
2183  class 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  
2235  class 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  
2319  class 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  
2352  class 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   */
2408  class 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  }