commerce_amws-8.x-1.x-dev/modules/feed/src/Plugin/Field/FieldFormatter/Document.php
modules/feed/src/Plugin/Field/FieldFormatter/Document.php
<?php
namespace Drupal\commerce_amws_feed\Plugin\Field\FieldFormatter;
use Drupal\commerce_amws\MachineName\Field\Order as OrderField;
use Drupal\entity_sync\Entity\OperationInterface;
use Drupal\entity_sync\MachineName\Field\Operation as OperationField;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use SellingPartnerApi\Api\FeedsApi;
use SellingPartnerApi\Configuration;
use SellingPartnerApi\Document as FeedDocument;
use SellingPartnerApi\Endpoint;
use SellingPartnerApi\FeedType;
/**
* Formatter for displaying a feed's' document.
*
* The field must contain the ID of the content or the result document.
*
* @FieldFormatter(
* id = "commerce_amws_feed_document",
* label = @Translation("Feed document"),
* field_types = {
* "string"
* }
* )
*/
class Document extends FormatterBase {
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'display_id' => TRUE,
'display_message' => TRUE,
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$form = parent::settingsForm($form, $form_state);
$form['display_id'] = [
'#type' => 'checkbox',
'#title' => $this->t('Display the document ID'),
'#default_value' => $this->getSetting('display_id'),
];
$form['display_message'] = [
'#type' => 'checkbox',
'#title' => $this->t('Display the document message'),
'#default_value' => $this->getSetting('display_message'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$summary = [];
if ($this->getSetting('display_id')) {
$summary[] = $this->t('Displaying the document ID.');
}
if ($this->getSetting('display_message')) {
$summary[] = $this->t('Displaying the document message.');
}
return $summary;
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$display_id = $this->getSetting('display_id');
$display_message = $this->getSetting('display_message');
if (!($display_id || $display_message)) {
return [];
}
$element = [];
$operation = $items->getEntity();
foreach ($items as $delta => $item) {
$template = '';
$context = [];
$cache = [];
if ($display_id && $display_message) {
$template = '{{ id_label }}: {{ id_value }}<br />{{ message_label }}: {{ message_value }} }}';
$context = [
'id_label' => $this->t('Document ID'),
'id_value' => $item->value,
'message_label' => $this->t('Document message'),
'message_value' => $this->getDocumentMessage($operation, $item->value),
];
$cache = [
'contexts' => [
'languages:' . LanguageInterface::TYPE_INTERFACE,
],
];
}
elseif ($display_id) {
$template = '{{ id_value }}';
$context = [
'id_value' => $item->value,
];
}
elseif ($display_message) {
$template = '{{ message_value }}';
$context = [
'message_value' => $this->getDocumentMessage($operation, $item->value),
];
}
$element[$delta] = [
'#type' => 'inline_template',
'#template' => $template,
'#context' => $context,
'#cache' => $cache,
];
}
return $element;
}
/**
* Fetches and returns the message for the given document ID.
*
* @param \Drupal\entity_sync\Entity\OperationInterface $operation
* The operation.
* @param string $document_id
* The document ID.
*
* @return string
* The document message.
*/
protected function getDocumentMessage(
OperationInterface $operation,
string $document_id
) {
$feeds_api = $this->getFeedsApi($operation);
$document = new FeedDocument(
$feeds_api->getFeedDocument($document_id),
// phpcs:disable
// @I Make this configurable? Or get it from the configurator plugin.
// type : bug
// priority : high
// labels : feed, field
// phpcs:enable
FeedType::POST_ORDER_FULFILLMENT_DATA
);
return $document->download();
}
/**
* Returns a configured Feeds API client.
*
* @param \Drupal\entity_sync\Entity\OperationInterface $operation
* The operation.
*
* @return \SellingPartnerApi\Api\FeedsApi
* The Feeds API client.
* phpcs:disable
* @I Provide a general mechanism for building SP-API clients
* type : task
* priority : normal
* labels : modularity
*
* @I Support all feed types
* type : bug
* priority : high
* labels : modularity
* phpcs:enable
*/
protected function getFeedsApi(OperationInterface $operation) {
$shipment = $operation->get(OperationField::ENTITY)->entity;
$order = $shipment->getOrder();
if (!$order) {
throw new \Exception(sprintf(
'No order found for shipment with ID "%s".',
$shipment->id()
));
}
$amws_store_field = $order->get(OrderField::AMWS_STORE);
if ($amws_store_field->isEmpty()) {
throw new \Exception(sprintf(
'Order with ID "%s" does not belong to an Amazon MWS store.',
$order->id()
));
}
$amws_store = $amws_store_field->entity;
if (!$amws_store) {
throw new \Exception(sprintf(
'Order with ID "%s" belongs a non-existing Amazon MWS store with ID "%s".',
$order->id(),
$amws_store_field->target_id
));
}
$configuration = new Configuration([
'lwaClientId' => $amws_store->getLwaClientId(),
'lwaClientSecret' => $amws_store->getLwaClientSecret(),
'lwaRefreshToken' => $amws_store->getLwaRefreshToken(),
'awsAccessKeyId' => $amws_store->getAwsAccessKeyId(),
'awsSecretAccessKey' => $amws_store->getAwsSecretAccessKey(),
'endpoint' => Endpoint::getByMarketplaceId(
$amws_store->getMarketplaceId()
),
]);
return new FeedsApi($configuration);
}
}
