Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401]

   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   * Moodle Wiki 2.0 Renderer
  20   *
  21   * @package   mod_wiki
  22   * @copyright 2010 Dongsheng Cai <dongsheng@moodle.com>
  23   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  class mod_wiki_renderer extends plugin_renderer_base {
  29      public function page_index() {
  30          global $CFG;
  31          $output = '';
  32          // Checking wiki instance
  33          if (!$wiki = wiki_get_wiki($this->page->cm->instance)) {
  34              return false;
  35          }
  36  
  37          // @TODO: Fix call to wiki_get_subwiki_by_group
  38          $gid = groups_get_activity_group($this->page->cm);
  39          $gid = !empty($gid) ? $gid : 0;
  40          if (!$subwiki = wiki_get_subwiki_by_group($this->page->cm->instance, $gid)) {
  41              return false;
  42          }
  43          $swid = $subwiki->id;
  44          $pages = wiki_get_page_list($swid);
  45          $selectoptions = array();
  46          foreach ($pages as $page) {
  47              $selectoptions[$page->id] = format_string($page->title, true, array('context' => $this->page->context));
  48          }
  49          $label = get_string('pageindex', 'wiki') . ': ';
  50          $select = new single_select(new moodle_url('/mod/wiki/view.php'), 'pageid', $selectoptions);
  51          $select->label = $label;
  52          return $this->output->container($this->output->render($select), 'wiki_index');
  53      }
  54  
  55      public function search_result($records, $subwiki) {
  56          global $CFG;
  57          $table = new html_table();
  58          $context = context_module::instance($this->page->cm->id);
  59          $strsearchresults = get_string('searchresult', 'wiki');
  60          $totalcount = count($records);
  61          $html = $this->output->heading("$strsearchresults $totalcount", 3);
  62          foreach ($records as $page) {
  63              $table->head = array('title' => format_string($page->title) . ' (' . html_writer::link($CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $page->id, get_string('view', 'wiki')) . ')');
  64              $table->align = array('title' => 'left');
  65              $table->width = '100%';
  66              $table->data = array(array(file_rewrite_pluginfile_urls(format_text($page->cachedcontent, FORMAT_HTML), 'pluginfile.php', $context->id, 'mod_wiki', 'attachments', $subwiki->id)));
  67              $table->colclasses = array('wikisearchresults');
  68              $html .= html_writer::table($table);
  69          }
  70          $html = html_writer::tag('div', $html, array('class'=>'no-overflow'));
  71          return $this->output->container($html);
  72      }
  73  
  74      public function diff($pageid, $old, $new, $options = array()) {
  75          global $CFG;
  76          if (!empty($options['total'])) {
  77              $total = $options['total'];
  78          } else {
  79              $total = 0;
  80          }
  81          $diff1 = format_text($old->diff, FORMAT_HTML, array('overflowdiv'=>true));
  82          $diff2 = format_text($new->diff, FORMAT_HTML, array('overflowdiv'=>true));
  83          $strdatetime = get_string('strftimedatetime', 'langconfig');
  84  
  85          $olduser = $old->user;
  86          $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $old->id));
  87          $restorelink = new moodle_url('/mod/wiki/restoreversion.php', array('pageid' => $pageid, 'versionid' => $old->id));
  88          $userlink = new moodle_url('/user/view.php', array('id' => $olduser->id));
  89          // view version link
  90          $oldversionview = ' ';
  91          $oldversionview .= html_writer::link($versionlink->out(false), get_string('view', 'wiki'), array('class' => 'wiki_diffview'));
  92          $oldversionview .= ' ';
  93          // restore version link
  94          $oldversionview .= html_writer::link($restorelink->out(false), get_string('restore', 'wiki'), array('class' => 'wiki_diffview'));
  95  
  96          // userinfo container
  97          $oldheading = $this->output->container_start('wiki_diffuserleft');
  98          // username
  99          $oldheading .= html_writer::link($CFG->wwwroot . '/user/view.php?id=' . $olduser->id, fullname($olduser)) . '&nbsp;';
 100          // user picture
 101          $oldheading .= html_writer::link($userlink->out(false), $this->output->user_picture($olduser, array('popup' => true)), array('class' => 'notunderlined'));
 102          $oldheading .= $this->output->container_end();
 103  
 104          // version number container
 105          $oldheading .= $this->output->container_start('wiki_diffversion');
 106          $oldheading .= get_string('version') . ' ' . $old->version . $oldversionview;
 107          $oldheading .= $this->output->container_end();
 108          // userdate container
 109          $oldheading .= $this->output->container_start('wiki_difftime');
 110          $oldheading .= userdate($old->timecreated, $strdatetime);
 111          $oldheading .= $this->output->container_end();
 112  
 113          $newuser = $new->user;
 114          $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $new->id));
 115          $restorelink = new moodle_url('/mod/wiki/restoreversion.php', array('pageid' => $pageid, 'versionid' => $new->id));
 116          $userlink = new moodle_url('/user/view.php', array('id' => $newuser->id));
 117  
 118          $newversionview = ' ';
 119          $newversionview .= html_writer::link($versionlink->out(false), get_string('view', 'wiki'), array('class' => 'wiki_diffview'));
 120          // new user info
 121          $newheading = $this->output->container_start('wiki_diffuserright');
 122          $newheading .= $this->output->user_picture($newuser, array('popup' => true));
 123  
 124          $newheading .= html_writer::link($userlink->out(false), fullname($newuser), array('class' => 'notunderlined'));
 125          $newheading .= $this->output->container_end();
 126  
 127          // version
 128          $newheading .= $this->output->container_start('wiki_diffversion');
 129          $newheading .= get_string('version') . '&nbsp;' . $new->version . $newversionview;
 130          $newheading .= $this->output->container_end();
 131          // userdate
 132          $newheading .= $this->output->container_start('wiki_difftime');
 133          $newheading .= userdate($new->timecreated, $strdatetime);
 134          $newheading .= $this->output->container_end();
 135  
 136          $oldheading = html_writer::tag('div', $oldheading, array('class'=>'wiki-diff-heading header clearfix'));
 137          $newheading = html_writer::tag('div', $newheading, array('class'=>'wiki-diff-heading header clearfix'));
 138  
 139          $output  = '';
 140          $output .= html_writer::start_tag('div', array('class'=>'wiki-diff-container clearfix'));
 141          $output .= html_writer::tag('div', $oldheading.$diff1, array('class'=>'wiki-diff-leftside'));
 142          $output .= html_writer::tag('div', $newheading.$diff2, array('class'=>'wiki-diff-rightside'));
 143          $output .= html_writer::end_tag('div');
 144  
 145          if (!empty($total)) {
 146              $output .= '<div class="wiki_diff_paging">';
 147              $output .= $this->output->container($this->diff_paging_bar(1, $new->version - 1, $old->version, $CFG->wwwroot . '/mod/wiki/diff.php?pageid=' . $pageid . '&amp;comparewith=' . $new->version . '&amp;', 'compare', false, true), 'wiki_diff_oldpaging');
 148              $output .= $this->output->container($this->diff_paging_bar($old->version + 1, $total, $new->version, $CFG->wwwroot . '/mod/wiki/diff.php?pageid=' . $pageid . '&amp;compare=' . $old->version . '&amp;', 'comparewith', false, true), 'wiki_diff_newpaging');
 149              $output .= '</div>';
 150          }
 151  
 152          return $output;
 153      }
 154  
 155      /**
 156       * Prints a single paging bar to provide access to other versions
 157       *
 158       * @param int $minpage First page to be displayed in the bar
 159       * @param int $maxpage Last page to be displayed in the bar
 160       * @param int $page The page you are currently viewing
 161       * @param mixed $baseurl If this  is a string then it is the url which will be appended with $pagevar, an equals sign and the page number.
 162       *                          If this is a moodle_url object then the pagevar param will be replaced by the page no, for each page.
 163       * @param string $pagevar This is the variable name that you use for the page number in your code (ie. 'tablepage', 'blogpage', etc)
 164       * @param bool $nocurr do not display the current page as a link
 165       * @param bool $return whether to return an output string or echo now
 166       * @return bool or string
 167       */
 168      public function diff_paging_bar($minpage, $maxpage, $page, $baseurl, $pagevar = 'page', $nocurr = false) {
 169          $totalcount = $maxpage - $minpage;
 170          $maxdisplay = 2;
 171          $output = '';
 172  
 173          if ($totalcount > 0) {
 174              $output .= '<div class="paging">';
 175              $output .= get_string('version', 'wiki') . ':';
 176              if ($page - $minpage > 0) {
 177                  $pagenum = $page - 1;
 178                  if (!is_a($baseurl, 'moodle_url')) {
 179                      $output .= '&nbsp;(<a class="previous" href="' . $baseurl . $pagevar . '=' . $pagenum . '">' . get_string('previous') . '</a>)&nbsp;';
 180                  } else {
 181                      $output .= '&nbsp;(<a class="previous" href="' . $baseurl->out(false, array($pagevar => $pagenum)) . '">' . get_string('previous') . '</a>)&nbsp;';
 182                  }
 183              }
 184  
 185              if ($page - $minpage > 4) {
 186                  $startpage = $page - 3;
 187                  if (!is_a($baseurl, 'moodle_url')) {
 188                      $output .= '&nbsp;<a href="' . $baseurl . $pagevar . '=' . $minpage . '">' . $minpage . '</a>&nbsp;...';
 189                  } else {
 190                      $output .= '&nbsp;<a href="' . $baseurl->out(false, array($pagevar => $minpage)) . '">' . $minpage . '</a>&nbsp;...';
 191                  }
 192              } else {
 193                  $startpage = $minpage;
 194              }
 195              $currpage = $startpage;
 196              $displaycount = 0;
 197              while ($displaycount < $maxdisplay and $currpage <= $maxpage) {
 198                  if ($page == $currpage && empty($nocurr)) {
 199                      $output .= '&nbsp;&nbsp;' . $currpage;
 200                  } else {
 201                      if (!is_a($baseurl, 'moodle_url')) {
 202                          $output .= '&nbsp;&nbsp;<a href="' . $baseurl . $pagevar . '=' . $currpage . '">' . $currpage . '</a>';
 203                      } else {
 204                          $output .= '&nbsp;&nbsp;<a href="' . $baseurl->out(false, array($pagevar => $currpage)) . '">' . $currpage . '</a>';
 205                      }
 206  
 207                  }
 208                  $displaycount++;
 209                  $currpage++;
 210              }
 211              if ($currpage < $maxpage) {
 212                  if (!is_a($baseurl, 'moodle_url')) {
 213                      $output .= '&nbsp;...<a href="' . $baseurl . $pagevar . '=' . $maxpage . '">' . $maxpage . '</a>&nbsp;';
 214                  } else {
 215                      $output .= '&nbsp;...<a href="' . $baseurl->out(false, array($pagevar => $maxpage)) . '">' . $maxpage . '</a>&nbsp;';
 216                  }
 217              } else if ($currpage == $maxpage) {
 218                  if (!is_a($baseurl, 'moodle_url')) {
 219                      $output .= '&nbsp;&nbsp;<a href="' . $baseurl . $pagevar . '=' . $currpage . '">' . $currpage . '</a>';
 220                  } else {
 221                      $output .= '&nbsp;&nbsp;<a href="' . $baseurl->out(false, array($pagevar => $currpage)) . '">' . $currpage . '</a>';
 222                  }
 223              }
 224              $pagenum = $page + 1;
 225              if ($page != $maxpage) {
 226                  if (!is_a($baseurl, 'moodle_url')) {
 227                      $output .= '&nbsp;&nbsp;(<a class="next" href="' . $baseurl . $pagevar . '=' . $pagenum . '">' . get_string('next') . '</a>)';
 228                  } else {
 229                      $output .= '&nbsp;&nbsp;(<a class="next" href="' . $baseurl->out(false, array($pagevar => $pagenum)) . '">' . get_string('next') . '</a>)';
 230                  }
 231              }
 232              $output .= '</div>';
 233          }
 234  
 235          return $output;
 236      }
 237  
 238      /**
 239       * Print the wiki activity information and intro
 240       *
 241       * @return string
 242       * @deprecated since 4.0. Now handled in PAGE's activity header
 243       */
 244      public function wiki_info() {
 245          global $USER;
 246  
 247          debugging(
 248              'wiki_info() is deprecated. Output is handled within the $PAGE->activityheader instead.',
 249              DEBUG_DEVELOPER
 250          );
 251  
 252          // Display any activity information (eg completion requirements / dates).
 253          $cminfo = cm_info::create($this->page->cm);
 254          $completiondetails = \core_completion\cm_completion_details::get_instance($cminfo, $USER->id);
 255          $activitydates = \core\activity_dates::get_dates_for_module($cminfo, $USER->id);
 256          $info = $this->output->activity_information($cminfo, $completiondetails, $activitydates);
 257  
 258          // Add the rest of the wiki info.
 259          $info .= $this->output->box(format_module_intro('wiki',
 260                  $this->page->activityrecord, $this->page->cm->id), 'generalbox', 'intro');
 261  
 262          return $info;
 263      }
 264  
 265      public function tabs($page, $tabitems, $options) {
 266          $tabs = array();
 267          $context = context_module::instance($this->page->cm->id);
 268  
 269          $pageid = null;
 270          if (!empty($page)) {
 271              $pageid = $page->id;
 272          }
 273  
 274          $selected = $options['activetab'];
 275  
 276          // make specific tab linked even it is active
 277          if (!empty($options['linkedwhenactive'])) {
 278              $linked = $options['linkedwhenactive'];
 279          } else {
 280              $linked = '';
 281          }
 282  
 283          if (!empty($options['inactivetabs'])) {
 284              $inactive = $options['inactivetabs'];
 285          } else {
 286              $inactive = array();
 287          }
 288  
 289          foreach ($tabitems as $tab) {
 290              if ($tab == 'edit' && !has_capability('mod/wiki:editpage', $context)) {
 291                  continue;
 292              }
 293              if ($tab == 'comments' && !has_capability('mod/wiki:viewcomment', $context)) {
 294                  continue;
 295              }
 296              if ($tab == 'files' && !has_capability('mod/wiki:viewpage', $context)) {
 297                  continue;
 298              }
 299              if (($tab == 'view' || $tab == 'map' || $tab == 'history') && !has_capability('mod/wiki:viewpage', $context)) {
 300                  continue;
 301              }
 302              if ($tab == 'admin' && !has_capability('mod/wiki:managewiki', $context)) {
 303                  continue;
 304              }
 305              $link = new moodle_url('/mod/wiki/'. $tab. '.php', array('pageid' => $pageid));
 306              if ($linked == $tab) {
 307                  $tabs[] = new tabobject($tab, $link, get_string($tab, 'wiki'), '', true);
 308              } else {
 309                  $tabs[] = new tabobject($tab, $link, get_string($tab, 'wiki'));
 310              }
 311          }
 312  
 313          return $this->tabtree($tabs, $selected, $inactive);
 314      }
 315  
 316      public function prettyview_link($page) {
 317          $html = '';
 318          $link = new moodle_url('/mod/wiki/prettyview.php', array('pageid' => $page->id));
 319          $html .= $this->output->container_start('wiki_right');
 320          $html .= $this->output->action_link($link, get_string('prettyprint', 'wiki'), new popup_action('click', $link), array('class' => 'printicon'));
 321          $html .= $this->output->container_end();
 322          return $html;
 323      }
 324  
 325      public function wiki_print_subwiki_selector($wiki, $subwiki, $page, $pagetype = 'view') {
 326          global $CFG, $USER;
 327          require_once($CFG->dirroot . '/user/lib.php');
 328          $cm = get_coursemodule_from_instance('wiki', $wiki->id);
 329  
 330          switch ($pagetype) {
 331          case 'files':
 332              $baseurl = new moodle_url('/mod/wiki/files.php',
 333                      array('wid' => $wiki->id, 'title' => $page->title, 'pageid' => $page->id));
 334              break;
 335          case 'search':
 336              $search = optional_param('searchstring', null, PARAM_TEXT);
 337              $searchcontent = optional_param('searchwikicontent', 0, PARAM_INT);
 338              $baseurl = new moodle_url('/mod/wiki/search.php',
 339                      array('cmid' => $cm->id, 'courseid' => $cm->course,
 340                          'searchstring' => $search, 'searchwikicontent' => $searchcontent));
 341              break;
 342          case 'view':
 343          default:
 344              $baseurl = new moodle_url('/mod/wiki/view.php',
 345                      array('wid' => $wiki->id, 'title' => $page->title));
 346              break;
 347          }
 348  
 349          $context = context_module::instance($cm->id);
 350          // @TODO: A plenty of duplicated code below this lines.
 351          // Create private functions.
 352          switch (groups_get_activity_groupmode($cm)) {
 353          case NOGROUPS:
 354              if ($wiki->wikimode == 'collaborative') {
 355                  // No need to print anything
 356                  return;
 357              } else if ($wiki->wikimode == 'individual') {
 358                  // We have private wikis here
 359  
 360                  $view = has_capability('mod/wiki:viewpage', $context);
 361                  $manage = has_capability('mod/wiki:managewiki', $context);
 362  
 363                  // Only people with these capabilities can view all wikis
 364                  if ($view && $manage) {
 365                      // @TODO: Print here a combo that contains all users.
 366                      $users = get_enrolled_users($context);
 367                      $options = array();
 368                      foreach ($users as $user) {
 369                          $options[$user->id] = fullname($user);
 370                      }
 371  
 372                      echo $this->output->container_start('wiki_right');
 373                      $name = 'uid';
 374                      $selected = $subwiki->userid;
 375                      echo $this->output->single_select($baseurl, $name, $options, $selected, null, null,
 376                          array('label' => get_string('user') . ':'));
 377                      echo $this->output->container_end();
 378                  }
 379                  return;
 380              } else {
 381                  // error
 382                  return;
 383              }
 384          case SEPARATEGROUPS:
 385              if ($wiki->wikimode == 'collaborative') {
 386                  // We need to print a select to choose a course group
 387  
 388                  echo $this->output->container_start('wiki_right');
 389                  groups_print_activity_menu($cm, $baseurl);
 390                  echo $this->output->container_end();
 391                  return;
 392              } else if ($wiki->wikimode == 'individual') {
 393                  //  @TODO: Print here a combo that contains all users of that subwiki.
 394                  $view = has_capability('mod/wiki:viewpage', $context);
 395                  $manage = has_capability('mod/wiki:managewiki', $context);
 396  
 397                  // Only people with these capabilities can view all wikis
 398                  if ($view && $manage) {
 399                      $users = get_enrolled_users($context);
 400                      $options = array();
 401                      foreach ($users as $user) {
 402                          $groups = groups_get_all_groups($cm->course, $user->id);
 403                          if (!empty($groups)) {
 404                              foreach ($groups as $group) {
 405                                  $options[$group->id][$group->name][$group->id . '-' . $user->id] = fullname($user);
 406                              }
 407                          } else {
 408                              $name = get_string('notingroup', 'wiki');
 409                              $options[0][$name]['0' . '-' . $user->id] = fullname($user);
 410                          }
 411                      }
 412                  } else {
 413                      $group = groups_get_group($subwiki->groupid);
 414                      if (!$group) {
 415                          return;
 416                      }
 417                      $users = groups_get_members($subwiki->groupid);
 418                      foreach ($users as $user) {
 419                          $options[$group->id][$group->name][$group->id . '-' . $user->id] = fullname($user);
 420                      }
 421                  }
 422                  echo $this->output->container_start('wiki_right');
 423                  $name = 'groupanduser';
 424                  $selected = $subwiki->groupid . '-' . $subwiki->userid;
 425                  echo $this->output->single_select($baseurl, $name, $options, $selected, null, null,
 426                      array('label' => get_string('user') . ':'));
 427                  echo $this->output->container_end();
 428  
 429                  return;
 430  
 431              } else {
 432                  // error
 433                  return;
 434              }
 435          CASE VISIBLEGROUPS:
 436              if ($wiki->wikimode == 'collaborative') {
 437                  // We need to print a select to choose a course group
 438                  // moodle_url will take care of encoding for us
 439  
 440                  echo $this->output->container_start('wiki_right');
 441                  groups_print_activity_menu($cm, $baseurl);
 442                  echo $this->output->container_end();
 443                  return;
 444  
 445              } else if ($wiki->wikimode == 'individual') {
 446                  $users = get_enrolled_users($context);
 447                  $options = array();
 448                  foreach ($users as $user) {
 449                      $groups = groups_get_all_groups($cm->course, $user->id);
 450                      if (!empty($groups)) {
 451                          foreach ($groups as $group) {
 452                              $options[$group->id][$group->name][$group->id . '-' . $user->id] = fullname($user);
 453                          }
 454                      } else {
 455                          $name = get_string('notingroup', 'wiki');
 456                          $options[0][$name]['0' . '-' . $user->id] = fullname($user);
 457                      }
 458                  }
 459  
 460                  echo $this->output->container_start('wiki_right');
 461                  $name = 'groupanduser';
 462                  $selected = $subwiki->groupid . '-' . $subwiki->userid;
 463                  echo $this->output->single_select($baseurl, $name, $options, $selected, null, null,
 464                      array('label' => get_string('user') . ':'));
 465                  echo $this->output->container_end();
 466  
 467                  return;
 468  
 469              } else {
 470                  // error
 471                  return;
 472              }
 473          default:
 474              // error
 475              return;
 476  
 477          }
 478  
 479      }
 480  
 481      function menu_map($pageid, $currentselect) {
 482          if (empty($currentselect)) {
 483              // The wiki uses digit number to match the options and 5 is the default one.
 484              $currentselect = 5;
 485          }
 486          $options = array('contributions', 'links', 'orphaned', 'pageindex', 'pagelist', 'updatedpages');
 487          $items = array();
 488          foreach ($options as $opt) {
 489              $items[] = get_string($opt, 'wiki');
 490          }
 491          $selectoptions = array();
 492          foreach ($items as $key => $item) {
 493              $selectoptions[$key + 1] = $item;
 494          }
 495          $select = new single_select(new moodle_url('/mod/wiki/map.php', array('pageid' => $pageid)), 'option', $selectoptions, $currentselect, null);
 496          $select->label = get_string('mapmenu', 'wiki') . ': ';
 497          return $this->output->container($this->output->render($select), 'midpad');
 498      }
 499      public function wiki_files_tree($context, $subwiki) {
 500          return $this->render(new wiki_files_tree($context, $subwiki));
 501      }
 502      public function render_wiki_files_tree(wiki_files_tree $tree) {
 503          if (empty($tree->dir['subdirs']) && empty($tree->dir['files'])) {
 504              $html = $this->output->box(get_string('nofilesavailable', 'repository'));
 505          } else {
 506              $htmlid = 'wiki_files_tree_'.uniqid();
 507              $module = array('name'=>'mod_wiki', 'fullpath'=>'/mod/wiki/module.js');
 508              $this->page->requires->js_init_call('M.mod_wiki.init_tree', array(false, $htmlid), false, $module);
 509              $html = '<div id="'.$htmlid.'">';
 510              $html .= $this->htmllize_tree($tree, $tree->dir);
 511              $html .= '</div>';
 512          }
 513          return $html;
 514      }
 515  
 516      function menu_admin($pageid, $currentselect) {
 517          $options = array('removepages', 'deleteversions');
 518          $items = array();
 519          foreach ($options as $opt) {
 520              $items[] = get_string($opt, 'wiki');
 521          }
 522          $selectoptions = array();
 523          foreach ($items as $key => $item) {
 524              $selectoptions[$key + 1] = $item;
 525          }
 526          $select = new single_select(new moodle_url('/mod/wiki/admin.php', array('pageid' => $pageid)), 'option', $selectoptions, $currentselect, null);
 527          $select->label = get_string('adminmenu', 'wiki') . ': ';
 528          return $this->output->container($this->output->render($select), 'midpad');
 529      }
 530  
 531      /**
 532       * Internal function - creates htmls structure suitable for YUI tree.
 533       */
 534      protected function htmllize_tree($tree, $dir) {
 535          global $CFG;
 536          $yuiconfig = array();
 537          $yuiconfig['type'] = 'html';
 538  
 539          if (empty($dir['subdirs']) and empty($dir['files'])) {
 540              return '';
 541          }
 542          $result = '<ul>';
 543          foreach ($dir['subdirs'] as $subdir) {
 544              $image = $this->output->pix_icon(file_folder_icon(), $subdir['dirname'], 'moodle', array('class'=>'icon'));
 545              $result .= '<li yuiConfig=\''.json_encode($yuiconfig).'\'><div>'.$image.' '.s($subdir['dirname']).'</div> '.$this->htmllize_tree($tree, $subdir).'</li>';
 546          }
 547          foreach ($dir['files'] as $file) {
 548              $url = file_encode_url("$CFG->wwwroot/pluginfile.php", '/'.$tree->context->id.'/mod_wiki/attachments/' . $tree->subwiki->id . '/'. $file->get_filepath() . $file->get_filename(), true);
 549              $filename = $file->get_filename();
 550              $image = $this->output->pix_icon(file_file_icon($file), $filename, 'moodle', array('class'=>'icon'));
 551              $result .= '<li yuiConfig=\''.json_encode($yuiconfig).'\'><div>'.$image.' '.html_writer::link($url, $filename).'</div></li>';
 552          }
 553          $result .= '</ul>';
 554  
 555          return $result;
 556      }
 557  
 558      /**
 559       * Renders the action bar.
 560       *
 561       * @param \mod_wiki\output\action_bar $actionbar
 562       * @return string The HTML output
 563       */
 564      public function render_action_bar(\mod_wiki\output\action_bar $actionbar): string {
 565          $data = $actionbar->export_for_template($this);
 566          return $this->render_from_template('mod_wiki/action_bar', $data);
 567      }
 568  }
 569  
 570  class wiki_files_tree implements renderable {
 571      public $context;
 572      public $dir;
 573      public $subwiki;
 574      public function __construct($context, $subwiki) {
 575          $fs = get_file_storage();
 576          $this->context = $context;
 577          $this->subwiki = $subwiki;
 578          $this->dir = $fs->get_area_tree($context->id, 'mod_wiki', 'attachments', $subwiki->id);
 579      }
 580  }