How to write a new hook plugin¶
In this tutorial we will show you how to write a new hook plugin for the Springbok framework.
We are going to create a DeleteHook that will be called after each bulk has been processed. This hook will be used to mark concrete products as deleted.
Step 1: Create a new DeleteHook
First we need to create a new Hook class which can implement multiple hook interfaces. In this example we are going to use a AfterBulkHookInterface to collect ProductConcreteIds and then a AfterPipelineHookInterface to mark those ids as deleted.
To do this we need to create a new class that implements the AfterBulkHookInterface and AfterPipelineHookInterface.
<?php
namespace Pyz\Zed\SpringbokCommon\Business\Hook;
use Antiloop\Zed\Springbok\Dependency\Plugin\AfterBulkHookInterface;
use Antiloop\Zed\Springbok\Dependency\Plugin\AfterPipelineHookInterface;
use Flow\ETL\Rows;
use Spryker\Zed\Product\Business\ProductFacadeInterface;
class DeleteHook implements AfterBulkHookInterface, AfterPipelineHookInterface
{
/**
* @var array<int, int>
*/
protected array $productConcreteIds = [];
/**
* @var \Spryker\Zed\Product\Business\ProductFacadeInterface
*/
protected ProductFacadeInterface $productFacade;
/**
* @var string
*/
protected string $idColumn;
/**
* @param \Spryker\Zed\Product\Business\ProductFacadeInterface $productFacade
* @param string $idColumn
*/
public function __construct(ProductFacadeInterface $productFacade, string $idColumn)
{
$this->productFacade = $productFacade;
$this->idColumn = $idColumn;
}
/**
* Gets called after a bulk of rows is processed.
*
* @param \Flow\ETL\Rows $rows
*
* @return void
*/
public function afterBulk(Rows $rows): void
{
foreach ($rows as $row) {
$this->productConcreteIds[] = $row->get($this->idColumn)->value();
}
}
/**
* Gets called after the pipeline is executed.
*
* @return void
*/
public function afterPipeline(): void
{
foreach ($this->productConcreteIds as $idProductConcrete) {
$this->productFacade->touchProductConcreteDelete($idProductConcrete);
}
}
}
Step 2: Add the hook to the factory
Now that we have created the hook we need to add it to the factory so that we can instantiate it.
We are using the factory to create our actual Hook. We need to add a factory method to the SpringbokCommonCommunicationFactory class.
SpringbokCommonCommunicationFactory.php:
<?php
namespace Pyz\Zed\SpringbokCommon\Communication;
use Flow\ETL\Loader;
use Flow\ETL\Transformer;
use Pyz\Zed\SpringbokCommon\Business\Hook\DeleteHook;
class SpringbokCommonCommunicationFactory extends AbstractCommunicationFactory
{
/**
* @return \Pyz\Zed\SpringbokCommon\Business\Hook\DeleteHook
*/
public function createDeleteHook(string $idColumn): DeleteHook
{
return new DeleteHook($this->getProductFacade(), $idColumn);
}
}
Step 3: Create a plugin that will allow us to use the hook in a pipeline
To make springbok aware of the hook we need to create a plugin that will allow us to use the hook in a pipeline.
We need to create a new class that extends the AbstractPlugin class and implements the HookPluginInterface.
<?php
namespace Pyz\Zed\SpringbokCommon\Communication\Plugins;
use Antiloop\Zed\Springbok\Dependency\Plugin\HookInterface;
use Antiloop\Zed\Springbok\Dependency\Plugin\HookPluginInterface;
use Spryker\Zed\Kernel\Communication\AbstractPlugin;
/**
* @method \Pyz\Zed\SpringbokCommon\Communication\SpringbokCommonCommunicationFactory getFactory()
*/
class DeleteHookPlugin extends AbstractPlugin implements HookPluginInterface
{
/**
* @var string
*/
protected const NAME = 'delete-hook';
/**
* @return string
*/
public function getName(): string
{
return static::NAME;
}
/**
* @param array $xml
* @param array $options
*
* @return \Antiloop\Zed\Springbok\Dependency\Plugin\HookInterface
*/
public function build(array $xml, array $options): HookInterface
{
$idColumn = $xml['@idColumn'];
return $this->getFactory()->createDeleteHook($idColumn);
}
}
Step 4: Register the plugin
Finally, we need to register the plugin in the SpringbokDependencyProvider class.
<?php
namespace Pyz\Zed\Springbok;
use Antiloop\Zed\Springbok\SpringbokDependencyProvider as SpringbokSpringbokDependencyProvider;
use Pyz\Zed\SpringbokCommon\Communication\Plugins\DeleteHookPlugin;
class SpringbokDependencyProvider extends SpringbokSpringbokDependencyProvider
{
/**
* @return array<\Antiloop\Zed\Springbok\Dependency\Plugin\HookPluginInterface>
*/
protected function getHookPlugins(): array
{
return [
new DeleteHookPlugin(),
];
}
}
Step 5: Use the plugin
Now you can use the plugin in your Springbok pipeline configuration.
<delete-hook />
What we have done in this tutorial?
We have created a DeleteHook
We added the hook to the factory so that we can instantiate.
We created a plugin that will allow us to use the hook in a pipeline.
We added the plugin to the dependency provider so that it can be used in the pipeline.
Now you can use the plugin in your pipeline configuration file. And this concludes the tutorial on how to write a new hook plugin for the Springbok framework.
Further reading:
See Features for more information on which HookInterfaces are available.
See the How to write a new extractor plugin for more information on how to write a extractor plugin.
See the How to write a new transformer plugin for more information on how to write a transformer plugin.
See the How to write a new loader plugin for more information on how to write a loader plugin.
See the Pipeline documentation for more information on how to use the plugin in a pipeline.