Search moodle.org's
Developer Documentation

See Release Notes

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

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

   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   * A condition for adding filtering by tag to the question bank.
  19   *
  20   * @package   core_question
  21   * @copyright 2018 Ryan Wyllie <ryan@moodle.com>
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace core_question\bank\search;
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  /**
  29   * Question bank search class to allow searching/filtering by tags on a question.
  30   *
  31   * @copyright 2018 Ryan Wyllie <ryan@moodle.com>
  32   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33   */
  34  class tag_condition extends condition {
  35      /** @var string SQL fragment to add to the where clause. */
  36      protected $where;
  37      /** @var string SQL fragment to add to the where clause. */
  38      protected $contexts;
  39      /** @var array List of IDs for tags that have been selected in the form. */
  40      protected $selectedtagids;
  41  
  42      /**
  43       * Constructor.
  44       * @param context[] $contexts List of contexts to show tags from
  45       * @param int[] $selectedtagids List of IDs for tags to filter by.
  46       */
  47      public function __construct(array $contexts, array $selectedtagids = []) {
  48          global $DB;
  49  
  50          $this->contexts = $contexts;
  51  
  52          // If some tags have been selected then we need to filter
  53          // the question list by the selected tags.
  54          if ($selectedtagids) {
  55              // We treat each additional tag as an AND condition rather than
  56              // an OR condition.
  57              //
  58              // For example, if the user filters by the tags "foo" and "bar" then
  59              // we reduce the question list to questions that are tagged with both
  60              // "foo" AND "bar". Any question that does not have ALL of the specified
  61              // tags will be omitted.
  62              list($tagsql, $tagparams) = $DB->get_in_or_equal($selectedtagids, SQL_PARAMS_NAMED);
  63              $tagparams['tagcount'] = count($selectedtagids);
  64              $tagparams['questionitemtype'] = 'question';
  65              $tagparams['questioncomponent'] = 'core_question';
  66              $this->selectedtagids = $selectedtagids;
  67              $this->params = $tagparams;
  68              $this->where = "q.id IN (SELECT ti.itemid
  69                                         FROM {tag_instance} ti
  70                                        WHERE ti.itemtype = :questionitemtype
  71                                              AND ti.component = :questioncomponent
  72                                              AND ti.tagid {$tagsql}
  73                                     GROUP BY ti.itemid
  74                                       HAVING COUNT(itemid) = :tagcount)";
  75  
  76          } else {
  77              $this->selectedtagids = [];
  78              $this->params = [];
  79              $this->where = '';
  80          }
  81      }
  82  
  83      /**
  84       * Get the SQL WHERE snippet to be used in the SQL to retrieve the
  85       * list of questions. This SQL snippet will add the logic for the
  86       * tag condition.
  87       *
  88       * @return string
  89       */
  90      public function where() {
  91          return $this->where;
  92      }
  93  
  94      /**
  95       * Named SQL params to be used with the SQL WHERE snippet.
  96       *
  97       * @return array
  98       */
  99      public function params() {
 100          return $this->params;
 101      }
 102  
 103      /**
 104       * Print HTML to display the list of tags to filter by.
 105       */
 106      public function display_options() {
 107          global $OUTPUT;
 108  
 109          $tags = \core_tag_tag::get_tags_by_area_in_contexts('core_question', 'question', $this->contexts);
 110          $tagoptions = array_map(function($tag) {
 111              return [
 112                  'id' => $tag->id,
 113                  'name' => $tag->name,
 114                  'selected' => in_array($tag->id, $this->selectedtagids)
 115              ];
 116          }, array_values($tags));
 117          $context = [
 118              'tagoptions' => $tagoptions
 119          ];
 120  
 121          echo $OUTPUT->render_from_template('core_question/tag_condition', $context);
 122      }
 123  }