Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 400 and 403] [Versions 401 and 403] [Versions 402 and 403]

   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  namespace qbank_history;
  18  
  19  use core_question\local\bank\question_edit_contexts;
  20  use core_question\local\bank\view;
  21  use moodle_url;
  22  use stdClass;
  23  
  24  /**
  25   * Custom view class for the history page.
  26   *
  27   * @package    qbank_history
  28   * @copyright  2022 Catalyst IT Australia Pty Ltd
  29   * @author     Safat Shahin <safatshahin@catalyst-au.net>
  30   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  31   */
  32  class question_history_view extends view {
  33  
  34      /**
  35       * Entry id to get the versions
  36       *
  37       * @var int $entryid
  38       */
  39      protected $entryid;
  40  
  41      /**
  42       * Base url for the return.
  43       *
  44       * @var \moodle_url $basereturnurl
  45       */
  46      protected $basereturnurl;
  47  
  48      /**
  49       * Constructor for the history.
  50       * @param question_edit_contexts $contexts the contexts of api call
  51       * @param moodle_url $pageurl url of the page
  52       * @param stdClass $course course settings
  53       * @param stdClass|null $cm (optional) activity settings.
  54       * @param array $params the parameters required to initialize the api.
  55       * @param array $extraparams any extra parameters need to initialized if the api is extended, it will be passed to js.
  56       * @throws \moodle_exception
  57       */
  58      public function __construct(
  59          question_edit_contexts $contexts,
  60          moodle_url $pageurl,
  61          stdClass $course,
  62          stdClass $cm = null,
  63          array $params = [],
  64          array $extraparams = [],
  65      ) {
  66          $this->entryid = $extraparams['entryid'];
  67          $this->basereturnurl = new \moodle_url($extraparams['returnurl']);
  68          parent::__construct($contexts, $pageurl, $course, $cm, $params, $extraparams);
  69      }
  70  
  71      protected function init_question_actions(): void {
  72          parent::init_question_actions();
  73          unset($this->questionactions['qbank_history\history_action']);
  74      }
  75  
  76      protected function wanted_columns(): array {
  77          $this->requiredcolumns = [];
  78          $questionbankcolumns = $this->get_question_bank_plugins();
  79          foreach ($questionbankcolumns as $classobject) {
  80              if (empty($classobject)) {
  81                  continue;
  82              }
  83              $this->requiredcolumns[$classobject->get_column_name()] = $classobject;
  84          }
  85  
  86          return $this->requiredcolumns;
  87      }
  88  
  89      protected function display_advanced_search_form($advancedsearch): void {
  90          foreach ($advancedsearch as $searchcondition) {
  91              echo $searchcondition->display_options_adv();
  92          }
  93      }
  94  
  95      public function allow_add_questions(): bool {
  96          // As we dont want to create questions in this page.
  97          return false;
  98      }
  99  
 100      /**
 101       * Default sort for question data.
 102       * @return array
 103       */
 104      protected function default_sort(): array {
 105          $defaultsort = [];
 106          if (class_exists('\\qbank_viewcreator\\creator_name_column')) {
 107              $sort = 'qbank_viewcreator\creator_name_column-timecreated';
 108          }
 109          $defaultsort[$sort] = 1;
 110  
 111          return $defaultsort;
 112      }
 113  
 114      protected function build_query(): void {
 115          // Get the required tables and fields.
 116          [$fields, $joins] = $this->get_component_requirements(array_merge($this->requiredcolumns, $this->questionactions));
 117  
 118          // Build the order by clause.
 119          $sorts = [];
 120          foreach ($this->sort as $sortname => $sortorder) {
 121              list($colname, $subsort) = $this->parse_subsort($sortname);
 122              $sorts[] = $this->requiredcolumns[$colname]->sort_expression($sortorder == SORT_DESC, $subsort);
 123          }
 124  
 125          // Build the where clause.
 126          $entryid = "qbe.id = $this->entryid";
 127          // Changes done here to get the questions only for the passed entryid.
 128          $tests = ['q.parent = 0', $entryid];
 129          $this->sqlparams = [];
 130          foreach ($this->searchconditions as $searchcondition) {
 131              if ($searchcondition->where()) {
 132                  $tests[] = '((' . $searchcondition->where() .'))';
 133              }
 134              if ($searchcondition->params()) {
 135                  $this->sqlparams = array_merge($this->sqlparams, $searchcondition->params());
 136              }
 137          }
 138          // Build the SQL.
 139          $sql = ' FROM {question} q ' . implode(' ', $joins);
 140          $sql .= ' WHERE ' . implode(' AND ', $tests);
 141          $this->countsql = 'SELECT count(1)' . $sql;
 142          $this->loadsql = 'SELECT ' . implode(', ', $fields) . $sql . ' ORDER BY ' . implode(', ', $sorts);
 143      }
 144  
 145      /**
 146       * Display the header for the question bank in the history page to include question name and type.
 147       */
 148      public function display_question_bank_header(): void {
 149          global $PAGE, $DB, $OUTPUT;
 150          $sql = 'SELECT q.*
 151                   FROM {question} q
 152                   JOIN {question_versions} qv ON qv.questionid = q.id
 153                   JOIN {question_bank_entries} qbe ON qbe.id = qv.questionbankentryid
 154                  WHERE qv.version  = (SELECT MAX(v.version)
 155                                         FROM {question_versions} v
 156                                         JOIN {question_bank_entries} be
 157                                           ON be.id = v.questionbankentryid
 158                                        WHERE be.id = qbe.id)
 159                    AND qbe.id = ?';
 160          $latestquestiondata = $DB->get_record_sql($sql, [$this->entryid]);
 161          if ($latestquestiondata) {
 162              $historydata = [
 163                  'questionname' => $latestquestiondata->name,
 164                  'returnurl' => $this->basereturnurl,
 165                  'questionicon' => print_question_icon($latestquestiondata)
 166              ];
 167              // Header for the page before the actual form from the api.
 168              echo $PAGE->get_renderer('qbank_history')->render_history_header($historydata);
 169          } else {
 170              // Continue when all the question versions are deleted.
 171              echo $OUTPUT->notification(get_string('allquestionversionsdeleted', 'qbank_history'), 'notifysuccess');
 172              echo $OUTPUT->continue_button($this->basereturnurl);
 173          }
 174      }
 175  
 176      public function is_listing_specific_versions(): bool {
 177          return true;
 178      }
 179  
 180      /**
 181       * Override wanted_filters so that we apply the filters provided by the URL, but don't display the filter UI.
 182       *
 183       * @return void
 184       */
 185      public function wanted_filters(): void {
 186          $this->display_question_bank_header();
 187          // Add search conditions.
 188          $this->add_standard_search_conditions();
 189      }
 190  
 191  }