Rules is a tool that enables you to define automatic, conditionally executed actions, triggered by various types of events. in this tutorial I’ll show you how to create custom rules event in Drupal 8.
Create a module
In Drupal 8, it is necessary to create an info.yml
file that contains the metadata for every custom module. you will need to create the codimth_custom_rules_event.info.yml
file under the modules/custom/codimth_custom_rules_event
folder. Inside this file enter following:
name: Codimth Custom Rules Event
description: Create a custom rules Event
package: CodimTh
type: module
core: 8.x
dependencies:
- rules
Once the folder and file has been created, you can go to your Drupal dashboard and enable the custom module we have just created.
Create 'Before Delete an entity' Event
Rules uses the Symfony event dispatching system to trigger events and invoke reaction rules when an event occurs. A module that wants to provide events can do so without having a module dependency to Rules -dispatching standard Symfony events in code is enough.
In order to make an event known to Rules a codimth_custom_rules_event.rules.events.yml
file has to be provided to register the event. Inside this file enter following:
codimth_custom_rules_event_entity_predelete:
label: 'Before delete an entity'
deriver: '\Drupal\codimth_custom_rules_event\Plugin\RulesEvent\EntityPredeleteDeriver'
class: '\Drupal\rules\EventHandler\ConfigurableEventHandlerEntityBundle'
Create a RulesEvent Deriver Class
Now, we’ll create a class that will contain the logic of our event. we’ll place our EntityPredeleteDeriver.php
class under the modules/custom/codimth_custom_rules_event/src/Plugin/RulesEvent
directory.
Now, this is what the class file should contain in the end:
<?php
namespace Drupal\codimth_custom_rules_event\Plugin\RulesEvent;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Derives entity Predelete plugin definitions based on content entity types.
*/
class EntityPredeleteDeriver extends DeriverBase implements ContainerDeriverInterface {
use StringTranslationTrait;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Creates a new EntityDeleteDeriver object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
* The string translation service.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, TranslationInterface $string_translation) {
$this->entityTypeManager = $entity_type_manager;
$this->stringTranslation = $string_translation;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $base_plugin_id) {
return new static($container->get('entity_type.manager'), $container->get('string_translation'));
}
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) {
// Only allow content entities and ignore configuration entities.
if (!$entity_type instanceof ContentEntityTypeInterface) {
continue;
}
$this->derivatives[$entity_type_id] = [
'label' => $this->t('Before deleting @entity_type', ['@entity_type' => $entity_type->getLowercaseLabel()]),
'category' => $entity_type->getLabel(),
'entity_type_id' => $entity_type_id,
'context' => [
$entity_type_id => [
'type' => "entity:$entity_type_id",
'label' => $entity_type->getLabel(),
],
],
] + $base_plugin_definition;
}
return $this->derivatives;
}
}
Invoking the event
<?php
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\rules\Event\EntityEvent;
/**
* Implements hook_entity_predelete().
*/
function codimth_custom_rules_event_entity_predelete(EntityInterface $entity) {
if ($entity instanceof ContentEntityInterface) {
$entity_type_id = $entity->getEntityTypeId();
$event = new EntityEvent($entity, [$entity_type_id => $entity]);
$event_dispatcher = \Drupal::service('event_dispatcher');
$event_dispatcher->dispatch("codimth_custom_rules_event_entity_predelete:$entity_type_id", $event);
}
}
Now, go back to your site, and you should be able to see the Action you have just created. follow these screenshots to know how to use it.
Next steps
- Clear your Drupal 8 caches. To do this I use this Drush command:
drush cr
if you don’t currently use Drush, I highly recommend using it, or the Drupal Console. - I hope you found this article useful. let me know if you have any questions and I’ll be happy to answer them.