You are here

class Cart in Ubercart 8.4

Utility class providing methods for the management of shopping carts.

Hierarchy

Expanded class hierarchy of Cart

3 string references to 'Cart'
uc_cart.info.yml in uc_cart/uc_cart.info.yml
uc_cart/uc_cart.info.yml
uc_cart.links.menu.yml in uc_cart/uc_cart.links.menu.yml
uc_cart/uc_cart.links.menu.yml
uc_cart.rules.events.yml in uc_cart/uc_cart.rules.events.yml
uc_cart/uc_cart.rules.events.yml

File

uc_cart/src/Cart.php, line 16

Namespace

Drupal\uc_cart
View source
class Cart implements CartInterface {
  use MessengerTrait;
  use StringTranslationTrait;

  /**
   * The cart ID.
   *
   * @var string
   */
  protected $id;

  /**
   * Constructor.
   *
   * @param string $id
   *   The cart ID.
   */
  public function __construct($id) {
    $this->id = $id;
  }

  /**
   * {@inheritdoc}
   */
  public function getId() {
    return $this->id;
  }

  /**
   * {@inheritdoc}
   */
  public function getContents() {
    $items = [];
    $result = \Drupal::entityQuery('uc_cart_item')
      ->condition('cart_id', $this->id)
      ->sort('cart_item_id', 'ASC')
      ->execute();
    if (!empty($result)) {
      $items = \Drupal::entityTypeManager()
        ->getStorage('uc_cart_item')
        ->loadMultiple(array_keys($result));
    }

    // Allow other modules a chance to alter the fully loaded cart object.
    \Drupal::moduleHandler()
      ->alter('uc_cart', $items);
    return $items;
  }

  /**
   * {@inheritdoc}
   */
  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();
  }

  /**
   * Computes the destination Url for an add-to-cart action.
   *
   * Redirect Url is chosen in the following order:
   * - Query parameter "destination"
   * - Cart config variable "uc_cart.settings.add_item_redirect"
   *
   * @return \Drupal\Core\Url
   *   A Url destination for redirection.
   */
  protected function getAddItemRedirect() {

    // Check for 'destination=' query string.
    $query = \Drupal::request()->query;
    $destination = $query
      ->get('destination');
    if (!empty($destination)) {
      return Url::fromUri('base:' . $destination);
    }

    // Save current Url to session before redirecting
    // so we can go "back" here from the cart.
    $session = \Drupal::service('session');
    $session
      ->set('uc_cart_last_url', Url::fromRoute('<current>')
      ->toString());
    $redirect = \Drupal::config('uc_cart.settings')
      ->get('add_item_redirect');
    if ($redirect != '<none>') {
      return Url::fromUri('base:' . $redirect);
    }
    else {
      return Url::fromRoute('<current>', [], [
        'query' => UrlHelper::filterQueryParameters($query
          ->all()),
      ]);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function emptyCart() {
    $result = \Drupal::entityQuery('uc_cart_item')
      ->condition('cart_id', $this->id)
      ->execute();
    if (!empty($result)) {
      $storage = \Drupal::entityTypeManager()
        ->getStorage('uc_cart_item');
      $entities = $storage
        ->loadMultiple(array_keys($result));
      $storage
        ->delete($entities);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function isShippable() {
    $items = $this
      ->getContents();
    foreach ($items as $item) {
      if (uc_order_product_is_shippable($item)) {
        return TRUE;
      }
    }
    return FALSE;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
Cart::$id protected property The cart ID.
Cart::addItem public function Adds an item to the cart. Overrides CartInterface::addItem
Cart::emptyCart public function Empties a cart of its contents. Overrides CartInterface::emptyCart
Cart::getAddItemRedirect protected function Computes the destination Url for an add-to-cart action.
Cart::getContents public function Returns the items in the shopping cart. Overrides CartInterface::getContents
Cart::getId public function Returns the unique ID for the cart. Overrides CartInterface::getId
Cart::isShippable public function Determines whether a cart contains shippable items or not. Overrides CartInterface::isShippable
Cart::__construct public function Constructor.
CartInterface::CHECKOUT_TIMEOUT constant Time in seconds after which the checkout page is deemed abandoned.
CartInterface::ORDER_TIMEOUT constant Time in seconds after which a cart order is deemed abandoned.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.