diff --git a/modules/salesforce_example/src/EventSubscriber/SalesforceExampleSubscriber.php b/modules/salesforce_example/src/EventSubscriber/SalesforceExampleSubscriber.php index 6f8f65090a5da08a0ccec9655930c24320c22fd8..96536fcf85e2b88058a744dbe117df3374da5876 100644 --- a/modules/salesforce_example/src/EventSubscriber/SalesforceExampleSubscriber.php +++ b/modules/salesforce_example/src/EventSubscriber/SalesforceExampleSubscriber.php @@ -4,6 +4,7 @@ namespace Drupal\salesforce_example\EventSubscriber; use Drupal\salesforce\Event\SalesforceEvents; use Drupal\salesforce_mapping\Event\SalesforcePushOpEvent; +use Drupal\salesforce_mapping\Event\SalesforcePushAllowedEvent; use Drupal\salesforce_mapping\Event\SalesforcePushParamsEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Drupal\salesforce\Exception; @@ -20,11 +21,11 @@ class SalesforceExampleSubscriber implements EventSubscriberInterface { /** * */ - public function pushAllowed(SalesforcePushOpEvent $event) { + public function pushAllowed(SalesforcePushAllowedEvent $event) { /** @var \Drupal\Core\Entity\Entity $entity */ $entity = $event->getEntity(); if ($entity && $entity->getEntityTypeId() == 'unpushable_entity') { - throw new Exception('Prevent push of Unpushable Entity'); + $event->disallowPush(); } } diff --git a/modules/salesforce_mapping/src/Event/SalesforcePushAllowedEvent.php b/modules/salesforce_mapping/src/Event/SalesforcePushAllowedEvent.php new file mode 100644 index 0000000000000000000000000000000000000000..fd6a4774574054606cefe9386c9894b32e61812c --- /dev/null +++ b/modules/salesforce_mapping/src/Event/SalesforcePushAllowedEvent.php @@ -0,0 +1,63 @@ +<?php + +namespace Drupal\salesforce_mapping\Event; + +use Drupal\salesforce_mapping\Entity\MappedObjectInterface; + +/** + * + */ +class SalesforcePushAllowedEvent extends SalesforcePushOpEvent { + + protected $op; + protected $push_allowed; + + /** + * {@inheritdoc} + * + * SalesforcePushAllowedEvent is fired when PushParams are not available, for + * example on SalesforceEvents::PUSH_ALLOWED, before any entities have been + * loaded. + * + * @param \Drupal\salesforce_mapping\Entity\MappedObjectInterface $mapped_object + * @param string $op + * One of + * Drupal\salesforce_mapping\MappingConstants:: + * SALESFORCE_MAPPING_SYNC_DRUPAL_CREATE + * SALESFORCE_MAPPING_SYNC_DRUPAL_UPDATE + * SALESFORCE_MAPPING_SYNC_DRUPAL_DELETE. + */ + public function __construct(MappedObjectInterface $mapped_object, $op) { + parent::__construct($mapped_object); + $this->op = $op; + } + + /** + * + */ + public function getOp() { + return $this->op; + } + + /** + * Returns FALSE if PUSH_ALLOWED event has been fired, and any subscriber + * wants to prevent push. Otherwise, returns NULL. Note: a subscriber cannot + * "force" a push when any other subscriber which wants to prevent pushing. + * + * @return FALSE or NULL + */ + public function isPushAllowed() { + return $this->push_allowed === FALSE ? FALSE : NULL; + } + + /** + * Stop Salesforce record from being pushed. + * + * @return $this + */ + public function disallowPush() { + $this->push_allowed = FALSE; + return $this; + } + +} diff --git a/modules/salesforce_pull/src/Plugin/QueueWorker/PullBase.php b/modules/salesforce_pull/src/Plugin/QueueWorker/PullBase.php index 5ef06579c3320fd84cc8470934de1e92164de144..dabfdc1d4682cca1d7badffaebf494c94882a2db 100644 --- a/modules/salesforce_pull/src/Plugin/QueueWorker/PullBase.php +++ b/modules/salesforce_pull/src/Plugin/QueueWorker/PullBase.php @@ -196,12 +196,9 @@ abstract class PullBase extends QueueWorkerBase implements ContainerFactoryPlugi } } catch (\Exception $e) { - $this->eventDispatcher->dispatch(SalesforceEvents::ERROR, new SalesforceErrorEvent($e, 'Failed to update entity %label from Salesforce object %sfobjectid.', ['%label' => (isset($entity)) ? $entity->label() : "Unknown", '%sfobjectid' => (string) $sf_object->id()])); - - if ($e instanceof PullException) { - // Throwing a new exception to keep current item in queue in Cron. - throw $e; - } + $this->eventDispatcher->dispatch(SalesforceEvents::WARNING, new SalesforceErrorEvent($e, 'Failed to update entity %label from Salesforce object %sfobjectid.', ['%label' => (isset($entity)) ? $entity->label() : "Unknown", '%sfobjectid' => (string) $sf_object->id()])); + // Throwing a new exception keeps current item in cron queue. + throw $e; } } @@ -284,11 +281,9 @@ abstract class PullBase extends QueueWorkerBase implements ContainerFactoryPlugi return MappingConstants::SALESFORCE_MAPPING_SYNC_SF_CREATE; } catch (\Exception $e) { - $this->eventDispatcher->dispatch(SalesforceEvents::NOTICE, new SalesforceNoticeEvent($e, 'Pull-create failed for Salesforce Object ID: %sfobjectid', ['%sfobjectid' => (string) $sf_object->id()])); - if ($e instanceof PullException) { - // Throwing a new exception to keep current item in queue in Cron. - throw $e; - } + $this->eventDispatcher->dispatch(SalesforceEvents::WARNING, new SalesforceNoticeEvent($e, 'Pull-create failed for Salesforce Object ID: %sfobjectid', ['%sfobjectid' => (string) $sf_object->id()])); + // Throwing a new exception to keep current item in cron queue. + throw $e; } } diff --git a/modules/salesforce_push/salesforce_push.module b/modules/salesforce_push/salesforce_push.module index a62ac73c8a1bdff4774473ebf28467d7327e5e99..c8115e41dcea8dd8579e88d74ae81c46978b6bcf 100644 --- a/modules/salesforce_push/salesforce_push.module +++ b/modules/salesforce_push/salesforce_push.module @@ -122,11 +122,14 @@ function salesforce_push_entity_crud_mapping(EntityInterface $entity, $op, Sales $mapped_object = current($mapped_objects); } - // Event subscribers should throw an exception to prevent push. - \Drupal::service('event_dispatcher')->dispatch( + // Event subscribers should call $event->disallowPush() to prevent push. + $event = \Drupal::service('event_dispatcher')->dispatch( SalesforceEvents::PUSH_ALLOWED, - new SalesforcePushOpEvent($mapped_object, $op) + new SalesforcePushAllowedEvent($mapped_object, $op) ); + if ($event->isPushAllowed() === FALSE) { + return FALSE; + } // Enqueue async push if the mapping is configured to do so, and quit. if ($mapping->async) { @@ -141,7 +144,6 @@ function salesforce_push_entity_crud_mapping(EntityInterface $entity, $op, Sales // Attempt real-time push. Enqueue async push on failure. try { - // @TODO this doesn't really seem distinct from PUSH_ALLOWED anymore. Do we still have a use case for this event? \Drupal::service('event_dispatcher')->dispatch( SalesforceEvents::PUSH_MAPPING_OBJECT, new SalesforcePushOpEvent($mapped_object, $op) diff --git a/modules/salesforce_push/src/PushQueue.php b/modules/salesforce_push/src/PushQueue.php index f59272338f96b2712ac4604854df11d65dfe11c8..d732a35b88b971e4d9f3df8694209f3c2adaf4c6 100644 --- a/modules/salesforce_push/src/PushQueue.php +++ b/modules/salesforce_push/src/PushQueue.php @@ -388,7 +388,7 @@ class PushQueue extends DatabaseQueue implements PushQueueInterface { // Getting a Requeue here is weird for a group of items, but we'll // deal with it. $this->releaseItems($items); - $this->eventDispatcher->dispatch(SalesforceEvents::ERROR, new SalesforceErrorEvent($e)); + $this->eventDispatcher->dispatch(SalesforceEvents::WARNING, new SalesforceErrorEvent($e)); continue; } catch (SuspendQueueException $e) { @@ -396,7 +396,7 @@ class PushQueue extends DatabaseQueue implements PushQueueInterface { // or authorization error. Release items and move on to the next // mapping in this case. $this->releaseItems($items); - $this->eventDispatcher->dispatch(SalesforceEvents::ERROR, new SalesforceErrorEvent($e)); + $this->eventDispatcher->dispatch(SalesforceEvents::WARNING, new SalesforceErrorEvent($e)); return $i; } catch (\Exception $e) { diff --git a/src/Event/SalesforceEvents.php b/src/Event/SalesforceEvents.php index c223ad9000d4263e11c24bd8d2df016aae26cda6..00fd243c4e084369d3b05cad87550a23c1b75be1 100644 --- a/src/Event/SalesforceEvents.php +++ b/src/Event/SalesforceEvents.php @@ -14,7 +14,7 @@ class SalesforceEvents { * The event listener method receives a * \Drupal\salesforce_mapping\Event\SalesforcePushOpEvent instance. * - * Event listeners should throw an exception to prevent push. + * Event listeners should call $event->disallowPush() to prevent push. * * @Event * @@ -92,11 +92,15 @@ class SalesforceEvents { * example, to alter SF object retrieved from Salesforce or to assign a * different Drupal entity. * - * Listeners should throw an exception to prevent an item from being pulled. + * Listeners should throw an exception to prevent an item from being pulled, + * per Drupal\Core\Queue\QueueWorkerInterface + * + * @see \Drupal\Core\Queue\QueueWorkerInterface * * @Event * * @var string + * */ const PULL_PREPULL = 'salesforce.pull_prepull';