Skip to content
Snippets Groups Projects
Commit 50f47a6b authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3418306 by alexpott, daniel.bosen: Add hook to allow an entity to have...

Issue #3418306 by alexpott, daniel.bosen: Add hook to allow an entity to have a counter ID but not be queued
parent 85f09a42
No related branches found
Tags 2.0.0-beta10
1 merge request!35Add hook to exclude entities from the queue
Pipeline #85492 passed
parameters:
ignoreErrors:
-
message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#"
count: 1
path: src/EntityQueuer.php
-
message: """
#^Call to deprecated method expectErrorMessageMatches\\(\\) of class PHPUnit\\\\Framework\\\\TestCase\\:
......
......@@ -9,6 +9,7 @@ use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityPublishedInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\vgwort\Plugin\AdvancedQueue\JobType\RegistrationNotification;
/**
......@@ -26,6 +27,11 @@ class EntityQueuer {
*/
private EntityJobMapper $entityJobMapper;
/**
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
private ModuleHandlerInterface $moduleHandler;
/**
* Constructs the EntityQueuer object.
*
......@@ -33,10 +39,19 @@ class EntityQueuer {
* The config factory service.
* @param \Drupal\vgwort\EntityJobMapper $entityJobMapper
* The entity job mapper service.
* @param \Drupal\Core\Extension\ModuleHandlerInterface|null $moduleHandler
* The module handler.
*/
public function __construct(ConfigFactoryInterface $configFactory, EntityJobMapper $entityJobMapper) {
public function __construct(ConfigFactoryInterface $configFactory, EntityJobMapper $entityJobMapper, ModuleHandlerInterface $moduleHandler = NULL) {
$this->config = $configFactory->get('vgwort.settings');
$this->entityJobMapper = $entityJobMapper;
// Provide BC so sites do not need to run a container rebuild.
// @todo remove in a few releases.
if ($moduleHandler === NULL) {
$moduleHandler = \Drupal::service('module_handler');
@trigger_error('Calling ' . __METHOD__ . '() without the $moduleHandler argument is deprecated in vgwort:2.0.0 and will be required in vgwort:2.1.0. See https://www.drupal.org/node/3418306', E_USER_DEPRECATED);
}
$this->moduleHandler = $moduleHandler;
}
/**
......@@ -67,6 +82,21 @@ class EntityQueuer {
return FALSE;
}
$queue_entity = TRUE;
$this->moduleHandler->invokeAllWith('vgwort_queue_entity', function (callable $hook) use ($entity, &$queue_entity) {
// Once an implementation has returned false do not call any other
// implementation.
if ($queue_entity) {
$queue_entity = $hook($entity);
}
});
if (!$queue_entity) {
// An implementation of hook_vgwort_queue_entity() has returned
// false.
return FALSE;
}
$queue = Queue::load('vgwort');
// If there is no queue fail silently. This ensures content can be inserted
// or updated prior to vgwort_post_update_create_queue() running.
......
......@@ -45,7 +45,7 @@ class CounterIdFieldItemList extends FieldItemList {
});
if (!$enabled_for_entity) {
// An implementation og hook_vgwort_enable_for_entity() has returned
// An implementation of hook_vgwort_enable_for_entity() has returned
// false.
return;
}
......
......@@ -17,6 +17,13 @@ function vgwort_test_vgwort_enable_for_entity(EntityInterface $entity): bool {
return !in_array($entity->id(), \Drupal::state()->get('vgwort_test_vgwort_enable_for_entity', []), TRUE);
}
/**
* Implements hook_vgwort_queue_entity().
*/
function vgwort_test_vgwort_queue_entity(EntityInterface $entity): bool {
return !in_array($entity->id(), \Drupal::state()->get('vgwort_test_vgwort_queue_entity', []), TRUE);
}
/**
* Implements hook_entity_type_alter().
*/
......
......@@ -519,6 +519,58 @@ class EntityQueueTest extends VgWortKernelTestBase {
$this->assertSame($jobs, $queue_backend->countJobs());
}
/**
* Tests hook_vgwort_entity_queue().
*/
public function testHookVgwortEntityQueue() {
// Exclude entities with an ID of 2 from the queue.
\Drupal::state()->set('vgwort_test_vgwort_queue_entity', ['2']);
$queue = Queue::load('vgwort');
$this->assertInstanceOf(Queue::class, $queue);
// Test that excluding specific entities from the queue does not exclude
// them all.
$jobs = self::JOB_COUNT;
$this->assertSame($jobs, $queue->getBackend()->countJobs());
$entity_storage = $this->container->get('entity_type.manager')->getStorage(static::ENTITY_TYPE);
/** @var \Drupal\entity_test\Entity\EntityTestRevPub $entity */
$entity = $entity_storage->create([
'vgwort_test' => [
'card_number' => '123123123',
'firstname' => 'Bob',
'surname' => 'Jones',
'agency_abbr' => '',
],
'text' => 'Some text',
'name' => 'A title',
]);
$entity->save();
$jobs[Job::STATE_QUEUED] = '1';
$this->assertSame($jobs, $queue->getBackend()->countJobs());
// Test that entities can be excluded from the queue but still have a
// counter ID.
/** @var \Drupal\entity_test\Entity\EntityTestRevPub $another_entity */
$another_entity = $entity_storage->create([
'vgwort_test' => [
'card_number' => '123123123',
'firstname' => 'Bob',
'surname' => 'Jones',
'agency_abbr' => '',
],
'text' => 'Some text',
'name' => 'A title',
]);
$another_entity->save();
$this->assertSame('2', (string) $another_entity->id());
$jobs[Job::STATE_QUEUED] = '1';
$this->assertSame($jobs, $queue->getBackend()->countJobs());
$this->assertNull($this->container->get('vgwort.entity_job_mapper')->getJob($another_entity));
$this->assertStringEndsWith($another_entity->uuid(), $another_entity->vgwort_counter_id->value);
}
/**
* Determines if an entity is in the map table.
*
......
......@@ -6,7 +6,7 @@
*/
/**
* Determines if an entity should be sent to VG Wort.
* Determines if an entity should have VG Wort counter ID.
*
* This hook can be used to exclude entities that the site does not have the
* rights to send to VG Wort. See \Drupal\vgwort\Api\NewMessage for more
......@@ -23,6 +23,28 @@ function hook_vgwort_enable_for_entity(\Drupal\Core\Entity\EntityInterface $enti
return $entity->bundle() !== 'not_my_content';
}
/**
* Determines if entity information should be queued for sending to VG Wort.
*
* NOTE: this hook is for a strange use-case where you want to add the counter
* ID to content but do not want to send the entity to VG Wort. Ideally if you
* implement this hook you have a plan to remove it in the future. Normally, you
* should implement hook_vgwort_enable_for_entity() to exclude an entity
* completely from VG Wort.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity to check.
*
* @return bool
* TRUE if the entity should be queued for sending to VG Wort, FALSE if not.
*/
function hook_vgwort_queue_entity(\Drupal\Core\Entity\EntityInterface $entity): bool {
return match ($entity->bundle()) {
'not_my_content' => FALSE,
default => TRUE,
};
}
/**
* Overrides the field used to determine the VG Wort counter ID.
*
......
......@@ -12,7 +12,7 @@ services:
arguments: ['@vgwort.participant_list_manager', '@entity_type.manager', '@renderer', '@config.factory', '@module_handler']
vgwort.entity_queuer:
class: Drupal\vgwort\EntityQueuer
arguments: ['@config.factory', '@vgwort.entity_job_mapper']
arguments: ['@config.factory', '@vgwort.entity_job_mapper', '@module_handler']
vgwort.entity_job_mapper:
class: Drupal\vgwort\EntityJobMapper
arguments: ['@database', '@entity_type.manager', '@lock']
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment