Skip to content

Commit

Permalink
feat: Use destruction events at a later runtime
Browse files Browse the repository at this point in the history
Fixes #444
  • Loading branch information
mglaman authored Dec 12, 2023
1 parent 183605b commit ec2cee0
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 23 deletions.
16 changes: 3 additions & 13 deletions modules/next/next.module
Original file line number Diff line number Diff line change
Expand Up @@ -69,31 +69,21 @@ function next_next_site_preview_alter(array &$preview, array $context) {
*/
function next_entity_insert(EntityInterface $entity) {
$event = EntityActionEvent::createFromEntity($entity, EntityActionEventInterface::INSERT_ACTION);
drupal_register_shutdown_function('_next_dispatch_entity_action_event', $event);
\Drupal::service('next.entity_action_event_dispatcher')->addEvent($event);
}

/**
* Implements hook_entity_update().
*/
function next_entity_update(EntityInterface $entity) {
$event = EntityActionEvent::createFromEntity($entity, EntityActionEventInterface::UPDATE_ACTION);
drupal_register_shutdown_function('_next_dispatch_entity_action_event', $event);
\Drupal::service('next.entity_action_event_dispatcher')->addEvent($event);
}

/**
* Implements hook_entity_predelete().
*/
function next_entity_predelete(EntityInterface $entity) {
$event = EntityActionEvent::createFromEntity($entity, EntityActionEventInterface::DELETE_ACTION);
drupal_register_shutdown_function('_next_dispatch_entity_action_event', $event);
}

/**
* Helper to dispatch an entity action event.
*
* @param \Drupal\next\Event\EntityActionEventInterface $event
* The entity action event.
*/
function _next_dispatch_entity_action_event(EntityActionEventInterface $event) {
\Drupal::service('event_dispatcher')->dispatch($event, EntityEvents::ENTITY_ACTION);
\Drupal::service('next.entity_action_event_dispatcher')->addEvent($event);
}
6 changes: 6 additions & 0 deletions modules/next/next.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,9 @@ services:
]
tags:
- { name: event_subscriber }

next.entity_action_event_dispatcher:
class: Drupal\next\EventSubscriber\EntityActionEventDispatcher
arguments: ['@event_dispatcher']
tags:
- { name: needs_destruction }
49 changes: 49 additions & 0 deletions modules/next/src/EventSubscriber/EntityActionEventDispatcher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace Drupal\next\EventSubscriber;

use Drupal\Core\DestructableInterface;
use Drupal\next\Event\EntityActionEvent;
use Drupal\next\Event\EntityEvents;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

/**
* Defines an event subscriber for dispatching entity events.
*/
final class EntityActionEventDispatcher implements DestructableInterface {

/**
* The events to dispach.
*
* @var \Drupal\next\Event\EntityActionEvent[]
*/
private array $events = [];

/**
* EntityActionEventDispatcher constructor.
*/
public function __construct(
private EventDispatcherInterface $eventDispatcher
) {
}

/**
* Adds an event to be dispatched at the end of the request.
*
* @param \Drupal\next\Event\EntityActionEvent $event
* The event.
*/
public function addEvent(EntityActionEvent $event): void {
$this->events[] = $event;
}

/**
* {@inheritdoc}
*/
public function destruct() {
foreach ($this->events as $event) {
$this->eventDispatcher->dispatch($event, EntityEvents::ENTITY_ACTION);
}
}

}
8 changes: 5 additions & 3 deletions modules/next/tests/src/Kernel/Event/EntityActionEventTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use Drupal\KernelTests\KernelTestBase;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\node\Traits\NodeCreationTrait;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
* Tests the EntityActionEvent.
Expand Down Expand Up @@ -60,17 +62,17 @@ public function testEntityActionEvents() {

// Insert.
$page->save();
_drupal_shutdown_function();
$this->container->get('kernel')->terminate(Request::create('/'), new Response());
$this->assertLogsContains("Event next.entity.action dispatched for entity A page and action insert.");

// Update.
$page->set('title', 'A page updated')->save();
_drupal_shutdown_function();
$this->container->get('kernel')->terminate(Request::create('/'), new Response());
$this->assertLogsContains("Event next.entity.action dispatched for entity A page updated and action update.");

// Delete.
$page->delete();
_drupal_shutdown_function();
$this->container->get('kernel')->terminate(Request::create('/'), new Response());
$this->assertLogsContains("Event next.entity.action dispatched for entity A page updated and action delete.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use Drupal\KernelTests\KernelTestBase;
use Drupal\next\Entity\NextEntityTypeConfig;
use Drupal\Tests\node\Traits\NodeCreationTrait;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
* Tests the EntityRevalidatedEvent.
Expand Down Expand Up @@ -70,17 +72,17 @@ public function testEntityRevalidatedEvents() {

// Insert.
$page->save();
_drupal_shutdown_function();
$this->container->get('kernel')->terminate(Request::create('/'), new Response());
$this->assertLogsContains("Entity A page, action insert, revalidated 0.");

// Update.
$page->set('title', 'A page updated')->save();
_drupal_shutdown_function();
$this->container->get('kernel')->terminate(Request::create('/'), new Response());
$this->assertLogsContains("Entity A page updated, action update, revalidated 0.");

// Delete.
$page->delete();
_drupal_shutdown_function();
$this->container->get('kernel')->terminate(Request::create('/'), new Response());
$this->assertLogsContains("Entity A page updated, action delete, revalidated 0.");
}

Expand Down
10 changes: 6 additions & 4 deletions modules/next/tests/src/Kernel/Plugin/PathRevalidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use Drupal\Tests\node\Traits\NodeCreationTrait;
use GuzzleHttp\ClientInterface;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
* Tests the path revalidator plugin.
Expand Down Expand Up @@ -80,13 +82,13 @@ public function testRevalidate() {
$client->request('GET', $this->any())->shouldNotBeCalled();
$page = $this->createNode();
$page->save();
_drupal_shutdown_function();
$this->container->get('kernel')->terminate(Request::create('/'), new Response());

$client->request('GET', 'http://blog.com/api/revalidate?slug=/node/2')->shouldBeCalled();
$blog_site->setRevalidateUrl('http://blog.com/api/revalidate')->save();
$page = $this->createNode();
$page->save();
_drupal_shutdown_function();
$this->container->get('kernel')->terminate(Request::create('/'), new Response());

$marketing = NextSite::create([
'id' => 'marketing',
Expand All @@ -105,7 +107,7 @@ public function testRevalidate() {
$client->request('GET', 'http://blog.com/api/revalidate?slug=/node/3')->shouldBeCalled();
$page = $this->createNode();
$page->save();
_drupal_shutdown_function();
$this->container->get('kernel')->terminate(Request::create('/'), new Response());

$entity_type_config->setRevalidatorConfiguration('path', [
'additional_paths' => "/\n/blog",
Expand All @@ -119,7 +121,7 @@ public function testRevalidate() {
$client->request('GET', 'http://blog.com/api/revalidate?slug=/blog')->shouldBeCalled();
$page = $this->createNode();
$page->save();
_drupal_shutdown_function();
$this->container->get('kernel')->terminate(Request::create('/'), new Response());
}

}

0 comments on commit ec2cee0

Please sign in to comment.