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 Generic 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\GenericExecutionEngineBundle\Messenger\Messages\GenericExecutionEngineMessageInterface
(there is an abstract classPimcore\Bundle\GenericExecutionEngineBundle\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\GenericExecutionEngineBundle\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 Generic Execution Engine documentation in the pimcore core.
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.
Make sure to use the correct engine in the configuration as seen in the following example:
pimcore_copilot:
automation_actions:
step_implementation_mapping:
variant_generator:
class: 'Pimcore\Bundle\PimcoreCopilotBundle\AutomationAction\Messenger\Messages\Generic\GenericVariantGeneratorMessage'
engine: !php/const Pimcore\Bundle\CopilotBundle\JobExecutionEngine\Enum\ExecutionEngines::GENERIC_EXECUTION_ENGINE
asset_relation_object_name:
class: 'Pimcore\Bundle\CopilotBundle\AutomationAction\Messenger\Messages\Generic\GenericAssetObjectRelationByNameMessage'
engine: !php/const Pimcore\Bundle\CopilotBundle\JobExecutionEngine\Enum\ExecutionEngines::GENERIC_EXECUTION_ENGINE
asset_relation_object_meta:
class: 'Pimcore\Bundle\CopilotBundle\AutomationAction\Messenger\Messages\Generic\GenericAssetObjectRelationByMetaMessage'
engine: !php/const Pimcore\Bundle\CopilotBundle\JobExecutionEngine\Enum\ExecutionEngines::GENERIC_EXECUTION_ENGINE
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\GenericExecutionEngineBundle\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');
}
}
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'
engine: !php/const Pimcore\Bundle\CopilotBundle\JobExecutionEngine\Enum\ExecutionEngines::GENERIC_EXECUTION_ENGINE
Result:
Selection Processing Mode
You can add a selection processing mode to your custom step.
This will determine how the selected elements are handled in the automation action.
For details please see the Generic Execution Engine
documentation here.
Configuration example:
generic_send_notification:
class: 'Pimcore\Bundle\CopilotBundle\AutomationAction\Messenger\Messages\Generic\GenericSendNotificationMessage'
inline_help_file_name: '@PimcoreCopilot/InlineHelp/AutomationAction/Step/send_notification.html.twig'
engine: !php/const Pimcore\Bundle\CopilotBundle\JobExecutionEngine\Enum\ExecutionEngines::GENERIC_EXECUTION_ENGINE
selectionProcessingMode: !php/const Pimcore\Bundle\GenericExecutionEngineBundle\Utils\Enums\SelectionProcessingMode::ONCE
Automation Action Triggered By Event
If an automation action gets triggered by an event, the event data, based on the triggered event, is available as environment variable. Additionally, the element associated with the workflow or pimcore events gets passed as selected element to the automation action.
Workflow event environment data:
[
'eventArguments' => [
'workflow_name' => 'Workflow Name',
'transition' => [
'name' => 'Transition Name',
'options' => [ ... ],
'froms' => [ ... ],
'tos' => [ ... ]
],
'marking' => [
'places' => [ ... ]
]
]
]
Pimcore event environment data:
[
'eventArguments' => [
'saveVersionOnly' => true,
]
]