commerce_shipping-8.x-2.0-rc2/src/Plugin/Field/FieldFormatter/ShippingInformationFormatter.php
src/Plugin/Field/FieldFormatter/ShippingInformationFormatter.php
<?php
namespace Drupal\commerce_shipping\Plugin\Field\FieldFormatter;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\Attribute\FieldFormatter;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\Plugin\Field\FieldFormatter\EntityReferenceFormatterBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Plugin implementation of the 'commerce_shipping_information' formatter.
*/
#[FieldFormatter(
id: 'commerce_shipping_information',
label: new TranslatableMarkup('Shipping information'),
field_types: ['entity_reference'],
)]
class ShippingInformationFormatter extends EntityReferenceFormatterBase {
/**
* The entity type manager.
*/
protected EntityTypeManagerInterface $entityTypeManager;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$instance->entityTypeManager = $container->get('entity_type.manager');
return $instance;
}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'allow_adding_shipment' => TRUE,
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$form = parent::settingsForm($form, $form_state);
$form['allow_adding_shipment'] = [
'#type' => 'checkbox',
'#title' => $this->t('Allow adding shipment'),
'#description' => $this->t('Adds additional tab to add shipment in the order.'),
'#default_value' => $this->getSetting('allow_adding_shipment'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$summary = [];
if ($this->getSetting('allow_adding_shipment')) {
$summary[] = $this->t('"Add shipment" is enabled');
}
else {
$summary[] = $this->t('"Add shipment" is disabled');
}
return $summary;
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
/** @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $items */
/** @var \Drupal\commerce_shipping\Entity\ShipmentInterface[] $shipments */
$shipments = $items->referencedEntities();
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $items->getEntity();
// Generate "order information" initial badge.
$badge = [];
if (!$items->isEmpty()) {
$shipment = reset($shipments);
if ($shipment->access('update')) {
$badge = [
'#type' => 'link',
'#title' => $this->t('Edit'),
'#url' => $shipment->toUrl('edit-modal-form'),
'#attributes' => [
'class' => ['use-ajax', 'commerce-edit-link'],
'data-dialog-type' => 'modal',
'data-dialog-options' => Json::encode([
'width' => 880,
]),
],
];
}
}
return [
[
'#type' => 'component',
'#component' => 'commerce:commerce-admin-card',
'#props' => [
'title' => $this->t('Shipping information'),
'content' => $this->getShipmentsContent($shipments, $order),
'badge' => $badge,
],
'#attached' => [
'library' => ['core/drupal.dialog.ajax'],
],
],
];
}
/**
* {@inheritdoc}
*/
public function view(FieldItemListInterface $items, $langcode = NULL) {
$elements = parent::view($items, $langcode);
// Be sure the field's label is hidden even if it's enabled on view mode.
$elements['#label_display'] = 'hidden';
return $elements;
}
/**
* {@inheritdoc}
*/
public static function isApplicable(FieldDefinitionInterface $field_definition) {
return $field_definition->getTargetEntityTypeId() === 'commerce_order' && $field_definition->getName() === 'shipments';
}
/**
* Returns content for the shipping information.
*
* @param \Drupal\commerce_shipping\Entity\ShipmentInterface[] $shipments
* The list of shipments in the order.
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The order entity.
*/
protected function getShipmentsContent(array $shipments, OrderInterface $order): array {
$add_shipment_link = $this->getAddShipmentModalLink($order);
if (empty($shipments)) {
// Create a panel with the "Add shipment" button.
if ($add_shipment_link) {
return $add_shipment_link->toRenderable();
}
}
else {
$shipment_view_builder = $this->entityTypeManager->getViewBuilder('commerce_shipment');
$shipment_panes = $navigation_tabs = [];
$index = 1;
foreach ($shipments as $shipment) {
$shipment_panes[] = $shipment_view_builder->view($shipment, 'admin');
$navigation_tabs[] = [
'#type' => 'html_tag',
'#tag' => 'button',
'#value' => $index,
'#attributes' => [
'class' => ['button', 'button--default'],
'data-shipment-pane-target' => sprintf('shipment-pane-%s', $index),
'data-shipment-edit-url' => $shipment->toUrl('edit-modal-form')->toString(),
],
];
$index++;
}
if ($add_shipment_link) {
$add_shipment_link->setText('+');
$navigation_tabs[] = $add_shipment_link->toRenderable();
}
return [
'#type' => 'component',
'#component' => 'commerce_shipping:commerce-shipment-panes',
'#slots' => [
'shipment_panes' => $shipment_panes,
'navigation_tabs' => $navigation_tabs,
],
];
}
return [];
}
/**
* Returns link object to add a new shipment in modal.
*
* @param \Drupal\commerce_order\Entity\OrderInterface $order
* The order entity.
*/
private function getAddShipmentModalLink(OrderInterface $order): ?Link {
if (!$this->getSetting('allow_adding_shipment')) {
return NULL;
}
$order_type_storage = $this->entityTypeManager->getStorage('commerce_order_type');
/** @var \Drupal\commerce_order\Entity\OrderTypeInterface $order_type */
$order_type = $order_type_storage->load($order->bundle());
$add_shipment_url = Url::fromRoute(
'entity.commerce_shipment.add_modal_form',
[
'commerce_order' => $order->id(),
'commerce_shipment_type' => $order_type->getThirdPartySetting('commerce_shipping', 'shipment_type'),
]
);
if ($add_shipment_url->access()) {
$add_shipment_url->setOption('attributes', [
'class' => ['button', 'button--primary', 'use-ajax'],
'data-dialog-type' => 'modal',
'data-dialog-options' => Json::encode([
'width' => 880,
]),
]);
return Link::fromTextAndUrl('Add shipping information', $add_shipment_url);
}
return NULL;
}
}
