Search moodle.org's
Developer Documentation

See Release Notes

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

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

   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      public function wiki_info() {
 238          global $USER;
 239  
 240          // Display any activity information (eg completion requirements / dates).
 241          $cminfo = cm_info::create($this->page->cm);
 242          $completiondetails = \core_completion\cm_completion_details::get_instance($cminfo, $USER->id);
 243          $activitydates = \core\activity_dates::get_dates_for_module($cminfo, $USER->id);
 244          $info = $this->output->activity_information($cminfo, $completiondetails, $activitydates);
 245  
 246          // Add the rest of the wiki info.
 247          $info .= $this->output->box(format_module_intro('wiki',
 248                  $this->page->activityrecord, $this->page->cm->id), 'generalbox', 'intro');
 249  
 250          return $info;
 251      }
 252  
 253      public function tabs($page, $tabitems, $options) {
 254          $tabs = array();
 255          $context = context_module::instance($this->page->cm->id);
 256  
 257          $pageid = null;
 258          if (!empty($page)) {
 259              $pageid = $page->id;
 260          }
 261  
 262          $selected = $options['activetab'];
 263  
 264          // make specific tab linked even it is active
 265          if (!empty($options['linkedwhenactive'])) {
 266              $linked = $options['linkedwhenactive'];
 267          } else {
 268              $linked = '';
 269          }
 270  
 271          if (!empty($options['inactivetabs'])) {
 272              $inactive = $options['inactivetabs'];
 273          } else {
 274              $inactive = array();
 275          }
 276  
 277          foreach ($tabitems as $tab) {
 278              if ($tab == 'edit' && !has_capability('mod/wiki:editpage', $context)) {
 279                  continue;
 280              }
 281              if ($tab == 'comments' && !has_capability('mod/wiki:viewcomment', $context)) {
 282                  continue;
 283              }
 284              if ($tab == 'files' && !has_capability('mod/wiki:viewpage', $context)) {
 285                  continue;
 286              }
 287              if (($tab == 'view' || $tab == 'map' || $tab == 'history') && !has_capability('mod/wiki:viewpage', $context)) {
 288                  continue;
 289              }
 290              if ($tab == 'admin' && !has_capability('mod/wiki:managewiki', $context)) {
 291                  continue;
 292              }
 293              $link = new moodle_url('/mod/wiki/'. $tab. '.php', array('pageid' => $pageid));
 294              if ($linked == $tab) {
 295                  $tabs[] = new tabobject($tab, $link, get_string($tab, 'wiki'), '', true);
 296              } else {
 297                  $tabs[] = new tabobject($tab, $link, get_string($tab, 'wiki'));
 298              }
 299          }
 300  
 301          return $this->tabtree($tabs, $selected, $inactive);
 302      }
 303  
 304      public function prettyview_link($page) {
 305          $html = '';
 306          $link = new moodle_url('/mod/wiki/prettyview.php', array('pageid' => $page->id));
 307          $html .= $this->output->container_start('wiki_right');
 308          $html .= $this->output->action_link($link, get_string('prettyprint', 'wiki'), new popup_action('click', $link), array('class' => 'printicon'));
 309          $html .= $this->output->container_end();
 310          return $html;
 311      }
 312  
 313      public function wiki_print_subwiki_selector($wiki, $subwiki, $page, $pagetype = 'view') {
 314          global $CFG, $USER;
 315          require_once($CFG->dirroot . '/user/lib.php');
 316          $cm = get_coursemodule_from_instance('wiki', $wiki->id);
 317  
 318          switch ($pagetype) {
 319          case 'files':
 320              $baseurl = new moodle_url('/mod/wiki/files.php',
 321                      array('wid' => $wiki->id, 'title' => $page->title, 'pageid' => $page->id));
 322              break;
 323          case 'search':
 324              $search = optional_param('searchstring', null, PARAM_TEXT);
 325              $searchcontent = optional_param('searchwikicontent', 0, PARAM_INT);
 326              $baseurl = new moodle_url('/mod/wiki/search.php',
 327                      array('cmid' => $cm->id, 'courseid' => $cm->course,
 328                          'searchstring' => $search, 'searchwikicontent' => $searchcontent));
 329              break;
 330          case 'view':
 331          default:
 332              $baseurl = new moodle_url('/mod/wiki/view.php',
 333                      array('wid' => $wiki->id, 'title' => $page->title));
 334              break;
 335          }
 336  
 337          $context = context_module::instance($cm->id);
 338          // @TODO: A plenty of duplicated code below this lines.
 339          // Create private functions.
 340          switch (groups_get_activity_groupmode($cm)) {
 341          case NOGROUPS:
 342              if ($wiki->wikimode == 'collaborative') {
 343                  // No need to print anything
 344                  return;
 345              } else if ($wiki->wikimode == 'individual') {
 346                  // We have private wikis here
 347  
 348                  $view = has_capability('mod/wiki:viewpage', $context);
 349                  $manage = has_capability('mod/wiki:managewiki', $context);
 350  
 351                  // Only people with these capabilities can view all wikis
 352                  if ($view && $manage) {
 353                      // @TODO: Print here a combo that contains all users.
 354                      $users = get_enrolled_users($context);
 355                      $options = array();
 356                      foreach ($users as $user) {
 357                          $options[$user->id] = fullname($user);
 358                      }
 359  
 360                      echo $this->output->container_start('wiki_right');
 361                      $name = 'uid';
 362                      $selected = $subwiki->userid;
 363                      echo $this->output->single_select($baseurl, $name, $options, $selected, null, null,
 364                          array('label' => get_string('user') . ':'));
 365                      echo $this->output->container_end();
 366                  }
 367                  return;
 368              } else {
 369                  // error
 370                  return;
 371              }
 372          case SEPARATEGROUPS:
 373              if ($wiki->wikimode == 'collaborative') {
 374                  // We need to print a select to choose a course group
 375  
 376                  echo $this->output->container_start('wiki_right');
 377                  groups_print_activity_menu($cm, $baseurl);
 378                  echo $this->output->container_end();
 379                  return;
 380              } else if ($wiki->wikimode == 'individual') {
 381                  //  @TODO: Print here a combo that contains all users of that subwiki.
 382                  $view = has_capability('mod/wiki:viewpage', $context);
 383                  $manage = has_capability('mod/wiki:managewiki', $context);
 384  
 385                  // Only people with these capabilities can view all wikis
 386                  if ($view && $manage) {
 387                      $users = get_enrolled_users($context);
 388                      $options = array();
 389                      foreach ($users as $user) {
 390                          $groups = groups_get_all_groups($cm->course, $user->id);
 391                          if (!empty($groups)) {
 392                              foreach ($groups as $group) {
 393                                  $options[$group->id][$group->name][$group->id . '-' . $user->id] = fullname($user);
 394                              }
 395                          } else {
 396                              $name = get_string('notingroup', 'wiki');
 397                              $options[0][$name]['0' . '-' . $user->id] = fullname($user);
 398                          }
 399                      }
 400                  } else {
 401                      $group = groups_get_group($subwiki->groupid);
 402                      if (!$group) {
 403                          return;
 404                      }
 405                      $users = groups_get_members($subwiki->groupid);
 406                      foreach ($users as $user) {
 407                          $options[$group->id][$group->name][$group->id . '-' . $user->id] = fullname($user);
 408                      }
 409                  }
 410                  echo $this->output->container_start('wiki_right');
 411                  $name = 'groupanduser';
 412                  $selected = $subwiki->groupid . '-' . $subwiki->userid;
 413                  echo $this->output->single_select($baseurl, $name, $options, $selected, null, null,
 414                      array('label' => get_string('user') . ':'));
 415                  echo $this->output->container_end();
 416  
 417                  return;
 418  
 419              } else {
 420                  // error
 421                  return;
 422              }
 423          CASE VISIBLEGROUPS:
 424              if ($wiki->wikimode == 'collaborative') {
 425                  // We need to print a select to choose a course group
 426                  // moodle_url will take care of encoding for us
 427  
 428                  echo $this->output->container_start('wiki_right');
 429                  groups_print_activity_menu($cm, $baseurl);
 430                  echo $this->output->container_end();
 431                  return;
 432  
 433              } else if ($wiki->wikimode == 'individual') {
 434                  $users = get_enrolled_users($context);
 435                  $options = array();
 436                  foreach ($users as $user) {
 437                      $groups = groups_get_all_groups($cm->course, $user->id);
 438                      if (!empty($groups)) {
 439                          foreach ($groups as $group) {
 440                              $options[$group->id][$group->name][$group->id . '-' . $user->id] = fullname($user);
 441                          }
 442                      } else {
 443                          $name = get_string('notingroup', 'wiki');
 444                          $options[0][$name]['0' . '-' . $user->id] = fullname($user);
 445                      }
 446                  }
 447  
 448                  echo $this->output->container_start('wiki_right');
 449                  $name = 'groupanduser';
 450                  $selected = $subwiki->groupid . '-' . $subwiki->userid;
 451                  echo $this->output->single_select($baseurl, $name, $options, $selected, null, null,
 452                      array('label' => get_string('user') . ':'));
 453                  echo $this->output->container_end();
 454  
 455                  return;
 456  
 457              } else {
 458                  // error
 459                  return;
 460              }
 461          default:
 462              // error
 463              return;
 464  
 465          }
 466  
 467      }
 468  
 469      function menu_map($pageid, $currentselect) {
 470          if (empty($currentselect)) {
 471              // The wiki uses digit number to match the options and 5 is the default one.
 472              $currentselect = 5;
 473          }
 474          $options = array('contributions', 'links', 'orphaned', 'pageindex', 'pagelist', 'updatedpages');
 475          $items = array();
 476          foreach ($options as $opt) {
 477              $items[] = get_string($opt, 'wiki');
 478          }
 479          $selectoptions = array();
 480          foreach ($items as $key => $item) {
 481              $selectoptions[$key + 1] = $item;
 482          }
 483          $select = new single_select(new moodle_url('/mod/wiki/map.php', array('pageid' => $pageid)), 'option', $selectoptions, $currentselect, null);
 484          $select->label = get_string('mapmenu', 'wiki') . ': ';
 485          return $this->output->container($this->output->render($select), 'midpad');
 486      }
 487      public function wiki_files_tree($context, $subwiki) {
 488          return $this->render(new wiki_files_tree($context, $subwiki));
 489      }
 490      public function render_wiki_files_tree(wiki_files_tree $tree) {
 491          if (empty($tree->dir['subdirs']) && empty($tree->dir['files'])) {
 492              $html = $this->output->box(get_string('nofilesavailable', 'repository'));
 493          } else {
 494              $htmlid = 'wiki_files_tree_'.uniqid();
 495              $module = array('name'=>'mod_wiki', 'fullpath'=>'/mod/wiki/module.js');
 496              $this->page->requires->js_init_call('M.mod_wiki.init_tree', array(false, $htmlid), false, $module);
 497              $html = '<div id="'.$htmlid.'">';
 498              $html .= $this->htmllize_tree($tree, $tree->dir);
 499              $html .= '</div>';
 500          }
 501          return $html;
 502      }
 503  
 504      function menu_admin($pageid, $currentselect) {
 505          $options = array('removepages', 'deleteversions');
 506          $items = array();
 507          foreach ($options as $opt) {
 508              $items[] = get_string($opt, 'wiki');
 509          }
 510          $selectoptions = array();
 511          foreach ($items as $key => $item) {
 512              $selectoptions[$key + 1] = $item;
 513          }
 514          $select = new single_select(new moodle_url('/mod/wiki/admin.php', array('pageid' => $pageid)), 'option', $selectoptions, $currentselect, null);
 515          $select->label = get_string('adminmenu', 'wiki') . ': ';
 516          return $this->output->container($this->output->render($select), 'midpad');
 517      }
 518  
 519      /**
 520       * Internal function - creates htmls structure suitable for YUI tree.
 521       */
 522      protected function htmllize_tree($tree, $dir) {
 523          global $CFG;
 524          $yuiconfig = array();
 525          $yuiconfig['type'] = 'html';
 526  
 527          if (empty($dir['subdirs']) and empty($dir['files'])) {
 528              return '';
 529          }
 530          $result = '<ul>';
 531          foreach ($dir['subdirs'] as $subdir) {
 532              $image = $this->output->pix_icon(file_folder_icon(), $subdir['dirname'], 'moodle', array('class'=>'icon'));
 533              $result .= '<li yuiConfig=\''.json_encode($yuiconfig).'\'><div>'.$image.' '.s($subdir['dirname']).'</div> '.$this->htmllize_tree($tree, $subdir).'</li>';
 534          }
 535          foreach ($dir['files'] as $file) {
 536              $url = file_encode_url("$CFG->wwwroot/pluginfile.php", '/'.$tree->context->id.'/mod_wiki/attachments/' . $tree->subwiki->id . '/'. $file->get_filepath() . $file->get_filename(), true);
 537              $filename = $file->get_filename();
 538              $image = $this->output->pix_icon(file_file_icon($file), $filename, 'moodle', array('class'=>'icon'));
 539              $result .= '<li yuiConfig=\''.json_encode($yuiconfig).'\'><div>'.$image.' '.html_writer::link($url, $filename).'</div></li>';
 540          }
 541          $result .= '</ul>';
 542  
 543          return $result;
 544      }
 545  }
 546  
 547  class wiki_files_tree implements renderable {
 548      public $context;
 549      public $dir;
 550      public $subwiki;
 551      public function __construct($context, $subwiki) {
 552          $fs = get_file_storage();
 553          $this->context = $context;
 554          $this->subwiki = $subwiki;
 555          $this->dir = $fs->get_area_tree($context->id, 'mod_wiki', 'attachments', $subwiki->id);
 556      }
 557  }