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 declare(strict_types=1); 18 19 namespace core_reportbuilder\local\entities; 20 21 use coding_exception; 22 use lang_string; 23 use core_reportbuilder\local\report\column; 24 use core_reportbuilder\local\report\filter; 25 26 /** 27 * Base class for all report entities 28 * 29 * @package core_reportbuilder 30 * @copyright 2019 Marina Glancy <marina@moodle.com> 31 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 32 */ 33 abstract class base { 34 35 /** @var string $entityname Internal reference to name of entity */ 36 private $entityname = null; 37 38 /** @var lang_string $entitytitle Used as a title for the entity in reports */ 39 private $entitytitle = null; 40 41 /** @var array $tablealiases Database tables that this entity uses and their aliases */ 42 private $tablealiases = []; 43 44 /** @var array $tablejoinaliases Database tables that have already been joined to the report and their aliases */ 45 private $tablejoinaliases = []; 46 47 /** @var string[] $joins List of SQL joins for the entity */ 48 private $joins = []; 49 50 /** @var column[] $columns List of columns for the entity */ 51 private $columns = []; 52 53 /** @var filter[] $filters List of filters for the entity */ 54 private $filters = []; 55 56 /** @var filter[] $conditions List of conditions for the entity */ 57 private $conditions = []; 58 59 /** 60 * Database tables that this entity uses and their default aliases 61 * 62 * Must be overridden by the entity to list all database tables that it expects to be present in the main 63 * SQL or in JOINs added to this entity 64 * 65 * @return string[] Array of $tablename => $alias 66 */ 67 abstract protected function get_default_table_aliases(): array; 68 69 /** 70 * The default title for this entity 71 * 72 * @return lang_string 73 */ 74 abstract protected function get_default_entity_title(): lang_string; 75 76 /** 77 * Initialise the entity, called automatically when it is added to a report 78 * 79 * This is where entity defines all its columns and filters by calling: 80 * - {@see add_column} 81 * - {@see add_filter} 82 * - etc 83 * 84 * @return self 85 */ 86 abstract public function initialise(): self; 87 88 /** 89 * The default machine-readable name for this entity that will be used in the internal names of the columns/filters 90 * 91 * @return string 92 */ 93 private function get_default_entity_name(): string { 94 $namespace = explode('\\', get_called_class()); 95 96 return end($namespace); 97 } 98 99 /** 100 * Set entity name 101 * 102 * @param string $entityname 103 * @return self 104 */ 105 final public function set_entity_name(string $entityname): self { 106 $this->entityname = $entityname; 107 return $this; 108 } 109 110 /** 111 * Return entity name 112 * 113 * @return string 114 */ 115 final public function get_entity_name(): string { 116 return $this->entityname ?? $this->get_default_entity_name(); 117 } 118 119 /** 120 * Set entity title 121 * 122 * @param lang_string $title 123 * @return self 124 */ 125 final public function set_entity_title(lang_string $title): self { 126 $this->entitytitle = $title; 127 return $this; 128 } 129 130 /** 131 * Get entity title 132 * 133 * @return lang_string 134 */ 135 final public function get_entity_title(): lang_string { 136 return $this->entitytitle ?? $this->get_default_entity_title(); 137 } 138 139 /** 140 * Override the default alias for given database table used in entity queries, to avoid table alias clashes that may occur 141 * if multiple entities of a report each define the same default alias for one of their tables 142 * 143 * @param string $tablename 144 * @param string $alias 145 * @return self 146 * @throws coding_exception 147 */ 148 final public function set_table_alias(string $tablename, string $alias): self { 149 if (!array_key_exists($tablename, $this->get_default_table_aliases())) { 150 throw new coding_exception('Invalid table name', $tablename); 151 } 152 153 $this->tablealiases[$tablename] = $alias; 154 return $this; 155 } 156 157 /** 158 * Override multiple default database table aliases used in entity queries as per {@see set_table_alias}, typically when 159 * you're adding an entity multiple times to a report you'd want to override the table aliases in the second instance to 160 * avoid clashes with the first 161 * 162 * @param array $aliases Array of tablename => alias values 163 * @return self 164 */ 165 final public function set_table_aliases(array $aliases): self { 166 foreach ($aliases as $tablename => $alias) { 167 $this->set_table_alias($tablename, $alias); 168 } 169 return $this; 170 } 171 172 /** 173 * Returns an alias used in the queries for a given table 174 * 175 * @param string $tablename 176 * @return string 177 * @throws coding_exception 178 */ 179 final public function get_table_alias(string $tablename): string { 180 $defaulttablealiases = $this->get_default_table_aliases(); 181 if (!array_key_exists($tablename, $defaulttablealiases)) { 182 throw new coding_exception('Invalid table name', $tablename); 183 } 184 185 return $this->tablealiases[$tablename] ?? $defaulttablealiases[$tablename]; 186 } 187 188 /** 189 * Set the alias for given database table that has already been added to the report. Enables entities to avoid additional 190 * joins on the same table by allowing re-use of existing table aliases in their own queries, {@see has_table_join_alias} 191 * 192 * @param string $tablename 193 * @param string $alias 194 * @return self 195 */ 196 final public function set_table_join_alias(string $tablename, string $alias): self { 197 $this->tablejoinaliases[$tablename] = $alias; 198 199 // Internally set the same table alias for the entity. 200 return $this->set_table_alias($tablename, $alias); 201 } 202 203 /** 204 * Determine whether defined table join alias was specified. Call {@see get_table_alias} to retrieve said value 205 * 206 * @param string $tablename 207 * @return bool 208 */ 209 final public function has_table_join_alias(string $tablename): bool { 210 return array_key_exists($tablename, $this->tablejoinaliases); 211 } 212 213 /** 214 * Add join clause required for this entity to join to existing tables/entities 215 * 216 * @param string $join 217 * @return self 218 */ 219 final public function add_join(string $join): self { 220 $this->joins[trim($join)] = trim($join); 221 return $this; 222 } 223 224 /** 225 * Add multiple join clauses required for this entity {@see add_join} 226 * 227 * @param string[] $joins 228 * @return self 229 */ 230 final public function add_joins(array $joins): self { 231 foreach ($joins as $join) { 232 $this->add_join($join); 233 } 234 return $this; 235 } 236 237 /** 238 * Return entity joins 239 * 240 * @return string[] 241 */ 242 final public function get_joins(): array { 243 return array_values($this->joins); 244 } 245 246 /** 247 * Helper method for returning joins necessary for retrieving tags related to the current entity 248 * 249 * Both 'tag' and 'tag_instance' aliases must be returned by the entity {@see get_default_table_aliases} method 250 * 251 * @param string $component 252 * @param string $itemtype 253 * @param string $itemidfield 254 * @return string[] 255 */ 256 final protected function get_tag_joins_for_entity(string $component, string $itemtype, string $itemidfield): array { 257 $taginstancealias = $this->get_table_alias('tag_instance'); 258 $tagalias = $this->get_table_alias('tag'); 259 260 return [ 261 "LEFT JOIN {tag_instance} {$taginstancealias} 262 ON {$taginstancealias}.component = '{$component}' 263 AND {$taginstancealias}.itemtype = '{$itemtype}' 264 AND {$taginstancealias}.itemid = {$itemidfield}", 265 "LEFT JOIN {tag} {$tagalias} 266 ON {$tagalias}.id = {$taginstancealias}.tagid", 267 ]; 268 } 269 270 /** 271 * Add a column to the entity 272 * 273 * @param column $column 274 * @return self 275 */ 276 final protected function add_column(column $column): self { 277 $this->columns[$column->get_name()] = $column; 278 return $this; 279 } 280 281 /** 282 * Returns entity columns 283 * 284 * @return column[] 285 */ 286 final public function get_columns(): array { 287 return $this->columns; 288 } 289 290 /** 291 * Returns an entity column 292 * 293 * @param string $name 294 * @return column 295 * @throws coding_exception For invalid column name 296 */ 297 final public function get_column(string $name): column { 298 if (!array_key_exists($name, $this->columns)) { 299 throw new coding_exception('Invalid column name', $name); 300 } 301 302 return $this->columns[$name]; 303 } 304 305 /** 306 * Add a filter to the entity 307 * 308 * @param filter $filter 309 * @return self 310 */ 311 final protected function add_filter(filter $filter): self { 312 $this->filters[$filter->get_name()] = $filter; 313 return $this; 314 } 315 316 /** 317 * Returns entity filters 318 * 319 * @return filter[] 320 */ 321 final public function get_filters(): array { 322 return $this->filters; 323 } 324 325 /** 326 * Returns an entity filter 327 * 328 * @param string $name 329 * @return filter 330 * @throws coding_exception For invalid filter name 331 */ 332 final public function get_filter(string $name): filter { 333 if (!array_key_exists($name, $this->filters)) { 334 throw new coding_exception('Invalid filter name', $name); 335 } 336 337 return $this->filters[$name]; 338 } 339 340 /** 341 * Add a condition to the entity 342 * 343 * @param filter $condition 344 * @return $this 345 */ 346 final protected function add_condition(filter $condition): self { 347 $this->conditions[$condition->get_name()] = $condition; 348 return $this; 349 } 350 351 /** 352 * Returns entity conditions 353 * 354 * @return filter[] 355 */ 356 final public function get_conditions(): array { 357 return $this->conditions; 358 } 359 360 /** 361 * Returns an entity condition 362 * 363 * @param string $name 364 * @return filter 365 * @throws coding_exception For invalid condition name 366 */ 367 final public function get_condition(string $name): filter { 368 if (!array_key_exists($name, $this->conditions)) { 369 throw new coding_exception('Invalid condition name', $name); 370 } 371 372 return $this->conditions[$name]; 373 } 374 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body