Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 401 and 402] [Versions 401 and 403]

   1  <?php
   2  
   3  // This file is part of Moodle - http://moodle.org/
   4  //
   5  // Moodle is free software: you can redistribute it and/or modify
   6  // it under the terms of the GNU General Public License as published by
   7  // the Free Software Foundation, either version 3 of the License, or
   8  // (at your option) any later version.
   9  //
  10  // Moodle is distributed in the hope that it will be useful,
  11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  // GNU General Public License for more details.
  14  //
  15  // You should have received a copy of the GNU General Public License
  16  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  17  
  18  /**
  19   * Output rendering for the plugin.
  20   *
  21   * @package     tool_task
  22   * @copyright   2014 Damyon Wiese
  23   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  use core\task\scheduled_task;
  29  
  30  
  31  /**
  32   * Implements the plugin renderer
  33   *
  34   * @copyright 2014 Damyon Wiese
  35   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class tool_task_renderer extends plugin_renderer_base {
  38      /**
  39       * This function will render one beautiful table with all the scheduled tasks.
  40       *
  41       * @param \core\task\scheduled_task[] $tasks - list of all scheduled tasks.
  42       * @param string $lastchanged (optional) the last task edited. Gets highlighted in teh table.
  43       * @return string HTML to output.
  44       */
  45      public function scheduled_tasks_table($tasks, $lastchanged = '') {
  46          global $CFG;
  47  
  48          $showloglink = \core\task\logmanager::has_log_report();
  49  
  50          $table = new html_table();
  51          $table->caption = get_string('scheduledtasks', 'tool_task');
  52          $table->head = [
  53              get_string('name'),
  54              get_string('component', 'tool_task'),
  55              get_string('edit'),
  56              get_string('logs'),
  57              get_string('lastruntime', 'tool_task'),
  58              get_string('nextruntime', 'tool_task'),
  59              get_string('taskscheduleminute', 'tool_task'),
  60              get_string('taskschedulehour', 'tool_task'),
  61              get_string('taskscheduleday', 'tool_task'),
  62              get_string('taskscheduledayofweek', 'tool_task'),
  63              get_string('taskschedulemonth', 'tool_task'),
  64              get_string('faildelay', 'tool_task'),
  65              get_string('default', 'tool_task'),
  66          ];
  67  
  68          $table->attributes['class'] = 'admintable generaltable';
  69          $table->colclasses = [];
  70  
  71          if (!$showloglink) {
  72              // Hide the log links.
  73              $table->colclasses['3'] = 'hidden';
  74          }
  75  
  76          $data = [];
  77          $yes = get_string('yes');
  78          $no = get_string('no');
  79          $canruntasks = \core\task\manager::is_runnable() && get_config('tool_task', 'enablerunnow');
  80          foreach ($tasks as $task) {
  81              $classname = get_class($task);
  82              $defaulttask = \core\task\manager::get_default_scheduled_task($classname, false);
  83  
  84              $customised = $task->is_customised() ? $no : $yes;
  85              if (empty($CFG->preventscheduledtaskchanges) && !$task->is_overridden()) {
  86                  $configureurl = new moodle_url('/admin/tool/task/scheduledtasks.php',
  87                          ['action' => 'edit', 'task' => $classname]);
  88                  $editlink = $this->output->action_icon($configureurl, new pix_icon('t/edit',
  89                          get_string('edittaskschedule', 'tool_task', $task->get_name())));
  90              } else {
  91                  $editlink = $this->render(new pix_icon('t/locked',
  92                          get_string('scheduledtaskchangesdisabled', 'tool_task')));
  93              }
  94  
  95              $loglink = '';
  96              if ($showloglink) {
  97                  $loglink = $this->output->action_icon(
  98                      \core\task\logmanager::get_url_for_task_class($classname),
  99                      new pix_icon('e/file-text', get_string('viewlogs', 'tool_task', $task->get_name())
 100                  ));
 101              }
 102  
 103              $namecellcontent = $task->get_name() . "\n" .
 104                  html_writer::span('\\' . $classname, 'task-class text-ltr');
 105              if ($task->is_overridden()) {
 106                  // Let the user know the scheduled task is defined in config.
 107                  $namecellcontent .= "\n" . html_writer::div(get_string('configoverride', 'admin'), 'alert-info');
 108              }
 109              $namecell = new html_table_cell($namecellcontent);
 110              $namecell->header = true;
 111              $namecell->id = scheduled_task::get_html_id($classname);
 112  
 113              $runnow = '';
 114              $canrunthistask = $canruntasks && $task->can_run();
 115              if ($canrunthistask) {
 116                  $runnow = html_writer::div(html_writer::link(
 117                          new moodle_url('/admin/tool/task/schedule_task.php',
 118                              ['task' => $classname]),
 119                          get_string('runnow', 'tool_task')), 'task-runnow');
 120              }
 121  
 122              $faildelaycell = new html_table_cell($task->get_fail_delay());
 123              if ($task->get_fail_delay()) {
 124                  $faildelaycell->text .= html_writer::div(html_writer::link(
 125                          new moodle_url('/admin/tool/task/clear_fail_delay.php',
 126                                  ['task' => $classname, 'sesskey' => sesskey()]),
 127                          get_string('clear')), 'task-clearfaildelay');
 128                  $faildelaycell->attributes['class'] = 'table-danger';
 129              }
 130  
 131              $row = new html_table_row([
 132                          $namecell,
 133                          new html_table_cell($this->component_name($task->get_component())),
 134                          new html_table_cell($editlink),
 135                          new html_table_cell($loglink),
 136                          new html_table_cell($this->last_run_time($task) . $runnow),
 137                          new html_table_cell($this->next_run_time($task)),
 138                          $this->time_cell($task->get_minute(), $defaulttask->get_minute()),
 139                          $this->time_cell($task->get_hour(), $defaulttask->get_hour()),
 140                          $this->time_cell($task->get_day(), $defaulttask->get_day()),
 141                          $this->time_cell($task->get_day_of_week(), $defaulttask->get_day_of_week()),
 142                          $this->time_cell($task->get_month(), $defaulttask->get_month()),
 143                          $faildelaycell,
 144                          new html_table_cell($customised)]);
 145  
 146              $classes = [];
 147              if (!$task->is_enabled()) {
 148                  $classes[] = 'disabled';
 149              }
 150              if (get_class($task) == $lastchanged) {
 151                  $classes[] = 'table-primary';
 152              }
 153              $row->attributes['class'] = implode(' ', $classes);
 154              $data[] = $row;
 155          }
 156          $table->data = $data;
 157          if ($lastchanged) {
 158              // IE does not support this, and the ancient version of Firefox we use for Behat
 159              // has the method, but then errors on 'centre'. So, just try to scroll, and if it fails, don't care.
 160              $this->page->requires->js_init_code(
 161                      'try{document.querySelector("tr.table-primary").scrollIntoView({block: "center"});}catch(e){}');
 162          }
 163          return html_writer::table($table);
 164      }
 165  
 166      /**
 167       * Nicely display the name of a component, with its disabled status and internal name.
 168       *
 169       * @param string $component component name, e.g. 'core' or 'mod_forum'.
 170       * @return string HTML.
 171       */
 172      public function component_name(string $component): string {
 173          list($type) = core_component::normalize_component($component);
 174          if ($type === 'core') {
 175              return get_string('corecomponent', 'tool_task');
 176          }
 177  
 178          $plugininfo = core_plugin_manager::instance()->get_plugin_info($component);
 179          if (!$plugininfo) {
 180              return $component;
 181          }
 182  
 183          $plugininfo->init_display_name();
 184  
 185          $componentname = $plugininfo->displayname;
 186          if ($plugininfo->is_enabled() === false) {
 187              $componentname .= ' ' . html_writer::span(
 188                              get_string('disabled', 'tool_task'), 'badge badge-secondary');
 189          }
 190          $componentname .= "\n" . html_writer::span($plugininfo->component, 'task-class text-ltr');
 191  
 192          return $componentname;
 193      }
 194  
 195      /**
 196       * Standard display of a tasks last run time.
 197       *
 198       * @param scheduled_task $task
 199       * @return string HTML.
 200       */
 201      public function last_run_time(scheduled_task $task): string {
 202          if ($task->get_last_run_time()) {
 203              return userdate($task->get_last_run_time());
 204          } else {
 205              return get_string('never');
 206          }
 207      }
 208  
 209      /**
 210       * Standard display of a tasks next run time.
 211       *
 212       * @param scheduled_task $task
 213       * @return string HTML.
 214       */
 215      public function next_run_time(scheduled_task $task): string {
 216          $nextrun = $task->get_next_run_time();
 217  
 218          if (!$task->is_component_enabled() && !$task->get_run_if_component_disabled()) {
 219              $nextrun = get_string('plugindisabled', 'tool_task');
 220          } else if ($task->get_disabled()) {
 221              $nextrun = get_string('taskdisabled', 'tool_task');
 222          } else if ($nextrun > time()) {
 223              $nextrun = userdate($nextrun);
 224          } else {
 225              $nextrun = get_string('asap', 'tool_task');
 226          }
 227  
 228          return $nextrun;
 229      }
 230  
 231      /**
 232       * Get a table cell to show one time, comparing it to the default.
 233       *
 234       * @param string $current the current setting.
 235       * @param string $default the default setting from the db/tasks.php file.
 236       * @return html_table_cell for use in the table.
 237       */
 238      protected function time_cell(string $current, string $default): html_table_cell {
 239          $cell = new html_table_cell($current);
 240          // Cron-style values must always be LTR.
 241          $cell->attributes['class'] = 'text-ltr';
 242  
 243          // If the current value is default, that is all we want to do.
 244          if ($default === '*') {
 245              if ($current === '*') {
 246                  return $cell;
 247              }
 248          } else if ($default === 'R' ) {
 249              if (is_numeric($current)) {
 250                  return $cell;
 251              }
 252          } else {
 253              if ($default === $current) {
 254                  return $cell;
 255              }
 256          }
 257  
 258          // Otherwise, highlight and show the default.
 259          $cell->attributes['class'] .= ' table-warning';
 260          $cell->text .= ' ' . html_writer::span(
 261                  get_string('defaultx', 'tool_task', $default), 'task-class');
 262          return $cell;
 263      }
 264  
 265      /**
 266       * Displays a warning on the page if cron is disabled.
 267       *
 268       * @return string HTML code for information about cron being disabled
 269       * @throws moodle_exception
 270       */
 271      public function cron_disabled(): string {
 272          return $this->output->notification(get_string('crondisabled', 'tool_task'), 'warning');
 273      }
 274  
 275      /**
 276       * Renders a link back to the scheduled tasks page (used from the 'run now' screen).
 277       *
 278       * @param string $taskclassname if specified, the list of tasks will scroll to show this task.
 279       * @return string HTML code
 280       */
 281      public function link_back($taskclassname = '') {
 282          $url = new moodle_url('/admin/tool/task/scheduledtasks.php');
 283          if ($taskclassname) {
 284              $url->param('lastchanged', $taskclassname);
 285          }
 286          return $this->render_from_template('tool_task/link_back', ['url' => $url]);
 287      }
 288  }