Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

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