See Release Notes
Long Term Support Release
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 declare(strict_types=1); 18 19 namespace core_reportbuilder\local\filters; 20 21 use coding_exception; 22 use core_tag_tag; 23 use lang_string; 24 use MoodleQuickForm; 25 use stdClass; 26 use core_reportbuilder\local\helpers\database; 27 28 /** 29 * Class containing logic for the tags filter 30 * 31 * The field SQL should be the field containing the ID of the {tag} table 32 * 33 * @package core_reportbuilder 34 * @copyright 2022 Paul Holden <paulh@moodle.com> 35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 */ 37 class tags extends base { 38 39 /** @var int Any value */ 40 public const ANY_VALUE = 0; 41 42 /** @var int Tags are present */ 43 public const NOT_EMPTY = 1; 44 45 /** @var int Filter for selected tags */ 46 public const EQUAL_TO = 2; 47 48 /** @var int Tags are not present */ 49 public const EMPTY = 3; 50 51 /** @var int Filter for excluded tags */ 52 public const NOT_EQUAL_TO = 4; 53 54 /** 55 * Returns an array of comparison operators 56 * 57 * @return array 58 */ 59 private function get_operators(): array { 60 $operators = [ 61 self::ANY_VALUE => new lang_string('filterisanyvalue', 'core_reportbuilder'), 62 self::NOT_EMPTY => new lang_string('filterisnotempty', 'core_reportbuilder'), 63 self::EMPTY => new lang_string('filterisempty', 'core_reportbuilder'), 64 self::EQUAL_TO => new lang_string('filterisequalto', 'core_reportbuilder'), 65 self::NOT_EQUAL_TO => new lang_string('filterisnotequalto', 'core_reportbuilder'), 66 ]; 67 68 return $this->filter->restrict_limited_operators($operators); 69 } 70 71 /** 72 * Setup form 73 * 74 * @param MoodleQuickForm $mform 75 */ 76 public function setup_form(MoodleQuickForm $mform): void { 77 global $DB; 78 79 $operatorlabel = get_string('filterfieldoperator', 'core_reportbuilder', $this->get_header()); 80 $mform->addElement('select', "{$this->name}_operator", $operatorlabel, $this->get_operators()) 81 ->setHiddenLabel(true); 82 83 $sql = 'SELECT DISTINCT t.id, t.name, t.rawname 84 FROM {tag} t 85 ORDER BY t.name'; 86 87 // Transform tag records into appropriate display name, for selection in the autocomplete element. 88 $tags = array_map(static function(stdClass $record): string { 89 return core_tag_tag::make_display_name($record); 90 }, $DB->get_records_sql($sql)); 91 92 $valuelabel = get_string('filterfieldvalue', 'core_reportbuilder', $this->get_header()); 93 $mform->addElement('autocomplete', "{$this->name}_value", $valuelabel, $tags, ['multiple' => true]) 94 ->setHiddenLabel(true); 95 $mform->hideIf("{$this->name}_value", "{$this->name}_operator", 'in', [self::ANY_VALUE, self::EMPTY, self::NOT_EMPTY]); 96 } 97 98 /** 99 * Return filter SQL 100 * 101 * @param array $values 102 * @return array 103 */ 104 public function get_sql_filter(array $values): array { 105 global $DB; 106 107 $fieldsql = $this->filter->get_field_sql(); 108 $params = $this->filter->get_field_params(); 109 110 $operator = (int) ($values["{$this->name}_operator"] ?? self::ANY_VALUE); 111 $tags = (array) ($values["{$this->name}_value"] ?? []); 112 113 if ($operator === self::NOT_EMPTY) { 114 $select = "{$fieldsql} IS NOT NULL"; 115 } else if ($operator === self::EMPTY) { 116 $select = "{$fieldsql} IS NULL"; 117 } else if ($operator === self::EQUAL_TO && !empty($tags)) { 118 [$tagselect, $tagselectparams] = $DB->get_in_or_equal($tags, SQL_PARAMS_NAMED, 119 database::generate_param_name() . '_'); 120 121 $select = "{$fieldsql} {$tagselect}"; 122 $params = array_merge($params, $tagselectparams); 123 } else if ($operator === self::NOT_EQUAL_TO && !empty($tags)) { 124 [$tagselect, $tagselectparams] = $DB->get_in_or_equal($tags, SQL_PARAMS_NAMED, 125 database::generate_param_name() . '_', false); 126 127 // We should also return those elements that aren't tagged at all. 128 $select = "COALESCE({$fieldsql}, 0) {$tagselect}"; 129 $params = array_merge($params, $tagselectparams); 130 } else { 131 // Invalid/inactive (any value) filter.. 132 return ['', []]; 133 } 134 135 return [$select, $params]; 136 } 137 138 /** 139 * Return sample filter values 140 * 141 * @return array 142 */ 143 public function get_sample_values(): array { 144 return [ 145 "{$this->name}_operator" => self::EQUAL_TO, 146 "{$this->name}_value" => [1], 147 ]; 148 } 149 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body