[ Index ]

PHP Cross Reference of moodle-2.8

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


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1