Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

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

   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();
  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)) {
  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              $namecell = new html_table_cell($task->get_name() . "\n" .
 104                      html_writer::span('\\' . $classname, 'task-class text-ltr'));
 105              $namecell->header = true;
 106  
 107              $plugininfo = core_plugin_manager::instance()->get_plugin_info($task->get_component());
 108              $plugindisabled = $plugininfo && $plugininfo->is_enabled() === false &&
 109                      !$task->get_run_if_component_disabled();
 110              $disabled = $plugindisabled || $task->get_disabled();
 111  
 112              $runnow = '';
 113              if (!$disabled && get_config('tool_task', 'enablerunnow') && $canruntasks ) {
 114                  $runnow = html_writer::div(html_writer::link(
 115                          new moodle_url('/admin/tool/task/schedule_task.php',
 116                              ['task' => $classname]),
 117                          get_string('runnow', 'tool_task')), 'task-runnow');
 118              }
 119  
 120              $faildelaycell = new html_table_cell($task->get_fail_delay());
 121              if ($task->get_fail_delay()) {
 122                  $faildelaycell->text .= html_writer::div(html_writer::link(
 123                          new moodle_url('/admin/tool/task/clear_fail_delay.php',
 124                                  ['task' => $classname, 'sesskey' => sesskey()]),
 125                          get_string('clear')), 'task-clearfaildelay');
 126                  $faildelaycell->attributes['class'] = 'table-danger';
 127              }
 128  
 129              $row = new html_table_row([
 130                          $namecell,
 131                          new html_table_cell($this->component_name($task->get_component())),
 132                          new html_table_cell($editlink),
 133                          new html_table_cell($loglink),
 134                          new html_table_cell($this->last_run_time($task) . $runnow),
 135                          new html_table_cell($this->next_run_time($task)),
 136                          $this->time_cell($task->get_minute(), $defaulttask->get_minute()),
 137                          $this->time_cell($task->get_hour(), $defaulttask->get_hour()),
 138                          $this->time_cell($task->get_day(), $defaulttask->get_day()),
 139                          $this->time_cell($task->get_day_of_week(), $defaulttask->get_day_of_week()),
 140                          $this->time_cell($task->get_month(), $defaulttask->get_month()),
 141                          $faildelaycell,
 142                          new html_table_cell($customised)]);
 143  
 144              $classes = [];
 145              if ($disabled) {
 146                  $classes[] = 'disabled';
 147              }
 148              if (get_class($task) == $lastchanged) {
 149                  $classes[] = 'table-primary';
 150              }
 151              $row->attributes['class'] = implode(' ', $classes);
 152              $data[] = $row;
 153          }
 154          $table->data = $data;
 155          if ($lastchanged) {
 156              // IE does not support this, and the ancient version of Firefox we use for Behat
 157              // has the method, but then errors on 'centre'. So, just try to scroll, and if it fails, don't care.
 158              $this->page->requires->js_init_code(
 159                      'try{document.querySelector("tr.table-primary").scrollIntoView({block: "center"});}catch(e){}');
 160          }
 161          return html_writer::table($table);
 162      }
 163  
 164      /**
 165       * Nicely display the name of a component, with its disabled status and internal name.
 166       *
 167       * @param string $component component name, e.g. 'core' or 'mod_forum'.
 168       * @return string HTML.
 169       */
 170      public function component_name(string $component): string {
 171          list($type) = core_component::normalize_component($component);
 172          if ($type === 'core') {
 173              return get_string('corecomponent', 'tool_task');
 174          }
 175  
 176          $plugininfo = core_plugin_manager::instance()->get_plugin_info($component);
 177          if (!$plugininfo) {
 178              return $component;
 179          }
 180  
 181          $plugininfo->init_display_name();
 182  
 183          $componentname = $plugininfo->displayname;
 184          if ($plugininfo->is_enabled() === false) {
 185              $componentname .= ' ' . html_writer::span(
 186                              get_string('disabled', 'tool_task'), 'badge badge-secondary');
 187          }
 188          $componentname .= "\n" . html_writer::span($plugininfo->component, 'task-class text-ltr');
 189  
 190          return $componentname;
 191      }
 192  
 193      /**
 194       * Standard display of a tasks last run time.
 195       *
 196       * @param scheduled_task $task
 197       * @return string HTML.
 198       */
 199      public function last_run_time(scheduled_task $task): string {
 200          if ($task->get_last_run_time()) {
 201              return userdate($task->get_last_run_time());
 202          } else {
 203              return get_string('never');
 204          }
 205      }
 206  
 207      /**
 208       * Standard display of a tasks next run time.
 209       *
 210       * @param scheduled_task $task
 211       * @return string HTML.
 212       */
 213      public function next_run_time(scheduled_task $task): string {
 214          $plugininfo = core_plugin_manager::instance()->get_plugin_info($task->get_component());
 215  
 216          $nextrun = $task->get_next_run_time();
 217          if ($plugininfo && $plugininfo->is_enabled() === false && !$task->get_run_if_component_disabled()) {
 218              $nextrun = get_string('plugindisabled', 'tool_task');
 219          } else if ($task->get_disabled()) {
 220              $nextrun = get_string('taskdisabled', 'tool_task');
 221          } else if ($nextrun > time()) {
 222              $nextrun = userdate($nextrun);
 223          } else {
 224              $nextrun = get_string('asap', 'tool_task');
 225          }
 226  
 227          return $nextrun;
 228      }
 229  
 230      /**
 231       * Get a table cell to show one time, comparing it to the default.
 232       *
 233       * @param string $current the current setting.
 234       * @param string $default the default setting from the db/tasks.php file.
 235       * @return html_table_cell for use in the table.
 236       */
 237      protected function time_cell(string $current, string $default): html_table_cell {
 238          $cell = new html_table_cell($current);
 239          // Cron-style values must always be LTR.
 240          $cell->attributes['class'] = 'text-ltr';
 241  
 242          // If the current value is default, that is all we want to do.
 243          if ($default === '*') {
 244              if ($current === '*') {
 245                  return $cell;
 246              }
 247          } else if ($default === 'R' ) {
 248              if (is_numeric($current)) {
 249                  return $cell;
 250              }
 251          } else {
 252              if ($default === $current) {
 253                  return $cell;
 254              }
 255          }
 256  
 257          // Otherwise, highlight and show the default.
 258          $cell->attributes['class'] .= ' table-warning';
 259          $cell->text .= ' ' . html_writer::span(
 260                  get_string('defaultx', 'tool_task', $default), 'task-class');
 261          return $cell;
 262      }
 263  
 264      /**
 265       * Displays a warning on the page if cron is disabled.
 266       *
 267       * @return string HTML code for information about cron being disabled
 268       * @throws moodle_exception
 269       */
 270      public function cron_disabled(): string {
 271          return $this->output->notification(get_string('crondisabled', 'tool_task'), 'warning');
 272      }
 273  
 274      /**
 275       * Renders a link back to the scheduled tasks page (used from the 'run now' screen).
 276       *
 277       * @param string $taskclassname if specified, the list of tasks will scroll to show this task.
 278       * @return string HTML code
 279       */
 280      public function link_back($taskclassname = '') {
 281          $url = new moodle_url('/admin/tool/task/scheduledtasks.php');
 282          if ($taskclassname) {
 283              $url->param('lastchanged', $taskclassname);
 284          }
 285          return $this->render_from_template('tool_task/link_back', ['url' => $url]);
 286      }
 287  }