Create a Task Runner

Now that our task is installed, we need to implement our tasks getTaskRunner method. This method is responsible for returning a class that implements the Concrete\Core\Command\Task\Runner\TaskRunnerInterface. There are three such tasks available within version 9:

  • Concrete\Core\Command\Task\Runner\CommandTaskRunner
  • Concrete\Core\Command\Task\Runner\ProcessTaskRunner
  • Concrete\Core\Command\Task\Runner\BatchProcessTaskRunner

These task runners correspond to the types of task you’re creating. If you want to run a simple command the moment the task is invoked without worrying about asynchronous processing or queues, choose the CommandTaskRunner. If you want to defer processing until later, but otherwise just run a single command, choose the ProcessTaskRunner. Finally, if you’re implementing a command that is actually a batch process of many smaller commands, return an instance of the BatchProcessTaskRunner. Since we’re creating a simple, synchronous task to clear our log, we’ll implement the CommandTaskRunner within our getTaskRunner method.

return new CommandTaskRunner($task, $command, t('Log cleared successfully.'));

This task runner take three parameters. The first is the $task object, which is passed through the getTaskRunner method. All you have to do is pass it on to the CommandTaskRunner class. The third argument is the message you want to display to the user after running the command is complete. This is pretty obvious; let’s display “Log cleared successfully.”

The second argument is the most important part of this method. This is a command, which we will pair with a command handler.

Create a Command

First, let’s create a command for clearing the logs, following the information in the Commands and Command Handlers section of the documentation. If you haven’t read this documentation yet, you should head over and learn more about how Concrete version 9 handles commands and command handlers.

Let’s create our command at packages/log_utilities/src/Logging/Command/ClearLogCommand.php. Here’s what that file looks like.

<?php
namespace Concrete\Documentation\LogUtilities\Logging\Command;

use Concrete\Core\Foundation\Command\Command;

defined('C5_EXECUTE') or die("Access Denied.");

class ClearLogCommand extends Command
{



}

Since the clearing of the log isn’t going to take any parameters or need any additional input, we don’t need to add any properties to this class. Just naming it and extending the core Command class will be enough.

Create a Command Handler

Now that we have a command, we need a command handler. Since we extended the core Command class, we’ll automatically be looking for a handler for this class in the same namespace, named the same as the command – just with the suffix Handler on the class. That means we need to create a file named packages/log_utilities/src/Logging/Command/ClearLogCommandHandler.php and put the business logic of clearing the logs within that handler’s __invoke() method. Here’s what that looks like:

<?php
namespace Concrete\Documentation\LogUtilities\Logging\Command;

defined('C5_EXECUTE') or die("Access Denied.");

class ClearLogCommandHandler
{

    public function __invoke(ClearLogCommand $command)
    {

    }

}

Add the Command to the Task Runner

Now that we have a command and a command handler, let’s add it to the task runner we made earlier, so that Concrete knows that when we run our Clear Log task, we want to execute the Clear log command. In order to do that, we add our new command to the top of the ClearLogController class:

use Concrete\Documentation\LogUtilities\Logging\Command\ClearLogCommand;

And we reference it from within getTaskRunner

public function getTaskRunner(TaskInterface $task, InputInterface $input): TaskRunnerInterface
{
    $command = new ClearLogCommand();
    return new CommandTaskRunner($task, $command, t('Log cleared successfully.'));
}

Test the Task

Next, let's test out task. From the Dashboard, try running the “Clear Log Task”:

Clicking “Run Task” executes the task:

Similarly, running the task from the command line shows that we’ve wired things up successfully:

Add Logic to the Command Handler

Unfortunately, we haven’t actually finished our task just yet. Our task is reporting that it’s run, and it has, but it hasn’t actually done anything yet because our handler doesn’t have any logic in it. Our log still has entries:

Let’s add the relevant logic to the ClearLogCommandHandler class to clear logs. Thankfully this is a simple static method that doesn’t even require that we add any dependencies to the class. Just add

use Concrete\Core\Logging\Handler\DatabaseHandler;

to the top of the class, and execute its clearAll method from within the __invoke() method. The final handler code looks like this:

<?php
namespace Concrete\Documentation\LogUtilities\Logging\Command;

use Concrete\Core\Logging\Handler\DatabaseHandler;

defined('C5_EXECUTE') or die("Access Denied.");

class ClearLogCommandHandler
{

    public function __invoke(ClearLogCommand $command)
    {
        DatabaseHandler::clearAll();
    }

}

Now let's re-run our task.

And our log is clear!