View source
<?php
namespace Drupal\salesforce_mapping;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\salesforce\Event\SalesforceEvents;
use Drupal\salesforce\Event\SalesforceWarningEvent;
use Drupal\salesforce\Exception as SalesforceException;
use Drupal\salesforce\Rest\RestClientInterface;
use Drupal\salesforce\SFID;
use Drupal\salesforce\SObject;
use Drupal\salesforce_mapping\Entity\SalesforceMappingInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use DateTime;
abstract class SalesforceMappingFieldPluginBase extends PluginBase implements SalesforceMappingFieldPluginInterface {
protected $label;
protected $id;
protected $entityTypeBundleInfo;
protected $entityFieldManager;
protected $salesforceClient;
protected $mappingStorage;
protected $mappedObjectStorage;
protected $entityTypeManager;
protected $eventDispatcher;
protected $mapping;
public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityTypeBundleInfoInterface $entity_type_bundle_info, EntityFieldManagerInterface $entity_field_manager, RestClientInterface $rest_client, EntityTypeManagerInterface $etm, DateFormatterInterface $dateFormatter, EventDispatcherInterface $event_dispatcher) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
if (!empty($configuration['mapping'])) {
$this->mapping = $configuration['mapping'];
}
$this->entityTypeBundleInfo = $entity_type_bundle_info;
$this->entityFieldManager = $entity_field_manager;
$this->salesforceClient = $rest_client;
$this->entityTypeManager = $etm;
$this->mappingStorage = $etm
->getStorage('salesforce_mapping');
$this->mappedObjectStorage = $etm
->getStorage('salesforce_mapped_object');
$this->dateFormatter = $dateFormatter;
$this->eventDispatcher = $event_dispatcher;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('entity_type.bundle.info'), $container
->get('entity_field.manager'), $container
->get('salesforce.client'), $container
->get('entity_type.manager'), $container
->get('date.formatter'), $container
->get('event_dispatcher'));
}
public static function isAllowed(SalesforceMappingInterface $mapping) {
return TRUE;
}
public function pushValue(EntityInterface $entity, SalesforceMappingInterface $mapping) {
$value = $this
->value($entity, $mapping);
if (!$this
->push() || empty($this
->config('salesforce_field'))) {
return $value;
}
$describe = $this->salesforceClient
->objectDescribe($mapping
->getSalesforceObjectType());
try {
$field_definition = $describe
->getField($this
->config('salesforce_field'));
} catch (\Exception $e) {
$this->eventDispatcher
->dispatch(SalesforceEvents::WARNING, new SalesforceWarningEvent($e, 'Field definition not found for %describe.%field', [
'%describe' => $describe
->getName(),
'%field' => $this
->config('salesforce_field'),
]));
return $value;
}
switch (strtolower($field_definition['type'])) {
case 'boolean':
if ($value == 'false') {
$value = FALSE;
}
$value = (bool) $value;
break;
case 'date':
case 'datetime':
if (!empty($value)) {
$date = new DrupalDateTime($value, 'UTC');
$value = $date
->format(DateTime::ISO8601);
}
break;
case 'double':
$value = (double) $value;
break;
case 'integer':
$value = (int) $value;
break;
case 'multipicklist':
if (is_array($value)) {
$value = implode(';', $value);
}
break;
case 'id':
case 'reference':
if (empty($value)) {
break;
}
if ($value instanceof SFID) {
$value = (string) $value;
}
else {
$value = (string) new SFID($value);
}
break;
}
if ($field_definition['length'] > 0 && strlen($value) > $field_definition['length']) {
$value = substr($value, 0, $field_definition['length']);
}
return $value;
}
public function pullValue(SObject $sf_object, EntityInterface $entity, SalesforceMappingInterface $mapping) {
if (!$this
->pull() || empty($this
->config('salesforce_field'))) {
throw new SalesforceException('No data to pull. Salesforce field mapping is not defined.');
}
$value = $sf_object
->field($this
->config('salesforce_field'));
$describe = $this->salesforceClient
->objectDescribe($mapping
->getSalesforceObjectType());
$data_definition = $this
->getFieldDataDefinition($entity);
$drupal_field_type = $this
->getDrupalFieldType($data_definition);
$drupal_field_settings = $data_definition
->getSettings();
$field_definition = $describe
->getField($this
->config('salesforce_field'));
switch (strtolower($field_definition['type'])) {
case 'boolean':
if (is_string($value) && strtolower($value) === 'false') {
$value = FALSE;
}
$value = (bool) $value;
break;
case 'datetime':
if ($drupal_field_type === 'datetime_iso8601') {
$value = substr($value, 0, 19);
}
break;
case 'double':
$value = $value === NULL ? $value : (double) $value;
break;
case 'integer':
$value = $value === NULL ? $value : (int) $value;
break;
case 'multipicklist':
if (!is_array($value)) {
$value = explode(';', $value);
$value = array_map('trim', $value);
}
break;
case 'id':
case 'reference':
if (empty($value)) {
break;
}
if ($value instanceof SFID) {
$value = (string) $value;
}
else {
$value = (string) new SFID($value);
}
break;
default:
if (is_string($value)) {
if (isset($drupal_field_settings['max_length']) && $drupal_field_settings['max_length'] > 0 && $drupal_field_settings['max_length'] < strlen($value)) {
$value = substr($value, 0, $drupal_field_settings['max_length']);
}
}
break;
}
return $value;
}
public function getConfiguration() {
return $this->configuration;
}
public function setConfiguration(array $configuration) {
$this->configuration = $configuration;
}
public function config($key = NULL, $value = NULL) {
if ($key === NULL) {
return $this->configuration;
}
if ($value !== NULL) {
$this->configuration[$key] = $value;
}
if (array_key_exists($key, $this->configuration)) {
return $this->configuration[$key];
}
return NULL;
}
public function defaultConfiguration() {
return [
'direction' => MappingConstants::SALESFORCE_MAPPING_DIRECTION_SYNC,
'salesforce_field' => [],
'drupal_field_type' => $this
->getPluginId(),
'drupal_field_value' => '',
'mapping_id' => '',
'description' => '',
];
}
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$pluginForm = [];
$plugin_def = $this
->getPluginDefinition();
$pluginForm['drupal_field_value'] = [
'#title' => $plugin_def['label'],
];
$options = $this
->getSalesforceFieldOptions($form['#entity']
->getSalesforceObjectType());
$pluginForm['salesforce_field'] = [
'#title' => $this
->t('Salesforce field'),
'#type' => 'select',
'#description' => $this
->t('Select a Salesforce field to map.'),
'#options' => $options,
'#default_value' => $this
->config('salesforce_field'),
'#empty_option' => $this
->t('- Select -'),
];
$pluginForm['direction'] = [
'#title' => $this
->t('Direction'),
'#type' => 'radios',
'#options' => [
MappingConstants::SALESFORCE_MAPPING_DIRECTION_DRUPAL_SF => $this
->t('Drupal to SF'),
MappingConstants::SALESFORCE_MAPPING_DIRECTION_SF_DRUPAL => $this
->t('SF to Drupal'),
MappingConstants::SALESFORCE_MAPPING_DIRECTION_SYNC => $this
->t('Sync'),
],
'#required' => TRUE,
'#default_value' => $this
->config('direction') ? $this
->config('direction') : MappingConstants::SALESFORCE_MAPPING_DIRECTION_SYNC,
'#attributes' => [
'class' => [
'narrow',
],
],
];
$pluginForm['description'] = [
'#title' => t('Description'),
'#type' => 'textarea',
'#description' => t('Details about this field mapping.'),
'#default_value' => $this
->config('description'),
];
return $pluginForm;
}
protected function buildBrokenConfigurationForm(array &$pluginForm, FormStateInterface $form_state) {
foreach ($this
->config() as $key => $value) {
if (!empty($pluginForm[$key])) {
$pluginForm[$key]['#type'] = 'hidden';
$pluginForm[$key]['#value'] = $value;
}
}
$pluginForm['drupal_field_type'] = [
'#type' => 'hidden',
'#value' => $this
->config('drupal_field_type'),
];
return [
'message' => [
'#markup' => '<div class="error">' . $this
->t('The field plugin %plugin is broken or missing.', [
'%plugin' => $this
->config('drupal_field_type'),
]) . '</div>',
],
];
}
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
}
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
}
public function calculateDependencies() {
}
public function label() {
return $this
->get('label');
}
public function get($key) {
return $this
->config($key);
}
public function set($key, $value) {
$this->{$key} = $value;
}
public function push() {
return in_array($this
->config('direction'), [
MappingConstants::SALESFORCE_MAPPING_DIRECTION_DRUPAL_SF,
MappingConstants::SALESFORCE_MAPPING_DIRECTION_SYNC,
]);
}
public function pull() {
return in_array($this
->config('direction'), [
MappingConstants::SALESFORCE_MAPPING_DIRECTION_SYNC,
MappingConstants::SALESFORCE_MAPPING_DIRECTION_SF_DRUPAL,
]);
}
protected function getSalesforceFieldOptions($sfobject_name) {
$options =& drupal_static(__CLASS__ . __FUNCTION__, []);
if (empty($options[$sfobject_name])) {
$describe = $this->salesforceClient
->objectDescribe($sfobject_name);
$options[$sfobject_name] = $describe
->getFieldOptions();
}
return $options[$sfobject_name];
}
public function checkFieldMappingDependency(array $dependencies) {
return FALSE;
}
protected function instanceOfEntityReference(FieldDefinitionInterface $instance) {
$handler = $instance
->getSetting('handler');
if (empty($handler)) {
return FALSE;
}
$plugin = $this
->selectionPluginManager()
->getSelectionHandler($instance);
return $plugin instanceof SelectionInterface;
}
protected function selectionPluginManager() {
return \Drupal::service('plugin.manager.entity_reference_selection');
}
protected function getFieldDataDefinition(EntityInterface $entity) {
return $entity
->get($this
->config('drupal_field_value'))
->getFieldDefinition()
->getItemDefinition();
}
protected function getDrupalFieldType(DataDefinitionInterface $data_definition) {
$field_main_property = $data_definition
->getPropertyDefinition($data_definition
->getMainPropertyName());
return $field_main_property ? $field_main_property
->getDataType() : NULL;
}
}