commerce_amws-8.x-1.x-dev/modules/order/src/Plugin/EntitySync/FieldTransformer/OrderBillingProfile.php
modules/order/src/Plugin/EntitySync/FieldTransformer/OrderBillingProfile.php
<?php
namespace Drupal\commerce_amws_order\Plugin\EntitySync\FieldTransformer;
use Drupal\commerce_amws_order\HelperService as OrderHelper;
use Drupal\commerce_amws_order\Form\SettingsForm as OrderConfig;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\entity_sync\FieldTransformer\PluginBase;
use Drupal\profile\Entity\ProfileInterface;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
/**
* Transformer that creates and sets the billing profile for an order.
*
* Depending on configuration, the billing profile will be created either from
* the one provided in configuration, or from the order's shipping address.
*
* Supported configuration properties:
* - profile_type: (string, required, defaults to `customer`) The type of the
* profile that will be created.
* - phone_field: (string, optional) The machine name of the field where the
* phone number will be stored in, if using the shipping address. It should be
* of `telephone` type, even though that's not enforced here.
*
* @EntitySyncFieldTransformer(
* id = "commerce_amws_order_billing_profile"
* )
*
* @I Replace module configuration with field transformer configuration
* type : improvement
* priority : low
* labels : config, field-transformer
*/
class OrderBillingProfile extends PluginBase {
/**
* The Commerce AMWS order helper service.
*
* @var \Drupal\commerce_amws_order\HelperService
*/
protected $orderHelper;
/**
* The Amazon MWS order configuration.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
protected $orderConfig;
/**
* The profile storage.
*
* @var \Drupal\profile\ProfileStorageInterface
*/
protected $profileStorage;
/**
* Constructs a new OrderBillingProfile object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Symfony\Component\Validator\Validator\ValidatorInterface $constraint_validator
* The constraint validator.
* @param \Drupal\Component\Plugin\PluginManagerInterface $constraint_manager
* The constraint plugin manager.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The configuration factory.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\commerce_amws_order\HelperService $order_helper
* The Commerce AMWS order helper.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
ValidatorInterface $constraint_validator,
PluginManagerInterface $constraint_manager,
ConfigFactoryInterface $config_factory,
EntityTypeManagerInterface $entity_type_manager,
OrderHelper $order_helper
) {
parent::__construct(
$configuration,
$plugin_id,
$plugin_definition,
$constraint_validator,
$constraint_manager
);
$this->orderHelper = $order_helper;
$this->orderConfig = $config_factory->get('commerce_amws_order.settings');
$this->profileStorage = $entity_type_manager->getStorage('profile');
}
/**
* {@inheritdoc}
*/
public static function create(
ContainerInterface $container,
ValidatorInterface $constraint_validator,
array $configuration,
$plugin_id,
$plugin_definition
) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$constraint_validator,
$container->get('plugin.manager.entity_sync_validation_constraint'),
$container->get('config.factory'),
$container->get('entity_type.manager'),
$container->get('commerce_amws_order.helper_service')
);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'profile_type' => 'customer',
'phone_field' => NULL,
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
protected function transformImportedValue(
$value,
\stdClass $remote_entity,
ContentEntityInterface $local_entity,
array $field_info,
array $context
) {
$source = $this->orderConfig->get('billing_profile.source');
if (!$source) {
throw new \RuntimeException(
'No billing profile source configured.'
);
}
// Create the billing profile depending on the configured source.
$profile = $local_entity->getBillingProfile();
switch ($source) {
case OrderConfig::BILLING_PROFILE_SOURCE_SHIPPING_INFORMATION:
$profile = $this->profileFromShipping(
$value,
$remote_entity,
$local_entity,
$profile
);
break;
case OrderConfig::BILLING_PROFILE_SOURCE_CUSTOM:
$profile = $this->profileFromCustom(
$remote_entity,
$local_entity,
$profile
);
break;
}
if (!$profile) {
return;
}
$profile->save();
return $profile;
}
/**
* Creates a profile based on the Amazon MWS order's shipping information.
*
* If a profile is given - which should be the order's existing billing
* profile - that profile will be updated. Otherwise, a new profile will be
* created and associated with the order.
*
* @param object $amws_address
* The value of the ShippingAddress property for the Amazon MWS order being
* imported.
* @param object $amws_order
* The Amazon MWS order being imported.
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The Drupal Commerce order being created.
* @param \Drupal\profile\Entity\ProfileInterface|null $profile
* The billing profile of the order, or NULL if it doesn't have one yet.
*
* @return \Drupal\profile\Entity\ProfileInterface
* The unsaved created or updated profile.
*/
protected function profileFromShipping(
\stdClass $amws_address,
\stdClass $amws_order,
OrderInterface $order,
ProfileInterface $profile = NULL
) {
if ($profile) {
$profile->set(
'address',
$this->orderHelper->amwsAddressToAddressValue($amws_address)
);
}
else {
$profile = $this->orderHelper->amwsAddressToCustomerProfile(
$order,
$amws_address,
$this->configuration['profile_type'],
FALSE
);
}
if (!empty($this->configuration['phone_field'])) {
$profile->set(
$this->configuration['phone_field'],
$amws_address->Phone ?? NULL
);
}
return $profile;
}
/**
* Creates a profile from custom information defined in the module's settings.
*
* If a profile is given - which should be the order's existing billing
* profile - that profile will be updated. Otherwise, a new profile will be
* created and associated with the order.
*
* @param object $amws_order
* The Amazon MWS order being imported.
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The Drupal Commerce order being created.
* @param \Drupal\profile\Entity\ProfileInterface|null $profile
* The billing profile of the order, or NULL if it doesn't have one yet.
*
* @return \Drupal\profile\Entity\ProfileInterface
* The unsaved created or updated profile.
*/
protected function profileFromCustom(
\stdClass $amws_order,
OrderInterface $order,
ProfileInterface $profile = NULL
) {
$address = $this->orderConfig->get('billing_profile.custom_address');
if (!$address) {
throw new \RuntimeException(
'No custom billing profile configured.'
);
}
if ($profile) {
$profile->set('address', $address);
}
else {
$profile = $this->profileStorage->create([
'type' => $this->configuration['profile_type'],
// Following Drupal Commerce conventions, the profile belongs to the
// order and not to the user's address book therefore the 0 owner ID.
'uid' => 0,
'address' => $address,
]);
}
return $profile;
}
}
