Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

Differences Between: [Versions 310 and 400] [Versions 311 and 400] [Versions 39 and 400] [Versions 400 and 401] [Versions 400 and 402] [Versions 400 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              print_error(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              $cell3->atributtes ['width'] = "80%";
 664              $cell4 = new html_table_cell();
 665              $cell5 = new html_table_cell();
 666  
 667              $row1 = new html_table_row();
 668              $row1->cells[] = $cell1;
 669              $row1->cells[] = $cell2;
 670              $row2 = new html_table_row();
 671              $row2->cells[] = $cell3;
 672  
 673              if ($format != 'html') {
 674                  if ($format == 'creole') {
 675                      $parsedcontent = wiki_parse_content('creole', $comment->content, $options);
 676                  } else if ($format == 'nwiki') {
 677                      $parsedcontent = wiki_parse_content('nwiki', $comment->content, $options);
 678                  }
 679  
 680                  $cell4->text = format_text(html_entity_decode($parsedcontent['parsed_text'], ENT_QUOTES, 'UTF-8'), FORMAT_HTML);
 681              } else {
 682                  $cell4->text = format_text($comment->content, FORMAT_HTML);
 683              }
 684  
 685              $row2->cells[] = $cell4;
 686  
 687              $t->data = array($row1, $row2);
 688  
 689              $canedit = $candelete = false;
 690              if ((has_capability('mod/wiki:editcomment', $this->modcontext)) and ($USER->id == $user->id)) {
 691                  $candelete = $canedit = true;
 692              }
 693              if ((has_capability('mod/wiki:managecomment', $this->modcontext))) {
 694                  $candelete = true;
 695              }
 696  
 697              $editicon = $deleteicon = '';
 698              if ($canedit) {
 699                  $urledit = new moodle_url('/mod/wiki/editcomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'edit'));
 700                  $editicon = $OUTPUT->action_icon($urledit, new pix_icon('t/edit', get_string('edit'), '', array('class' => 'iconsmall')));
 701              }
 702              if ($candelete) {
 703                  $urldelete = new moodle_url('/mod/wiki/instancecomments.php', array('commentid' => $comment->id, 'pageid' => $page->id, 'action' => 'delete'));
 704                  $deleteicon = $OUTPUT->action_icon($urldelete,
 705                                                    new pix_icon('t/delete',
 706                                                                 get_string('delete'),
 707                                                                 '',
 708                                                                 array('class' => 'iconsmall')));
 709              }
 710  
 711              if ($candelete || $canedit) {
 712                  $cell6 = new html_table_cell($editicon.$deleteicon);
 713                  $row3 = new html_table_row();
 714                  $row3->cells[] = $cell5;
 715                  $row3->cells[] = $cell6;
 716                  $t->data[] = $row3;
 717              }
 718  
 719              echo html_writer::tag('div', html_writer::table($t), array('class'=>'no-overflow'));
 720  
 721          }
 722      }
 723  
 724      function set_url() {
 725          global $PAGE, $CFG;
 726          $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
 727      }
 728  
 729      protected function create_navbar() {
 730          global $PAGE, $CFG;
 731  
 732          parent::create_navbar();
 733          $PAGE->navbar->add(get_string('comments', 'wiki'));
 734      }
 735  
 736  }
 737  
 738  /**
 739   * Class that models the behavior of wiki's edit comment
 740   *
 741   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 742   */
 743  class page_wiki_editcomment extends page_wiki {
 744      private $comment;
 745      private $action;
 746      private $form;
 747      private $format;
 748  
 749      function set_url() {
 750          global $PAGE, $CFG;
 751          $PAGE->set_url($CFG->wwwroot . '/mod/wiki/comments.php', array('pageid' => $this->page->id));
 752      }
 753  
 754      function print_header() {
 755          parent::print_header();
 756          $this->print_pagetitle();
 757      }
 758  
 759      function print_content() {
 760          global $PAGE;
 761  
 762          require_capability('mod/wiki:editcomment', $this->modcontext, NULL, true, 'noeditcommentpermission', 'wiki');
 763  
 764          if ($this->action == 'add') {
 765              $this->add_comment_form();
 766          } else if ($this->action == 'edit') {
 767              $this->edit_comment_form($this->comment);
 768          }
 769      }
 770  
 771      function set_action($action, $comment) {
 772          global $CFG;
 773          require_once($CFG->dirroot . '/mod/wiki/comments_form.php');
 774  
 775          $this->action = $action;
 776          $this->comment = $comment;
 777          $version = wiki_get_current_version($this->page->id);
 778          $this->format = $version->contentformat;
 779  
 780          if ($this->format == 'html') {
 781              $destination = $CFG->wwwroot . '/mod/wiki/instancecomments.php?pageid=' . $this->page->id;
 782              $this->form = new mod_wiki_comments_form($destination);
 783          }
 784      }
 785  
 786      protected function create_navbar() {
 787          global $PAGE, $CFG;
 788  
 789          $PAGE->navbar->add(get_string('comments', 'wiki'), $CFG->wwwroot . '/mod/wiki/comments.php?pageid=' . $this->page->id);
 790  
 791          if ($this->action == 'add') {
 792              $PAGE->navbar->add(get_string('insertcomment', 'wiki'));
 793          } else {
 794              $PAGE->navbar->add(get_string('editcomment', 'wiki'));
 795          }
 796      }
 797  
 798      protected function setup_tabs($options = array()) {
 799          parent::setup_tabs(array('linkedwhenactive' => 'comments', 'activetab' => 'comments'));
 800      }
 801  
 802      /**
 803       * This method returns the action bar.
 804       *
 805       * @param int $pageid The page id.
 806       * @param moodle_url $pageurl The page url.
 807       * @return string The HTML for the action bar.
 808       */
 809      protected function action_bar(int $pageid, moodle_url $pageurl): string {
 810          // The given page does not require an action bar.
 811          return '';
 812      }
 813  
 814      private function add_comment_form() {
 815          global $CFG;
 816          require_once($CFG->dirroot . '/mod/wiki/editors/wiki_editor.php');
 817  
 818          $pageid = $this->page->id;
 819  
 820          if ($this->format == 'html') {
 821              $com = new stdClass();
 822              $com->action = 'add';
 823              $com->commentoptions = array('trusttext' => true, 'maxfiles' => 0);
 824              $this->form->set_data($com);
 825              $this->form->display();
 826          } else {
 827              wiki_print_editor_wiki($this->page->id, null, $this->format, -1, null, false, null, 'addcomments');
 828          }
 829      }
 830  
 831      private function edit_comment_form($com) {
 832          global $CFG;
 833          require_once($CFG->dirroot . '/mod/wiki/comments_form.php');
 834          require_once($CFG->dirroot . '/mod/wiki/editors/wiki_editor.php');
 835  
 836          if ($this->format == 'html') {
 837              $com->action = 'edit';
 838              $com->entrycomment_editor['text'] = clean_text($com->content, $this->format);
 839              $com->commentoptions = array('trusttext' => true, 'maxfiles' => 0);
 840  
 841              $this->form->set_data($com);
 842              $this->form->display();
 843          } else {
 844              wiki_print_editor_wiki($this->page->id, $com->content, $this->format, -1, null, false, array(), 'editcomments', $com->id);
 845          }
 846  
 847      }
 848  
 849  }
 850  
 851  /**
 852   * Wiki page search page
 853   *
 854   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 855   */
 856  class page_wiki_search extends page_wiki {
 857      private $search_result;
 858  
 859      protected function create_navbar() {
 860          global $PAGE, $CFG;
 861  
 862          $PAGE->navbar->add(format_string($this->title));
 863      }
 864  
 865      function set_search_string($search, $searchcontent) {
 866          $swid = $this->subwiki->id;
 867          if ($searchcontent) {
 868              $this->search_result = wiki_search_all($swid, $search);
 869          } else {
 870              $this->search_result = wiki_search_title($swid, $search);
 871          }
 872  
 873      }
 874  
 875      function set_url() {
 876          global $PAGE, $CFG;
 877          $PAGE->set_url($CFG->wwwroot . '/mod/wiki/search.php');
 878      }
 879  
 880      function print_header() {
 881          global $PAGE;
 882  
 883          parent::print_header();
 884  
 885          $wiki = $PAGE->activityrecord;
 886          $page = (object)array('title' => $wiki->firstpagetitle);
 887          $this->wikioutput->wiki_print_subwiki_selector($wiki, $this->subwiki, $page, 'search');
 888      }
 889  
 890      function print_content() {
 891          global $PAGE;
 892  
 893          require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
 894  
 895          echo $this->wikioutput->search_result($this->search_result, $this->subwiki);
 896      }
 897  }
 898  
 899  /**
 900   *
 901   * Class that models the behavior of wiki's
 902   * create page
 903   *
 904   */
 905  class page_wiki_create extends page_wiki {
 906  
 907      private $format;
 908      private $swid;
 909      private $wid;
 910      private $action;
 911      private $mform;
 912      private $groups;
 913  
 914      function print_header() {
 915          $this->set_url();
 916          parent::print_header();
 917      }
 918  
 919      function set_url() {
 920          global $PAGE, $CFG;
 921  
 922          $params = array();
 923          $params['swid'] = $this->swid;
 924          if ($this->action == 'new') {
 925              $params['action'] = 'new';
 926              $params['wid'] = $this->wid;
 927              if ($this->title != get_string('newpage', 'wiki')) {
 928                  $params['title'] = $this->title;
 929              }
 930          } else {
 931              $params['action'] = 'create';
 932          }
 933          $PAGE->set_url(new moodle_url('/mod/wiki/create.php', $params));
 934      }
 935  
 936      function set_format($format) {
 937          $this->format = $format;
 938      }
 939  
 940      function set_wid($wid) {
 941          $this->wid = $wid;
 942      }
 943  
 944      function set_swid($swid) {
 945          $this->swid = $swid;
 946      }
 947  
 948      function set_availablegroups($group) {
 949          $this->groups = $group;
 950      }
 951  
 952      function set_action($action) {
 953          global $PAGE;
 954          $this->action = $action;
 955  
 956          require_once (__DIR__ . '/create_form.php');
 957          $url = new moodle_url('/mod/wiki/create.php', array('action' => 'create', 'wid' => $PAGE->activityrecord->id, 'group' => $this->gid, 'uid' => $this->uid));
 958          $formats = wiki_get_formats();
 959          $options = array('formats' => $formats, 'defaultformat' => $PAGE->activityrecord->defaultformat, 'forceformat' => $PAGE->activityrecord->forceformat, 'groups' => $this->groups);
 960          if ($this->title != get_string('newpage', 'wiki')) {
 961              $options['disable_pagetitle'] = true;
 962          }
 963          $this->mform = new mod_wiki_create_form($url->out(false), $options);
 964      }
 965  
 966      protected function create_navbar() {
 967          global $PAGE;
 968          // navigation_node::get_content formats this before printing.
 969          $PAGE->navbar->add($this->title);
 970      }
 971  
 972      function print_content($pagetitle = '') {
 973          global $PAGE;
 974  
 975          // @TODO: Change this to has_capability and show an alternative interface.
 976          require_capability('mod/wiki:createpage', $this->modcontext, NULL, true, 'nocreatepermission', 'wiki');
 977          $data = new stdClass();
 978          if (!empty($pagetitle)) {
 979              $data->pagetitle = $pagetitle;
 980          }
 981          $data->pageformat = $PAGE->activityrecord->defaultformat;
 982  
 983          $this->mform->set_data($data);
 984          $this->mform->display();
 985      }
 986  
 987      function create_page($pagetitle) {
 988          global $USER, $PAGE;
 989  
 990          $data = $this->mform->get_data();
 991          if (isset($data->groupinfo)) {
 992              $groupid = $data->groupinfo;
 993          } else if (!empty($this->gid)) {
 994              $groupid = $this->gid;
 995          } else {
 996              $groupid = '0';
 997          }
 998          if (empty($this->subwiki)) {
 999              // If subwiki is not set then try find one and set else create one.
1000              if (!$this->subwiki = wiki_get_subwiki_by_group($this->wid, $groupid, $this->uid)) {
1001                  $swid = wiki_add_subwiki($PAGE->activityrecord->id, $groupid, $this->uid);
1002                  $this->subwiki = wiki_get_subwiki($swid);
1003              }
1004          }
1005          if ($data) {
1006              $this->set_title($data->pagetitle);
1007              $id = wiki_create_page($this->subwiki->id, $data->pagetitle, $data->pageformat, $USER->id);
1008          } else {
1009              $this->set_title($pagetitle);
1010              $id = wiki_create_page($this->subwiki->id, $pagetitle, $PAGE->activityrecord->defaultformat, $USER->id);
1011          }
1012          $this->page = $id;
1013          return $id;
1014      }
1015  }
1016  
1017  class page_wiki_preview extends page_wiki_edit {
1018  
1019      private $newcontent;
1020  
1021      function print_header() {
1022          global $PAGE, $CFG;
1023  
1024          parent::print_header();
1025  
1026      }
1027  
1028      function print_content() {
1029          global $PAGE;
1030  
1031          require_capability('mod/wiki:editpage', $this->modcontext, NULL, true, 'noeditpermission', 'wiki');
1032  
1033          $this->print_preview();
1034      }
1035  
1036      function set_newcontent($newcontent) {
1037          $this->newcontent = $newcontent;
1038      }
1039  
1040      function set_url() {
1041          global $PAGE, $CFG;
1042  
1043          $params = array('pageid' => $this->page->id
1044          );
1045  
1046          if (isset($this->section)) {
1047              $params['section'] = $this->section;
1048          }
1049  
1050          $PAGE->set_url($CFG->wwwroot . '/mod/wiki/edit.php', $params);
1051      }
1052  
1053      protected function setup_tabs($options = array()) {
1054          parent::setup_tabs(array('linkedwhenactive' => 'view', 'activetab' => 'view'));
1055      }
1056  
1057      protected function check_locks() {
1058          return true;
1059      }
1060  
1061      protected function print_preview() {
1062          global $CFG, $PAGE, $OUTPUT;
1063  
1064          $version = wiki_get_current_version($this->page->id);
1065          $format = $version->contentformat;
1066          $content = $version->content;
1067  
1068          $url = $CFG->wwwroot . '/mod/wiki/edit.php?pageid=' . $this->page->id;
1069          if (!empty($this->section)) {
1070              $url .= "&section=" . urlencode($this->section);
1071          }
1072          $params = array(
1073              'attachmentoptions' => page_wiki_edit::$attachmentoptions,
1074              'format' => $this->format,
1075              'version' => $this->versionnumber,
1076              'contextid' => $this->modcontext->id
1077          );
1078  
1079          if ($this->format != 'html') {
1080              $params['component'] = 'mod_wiki';
1081              $params['filearea'] = 'attachments';
1082              $params['fileitemid'] = $this->page->id;
1083          }
1084          $form = new mod_wiki_edit_form($url, $params);
1085  
1086  
1087          $options = array('swid' => $this->page->subwikiid, 'pageid' => $this->page->id, 'pretty_print' => true);
1088  
1089          if ($data = $form->get_data()) {
1090              if (isset($data->newcontent)) {
1091                  // wiki fromat
1092                  $text = $data->newcontent;
1093              } else {
1094                  // html format
1095                  $text = $data->newcontent_editor['text'];
1096              }
1097              $parseroutput = wiki_parse_content($data->contentformat, $text, $options);
1098              $this->set_newcontent($text);
1099              echo $OUTPUT->notification(get_string('previewwarning', 'wiki'), 'notifyproblem');
1100              $content = format_text($parseroutput['parsed_text'], FORMAT_HTML, array('overflowdiv'=>true, 'filter'=>false));
1101              echo $OUTPUT->box($content, 'generalbox wiki_previewbox');
1102              $content = $this->newcontent;
1103          }
1104  
1105          $this->print_edit($content);
1106      }
1107  
1108  }
1109  
1110  /**
1111   *
1112   * Class that models the behavior of wiki's
1113   * view differences
1114   *
1115   */
1116  class page_wiki_diff extends page_wiki {
1117  
1118      private $compare;
1119      private $comparewith;
1120  
1121      function print_header() {
1122          global $OUTPUT;
1123  
1124          parent::print_header();
1125  
1126          $this->print_pagetitle();
1127          $vstring = new stdClass();
1128          $vstring->old = $this->compare;
1129          $vstring->new = $this->comparewith;
1130          echo html_writer::tag('div', get_string('comparewith', 'wiki', $vstring), array('class' => 'wiki_headingtitle'));
1131      }
1132  
1133      /**
1134       * Print the diff view
1135       */
1136      function print_content() {
1137          global $PAGE;
1138  
1139          require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1140  
1141          $this->print_diff_content();
1142      }
1143  
1144      function set_url() {
1145          global $PAGE, $CFG;
1146  
1147          $PAGE->set_url($CFG->wwwroot . '/mod/wiki/diff.php', array('pageid' => $this->page->id, 'comparewith' => $this->comparewith, 'compare' => $this->compare));
1148      }
1149  
1150      function set_comparison($compare, $comparewith) {
1151          $this->compare = $compare;
1152          $this->comparewith = $comparewith;
1153      }
1154  
1155      protected function create_navbar() {
1156          global $PAGE, $CFG;
1157  
1158          parent::create_navbar();
1159          $PAGE->navbar->add(get_string('history', 'wiki'), $CFG->wwwroot . '/mod/wiki/history.php?pageid=' . $this->page->id);
1160          $PAGE->navbar->add(get_string('diff', 'wiki'));
1161      }
1162  
1163      protected function setup_tabs($options = array()) {
1164          parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history'));
1165      }
1166  
1167      /**
1168       * This method returns the action bar.
1169       *
1170       * @param int $pageid The page id.
1171       * @param moodle_url $pageurl The page url.
1172       * @return string The HTML for the action bar.
1173       */
1174      protected function action_bar(int $pageid, moodle_url $pageurl): string {
1175          $backlink = new moodle_url('/mod/wiki/history.php', ['pageid' => $pageid]);
1176          return html_writer::link($backlink, get_string('back'), ['class' => 'btn btn-secondary mb-4']);
1177      }
1178  
1179      /**
1180       * Given two versions of a page, prints a page displaying the differences between them.
1181       *
1182       * @global object $CFG
1183       * @global object $OUTPUT
1184       * @global object $PAGE
1185       */
1186      private function print_diff_content() {
1187          global $CFG, $OUTPUT, $PAGE;
1188  
1189          $pageid = $this->page->id;
1190          $total = wiki_count_wiki_page_versions($pageid) - 1;
1191  
1192          $oldversion = wiki_get_wiki_page_version($pageid, $this->compare);
1193  
1194          $newversion = wiki_get_wiki_page_version($pageid, $this->comparewith);
1195  
1196          if ($oldversion && $newversion) {
1197  
1198              $oldtext = format_text(file_rewrite_pluginfile_urls($oldversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id));
1199              $newtext = format_text(file_rewrite_pluginfile_urls($newversion->content, 'pluginfile.php', $this->modcontext->id, 'mod_wiki', 'attachments', $this->subwiki->id));
1200              list($diff1, $diff2) = ouwiki_diff_html($oldtext, $newtext);
1201              $oldversion->diff = $diff1;
1202              $oldversion->user = wiki_get_user_info($oldversion->userid);
1203              $newversion->diff = $diff2;
1204              $newversion->user = wiki_get_user_info($newversion->userid);
1205  
1206              echo $this->wikioutput->diff($pageid, $oldversion, $newversion, array('total' => $total));
1207          } else {
1208              print_error('versionerror', 'wiki');
1209          }
1210      }
1211  }
1212  
1213  /**
1214   *
1215   * Class that models the behavior of wiki's history page
1216   *
1217   */
1218  class page_wiki_history extends page_wiki {
1219      /**
1220       * @var int $paging current page
1221       */
1222      private $paging;
1223  
1224      /**
1225       * @var int @rowsperpage Items per page
1226       */
1227      private $rowsperpage = 10;
1228  
1229      /**
1230       * @var int $allversion if $allversion != 0, all versions will be printed in a signle table
1231       */
1232      private $allversion;
1233  
1234      /**
1235       * The page_wiki_history constructor.
1236       *
1237       * @param stdClass $wiki Current wiki.
1238       * @param stdClass $subwiki Current subwiki.
1239       * @param stdClass $cm Current course_module.
1240       * @param string|null $activesecondarytab Secondary navigation node to be activated on the page, if required
1241       */
1242      public function __construct($wiki, $subwiki, $cm, ?string $activesecondarytab = null) {
1243          global $PAGE;
1244          parent::__construct($wiki, $subwiki, $cm, $activesecondarytab);
1245          $PAGE->requires->js_init_call('M.mod_wiki.history', null, true);
1246      }
1247  
1248      function print_header() {
1249          parent::print_header();
1250          $this->print_pagetitle();
1251      }
1252  
1253      function print_pagetitle() {
1254          global $OUTPUT;
1255          $html = '';
1256  
1257          $html .= $OUTPUT->container_start('wiki_headingtitle');
1258          $html .= $OUTPUT->heading_with_help(format_string($this->title), 'history', 'wiki', '', '', 3);
1259          $html .= $OUTPUT->container_end();
1260          echo $html;
1261      }
1262  
1263      function print_content() {
1264          global $PAGE;
1265  
1266          require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1267  
1268          $this->print_history_content();
1269      }
1270  
1271      function set_url() {
1272          global $PAGE, $CFG;
1273          $PAGE->set_url($CFG->wwwroot . '/mod/wiki/history.php', array('pageid' => $this->page->id));
1274      }
1275  
1276      function set_paging($paging) {
1277          $this->paging = $paging;
1278      }
1279  
1280      function set_allversion($allversion) {
1281          $this->allversion = $allversion;
1282      }
1283  
1284      protected function create_navbar() {
1285          global $PAGE, $CFG;
1286  
1287          parent::create_navbar();
1288          $PAGE->navbar->add(get_string('history', 'wiki'));
1289      }
1290  
1291      /**
1292       * Prints the history for a given wiki page
1293       *
1294       * @global object $CFG
1295       * @global object $OUTPUT
1296       * @global object $PAGE
1297       */
1298      private function print_history_content() {
1299          global $CFG, $OUTPUT, $PAGE;
1300  
1301          $pageid = $this->page->id;
1302          $offset = $this->paging * $this->rowsperpage;
1303          // vcount is the latest version
1304          $vcount = wiki_count_wiki_page_versions($pageid) - 1;
1305          if ($this->allversion) {
1306              $versions = wiki_get_wiki_page_versions($pageid, 0, $vcount);
1307          } else {
1308              $versions = wiki_get_wiki_page_versions($pageid, $offset, $this->rowsperpage);
1309          }
1310          // We don't want version 0 to be displayed
1311          // version 0 is blank page
1312          if (end($versions)->version == 0) {
1313              array_pop($versions);
1314          }
1315  
1316          $contents = array();
1317  
1318          $version0page = wiki_get_wiki_page_version($this->page->id, 0);
1319          $creator = wiki_get_user_info($version0page->userid);
1320          $a = new StdClass;
1321          $a->date = userdate($this->page->timecreated, get_string('strftimedaydatetime', 'langconfig'));
1322          $a->username = fullname($creator);
1323          echo html_writer::tag ('div', get_string('createddate', 'wiki', $a), array('class' => 'wiki_headingtime'));
1324          if ($vcount > 0) {
1325  
1326              /// If there is only one version, we don't need radios nor forms
1327              if (count($versions) == 1) {
1328  
1329                  $row = array_shift($versions);
1330  
1331                  $username = wiki_get_user_info($row->userid);
1332                  $picture = $OUTPUT->user_picture($username);
1333                  $date = userdate($row->timecreated, get_string('strftimedate', 'langconfig'));
1334                  $time = userdate($row->timecreated, get_string('strftimetime', 'langconfig'));
1335                  $versionid = wiki_get_version($row->id);
1336                  $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
1337                  $userlink = new moodle_url('/user/view.php', array('id' => $username->id, 'course' => $this->cm->course));
1338                  $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'));
1339  
1340                  $table = new html_table();
1341                  $table->head = array('', get_string('version'), get_string('user'), get_string('modified'), '');
1342                  $table->data = $contents;
1343  
1344                  echo html_writer::table($table);
1345  
1346              } else {
1347  
1348                  $checked = $vcount - $offset;
1349                  $rowclass = array();
1350  
1351                  foreach ($versions as $version) {
1352                      $user = wiki_get_user_info($version->userid);
1353                      $picture = $OUTPUT->user_picture($user, array('popup' => true));
1354                      $date = userdate($version->timecreated, get_string('strftimedate'));
1355                      $rowclass[] = 'wiki_histnewdate';
1356                      $time = userdate($version->timecreated, get_string('strftimetime', 'langconfig'));
1357                      $versionid = wiki_get_version($version->id);
1358                      if ($versionid) {
1359                          $url = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $versionid->id));
1360                          $viewlink = html_writer::link($url->out(false), $version->version);
1361                      } else {
1362                          $viewlink = $version->version;
1363                      }
1364                      $userlink = new moodle_url('/user/view.php', array('id' => $version->userid, 'course' => $this->cm->course));
1365                      $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'));
1366                  }
1367  
1368                  $table = new html_table();
1369  
1370                  $icon = $OUTPUT->help_icon('diff', 'wiki');
1371  
1372                  $table->head = array(get_string('diff', 'wiki') . $icon, get_string('version'), get_string('user'), get_string('modified'), '');
1373                  $table->data = $contents;
1374                  $table->attributes['class'] = 'table generaltable';
1375                  $table->rowclasses = $rowclass;
1376  
1377                  // Print the form.
1378                  echo html_writer::start_tag('form', array('action'=>new moodle_url('/mod/wiki/diff.php'), 'method'=>'get', 'id'=>'diff'));
1379                  echo html_writer::tag('div', html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'pageid', 'value'=>$pageid)));
1380                  echo html_writer::table($table);
1381                  echo html_writer::start_tag('div');
1382                  echo html_writer::empty_tag('input', array('type'=>'submit', 'class'=>'wiki_form-button btn btn-secondary', 'value'=>get_string('comparesel', 'wiki')));
1383                  echo html_writer::end_tag('div');
1384                  echo html_writer::end_tag('form');
1385              }
1386          } else {
1387              print_string('nohistory', 'wiki');
1388          }
1389          if (!$this->allversion) {
1390              //$pagingbar = moodle_paging_bar::make($vcount, $this->paging, $this->rowsperpage, $CFG->wwwroot.'/mod/wiki/history.php?pageid='.$pageid.'&amp;');
1391              // $pagingbar->pagevar = $pagevar;
1392              echo $OUTPUT->paging_bar($vcount, $this->paging, $this->rowsperpage, $CFG->wwwroot . '/mod/wiki/history.php?pageid=' . $pageid . '&amp;');
1393              //print_paging_bar($vcount, $paging, $rowsperpage,$CFG->wwwroot.'/mod/wiki/history.php?pageid='.$pageid.'&amp;','paging');
1394              } else {
1395              $link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid));
1396              $OUTPUT->container(html_writer::link($link->out(false), get_string('viewperpage', 'wiki', $this->rowsperpage)));
1397          }
1398          if ($vcount > $this->rowsperpage && !$this->allversion) {
1399              $link = new moodle_url('/mod/wiki/history.php', array('pageid' => $pageid, 'allversion' => 1));
1400              $OUTPUT->container(html_writer::link($link->out(false), get_string('viewallhistory', 'wiki')));
1401          }
1402      }
1403  
1404      /**
1405       * Given an array of values, creates a group of radio buttons to be part of a form
1406       *
1407       * @param array  $options  An array of value-label pairs for the radio group (values as keys).
1408       * @param string $name     Name of the radiogroup (unique in the form).
1409       * @param string $onclick  Function to be executed when the radios are clicked.
1410       * @param string $checked  The value that is already checked.
1411       * @param bool   $return   If true, return the HTML as a string, otherwise print it.
1412       *
1413       * @return mixed If $return is false, returns nothing, otherwise returns a string of HTML.
1414       */
1415      private function choose_from_radio($options, $name, $onclick = '', $checked = '', $return = false) {
1416  
1417          static $idcounter = 0;
1418  
1419          if (!$name) {
1420              $name = 'unnamed';
1421          }
1422  
1423          $output = '<span class="radiogroup ' . $name . "\">\n";
1424  
1425          if (!empty($options)) {
1426              $currentradio = 0;
1427              foreach ($options as $value => $label) {
1428                  $htmlid = 'auto-rb' . sprintf('%04d', ++$idcounter);
1429                  $output .= ' <span class="radioelement ' . $name . ' rb' . $currentradio . "\">";
1430                  $output .= '<input name="' . $name . '" id="' . $htmlid . '" type="radio" value="' . $value . '"';
1431                  if ($value == $checked) {
1432                      $output .= ' checked="checked"';
1433                  }
1434                  if ($onclick) {
1435                      $output .= ' onclick="' . $onclick . '"';
1436                  }
1437                  if ($label === '') {
1438                      $output .= ' /> <label for="' . $htmlid . '">' . $value . '</label></span>' . "\n";
1439                  } else {
1440                      $output .= ' /> <label for="' . $htmlid . '">' . $label . '</label></span>' . "\n";
1441                  }
1442                  $currentradio = ($currentradio + 1) % 2;
1443              }
1444          }
1445  
1446          $output .= '</span>' . "\n";
1447  
1448          if ($return) {
1449              return $output;
1450          } else {
1451              echo $output;
1452          }
1453      }
1454  }
1455  
1456  /**
1457   * Class that models the behavior of wiki's map page
1458   *
1459   */
1460  class page_wiki_map extends page_wiki {
1461  
1462      /**
1463       * @var int wiki view option
1464       */
1465      private $view;
1466  
1467      function print_header() {
1468          parent::print_header();
1469          $this->print_pagetitle();
1470      }
1471  
1472      function print_content() {
1473          global $CFG, $PAGE;
1474  
1475          require_capability('mod/wiki:viewpage', $this->modcontext, NULL, true, 'noviewpagepermission', 'wiki');
1476  
1477          if ($this->view > 0) {
1478              //echo '<div><a href="' . $CFG->wwwroot . '/mod/wiki/map.php?pageid=' . $this->page->id . '">' . get_string('backtomapmenu', 'wiki') . '</a></div>';
1479          }
1480  
1481          switch ($this->view) {
1482          case 1:
1483              echo $this->wikioutput->menu_map($this->page->id, $this->view);
1484              $this->print_contributions_content();
1485              break;
1486          case 2:
1487              echo $this->wikioutput->menu_map($this->page->id, $this->view);
1488              $this->print_navigation_content();
1489              break;
1490          case 3:
1491              echo $this->wikioutput->menu_map($this->page->id, $this->view);
1492              $this->print_orphaned_content();
1493              break;
1494          case 4:
1495              echo $this->wikioutput->menu_map($this->page->id, $this->view);
1496              $this->print_index_content();
1497              break;
1498          case 6:
1499              echo $this->wikioutput->menu_map($this->page->id, $this->view);
1500              $this->print_updated_content();
1501              break;
1502          case 5:
1503          default:
1504              echo $this->wikioutput->menu_map($this->page->id, $this->view);
1505              $this->print_page_list_content();
1506          }
1507      }
1508  
1509      function set_view($option) {
1510          $this->view = $option;
1511      }
1512  
1513      function set_url() {
1514          global $PAGE, $CFG;
1515          $PAGE->set_url($CFG->wwwroot . '/mod/wiki/map.php', array('pageid' => $this->page->id));
1516      }
1517  
1518      protected function create_navbar() {
1519          global $PAGE;
1520  
1521          parent::create_navbar();
1522          $PAGE->navbar->add(get_string('map', 'wiki'));
1523      }
1524  
1525      /**
1526       * Prints the contributions tab content
1527       *
1528       * @uses $OUTPUT, $USER
1529       *
1530       */
1531      private function print_contributions_content() {
1532          global $CFG, $OUTPUT, $USER;
1533          $page = $this->page;
1534  
1535          if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1536              $fresh = wiki_refresh_cachedcontent($page);
1537              $page = $fresh['page'];
1538          }
1539  
1540          $swid = $this->subwiki->id;
1541  
1542          $table = new html_table();
1543          $table->head = array(get_string('contributions', 'wiki') . $OUTPUT->help_icon('contributions', 'wiki'));
1544          $table->attributes['class'] = 'generalbox table';
1545          $table->data = array();
1546          $table->rowclasses = array();
1547  
1548          $lastversions = array();
1549          $pages = array();
1550          $users = array();
1551  
1552          if ($contribs = wiki_get_contributions($swid, $USER->id)) {
1553              foreach ($contribs as $contrib) {
1554                  if (!array_key_exists($contrib->pageid, $pages)) {
1555                      $page = wiki_get_page($contrib->pageid);
1556                      $pages[$contrib->pageid] = $page;
1557                  } else {
1558                      continue;
1559                  }
1560  
1561                  if (!array_key_exists($page->id, $lastversions)) {
1562                      $version = wiki_get_last_version($page->id);
1563                      $lastversions[$page->id] = $version;
1564                  } else {
1565                      $version = $lastversions[$page->id];
1566                  }
1567  
1568                  if (!array_key_exists($version->userid, $users)) {
1569                      $user = wiki_get_user_info($version->userid);
1570                      $users[$version->userid] = $user;
1571                  } else {
1572                      $user = $users[$version->userid];
1573                  }
1574  
1575                  $link = wiki_parser_link($page->title, array('swid' => $swid));
1576                  $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1577  
1578                  $linkpage = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content'], true, array('context' => $this->modcontext)) . '</a>';
1579                  $icon = $OUTPUT->user_picture($user, array('popup' => true));
1580  
1581                  $table->data[] = array("$icon&nbsp;$linkpage");
1582              }
1583          } else {
1584              $table->data[] = array(get_string('nocontribs', 'wiki'));
1585          }
1586          echo html_writer::table($table);
1587      }
1588  
1589      /**
1590       * Prints the navigation tab content
1591       *
1592       * @uses $OUTPUT
1593       *
1594       */
1595      private function print_navigation_content() {
1596          global $OUTPUT;
1597          $page = $this->page;
1598  
1599          if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1600              $fresh = wiki_refresh_cachedcontent($page);
1601              $page = $fresh['page'];
1602          }
1603  
1604          $tolinks = wiki_get_linked_to_pages($page->id);
1605          $fromlinks = wiki_get_linked_from_pages($page->id);
1606  
1607          $table = new html_table();
1608          $table->attributes['class'] = 'wiki_navigation_from table';
1609          $table->head = array(get_string('navigationfrom', 'wiki') . $OUTPUT->help_icon('navigationfrom', 'wiki') . ':');
1610          $table->data = array();
1611          $table->rowclasses = array();
1612          foreach ($fromlinks as $link) {
1613              $lpage = wiki_get_page($link->frompageid);
1614              $link = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
1615              $table->data[] = array(html_writer::link($link->out(false), format_string($lpage->title)));
1616          }
1617  
1618          $table_left = $OUTPUT->container(html_writer::table($table), 'col-md-6');
1619  
1620          $table = new html_table();
1621          $table->attributes['class'] = 'wiki_navigation_to table';
1622          $table->head = array(get_string('navigationto', 'wiki') . $OUTPUT->help_icon('navigationto', 'wiki') . ':');
1623          $table->data = array();
1624          $table->rowclasses = array();
1625          foreach ($tolinks as $link) {
1626              if ($link->tomissingpage) {
1627                  $viewlink = new moodle_url('/mod/wiki/create.php', array('swid' => $page->subwikiid, 'title' => $link->tomissingpage, 'action' => 'new'));
1628                  $table->data[] = array(html_writer::link($viewlink->out(false), format_string($link->tomissingpage), array('class' => 'wiki_newentry')));
1629              } else {
1630                  $lpage = wiki_get_page($link->topageid);
1631                  $viewlink = new moodle_url('/mod/wiki/view.php', array('pageid' => $lpage->id));
1632                  $table->data[] = array(html_writer::link($viewlink->out(false), format_string($lpage->title)));
1633              }
1634          }
1635          $table_right = $OUTPUT->container(html_writer::table($table), 'col-md-6');
1636          echo $OUTPUT->container($table_left . $table_right, 'wiki_navigation_container row');
1637      }
1638  
1639      /**
1640       * Prints the index page tab content
1641       *
1642       *
1643       */
1644      private function print_index_content() {
1645          global $OUTPUT;
1646          $page = $this->page;
1647  
1648          if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1649              $fresh = wiki_refresh_cachedcontent($page);
1650              $page = $fresh['page'];
1651          }
1652  
1653          // navigation_node get_content calls format string for us
1654          $node = new navigation_node($page->title);
1655  
1656          $keys = array();
1657          $tree = array();
1658          $tree = wiki_build_tree($page, $node, $keys);
1659  
1660          $table = new html_table();
1661          $table->head = array(get_string('pageindex', 'wiki') . $OUTPUT->help_icon('pageindex', 'wiki'));
1662          $table->attributes['class'] = 'generalbox table';
1663          $table->data[] = array($this->render_navigation_node($tree));
1664  
1665          echo html_writer::table($table);
1666      }
1667  
1668      /**
1669       * Prints the page list tab content
1670       *
1671       *
1672       */
1673      private function print_page_list_content() {
1674          global $OUTPUT;
1675          $page = $this->page;
1676  
1677          if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1678              $fresh = wiki_refresh_cachedcontent($page);
1679              $page = $fresh['page'];
1680          }
1681  
1682          $pages = wiki_get_page_list($this->subwiki->id);
1683  
1684          $stdaux = new stdClass();
1685          $strspecial = get_string('special', 'wiki');
1686  
1687          foreach ($pages as $page) {
1688              // We need to format the title here to account for any filtering
1689              $letter = format_string($page->title, true, array('context' => $this->modcontext));
1690              $letter = core_text::substr($letter, 0, 1);
1691              if (preg_match('/^[a-zA-Z]$/', $letter)) {
1692                  $letter = core_text::strtoupper($letter);
1693                  $stdaux->{$letter}[] = wiki_parser_link($page);
1694              } else {
1695                  $stdaux->{$strspecial}[] = wiki_parser_link($page);
1696              }
1697          }
1698  
1699          $table = new html_table();
1700          $table->head = array(get_string('pagelist', 'wiki') . $OUTPUT->help_icon('pagelist', 'wiki'));
1701          $table->attributes['class'] = 'generalbox table';
1702          foreach ($stdaux as $key => $elem) {
1703              $table->data[] = array($key);
1704              foreach ($elem as $e) {
1705                  $table->data[] = array(html_writer::link($e['url'], format_string($e['content'], true, array('context' => $this->modcontext))));
1706              }
1707          }
1708          echo html_writer::table($table);
1709      }
1710  
1711      /**
1712       * Prints the orphaned tab content
1713       *
1714       *
1715       */
1716      private function print_orphaned_content() {
1717          global $OUTPUT;
1718  
1719          $page = $this->page;
1720  
1721          if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1722              $fresh = wiki_refresh_cachedcontent($page);
1723              $page = $fresh['page'];
1724          }
1725  
1726          $swid = $this->subwiki->id;
1727  
1728          $table = new html_table();
1729          $table->head = array(get_string('orphaned', 'wiki') . $OUTPUT->help_icon('orphaned', 'wiki'));
1730          $table->attributes['class'] = 'generalbox table';
1731          $table->data = array();
1732          $table->rowclasses = array();
1733  
1734          if ($orphanedpages = wiki_get_orphaned_pages($swid)) {
1735              foreach ($orphanedpages as $page) {
1736                  $link = wiki_parser_link($page->title, array('swid' => $swid));
1737                  $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1738                  $table->data[] = array('<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>');
1739              }
1740          } else {
1741              $table->data[] = array(get_string('noorphanedpages', 'wiki'));
1742          }
1743  
1744          echo html_writer::table($table);
1745      }
1746  
1747      /**
1748       * Prints the updated tab content
1749       *
1750       * @uses $COURSE, $OUTPUT
1751       *
1752       */
1753      private function print_updated_content() {
1754          global $COURSE, $OUTPUT;
1755          $page = $this->page;
1756  
1757          if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1758              $fresh = wiki_refresh_cachedcontent($page);
1759              $page = $fresh['page'];
1760          }
1761  
1762          $swid = $this->subwiki->id;
1763  
1764          $table = new html_table();
1765          $table->head = array(get_string('updatedpages', 'wiki') . $OUTPUT->help_icon('updatedpages', 'wiki'));
1766          $table->attributes['class'] = 'generalbox table';
1767          $table->data = array();
1768          $table->rowclasses = array();
1769  
1770          if ($pages = wiki_get_updated_pages_by_subwiki($swid)) {
1771              $strdataux = '';
1772              foreach ($pages as $page) {
1773                  $user = wiki_get_user_info($page->userid);
1774                  $strdata = strftime('%d %b %Y', $page->timemodified);
1775                  if ($strdata != $strdataux) {
1776                      $table->data[] = array($OUTPUT->heading($strdata, 4));
1777                      $strdataux = $strdata;
1778                  }
1779                  $link = wiki_parser_link($page->title, array('swid' => $swid));
1780                  $class = ($link['new']) ? 'class="wiki_newentry"' : '';
1781  
1782                  $linkpage = '<a href="' . $link['url'] . '"' . $class . '>' . format_string($link['content']) . '</a>';
1783                  $icon = $OUTPUT->user_picture($user, array($COURSE->id));
1784                  $table->data[] = array("$icon&nbsp;$linkpage");
1785              }
1786          } else {
1787              $table->data[] = array(get_string('noupdatedpages', 'wiki'));
1788          }
1789  
1790          echo html_writer::table($table);
1791      }
1792  
1793      protected function render_navigation_node($items, $attrs = array(), $expansionlimit = null, $depth = 1) {
1794  
1795          // exit if empty, we don't want an empty ul element
1796          if (count($items) == 0) {
1797              return '';
1798          }
1799  
1800          // array of nested li elements
1801          $lis = array();
1802          foreach ($items as $item) {
1803              if (!$item->display) {
1804                  continue;
1805              }
1806              $content = $item->get_content();
1807              $title = $item->get_title();
1808              if ($item->icon instanceof renderable) {
1809                  $icon = $this->wikioutput->render($item->icon);
1810                  $content = $icon . '&nbsp;' . $content; // use CSS for spacing of icons
1811                  }
1812              if ($item->helpbutton !== null) {
1813                  $content = trim($item->helpbutton) . html_writer::tag('span', $content, array('class' => 'clearhelpbutton'));
1814              }
1815  
1816              if ($content === '') {
1817                  continue;
1818              }
1819  
1820              if ($item->action instanceof action_link) {
1821                  //TODO: to be replaced with something else
1822                  $link = $item->action;
1823                  if ($item->hidden) {
1824                      $link->add_class('dimmed');
1825                  }
1826                  $content = $this->output->render($link);
1827              } else if ($item->action instanceof moodle_url) {
1828                  $attributes = array();
1829                  if ($title !== '') {
1830                      $attributes['title'] = $title;
1831                  }
1832                  if ($item->hidden) {
1833                      $attributes['class'] = 'dimmed_text';
1834                  }
1835                  $content = html_writer::link($item->action, $content, $attributes);
1836  
1837              } else if (is_string($item->action) || empty($item->action)) {
1838                  $attributes = array();
1839                  if ($title !== '') {
1840                      $attributes['title'] = $title;
1841                  }
1842                  if ($item->hidden) {
1843                      $attributes['class'] = 'dimmed_text';
1844                  }
1845                  $content = html_writer::tag('span', $content, $attributes);
1846              }
1847  
1848              // this applies to the li item which contains all child lists too
1849              $liclasses = array($item->get_css_type(), 'depth_' . $depth);
1850              if ($item->has_children() && (!$item->forceopen || $item->collapse)) {
1851                  $liclasses[] = 'collapsed';
1852              }
1853              if ($item->isactive === true) {
1854                  $liclasses[] = 'current_branch';
1855              }
1856              $liattr = array('class' => join(' ', $liclasses));
1857              // class attribute on the div item which only contains the item content
1858              $divclasses = array('tree_item');
1859              if ((empty($expansionlimit) || $item->type != $expansionlimit) && ($item->children->count() > 0 || ($item->nodetype == navigation_node::NODETYPE_BRANCH && $item->children->count() == 0 && isloggedin()))) {
1860                  $divclasses[] = 'branch';
1861              } else {
1862                  $divclasses[] = 'leaf';
1863              }
1864              if (!empty($item->classes) && count($item->classes) > 0) {
1865                  $divclasses[] = join(' ', $item->classes);
1866              }
1867              $divattr = array('class' => join(' ', $divclasses));
1868              if (!empty($item->id)) {
1869                  $divattr['id'] = $item->id;
1870              }
1871              $content = html_writer::tag('p', $content, $divattr) . $this->render_navigation_node($item->children, array(), $expansionlimit, $depth + 1);
1872              if (!empty($item->preceedwithhr) && $item->preceedwithhr === true) {
1873                  $content = html_writer::empty_tag('hr') . $content;
1874              }
1875              $content = html_writer::tag('li', $content, $liattr);
1876              $lis[] = $content;
1877          }
1878  
1879          if (count($lis)) {
1880              return html_writer::tag('ul', implode("\n", $lis), $attrs);
1881          } else {
1882              return '';
1883          }
1884      }
1885  
1886  }
1887  
1888  /**
1889   * Class that models the behavior of wiki's restore version page
1890   *
1891   */
1892  class page_wiki_restoreversion extends page_wiki {
1893      private $version;
1894  
1895      function print_header() {
1896          parent::print_header();
1897          $this->print_pagetitle();
1898      }
1899  
1900      function print_content() {
1901          global $PAGE;
1902  
1903          $wiki = $PAGE->activityrecord;
1904          if (wiki_user_can_edit($this->subwiki, $wiki)) {
1905              $this->print_restoreversion();
1906          } else {
1907              echo get_string('cannoteditpage', 'wiki');
1908          }
1909  
1910      }
1911  
1912      function set_url() {
1913          global $PAGE, $CFG;
1914          $PAGE->set_url($CFG->wwwroot . '/mod/wiki/viewversion.php', array('pageid' => $this->page->id, 'versionid' => $this->version->id));
1915      }
1916  
1917      function set_versionid($versionid) {
1918          $this->version = wiki_get_version($versionid);
1919      }
1920  
1921      protected function create_navbar() {
1922          global $PAGE, $CFG;
1923  
1924          parent::create_navbar();
1925          $PAGE->navbar->add(get_string('restoreversion', 'wiki'));
1926      }
1927  
1928      protected function setup_tabs($options = array()) {
1929          parent::setup_tabs(array('linkedwhenactive' => 'history', 'activetab' => 'history'));
1930      }
1931  
1932      /**
1933       * This method returns the action bar.
1934       *
1935       * @param int $pageid The page id.
1936       * @param moodle_url $pageurl The page url.
1937       * @return string The HTML for the action bar.
1938       */
1939      protected function action_bar(int $pageid, moodle_url $pageurl): string {
1940          // The given page does not require an action bar.
1941          return '';
1942      }
1943  
1944      /**
1945       * Prints the restore version content
1946       *
1947       * @uses $CFG
1948       *
1949       * @param page $page The page whose version will be restored
1950       * @param int  $versionid The version to be restored
1951       * @param bool $confirm If false, shows a yes/no confirmation page.
1952       *     If true, restores the old version and redirects the user to the 'view' tab.
1953       */
1954      private function print_restoreversion() {
1955          global $OUTPUT;
1956  
1957          $version = wiki_get_version($this->version->id);
1958  
1959          $optionsyes = array('confirm'=>1, 'pageid'=>$this->page->id, 'versionid'=>$version->id, 'sesskey'=>sesskey());
1960          $restoreurl = new moodle_url('/mod/wiki/restoreversion.php', $optionsyes);
1961          $return = new moodle_url('/mod/wiki/viewversion.php', array('pageid'=>$this->page->id, 'versionid'=>$version->id));
1962  
1963          echo $OUTPUT->container_start();
1964          echo html_writer::tag('div', get_string('restoreconfirm', 'wiki', $version->version));
1965          echo $OUTPUT->container_start('mt-2', 'wiki_restoreform');
1966          $yesbutton = new single_button($restoreurl, get_string('yes'), 'post');
1967          $nobutton = new single_button($return, get_string('no'), 'post');
1968          $nobutton->class .= ' ml-2';
1969          echo $OUTPUT->render($yesbutton);
1970          echo $OUTPUT->render($nobutton);
1971          echo $OUTPUT->container_end();
1972          echo $OUTPUT->container_end();
1973      }
1974  }
1975  /**
1976   * Class that models the behavior of wiki's delete comment confirmation page
1977   *
1978   */
1979  class page_wiki_deletecomment extends page_wiki {
1980      private $commentid;
1981  
1982      function print_header() {
1983          parent::print_header();
1984          $this->print_pagetitle();
1985      }
1986  
1987      function print_content() {
1988          $this->printconfirmdelete();
1989      }
1990  
1991      function set_url() {
1992          global $PAGE;
1993          $PAGE->set_url('/mod/wiki/instancecomments.php', array('pageid' => $this->page->id, 'commentid' => $this->commentid));
1994      }
1995  
1996      public function set_action($action, $commentid, $content) {
1997          $this->action = $action;
1998          $this->commentid = $commentid;
1999          $this->content = $content;
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              print_error('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              print_error('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              print_error('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                  print_error('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  }