Merge branch 'MDL-81780-Adhoc-task-improvements' of https://github.com/waleedhassan5/moodle

This commit is contained in:
Jun Pataleta
2025-01-17 11:53:28 +08:00
7 changed files with 150 additions and 15 deletions
+3 -2
View File
@@ -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();
+46
View File
@@ -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);
+5
View File
@@ -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}';
+43 -3
View File
@@ -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;
+10 -7
View File
@@ -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
+22 -3
View File
@@ -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.
*