MDL-81780 tool_task : Adhoc task improvements
Added fail delay column in the adhock task table on the admin page, Added a new column for a delete action for the adhoc tasks on and Wrote delete_adhoctask.php for delete functionality of adhoc tasks. Wrote behat test for the delete functionality. Also there was a logical error in the previous code where it was checking if the task is due or not and it was just showing Never or ASAP instead of actual time so fixed that as well.
This commit is contained in:
@@ -28,6 +28,7 @@ require_once($CFG->libdir.'/adminlib.php');
|
||||
admin_externalpage_setup('adhoctasks');
|
||||
|
||||
$failedonly = optional_param('failedonly', false, PARAM_BOOL);
|
||||
$dueonly = optional_param('dueonly', false, PARAM_BOOL);
|
||||
$classname = optional_param('classname', null, PARAM_RAW);
|
||||
|
||||
$renderer = $PAGE->get_renderer('tool_task');
|
||||
@@ -37,7 +38,7 @@ if ($classname) {
|
||||
$PAGE->navbar->add(get_string('adhoctasks', 'tool_task'), $pageurl);
|
||||
$PAGE->navbar->add(s($classname), $PAGE->url);
|
||||
|
||||
$tasks = core\task\manager::get_adhoc_tasks($classname, $failedonly);
|
||||
$tasks = core\task\manager::get_adhoc_tasks($classname, $failedonly, dueonly: $dueonly);
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
@@ -45,7 +46,7 @@ if ($classname) {
|
||||
echo $renderer->cron_disabled();
|
||||
}
|
||||
|
||||
echo $renderer->adhoc_tasks_class_table($classname, $tasks, ['failedonly' => $failedonly]);
|
||||
echo $renderer->adhoc_tasks_class_table($classname, $tasks, ['failedonly' => $failedonly , 'dueonly' => $dueonly ]);
|
||||
} else {
|
||||
$summary = core\task\manager::get_adhoc_tasks_summary();
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Script deletes an adhoc task.
|
||||
*
|
||||
* @package tool_task
|
||||
* @copyright Catalyst
|
||||
* @author Waleed ul hassan
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
|
||||
require('../../../config.php');
|
||||
|
||||
// Basic security checks.
|
||||
require_admin();
|
||||
$context = context_system::instance();
|
||||
|
||||
// Get task and check the parameter is valid.
|
||||
$taskid = required_param('taskid', PARAM_INT);
|
||||
$task = \core\task\manager::get_adhoc_task($taskid);
|
||||
if (!$task) {
|
||||
throw new \moodle_exception('cannotfindinfo', 'error', $taskid);
|
||||
}
|
||||
|
||||
$returnurl = new moodle_url('/admin/tool/task/adhoctasks.php',
|
||||
['classname' => get_class($task)]);
|
||||
|
||||
require_sesskey();
|
||||
\core\task\manager::delete_adhoc_task($taskid);
|
||||
redirect($returnurl);
|
||||
@@ -46,11 +46,13 @@ $string['checklongrunningtasks'] = 'Long running tasks';
|
||||
$string['checklongrunningtaskcount'] = 'Long running tasks: {$a}';
|
||||
$string['clearfaildelay_confirm'] = 'Are you sure you want to clear the fail delay for task \'{$a}\'? After clearing the delay, the task will run according to its normal schedule.';
|
||||
$string['component'] = 'Component';
|
||||
$string['confirmdeletetaskwithid'] = 'Are you sure you want to delete the task with id: {$a->id}?';
|
||||
$string['corecomponent'] = 'Core';
|
||||
$string['crondisabled'] = 'Cron is disabled. No new tasks will be started. The system will not operate properly until it is enabled again.';
|
||||
$string['cronok'] = 'Cron is running frequently';
|
||||
$string['default'] = 'Default';
|
||||
$string['defaultx'] = 'Default: {$a}';
|
||||
$string['deletetask'] = 'Delete task';
|
||||
$string['disabled'] = 'Disabled';
|
||||
$string['disabled_help'] = 'Disabled scheduled tasks are not executed from cron, however they can still be executed manually via the CLI tool.';
|
||||
$string['edittaskschedule'] = 'Edit task schedule: {$a}';
|
||||
@@ -85,6 +87,7 @@ $string['runadhoctasks'] = 'Run all \'{$a}\' tasks';
|
||||
$string['runadhoctasksfailed'] = 'Run failed \'{$a}\' tasks';
|
||||
$string['runnow_confirm'] = 'Are you sure you want to run this task \'{$a}\' now? The task will run on the web server and may take some time to complete.';
|
||||
$string['runclassname'] = 'Run all';
|
||||
$string['runclassnamedueonly'] = 'Run due only';
|
||||
$string['runclassnamefailedonly'] = 'Run all failed';
|
||||
$string['runpattern'] = 'Run pattern';
|
||||
$string['scheduled'] = 'Scheduled';
|
||||
@@ -140,3 +143,5 @@ $string['taskschedulemonth_help'] = 'Month field for task schedule. The field us
|
||||
* <strong>1,5</strong> Every January and May';
|
||||
$string['privacy:metadata'] = 'The Scheduled task configuration plugin does not store any personal data.';
|
||||
$string['viewlogs'] = 'View logs for {$a}';
|
||||
$string['actions'] = 'Actions';
|
||||
$string['deleteadhoctask'] = 'Delete ad hoc task {$a->id}';
|
||||
|
||||
@@ -96,6 +96,16 @@ class tool_task_renderer extends plugin_renderer_base {
|
||||
),
|
||||
'task-runnow'
|
||||
);
|
||||
$duecontent .= html_writer::div(
|
||||
html_writer::link(
|
||||
new moodle_url(
|
||||
$adhocrunurl,
|
||||
['classname' => $classname, 'dueonly' => 1]
|
||||
),
|
||||
get_string('runclassnamedueonly', 'tool_task')
|
||||
),
|
||||
'task-runnow'
|
||||
);
|
||||
}
|
||||
|
||||
// Mark cell if has failed tasks.
|
||||
@@ -233,6 +243,7 @@ class tool_task_renderer extends plugin_renderer_base {
|
||||
*/
|
||||
private function generate_adhoc_tasks_simple_table(array $tasks, bool $wantruntasks = false): html_table {
|
||||
$adhocrunurl = '/admin/tool/task/run_adhoctasks.php';
|
||||
$adhocdeleteurl = '/admin/tool/task/delete_adhoctasks.php';
|
||||
$now = time();
|
||||
$failedstr = get_string('failed', 'tool_task');
|
||||
|
||||
@@ -243,7 +254,9 @@ class tool_task_renderer extends plugin_renderer_base {
|
||||
get_string('taskid', 'tool_task'),
|
||||
get_string('nextruntime', 'tool_task'),
|
||||
get_string('payload', 'tool_task'),
|
||||
$failedstr
|
||||
$failedstr,
|
||||
get_string('faildelay', 'tool_task'),
|
||||
get_string('actions','tool_task'),
|
||||
];
|
||||
|
||||
$table->attributes['class'] = 'generaltable';
|
||||
@@ -263,9 +276,9 @@ class tool_task_renderer extends plugin_renderer_base {
|
||||
|
||||
// Mark cell if task has failed.
|
||||
$faildelay = $task->get_fail_delay();
|
||||
$faildelaycell = new html_table_cell($faildelay ? $failedstr : '');
|
||||
$failedcell = new html_table_cell($faildelay ? $failedstr : '');
|
||||
if ($faildelay) {
|
||||
$faildelaycell->attributes['class'] = 'table-danger';
|
||||
$failedcell->attributes['class'] = 'table-danger';
|
||||
}
|
||||
|
||||
// Prepares the next run time cell contents.
|
||||
@@ -293,11 +306,38 @@ class tool_task_renderer extends plugin_renderer_base {
|
||||
}
|
||||
}
|
||||
|
||||
// Create fail delay cell.
|
||||
$faildelaycellcontent = $faildelay;
|
||||
$faildelaycell = new html_table_cell($faildelaycellcontent);
|
||||
|
||||
if ($faildelay) {
|
||||
$faildelaycell->attributes['class'] = 'table-danger';
|
||||
}
|
||||
|
||||
// Add delete link with modal trigger.
|
||||
$deletelink = html_writer::link(
|
||||
new moodle_url($adhocdeleteurl, ['taskid' => $taskid, 'sesskey' => sesskey()]),
|
||||
get_string('delete'),
|
||||
[
|
||||
'class' => 'btn btn-danger',
|
||||
'role' => 'button',
|
||||
'aria-label' => get_string('deleteadhoctask', 'tool_task', $taskid),
|
||||
'data-confirmation' => 'modal',
|
||||
'data-confirmation-type' => 'delete',
|
||||
'data-confirmation-title-str' => '["deleteadhoctask", "tool_task",{"id":'.$taskid.'}]',
|
||||
'data-confirmation-content-str' => '["confirmdeletetaskwithid", "tool_task", {"id":'.$taskid.'}]',
|
||||
'data-confirmation-yes-button-str' => '["delete", "core"]',
|
||||
]
|
||||
);
|
||||
$deletecell = new html_table_cell($deletelink);
|
||||
|
||||
$data[] = new html_table_row([
|
||||
$taskidcell,
|
||||
new html_table_cell($nextrun),
|
||||
new html_table_cell($task->get_custom_data_as_string()),
|
||||
$failedcell,
|
||||
$faildelaycell,
|
||||
$deletecell,
|
||||
]);
|
||||
}
|
||||
$table->data = $data;
|
||||
|
||||
@@ -37,6 +37,7 @@ $tasksurl = '/admin/tool/task/adhoctasks.php';
|
||||
// Allow execution of single task. This requires login and has different rules.
|
||||
$classname = optional_param('classname', null, PARAM_RAW);
|
||||
$failedonly = optional_param('failedonly', false, PARAM_BOOL);
|
||||
$dueonly = optional_param('dueonly', false, PARAM_BOOL);
|
||||
$taskid = optional_param('id', null, PARAM_INT);
|
||||
$confirmed = optional_param('confirm', 0, PARAM_INT);
|
||||
|
||||
@@ -45,7 +46,7 @@ if (!\core\task\manager::is_runnable()) {
|
||||
throw new moodle_exception('cannotfindthepathtothecli', 'tool_task', $redirecturl->out());
|
||||
}
|
||||
|
||||
$params = ['classname' => $classname, 'failedonly' => $failedonly, 'id' => $taskid];
|
||||
$params = ['classname' => $classname, 'failedonly' => $failedonly, 'dueonly' => $dueonly, 'id' => $taskid];
|
||||
|
||||
// Check input parameter id against all existing tasks.
|
||||
if ($taskid) {
|
||||
@@ -69,7 +70,7 @@ if ($taskid) {
|
||||
|
||||
$now = time();
|
||||
$tasks = array_filter(
|
||||
core\task\manager::get_adhoc_tasks($classname, $failedonly, true),
|
||||
core\task\manager::get_adhoc_tasks($classname, $failedonly, $dueonly, true),
|
||||
function ($t) use ($now) {
|
||||
return $t->get_fail_delay() || $t->get_next_run_time() <= $now;
|
||||
}
|
||||
@@ -130,14 +131,16 @@ if ($taskid) {
|
||||
\core\task\manager::run_adhoc_from_cli($taskid);
|
||||
echo html_writer::end_tag('pre');
|
||||
} else {
|
||||
$repeat = core\task\manager::get_adhoc_tasks($classname, $failedonly, true);
|
||||
$repeat = core\task\manager::get_adhoc_tasks($classname, $failedonly, $dueonly, true);
|
||||
|
||||
// Run failed first (if any). We have to run them separately anyway,
|
||||
// because faildelay is observed if failed flag is not true.
|
||||
echo html_writer::tag('p', get_string('runningfailedtasks', 'tool_task'), ['class' => 'lead']);
|
||||
echo html_writer::start_tag('pre', ['class' => 'task-output']);
|
||||
\core\task\manager::run_all_adhoc_from_cli(true, $classname);
|
||||
echo html_writer::end_tag('pre');
|
||||
if (!$dueonly) {
|
||||
echo html_writer::tag('p', get_string('runningfailedtasks', 'tool_task'), ['class' => 'lead']);
|
||||
echo html_writer::start_tag('pre', ['class' => 'task-output']);
|
||||
\core\task\manager::run_all_adhoc_from_cli(true, $classname);
|
||||
echo html_writer::end_tag('pre');
|
||||
}
|
||||
|
||||
if (!$failedonly) {
|
||||
echo html_writer::tag('p', get_string('runningalltasks', 'tool_task'), ['class' => 'lead']);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
@tool @tool_task @javascript
|
||||
Feature: Delete an adhoc task
|
||||
In order to manage adhoc tasks
|
||||
As an admin
|
||||
I need to be able to delete adhoc tasks
|
||||
|
||||
Scenario: Delete an existing adhoc task
|
||||
Given I log in as "admin"
|
||||
And the following "tool_task > adhoc tasks" exist:
|
||||
| classname | seconds | hostname | pid |
|
||||
| \core\task\asynchronous_backup_task | 7201 | c69335460f7f | 1915 |
|
||||
| \core\task\asynchronous_restore_task | 172800 | c69335460f7f | 1916 |
|
||||
And I navigate to "Server > Tasks > Ad hoc tasks" in site administration
|
||||
Then "asynchronous_backup_task" "table_row" should exist
|
||||
And "asynchronous_restore_task" "table_row" should exist
|
||||
And I follow "asynchronous_backup_task"
|
||||
When I follow "Delete"
|
||||
And I click on "Delete" "button" in the ".modal-dialog" "css_element"
|
||||
Then I navigate to "Server > Tasks > Ad hoc tasks" in site administration
|
||||
And "asynchronous_backup_task" "table_row" should not exist
|
||||
And "asynchronous_restore_task" "table_row" should exist
|
||||
@@ -507,11 +507,17 @@ class manager {
|
||||
* This function load the adhoc tasks for a given classname.
|
||||
*
|
||||
* @param string $classname
|
||||
* @param bool $failedonly
|
||||
* @param bool $skiprunning do not return tasks that are in the running state
|
||||
* @param bool $failedonly Return only failed tasks
|
||||
* @param bool $skiprunning Do not return tasks that are in the running state
|
||||
* @param bool $dueonly Return only tasks that are due to run (nextruntime < now)
|
||||
* @return array
|
||||
*/
|
||||
public static function get_adhoc_tasks(string $classname, bool $failedonly = false, bool $skiprunning = false): array {
|
||||
public static function get_adhoc_tasks(
|
||||
string $classname,
|
||||
bool $failedonly = false,
|
||||
bool $skiprunning = false,
|
||||
bool $dueonly = false
|
||||
): array {
|
||||
global $DB;
|
||||
|
||||
$conds[] = 'classname = ?';
|
||||
@@ -519,6 +525,8 @@ class manager {
|
||||
|
||||
if ($failedonly) {
|
||||
$conds[] = 'faildelay > 0';
|
||||
} else if ($dueonly) {
|
||||
$conds[] = 'faildelay = 0';
|
||||
}
|
||||
if ($skiprunning) {
|
||||
$conds[] = 'timestarted IS NULL';
|
||||
@@ -950,6 +958,17 @@ class manager {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will delete an adhoc task by id. The task will be removed
|
||||
* from the database.
|
||||
*
|
||||
* @param int $taskid
|
||||
*/
|
||||
public static function delete_adhoc_task(int $taskid): void {
|
||||
global $DB;
|
||||
$DB->delete_records('task_adhoc', ['id' => $taskid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set locks on the task.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user