commerce-8.x-2.8/modules/cart/src/Plugin/views/field/EditQuantity.php
modules/cart/src/Plugin/views/field/EditQuantity.php
<?php namespace Drupal\commerce_cart\Plugin\views\field; use Drupal\commerce_cart\CartManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\views\Plugin\views\field\FieldPluginBase; use Drupal\views\Plugin\views\field\UncacheableFieldHandlerTrait; use Drupal\views\ResultRow; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Defines a form element for editing the order item quantity. * * @ViewsField("commerce_order_item_edit_quantity") */ class EditQuantity extends FieldPluginBase { use UncacheableFieldHandlerTrait; /** * The cart manager. * * @var \Drupal\commerce_cart\CartManagerInterface */ protected $cartManager; /** * The entity type manager. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * The messenger. * * @var \Drupal\Core\Messenger\MessengerInterface */ protected $messenger; /** * Constructs a new EditQuantity 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 \Drupal\commerce_cart\CartManagerInterface $cart_manager * The cart manager. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager. * @param \Drupal\Core\Messenger\MessengerInterface $messenger * The messenger. */ public function __construct(array $configuration, $plugin_id, $plugin_definition, CartManagerInterface $cart_manager, EntityTypeManagerInterface $entity_type_manager, MessengerInterface $messenger) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->cartManager = $cart_manager; $this->entityTypeManager = $entity_type_manager; $this->messenger = $messenger; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('commerce_cart.cart_manager'), $container->get('entity_type.manager'), $container->get('messenger') ); } /** * {@inheritdoc} */ public function clickSortable() { return FALSE; } /** * {@inheritdoc} */ protected function defineOptions() { $options = parent::defineOptions(); $options['allow_decimal'] = ['default' => FALSE]; return $options; } /** * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $form['allow_decimal'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow decimal quantities'), '#default_value' => $this->options['allow_decimal'], ]; } /** * {@inheritdoc} */ public function getValue(ResultRow $row, $field = NULL) { return '<!--form-item-' . $this->options['id'] . '--' . $row->index . '-->'; } /** * Form constructor for the views form. * * @param array $form * An associative array containing the structure of the form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. */ public function viewsForm(array &$form, FormStateInterface $form_state) { // Make sure we do not accidentally cache this form. $form['#cache']['max-age'] = 0; // The view is empty, abort. if (empty($this->view->result)) { unset($form['actions']); return; } $form[$this->options['id']]['#tree'] = TRUE; foreach ($this->view->result as $row_index => $row) { /** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */ $order_item = $this->getEntity($row); if ($this->options['allow_decimal']) { $form_display = commerce_get_entity_display('commerce_order_item', $order_item->bundle(), 'form'); $quantity_component = $form_display->getComponent('quantity'); $step = $quantity_component['settings']['step']; $precision = $step >= '1' ? 0 : strlen($step) - 2; } else { $step = 1; $precision = 0; } $form[$this->options['id']][$row_index] = [ '#type' => 'number', '#title' => $this->t('Quantity'), '#title_display' => 'invisible', '#default_value' => round($order_item->getQuantity(), $precision), '#size' => 4, '#min' => 0, '#max' => 9999, '#step' => $step, '#required' => TRUE, ]; } $form['actions']['submit']['#update_cart'] = TRUE; $form['actions']['submit']['#show_update_message'] = TRUE; // Replace the form submit button label. $form['actions']['submit']['#value'] = $this->t('Update cart'); } /** * Submit handler for the views form. * * @param array $form * An associative array containing the structure of the form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. */ public function viewsFormSubmit(array &$form, FormStateInterface $form_state) { $triggering_element = $form_state->getTriggeringElement(); if (empty($triggering_element['#update_cart'])) { // Don't run when the "Remove" or "Empty cart" buttons are pressed. return; } $order_storage = $this->entityTypeManager->getStorage('commerce_order'); /** @var \Drupal\commerce_order\Entity\OrderInterface $cart */ $cart = $order_storage->load($this->view->argument['order_id']->getValue()); $quantities = $form_state->getValue($this->options['id'], []); $save_cart = FALSE; foreach ($quantities as $row_index => $quantity) { if (!is_numeric($quantity) || $quantity < 0) { // The input might be invalid if the #required or #min attributes // were removed by an alter hook. continue; } /** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */ $order_item = $this->getEntity($this->view->result[$row_index]); if ($order_item->getQuantity() == $quantity) { // The quantity hasn't changed. continue; } if ($quantity > 0) { $order_item->setQuantity($quantity); $this->cartManager->updateOrderItem($cart, $order_item, FALSE); } else { // Treat quantity "0" as a request for deletion. $this->cartManager->removeOrderItem($cart, $order_item, FALSE); } $save_cart = TRUE; } if ($save_cart) { $cart->save(); if (!empty($triggering_element['#show_update_message'])) { $this->messenger->addMessage($this->t('Your shopping cart has been updated.')); } } } /** * {@inheritdoc} */ public function query() { // Do nothing. } }