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_course\reportbuilder\local\entities; 20 21 use context_course; 22 use core_course\reportbuilder\local\formatters\enrolment as enrolment_formatter; 23 use core_reportbuilder\local\entities\base; 24 use core_reportbuilder\local\filters\date; 25 use core_reportbuilder\local\filters\select; 26 use core_reportbuilder\local\helpers\database; 27 use core_reportbuilder\local\helpers\format; 28 use core_reportbuilder\local\report\column; 29 use core_reportbuilder\local\report\filter; 30 use core_user\output\status_field; 31 use enrol_plugin; 32 use lang_string; 33 use stdClass; 34 35 /** 36 * Course enrolment entity implementation 37 * 38 * @package core_course 39 * @copyright 2022 David Matamoros <davidmc@moodle.com> 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 class enrolment extends base { 43 44 /** 45 * Database tables that this entity uses and their default aliases 46 * 47 * @return array 48 */ 49 protected function get_default_table_aliases(): array { 50 return ['user_enrolments' => 'ue', 'enrol' => 'e']; 51 } 52 53 /** 54 * The default title for this entity in the list of columns/conditions/filters in the report builder 55 * 56 * @return lang_string 57 */ 58 protected function get_default_entity_title(): lang_string { 59 return new lang_string('enrolment', 'enrol'); 60 } 61 62 /** 63 * Initialise the entity 64 * 65 * @return base 66 */ 67 public function initialise(): base { 68 foreach ($this->get_all_columns() as $column) { 69 $this->add_column($column); 70 } 71 72 // All the filters defined by the entity can also be used as conditions. 73 foreach ($this->get_all_filters() as $filter) { 74 $this 75 ->add_filter($filter) 76 ->add_condition($filter); 77 } 78 79 return $this; 80 } 81 82 /** 83 * Returns list of all available columns 84 * 85 * @return column[] 86 */ 87 protected function get_all_columns(): array { 88 $userenrolments = $this->get_table_alias('user_enrolments'); 89 $enrol = $this->get_table_alias('enrol'); 90 91 // Enrolment method column. 92 $columns[] = (new column( 93 'method', 94 new lang_string('method', 'enrol'), 95 $this->get_entity_name() 96 )) 97 ->add_joins($this->get_joins()) 98 ->set_type(column::TYPE_TEXT) 99 ->add_fields("{$enrol}.enrol, {$enrol}.id") 100 ->set_is_sortable(true) 101 ->add_callback([enrolment_formatter::class, 'enrolment_name']); 102 103 // Enrolment time created. 104 $columns[] = (new column( 105 'timecreated', 106 new lang_string('timecreated', 'moodle'), 107 $this->get_entity_name() 108 )) 109 ->add_joins($this->get_joins()) 110 ->set_type(column::TYPE_TIMESTAMP) 111 ->add_field("{$userenrolments}.timecreated") 112 ->set_is_sortable(true) 113 ->add_callback([format::class, 'userdate']); 114 115 // Enrolment time started. 116 $columns[] = (new column( 117 'timestarted', 118 new lang_string('timestarted', 'enrol'), 119 $this->get_entity_name() 120 )) 121 ->add_joins($this->get_joins()) 122 ->set_type(column::TYPE_TIMESTAMP) 123 ->add_field(" 124 CASE WHEN {$userenrolments}.timestart = 0 125 THEN {$userenrolments}.timecreated 126 ELSE {$userenrolments}.timestart 127 END", 'timestarted') 128 ->set_is_sortable(true) 129 ->add_callback([format::class, 'userdate']); 130 131 // Enrolment time ended. 132 $columns[] = (new column( 133 'timeended', 134 new lang_string('timeended', 'enrol'), 135 $this->get_entity_name() 136 )) 137 ->add_joins($this->get_joins()) 138 ->set_type(column::TYPE_TIMESTAMP) 139 ->add_field("{$userenrolments}.timeend") 140 ->set_is_sortable(true) 141 ->add_callback([format::class, 'userdate']); 142 143 // Enrolment status. 144 $columns[] = (new column( 145 'status', 146 new lang_string('status', 'moodle'), 147 $this->get_entity_name() 148 )) 149 ->add_joins($this->get_joins()) 150 ->set_type(column::TYPE_TEXT) 151 ->add_field($this->get_status_field_sql(), 'status') 152 ->set_is_sortable(true) 153 ->add_callback([enrolment_formatter::class, 'enrolment_status']); 154 155 // Role method column. 156 $ctx = database::generate_alias(); 157 $ra = database::generate_alias(); 158 $r = database::generate_alias(); 159 $columns[] = (new column( 160 'role', 161 new lang_string('role', 'moodle'), 162 $this->get_entity_name() 163 )) 164 ->add_joins($this->get_joins()) 165 ->add_join("LEFT JOIN {context} {$ctx} 166 ON {$ctx}.instanceid = {$enrol}.courseid AND {$ctx}.contextlevel = " . CONTEXT_COURSE) 167 ->add_join("LEFT JOIN {role_assignments} {$ra} 168 ON {$ra}.contextid = {$ctx}.id AND {$ra}.userid = {$userenrolments}.userid") 169 ->add_join("LEFT JOIN {role} {$r} ON {$r}.id = {$ra}.roleid") 170 ->set_type(column::TYPE_TEXT) 171 ->add_fields("{$r}.id, {$r}.name, {$r}.shortname, {$ctx}.instanceid") 172 ->set_is_sortable(true, ["{$r}.shortname"]) 173 ->add_callback(static function(?string $value, stdClass $row): string { 174 if (!$row->id) { 175 return ''; 176 } 177 $context = context_course::instance($row->instanceid); 178 return role_get_name($row, $context, ROLENAME_ALIAS); 179 }); 180 181 return $columns; 182 } 183 184 /** 185 * Generate SQL snippet suitable for returning enrolment status field 186 * 187 * @return string 188 */ 189 private function get_status_field_sql(): string { 190 $time = time(); 191 $userenrolments = $this->get_table_alias('user_enrolments'); 192 $enrol = $this->get_table_alias('enrol'); 193 194 return " 195 CASE WHEN {$userenrolments}.status = " . ENROL_USER_ACTIVE . " 196 THEN CASE WHEN ({$userenrolments}.timestart > {$time}) 197 OR ({$userenrolments}.timeend > 0 AND {$userenrolments}.timeend < {$time}) 198 OR ({$enrol}.status = " . ENROL_INSTANCE_DISABLED . ") 199 THEN " . status_field::STATUS_NOT_CURRENT . " 200 ELSE " . status_field::STATUS_ACTIVE . " 201 END 202 ELSE {$userenrolments}.status 203 END"; 204 } 205 206 /** 207 * Return list of all available filters 208 * 209 * @return filter[] 210 */ 211 protected function get_all_filters(): array { 212 $userenrolments = $this->get_table_alias('user_enrolments'); 213 $enrol = $this->get_table_alias('enrol'); 214 215 // Enrolment method. 216 $enrolmentmethods = static function(): array { 217 return array_map(static function(enrol_plugin $plugin): string { 218 return get_string('pluginname', 'enrol_' . $plugin->get_name()); 219 }, enrol_get_plugins(true)); 220 }; 221 $filters[] = (new filter( 222 select::class, 223 'method', 224 new lang_string('method', 'enrol'), 225 $this->get_entity_name(), 226 "{$enrol}.enrol" 227 )) 228 ->add_joins($this->get_joins()) 229 ->set_options_callback($enrolmentmethods); 230 231 // Enrolment time created. 232 $filters[] = (new filter( 233 date::class, 234 'timecreated', 235 new lang_string('timecreated', 'moodle'), 236 $this->get_entity_name(), 237 "{$userenrolments}.timecreated" 238 )) 239 ->add_joins($this->get_joins()) 240 ->set_limited_operators([ 241 date::DATE_ANY, 242 date::DATE_NOT_EMPTY, 243 date::DATE_EMPTY, 244 date::DATE_RANGE, 245 date::DATE_LAST, 246 date::DATE_CURRENT, 247 ]); 248 249 // Enrolment time started. 250 $filters[] = (new filter( 251 date::class, 252 'timestarted', 253 new lang_string('timestarted', 'enrol'), 254 $this->get_entity_name(), 255 "CASE WHEN {$userenrolments}.timestart = 0 256 THEN {$userenrolments}.timecreated 257 ELSE {$userenrolments}.timestart 258 END" 259 )) 260 ->add_joins($this->get_joins()) 261 ->set_limited_operators([ 262 date::DATE_ANY, 263 date::DATE_NOT_EMPTY, 264 date::DATE_EMPTY, 265 date::DATE_RANGE, 266 date::DATE_LAST, 267 date::DATE_CURRENT, 268 ]); 269 270 // Enrolment time ended. 271 $filters[] = (new filter( 272 date::class, 273 'timeended', 274 new lang_string('timeended', 'enrol'), 275 $this->get_entity_name(), 276 "{$userenrolments}.timeend" 277 )) 278 ->add_joins($this->get_joins()) 279 ->set_limited_operators([ 280 date::DATE_ANY, 281 date::DATE_NOT_EMPTY, 282 date::DATE_EMPTY, 283 date::DATE_RANGE, 284 date::DATE_LAST, 285 date::DATE_CURRENT, 286 ]); 287 288 // Enrolment status. 289 $filters[] = (new filter( 290 select::class, 291 'status', 292 new lang_string('status', 'moodle'), 293 $this->get_entity_name(), 294 $this->get_status_field_sql() 295 )) 296 ->add_joins($this->get_joins()) 297 ->set_options(enrolment_formatter::enrolment_values()); 298 299 return $filters; 300 } 301 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body