Differences Between: [Versions 400 and 402] [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\helpers; 20 21 use stdClass; 22 use invalid_parameter_exception; 23 use core\persistent; 24 use core_reportbuilder\datasource; 25 use core_reportbuilder\manager; 26 use core_reportbuilder\local\models\column; 27 use core_reportbuilder\local\models\filter; 28 use core_reportbuilder\local\models\report as report_model; 29 30 /** 31 * Helper class for manipulating custom reports and their elements (columns, filters, conditions, etc) 32 * 33 * @package core_reportbuilder 34 * @copyright 2021 Paul Holden <paulh@moodle.com> 35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 */ 37 class report { 38 39 /** 40 * Create custom report 41 * 42 * @param stdClass $data 43 * @param bool $default If $default is set to true it will populate report with default layout as defined by the selected 44 * source. These include pre-defined columns, filters and conditions. 45 * @return report_model 46 */ 47 public static function create_report(stdClass $data, bool $default = true): report_model { 48 $data->name = trim($data->name); 49 $data->type = datasource::TYPE_CUSTOM_REPORT; 50 51 $reportpersistent = manager::create_report_persistent($data); 52 53 // Add datasource default columns, filters and conditions to the report. 54 if ($default) { 55 $source = $reportpersistent->get('source'); 56 /** @var datasource $datasource */ 57 $datasource = new $source($reportpersistent, []); 58 $datasource->add_default_columns(); 59 $datasource->add_default_filters(); 60 $datasource->add_default_conditions(); 61 } 62 63 return $reportpersistent; 64 } 65 66 /** 67 * Update custom report 68 * 69 * @param stdClass $data 70 * @return report_model 71 */ 72 public static function update_report(stdClass $data): report_model { 73 $report = report_model::get_record(['id' => $data->id, 'type' => datasource::TYPE_CUSTOM_REPORT]); 74 if ($report === false) { 75 throw new invalid_parameter_exception('Invalid report'); 76 } 77 78 $report->set_many([ 79 'name' => trim($data->name), 80 'uniquerows' => $data->uniquerows, 81 ])->update(); 82 83 return $report; 84 } 85 86 /** 87 * Delete custom report 88 * 89 * @param int $reportid 90 * @return bool 91 * @throws invalid_parameter_exception 92 */ 93 public static function delete_report(int $reportid): bool { 94 $report = report_model::get_record(['id' => $reportid, 'type' => datasource::TYPE_CUSTOM_REPORT]); 95 if ($report === false) { 96 throw new invalid_parameter_exception('Invalid report'); 97 } 98 99 return $report->delete(); 100 } 101 102 /** 103 * Add given column to report 104 * 105 * @param int $reportid 106 * @param string $uniqueidentifier 107 * @return column 108 * @throws invalid_parameter_exception 109 */ 110 public static function add_report_column(int $reportid, string $uniqueidentifier): column { 111 $report = manager::get_report_from_id($reportid); 112 113 if (!array_key_exists($uniqueidentifier, $report->get_columns())) { 114 throw new invalid_parameter_exception('Invalid column'); 115 } 116 117 $column = new column(0, (object) [ 118 'reportid' => $reportid, 119 'uniqueidentifier' => $uniqueidentifier, 120 'columnorder' => column::get_max_columnorder($reportid, 'columnorder') + 1, 121 'sortorder' => column::get_max_columnorder($reportid, 'sortorder') + 1, 122 ]); 123 124 return $column->create(); 125 } 126 127 /** 128 * Delete given column from report 129 * 130 * @param int $reportid 131 * @param int $columnid 132 * @return bool 133 * @throws invalid_parameter_exception 134 */ 135 public static function delete_report_column(int $reportid, int $columnid): bool { 136 global $DB; 137 138 $column = column::get_record(['id' => $columnid, 'reportid' => $reportid]); 139 if ($column === false) { 140 throw new invalid_parameter_exception('Invalid column'); 141 } 142 143 // After deletion, re-index remaining report columns. 144 if ($result = $column->delete()) { 145 $sqlupdateorder = ' 146 UPDATE {' . column::TABLE . '} 147 SET columnorder = columnorder - 1 148 WHERE reportid = :reportid 149 AND columnorder > :columnorder'; 150 151 $DB->execute($sqlupdateorder, ['reportid' => $reportid, 'columnorder' => $column->get('columnorder')]); 152 } 153 154 return $result; 155 } 156 157 /** 158 * Re-order given column within a report 159 * 160 * @param int $reportid 161 * @param int $columnid 162 * @param int $position 163 * @return bool 164 * @throws invalid_parameter_exception 165 */ 166 public static function reorder_report_column(int $reportid, int $columnid, int $position): bool { 167 $column = column::get_record(['id' => $columnid, 'reportid' => $reportid]); 168 if ($column === false) { 169 throw new invalid_parameter_exception('Invalid column'); 170 } 171 172 // Get the rest of the report columns, excluding the one we are moving. 173 $columns = column::get_records_select('reportid = :reportid AND id <> :id', [ 174 'reportid' => $reportid, 175 'id' => $columnid, 176 ], 'columnorder'); 177 178 return static::reorder_persistents_by_field($column, $columns, $position, 'columnorder'); 179 } 180 181 /** 182 * Re-order given column sorting within a report 183 * 184 * @param int $reportid 185 * @param int $columnid 186 * @param int $position 187 * @return bool 188 * @throws invalid_parameter_exception 189 */ 190 public static function reorder_report_column_sorting(int $reportid, int $columnid, int $position): bool { 191 $column = column::get_record(['id' => $columnid, 'reportid' => $reportid]); 192 if ($column === false) { 193 throw new invalid_parameter_exception('Invalid column'); 194 } 195 196 // Get the rest of the report columns, excluding the one we are moving. 197 $columns = column::get_records_select('reportid = :reportid AND id <> :id', [ 198 'reportid' => $reportid, 199 'id' => $columnid, 200 ], 'sortorder'); 201 202 return static::reorder_persistents_by_field($column, $columns, $position, 'sortorder'); 203 } 204 205 /** 206 * Toggle sorting options for given column within a report 207 * 208 * @param int $reportid 209 * @param int $columnid 210 * @param bool $enabled 211 * @param int $direction 212 * @return bool 213 * @throws invalid_parameter_exception 214 */ 215 public static function toggle_report_column_sorting(int $reportid, int $columnid, bool $enabled, 216 int $direction = SORT_ASC): bool { 217 218 $column = column::get_record(['id' => $columnid, 'reportid' => $reportid]); 219 if ($column === false) { 220 throw new invalid_parameter_exception('Invalid column'); 221 } 222 223 return $column->set_many([ 224 'sortenabled' => $enabled, 225 'sortdirection' => $direction, 226 ])->update(); 227 } 228 229 /** 230 * Add given condition to report 231 * 232 * @param int $reportid 233 * @param string $uniqueidentifier 234 * @return filter 235 * @throws invalid_parameter_exception 236 */ 237 public static function add_report_condition(int $reportid, string $uniqueidentifier): filter { 238 $report = manager::get_report_from_id($reportid); 239 240 if (!array_key_exists($uniqueidentifier, $report->get_conditions())) { 241 throw new invalid_parameter_exception('Invalid condition'); 242 } 243 244 $condition = new filter(0, (object) [ 245 'reportid' => $reportid, 246 'uniqueidentifier' => $uniqueidentifier, 247 'iscondition' => true, 248 'filterorder' => filter::get_max_filterorder($reportid, true) + 1, 249 ]); 250 251 return $condition->create(); 252 } 253 254 /** 255 * Delete given condition from report 256 * 257 * @param int $reportid 258 * @param int $conditionid 259 * @return bool 260 * @throws invalid_parameter_exception 261 */ 262 public static function delete_report_condition(int $reportid, int $conditionid): bool { 263 global $DB; 264 265 $condition = filter::get_condition_record($reportid, $conditionid); 266 if ($condition === false) { 267 throw new invalid_parameter_exception('Invalid condition'); 268 } 269 270 // After deletion, re-index remaining report conditions. 271 if ($result = $condition->delete()) { 272 $sqlupdateorder = ' 273 UPDATE {' . filter::TABLE . '} 274 SET filterorder = filterorder - 1 275 WHERE reportid = :reportid 276 AND filterorder > :filterorder 277 AND iscondition = 1'; 278 279 $DB->execute($sqlupdateorder, ['reportid' => $reportid, 'filterorder' => $condition->get('filterorder')]); 280 } 281 282 return $result; 283 } 284 285 /** 286 * Re-order given condition within a report 287 * 288 * @param int $reportid 289 * @param int $conditionid 290 * @param int $position 291 * @return bool 292 * @throws invalid_parameter_exception 293 */ 294 public static function reorder_report_condition(int $reportid, int $conditionid, int $position): bool { 295 $condition = filter::get_condition_record($reportid, $conditionid); 296 if ($condition === false) { 297 throw new invalid_parameter_exception('Invalid condition'); 298 } 299 300 // Get the rest of the report conditions, excluding the one we are moving. 301 $conditions = filter::get_records_select('reportid = :reportid AND iscondition = 1 AND id <> :id', [ 302 'reportid' => $reportid, 303 'id' => $conditionid, 304 ], 'filterorder'); 305 306 return static::reorder_persistents_by_field($condition, $conditions, $position, 'filterorder'); 307 } 308 309 /** 310 * Add given filter to report 311 * 312 * @param int $reportid 313 * @param string $uniqueidentifier 314 * @return filter 315 * @throws invalid_parameter_exception 316 */ 317 public static function add_report_filter(int $reportid, string $uniqueidentifier): filter { 318 $report = manager::get_report_from_id($reportid); 319 320 $reportfilters = $report->get_filters(); 321 if (!array_key_exists($uniqueidentifier, $reportfilters)) { 322 throw new invalid_parameter_exception('Invalid filter'); 323 } 324 325 $filter = new filter(0, (object) [ 326 'reportid' => $reportid, 327 'uniqueidentifier' => $uniqueidentifier, 328 'filterorder' => filter::get_max_filterorder($reportid) + 1, 329 ]); 330 331 return $filter->create(); 332 } 333 334 /** 335 * Delete given filter from report 336 * 337 * @param int $reportid 338 * @param int $filterid 339 * @return bool 340 * @throws invalid_parameter_exception 341 */ 342 public static function delete_report_filter(int $reportid, int $filterid): bool { 343 global $DB; 344 345 $filter = filter::get_filter_record($reportid, $filterid); 346 if ($filter === false) { 347 throw new invalid_parameter_exception('Invalid filter'); 348 } 349 350 // After deletion, re-index remaining report filters. 351 if ($result = $filter->delete()) { 352 $sqlupdateorder = ' 353 UPDATE {' . filter::TABLE . '} 354 SET filterorder = filterorder - 1 355 WHERE reportid = :reportid 356 AND filterorder > :filterorder 357 AND iscondition = 0'; 358 359 $DB->execute($sqlupdateorder, ['reportid' => $reportid, 'filterorder' => $filter->get('filterorder')]); 360 } 361 362 return $result; 363 } 364 365 /** 366 * Re-order given filter within a report 367 * 368 * @param int $reportid 369 * @param int $filterid 370 * @param int $position 371 * @return bool 372 * @throws invalid_parameter_exception 373 */ 374 public static function reorder_report_filter(int $reportid, int $filterid, int $position): bool { 375 $filter = filter::get_filter_record($reportid, $filterid); 376 if ($filter === false) { 377 throw new invalid_parameter_exception('Invalid filter'); 378 } 379 380 // Get the rest of the report filters, excluding the one we are moving. 381 $filters = filter::get_records_select('reportid = :reportid AND iscondition = 0 AND id <> :id', [ 382 'reportid' => $reportid, 383 'id' => $filterid, 384 ], 'filterorder'); 385 386 return static::reorder_persistents_by_field($filter, $filters, $position, 'filterorder'); 387 } 388 389 /** 390 * Get available columns for a given report 391 * 392 * @param report_model $persistent 393 * @return array 394 * 395 * @deprecated since Moodle 4.1 - please do not use this function any more, {@see custom_report_column_cards_exporter} 396 */ 397 public static function get_available_columns(report_model $persistent) : array { 398 debugging('The function ' . __FUNCTION__ . '() is deprecated, please do not use it any more. ' . 399 'See \'custom_report_column_cards_exporter\' class for replacement', DEBUG_DEVELOPER); 400 401 $available = []; 402 403 $report = manager::get_report_from_persistent($persistent); 404 405 // Get current report columns. 406 foreach ($report->get_columns() as $column) { 407 $entityname = $column->get_entity_name(); 408 $entitytitle = $column->get_title(); 409 if (!array_key_exists($entityname, $available)) { 410 $available[$entityname] = [ 411 'name' => (string) $report->get_entity_title($entityname), 412 'key' => $entityname, 413 'items' => [], 414 ]; 415 } 416 417 $available[$entityname]['items'][] = [ 418 'name' => $entitytitle, 419 'identifier' => $column->get_unique_identifier(), 420 'title' => get_string('addcolumn', 'core_reportbuilder', $entitytitle), 421 'action' => 'report-add-column' 422 ]; 423 } 424 425 return array_values($available); 426 } 427 428 /** 429 * Helper method for re-ordering given persistents (columns, filters, etc) 430 * 431 * @param persistent $persistent The persistent we are moving 432 * @param persistent[] $persistents The rest of the persistents 433 * @param int $position 434 * @param string $field The field we need to update 435 * @return bool 436 */ 437 private static function reorder_persistents_by_field(persistent $persistent, array $persistents, int $position, 438 string $field): bool { 439 440 // Splice into new position. 441 array_splice($persistents, $position - 1, 0, [$persistent]); 442 443 $fieldorder = 1; 444 foreach ($persistents as $persistent) { 445 $persistent->set($field, $fieldorder++) 446 ->update(); 447 } 448 449 return true; 450 } 451 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body