Skip to main content
Version: 2024.1

Implement Custom Job Steps

Job step implementations contain the actual business logic that can be executed via automation actions, e.g. generating variants. They should be kept somehow generic and can be further configured with the step specific configuration options in the actual Action Configuration.

Implement and Register Job Steps

Job step implementations are executed via the Job Execution Engine which means they are implemented via Symfony Messenger messages/handlers. So, for creating custom job step implementations it is necessary to

  • Create message class implementing Pimcore\Bundle\CopilotBundle\JobExecutionEngine\Messenger\Messages\JobExecutionEngineMessageInterface (there is an abstract class Pimcore\Bundle\CopilotBundle\JobExecutionEngine\Messenger\Messages\AbstractExecutionEngineMessage to be used for convenience).
  • Create a message handler capable of handling the message and doing all the desired logic. There is an abstract class Pimcore\Bundle\CopilotBundle\JobExecutionEngine\Messenger\Handler\AbstractAutomationActionHandler providing some convenience functions in working with Job Runs.
  • Make sure the message class is registered in Symfony Messenger routing accordingly.

Details see existing job step implementations and also see Job Execution Engine.

In addition to the message and handler, job step implementations need to be registered in Symfony configuration tree to be usable for automation actions. This configuration is a mapping between name to be used in action configuration and FQCN of Symfony Messenger message.

Example

pimcore_copilot:
automation_actions:
step_implementation_mapping:
variant_generator:
class: 'Pimcore\Bundle\PimcoreCopilotBundle\AutomationAction\Messenger\Messages\VariantGeneratorMessage'
asset_relation_object_name:
class: 'Pimcore\Bundle\CopilotBundle\AutomationAction\Messenger\Messages\AssetObjectRelationByNameMessage'
asset_relation_object_meta:
class: 'Pimcore\Bundle\CopilotBundle\AutomationAction\Messenger\Messages\AssetObjectRelationByMetaMessage'

Extracting Environment Variables in Automation Actions

Here is an example on how the environment variables can be used in an automation action.

<?php

#[AsMessageHandler]
final class TestHandler extends AbstractAutomationActionHandler
{
public function __invoke(TestMessage $message): void
{
$jobRun = $this->getJobRun($message);

//extract environmental data
$environmentVariables = $jobRun->getJob()?->getEnvironmentData() ?? [];

$matrixFieldName = $this->extractConfigFieldFromJobStepConfig($message, 'matrix_variable');

$matrixData = $environmentVariables[$matrixFieldName] ?? [];
$objectType = $environmentVariables['ObjectType'] ?? AbstractObject::OBJECT_TYPE_OBJECT;
$published = (bool)($environmentVariables['Published'] ?? false);
}
}

Configure and Validate Step Implementations

The step configurations have a dynamic configuration section for step specific configuration options.

steps:
- step_implementation: 'variant_generator'
name: 'Generate Variants'
condition: 'Symfony Expression can be used here'
configuration:
class_name: 'Pimcore\Model\DataObject\Car'
matrix_variable: Variants

Pimcore\Bundle\CopilotBundle\JobExecutionEngine\Messenger\Handler\AbstractAutomationActionHandler provides some convenience functionality to configure and validate these options, for example the options for the configuration can be defined using The OptionsResolver Component from Symfony.

    class VariantGeneratorHandler extends AbstractAutomationActionHandler
{
...
// only necessary if you need other services in the constructor
public function __construct(JobRunExtractorInterface $jobRunExtractor)
{
parent::__construct($jobRunExtractor);
}

public function __invoke(VariantGeneratorMessage $message): void
{
...
$class_name = $this->extractConfigFieldFromJobStepConfig($message, 'class_name');
...
}


protected function configureStep() : void
{
$this->stepConfiguration->setRequired('class_name');
$this->stepConfiguration->setRequired('matrix_variable');
}
}

Handling exceptions during execution

To make sure the job execution engine does not retry failed messages you should use the provided functionality from the AbstractAutomationActionHandler to handle exceptions.

    class VariantGeneratorHandler extends AbstractAutomationActionHandler
{
...
protected function doInvoke(JobExecutionEngineMessageInterface $message){
...
try {
...
} catch (Exception $exception) {
$this->throwUnRecoverableException($exception);
}
}
}

Inline Help Data

To add inline help data for your custom step, you need to provide a twig template that will be used to render the help data in the UI. The template needs to be configured in the step_imlementation_mapping configuration, using the inline_help_file_name key.

Configuration example:

pimcore_copilot:
automation_actions:
step_implementation_mapping:
variant_generator:
class: 'Pimcore\Bundle\CopilotBundle\AutomationAction\Messenger\Messages\VariantGeneratorMessage'
inline_help_file_name: '@PimcoreCopilot/InlineHelp/AutomationAction/Step/variant_generator.html.twig'

Result:

extending-automation-action-inline-help.pngextending-automation-action-inline-help.pngextending-automation-action-inline-help.png