abstract class PullBase in Salesforce Suite 8.4
Same name and namespace in other branches
- 8.3 modules/salesforce_pull/src/Plugin/QueueWorker/PullBase.php \Drupal\salesforce_pull\Plugin\QueueWorker\PullBase
- 5.0.x modules/salesforce_pull/src/Plugin/QueueWorker/PullBase.php \Drupal\salesforce_pull\Plugin\QueueWorker\PullBase
Provides base functionality for the Salesforce Pull Queue Workers.
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Queue\QueueWorkerBase implements QueueWorkerInterface
- class \Drupal\salesforce_pull\Plugin\QueueWorker\PullBase implements ContainerFactoryPluginInterface
- class \Drupal\Core\Queue\QueueWorkerBase implements QueueWorkerInterface
Expanded class hierarchy of PullBase
1 file declares its use of PullBase
- PullBaseTest.php in modules/
salesforce_pull/ tests/ src/ Unit/ PullBaseTest.php
File
- modules/
salesforce_pull/ src/ Plugin/ QueueWorker/ PullBase.php, line 27
Namespace
Drupal\salesforce_pull\Plugin\QueueWorkerView source
abstract class PullBase extends QueueWorkerBase implements ContainerFactoryPluginInterface {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $etm;
/**
* The SF REST client.
*
* @var \Drupal\salesforce\Rest\RestClientInterface
*/
protected $client;
/**
* Storage handler for SF mappings.
*
* @var \Drupal\salesforce_mapping\SalesforceMappingStorage
*/
protected $mappingStorage;
/**
* Storage handler for Mapped Objects.
*
* @var \Drupal\salesforce_mapping\MappedObjectStorage
*/
protected $mappedObjectStorage;
/**
* Event dispatcher service.
*
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* Creates a new PullBase object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\salesforce\Rest\RestClientInterface $client
* Salesforce REST client.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
* Event dispatcher service.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, RestClientInterface $client, EventDispatcherInterface $event_dispatcher) {
$this->etm = $entity_type_manager;
$this->client = $client;
$this->eventDispatcher = $event_dispatcher;
$this->mappingStorage = $this->etm
->getStorage('salesforce_mapping');
$this->mappedObjectStorage = $this->etm
->getStorage('salesforce_mapped_object');
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($container
->get('entity_type.manager'), $container
->get('salesforce.client'), $container
->get('event_dispatcher'));
}
/**
* Queue item process callback.
*
* @param \Drupal\salesforce_pull\PullQueueItem $item
* Pull queue item. Note: typehint missing because we can't change the
* inherited API.
*
* @return string|null
* Return \Drupal\salesforce_mapping\MappingConstants::SALESFORCE_MAPPING_SYNC_SF_UPDATE
* or Return \Drupal\salesforce_mapping\MappingConstants::SALESFORCE_MAPPING_SYNC_SF_CREATE
* on successful update or create, NULL otherwise.
*
* @throws \Exception
*/
public function processItem($item) {
// @codingStandardsIgnoreLine
$sf_object = $item
->getSobject();
$mapping = $this->mappingStorage
->load($item
->getMappingId());
if (!$mapping) {
return;
}
// loadMappedObjects returns an array, but providing salesforce id and
// mapping guarantees at most one result.
$mapped_object = $this->mappedObjectStorage
->loadByProperties([
'salesforce_id' => (string) $sf_object
->id(),
'salesforce_mapping' => $mapping->id,
]);
// @TODO one-to-many: this is a blocker for OTM support:
$mapped_object = current($mapped_object);
if (!empty($mapped_object)) {
return $this
->updateEntity($mapping, $mapped_object, $sf_object, $item
->getForcePull());
}
else {
return $this
->createEntity($mapping, $sf_object);
}
}
/**
* Update an existing Drupal entity.
*
* @param \Drupal\salesforce_mapping\Entity\SalesforceMappingInterface $mapping
* Object of field maps.
* @param \Drupal\salesforce_mapping\Entity\MappedObjectInterface $mapped_object
* SF Mmapped object.
* @param \Drupal\salesforce\SObject $sf_object
* Current Salesforce record array.
* @param bool $force_pull
* If true, ignore entity and SF timestamps.
*
* @return string|null
* Return \Drupal\salesforce_mapping\MappingConstants::SALESFORCE_MAPPING_SYNC_SF_UPDATE
* on successful update, NULL otherwise.
*
* @throws \Exception
*/
protected function updateEntity(SalesforceMappingInterface $mapping, MappedObjectInterface $mapped_object, SObject $sf_object, $force_pull = FALSE) {
if (!$mapping
->checkTriggers([
MappingConstants::SALESFORCE_MAPPING_SYNC_SF_UPDATE,
])) {
return;
}
try {
$entity = $mapped_object
->getMappedEntity();
if (!$entity) {
$this->eventDispatcher
->dispatch(SalesforceEvents::ERROR, new SalesforceErrorEvent(NULL, 'Drupal entity existed at one time for Salesforce object %sfobjectid, but does not currently exist.', [
'%sfobjectid' => (string) $sf_object
->id(),
]));
return;
}
// Flag this entity as having been processed. This does not persist,
// but is used by salesforce_push to avoid duplicate processing.
$entity->salesforce_pull = TRUE;
$entity_updated = !empty($entity->changed->value) ? $entity->changed->value : $mapped_object
->getChanged();
$pull_trigger_date = $sf_object
->field($mapping
->getPullTriggerDate());
$sf_record_updated = strtotime($pull_trigger_date);
$mapped_object
->setDrupalEntity($entity)
->setSalesforceRecord($sf_object);
// Push upsert ID to SF object, if allowed and not set.
if ($mapping
->hasKey() && $mapping
->checkTriggers([
MappingConstants::SALESFORCE_MAPPING_SYNC_DRUPAL_CREATE,
MappingConstants::SALESFORCE_MAPPING_SYNC_DRUPAL_UPDATE,
]) && $sf_object
->field($mapping
->getKeyField()) === NULL) {
$params = new PushParams($mapping, $entity);
$this->eventDispatcher
->dispatch(SalesforceEvents::PUSH_PARAMS, new SalesforcePushParamsEvent($mapped_object, $params));
// Get just the key param and send that.
$key_field = $mapping
->getKeyField();
$key_param = [
$key_field => $params
->getParam($key_field),
];
$sent_id = $this
->sendEntityId($mapping
->getSalesforceObjectType(), $mapped_object
->sfid(), $key_param);
if (!$sent_id) {
throw new PullException();
}
}
$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.
$mapped_object
->pull();
$this->eventDispatcher
->dispatch(SalesforceEvents::NOTICE, new SalesforceNoticeEvent(NULL, 'Updated entity %label associated with Salesforce Object ID: %sfid', [
'%label' => $entity
->label(),
'%sfid' => (string) $sf_object
->id(),
]));
return MappingConstants::SALESFORCE_MAPPING_SYNC_SF_UPDATE;
}
} catch (\Exception $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;
}
}
/**
* Create a Drupal entity and mapped object.
*
* @param \Drupal\salesforce_mapping\Entity\SalesforceMappingInterface $mapping
* Object of field maps.
* @param \Drupal\salesforce\SObject $sf_object
* Current Salesforce record array.
*
* @return string|null
* Return \Drupal\salesforce_mapping\MappingConstants::SALESFORCE_MAPPING_SYNC_SF_CREATE
* on successful create, NULL otherwise.
*
* @throws \Exception
*/
protected function createEntity(SalesforceMappingInterface $mapping, SObject $sf_object) {
if (!$mapping
->checkTriggers([
MappingConstants::SALESFORCE_MAPPING_SYNC_SF_CREATE,
])) {
return;
}
try {
// Define values to pass to entity_create().
$entity_type = $mapping
->getDrupalEntityType();
$entity_keys = $this->etm
->getDefinition($entity_type)
->getKeys();
$values = [];
if (isset($entity_keys['bundle']) && !empty($entity_keys['bundle'])) {
$values[$entity_keys['bundle']] = $mapping
->getDrupalBundle();
}
// See note above about flag.
$values['salesforce_pull'] = TRUE;
// Create entity.
$entity = $this->etm
->getStorage($entity_type)
->create($values);
// Create mapped object.
$mapped_object = $this->mappedObjectStorage
->create([
'drupal_entity' => [
'target_type' => $entity_type,
],
'salesforce_mapping' => $mapping->id,
'salesforce_id' => (string) $sf_object
->id(),
]);
$mapped_object
->setDrupalEntity($entity)
->setSalesforceRecord($sf_object);
$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();
// Push upsert ID to SF object, if allowed and not already set.
if ($mapping
->hasKey() && $mapping
->checkTriggers([
MappingConstants::SALESFORCE_MAPPING_SYNC_DRUPAL_CREATE,
MappingConstants::SALESFORCE_MAPPING_SYNC_DRUPAL_UPDATE,
]) && $sf_object
->field($mapping
->getKeyField()) === NULL) {
$params = new PushParams($mapping, $entity);
$this->eventDispatcher
->dispatch(SalesforceEvents::PUSH_PARAMS, new SalesforcePushParamsEvent($mapped_object, $params));
// Get just the key param and send that.
$key_field = $mapping
->getKeyField();
$key_param = [
$key_field => $params
->getParam($key_field),
];
$sent_id = $this
->sendEntityId($mapping
->getSalesforceObjectType(), $mapped_object
->sfid(), $key_param);
if (!$sent_id) {
throw new PullException();
}
}
$this->eventDispatcher
->dispatch(SalesforceEvents::NOTICE, new SalesforceNoticeEvent(NULL, 'Created entity %id %label associated with Salesforce Object ID: %sfid', [
'%id' => $entity
->id(),
'%label' => $entity
->label(),
'%sfid' => (string) $sf_object
->id(),
]));
return MappingConstants::SALESFORCE_MAPPING_SYNC_SF_CREATE;
} catch (\Exception $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;
}
}
/**
* Push the Entity ID up to Salesforce.
*
* @param string $object_type
* Salesforce object type.
* @param string $sfid
* Salesforce ID.
* @param array $key_param
* Key parameter to be pushed.
*
* @return bool
* TRUE/FALSE
*/
protected function sendEntityId(string $object_type, string $sfid, array $key_param) {
try {
$this->client
->objectUpdate($object_type, $sfid, $key_param);
return TRUE;
} catch (RestException $e) {
$this->eventDispatcher
->dispatch(SalesforceEvents::ERROR, new SalesforceErrorEvent($e));
return FALSE;
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
PullBase:: |
protected | property | The SF REST client. | |
PullBase:: |
protected | property | The entity type manager. | |
PullBase:: |
protected | property | Event dispatcher service. | |
PullBase:: |
protected | property | Storage handler for Mapped Objects. | |
PullBase:: |
protected | property | Storage handler for SF mappings. | |
PullBase:: |
public static | function |
Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface:: |
|
PullBase:: |
protected | function | Create a Drupal entity and mapped object. | |
PullBase:: |
public | function |
Queue item process callback. Overrides QueueWorkerInterface:: |
|
PullBase:: |
protected | function | Push the Entity ID up to Salesforce. | |
PullBase:: |
protected | function | Update an existing Drupal entity. | |
PullBase:: |
public | function |
Creates a new PullBase object. Overrides PluginBase:: |