From f16bf66c1e0c9f8891e2bfb5f643a70c7d3539ba Mon Sep 17 00:00:00 2001 From: acrosman <acrosman@65233.no-reply.drupal.org> Date: Tue, 2 Jul 2019 14:59:53 -0400 Subject: [PATCH] Issue #3038688 by AaronBauman, acrosman: Add "pull allowed", analogous to "push allowed" --- .../SalesforceExampleSubscriber.php | 32 +++++++++++++++++++ .../src/Event/SalesforcePullEvent.php | 26 +++++++++++++++ .../src/Plugin/QueueWorker/PullBase.php | 12 +++++-- .../tests/src/Unit/PullBaseTest.php | 3 +- 4 files changed, 70 insertions(+), 3 deletions(-) diff --git a/modules/salesforce_example/src/EventSubscriber/SalesforceExampleSubscriber.php b/modules/salesforce_example/src/EventSubscriber/SalesforceExampleSubscriber.php index 3b34f3c8..e6bc6a4c 100644 --- a/modules/salesforce_example/src/EventSubscriber/SalesforceExampleSubscriber.php +++ b/modules/salesforce_example/src/EventSubscriber/SalesforceExampleSubscriber.php @@ -172,6 +172,37 @@ class SalesforceExampleSubscriber implements EventSubscriberInterface { } } + /** + * PULL_PREPULL event subscriber example. + */ + public function pullPrepull(SalesforcePullEvent $event) { + // For the "contact" mapping, if the SF record is marked "Inactive", do not + // pull the record and block the user account. + $mapping = $event->getMapping(); + switch ($mapping->id()) { + case 'contact': + $sf_data = $event->getMappedObject()->getSalesforceRecord(); + /** @var \Drupal\user\Entity\User $account */ + $account = $event->getEntity(); + try { + if (!$sf_data->field('Inactive__c')) { + // If the SF record is not marked "Inactive", proceed as normal. + return; + } + } + catch (\Exception $e) { + // Fall through if "Inactive" field was not found. + } + // If we got here, SF record is marked inactive. Don't pull it. + $event->disallowPull(); + if (!$account->isNew()) { + // If this is an update to an existing account, block the account. + // If this is a new account, it won't be created. + $account->block()->save(); + } + } + } + /** * {@inheritdoc} */ @@ -183,6 +214,7 @@ class SalesforceExampleSubscriber implements EventSubscriberInterface { SalesforceEvents::PUSH_FAIL => 'pushFail', SalesforceEvents::PULL_PRESAVE => 'pullPresave', SalesforceEvents::PULL_QUERY => 'pullQueryAlter', + SalesforceEvents::PULL_PREPULL => 'pullPrepull', ]; return $events; } diff --git a/modules/salesforce_mapping/src/Event/SalesforcePullEvent.php b/modules/salesforce_mapping/src/Event/SalesforcePullEvent.php index 7bd7822a..bb9c78cf 100644 --- a/modules/salesforce_mapping/src/Event/SalesforcePullEvent.php +++ b/modules/salesforce_mapping/src/Event/SalesforcePullEvent.php @@ -43,6 +43,13 @@ class SalesforcePullEvent extends SalesforceBaseEvent { */ protected $op; + /** + * TRUE or FALSE to indicate if pull is allowed for this event. + * + * @var bool + */ + protected $pullAllowed; + /** * SalesforcePullEvent constructor. * @@ -56,6 +63,7 @@ class SalesforcePullEvent extends SalesforceBaseEvent { $this->entity = $mappedObject->getMappedEntity(); $this->mapping = $mappedObject->getMapping(); $this->op = $op; + $this->pullAllowed = TRUE; } /** @@ -103,4 +111,22 @@ class SalesforcePullEvent extends SalesforceBaseEvent { return $this->op; } + /** + * Disallow and stop pull for the current queue item. + */ + public function disallowPull() { + $this->pullAllowed = FALSE; + return $this; + } + + /** + * Will return FALSE if any subscribers have called disallowPull(). + * + * @return bool + * TRUE if pull is allowed, false otherwise. + */ + public function isPullAllowed() { + return $this->pullAllowed; + } + } diff --git a/modules/salesforce_pull/src/Plugin/QueueWorker/PullBase.php b/modules/salesforce_pull/src/Plugin/QueueWorker/PullBase.php index ec0dfe00..e7d7955f 100644 --- a/modules/salesforce_pull/src/Plugin/QueueWorker/PullBase.php +++ b/modules/salesforce_pull/src/Plugin/QueueWorker/PullBase.php @@ -204,10 +204,14 @@ abstract class PullBase extends QueueWorkerBase implements ContainerFactoryPlugi } } - $this->eventDispatcher->dispatch( + $event = $this->eventDispatcher->dispatch( SalesforceEvents::PULL_PREPULL, new SalesforcePullEvent($mapped_object, MappingConstants::SALESFORCE_MAPPING_SYNC_SF_UPDATE) ); + if (!$event->isPullAllowed()) { + $this->eventDispatcher->dispatch(SalesforceEvents::NOTICE, new SalesforceNoticeEvent(NULL, 'Pull was not allowed for %label with %sfid', ['%label' => $entity->label(), '%sfid' => (string) $sf_object->id()])); + return FALSE; + } if ($sf_record_updated > $entity_updated || $mapped_object->force_pull || $force_pull) { // Set fields values on the Drupal entity. @@ -272,10 +276,14 @@ abstract class PullBase extends QueueWorkerBase implements ContainerFactoryPlugi ->setDrupalEntity($entity) ->setSalesforceRecord($sf_object); - $this->eventDispatcher->dispatch( + $event = $this->eventDispatcher->dispatch( SalesforceEvents::PULL_PREPULL, new SalesforcePullEvent($mapped_object, MappingConstants::SALESFORCE_MAPPING_SYNC_SF_CREATE) ); + if (!$event->isPullAllowed()) { + $this->eventDispatcher->dispatch(SalesforceEvents::NOTICE, new SalesforceNoticeEvent(NULL, 'Pull was not allowed for %label with %sfid', ['%label' => $entity->label(), '%sfid' => (string) $sf_object->id()])); + return FALSE; + } $mapped_object->pull(); diff --git a/modules/salesforce_pull/tests/src/Unit/PullBaseTest.php b/modules/salesforce_pull/tests/src/Unit/PullBaseTest.php index a4410e42..da4f47b3 100644 --- a/modules/salesforce_pull/tests/src/Unit/PullBaseTest.php +++ b/modules/salesforce_pull/tests/src/Unit/PullBaseTest.php @@ -8,6 +8,7 @@ use Drupal\Core\Entity\EntityStorageBase; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Field\Plugin\Field\FieldType\StringItem; +use Drupal\salesforce_mapping\Event\SalesforcePullEvent; use Drupal\Tests\UnitTestCase; use Drupal\salesforce\Rest\RestClientInterface; use Drupal\salesforce\SFID; @@ -198,7 +199,7 @@ class PullBaseTest extends UnitTestCase { $this->ed ->expects($this->any()) ->method('dispatch') - ->willReturn(NULL); + ->willReturn(new SalesforcePullEvent($this->mappedObject, MappingConstants::SALESFORCE_MAPPING_SYNC_SF_UPDATE)); $container = new ContainerBuilder(); $container->set('salesforce.client', $this->sfapi); -- GitLab