See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
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 * Table filterset. 19 * 20 * @package core 21 * @category table 22 * @copyright 2020 Andrew Nicols <andrew@nicols.co.uk> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 declare(strict_types=1); 27 28 namespace core_table\local\filter; 29 30 use Countable; 31 use JsonSerializable; 32 use InvalidArgumentException; 33 use Iterator; 34 35 /** 36 * Class representing a generic filter of any type. 37 * 38 * @package core 39 * @copyright 2020 Andrew Nicols <andrew@nicols.co.uk> 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 class filter implements Countable, Iterator, JsonSerializable { 43 44 /** @var int The default filter type (ANY) */ 45 const JOINTYPE_DEFAULT = 1; 46 47 /** @var int None of the following match */ 48 const JOINTYPE_NONE = 0; 49 50 /** @var int Any of the following match */ 51 const JOINTYPE_ANY = 1; 52 53 /** @var int All of the following match */ 54 const JOINTYPE_ALL = 2; 55 56 /** @var string The name of this filter */ 57 protected $name = null; 58 59 /** @var int The join type currently in use */ 60 protected $jointype = self::JOINTYPE_DEFAULT; 61 62 /** @var array The list of active filter values */ 63 protected $filtervalues = []; 64 65 /** @var int[] valid join types */ 66 protected $jointypes = [ 67 self::JOINTYPE_NONE, 68 self::JOINTYPE_ANY, 69 self::JOINTYPE_ALL, 70 ]; 71 72 /** @var int The current iterator position */ 73 protected $iteratorposition = null; 74 75 /** 76 * Constructor for the generic filter class. 77 * 78 * @param string $name The name of the current filter. 79 * @param int $jointype The join to use when combining the filters. 80 * See the JOINTYPE_ constants for further information on the field. 81 * @param mixed[] $values An array of filter objects to be applied. 82 */ 83 public function __construct(string $name, ?int $jointype = null, ?array $values = null) { 84 $this->name = $name; 85 86 if ($jointype !== null) { 87 $this->set_join_type($jointype); 88 } 89 90 if (!empty($values)) { 91 foreach ($values as $value) { 92 $this->add_filter_value($value); 93 } 94 } 95 } 96 97 /** 98 * Reset the iterator position. 99 */ 100 public function reset_iterator(): void { 101 $this->iteratorposition = null; 102 } 103 104 /** 105 * Return the current filter value. 106 */ 107 #[\ReturnTypeWillChange] 108 public function current() { 109 if ($this->iteratorposition === null) { 110 $this->rewind(); 111 } 112 113 if ($this->iteratorposition === null) { 114 return null; 115 } 116 117 return $this->filtervalues[$this->iteratorposition]; 118 } 119 120 /** 121 * Returns the current position of the iterator. 122 * 123 * @return int 124 */ 125 #[\ReturnTypeWillChange] 126 public function key() { 127 if ($this->iteratorposition === null) { 128 $this->rewind(); 129 } 130 131 return $this->iteratorposition; 132 } 133 134 /** 135 * Rewind the Iterator position to the start. 136 */ 137 public function rewind(): void { 138 if ($this->iteratorposition === null) { 139 $this->sort_filter_values(); 140 } 141 142 if (count($this->filtervalues)) { 143 $this->iteratorposition = 0; 144 } 145 } 146 147 /** 148 * Move to the next value in the list. 149 */ 150 public function next(): void { 151 ++$this->iteratorposition; 152 } 153 154 /** 155 * Check if the current position is valid. 156 * 157 * @return bool 158 */ 159 public function valid(): bool { 160 return isset($this->filtervalues[$this->iteratorposition]); 161 } 162 163 /** 164 * Return the number of contexts. 165 * 166 * @return int 167 */ 168 public function count(): int { 169 return count($this->filtervalues); 170 } 171 172 /** 173 * Return the name of the filter. 174 * 175 * @return string 176 */ 177 public function get_name(): string { 178 return $this->name; 179 } 180 181 /** 182 * Specify the type of join to employ for the filter. 183 * 184 * @param int $jointype The join type to use using one of the supplied constants 185 * @return self 186 */ 187 public function set_join_type(int $jointype): self { 188 if (array_search($jointype, $this->jointypes) === false) { 189 throw new InvalidArgumentException('Invalid join type specified'); 190 } 191 192 $this->jointype = $jointype; 193 194 return $this; 195 } 196 197 /** 198 * Return the currently specified join type. 199 * 200 * @return int 201 */ 202 public function get_join_type(): int { 203 return $this->jointype; 204 } 205 206 /** 207 * Add a value to the filter. 208 * 209 * @param mixed $value 210 * @return self 211 */ 212 public function add_filter_value($value): self { 213 if ($value === null) { 214 // Null values are usually invalid. 215 return $this; 216 } 217 218 if ($value === '') { 219 // Empty strings are invalid. 220 return $this; 221 } 222 223 if (array_search($value, $this->filtervalues) !== false) { 224 // Remove duplicates. 225 return $this; 226 } 227 228 $this->filtervalues[] = $value; 229 230 // Reset the iterator position. 231 $this->reset_iterator(); 232 233 return $this; 234 } 235 236 /** 237 * Sort the filter values to ensure reliable, and consistent output. 238 */ 239 protected function sort_filter_values(): void { 240 // Sort the filter values to ensure consistent output. 241 // Note: This is not a locale-aware sort, but we don't need this. 242 // It's primarily for consistency, not for actual sorting. 243 sort($this->filtervalues); 244 245 $this->reset_iterator(); 246 } 247 248 /** 249 * Return the current filter values. 250 * 251 * @return mixed[] 252 */ 253 public function get_filter_values(): array { 254 $this->sort_filter_values(); 255 return $this->filtervalues; 256 } 257 258 /** 259 * Serialize filter. 260 * 261 * @return mixed|object 262 */ 263 #[\ReturnTypeWillChange] 264 public function jsonSerialize() { 265 return (object) [ 266 'name' => $this->get_name(), 267 'jointype' => $this->get_join_type(), 268 'values' => $this->get_filter_values(), 269 ]; 270 } 271 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body