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 classPimcore\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: