Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

Differences Between: [Versions 400 and 401] [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;
  20  
  21  use coding_exception;
  22  use core_reportbuilder\local\helpers\report;
  23  use core_reportbuilder\local\models\column as column_model;
  24  use core_reportbuilder\local\models\filter as filter_model;
  25  use core_reportbuilder\local\report\base;
  26  use core_reportbuilder\local\report\column;
  27  use core_reportbuilder\local\report\filter;
  28  
  29  /**
  30   * Class datasource
  31   *
  32   * @package   core_reportbuilder
  33   * @copyright 2021 David Matamoros <davidmc@moodle.com>
  34   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  abstract class datasource extends base {
  37  
  38      /**
  39       * Return user friendly name of the datasource
  40       *
  41       * @return string
  42       */
  43      abstract public static function get_name(): string;
  44  
  45      /**
  46       * Add columns from the given entity name to be available to use in a custom report
  47       *
  48       * @param string $entityname
  49       * @param array $include Include only these columns, if omitted then include all
  50       * @param array $exclude Exclude these columns, if omitted then exclude none
  51       * @throws coding_exception If both $include and $exclude are non-empty
  52       */
  53      final protected function add_columns_from_entity(string $entityname, array $include = [], array $exclude = []): void {
  54          if (!empty($include) && !empty($exclude)) {
  55              throw new coding_exception('Cannot specify columns to include and exclude simultaneously');
  56          }
  57  
  58          $entity = $this->get_entity($entityname);
  59  
  60          // Retrieve filtered columns from entity, respecting given $include/$exclude parameters.
  61          $columns = array_filter($entity->get_columns(), static function(column $column) use ($include, $exclude): bool {
  62              if (!empty($include)) {
  63                  return in_array($column->get_name(), $include);
  64              }
  65  
  66              if (!empty($exclude)) {
  67                  return !in_array($column->get_name(), $exclude);
  68              }
  69  
  70              return true;
  71          });
  72  
  73          foreach ($columns as $column) {
  74              $this->add_column($column);
  75          }
  76      }
  77  
  78      /**
  79       * Add default datasource columns to the report
  80       *
  81       * This method is optional and can be called when the report is created to add the default columns defined in the
  82       * selected datasource.
  83       */
  84      public function add_default_columns(): void {
  85          $reportid = $this->get_report_persistent()->get('id');
  86          $columnidentifiers = $this->get_default_columns();
  87          foreach ($columnidentifiers as $uniqueidentifier) {
  88              report::add_report_column($reportid, $uniqueidentifier);
  89          }
  90      }
  91  
  92      /**
  93       * Return the columns that will be added to the report once is created
  94       *
  95       * @return string[]
  96       */
  97      abstract public function get_default_columns(): array;
  98  
  99      /**
 100       * Return all configured report columns
 101       *
 102       * @return column[]
 103       */
 104      public function get_active_columns(): array {
 105          $columns = [];
 106  
 107          $activecolumns = column_model::get_records(['reportid' => $this->get_report_persistent()->get('id')], 'columnorder');
 108          foreach ($activecolumns as $index => $column) {
 109              $instance = $this->get_column($column->get('uniqueidentifier'));
 110              if ($instance !== null && $instance->get_is_available()) {
 111                  $instance->set_persistent($column);
 112  
 113                  // We should clone the report column to ensure if it's added twice to a report, each operates independently.
 114                  $columns[] = clone $instance
 115                      ->set_index($index)
 116                      ->set_aggregation($column->get('aggregation'));
 117              }
 118          }
 119  
 120          return $columns;
 121      }
 122  
 123      /**
 124       * Add filters from the given entity name to be available to use in a custom report
 125       *
 126       * @param string $entityname
 127       * @param array $include Include only these filters, if omitted then include all
 128       * @param array $exclude Exclude these filters, if omitted then exclude none
 129       * @throws coding_exception If both $include and $exclude are non-empty
 130       */
 131      final protected function add_filters_from_entity(string $entityname, array $include = [], array $exclude = []): void {
 132          if (!empty($include) && !empty($exclude)) {
 133              throw new coding_exception('Cannot specify filters to include and exclude simultaneously');
 134          }
 135  
 136          $entity = $this->get_entity($entityname);
 137  
 138          // Retrieve filtered filters from entity, respecting given $include/$exclude parameters.
 139          $filters = array_filter($entity->get_filters(), static function(filter $filter) use ($include, $exclude): bool {
 140              if (!empty($include)) {
 141                  return in_array($filter->get_name(), $include);
 142              }
 143  
 144              if (!empty($exclude)) {
 145                  return !in_array($filter->get_name(), $exclude);
 146              }
 147  
 148              return true;
 149          });
 150  
 151          foreach ($filters as $filter) {
 152              $this->add_filter($filter);
 153          }
 154      }
 155  
 156      /**
 157       * Add default datasource filters to the report
 158       *
 159       * This method is optional and can be called when the report is created to add the default filters defined in the
 160       * selected datasource.
 161       */
 162      public function add_default_filters(): void {
 163          $reportid = $this->get_report_persistent()->get('id');
 164          $filteridentifiers = $this->get_default_filters();
 165          foreach ($filteridentifiers as $uniqueidentifier) {
 166              report::add_report_filter($reportid, $uniqueidentifier);
 167          }
 168      }
 169  
 170      /**
 171       * Return the filters that will be added to the report once is created
 172       *
 173       * @return string[]
 174       */
 175      abstract public function get_default_filters(): array;
 176  
 177      /**
 178       * Return all configured report filters
 179       *
 180       * @return filter[]
 181       */
 182      public function get_active_filters(): array {
 183          $filters = [];
 184  
 185          $activefilters = filter_model::get_filter_records($this->get_report_persistent()->get('id'), 'filterorder');
 186          foreach ($activefilters as $filter) {
 187              $instance = $this->get_filter($filter->get('uniqueidentifier'));
 188              if ($instance !== null && $instance->get_is_available()) {
 189                  $filters[$instance->get_unique_identifier()] = $instance
 190                      ->set_persistent($filter);
 191              }
 192          }
 193  
 194          return $filters;
 195      }
 196  
 197      /**
 198       * Add conditions from the given entity name to be available to use in a custom report
 199       *
 200       * @param string $entityname
 201       * @param array $include Include only these conditions, if omitted then include all
 202       * @param array $exclude Exclude these conditions, if omitted then exclude none
 203       * @throws coding_exception If both $include and $exclude are non-empty
 204       */
 205      final protected function add_conditions_from_entity(string $entityname, array $include = [], array $exclude = []): void {
 206          if (!empty($include) && !empty($exclude)) {
 207              throw new coding_exception('Cannot specify conditions to include and exclude simultaneously');
 208          }
 209  
 210          $entity = $this->get_entity($entityname);
 211  
 212          // Retrieve filtered conditions from entity, respecting given $include/$exclude parameters.
 213          $conditions = array_filter($entity->get_conditions(), static function(filter $condition) use ($include, $exclude): bool {
 214              if (!empty($include)) {
 215                  return in_array($condition->get_name(), $include);
 216              }
 217  
 218              if (!empty($exclude)) {
 219                  return !in_array($condition->get_name(), $exclude);
 220              }
 221  
 222              return true;
 223          });
 224  
 225          foreach ($conditions as $condition) {
 226              $this->add_condition($condition);
 227          }
 228      }
 229  
 230      /**
 231       * Add default datasource conditions to the report
 232       *
 233       * This method is optional and can be called when the report is created to add the default conditions defined in the
 234       * selected datasource.
 235       */
 236      public function add_default_conditions(): void {
 237          $reportid = $this->get_report_persistent()->get('id');
 238          $conditionidentifiers = $this->get_default_conditions();
 239          foreach ($conditionidentifiers as $uniqueidentifier) {
 240              report::add_report_condition($reportid, $uniqueidentifier);
 241          }
 242      }
 243  
 244      /**
 245       * Return the conditions that will be added to the report once is created
 246       *
 247       * @return string[]
 248       */
 249      abstract public function get_default_conditions(): array;
 250  
 251      /**
 252       * Return all configured report conditions
 253       *
 254       * @return filter[]
 255       */
 256      public function get_active_conditions(): array {
 257          $conditions = [];
 258  
 259          $activeconditions = filter_model::get_condition_records($this->get_report_persistent()->get('id'), 'filterorder');
 260          foreach ($activeconditions as $condition) {
 261              $instance = $this->get_condition($condition->get('uniqueidentifier'));
 262              if ($instance !== null && $instance->get_is_available()) {
 263                  $conditions[$instance->get_unique_identifier()] = $instance->set_persistent($condition);
 264              }
 265          }
 266  
 267          return $conditions;
 268      }
 269  }