View source
<?php
namespace Drupal\commerce_cart;
use Drupal\commerce_cart\Exception\DuplicateCartException;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_store\CurrentStoreInterface;
use Drupal\commerce_store\Entity\StoreInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountInterface;
class CartProvider implements CartProviderInterface {
protected $orderStorage;
protected $currentStore;
protected $currentUser;
protected $cartSession;
protected $cartData = [];
public function __construct(EntityTypeManagerInterface $entity_type_manager, CurrentStoreInterface $current_store, AccountInterface $current_user, CartSessionInterface $cart_session) {
$this->orderStorage = $entity_type_manager
->getStorage('commerce_order');
$this->currentStore = $current_store;
$this->currentUser = $current_user;
$this->cartSession = $cart_session;
}
public function createCart($order_type, StoreInterface $store = NULL, AccountInterface $account = NULL) {
$store = $store ?: $this->currentStore
->getStore();
$account = $account ?: $this->currentUser;
$uid = $account
->id();
$store_id = $store
->id();
if ($this
->getCartId($order_type, $store, $account)) {
throw new DuplicateCartException("A cart order for type '{$order_type}', store '{$store_id}' and account '{$uid}' already exists.");
}
$cart = $this->orderStorage
->create([
'type' => $order_type,
'store_id' => $store_id,
'uid' => $uid,
'cart' => TRUE,
]);
$cart
->save();
if ($account
->isAnonymous()) {
$this->cartSession
->addCartId($cart
->id());
}
if (isset($this->cartData[$uid])) {
$this->cartData[$uid][$cart
->id()] = [
'type' => $order_type,
'store_id' => $store_id,
];
}
return $cart;
}
public function finalizeCart(OrderInterface $cart, $save_cart = TRUE) {
$cart->cart = FALSE;
if ($save_cart) {
$cart
->save();
}
if (!$cart
->getCustomerId()) {
$this->cartSession
->deleteCartId($cart
->id(), CartSession::ACTIVE);
$this->cartSession
->addCartId($cart
->id(), CartSession::COMPLETED);
}
if (isset($this->cartData[$cart
->getCustomerId()][$cart
->id()])) {
unset($this->cartData[$cart
->getCustomerId()][$cart
->id()]);
}
}
public function getCart($order_type, StoreInterface $store = NULL, AccountInterface $account = NULL) {
$cart = NULL;
$cart_id = $this
->getCartId($order_type, $store, $account);
if ($cart_id) {
$cart = $this->orderStorage
->load($cart_id);
}
return $cart;
}
public function getCartId($order_type, StoreInterface $store = NULL, AccountInterface $account = NULL) {
$cart_id = NULL;
$cart_data = $this
->loadCartData($account);
if ($cart_data) {
$store = $store ?: $this->currentStore
->getStore();
$search = [
'type' => $order_type,
'store_id' => $store
->id(),
];
$cart_id = array_search($search, $cart_data);
}
return $cart_id;
}
public function getCarts(AccountInterface $account = NULL, StoreInterface $store = NULL) {
$carts = [];
$cart_ids = $this
->getCartIds($account, $store);
if ($cart_ids) {
$carts = $this->orderStorage
->loadMultiple($cart_ids);
}
return $carts;
}
public function getCartIds(AccountInterface $account = NULL, StoreInterface $store = NULL) {
$cart_data = array_filter($this
->loadCartData($account), function ($data) use ($store) {
return !$store || $store
->id() === $data['store_id'];
});
return array_keys($cart_data);
}
public function clearCaches() {
$this->cartData = [];
}
protected function loadCartData(AccountInterface $account = NULL) {
$account = $account ?: $this->currentUser;
$uid = $account
->id();
if (isset($this->cartData[$uid])) {
return $this->cartData[$uid];
}
if ($account
->isAuthenticated()) {
$query = $this->orderStorage
->getQuery()
->condition('state', 'draft')
->condition('cart', TRUE)
->condition('uid', $account
->id())
->sort('order_id', 'DESC')
->accessCheck(FALSE);
$cart_ids = $query
->execute();
}
else {
$cart_ids = $this->cartSession
->getCartIds();
}
$this->cartData[$uid] = [];
if (!$cart_ids) {
return [];
}
$carts = $this->orderStorage
->loadMultiple($cart_ids);
$non_eligible_cart_ids = [];
foreach ($carts as $cart) {
if ($cart
->isLocked()) {
continue;
}
if ($cart
->getCustomerId() != $uid || empty($cart->cart->value) || $cart
->getState()
->getId() != 'draft') {
$non_eligible_cart_ids[] = $cart
->id();
continue;
}
$this->cartData[$uid][$cart
->id()] = [
'type' => $cart
->bundle(),
'store_id' => $cart
->getStoreId(),
];
}
if (!$account
->isAuthenticated()) {
foreach ($non_eligible_cart_ids as $cart_id) {
$this->cartSession
->deleteCartId($cart_id);
}
}
return $this->cartData[$uid];
}
}