Create automatic action from a subtask event

I’m trying to register an automatic action which I’ve built a plug in for (based on the plugin-example-automatic-action on GitHub).

I’d like to trigger the action on a Subtask event (setting it to “In Progress” and “Complete”) but these events don’t seem to appear in the drop down box of events that you can attach to.

For example my plugin has:

public function getCompatibleEvents()
    return array(


but when I try to choose this event in the “Automatic Actions”:

Is it not possible to use Subtask events to drive automatic actions?

Just a guess, but try adding:

$this->eventManager->register(SubtaskModel::EVENT_UPDATE, 'On subtask update');

In Plugin.php under initialize(), for your plugin.

Thanks for getting back to me. This didn’t work but I think that the behaviour I want can be made by modifying the SubtaskStatusController instead of using actions/events. Do you know of a clean way of doing this via a plugin rather than editing the Kanboard/App/Controller/SubtaskStatusController source code directly?

can you link the repo so i can clone it and take a look?

Right now I’m just editing the change() function of the SubtaskStatusController class directly so this is not in a plugin repo. I have the functionality I want but now want to overwrite the change() function that Kanboard uses but by a plugin so my edits are not in the main source code. Is there a way of registering a different function for a controller via a plugin?

I still have no clue what you are doing or seen any code, so it’s hard to help you.

you are making an automatic action, and are using the `SubtaskStatusController’ in the action? and want to instead override that controller to call your modified method, within your action?

If so, then, there is no need to “override” anything. Just call your modified controller instead.

The automatic action does not work on subtasks so I’ m not making an automatic action at all anymore. Currently my code is not in a plugin because I haven’t figured out how to achieve what I need that way. I have directly modified the change() function of the SubtaskStatusController in the Kanboard source code, see below. What I need is to be able to write a plugin that overrides the change() function of the SubtaskStatusController given a certain condition. This is similar to this request here which doesn’t look like it was resolved.

My adapted change function:

public function change()

    $task = $this->getTask();
    $subtask = $this->getSubtask($task);
    $fragment = $this->request->getStringParam('fragment');
    //debug statements
    error_log("current status:".$subtask['status']);

    $projectid = $this->request->getIntegerParam('project_id');
    error_log("project id: ".$projectid);

    error_log("full name: ".$user);

    error_log("user id: ".$id);

    $project_role = $this->helper->projectRole->getProjectUserRole($projectid);
    error_log("project_role: ".$project_role);
    // only change the status from complete to not started if user is project manager
        case 0:
            $status = $this->subtaskStatusModel->toggleStatus($subtask['id']);
            $subtask['status'] = $status;
        case 1:
            $status = $this->subtaskStatusModel->toggleStatus($subtask['id']);
            $subtask['status'] = $status;
        case 2:
            if ($project_role == Role::PROJECT_MANAGER){
                $status = $this->subtaskStatusModel->toggleStatus($subtask['id']);
                $subtask['status'] = $status;
            error_log("Subtask status not recognised.");

    if ($fragment === 'table') {
        $html = $this->renderTable($task);
    } elseif ($fragment === 'rows') {
        $html = $this->renderRows($task);
    } else {
        $html = $this->helper->subtask->renderToggleStatus($task, $subtask);



I dont know of a way to override all usages of a controller, but you could override templates that call the controller, and thus call your own controller.

Okay, thanks I understand that. The problem I’m having with that is that the SubtaskStatusController isn’t called by a Template, it’s called by a Helper - the SubtaskHelper. I’ve tried to overwrite a the helper stored in the container with no luck. Have you got any experience in writing new helpers or overwriting helpers?

I think I’m almost there with this problem. My new helper redirects to my custom controller but it says 'Internal Error: Controller Not Found". Do you know how to register/ link up controllers?

You need to add your plugin to the array when you call it, so it knows where it is.

$this->url->href('GroupAssignTaskCreationController', 'save', array('plugin' => 'Group_assign', 'project_id' => $project['id']))

I take it you figured out the Helper, let me know otherwise.

Actually, this works just fine, tested and confirmed.


2019/09/06 16:50:54 [error] 14#14: *1412 FastCGI sent in stderr: "PHP message: gotEventsPHP message: hasConditionPHP message: Subtask EVENT_UPDATE was triggered" while reading response header from upstream, client:, server: localhost, request: "GET /?controller=SubtaskStatusController&action=change&project_id=4&task_id=83&subtask_id=21&user_id=0&fragment=table&_=1567788572656 HTTP/1.1", upstream: "fastcgi://unix:/var/run/php-fpm.sock:", host: ""

PHP message: Subtask EVENT_UPDATE was triggered

Placed an error_log in the doAction to confirm:

    public function doAction(array $data)
        error_log('Subtask EVENT_UPDATE was triggered',0);

and as you can see in the log, it triggered.

If it’s not working, for you, then it is because you are doing something wrong, and of the list of things I can think of that would go wrong (that wouldn’t produce an error message)

  • in your getEventRequiredParameters() … you may be asking for information that isn’t included in the event.
  • your hasRequiredCondition() is returning false

The other possible issues, would come with blatant error messages, like improper use, or not including the use for the model at all.

Thanks for all of your help with this. I’ve got a working plugin now so your time is really appreciated. I ended up going down the modified controller and helper route as thinking more about my use case, I want to prevent an action from occurring rather than do something once it has happened. Again, thanks for the help.

That’s good. Glad you figured it out.

Now that I understand what you wanted to achieve, i would have mentioned the projectAccessMap. You can simply restrict access to any controller, based on role.

For reference:

So, something like:

    $this->projectAccessMap->add('SubtaskStatusController', '*'), Role::PROJECT_MANAGER);

would have blocked non project managers from accessing anything in that controller.

And here is another reference if you ever need to do it at the application level, using the applicationAccessMap: