Differences Between: [Versions 400 and 401] [Versions 400 and 402] [Versions 400 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 declare(strict_types=1); 18 19 namespace core_reportbuilder\local\filters; 20 21 use core_reportbuilder\local\helpers\database; 22 23 /** 24 * Number report filter 25 * 26 * @package core_reportbuilder 27 * @copyright 2021 David Matamoros <davidmc@moodle.com> 28 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 29 */ 30 class number extends base { 31 32 /** @var int Any value */ 33 public const ANY_VALUE = 0; 34 35 /** @var int Is not empty */ 36 public const IS_NOT_EMPTY = 1; 37 38 /** @var int Is empty */ 39 public const IS_EMPTY = 2; 40 41 /** @var int Less than */ 42 public const LESS_THAN = 3; 43 44 /** @var int Greater than */ 45 public const GREATER_THAN = 4; 46 47 /** @var int Equal to */ 48 public const EQUAL_TO = 5; 49 50 /** @var int Equal or less than */ 51 public const EQUAL_OR_LESS_THAN = 6; 52 53 /** @var int Equal or greater than */ 54 public const EQUAL_OR_GREATER_THAN = 7; 55 56 /** @var int Range */ 57 public const RANGE = 8; 58 59 /** 60 * Returns an array of comparison operators 61 * 62 * @return array of comparison operators 63 */ 64 private function get_operators(): array { 65 $operators = [ 66 self::ANY_VALUE => get_string('filterisanyvalue', 'core_reportbuilder'), 67 self::IS_NOT_EMPTY => get_string('filterisnotempty', 'core_reportbuilder'), 68 self::IS_EMPTY => get_string('filterisempty', 'core_reportbuilder'), 69 self::LESS_THAN => get_string('filterlessthan', 'core_reportbuilder'), 70 self::GREATER_THAN => get_string('filtergreaterthan', 'core_reportbuilder'), 71 self::EQUAL_TO => get_string('filterisequalto', 'core_reportbuilder'), 72 self::EQUAL_OR_LESS_THAN => get_string('filterequalorlessthan', 'core_reportbuilder'), 73 self::EQUAL_OR_GREATER_THAN => get_string('filterequalorgreaterthan', 'core_reportbuilder'), 74 self::RANGE => get_string('filterrange', 'core_reportbuilder'), 75 ]; 76 77 return $this->filter->restrict_limited_operators($operators); 78 } 79 80 /** 81 * Adds controls specific to this filter in the form. 82 * 83 * @param \MoodleQuickForm $mform 84 */ 85 public function setup_form(\MoodleQuickForm $mform): void { 86 $objs = []; 87 88 $objs['select'] = $mform->createElement('select', $this->name . '_operator', 89 get_string('filterfieldoperator', 'core_reportbuilder', $this->get_header()), $this->get_operators()); 90 $mform->setType($this->name . '_operator', PARAM_INT); 91 92 $objs['text'] = $mform->createElement('text', $this->name . '_value1', 93 get_string('filterfieldvalue', 'core_reportbuilder', $this->get_header()), ['size' => 3]); 94 $mform->setType($this->name . '_value1', PARAM_INT); 95 $mform->setDefault($this->name . '_value1', 0); 96 97 $objs['text2'] = $mform->createElement('text', $this->name . '_value2', get_string('to'), ['size' => 3]); 98 $mform->setType($this->name . '_value2', PARAM_INT); 99 $mform->setDefault($this->name . '_value2', 0); 100 101 $mform->addElement('group', $this->name . '_grp', '', $objs, '', false); 102 103 $mform->hideIf($this->name . '_value1', $this->name . '_operator', 'in', 104 [self::ANY_VALUE, self::IS_NOT_EMPTY, self::IS_EMPTY]); 105 $mform->hideIf($this->name . '_value2', $this->name . '_operator', 'noteq', self::RANGE); 106 } 107 108 /** 109 * Return filter SQL 110 * 111 * @param array $values 112 * @return array array of two elements - SQL query and named parameters 113 */ 114 public function get_sql_filter(array $values) : array { 115 $operator = (int) ($values["{$this->name}_operator"] ?? self::ANY_VALUE); 116 117 $value1 = $values["{$this->name}_value1"] ?? null; 118 $value2 = $values["{$this->name}_value2"] ?? null; 119 120 // Validate filter form values. 121 if (!$this->validate_filter_values($operator, $value1, $value2)) { 122 // Filter configuration is invalid. Ignore the filter. 123 return ['', []]; 124 } 125 126 $param = database::generate_param_name(); 127 $param2 = database::generate_param_name(); 128 $fieldsql = $this->filter->get_field_sql(); 129 $params = $this->filter->get_field_params(); 130 131 switch ($operator) { 132 case self::ANY_VALUE: 133 return ['', []]; 134 case self::IS_NOT_EMPTY: 135 $res = "COALESCE({$fieldsql}, 0) <> 0"; 136 break; 137 case self::IS_EMPTY: 138 $res = "COALESCE({$fieldsql}, 0) = 0"; 139 break; 140 case self::LESS_THAN: 141 $res = "{$fieldsql} < :{$param}"; 142 $params[$param] = $value1; 143 break; 144 case self::GREATER_THAN: 145 $res = "{$fieldsql} > :{$param}"; 146 $params[$param] = $value1; 147 break; 148 case self::EQUAL_TO: 149 $res = "{$fieldsql} = :{$param}"; 150 $params[$param] = $value1; 151 break; 152 case self::EQUAL_OR_LESS_THAN: 153 $res = "{$fieldsql} <= :{$param}"; 154 $params[$param] = $value1; 155 break; 156 case self::EQUAL_OR_GREATER_THAN: 157 $res = "{$fieldsql} >= :{$param}"; 158 $params[$param] = $value1; 159 break; 160 case self::RANGE: 161 $res = "{$fieldsql} BETWEEN :{$param} AND :{$param2}"; 162 $params[$param] = $value1; 163 $params[$param2] = $value2; 164 break; 165 default: 166 // Filter configuration is invalid. Ignore the filter. 167 return ['', []]; 168 } 169 return [$res, $params]; 170 } 171 172 /** 173 * Validate filter form values 174 * 175 * @param int $operator 176 * @param int|null $value1 177 * @param int|null $value2 178 * @return bool 179 */ 180 private function validate_filter_values(int $operator, ?int $value1, ?int $value2): bool { 181 // Check that for any of these operators value1 can not be null. 182 $requirescomparisonvalue = [ 183 self::LESS_THAN, 184 self::GREATER_THAN, 185 self::EQUAL_TO, 186 self::EQUAL_OR_LESS_THAN, 187 self::EQUAL_OR_GREATER_THAN 188 ]; 189 if (in_array($operator, $requirescomparisonvalue) && $value1 === null) { 190 return false; 191 } 192 193 // When operator is between $value1 and $value2, can not be null. 194 if (($operator === self::RANGE) && ($value1 === null || $value2 === null)) { 195 return false; 196 } 197 198 return true; 199 } 200 201 /** 202 * Return sample filter values 203 * 204 * @return array 205 */ 206 public function get_sample_values(): array { 207 return [ 208 "{$this->name}_operator" => self::GREATER_THAN, 209 "{$this->name}_value1" => 1, 210 ]; 211 } 212 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body