Skip to content

Commit

Permalink
Move over to event handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-vessey committed Apr 11, 2024
1 parent 49ac2b0 commit a323d51
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 22 deletions.
10 changes: 8 additions & 2 deletions embargo.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ services:
- '@entity_type.manager'
- '@datetime.time'
- '@date.formatter'
- '@event_dispatcher'
embargo.route_subscriber:
class: Drupal\embargo\Routing\EmbargoRouteSubscriber
arguments: ['@entity_type.manager']
tags:
- { name: event_subscriber }
- { name: 'event_subscriber' }
embargo.ip_range_redirect:
class: '\Drupal\embargo\EventSubscriber\IpRangeRedirect'
arguments:
Expand Down Expand Up @@ -56,4 +57,9 @@ services:
- '@request_stack'
- '@entity_type.manager'
tags:
- { name: cache.context }
- { name: 'cache.context' }
embargo.tagging_event_subscriber:
class: Drupal\embargo\EventSubscriber\TaggingEventSubscriber
tags:
- { name: 'event_subscriber' }

5 changes: 4 additions & 1 deletion src/Access/QueryTagger.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Drupal\islandora_hierarchical_access\Access\QueryConjunctionTrait;
use Drupal\islandora_hierarchical_access\TaggedTargetsTrait;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

/**
* Handles tagging entity queries with access restrictions for embargoes.
Expand All @@ -32,14 +33,16 @@ public function __construct(
Connection $database,
EntityTypeManagerInterface $entity_type_manager,
TimeInterface $time,
DateFormatterInterface $date_formatter
DateFormatterInterface $date_formatter,
EventDispatcherInterface $event_dispatcher,
) {
$this->user = $user;
$this->currentIp = $request_stack->getCurrentRequest()->getClientIp();
$this->database = $database;
$this->entityTypeManager = $entity_type_manager;
$this->time = $time;
$this->dateFormatter = $date_formatter;
$this->setEventDispatcher($event_dispatcher);
}

/**
Expand Down
55 changes: 38 additions & 17 deletions src/EmbargoExistenceQueryTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\embargo\Event\TagExclusionEvent;
use Drupal\embargo\Event\TagInclusionEvent;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

/**
* Helper trait; facilitate filtering of embargoed entities.
Expand Down Expand Up @@ -58,6 +61,13 @@ trait EmbargoExistenceQueryTrait {
*/
protected DateFormatterInterface $dateFormatter;

/**
* The event dispatcher service.
*
* @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface
*/
protected EventDispatcherInterface $eventDispatcher;

/**
* Helper; apply existence checks to a node(-like) table.
*
Expand All @@ -80,6 +90,30 @@ protected function applyExistenceQuery(
);
}

/**
* Set the event dispatcher service.
*
* @param \Symfony\Contracts\EventDispatcher\EventDispatcherInterface $event_dispatcher
* The event dispatcher service to set.
*
* @return \Drupal\embargo\EmbargoExistenceQueryTrait|\Drupal\embargo\Access\QueryTagger|\Drupal\embargo\EventSubscriber\IslandoraHierarchicalAccessEventSubscriber
* The current instance; fluent interface.
*/
protected function setEventDispatcher(EventDispatcherInterface $event_dispatcher) : self {
$this->eventDispatcher = $event_dispatcher;
return $this;
}

/**
* Get the event dispatcher service.
*
* @return \Symfony\Contracts\EventDispatcher\EventDispatcherInterface
* The event dispatcher service.
*/
protected function getEventDispatch() : EventDispatcherInterface {
return $this->eventDispatcher ?? \Drupal::service('event_dispatcher');
}

/**
* Build out condition for matching embargo entities.
*
Expand All @@ -90,17 +124,9 @@ protected function applyExistenceQuery(
* The condition to attach.
*/
protected function buildInclusionBaseCondition(SelectInterface $query) : ConditionInterface {
$condition = $query->orConditionGroup();
$dispatched_event = $this->getEventDispatch()->dispatch(new TagInclusionEvent($query));

$embargo_alias = $query->getMetaData('embargo_alias');
$target_aliases = $query->getMetaData('embargo_target_aliases');

$condition->where(strtr('!field IN (!targets)', [
'!field' => "{$embargo_alias}.embargoed_node",
'!targets' => implode(', ', $target_aliases),
]));

return $condition;
return $dispatched_event->getCondition();
}

/**
Expand All @@ -113,14 +139,9 @@ protected function buildInclusionBaseCondition(SelectInterface $query) : Conditi
* The condition to attach.
*/
protected function buildExclusionBaseCondition(SelectInterface $query) : ConditionInterface {
$condition = $query->orConditionGroup();

$embargo_alias = $query->getMetaData('embargo_alias');
$unexpired_alias = $query->getMetaData('embargo_unexpired_alias');

$condition->where("{$unexpired_alias}.embargoed_node = {$embargo_alias}.embargoed_node");
$dispatched_event = $this->getEventDispatch()->dispatch(new TagExclusionEvent($query));

return $condition;
return $dispatched_event->getCondition();
}

