You are here

public function Cart::addItem in Ubercart 8.4

Adds an item to the cart.

Parameters

int $nid: Node ID to add to cart.

int $qty: Quantity to add to cart.

array $data: Array of module-specific data to add to cart.

bool $msg: Whether to display a message upon adding an item to the cart.

Return value

\Drupal\Core\Url A URL to redirect to.

Overrides CartInterface::addItem

File

uc_cart/src/Cart.php, line 68

Class

Cart
Utility class providing methods for the management of shopping carts.

Namespace

Drupal\uc_cart

Code

public function addItem($nid, $qty = 1, array $data = NULL, $msg = TRUE) {
  $node = Node::load($nid);
  if (is_null($data) || !isset($data['module'])) {
    $data['module'] = 'uc_product';
  }

  // Invoke hook_uc_add_to_cart() to give other modules a chance
  // to affect the process.
  $result = \Drupal::moduleHandler()
    ->invokeAll('uc_add_to_cart', [
    $nid,
    $qty,
    $data,
  ]);
  if (is_array($result) && !empty($result)) {
    foreach ($result as $row) {
      if ($row['success'] === FALSE) {

        // Module implementing the hook does NOT want this item added!
        if (isset($row['message']) && !empty($row['message'])) {
          $message = $row['message'];
        }
        else {
          $message = $this
            ->t('Sorry, that item is not available for purchase at this time.');
        }
        if (isset($row['silent']) && $row['silent'] === TRUE) {
          return $this
            ->getAddItemRedirect();
        }
        else {
          $this
            ->messenger()
            ->addError($message);
        }

        // Stay on this page.
        $query = \Drupal::request()->query;
        return Url::fromRoute('<current>', [], [
          'query' => UrlHelper::filterQueryParameters($query
            ->all()),
        ]);
      }
    }
  }

  // Now we can go ahead and add the item because either:
  // 1) No modules implemented hook_uc_add_to_cart(), or
  // 2) All modules implementing that hook want this item added.
  $result = \Drupal::entityQuery('uc_cart_item')
    ->condition('cart_id', $this->id)
    ->condition('nid', $nid)
    ->condition('data', serialize($data))
    ->execute();
  if (empty($result)) {

    // If the item isn't in the cart yet, add it.
    $item_entity = CartItem::create([
      'cart_id' => $this->id,
      'nid' => $nid,
      'qty' => $qty,
      'data' => $data,
    ]);
    $item_entity
      ->save();
    if ($msg) {
      $this
        ->messenger()
        ->addMessage($this
        ->t('<strong>@product-title</strong> added to <a href=":url">your shopping cart</a>.', [
        '@product-title' => $node
          ->label(),
        ':url' => Url::fromRoute('uc_cart.cart')
          ->toString(),
      ]));
    }
  }
  else {

    // If it is in the cart, update the item instead.
    if ($msg) {
      $this
        ->messenger()
        ->addMessage($this
        ->t('Your item(s) have been updated.'));
    }
    $item_entity = CartItem::load(current(array_keys($result)));
    $qty += $item_entity->qty->value;
    \Drupal::moduleHandler()
      ->invoke($data['module'], 'uc_update_cart_item', [
      $nid,
      $data,
      min($qty, 999999),
      $this->id,
    ]);
  }

  // Invalidate the cache.
  Cache::invalidateTags([
    'uc_cart:' . $this->id,
  ]);

  // Invalidate the cart order.
  // @todo Remove this and cache the order object with a tag instead?
  $session = \Drupal::service('session');
  $session
    ->set('uc_cart_order_rebuild', TRUE);
  return $this
    ->getAddItemRedirect();
}