[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/quiz/classes/output/ -> edit_renderer.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Renderer outputting the quiz editing UI.
  19   *
  20   * @package mod_quiz
  21   * @copyright 2013 The Open University.
  22   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace mod_quiz\output;
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  use \mod_quiz\structure;
  29  use \html_writer;
  30  
  31  /**
  32   * Renderer outputting the quiz editing UI.
  33   *
  34   * @copyright 2013 The Open University.
  35   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   * @since Moodle 2.7
  37   */
  38  class edit_renderer extends \plugin_renderer_base {
  39  
  40      /**
  41       * Render the edit page
  42       *
  43       * @param \quiz $quizobj object containing all the quiz settings information.
  44       * @param structure $structure object containing the structure of the quiz.
  45       * @param \question_edit_contexts $contexts the relevant question bank contexts.
  46       * @param \moodle_url $pageurl the canonical URL of this page.
  47       * @param array $pagevars the variables from {@link question_edit_setup()}.
  48       * @return string HTML to output.
  49       */
  50      public function edit_page(\quiz $quizobj, structure $structure,
  51              \question_edit_contexts $contexts, \moodle_url $pageurl, array $pagevars) {
  52          $output = '';
  53  
  54          // Page title.
  55          $output .= $this->heading_with_help(get_string('editingquizx', 'quiz',
  56                  format_string($quizobj->get_quiz_name())), 'editingquiz', 'quiz', '',
  57                  get_string('basicideasofquiz', 'quiz'), 2);
  58  
  59          // Information at the top.
  60          $output .= $this->quiz_state_warnings($structure);
  61          $output .= $this->quiz_information($structure);
  62          $output .= $this->maximum_grade_input($structure, $pageurl);
  63          $output .= $this->repaginate_button($structure, $pageurl);
  64          $output .= $this->total_marks($quizobj->get_quiz());
  65  
  66          // Show the questions organised into sections and pages.
  67          $output .= $this->start_section_list($structure);
  68  
  69          foreach ($structure->get_sections() as $section) {
  70              $output .= $this->start_section($structure, $section);
  71              $output .= $this->questions_in_section($structure, $section, $contexts, $pagevars, $pageurl);
  72  
  73              if ($structure->is_last_section($section)) {
  74                  $output .= \html_writer::start_div('last-add-menu');
  75                  $output .= html_writer::tag('span', $this->add_menu_actions($structure, 0,
  76                          $pageurl, $contexts, $pagevars), array('class' => 'add-menu-outer'));
  77                  $output .= \html_writer::end_div();
  78              }
  79  
  80              $output .= $this->end_section();
  81          }
  82  
  83          $output .= $this->end_section_list();
  84  
  85          // Initialise the JavaScript.
  86          $this->initialise_editing_javascript($structure, $contexts, $pagevars, $pageurl);
  87  
  88          // Include the contents of any other popups required.
  89          if ($structure->can_be_edited()) {
  90              $popups = '';
  91  
  92              $popups .= $this->question_bank_loading();
  93              $this->page->requires->yui_module('moodle-mod_quiz-quizquestionbank',
  94                      'M.mod_quiz.quizquestionbank.init',
  95                      array('class' => 'questionbank', 'cmid' => $structure->get_cmid()));
  96  
  97              $popups .= $this->random_question_form($pageurl, $contexts, $pagevars);
  98              $this->page->requires->yui_module('moodle-mod_quiz-randomquestion',
  99                      'M.mod_quiz.randomquestion.init');
 100  
 101              $output .= html_writer::div($popups, 'mod_quiz_edit_forms');
 102  
 103              // Include the question chooser.
 104              $output .= $this->question_chooser();
 105              $this->page->requires->yui_module('moodle-mod_quiz-questionchooser', 'M.mod_quiz.init_questionchooser');
 106          }
 107  
 108          return $output;
 109      }
 110  
 111      /**
 112       * Render any warnings that might be required about the state of the quiz,
 113       * e.g. if it has been attempted, or if the shuffle questions option is
 114       * turned on.
 115       *
 116       * @param structure $structure the quiz structure.
 117       * @return string HTML to output.
 118       */
 119      public function quiz_state_warnings(structure $structure) {
 120          $warnings = $structure->get_edit_page_warnings();
 121  
 122          if (empty($warnings)) {
 123              return '';
 124          }
 125  
 126          $output = array();
 127          foreach ($warnings as $warning) {
 128              $output[] = \html_writer::tag('p', $warning);
 129          }
 130          return $this->box(implode("\n", $output), 'statusdisplay');
 131      }
 132  
 133      /**
 134       * Render the status bar.
 135       *
 136       * @param structure $structure the quiz structure.
 137       * @return string HTML to output.
 138       */
 139      public function quiz_information(structure $structure) {
 140          list($currentstatus, $explanation) = $structure->get_dates_summary();
 141  
 142          $output = html_writer::span(
 143                      get_string('numquestionsx', 'quiz', $structure->get_question_count()),
 144                      'numberofquestions') . ' | ' .
 145                  html_writer::span($currentstatus, 'quizopeningstatus',
 146                      array('title' => $explanation));
 147  
 148          return html_writer::div($output, 'statusbar');
 149      }
 150  
 151      /**
 152       * Render the form for setting a quiz' overall grade
 153       *
 154       * @param structure $structure the quiz structure.
 155       * @param \moodle_url $pageurl the canonical URL of this page.
 156       * @return string HTML to output.
 157       */
 158      public function maximum_grade_input($structure, \moodle_url $pageurl) {
 159          $output = '';
 160          $output .= html_writer::start_div('maxgrade');
 161          $output .= html_writer::start_tag('form', array('method' => 'post', 'action' => 'edit.php',
 162                  'class' => 'quizsavegradesform'));
 163          $output .= html_writer::start_tag('fieldset', array('class' => 'invisiblefieldset'));
 164          $output .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
 165          $output .= html_writer::input_hidden_params($pageurl);
 166          $a = html_writer::empty_tag('input', array('type' => 'text', 'id' => 'inputmaxgrade',
 167                  'name' => 'maxgrade', 'size' => ($structure->get_decimal_places_for_grades() + 2),
 168                  'value' => $structure->formatted_quiz_grade()));
 169          $output .= html_writer::tag('label', get_string('maximumgradex', '', $a),
 170                  array('for' => 'inputmaxgrade'));
 171          $output .= html_writer::empty_tag('input', array('type' => 'submit',
 172                  'name' => 'savechanges', 'value' => get_string('save', 'quiz')));
 173          $output .= html_writer::end_tag('fieldset');
 174          $output .= html_writer::end_tag('form');
 175          $output .= html_writer::end_tag('div');
 176          return $output;
 177      }
 178  
 179      /**
 180       * Return the repaginate button
 181       * @param structure $structure the structure of the quiz being edited.
 182       * @param \moodle_url $pageurl the canonical URL of this page.
 183       * @return string HTML to output.
 184       */
 185      protected function repaginate_button(structure $structure, \moodle_url $pageurl) {
 186  
 187          $header = html_writer::tag('span', get_string('repaginatecommand', 'quiz'), array('class' => 'repaginatecommand'));
 188          $form = $this->repaginate_form($structure, $pageurl);
 189          $containeroptions = array(
 190                  'class'  => 'rpcontainerclass',
 191                  'cmid'   => $structure->get_cmid(),
 192                  'header' => $header,
 193                  'form'   => $form,
 194          );
 195  
 196          $buttonoptions = array(
 197              'type'  => 'submit',
 198              'name'  => 'repaginate',
 199              'id'    => 'repaginatecommand',
 200              'value' => get_string('repaginatecommand', 'quiz'),
 201          );
 202          if (!$structure->can_be_repaginated()) {
 203              $buttonoptions['disabled'] = 'disabled';
 204          } else {
 205              $this->page->requires->yui_module('moodle-mod_quiz-repaginate', 'M.mod_quiz.repaginate.init');
 206          }
 207  
 208          return html_writer::tag('div',
 209                  html_writer::empty_tag('input', $buttonoptions), $containeroptions);
 210      }
 211  
 212      /**
 213       * Return the repaginate form
 214       * @param structure $structure the structure of the quiz being edited.
 215       * @param \moodle_url $pageurl the canonical URL of this page.
 216       * @return string HTML to output.
 217       */
 218      protected function repaginate_form(structure $structure, \moodle_url $pageurl) {
 219          $perpage = array();
 220          $perpage[0] = get_string('allinone', 'quiz');
 221          for ($i = 1; $i <= 50; ++$i) {
 222              $perpage[$i] = $i;
 223          }
 224  
 225          $hiddenurl = clone($pageurl);
 226          $hiddenurl->param('sesskey', sesskey());
 227  
 228          $select = html_writer::select($perpage, 'questionsperpage',
 229                  $structure->get_questions_per_page(), false);
 230  
 231          $buttonattributes = array('type' => 'submit', 'name' => 'repaginate', 'value' => get_string('go'));
 232  
 233          $formcontent = html_writer::tag('form', html_writer::div(
 234                      html_writer::input_hidden_params($hiddenurl) .
 235                      get_string('repaginate', 'quiz', $select) .
 236                      html_writer::empty_tag('input', $buttonattributes)
 237                  ), array('action' => 'edit.php', 'method' => 'post'));
 238  
 239          return html_writer::div($formcontent, '', array('id' => 'repaginatedialog'));
 240      }
 241  
 242      /**
 243       * Render the total marks available for the quiz.
 244       *
 245       * @param \stdClass $quiz the quiz settings from the database.
 246       * @return string HTML to output.
 247       */
 248      public function total_marks($quiz) {
 249          $totalmark = html_writer::span(quiz_format_grade($quiz, $quiz->sumgrades), 'mod_quiz_summarks');
 250          return html_writer::tag('span',
 251                  get_string('totalmarksx', 'quiz', $totalmark),
 252                  array('class' => 'totalpoints'));
 253      }
 254  
 255      /**
 256       * Generate the starting container html for the start of a list of sections
 257       * @param structure $structure the structure of the quiz being edited.
 258       * @return string HTML to output.
 259       */
 260      protected function start_section_list(structure $structure) {
 261          $class = 'slots';
 262          if ($structure->get_section_count() == 1) {
 263              $class .= ' only-one-section';
 264          }
 265          return html_writer::start_tag('ul', array('class' => $class));
 266      }
 267  
 268      /**
 269       * Generate the closing container html for the end of a list of sections
 270       * @return string HTML to output.
 271       */
 272      protected function end_section_list() {
 273          return html_writer::end_tag('ul');
 274      }
 275  
 276      /**
 277       * Display the start of a section, before the questions.
 278       *
 279       * @param structure $structure the structure of the quiz being edited.
 280       * @param \stdClass $section The quiz_section entry from DB
 281       * @return string HTML to output.
 282       */
 283      protected function start_section($structure, $section) {
 284  
 285          $output = '';
 286  
 287          $sectionstyle = '';
 288          if ($structure->is_only_one_slot_in_section($section)) {
 289              $sectionstyle = ' only-has-one-slot';
 290          }
 291  
 292          $output .= html_writer::start_tag('li', array('id' => 'section-'.$section->id,
 293              'class' => 'section main clearfix'.$sectionstyle, 'role' => 'region',
 294              'aria-label' => $section->heading));
 295  
 296          $output .= html_writer::start_div('content');
 297  
 298          $output .= html_writer::start_div('section-heading');
 299  
 300          $headingtext = $this->heading(html_writer::span(
 301                  html_writer::span($section->heading, 'instancesection'), 'sectioninstance'), 3);
 302  
 303          if (!$structure->can_be_edited()) {
 304              $editsectionheadingicon = '';
 305          } else {
 306              $editsectionheadingicon = html_writer::link(new \moodle_url('#'),
 307                  $this->pix_icon('t/editstring', get_string('sectionheadingedit', 'quiz', $section->heading),
 308                          'moodle', array('class' => 'editicon visibleifjs')),
 309                          array('class' => 'editing_section', 'data-action' => 'edit_section_title'));
 310          }
 311          $output .= html_writer::div($headingtext . $editsectionheadingicon, 'instancesectioncontainer');
 312  
 313          if (!$structure->is_first_section($section) && $structure->can_be_edited()) {
 314              $output .= $this->section_remove_icon($section);
 315          }
 316          $output .= $this->section_shuffle_questions($structure, $section);
 317  
 318          $output .= html_writer::end_div($output, 'section-heading');
 319  
 320          return $output;
 321      }
 322  
 323      /**
 324       * Display a checkbox for shuffling question within a section.
 325       *
 326       * @param structure $structure object containing the structure of the quiz.
 327       * @param \stdClass $section data from the quiz_section table.
 328       * @return string HTML to output.
 329       */
 330      public function section_shuffle_questions(structure $structure, $section) {
 331          $checkboxattributes = array(
 332              'type' => 'checkbox',
 333              'id' => 'shuffle-' . $section->id,
 334              'value' => 1,
 335              'data-action' => 'shuffle_questions',
 336              'class' => 'cm-edit-action',
 337          );
 338  
 339          if (!$structure->can_be_edited()) {
 340              $checkboxattributes['disabled'] = 'disabled';
 341          }
 342          if ($section->shufflequestions) {
 343              $checkboxattributes['checked'] = 'checked';
 344          }
 345  
 346          if ($structure->is_first_section($section)) {
 347              $help = $this->help_icon('shufflequestions', 'quiz');
 348          } else {
 349              $help = '';
 350          }
 351  
 352          $progressspan = html_writer::span('', 'shuffle-progress');
 353          $checkbox = html_writer::empty_tag('input', $checkboxattributes);
 354          $label = html_writer::label(get_string('shufflequestions', 'quiz') . ' ' . $help,
 355                  $checkboxattributes['id'], false);
 356          return html_writer::span($progressspan . $checkbox . $label,
 357                  'instanceshufflequestions', array('data-action' => 'shuffle_questions'));
 358      }
 359  
 360      /**
 361       * Display the end of a section, after the questions.
 362       *
 363       * @return string HTML to output.
 364       */
 365      protected function end_section() {
 366          $output = html_writer::end_tag('div');
 367          $output .= html_writer::end_tag('li');
 368  
 369          return $output;
 370      }
 371  
 372      /**
 373       * Render an icon to remove a section from the quiz.
 374       *
 375       * @param object $section the section to be removed.
 376       * @return string HTML to output.
 377       */
 378      public function section_remove_icon($section) {
 379          $title = get_string('sectionheadingremove', 'quiz', $section->heading);
 380          $url = new \moodle_url('/mod/quiz/edit.php',
 381                  array('sesskey' => sesskey(), 'removesection' => '1', 'sectionid' => $section->id));
 382          $image = $this->pix_icon('t/delete', $title);
 383          return $this->action_link($url, $image, null, array(
 384                  'class' => 'cm-edit-action editing_delete', 'data-action' => 'deletesection'));
 385      }
 386  
 387      /**
 388       * Renders HTML to display the questions in a section of the quiz.
 389       *
 390       * This function calls {@link core_course_renderer::quiz_section_question()}
 391       *
 392       * @param structure $structure object containing the structure of the quiz.
 393       * @param \stdClass $section information about the section.
 394       * @param \question_edit_contexts $contexts the relevant question bank contexts.
 395       * @param array $pagevars the variables from {@link \question_edit_setup()}.
 396       * @param \moodle_url $pageurl the canonical URL of this page.
 397       * @return string HTML to output.
 398       */
 399      public function questions_in_section(structure $structure, $section,
 400              $contexts, $pagevars, $pageurl) {
 401  
 402          $output = '';
 403          foreach ($structure->get_slots_in_section($section->id) as $slot) {
 404              $output .= $this->question_row($structure, $slot, $contexts, $pagevars, $pageurl);
 405          }
 406          return html_writer::tag('ul', $output, array('class' => 'section img-text'));
 407      }
 408  
 409      /**
 410       * Displays one question with the surrounding controls.
 411       *
 412       * @param structure $structure object containing the structure of the quiz.
 413       * @param int $slot which slot we are outputting.
 414       * @param \question_edit_contexts $contexts the relevant question bank contexts.
 415       * @param array $pagevars the variables from {@link \question_edit_setup()}.
 416       * @param \moodle_url $pageurl the canonical URL of this page.
 417       * @return string HTML to output.
 418       */
 419      public function question_row(structure $structure, $slot, $contexts, $pagevars, $pageurl) {
 420          $output = '';
 421  
 422          $output .= $this->page_row($structure, $slot, $contexts, $pagevars, $pageurl);
 423  
 424          // Page split/join icon.
 425          $joinhtml = '';
 426          if ($structure->can_be_edited() && !$structure->is_last_slot_in_quiz($slot) &&
 427                                              !$structure->is_last_slot_in_section($slot)) {
 428              $joinhtml = $this->page_split_join_button($structure, $slot);
 429          }
 430          // Question HTML.
 431          $questionhtml = $this->question($structure, $slot, $pageurl);
 432          $qtype = $structure->get_question_type_for_slot($slot);
 433          $questionclasses = 'activity ' . $qtype . ' qtype_' . $qtype . ' slot';
 434  
 435          $output .= html_writer::tag('li', $questionhtml . $joinhtml,
 436                  array('class' => $questionclasses, 'id' => 'slot-' . $structure->get_slot_id_for_slot($slot),
 437                          'data-canfinish' => $structure->can_finish_during_the_attempt($slot)));
 438  
 439          return $output;
 440      }
 441  
 442      /**
 443       * Displays one question with the surrounding controls.
 444       *
 445       * @param structure $structure object containing the structure of the quiz.
 446       * @param int $slot the first slot on the page we are outputting.
 447       * @param \question_edit_contexts $contexts the relevant question bank contexts.
 448       * @param array $pagevars the variables from {@link \question_edit_setup()}.
 449       * @param \moodle_url $pageurl the canonical URL of this page.
 450       * @return string HTML to output.
 451       */
 452      public function page_row(structure $structure, $slot, $contexts, $pagevars, $pageurl) {
 453          $output = '';
 454  
 455          $pagenumber = $structure->get_page_number_for_slot($slot);
 456  
 457          // Put page in a heading for accessibility and styling.
 458          $page = $this->heading(get_string('page') . ' ' . $pagenumber, 4);
 459  
 460          if ($structure->is_first_slot_on_page($slot)) {
 461              // Add the add-menu at the page level.
 462              $addmenu = html_writer::tag('span', $this->add_menu_actions($structure,
 463                      $pagenumber, $pageurl, $contexts, $pagevars),
 464                      array('class' => 'add-menu-outer'));
 465  
 466              $addquestionform = $this->add_question_form($structure,
 467                      $pagenumber, $pageurl, $pagevars);
 468  
 469              $output .= html_writer::tag('li', $page . $addmenu . $addquestionform,
 470                      array('class' => 'pagenumber activity yui3-dd-drop page', 'id' => 'page-' . $pagenumber));
 471          }
 472  
 473          return $output;
 474      }
 475  
 476      /**
 477       * Returns the add menu that is output once per page.
 478       * @param structure $structure object containing the structure of the quiz.
 479       * @param int $page the page number that this menu will add to.
 480       * @param \moodle_url $pageurl the canonical URL of this page.
 481       * @param \question_edit_contexts $contexts the relevant question bank contexts.
 482       * @param array $pagevars the variables from {@link \question_edit_setup()}.
 483       * @return string HTML to output.
 484       */
 485      public function add_menu_actions(structure $structure, $page, \moodle_url $pageurl,
 486              \question_edit_contexts $contexts, array $pagevars) {
 487  
 488          $actions = $this->edit_menu_actions($structure, $page, $pageurl, $pagevars);
 489          if (empty($actions)) {
 490              return '';
 491          }
 492          $menu = new \action_menu();
 493          $menu->set_alignment(\action_menu::TR, \action_menu::TR);
 494          $menu->set_constraint('.mod-quiz-edit-content');
 495          $trigger = html_writer::tag('span', get_string('add', 'quiz'), array('class' => 'add-menu'));
 496          $menu->set_menu_trigger($trigger);
 497          // The menu appears within an absolutely positioned element causing width problems.
 498          // Make sure no-wrap is set so that we don't get a squashed menu.
 499          $menu->set_nowrap_on_items(true);
 500  
 501          // Disable the link if quiz has attempts.
 502          if (!$structure->can_be_edited()) {
 503              return $this->render($menu);
 504          }
 505  
 506          foreach ($actions as $action) {
 507              if ($action instanceof \action_menu_link) {
 508                  $action->add_class('add-menu');
 509              }
 510              $menu->add($action);
 511          }
 512          $menu->attributes['class'] .= ' page-add-actions commands';
 513  
 514          // Prioritise the menu ahead of all other actions.
 515          $menu->prioritise = true;
 516  
 517          return $this->render($menu);
 518      }
 519  
 520      /**
 521       * Returns the list of actions to go in the add menu.
 522       * @param structure $structure object containing the structure of the quiz.
 523       * @param int $page the page number that this menu will add to.
 524       * @param \moodle_url $pageurl the canonical URL of this page.
 525       * @param array $pagevars the variables from {@link \question_edit_setup()}.
 526       * @return array the actions.
 527       */
 528      public function edit_menu_actions(structure $structure, $page,
 529              \moodle_url $pageurl, array $pagevars) {
 530          $questioncategoryid = question_get_category_id_from_pagevars($pagevars);
 531          static $str;
 532          if (!isset($str)) {
 533              $str = get_strings(array('addasection', 'addaquestion', 'addarandomquestion',
 534                      'addarandomselectedquestion', 'questionbank'), 'quiz');
 535          }
 536  
 537          // Get section, page, slotnumber and maxmark.
 538          $actions = array();
 539  
 540          // Add a new section to the add_menu if possible. This is always added to the HTML
 541          // then hidden with CSS when no needed, so that as things are re-ordered, etc. with
 542          // Ajax it can be relevaled again when necessary.
 543          $params = array('cmid' => $structure->get_cmid(), 'addsectionatpage' => $page);
 544  
 545          $actions['addasection'] = new \action_menu_link_secondary(
 546                  new \moodle_url($pageurl, $params),
 547                  new \pix_icon('t/add', $str->addasection, 'moodle', array('class' => 'iconsmall', 'title' => '')),
 548                  $str->addasection, array('class' => 'cm-edit-action addasection', 'data-action' => 'addasection')
 549          );
 550  
 551          // Add a new question to the quiz.
 552          $returnurl = new \moodle_url($pageurl, array('addonpage' => $page));
 553          $params = array('returnurl' => $returnurl->out_as_local_url(false),
 554                  'cmid' => $structure->get_cmid(), 'category' => $questioncategoryid,
 555                  'addonpage' => $page, 'appendqnumstring' => 'addquestion');
 556  
 557          $actions['addaquestion'] = new \action_menu_link_secondary(
 558              new \moodle_url('/question/addquestion.php', $params),
 559              new \pix_icon('t/add', $str->addaquestion, 'moodle', array('class' => 'iconsmall', 'title' => '')),
 560              $str->addaquestion, array('class' => 'cm-edit-action addquestion', 'data-action' => 'addquestion')
 561          );
 562  
 563          // Call question bank.
 564          $icon = new \pix_icon('t/add', $str->questionbank, 'moodle', array('class' => 'iconsmall', 'title' => ''));
 565          if ($page) {
 566              $title = get_string('addquestionfrombanktopage', 'quiz', $page);
 567          } else {
 568              $title = get_string('addquestionfrombankatend', 'quiz');
 569          }
 570          $attributes = array('class' => 'cm-edit-action questionbank',
 571                  'data-header' => $title, 'data-action' => 'questionbank', 'data-addonpage' => $page);
 572          $actions['questionbank'] = new \action_menu_link_secondary($pageurl, $icon, $str->questionbank, $attributes);
 573  
 574          // Add a random question.
 575          $returnurl = new \moodle_url('/mod/quiz/edit.php', array('cmid' => $structure->get_cmid(), 'data-addonpage' => $page));
 576          $params = array('returnurl' => $returnurl, 'cmid' => $structure->get_cmid(), 'appendqnumstring' => 'addarandomquestion');
 577          $url = new \moodle_url('/mod/quiz/addrandom.php', $params);
 578          $icon = new \pix_icon('t/add', $str->addarandomquestion, 'moodle', array('class' => 'iconsmall', 'title' => ''));
 579          $attributes = array('class' => 'cm-edit-action addarandomquestion', 'data-action' => 'addarandomquestion');
 580          if ($page) {
 581              $title = get_string('addrandomquestiontopage', 'quiz', $page);
 582          } else {
 583              $title = get_string('addrandomquestionatend', 'quiz');
 584          }
 585          $attributes = array_merge(array('data-header' => $title, 'data-addonpage' => $page), $attributes);
 586          $actions['addarandomquestion'] = new \action_menu_link_secondary($url, $icon, $str->addarandomquestion, $attributes);
 587  
 588          return $actions;
 589      }
 590  
 591      /**
 592       * Render the form that contains the data for adding a new question to the quiz.
 593       *
 594       * @param structure $structure object containing the structure of the quiz.
 595       * @param int $page the page number that this menu will add to.
 596       * @param \moodle_url $pageurl the canonical URL of this page.
 597       * @param array $pagevars the variables from {@link \question_edit_setup()}.
 598       * @return string HTML to output.
 599       */
 600      protected function add_question_form(structure $structure, $page, \moodle_url $pageurl, array $pagevars) {
 601  
 602          $questioncategoryid = question_get_category_id_from_pagevars($pagevars);
 603  
 604          $output = html_writer::tag('input', null,
 605                  array('type' => 'hidden', 'name' => 'returnurl',
 606                          'value' => $pageurl->out_as_local_url(false, array('addonpage' => $page))));
 607          $output .= html_writer::tag('input', null,
 608                  array('type' => 'hidden', 'name' => 'cmid', 'value' => $structure->get_cmid()));
 609          $output .= html_writer::tag('input', null,
 610                  array('type' => 'hidden', 'name' => 'appendqnumstring', 'value' => 'addquestion'));
 611          $output .= html_writer::tag('input', null,
 612                  array('type' => 'hidden', 'name' => 'category', 'value' => $questioncategoryid));
 613  
 614          return html_writer::tag('form', html_writer::div($output),
 615                  array('class' => 'addnewquestion', 'method' => 'post',
 616                          'action' => new \moodle_url('/question/addquestion.php')));
 617      }
 618  
 619      /**
 620       * Display a question.
 621       *
 622       * @param structure $structure object containing the structure of the quiz.
 623       * @param int $slot the first slot on the page we are outputting.
 624       * @param \moodle_url $pageurl the canonical URL of this page.
 625       * @return string HTML to output.
 626       */
 627      public function question(structure $structure, $slot, \moodle_url $pageurl) {
 628          $output = '';
 629          $output .= html_writer::start_tag('div');
 630  
 631          if ($structure->can_be_edited()) {
 632              $output .= $this->question_move_icon($structure, $slot);
 633          }
 634  
 635          $output .= html_writer::start_div('mod-indent-outer');
 636          $output .= $this->question_number($structure->get_displayed_number_for_slot($slot));
 637  
 638          // This div is used to indent the content.
 639          $output .= html_writer::div('', 'mod-indent');
 640  
 641          // Display the link to the question (or do nothing if question has no url).
 642          if ($structure->get_question_type_for_slot($slot) == 'random') {
 643              $questionname = $this->random_question($structure, $slot, $pageurl);
 644          } else {
 645              $questionname = $this->question_name($structure, $slot, $pageurl);
 646          }
 647  
 648          // Start the div for the activity title, excluding the edit icons.
 649          $output .= html_writer::start_div('activityinstance');
 650          $output .= $questionname;
 651  
 652          // Closing the tag which contains everything but edit icons. Content part of the module should not be part of this.
 653          $output .= html_writer::end_tag('div'); // .activityinstance.
 654  
 655          // Action icons.
 656          $questionicons = '';
 657          $questionicons .= $this->question_preview_icon($structure->get_quiz(), $structure->get_question_in_slot($slot));
 658          if ($structure->can_be_edited()) {
 659              $questionicons .= $this->question_remove_icon($structure, $slot, $pageurl);
 660          }
 661          $questionicons .= $this->marked_out_of_field($structure, $slot);
 662          $output .= html_writer::span($questionicons, 'actions'); // Required to add js spinner icon.
 663          if ($structure->can_be_edited()) {
 664              $output .= $this->question_dependency_icon($structure, $slot);
 665          }
 666  
 667          // End of indentation div.
 668          $output .= html_writer::end_tag('div');
 669          $output .= html_writer::end_tag('div');
 670  
 671          return $output;
 672      }
 673  
 674      /**
 675       * Render the move icon.
 676       *
 677       * @param structure $structure object containing the structure of the quiz.
 678       * @param int $slot the first slot on the page we are outputting.
 679       * @return string The markup for the move action.
 680       */
 681      public function question_move_icon(structure $structure, $slot) {
 682          return html_writer::link(new \moodle_url('#'),
 683              $this->pix_icon('i/dragdrop', get_string('move'), 'moodle', array('class' => 'iconsmall', 'title' => '')),
 684              array('class' => 'editing_move', 'data-action' => 'move')
 685          );
 686      }
 687  
 688      /**
 689       * Output the question number.
 690       * @param string $number The number, or 'i'.
 691       * @return string HTML to output.
 692       */
 693      public function question_number($number) {
 694          if (is_numeric($number)) {
 695              $number = html_writer::span(get_string('question'), 'accesshide') . ' ' . $number;
 696          }
 697          return html_writer::tag('span', $number, array('class' => 'slotnumber'));
 698      }
 699  
 700      /**
 701       * Render the preview icon.
 702       *
 703       * @param \stdClass $quiz the quiz settings from the database.
 704       * @param \stdClass $question data from the question and quiz_slots tables.
 705       * @param bool $label if true, show the preview question label after the icon
 706       * @param int $variant which question variant to preview (optional).
 707       * @return string HTML to output.
 708       */
 709      public function question_preview_icon($quiz, $question, $label = null, $variant = null) {
 710          $url = quiz_question_preview_url($quiz, $question, $variant);
 711  
 712          // Do we want a label?
 713          $strpreviewlabel = '';
 714          if ($label) {
 715              $strpreviewlabel = ' ' . get_string('preview', 'quiz');
 716          }
 717  
 718          // Build the icon.
 719          $strpreviewquestion = get_string('previewquestion', 'quiz');
 720          $image = $this->pix_icon('t/preview', $strpreviewquestion);
 721  
 722          $action = new \popup_action('click', $url, 'questionpreview',
 723                                          question_preview_popup_params());
 724  
 725          return $this->action_link($url, $image . $strpreviewlabel, $action,
 726                  array('title' => $strpreviewquestion, 'class' => 'preview'));
 727      }
 728  
 729      /**
 730       * Render an icon to remove a question from the quiz.
 731       *
 732       * @param structure $structure object containing the structure of the quiz.
 733       * @param int $slot the first slot on the page we are outputting.
 734       * @param \moodle_url $pageurl the canonical URL of the edit page.
 735       * @return string HTML to output.
 736       */
 737      public function question_remove_icon(structure $structure, $slot, $pageurl) {
 738          $url = new \moodle_url($pageurl, array('sesskey' => sesskey(), 'remove' => $slot));
 739          $strdelete = get_string('delete');
 740  
 741          $image = $this->pix_icon('t/delete', $strdelete);
 742  
 743          return $this->action_link($url, $image, null, array('title' => $strdelete,
 744                      'class' => 'cm-edit-action editing_delete', 'data-action' => 'delete'));
 745      }
 746  
 747      /**
 748       * Display an icon to split or join two pages of the quiz.
 749       *
 750       * @param structure $structure object containing the structure of the quiz.
 751       * @param int $slot the first slot on the page we are outputting.
 752       * @return string HTML to output.
 753       */
 754      public function page_split_join_button($structure, $slot) {
 755          $insertpagebreak = !$structure->is_last_slot_on_page($slot);
 756          $url = new \moodle_url('repaginate.php', array('quizid' => $structure->get_quizid(),
 757                  'slot' => $slot, 'repag' => $insertpagebreak ? 2 : 1, 'sesskey' => sesskey()));
 758  
 759          if ($insertpagebreak) {
 760              $title = get_string('addpagebreak', 'quiz');
 761              $image = $this->pix_icon('e/insert_page_break', $title);
 762              $action = 'addpagebreak';
 763          } else {
 764              $title = get_string('removepagebreak', 'quiz');
 765              $image = $this->pix_icon('e/remove_page_break', $title);
 766              $action = 'removepagebreak';
 767          }
 768  
 769          // Disable the link if quiz has attempts.
 770          $disabled = null;
 771          if (!$structure->can_be_edited()) {
 772              $disabled = 'disabled';
 773          }
 774          return html_writer::span($this->action_link($url, $image, null, array('title' => $title,
 775                      'class' => 'page_split_join cm-edit-action', 'disabled' => $disabled, 'data-action' => $action)),
 776                  'page_split_join_wrapper');
 777      }
 778  
 779      /**
 780       * Display the icon for whether this question can only be seen if the previous
 781       * one has been answered.
 782       *
 783       * @param structure $structure object containing the structure of the quiz.
 784       * @param int $slot the first slot on the page we are outputting.
 785       * @return string HTML to output.
 786       */
 787      public function question_dependency_icon($structure, $slot) {
 788          $a = array(
 789              'thisq' => $structure->get_displayed_number_for_slot($slot),
 790              'previousq' => $structure->get_displayed_number_for_slot(max($slot - 1, 1)),
 791          );
 792          if ($structure->is_question_dependent_on_previous_slot($slot)) {
 793              $title = get_string('questiondependencyremove', 'quiz', $a);
 794              $image = $this->pix_icon('t/locked', get_string('questiondependsonprevious', 'quiz'),
 795                      'moodle', array('title' => ''));
 796              $action = 'removedependency';
 797          } else {
 798              $title = get_string('questiondependencyadd', 'quiz', $a);
 799              $image = $this->pix_icon('t/unlocked', get_string('questiondependencyfree', 'quiz'),
 800                      'moodle', array('title' => ''));
 801              $action = 'adddependency';
 802          }
 803  
 804          // Disable the link if quiz has attempts.
 805          $disabled = null;
 806          if (!$structure->can_be_edited()) {
 807              $disabled = 'disabled';
 808          }
 809          $extraclass = '';
 810          if (!$structure->can_question_depend_on_previous_slot($slot)) {
 811              $extraclass = ' question_dependency_cannot_depend';
 812          }
 813          return html_writer::span($this->action_link('#', $image, null, array('title' => $title,
 814                  'class' => 'cm-edit-action', 'disabled' => $disabled, 'data-action' => $action)),
 815                  'question_dependency_wrapper' . $extraclass);
 816      }
 817  
 818      /**
 819       * Renders html to display a name with the link to the question on a quiz edit page
 820       *
 821       * If the user does not have permission to edi the question, it is rendered
 822       * without a link
 823       *
 824       * @param structure $structure object containing the structure of the quiz.
 825       * @param int $slot which slot we are outputting.
 826       * @param \moodle_url $pageurl the canonical URL of this page.
 827       * @return string HTML to output.
 828       */
 829      public function question_name(structure $structure, $slot, $pageurl) {
 830          $output = '';
 831  
 832          $question = $structure->get_question_in_slot($slot);
 833          $editurl = new \moodle_url('/question/question.php', array(
 834                  'returnurl' => $pageurl->out_as_local_url(),
 835                  'cmid' => $structure->get_cmid(), 'id' => $question->id));
 836  
 837          $instancename = quiz_question_tostring($question);
 838  
 839          $qtype = \question_bank::get_qtype($question->qtype, false);
 840          $namestr = $qtype->local_name();
 841  
 842          $icon = $this->pix_icon('icon', $namestr, $qtype->plugin_name(), array('title' => $namestr,
 843                  'class' => 'icon activityicon', 'alt' => ' ', 'role' => 'presentation'));
 844  
 845          $editicon = $this->pix_icon('t/edit', '', 'moodle', array('title' => ''));
 846  
 847          // Need plain question name without html tags for link title.
 848          $title = shorten_text(format_string($question->name), 100);
 849  
 850          // Display the link itself.
 851          $activitylink = $icon . html_writer::tag('span', $editicon . $instancename, array('class' => 'instancename'));
 852          $output .= html_writer::link($editurl, $activitylink,
 853                  array('title' => get_string('editquestion', 'quiz').' '.$title));
 854  
 855          return $output;
 856      }
 857  
 858      /**
 859       * Renders html to display a random question the link to edit the configuration
 860       * and also to see that category in the question bank.
 861       *
 862       * @param structure $structure object containing the structure of the quiz.
 863       * @param int $slot which slot we are outputting.
 864       * @param \moodle_url $pageurl the canonical URL of this page.
 865       * @return string HTML to output.
 866       */
 867      public function random_question(structure $structure, $slot, $pageurl) {
 868  
 869          $question = $structure->get_question_in_slot($slot);
 870          $editurl = new \moodle_url('/question/question.php', array(
 871                  'returnurl' => $pageurl->out_as_local_url(),
 872                  'cmid' => $structure->get_cmid(), 'id' => $question->id));
 873  
 874          $temp = clone($question);
 875          $temp->questiontext = '';
 876          $instancename = quiz_question_tostring($temp);
 877  
 878          $configuretitle = get_string('configurerandomquestion', 'quiz');
 879          $qtype = \question_bank::get_qtype($question->qtype, false);
 880          $namestr = $qtype->local_name();
 881          $icon = $this->pix_icon('icon', $namestr, $qtype->plugin_name(), array('title' => $namestr,
 882                  'class' => 'icon activityicon', 'alt' => ' ', 'role' => 'presentation'));
 883  
 884          $editicon = $this->pix_icon('t/edit', $configuretitle, 'moodle', array('title' => ''));
 885  
 886          // If this is a random question, display a link to show the questions
 887          // selected from in the question bank.
 888          $qbankurl = new \moodle_url('/question/edit.php', array(
 889                  'cmid' => $structure->get_cmid(),
 890                  'cat' => $question->category . ',' . $question->contextid,
 891                  'recurse' => !empty($question->questiontext)));
 892          $qbanklink = ' ' . \html_writer::link($qbankurl,
 893                  get_string('seequestions', 'quiz'), array('class' => 'mod_quiz_random_qbank_link'));
 894  
 895          return html_writer::link($editurl, $icon . $editicon, array('title' => $configuretitle)) .
 896                  ' ' . $instancename . ' ' . $qbanklink;
 897      }
 898  
 899      /**
 900       * Display the 'marked out of' information for a question.
 901       * Along with the regrade action.
 902       * @param structure $structure object containing the structure of the quiz.
 903       * @param int $slot which slot we are outputting.
 904       * @return string HTML to output.
 905       */
 906      public function marked_out_of_field(structure $structure, $slot) {
 907          if (!$structure->is_real_question($slot)) {
 908              $output = html_writer::span('',
 909                      'instancemaxmark decimalplaces_' . $structure->get_decimal_places_for_question_marks());
 910  
 911              $output .= html_writer::span(
 912                      $this->pix_icon('spacer', '', 'moodle', array('class' => 'editicon visibleifjs', 'title' => '')),
 913                      'editing_maxmark');
 914              return html_writer::span($output, 'instancemaxmarkcontainer infoitem');
 915          }
 916  
 917          $output = html_writer::span($structure->formatted_question_grade($slot),
 918                  'instancemaxmark decimalplaces_' . $structure->get_decimal_places_for_question_marks(),
 919                  array('title' => get_string('maxmark', 'quiz')));
 920  
 921          $output .= html_writer::span(
 922              html_writer::link(
 923                  new \moodle_url('#'),
 924                  $this->pix_icon('t/editstring', '', 'moodle', array('class' => 'editicon visibleifjs', 'title' => '')),
 925                  array(
 926                      'class' => 'editing_maxmark',
 927                      'data-action' => 'editmaxmark',
 928                      'title' => get_string('editmaxmark', 'quiz'),
 929                  )
 930              )
 931          );
 932          return html_writer::span($output, 'instancemaxmarkcontainer');
 933      }
 934  
 935      /**
 936       * Render the question type chooser dialogue.
 937       * @return string HTML to output.
 938       */
 939      public function question_chooser() {
 940          $container = html_writer::div(print_choose_qtype_to_add_form(array(), null, false), '',
 941                  array('id' => 'qtypechoicecontainer'));
 942          return html_writer::div($container, 'createnewquestion');
 943      }
 944  
 945      /**
 946       * Render the contents of the question bank pop-up in its initial state,
 947       * when it just contains a loading progress indicator.
 948       * @return string HTML to output.
 949       */
 950      public function question_bank_loading() {
 951          return html_writer::div(html_writer::empty_tag('img',
 952                  array('alt' => 'loading', 'class' => 'loading-icon', 'src' => $this->pix_url('i/loading'))),
 953                  'questionbankloading');
 954      }
 955  
 956      /**
 957       * Return random question form.
 958       * @param \moodle_url $thispageurl the canonical URL of this page.
 959       * @param \question_edit_contexts $contexts the relevant question bank contexts.
 960       * @param array $pagevars the variables from {@link \question_edit_setup()}.
 961       * @return string HTML to output.
 962       */
 963      protected function random_question_form(\moodle_url $thispageurl, \question_edit_contexts $contexts, array $pagevars) {
 964  
 965          if (!$contexts->have_cap('moodle/question:useall')) {
 966              return '';
 967          }
 968          $randomform = new \quiz_add_random_form(new \moodle_url('/mod/quiz/addrandom.php'),
 969                                   array('contexts' => $contexts, 'cat' => $pagevars['cat']));
 970          $randomform->set_data(array(
 971                  'category' => $pagevars['cat'],
 972                  'returnurl' => $thispageurl->out_as_local_url(true),
 973                  'randomnumber' => 1,
 974                  'cmid' => $thispageurl->param('cmid'),
 975          ));
 976          return html_writer::div($randomform->render(), 'randomquestionformforpopup');
 977      }
 978  
 979      /**
 980       * Initialise the JavaScript for the general editing. (JavaScript for popups
 981       * is handled with the specific code for those.)
 982       *
 983       * @param structure $structure object containing the structure of the quiz.
 984       * @param \question_edit_contexts $contexts the relevant question bank contexts.
 985       * @param array $pagevars the variables from {@link \question_edit_setup()}.
 986       * @param \moodle_url $pageurl the canonical URL of this page.
 987       * @return bool Always returns true
 988       */
 989      protected function initialise_editing_javascript(structure $structure,
 990              \question_edit_contexts $contexts, array $pagevars, \moodle_url $pageurl) {
 991  
 992          $config = new \stdClass();
 993          $config->resourceurl = '/mod/quiz/edit_rest.php';
 994          $config->sectionurl = '/mod/quiz/edit_rest.php';
 995          $config->pageparams = array();
 996          $config->questiondecimalpoints = $structure->get_decimal_places_for_question_marks();
 997          $config->pagehtml = $this->new_page_template($structure, $contexts, $pagevars, $pageurl);
 998          $config->addpageiconhtml = $this->add_page_icon_template($structure);
 999  
1000          $this->page->requires->yui_module('moodle-mod_quiz-toolboxes',
1001                  'M.mod_quiz.init_resource_toolbox',
1002                  array(array(
1003                          'courseid' => $structure->get_courseid(),
1004                          'quizid' => $structure->get_quizid(),
1005                          'ajaxurl' => $config->resourceurl,
1006                          'config' => $config,
1007                  ))
1008          );
1009          unset($config->pagehtml);
1010          unset($config->addpageiconhtml);
1011  
1012          $this->page->requires->yui_module('moodle-mod_quiz-toolboxes',
1013                  'M.mod_quiz.init_section_toolbox',
1014                  array(array(
1015                          'courseid' => $structure,
1016                          'quizid' => $structure->get_quizid(),
1017                          'ajaxurl' => $config->sectionurl,
1018                          'config' => $config,
1019                  ))
1020          );
1021  
1022          $this->page->requires->yui_module('moodle-mod_quiz-dragdrop', 'M.mod_quiz.init_section_dragdrop',
1023                  array(array(
1024                          'courseid' => $structure,
1025                          'quizid' => $structure->get_quizid(),
1026                          'ajaxurl' => $config->sectionurl,
1027                          'config' => $config,
1028                  )), null, true);
1029  
1030          $this->page->requires->yui_module('moodle-mod_quiz-dragdrop', 'M.mod_quiz.init_resource_dragdrop',
1031                  array(array(
1032                          'courseid' => $structure,
1033                          'quizid' => $structure->get_quizid(),
1034                          'ajaxurl' => $config->resourceurl,
1035                          'config' => $config,
1036                  )), null, true);
1037  
1038          // Require various strings for the command toolbox.
1039          $this->page->requires->strings_for_js(array(
1040                  'clicktohideshow',
1041                  'deletechecktype',
1042                  'deletechecktypename',
1043                  'edittitle',
1044                  'edittitleinstructions',
1045                  'emptydragdropregion',
1046                  'hide',
1047                  'markedthistopic',
1048                  'markthistopic',
1049                  'move',
1050                  'movecontent',
1051                  'moveleft',
1052                  'movesection',
1053                  'page',
1054                  'question',
1055                  'selectall',
1056                  'show',
1057                  'tocontent',
1058          ), 'moodle');
1059  
1060          $this->page->requires->strings_for_js(array(
1061                  'addpagebreak',
1062                  'confirmremovesectionheading',
1063                  'confirmremovequestion',
1064                  'dragtoafter',
1065                  'dragtostart',
1066                  'numquestionsx',
1067                  'sectionheadingedit',
1068                  'sectionheadingremove',
1069                  'removepagebreak',
1070                  'questiondependencyadd',
1071                  'questiondependencyfree',
1072                  'questiondependencyremove',
1073                  'questiondependsonprevious',
1074          ), 'quiz');
1075  
1076          foreach (\question_bank::get_all_qtypes() as $qtype => $notused) {
1077              $this->page->requires->string_for_js('pluginname', 'qtype_' . $qtype);
1078          }
1079  
1080          return true;
1081      }
1082  
1083      /**
1084       * HTML for a page, with ids stripped, so it can be used as a javascript template.
1085       *
1086       * @param structure $structure object containing the structure of the quiz.
1087       * @param \question_edit_contexts $contexts the relevant question bank contexts.
1088       * @param array $pagevars the variables from {@link \question_edit_setup()}.
1089       * @param \moodle_url $pageurl the canonical URL of this page.
1090       * @return string HTML for a new page.
1091       */
1092      protected function new_page_template(structure $structure,
1093              \question_edit_contexts $contexts, array $pagevars, \moodle_url $pageurl) {
1094          if (!$structure->has_questions()) {
1095              return '';
1096          }
1097  
1098          $pagehtml = $this->page_row($structure, 1, $contexts, $pagevars, $pageurl);
1099  
1100          // Normalise the page number.
1101          $pagenumber = $structure->get_page_number_for_slot(1);
1102          $strcontexts = array();
1103          $strcontexts[] = 'page-';
1104          $strcontexts[] = get_string('page') . ' ';
1105          $strcontexts[] = 'addonpage%3D';
1106          $strcontexts[] = 'addonpage=';
1107          $strcontexts[] = 'addonpage="';
1108          $strcontexts[] = get_string('addquestionfrombanktopage', 'quiz', '');
1109          $strcontexts[] = 'data-addonpage%3D';
1110          $strcontexts[] = 'action-menu-';
1111  
1112          foreach ($strcontexts as $strcontext) {
1113              $pagehtml = str_replace($strcontext . $pagenumber, $strcontext . '%%PAGENUMBER%%', $pagehtml);
1114          }
1115  
1116          return $pagehtml;
1117      }
1118  
1119      /**
1120       * HTML for a page, with ids stripped, so it can be used as a javascript template.
1121       *
1122       * @param structure $structure object containing the structure of the quiz.
1123       * @return string HTML for a new icon
1124       */
1125      protected function add_page_icon_template(structure $structure) {
1126  
1127          if (!$structure->has_questions()) {
1128              return '';
1129          }
1130  
1131          $html = $this->page_split_join_button($structure, 1);
1132          return str_replace('&amp;slot=1&amp;', '&amp;slot=%%SLOT%%&amp;', $html);
1133      }
1134  
1135      /**
1136       * Return the contents of the question bank, to be displayed in the question-bank pop-up.
1137       *
1138       * @param \mod_quiz\question\bank\custom_view $questionbank the question bank view object.
1139       * @param array $pagevars the variables from {@link \question_edit_setup()}.
1140       * @return string HTML to output / send back in response to an AJAX request.
1141       */
1142      public function question_bank_contents(\mod_quiz\question\bank\custom_view $questionbank, array $pagevars) {
1143  
1144          $qbank = $questionbank->render('editq', $pagevars['qpage'], $pagevars['qperpage'],
1145                  $pagevars['cat'], $pagevars['recurse'], $pagevars['showhidden'], $pagevars['qbshowtext']);
1146          return html_writer::div(html_writer::div($qbank, 'bd'), 'questionbankformforpopup');
1147      }
1148  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1