Differences Between: [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_badges\reportbuilder\local\entities; 20 21 use context_course; 22 use context_helper; 23 use context_system; 24 use html_writer; 25 use lang_string; 26 use moodle_url; 27 use stdClass; 28 use core_reportbuilder\local\entities\base; 29 use core_reportbuilder\local\filters\{select, text}; 30 use core_reportbuilder\local\report\{column, filter}; 31 32 defined('MOODLE_INTERNAL') or die; 33 34 global $CFG; 35 require_once("{$CFG->libdir}/badgeslib.php"); 36 37 /** 38 * Badge entity 39 * 40 * @package core_badges 41 * @copyright 2022 Paul Holden <paulh@moodle.com> 42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 43 */ 44 class badge extends base { 45 46 /** 47 * Database tables that this entity uses and their default aliases 48 * 49 * @return array 50 */ 51 protected function get_default_table_aliases(): array { 52 return [ 53 'badge' => 'b', 54 'context' => 'bctx', 55 'tag_instance' => 'bti', 56 'tag' => 'bt', 57 ]; 58 } 59 60 /** 61 * The default title for this entity 62 * 63 * @return lang_string 64 */ 65 protected function get_default_entity_title(): lang_string { 66 return new lang_string('badgedetails', 'core_badges'); 67 } 68 69 /** 70 * Initialise the entity 71 * 72 * @return base 73 */ 74 public function initialise(): base { 75 $columns = $this->get_all_columns(); 76 foreach ($columns as $column) { 77 $this->add_column($column); 78 } 79 80 // All the filters defined by the entity can also be used as conditions. 81 $filters = $this->get_all_filters(); 82 foreach ($filters as $filter) { 83 $this 84 ->add_filter($filter) 85 ->add_condition($filter); 86 } 87 88 return $this; 89 } 90 91 /** 92 * Returns list of all available columns 93 * 94 * @return column[] 95 */ 96 protected function get_all_columns(): array { 97 global $DB; 98 99 $badgealias = $this->get_table_alias('badge'); 100 $contextalias = $this->get_table_alias('context'); 101 102 // Name. 103 $columns[] = (new column( 104 'name', 105 new lang_string('name'), 106 $this->get_entity_name() 107 )) 108 ->add_joins($this->get_joins()) 109 ->set_type(column::TYPE_TEXT) 110 ->add_field("{$badgealias}.name") 111 ->set_is_sortable(true); 112 113 // Name with link. 114 $columns[] = (new column( 115 'namewithlink', 116 new lang_string('namewithlink', 'core_badges'), 117 $this->get_entity_name() 118 )) 119 ->add_joins($this->get_joins()) 120 ->set_type(column::TYPE_TEXT) 121 ->add_fields("{$badgealias}.name, {$badgealias}.id") 122 ->set_is_sortable(true) 123 ->add_callback(static function(?string $value, stdClass $row): string { 124 if (!$row->id) { 125 return ''; 126 } 127 128 $url = new moodle_url('/badges/overview.php', ['id' => $row->id]); 129 return html_writer::link($url, $row->name); 130 }); 131 132 // Description (note, this column contains plaintext so requires no post-processing). 133 $descriptionfieldsql = "{$badgealias}.description"; 134 if ($DB->get_dbfamily() === 'oracle') { 135 $descriptionfieldsql = $DB->sql_order_by_text($descriptionfieldsql, 1024); 136 } 137 $columns[] = (new column( 138 'description', 139 new lang_string('description', 'core_badges'), 140 $this->get_entity_name() 141 )) 142 ->add_joins($this->get_joins()) 143 ->set_type(column::TYPE_LONGTEXT) 144 ->add_field($descriptionfieldsql, 'description'); 145 146 // Criteria. 147 $columns[] = (new column( 148 'criteria', 149 new lang_string('bcriteria', 'core_badges'), 150 $this->get_entity_name() 151 )) 152 ->add_joins($this->get_joins()) 153 ->set_type(column::TYPE_TEXT) 154 ->add_field("{$badgealias}.id") 155 ->set_disabled_aggregation_all() 156 ->add_callback(static function($badgeid): string { 157 global $PAGE; 158 if (!$badgeid) { 159 return ''; 160 } 161 $badge = new \core_badges\badge($badgeid); 162 163 $renderer = $PAGE->get_renderer('core_badges'); 164 return $renderer->print_badge_criteria($badge, 'short'); 165 }); 166 167 // Image. 168 $columns[] = (new column( 169 'image', 170 new lang_string('badgeimage', 'core_badges'), 171 $this->get_entity_name() 172 )) 173 ->add_joins($this->get_joins()) 174 ->add_join("LEFT JOIN {context} {$contextalias} 175 ON {$contextalias}.contextlevel = " . CONTEXT_COURSE . " 176 AND {$contextalias}.instanceid = {$badgealias}.courseid") 177 ->set_type(column::TYPE_INTEGER) 178 ->add_fields("{$badgealias}.id, {$badgealias}.type, {$badgealias}.courseid") 179 ->add_field($DB->sql_cast_to_char("{$badgealias}.imagecaption"), 'imagecaption') 180 ->add_fields(context_helper::get_preload_record_columns_sql($contextalias)) 181 ->set_disabled_aggregation_all() 182 ->add_callback(static function(?int $badgeid, stdClass $badge): string { 183 if (!$badgeid) { 184 return ''; 185 } 186 if ($badge->type == BADGE_TYPE_SITE) { 187 $context = context_system::instance(); 188 } else { 189 context_helper::preload_from_record($badge); 190 $context = context_course::instance($badge->courseid); 191 } 192 193 $badgeimage = moodle_url::make_pluginfile_url($context->id, 'badges', 'badgeimage', $badgeid, '/', 'f2'); 194 return html_writer::img($badgeimage, $badge->imagecaption); 195 }); 196 197 // Language. 198 $columns[] = (new column( 199 'language', 200 new lang_string('language'), 201 $this->get_entity_name() 202 )) 203 ->add_joins($this->get_joins()) 204 ->set_type(column::TYPE_TEXT) 205 ->add_field("{$badgealias}.language") 206 ->set_is_sortable(true) 207 ->add_callback(static function($language): string { 208 $languages = get_string_manager()->get_list_of_languages(); 209 return $languages[$language] ?? $language ?? ''; 210 }); 211 212 // Version. 213 $columns[] = (new column( 214 'version', 215 new lang_string('version', 'core_badges'), 216 $this->get_entity_name() 217 )) 218 ->add_joins($this->get_joins()) 219 ->set_type(column::TYPE_TEXT) 220 ->add_field("{$badgealias}.version") 221 ->set_is_sortable(true); 222 223 // Status. 224 $columns[] = (new column( 225 'status', 226 new lang_string('status', 'core_badges'), 227 $this->get_entity_name() 228 )) 229 ->add_joins($this->get_joins()) 230 ->set_type(column::TYPE_TEXT) 231 ->add_field("{$badgealias}.status") 232 ->set_is_sortable(true) 233 ->add_callback(static function($status): string { 234 if ($status === null) { 235 return ''; 236 } 237 238 return get_string("badgestatus_{$status}", 'core_badges'); 239 }); 240 241 // Expiry date/period. 242 $columns[] = (new column( 243 'expiry', 244 new lang_string('expirydate', 'core_badges'), 245 $this->get_entity_name() 246 )) 247 ->add_joins($this->get_joins()) 248 ->set_type(column::TYPE_TIMESTAMP) 249 ->add_fields("{$badgealias}.expiredate, {$badgealias}.expireperiod, {$badgealias}.id") 250 ->set_is_sortable(true, ["{$badgealias}.expiredate", "{$badgealias}.expireperiod"]) 251 ->set_disabled_aggregation_all() 252 ->add_callback(static function(?int $expiredate, stdClass $badge): string { 253 if (!$badge->id) { 254 return ''; 255 } else if ($expiredate) { 256 return userdate($expiredate); 257 } else if ($badge->expireperiod) { 258 return format_time($badge->expireperiod); 259 } else { 260 return get_string('never', 'core_badges'); 261 } 262 }); 263 264 // Image author details. 265 foreach (['imageauthorname', 'imageauthoremail', 'imageauthorurl'] as $imageauthorfield) { 266 $columns[] = (new column( 267 $imageauthorfield, 268 new lang_string($imageauthorfield, 'core_badges'), 269 $this->get_entity_name() 270 )) 271 ->add_joins($this->get_joins()) 272 ->set_type(column::TYPE_TEXT) 273 ->add_field("{$badgealias}.{$imageauthorfield}") 274 ->set_is_sortable(true); 275 } 276 277 return $columns; 278 } 279 280 /** 281 * Return list of all available filters 282 * 283 * @return filter[] 284 */ 285 protected function get_all_filters(): array { 286 $badgealias = $this->get_table_alias('badge'); 287 288 // Name. 289 $filters[] = (new filter( 290 text::class, 291 'name', 292 new lang_string('name'), 293 $this->get_entity_name(), 294 "{$badgealias}.name" 295 )) 296 ->add_joins($this->get_joins()); 297 298 // Status. 299 $filters[] = (new filter( 300 select::class, 301 'status', 302 new lang_string('status', 'core_badges'), 303 $this->get_entity_name(), 304 "{$badgealias}.status" 305 )) 306 ->add_joins($this->get_joins()) 307 ->set_options([ 308 BADGE_STATUS_INACTIVE => new lang_string('badgestatus_0', 'core_badges'), 309 BADGE_STATUS_ACTIVE => new lang_string('badgestatus_1', 'core_badges'), 310 BADGE_STATUS_INACTIVE_LOCKED => new lang_string('badgestatus_2', 'core_badges'), 311 BADGE_STATUS_ACTIVE_LOCKED => new lang_string('badgestatus_3', 'core_badges'), 312 BADGE_STATUS_ARCHIVED => new lang_string('badgestatus_4', 'core_badges'), 313 ]); 314 315 // Type. 316 $filters[] = (new filter( 317 select::class, 318 'type', 319 new lang_string('type', 'core_badges'), 320 $this->get_entity_name(), 321 "{$badgealias}.type" 322 )) 323 ->add_joins($this->get_joins()) 324 ->set_options([ 325 BADGE_TYPE_SITE => new lang_string('site'), 326 BADGE_TYPE_COURSE => new lang_string('course'), 327 ]); 328 329 return $filters; 330 } 331 332 /** 333 * Return joins necessary for retrieving tags 334 * 335 * @return string[] 336 */ 337 public function get_tag_joins(): array { 338 return $this->get_tag_joins_for_entity('core_badges', 'badge', $this->get_table_alias('badge') . '.id'); 339 } 340 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body