Skip to main content
Category:

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.

 

 

Riadh Rahmi

Senior Web Developer PHP/Drupal & Laravel

I am a senior web developer, I have experience in planning and developing large scale dynamic web solutions especially in Drupal & Laravel.

Web Posts

Search

Page Facebook