How to Create a Custom Step¶
Previously we discussed about How to Create a New Connector
Let’s see how to go further by creating a custom step which sends a notification to an URL when a product export is finished.
Create our Step¶
We will begin by creating a NotifyStep with its configuration and a doExecute method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | <?php
namespace Acme\Bundle\DemoConnectorBundle\Step;
class NotifyStep extends AbstractStep
{
// here, the handler is a step element
protected $handler;
protected function doExecute(StepExecution $stepExecution)
{
// inject the step execution in the step item to be able to log summary info during execution
$this->handler->setStepExecution($stepExecution);
$this->handler->execute();
}
// as step configuration, we merge the step items configuration
public function getConfiguration()
{
$configuration = array();
foreach ($this->getConfigurableStepElements() as $stepElement) {
if ($stepElement instanceof AbstractConfigurableStepElement) {
foreach ($stepElement->getConfiguration() as $key => $value) {
if (!isset($configuration[$key]) || $value) {
$configuration[$key] = $value;
}
}
}
}
return $configuration;
}
// we inject the configuration in each step item
public function setConfiguration(array $config)
{
foreach ($this->getConfigurableStepElements() as $stepElement) {
if ($stepElement instanceof AbstractConfigurableStepElement) {
$stepElement->setConfiguration($config);
}
}
}
// these getter / setter are required to allow to configure from form and execute
public function getHandler()
{
return $this->handler;
}
public function setHandler(CurlHandler $handler)
{
$this->handler= $handler;
}
// step items which are configurable with the job edit form
public function getConfigurableStepElements()
{
return array('handler' => $this->getHandler());
}
}
|
Create our Step Element¶
Then we implement a Step Element, in our case, a handler responsible to send a ping request:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | <?php
namespace Acme\Bundle\DemoConnectorBundle\Handler;
// This element is configurable and knows the step execution
class CurlHandler extends AbstractConfigurableStepElement implements StepExecutionAwareInterface
{
protected $stepExecution;
protected $url;
protected $filePath;
// execute method uses configuration to do a curl exec
public function execute()
{
$filepath = $this->filePath;
$fields = sprintf("filepath=%s", urlencode($filepath));
$url = $this->url;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$result = curl_exec($ch);
if ($result === false) {
// we stop the whole job
throw new \Exception('Curl fail');
}
// we add custom details in summary
$this->stepExecution->addSummaryInfo('notified', 'yes');
curl_close($ch);
}
public function setStepExecution(StepExecution $stepExecution)
{
$this->stepExecution = $stepExecution;
}
// Getter and setter are required to be able to configure the Element
public function setFilePath($filePath)
{
$this->filePath = $filePath;
return $this;
}
public function getFilePath()
{
return $this->filePath;
}
public function setUrl($url)
{
$this->url = $url;
return $this;
}
public function getUrl()
{
return $this->url;
}
// Here, we define the form fields to use
public function getConfigurationFields()
{
return array(
'filePath' => array(
'options' => array(
'label' => 'pim_base_connector.export.filePath.label',
'help' => 'pim_base_connector.export.filePath.help'
)
),
'url' => array(
'options' => array(
'label' => 'pim_base_connector.export.url.label',
'help' => 'pim_base_connector.export.url.help'
)
)
);
}
}
|
Define the Step Element as Service¶
Add your step element to services.yml
to ensure that it is loaded and processed by DependencyInjection/AcmeDemoConnectorExtension
:
1 2 3 4 5 6 | parameters:
acme_democonnector.step.notify.class: Acme\Bundle\DemoConnectorBundle\Step\NotifyStep
acme_democonnector.handler.curl.class: Acme\Bundle\DemoConnectorBundle\Handler\CurlHandler
services:
acme_democonnector.handler.curl:
class: "%acme_democonnector.handler.curl.class%"
|
Configure our new Job¶
In Resources/config/batch_jobs.yml
, we use a first step to export products in csv and we configure the second one to send a notification:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | connector:
name: Demo Connector
jobs:
demo_custom_export:
title: pim_base_connector.jobs.demo_custom_export.title
type: export
steps:
export:
title: pim_base_connector.jobs.demo_custom_export.export.title
services:
reader: pim_base_connector.reader.doctrine.bulk_product
processor: pim_base_connector.processor.csv_serializer.product
writer: pim_base_connector.writer.product_file
notify:
title: pim_base_connector.jobs.demo_custom_export.notify.title
class: "%acme_democonnector.step.notify.class%"
services:
handler: acme_democonnector.handler.curl
|
You may have noticed that we use a custom class for the notification step and we define the handler as a step element.
That’s it, you can now connect to the PIM and begin to configure and use your new export!