Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [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 /** 40 * This function will render a table with the summary of all adhoc tasks. 41 * 42 * @param array $summary 43 * @return string HTML to output. 44 */ 45 public function adhoc_tasks_summary_table(array $summary): string { 46 $adhocurl = '/admin/tool/task/adhoctasks.php'; 47 $adhocrunurl = '/admin/tool/task/run_adhoctasks.php'; 48 49 // Main tasks table. 50 $table = new html_table(); 51 $table->caption = get_string('adhoctasks', 'tool_task'); 52 $table->head = [ 53 get_string('component', 'tool_task') . ' / ' . get_string('classname', 'tool_task'), 54 get_string('adhoctasksrunning', 'tool_task'), 55 get_string('adhoctasksdue', 'tool_task'), 56 get_string('adhoctasksfuture', 'tool_task'), 57 get_string('adhoctasksfailed', 'tool_task'), 58 get_string('nextruntime', 'tool_task'), 59 ]; 60 61 $table->attributes['class'] = 'admintable generaltable'; 62 $table->colclasses = []; 63 64 // For each task entry (row) show action buttons/logs link depending on the user permissions. 65 $data = []; 66 $canruntasks = \core\task\manager::is_runnable() && get_config('tool_task', 'enablerunnow'); 67 foreach ($summary as $component => $classes) { 68 // Component cell. 69 $componentcell = new html_table_cell($component); 70 $componentcell->header = true; 71 $componentcell->id = "tasks-$component"; 72 $componentcell->colspan = 6; 73 74 $data[] = new html_table_row([$componentcell]); 75 76 foreach ($classes as $classname => $stats) { 77 // Task class cell. 78 $classbits = explode('\\', $classname); 79 $classcontent = html_writer::link( 80 new moodle_url($adhocurl, ['classname' => $classname]), 81 end($classbits) 82 ); 83 $classcell = new html_table_cell($classcontent); 84 $classcell->header = true; 85 $classcell->attributes['class'] = "task-class-summary text-ltr"; 86 87 $duecontent = $stats['due']; 88 if ($canruntasks && ($stats['due'] > 0 || $stats['failed'] > 0)) { 89 $duecontent .= html_writer::div( 90 html_writer::link( 91 new moodle_url( 92 $adhocrunurl, 93 ['classname' => $classname] 94 ), 95 get_string('runclassname', 'tool_task') 96 ), 97 'task-runnow' 98 ); 99 } 100 101 // Mark cell if has failed tasks. 102 $failed = $stats['failed']; 103 if ($canruntasks && $failed > 0) { 104 $failed .= html_writer::div( 105 html_writer::link( 106 new moodle_url( 107 $adhocrunurl, 108 ['classname' => $classname, 'failedonly' => 1] 109 ), 110 get_string('runclassnamefailedonly', 'tool_task') 111 ), 112 'task-runnow' 113 ); 114 } 115 $failedcell = new html_table_cell($failed); 116 if ($failed > 0) { 117 $failedcell->attributes['class'] = 'table-danger'; 118 } 119 120 // Prepares the next run time cell contents. 121 $nextrun = ''; 122 if ($stats['due'] > 0) { 123 $nextrun = get_string('asap', 'tool_task'); 124 } else if ($stats['nextruntime']) { 125 $nextrun = userdate($stats['nextruntime']); 126 } 127 128 $data[] = new html_table_row([ 129 $classcell, 130 new html_table_cell($stats['running']), 131 new html_table_cell($duecontent), 132 new html_table_cell($stats['count'] - $stats['running'] - $stats['due']), 133 $failedcell, 134 new html_table_cell($nextrun), 135 ]); 136 } 137 } 138 $table->data = $data; 139 return html_writer::table($table); 140 } 141 142 /** 143 * This function will render a table with all the adhoc tasks for the class. 144 * 145 * @param string $classname 146 * @param array $tasks - list of all adhoc tasks. 147 * @param array|null $params 148 * @return string HTML to output. 149 */ 150 public function adhoc_tasks_class_table(string $classname, array $tasks, ?array $params = []): string { 151 $adhocurl = '/admin/tool/task/adhoctasks.php'; 152 $adhocrunurl = '/admin/tool/task/run_adhoctasks.php'; 153 $showloglink = \core\task\logmanager::has_log_report(); 154 $failedonly = !empty($params['failedonly']); 155 $canruntasks = \core\task\manager::is_runnable() && get_config('tool_task', 'enablerunnow'); 156 157 // Depending on the currently set parameters, set up toggle buttons. 158 $failedorall = html_writer::link( 159 new moodle_url( 160 $adhocurl, 161 array_merge($params, ['classname' => $classname, 'failedonly' => !$failedonly]) 162 ), 163 get_string($failedonly ? 'showall' : 'showfailedonly', 'tool_task') 164 ); 165 166 // Main tasks table. 167 $table = $this->generate_adhoc_tasks_simple_table($tasks, $canruntasks); 168 169 $table->caption = s($classname) . " " 170 . get_string($failedonly ? 'adhoctasksfailed' : 'adhoctasks', 'tool_task'); 171 $table->head[3] .= " $failedorall"; // Spice up faildelay heading. 172 173 if ($showloglink) { 174 // Insert logs as the second col. 175 array_splice($table->head, 1, 0, [get_string('logs')]); 176 array_walk($table->data, function ($row, $idx) use ($classname) { 177 $loglink = ''; 178 $faildelaycell = $row->cells[3]; 179 if ($faildelaycell->attributes['class'] == 'table-danger') { 180 // Failed task. 181 $loglink = $this->output->action_icon( 182 \core\task\logmanager::get_url_for_task_class($classname), 183 new pix_icon('e/file-text', get_string('viewlogs', 'tool_task', $classname) 184 )); 185 } 186 187 array_splice($row->cells, 1, 0, [new html_table_cell($loglink)]); 188 }); 189 } 190 191 return html_writer::table($table) 192 . html_writer::div( 193 html_writer::link( 194 new moodle_url( 195 $adhocrunurl, 196 array_merge($params, ['classname' => $classname]) 197 ), 198 get_string('runclassname', 'tool_task') 199 ), 200 'task-runnow' 201 ) 202 . html_writer::div( 203 html_writer::link( 204 new moodle_url( 205 $adhocurl 206 ), 207 get_string('showsummary', 'tool_task') 208 ), 209 'task-show-summary' 210 ); 211 } 212 213 /** 214 * This function will render a plain adhoc tasks table. 215 * 216 * @param array $tasks - list of adhoc tasks. 217 * @return string HTML to output. 218 */ 219 public function adhoc_tasks_simple_table(array $tasks): string { 220 $table = $this->generate_adhoc_tasks_simple_table($tasks); 221 222 return html_writer::table($table); 223 } 224 225 /** 226 * This function will render a plain adhoc tasks table. 227 * 228 * @param array $tasks - list of adhoc tasks. 229 * @param bool $wantruntasks add 'Run now' link 230 * @return html_table 231 */ 232 private function generate_adhoc_tasks_simple_table(array $tasks, bool $wantruntasks = false): html_table { 233 $adhocrunurl = '/admin/tool/task/run_adhoctasks.php'; 234 $now = time(); 235 $failedstr = get_string('failed', 'tool_task'); 236 237 // Main tasks table. 238 $table = new html_table(); 239 $table->caption = get_string('adhoctasks', 'tool_task'); 240 $table->head = [ 241 get_string('taskid', 'tool_task'), 242 get_string('nextruntime', 'tool_task'), 243 get_string('payload', 'tool_task'), 244 $failedstr 245 ]; 246 247 $table->attributes['class'] = 'generaltable'; 248 $table->colclasses = []; 249 250 // For each task entry (row) show action buttons/logs link depending on the user permissions. 251 $data = []; 252 foreach ($tasks as $task) { 253 $taskid = $task->get_id(); 254 $started = $task->get_timestarted(); 255 256 // Task id cell. 257 $taskidcellcontent = html_writer::span($taskid, 'task-id'); 258 $taskidcell = new html_table_cell($taskidcellcontent); 259 $taskidcell->header = true; 260 $taskidcell->id = "task-$taskid"; 261 262 // Mark cell if task has failed. 263 $faildelay = $task->get_fail_delay(); 264 $faildelaycell = new html_table_cell($faildelay ? $failedstr : ''); 265 if ($faildelay) { 266 $faildelaycell->attributes['class'] = 'table-danger'; 267 } 268 269 // Prepares the next run time cell contents. 270 $nextrun = get_string('started', 'tool_task'); 271 if (!$started) { 272 $nextruntime = $task->get_next_run_time(); 273 $due = $nextruntime < $now; 274 $nextrun = $due ? userdate($nextruntime) : get_string('asap', 'tool_task'); 275 276 if ($wantruntasks && ($faildelay || $due)) { 277 $nextrun .= ' '.html_writer::div( 278 html_writer::link( 279 new moodle_url( 280 $adhocrunurl, 281 ['id' => $taskid] 282 ), 283 get_string('runnow', 'tool_task') 284 ), 285 'task-runnow' 286 ); 287 } 288 } 289 290 $data[] = new html_table_row([ 291 $taskidcell, 292 new html_table_cell($nextrun), 293 new html_table_cell($task->get_custom_data_as_string()), 294 $faildelaycell, 295 ]); 296 } 297 $table->data = $data; 298 299 return $table; 300 } 301 302 /** 303 * Displays a notification on ad hoc task run request. 304 * 305 * @return string HTML notification block for task initiated message 306 */ 307 public function adhoc_task_run(): string { 308 return $this->output->notification(get_string('adhoctaskrun', 'tool_task'), 'info'); 309 } 310 311 /** 312 * This function will render one beautiful table with all the scheduled tasks. 313 * 314 * @param \core\task\scheduled_task[] $tasks - list of all scheduled tasks. 315 * @param string $lastchanged (optional) the last task edited. Gets highlighted in teh table. 316 * @return string HTML to output. 317 */ 318 public function scheduled_tasks_table($tasks, $lastchanged = '') { 319 global $CFG; 320 321 $showloglink = \core\task\logmanager::has_log_report(); 322 323 $table = new html_table(); 324 $table->caption = get_string('scheduledtasks', 'tool_task'); 325 $table->head = [ 326 get_string('name'), 327 get_string('component', 'tool_task'), 328 get_string('edit'), 329 get_string('logs'), 330 get_string('lastruntime', 'tool_task'), 331 get_string('nextruntime', 'tool_task'), 332 get_string('taskscheduleminute', 'tool_task'), 333 get_string('taskschedulehour', 'tool_task'), 334 get_string('taskscheduleday', 'tool_task'), 335 get_string('taskscheduledayofweek', 'tool_task'), 336 get_string('taskschedulemonth', 'tool_task'), 337 get_string('faildelay', 'tool_task'), 338 get_string('default', 'tool_task'), 339 ]; 340 341 $table->attributes['class'] = 'admintable generaltable'; 342 $table->colclasses = []; 343 344 if (!$showloglink) { 345 // Hide the log links. 346 $table->colclasses['3'] = 'hidden'; 347 } 348 349 $data = []; 350 $yes = get_string('yes'); 351 $no = get_string('no'); 352 $canruntasks = \core\task\manager::is_runnable() && get_config('tool_task', 'enablerunnow'); 353 foreach ($tasks as $task) { 354 $classname = get_class($task); 355 $defaulttask = \core\task\manager::get_default_scheduled_task($classname, false); 356 357 $customised = $task->is_customised() ? $no : $yes; 358 if (empty($CFG->preventscheduledtaskchanges) && !$task->is_overridden()) { 359 $configureurl = new moodle_url('/admin/tool/task/scheduledtasks.php', 360 ['action' => 'edit', 'task' => $classname]); 361 $editlink = $this->output->action_icon($configureurl, new pix_icon('t/edit', 362 get_string('edittaskschedule', 'tool_task', $task->get_name()))); 363 } else { 364 $editlink = $this->render(new pix_icon('t/locked', 365 get_string('scheduledtaskchangesdisabled', 'tool_task'))); 366 } 367 368 $loglink = ''; 369 if ($showloglink) { 370 $loglink = $this->output->action_icon( 371 \core\task\logmanager::get_url_for_task_class($classname), 372 new pix_icon('e/file-text', get_string('viewlogs', 'tool_task', $task->get_name()) 373 )); 374 } 375 376 $namecellcontent = $task->get_name() . "\n" . 377 html_writer::span('\\' . $classname, 'task-class text-ltr'); 378 if ($task->is_overridden()) { 379 // Let the user know the scheduled task is defined in config. 380 $namecellcontent .= "\n" . html_writer::div(get_string('configoverride', 'admin'), 'alert-info'); 381 } 382 $namecell = new html_table_cell($namecellcontent); 383 $namecell->header = true; 384 $namecell->id = scheduled_task::get_html_id($classname); 385 386 $runnow = ''; 387 $canrunthistask = $canruntasks && $task->can_run(); 388 if ($canrunthistask) { 389 $runnow = html_writer::div(html_writer::link( 390 new moodle_url('/admin/tool/task/schedule_task.php', 391 ['task' => $classname]), 392 get_string('runnow', 'tool_task')), 'task-runnow'); 393 } 394 395 $faildelaycell = new html_table_cell($task->get_fail_delay()); 396 if ($task->get_fail_delay()) { 397 $faildelaycell->text .= html_writer::div( 398 $this->output->single_button( 399 new moodle_url('/admin/tool/task/clear_fail_delay.php', 400 ['task' => $classname]), 401 get_string('clear') 402 ), 403 'task-runnow' 404 ); 405 $faildelaycell->attributes['class'] = 'table-danger'; 406 } 407 408 $row = new html_table_row([ 409 $namecell, 410 new html_table_cell($this->component_name($task->get_component())), 411 new html_table_cell($editlink), 412 new html_table_cell($loglink), 413 new html_table_cell($this->last_run_time($task) . $runnow), 414 new html_table_cell($this->next_run_time($task)), 415 $this->time_cell($task->get_minute(), $defaulttask->get_minute()), 416 $this->time_cell($task->get_hour(), $defaulttask->get_hour()), 417 $this->time_cell($task->get_day(), $defaulttask->get_day()), 418 $this->time_cell($task->get_day_of_week(), $defaulttask->get_day_of_week()), 419 $this->time_cell($task->get_month(), $defaulttask->get_month()), 420 $faildelaycell, 421 new html_table_cell($customised)]); 422 423 $classes = []; 424 if (!$task->is_enabled()) { 425 $classes[] = 'disabled'; 426 } 427 if (get_class($task) == $lastchanged) { 428 $classes[] = 'table-primary'; 429 } 430 $row->attributes['class'] = implode(' ', $classes); 431 $data[] = $row; 432 } 433 $table->data = $data; 434 if ($lastchanged) { 435 // IE does not support this, and the ancient version of Firefox we use for Behat 436 // has the method, but then errors on 'centre'. So, just try to scroll, and if it fails, don't care. 437 $this->page->requires->js_init_code( 438 'try{document.querySelector("tr.table-primary").scrollIntoView({block: "center"});}catch(e){}'); 439 } 440 return html_writer::table($table); 441 } 442 443 /** 444 * Nicely display the name of a component, with its disabled status and internal name. 445 * 446 * @param string $component component name, e.g. 'core' or 'mod_forum'. 447 * @return string HTML. 448 */ 449 public function component_name(string $component): string { 450 list($type) = core_component::normalize_component($component); 451 if ($type === 'core') { 452 return get_string('corecomponent', 'tool_task'); 453 } 454 455 $plugininfo = core_plugin_manager::instance()->get_plugin_info($component); 456 if (!$plugininfo) { 457 return $component; 458 } 459 460 $plugininfo->init_display_name(); 461 462 $componentname = $plugininfo->displayname; 463 if ($plugininfo->is_enabled() === false) { 464 $componentname .= ' ' . html_writer::span( 465 get_string('disabled', 'tool_task'), 'badge badge-secondary'); 466 } 467 $componentname .= "\n" . html_writer::span($plugininfo->component, 'task-class text-ltr'); 468 469 return $componentname; 470 } 471 472 /** 473 * Standard display of a tasks last run time. 474 * 475 * @param scheduled_task $task 476 * @return string HTML. 477 */ 478 public function last_run_time(scheduled_task $task): string { 479 if ($task->get_last_run_time()) { 480 return userdate($task->get_last_run_time()); 481 } else { 482 return get_string('never'); 483 } 484 } 485 486 /** 487 * Standard display of a tasks next run time. 488 * 489 * @param scheduled_task $task 490 * @return string HTML. 491 */ 492 public function next_run_time(scheduled_task $task): string { 493 $nextrun = $task->get_next_run_time(); 494 495 if (!$task->is_component_enabled() && !$task->get_run_if_component_disabled()) { 496 $nextrun = get_string('plugindisabled', 'tool_task'); 497 } else if ($task->get_disabled()) { 498 $nextrun = get_string('taskdisabled', 'tool_task'); 499 } else if ($nextrun > time()) { 500 $nextrun = userdate($nextrun); 501 } else { 502 $nextrun = get_string('asap', 'tool_task'); 503 } 504 505 return $nextrun; 506 } 507 508 /** 509 * Get a table cell to show one time, comparing it to the default. 510 * 511 * @param string $current the current setting. 512 * @param string $default the default setting from the db/tasks.php file. 513 * @return html_table_cell for use in the table. 514 */ 515 protected function time_cell(string $current, string $default): html_table_cell { 516 $cell = new html_table_cell($current); 517 // Cron-style values must always be LTR. 518 $cell->attributes['class'] = 'text-ltr'; 519 520 // If the current value is default, that is all we want to do. 521 if ($default === '*') { 522 if ($current === '*') { 523 return $cell; 524 } 525 } else if ($default === 'R' ) { 526 if (is_numeric($current)) { 527 return $cell; 528 } 529 } else { 530 if ($default === $current) { 531 return $cell; 532 } 533 } 534 535 // Otherwise, highlight and show the default. 536 $cell->attributes['class'] .= ' table-warning'; 537 $cell->text .= ' ' . html_writer::span( 538 get_string('defaultx', 'tool_task', $default), 'task-class'); 539 return $cell; 540 } 541 542 /** 543 * Displays a warning on the page if cron is disabled. 544 * 545 * @return string HTML code for information about cron being disabled 546 * @throws moodle_exception 547 */ 548 public function cron_disabled(): string { 549 return $this->output->notification(get_string('crondisabled', 'tool_task'), 'warning'); 550 } 551 552 /** 553 * Renders a link back to the scheduled tasks page (used from the 'run now' screen). 554 * 555 * @param string $taskclassname if specified, the list of tasks will scroll to show this task. 556 * @return string HTML code 557 */ 558 public function link_back($taskclassname = '') { 559 $url = new moodle_url('/admin/tool/task/scheduledtasks.php'); 560 if ($taskclassname) { 561 $url->param('lastchanged', $taskclassname); 562 } 563 return $this->render_from_template('tool_task/link_back', ['url' => $url]); 564 } 565 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body