Differences Between: [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_files\reportbuilder\local\entities; 20 21 use context; 22 use context_helper; 23 use lang_string; 24 use license_manager; 25 use html_writer; 26 use stdClass; 27 use core_reportbuilder\local\entities\base; 28 use core_reportbuilder\local\helpers\format; 29 use core_reportbuilder\local\filters\{boolean_select, date, number, select, text}; 30 use core_reportbuilder\local\report\{column, filter}; 31 32 /** 33 * File entity 34 * 35 * @package core_files 36 * @copyright 2022 Paul Holden <paulh@moodle.com> 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class file extends base { 40 41 /** 42 * Database tables that this entity uses and their default aliases 43 * 44 * @return array 45 */ 46 protected function get_default_table_aliases(): array { 47 return [ 48 'files' => 'f', 49 'context' => 'fctx', 50 ]; 51 } 52 53 /** 54 * The default title for this entity 55 * 56 * @return lang_string 57 */ 58 protected function get_default_entity_title(): lang_string { 59 return new lang_string('file'); 60 } 61 62 /** 63 * Initialise the entity 64 * 65 * @return base 66 */ 67 public function initialise(): base { 68 $columns = $this->get_all_columns(); 69 foreach ($columns as $column) { 70 $this->add_column($column); 71 } 72 73 // All the filters defined by the entity can also be used as conditions. 74 $filters = $this->get_all_filters(); 75 foreach ($filters as $filter) { 76 $this 77 ->add_filter($filter) 78 ->add_condition($filter); 79 } 80 81 return $this; 82 } 83 84 /** 85 * Returns list of all available columns 86 * 87 * @return column[] 88 */ 89 protected function get_all_columns(): array { 90 $filesalias = $this->get_table_alias('files'); 91 $contextalias = $this->get_table_alias('context'); 92 93 // Name. 94 $columns[] = (new column( 95 'name', 96 new lang_string('filename', 'core_repository'), 97 $this->get_entity_name() 98 )) 99 ->add_joins($this->get_joins()) 100 ->set_type(column::TYPE_TEXT) 101 ->add_field("{$filesalias}.filename") 102 ->set_is_sortable(true); 103 104 // Size. 105 $columns[] = (new column( 106 'size', 107 new lang_string('size'), 108 $this->get_entity_name() 109 )) 110 ->add_joins($this->get_joins()) 111 ->set_type(column::TYPE_INTEGER) 112 ->add_field("{$filesalias}.filesize") 113 ->add_field("CASE WHEN {$filesalias}.filename = '.' THEN 1 ELSE 0 END", 'directory') 114 ->set_is_sortable(true) 115 ->add_callback(static function($filesize, stdClass $fileinfo): string { 116 // Absent file size and/or directory should not return output. 117 if ($fileinfo->filesize === null || $fileinfo->directory) { 118 return ''; 119 } 120 return display_size($fileinfo->filesize); 121 }); 122 123 // Path. 124 $columns[] = (new column( 125 'path', 126 new lang_string('path'), 127 $this->get_entity_name() 128 )) 129 ->add_joins($this->get_joins()) 130 ->set_type(column::TYPE_TEXT) 131 ->add_field("{$filesalias}.filepath") 132 ->set_is_sortable(true); 133 134 // Type. 135 $columns[] = (new column( 136 'type', 137 new lang_string('type', 'core_repository'), 138 $this->get_entity_name() 139 )) 140 ->add_joins($this->get_joins()) 141 ->set_type(column::TYPE_TEXT) 142 ->add_field("{$filesalias}.mimetype") 143 ->add_field("CASE WHEN {$filesalias}.filename = '.' THEN 1 ELSE 0 END", 'directory') 144 ->set_is_sortable(true) 145 ->add_callback(static function($mimetype, stdClass $fileinfo): string { 146 global $CFG; 147 require_once("{$CFG->libdir}/filelib.php"); 148 149 // Absent mime type and/or directory has pre-determined output. 150 if ($fileinfo->mimetype === null && !$fileinfo->directory) { 151 return ''; 152 } else if ($fileinfo->directory) { 153 return get_string('directory'); 154 } 155 156 return get_mimetype_description($fileinfo->mimetype); 157 }); 158 159 // Author. 160 $columns[] = (new column( 161 'author', 162 new lang_string('author', 'core_repository'), 163 $this->get_entity_name() 164 )) 165 ->add_joins($this->get_joins()) 166 ->set_type(column::TYPE_TEXT) 167 ->add_field("{$filesalias}.author") 168 ->set_is_sortable(true); 169 170 // License. 171 $columns[] = (new column( 172 'license', 173 new lang_string('license', 'core_repository'), 174 $this->get_entity_name() 175 )) 176 ->add_joins($this->get_joins()) 177 ->set_type(column::TYPE_TEXT) 178 ->add_field("{$filesalias}.license") 179 ->set_is_sortable(true) 180 ->add_callback(static function(?string $license): string { 181 global $CFG; 182 require_once("{$CFG->libdir}/licenselib.php"); 183 184 $licenses = license_manager::get_licenses(); 185 if ($license === null || !array_key_exists($license, $licenses)) { 186 return ''; 187 } 188 return $licenses[$license]->fullname; 189 }); 190 191 // Context. 192 $columns[] = (new column( 193 'context', 194 new lang_string('context'), 195 $this->get_entity_name() 196 )) 197 ->add_joins($this->get_joins()) 198 ->set_type(column::TYPE_TEXT) 199 ->add_join("LEFT JOIN {context} {$contextalias} ON {$contextalias}.id = {$filesalias}.contextid") 200 ->add_fields("{$filesalias}.contextid, " . context_helper::get_preload_record_columns_sql($contextalias)) 201 // Sorting may not order alphabetically, but will at least group contexts together. 202 ->set_is_sortable(true) 203 ->add_callback(static function($contextid, stdClass $context): string { 204 if ($contextid === null) { 205 return ''; 206 } 207 208 context_helper::preload_from_record($context); 209 return context::instance_by_id($contextid)->get_context_name(); 210 }); 211 212 // Context link. 213 $columns[] = (new column( 214 'contexturl', 215 new lang_string('contexturl'), 216 $this->get_entity_name() 217 )) 218 ->add_joins($this->get_joins()) 219 ->set_type(column::TYPE_TEXT) 220 ->add_join("LEFT JOIN {context} {$contextalias} ON {$contextalias}.id = {$filesalias}.contextid") 221 ->add_fields("{$filesalias}.contextid, " . context_helper::get_preload_record_columns_sql($contextalias)) 222 // Sorting may not order alphabetically, but will at least group contexts together. 223 ->set_is_sortable(true) 224 ->add_callback(static function($contextid, stdClass $context): string { 225 if ($contextid === null) { 226 return ''; 227 } 228 229 context_helper::preload_from_record($context); 230 $context = context::instance_by_id($contextid); 231 232 return html_writer::link($context->get_url(), $context->get_context_name()); 233 }); 234 235 // Component. 236 $columns[] = (new column( 237 'component', 238 new lang_string('plugin'), 239 $this->get_entity_name() 240 )) 241 ->add_joins($this->get_joins()) 242 ->set_type(column::TYPE_TEXT) 243 ->add_fields("{$filesalias}.component") 244 ->set_is_sortable(true); 245 246 // Area. 247 $columns[] = (new column( 248 'area', 249 new lang_string('pluginarea'), 250 $this->get_entity_name() 251 )) 252 ->add_joins($this->get_joins()) 253 ->set_type(column::TYPE_TEXT) 254 ->add_fields("{$filesalias}.filearea") 255 ->set_is_sortable(true); 256 257 // Item ID. 258 $columns[] = (new column( 259 'itemid', 260 new lang_string('pluginitemid'), 261 $this->get_entity_name() 262 )) 263 ->add_joins($this->get_joins()) 264 ->set_type(column::TYPE_INTEGER) 265 ->add_fields("{$filesalias}.itemid") 266 ->set_is_sortable(true) 267 ->set_disabled_aggregation_all(); 268 269 // Time created. 270 $columns[] = (new column( 271 'timecreated', 272 new lang_string('timecreated', 'core_reportbuilder'), 273 $this->get_entity_name() 274 )) 275 ->add_joins($this->get_joins()) 276 ->set_type(column::TYPE_TIMESTAMP) 277 ->add_field("{$filesalias}.timecreated") 278 ->add_callback([format::class, 'userdate']) 279 ->set_is_sortable(true); 280 281 return $columns; 282 } 283 284 /** 285 * Return list of all available filters 286 * 287 * @return filter[] 288 */ 289 protected function get_all_filters(): array { 290 $filesalias = $this->get_table_alias('files'); 291 292 // Directory. 293 $filters[] = (new filter( 294 boolean_select::class, 295 'directory', 296 new lang_string('directory'), 297 $this->get_entity_name(), 298 "CASE WHEN {$filesalias}.filename = '.' THEN 1 ELSE 0 END" 299 )) 300 ->add_joins($this->get_joins()); 301 302 // Draft. 303 $filters[] = (new filter( 304 boolean_select::class, 305 'draft', 306 new lang_string('areauserdraft', 'core_repository'), 307 $this->get_entity_name(), 308 "CASE WHEN {$filesalias}.component = 'user' AND {$filesalias}.filearea = 'draft' THEN 1 ELSE 0 END" 309 )) 310 ->add_joins($this->get_joins()); 311 312 // Name. 313 $filters[] = (new filter( 314 text::class, 315 'name', 316 new lang_string('filename', 'core_repository'), 317 $this->get_entity_name(), 318 "{$filesalias}.filename" 319 )) 320 ->add_joins($this->get_joins()); 321 322 // Size. 323 $filters[] = (new filter( 324 number::class, 325 'size', 326 new lang_string('size'), 327 $this->get_entity_name(), 328 "{$filesalias}.filesize" 329 )) 330 ->add_joins($this->get_joins()) 331 ->set_limited_operators([ 332 number::ANY_VALUE, 333 number::LESS_THAN, 334 number::GREATER_THAN, 335 number::RANGE, 336 ]); 337 338 // License (consider null = 'unknown/license not specified' for filtering purposes). 339 $filters[] = (new filter( 340 select::class, 341 'license', 342 new lang_string('license', 'core_repository'), 343 $this->get_entity_name(), 344 "COALESCE({$filesalias}.license, 'unknown')" 345 )) 346 ->add_joins($this->get_joins()) 347 ->set_options_callback(static function(): array { 348 global $CFG; 349 require_once("{$CFG->libdir}/licenselib.php"); 350 351 $licenses = license_manager::get_licenses(); 352 353 return array_map(static function(stdClass $license): string { 354 return $license->fullname; 355 }, $licenses); 356 }); 357 358 // Time created. 359 $filters[] = (new filter( 360 date::class, 361 'timecreated', 362 new lang_string('timecreated', 'core_reportbuilder'), 363 $this->get_entity_name(), 364 "{$filesalias}.timecreated" 365 )) 366 ->add_joins($this->get_joins()) 367 ->set_limited_operators([ 368 date::DATE_ANY, 369 date::DATE_RANGE, 370 date::DATE_LAST, 371 date::DATE_CURRENT, 372 ]); 373 374 return $filters; 375 } 376 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body