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\local\systemreports;
  20  
  21  use context;
  22  use lang_string;
  23  use moodle_url;
  24  use pix_icon;
  25  use stdClass;
  26  use core_reportbuilder\permission;
  27  use core_reportbuilder\system_report;
  28  use core_reportbuilder\local\entities\user;
  29  use core_reportbuilder\local\filters\date;
  30  use core_reportbuilder\local\filters\text;
  31  use core_reportbuilder\local\helpers\format;
  32  use core_reportbuilder\local\helpers\schedule as helper;
  33  use core_reportbuilder\local\models\report;
  34  use core_reportbuilder\local\models\schedule;
  35  use core_reportbuilder\local\report\action;
  36  use core_reportbuilder\local\report\column;
  37  use core_reportbuilder\local\report\filter;
  38  use core_reportbuilder\output\schedule_name_editable;
  39  
  40  /**
  41   * Report schedules list
  42   *
  43   * @package     core_reportbuilder
  44   * @copyright   2021 Paul Holden <paulh@moodle.com>
  45   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  46   */
  47  class report_schedules extends system_report {
  48  
  49      /**
  50       * The name of our internal report entity
  51       *
  52       * @return string
  53       */
  54      private function get_schedule_entity_name(): string {
  55          return 'schedule';
  56      }
  57  
  58      /**
  59       * Initialise the report
  60       */
  61      protected function initialise(): void {
  62          $this->set_main_table(schedule::TABLE, 'sc');
  63          $this->add_join('JOIN {' . report::TABLE . '} rb ON rb.id = sc.reportid');
  64  
  65          $this->add_base_condition_simple('sc.reportid', $this->get_parameter('reportid', 0, PARAM_INT));
  66  
  67          // Select fields required for actions, permission checks, and row class callbacks.
  68          $this->add_base_fields('sc.id, sc.name, sc.enabled, rb.contextid');
  69  
  70          // Join user entity for "User modified" column.
  71          $entityuser = new user();
  72          $entityuseralias = $entityuser->get_table_alias('user');
  73  
  74          $this->add_entity($entityuser
  75              ->add_join("JOIN {user} {$entityuseralias} ON {$entityuseralias}.id = sc.usermodified")
  76          );
  77  
  78          // Define our internal entity for schedule elements.
  79          $this->annotate_entity($this->get_schedule_entity_name(),
  80              new lang_string('schedules', 'core_reportbuilder'));
  81  
  82          $this->add_columns();
  83          $this->add_filters();
  84          $this->add_actions();
  85  
  86          $this->set_downloadable(false);
  87      }
  88  
  89      /**
  90       * Ensure we can view the report
  91       *
  92       * @return bool
  93       */
  94      protected function can_view(): bool {
  95          return permission::can_view_reports_list();
  96      }
  97  
  98      /**
  99       * Dim the table row for disabled schedules
 100       *
 101       * @param stdClass $row
 102       * @return string
 103       */
 104      public function get_row_class(stdClass $row): string {
 105          return $row->enabled ? '' : 'text-muted';
 106      }
 107  
 108      /**
 109       * Add columns to report
 110       */
 111      protected function add_columns(): void {
 112          $tablealias = $this->get_main_table_alias();
 113  
 114          // Enable toggle column.
 115          $this->add_column((new column(
 116              'enabled',
 117              null,
 118              $this->get_schedule_entity_name()
 119          ))
 120              ->set_type(column::TYPE_BOOLEAN)
 121              ->add_fields("{$tablealias}.enabled, {$tablealias}.id")
 122              ->set_is_sortable(false)
 123              ->set_callback(static function(bool $enabled, stdClass $row): string {
 124                  global $PAGE;
 125  
 126                  $renderer = $PAGE->get_renderer('core_reportbuilder');
 127                  $attributes = [
 128                      ['name' => 'id', 'value' => $row->id],
 129                      ['name' => 'action', 'value' => 'schedule-toggle'],
 130                      ['name' => 'state', 'value' => $row->enabled],
 131                  ];
 132                  $label = $row->enabled ? get_string('disableschedule', 'core_reportbuilder')
 133                      : get_string('enableschedule', 'core_reportbuilder');
 134                  return $renderer->render_from_template('core/toggle', [
 135                      'id' => 'schedule-toggle-' . $row->id,
 136                      'checked' => $row->enabled,
 137                      'dataattributes' => $attributes,
 138                      'label' => $label,
 139                      'labelclasses' => 'sr-only'
 140                  ]);
 141              })
 142          );
 143  
 144          // Report name column.
 145          $this->add_column((new column(
 146              'name',
 147              new lang_string('name'),
 148              $this->get_schedule_entity_name()
 149          ))
 150              ->set_type(column::TYPE_TEXT)
 151              ->add_fields("{$tablealias}.name, {$tablealias}.id")
 152              ->set_is_sortable(true)
 153              ->add_callback(function(string $value, stdClass $schedule): string {
 154                  global $PAGE;
 155  
 156                  $editable = new schedule_name_editable((int) $schedule->id);
 157                  return $editable->render($PAGE->get_renderer('core'));
 158              })
 159          );
 160  
 161          // Time scheduled column.
 162          $this->add_column((new column(
 163              'timescheduled',
 164              new lang_string('startingfrom'),
 165              $this->get_schedule_entity_name()
 166          ))
 167              ->set_type(column::TYPE_TIMESTAMP)
 168              ->add_fields("{$tablealias}.timescheduled")
 169              ->set_is_sortable(true)
 170              ->add_callback([format::class, 'userdate'])
 171          );
 172  
 173          // Time last sent column.
 174          $this->add_column((new column(
 175              'timelastsent',
 176              new lang_string('timelastsent', 'core_reportbuilder'),
 177              $this->get_schedule_entity_name()
 178          ))
 179              ->set_type(column::TYPE_TIMESTAMP)
 180              ->add_fields("{$tablealias}.timelastsent")
 181              ->set_is_sortable(true)
 182              ->add_callback(static function(int $timelastsent, stdClass $row): string {
 183                  if ($timelastsent === 0) {
 184                      return get_string('never');
 185                  }
 186  
 187                  return format::userdate($timelastsent, $row);
 188              })
 189          );
 190  
 191          // Format column.
 192          $this->add_column((new column(
 193              'format',
 194              new lang_string('format'),
 195              $this->get_schedule_entity_name()
 196          ))
 197              ->set_type(column::TYPE_TEXT)
 198              ->add_fields("{$tablealias}.format")
 199              ->set_is_sortable(true)
 200              ->add_callback(static function(string $format): string {
 201                  $formats = helper::get_format_options();
 202                  return $formats[$format] ?? '';
 203              })
 204          );
 205  
 206          // Time created column.
 207          $this->add_column((new column(
 208              'timecreated',
 209              new lang_string('timecreated', 'core_reportbuilder'),
 210              $this->get_schedule_entity_name()
 211          ))
 212              ->set_type(column::TYPE_TIMESTAMP)
 213              ->add_fields("{$tablealias}.timecreated")
 214              ->set_is_sortable(true)
 215              ->add_callback([format::class, 'userdate'])
 216          );
 217  
 218          // Time modified column.
 219          $this->add_column((new column(
 220              'timemodified',
 221              new lang_string('timemodified', 'core_reportbuilder'),
 222              $this->get_schedule_entity_name()
 223          ))
 224              ->set_type(column::TYPE_TIMESTAMP)
 225              ->add_fields("{$tablealias}.timemodified")
 226              ->set_is_sortable(true)
 227              ->add_callback([format::class, 'userdate'])
 228          );
 229  
 230          // The user who modified the schedule.
 231          $this->add_column_from_entity('user:fullname')
 232              ->set_title(new lang_string('usermodified', 'core_reportbuilder'));
 233  
 234          // Initial sorting.
 235          $this->set_initial_sort_column('schedule:timecreated', SORT_DESC);
 236      }
 237  
 238      /**
 239       * Add filters to report
 240       */
 241      protected function add_filters(): void {
 242          $tablealias = $this->get_main_table_alias();
 243  
 244          // Name filter.
 245          $this->add_filter((new filter(
 246              text::class,
 247              'name',
 248              new lang_string('name'),
 249              $this->get_schedule_entity_name(),
 250              "{$tablealias}.name"
 251          )));
 252  
 253          // Time created filter.
 254          $this->add_filter((new filter(
 255              date::class,
 256              'timelastsent',
 257              new lang_string('timelastsent', 'core_reportbuilder'),
 258              $this->get_schedule_entity_name(),
 259              "{$tablealias}.timelastsent"
 260          ))
 261              ->set_limited_operators([
 262                  date::DATE_ANY,
 263                  date::DATE_EMPTY,
 264                  date::DATE_RANGE,
 265                  date::DATE_PREVIOUS,
 266                  date::DATE_CURRENT,
 267              ])
 268          );
 269  
 270      }
 271  
 272      /**
 273       * Add actions to report
 274       */
 275      protected function add_actions(): void {
 276          // Edit action.
 277          $this->add_action(new action(
 278              new moodle_url('#'),
 279              new pix_icon('t/edit', ''),
 280              ['data-action' => 'schedule-edit', 'data-schedule-id' => ':id'],
 281              false,
 282              new lang_string('editscheduledetails', 'core_reportbuilder')
 283          ));
 284  
 285          // Send now action.
 286          $this->add_action((new action(
 287              new moodle_url('#'),
 288              new pix_icon('t/email', ''),
 289              ['data-action' => 'schedule-send', 'data-schedule-id' => ':id', 'data-schedule-name' => ':name'],
 290              false,
 291              new lang_string('sendschedule', 'core_reportbuilder')
 292          ))
 293              ->add_callback(function(stdClass $row): bool {
 294  
 295                  // Ensure data name attribute is properly formatted.
 296                  $row->name = (new schedule(0, $row))->get_formatted_name(
 297                      context::instance_by_id($row->contextid));
 298  
 299                  return true;
 300              })
 301          );
 302  
 303          // Delete action.
 304          $this->add_action((new action(
 305              new moodle_url('#'),
 306              new pix_icon('t/delete', ''),
 307              ['data-action' => 'schedule-delete', 'data-schedule-id' => ':id', 'data-schedule-name' => ':name'],
 308              false,
 309              new lang_string('deleteschedule', 'core_reportbuilder')
 310          ))
 311              ->add_callback(function(stdClass $row): bool {
 312  
 313                  // Ensure data name attribute is properly formatted.
 314                  $row->name = (new schedule(0, $row))->get_formatted_name(
 315                      context::instance_by_id($row->contextid));
 316  
 317                  return true;
 318              })
 319          );
 320      }
 321  }