/**
Expand Down
70 changes: 70 additions & 0 deletions src/Event/AbstractTagEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace Drupal\embargo\Event;

use Drupal\Core\Database\Query\ConditionInterface;
use Drupal\Core\Database\Query\SelectInterface;
use Symfony\Contracts\EventDispatcher\Event;

/**
* Abstract base tag event class.
*/
abstract class AbstractTagEvent extends Event {

/**
* The build condition.
*
* @var \Drupal\Core\Database\Query\ConditionInterface
*/
protected ConditionInterface $condition;

/**
* Constructor.
*/
public function __construct(
protected SelectInterface $query,
) {
$this->condition = $this->query->orConditionGroup();
}

/**
* Get the query upon which to act.
*
* @return \Drupal\Core\Database\Query\SelectInterface
* The query upon which we are to act.
*/
public function getQuery() : SelectInterface {
return $this->query;
}

/**
* Get the current condition.
*
* @return \Drupal\Core\Database\Query\ConditionInterface
* The current condition.
*/
public function getCondition() : ConditionInterface {
return $this->condition;
}

/**
* Get the base "embargo" table alias.
*
* @return string
* The base "embargo" alias, as used in the query.
*/
public function getEmbargoAlias() : string {
return $this->query->getMetaData('embargo_alias');
}

/**
* Get the base query columns representing node IDs to find embargoes.
*
* @return string[]
* The column aliases representing node IDs.
*/
public function getTargetAliases() : array {
return $this->query->getMetaData('embargo_target_aliases');
}

}
14 changes: 14 additions & 0 deletions src/Event/EmbargoEvents.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Drupal\embargo\Event;

/**
* Enumerate our event types.
*/
final class EmbargoEvents {

const TAG_INCLUSION = TagInclusionEvent::class;

const TAG_EXCLUSION = TagExclusionEvent::class;

}
20 changes: 20 additions & 0 deletions src/Event/TagExclusionEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Drupal\embargo\Event;

/**
* Query tagging exclusion event.
*/
class TagExclusionEvent extends AbstractTagEvent {

/**
* Get the "unexpired" embargo alias.
*
* @return string
* The table alias.
*/
public function getUnexpiredAlias() : string {
return $this->query->getMetaData('embargo_unexpired_alias');
}

}
10 changes: 10 additions & 0 deletions src/Event/TagInclusionEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Drupal\embargo\Event;

/**
* Query tagging inclusion event.
*/
class TagInclusionEvent extends AbstractTagEvent {

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@ public function __construct(
* {@inheritDoc}
*/
public static function create(ContainerInterface $container) : self {
return new static(
return (new static(
$container->get('current_user'),
$container->get('request_stack'),
$container->get('database'),
$container->get('entity_type.manager'),
$container->get('datetime.time'),
$container->get('date.formatter'),
);
))
->setEventDispatcher($container->get('event_dispatcher'));
}

/**
Expand Down
48 changes: 48 additions & 0 deletions src/EventSubscriber/TaggingEventSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Drupal\embargo\EventSubscriber;

use Drupal\embargo\Event\EmbargoEvents;
use Drupal\embargo\Event\TagExclusionEvent;
use Drupal\embargo\Event\TagInclusionEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
* Query tagging event subscriber.
*/
class TaggingEventSubscriber implements EventSubscriberInterface {

/**
* {@inheritDoc}
*/
public static function getSubscribedEvents() : array {
return [
EmbargoEvents::TAG_INCLUSION => 'inclusion',
EmbargoEvents::TAG_EXCLUSION => 'exclusion',
];
}

/**
* Event handler; tagging inclusion event.
*
* @param \Drupal\embargo\Event\TagInclusionEvent $event
* The event being handled.
*/
public function inclusion(TagInclusionEvent $event) : void {
$event->getCondition()->where(strtr('!field IN (!targets)', [
'!field' => "{$event->getEmbargoAlias()}.embargoed_node",
'!targets' => implode(', ', $event->getTargetAliases()),
]));
}

/**
* Event handler; tagging exclusion event.
*
* @param \Drupal\embargo\Event\TagExclusionEvent $event
* The event being handled.
*/
public function exclusion(TagExclusionEvent $event) : void {
$event->getCondition()->where("{$event->getUnexpiredAlias()}.embargoed_node = {$event->getEmbargoAlias()}.embargoed_node");
}

}

0 comments on commit a323d51

Please sign in to comment.