Differences Between: [Versions 400 and 402] [Versions 400 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\audiences; 20 21 use core_plugin_manager; 22 use MoodleQuickForm; 23 use stdClass; 24 use core\output\notification; 25 use core_reportbuilder\local\models\audience; 26 use core_reportbuilder\report_access_exception; 27 28 /** 29 * Audience base class 30 * 31 * @package core_reportbuilder 32 * @copyright 2021 David Matamoros <davidmc@moodle.com> 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 abstract class base { 36 37 /** @var int Maximim number of multi-select elements to show in description, before appending "plus X more" */ 38 private const MULTI_SELECT_LIMIT = 5; 39 40 /** @var audience The persistent object associated with this audience */ 41 protected $audience; 42 43 /** 44 * Protected constructor, please use the static instance method. 45 */ 46 protected function __construct() { 47 } 48 49 /** 50 * Loads an existing instance of audience with persistent 51 * 52 * @param int $id 53 * @param null|stdClass $record 54 * @return self|null 55 */ 56 final public static function instance(int $id = 0, ?stdClass $record = null): ?self { 57 $persistent = new audience($id, $record); 58 // Needed for get_audience_types() method. 59 if (!$classname = $persistent->get('classname')) { 60 // Use the called class name. 61 $classname = get_called_class(); 62 $persistent->set('classname', $classname); 63 } 64 65 // Check if audience type class still exists in the system. 66 if (!class_exists($classname)) { 67 return null; 68 } 69 70 $instance = new $classname(); 71 $instance->audience = $persistent; 72 return $instance; 73 } 74 75 /** 76 * Creates a new audience and saves it to database 77 * 78 * @param int $reportid 79 * @param array $configdata 80 * @return self 81 */ 82 final public static function create(int $reportid, array $configdata): self { 83 $record = new stdClass(); 84 $record->reportid = $reportid; 85 $record->classname = get_called_class(); 86 $record->configdata = json_encode($configdata); 87 $instance = self::instance(0, $record); 88 $instance->audience->save(); 89 return $instance; 90 } 91 92 /** 93 * Helps to build SQL to retrieve users that matches the current audience 94 * 95 * Implementations must use api::generate_alias() for table/column aliases 96 * and api::generate_param_name() for named parameters 97 * 98 * @param string $usertablealias 99 * @return array array of three elements [$join, $where, $params] 100 */ 101 abstract public function get_sql(string $usertablealias): array; 102 103 /** 104 * Returns string for audience category. 105 * 106 * @return string 107 */ 108 final public function get_category(): string { 109 [$component] = explode('\\', get_class($this)); 110 111 if ($plugininfo = core_plugin_manager::instance()->get_plugin_info($component)) { 112 return $plugininfo->displayname; 113 } 114 115 return get_string('site'); 116 } 117 118 /** 119 * If the current user is able to add this audience type 120 * 121 * @return bool 122 */ 123 abstract public function user_can_add(): bool; 124 125 /** 126 * If the current user is able to edit this audience type 127 * 128 * @return bool 129 */ 130 abstract public function user_can_edit(): bool; 131 132 /** 133 * If the current user is able to use this audience type 134 * 135 * This method needs to return true if audience type is available to user for 136 * reasons other than permission check, which is done in {@see user_can_add}. 137 * (e.g. user can add cohort audience type only if there is at least one cohort 138 * they can access). 139 * 140 * @return bool 141 */ 142 public function is_available(): bool { 143 return true; 144 } 145 146 /** 147 * Return user friendly name of the audience type 148 * 149 * @return string 150 */ 151 abstract public function get_name(): string; 152 153 /** 154 * Return the description of this audience type 155 * 156 * @return string 157 */ 158 abstract public function get_description(): string; 159 160 /** 161 * Helper to format descriptions for audience types that may contain many selected elements, limiting number show according 162 * to {@see MULTI_SELECT_LIMIT} constant value 163 * 164 * @param array $elements 165 * @return string 166 */ 167 protected function format_description_for_multiselect(array $elements): string { 168 global $OUTPUT; 169 170 // Warn user if there are no elements (because they may no longer exist). 171 $elementcount = count($elements); 172 if ($elementcount === 0) { 173 $notification = new notification(get_string('nothingtodisplay'), notification::NOTIFY_WARNING); 174 return $OUTPUT->render($notification); 175 } 176 177 $listseparator = get_string('listsep', 'langconfig') . ' '; 178 if ($elementcount > self::MULTI_SELECT_LIMIT) { 179 $elements = array_slice($elements, 0, self::MULTI_SELECT_LIMIT); 180 181 // Append overflow element. 182 $elementoverflow = $elementcount - self::MULTI_SELECT_LIMIT; 183 $params = [ 184 'elements' => implode($listseparator, $elements), 185 'morecount' => $elementoverflow, 186 ]; 187 $description = get_string('audiencemultiselectpostfix', 'core_reportbuilder', $params); 188 } else { 189 $description = implode($listseparator, $elements); 190 } 191 192 return $description; 193 } 194 195 /** 196 * Adds audience-specific form elements 197 * 198 * @param MoodleQuickForm $mform The form to add elements to 199 */ 200 abstract public function get_config_form(MoodleQuickForm $mform): void; 201 202 /** 203 * Validates the configform of the condition. 204 * 205 * @param array $data Data from the form 206 * @return array Array with errors for each element 207 */ 208 public function validate_config_form(array $data): array { 209 return []; 210 } 211 212 /** 213 * Returns configdata as an associative array 214 * 215 * @return array decoded configdata 216 */ 217 final public function get_configdata(): array { 218 return json_decode($this->audience->get('configdata'), true); 219 } 220 221 /** 222 * Update configdata in audience persistent 223 * 224 * @param array $configdata 225 */ 226 final public function update_configdata(array $configdata): void { 227 $this->audience->set('configdata', json_encode($configdata)); 228 $this->audience->save(); 229 } 230 231 /** 232 * Returns $configdata from form data suitable for use in DB record. 233 * 234 * @param stdClass $data data obtained from $mform->get_data() 235 * @return array $configdata 236 */ 237 final public static function retrieve_configdata(stdClass $data): array { 238 $configdata = (array) $data; 239 $invalidkeys = array_fill_keys(['id', 'reportid', 'classname'], ''); 240 return array_diff_key($configdata, $invalidkeys); 241 } 242 243 /** 244 * Return audience persistent. 245 * 246 * @return audience 247 */ 248 public function get_persistent(): audience { 249 return $this->audience; 250 } 251 252 /** 253 * Require current user is able to add this audience type 254 * 255 * @throws report_access_exception 256 */ 257 final public function require_user_can_add(): void { 258 if (!$this->user_can_add()) { 259 throw new report_access_exception('errorreportedit'); 260 } 261 } 262 263 /** 264 * Require current user is able to edit this audience type 265 * 266 * @throws report_access_exception 267 */ 268 final public function require_user_can_edit(): void { 269 if (!$this->user_can_edit()) { 270 throw new report_access_exception('errorreportedit'); 271 } 272 } 273 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body