You are here

public function XquantityAddTocartForm::validateForm in Commerce Extended Quantity 8

Button-level validation handlers are highly discouraged for entity forms, as they will prevent entity validation from running. If the entity is going to be saved during the form submission, this method should be manually invoked from the button-level validation handler, otherwise an exception will be thrown.

Overrides ContentEntityForm::validateForm

File

src/Form/XquantityAddTocartForm.php, line 139

Class

XquantityAddTocartForm
Overrides the order item add to cart form.

Namespace

Drupal\commerce_xquantity\Form

Code

public function validateForm(array &$form, FormStateInterface $form_state) {

  /** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */
  $order_item = $this->entity;
  $settings = $order_item
    ->getQuantityWidgetSettings();
  $default = $step = $settings['step'] ?: $settings['base_step'];
  $scale = Numeric::getDecimalDigits($step);
  $min = $settings['min'] && $step <= $settings['min'] ? $settings['min'] : $step;
  $max = $settings['max'] && $step <= $settings['max'] ? $settings['max'] : $step;
  $default = $settings['default_value'] ?: ($settings['base_default_value'] ?: $min);
  $value = $form_state
    ->getValue([
    'quantity',
    0,
    'value',
  ]);

  // If the value is NULL it means the quantity field is disabled.
  $quantity = $cart_quantity = $value !== NULL ? $value : $default;
  if (!$quantity || $quantity < $min) {
    $form_state
      ->setErrorByName('quantity', $this
      ->t('The quantity should be no less than %min', [
      '%min' => $min,
    ]));
    return;
  }
  parent::validateForm($form, $form_state);
  if ($form_state
    ->getTriggeringElement()['#type'] == 'submit' && ($id = NestedArray::getValue($form, [
    'purchased_entity',
    'widget',
    '0',
    'variation',
    '#value',
  ]))) {

    /** @var \Drupal\commerce\PurchasableEntityInterface $purchased_entity */
    $purchased_entity = $order_item
      ->getPurchasedEntity()::load($id);
    if ($available = $purchased_entity && $this->moduleHandler
      ->moduleExists('xquantity_stock')) {
      $availability = \Drupal::service('xquantity_stock.availability_checker');
      if ($availability
        ->applies($order_item)) {
        $store = $this
          ->selectStore($purchased_entity);
        $context = new Context($this->currentUser, $store, time(), [
          'xquantity' => 'add_to_cart',
        ]);
        $available = !$availability
          ->check($order_item, $context, $quantity)
          ->isUnavailable();
        if (!$available && $order_item
          ->rotateStock($purchased_entity, $quantity, $context)) {
          $available = !$availability
            ->check($order_item, $context, $quantity)
            ->isUnavailable();
        }
      }
    }
    if (!$available) {
      $args = [
        '%quantity' => $quantity,
        '%label' => $purchased_entity ? $purchased_entity
          ->label() : $this
          ->t('???'),
        ':href' => $purchased_entity ? $purchased_entity
          ->toUrl()
          ->toString() : '/',
      ];
      $msg = $this
        ->t('Unfortunately, the quantity %quantity of the %label is not available right at the moment.', $args);
      \Drupal::logger('xquantity_stock')
        ->warning($this
        ->t('Possibly the <a href=":href">%label</a> with the quantity %quantity is out of stock.', $args));
      $purchased_entity && $this->moduleHandler
        ->alter("xquantity_add_to_cart_not_available_msg", $msg, $quantity, $purchased_entity);
      $form_state
        ->setErrorByName('quantity', $msg);
    }
    $order_type_id = $this->orderTypeResolver
      ->resolve($order_item);
    $store = $this
      ->selectStore($purchased_entity);
    $cart = $this->cartProvider
      ->getCart($order_type_id, $store);
    if ($cart && ($items = $cart
      ->getItems())) {
      $matcher = \Drupal::service('commerce_cart.order_item_matcher');
      if ($item = $matcher
        ->match($order_item, $items)) {
        $cart_quantity = bcadd($cart_quantity, $item
          ->getQuantity(), $scale);
      }
    }
    if (bccomp($cart_quantity, $max, $scale) === 1) {
      $form_state
        ->setErrorByName('quantity', $this
        ->t('Only %max items of the %label can be added to the shopping cart. You have %items items left to add.', [
        '%max' => $max,
        '%label' => $purchased_entity
          ->label(),
        '%items' => bcsub($max, bcsub($cart_quantity, $quantity, $scale), $scale),
      ]));
    }
  }
}