arch-8.x-1.x-dev/modules/stock/src/StockCartInfo.php
modules/stock/src/StockCartInfo.php
<?php namespace Drupal\arch_stock; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\TempStore\SharedTempStoreFactory; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Stock cart info service. * * @package Drupal\arch_stock */ class StockCartInfo implements StockCartInfoInterface, ContainerInjectionInterface { /** * Current user. * * @var \Drupal\Core\Session\AccountInterface */ protected $currentUser; /** * Shared temp store. * * @var \Drupal\Core\TempStore\SharedTempStore */ protected $store; /** * Storage factory. * * @var \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface */ protected $storageFactory; /** * StockCartInfo constructor. * * @param \Drupal\Core\Session\AccountInterface $current_user * Current user. * @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface $key_value_factory * Key value storage factory. * @param \Drupal\Core\TempStore\SharedTempStoreFactory $temp_store_factory * Shared temp store factory. */ public function __construct( AccountInterface $current_user, KeyValueExpirableFactoryInterface $key_value_factory, SharedTempStoreFactory $temp_store_factory, ) { $this->currentUser = $current_user; $this->storageFactory = $key_value_factory; $this->store = $temp_store_factory->get('arch_stock_in_cart'); } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('current_user'), $container->get('keyvalue.expirable'), $container->get('tempstore.shared') ); } /** * {@inheritdoc} */ public function addItem($product_id, $quantity) { return $this->updateItem($product_id, $quantity); } /** * {@inheritdoc} */ public function removeItem($product_id, $quantity) { $value = $this->quantityInCarts($product_id); $value -= $quantity; $this->setQuantityInCarts($product_id, $value); $this->saveOwnerData($product_id, NULL); return $this; } /** * {@inheritdoc} */ public function updateItem($product_id, $quantity) { $total = $this->quantityInCarts($product_id); $current_owner_value = $this->getOwnerQuantity($product_id); $new_total = $total - $current_owner_value + $quantity; $this->setQuantityInCarts($product_id, $new_total); $this->saveOwnerData($product_id, $quantity); return $this; } /** * {@inheritdoc} */ public function quantityInCarts($product_id) { return (float) $this->store->get('product:' . $product_id); } /** * Set total quantity in carts for product. * * @param int $product_id * Product ID. * @param float $quantity * Total quantity in carts. * * @throws \Drupal\Core\TempStore\TempStoreException */ protected function setQuantityInCarts($product_id, $quantity) { if (empty($quantity)) { $this->store->delete('product:' . $product_id); } else { $this->store->set('product:' . $product_id, $quantity); } } /** * Set owner quantity. * * @param string|int $owner * Session or User ID. * @param int $product_id * Product ID. * @param float|null $quantity * New quantity. * * @throws \Drupal\Core\TempStore\TempStoreException */ protected function setOwnerQuantity($owner, $product_id, $quantity = NULL) { $key = $owner . ':cart'; $data = $this->store->get($key); if (empty($quantity)) { unset($data[$product_id]); } else { $data[$product_id] = $quantity; } $this->store->set($key, $data); } /** * Get current quantity for current user. * * @param int $product_id * Product ID. * * @return float * Current quantity. */ protected function getOwnerQuantity($product_id) { $owner = $this->getOwner(); $key = $owner . ':cart'; $data = $this->store->get($key); if (empty($data[$product_id])) { return 0; } return (float) $data[$product_id]; } /** * Get owner. * * @return string * User or Session ID. */ protected function getOwner() { return $this->currentUser->id() ?: session_id(); } /** * Save owner data. * * @param int $product_id * Product ID. * @param float|null $quantity * New quantity. * * @throws \Drupal\Core\TempStore\TempStoreException */ protected function saveOwnerData($product_id, $quantity = NULL) { $owner = $this->getOwner(); $this->setOwnerQuantity($owner, $product_id, $quantity); } /** * {@inheritdoc} */ public function garbageCollection() { $tmp = $this->storageFactory->get('tempstore.private.arch_cart'); $products = []; $owner_counts = []; foreach ($tmp->getAll() as $key => $cart_data) { if (substr($key, -5) != ':cart') { continue; } $owner = substr($key, 0, -5); if (!isset($owner_counts[$owner])) { $owner_counts[$owner] = []; } foreach ($cart_data->data['items'] as $item) { if ($item['type'] !== 'product') { continue; } $product_id = $item['id']; if (!isset($products[$product_id])) { $products[$product_id] = 0; } $products[$product_id] += $item['quantity']; $owner_counts[$owner][$product_id] = $item['quantity']; } } $storage = $this->storageFactory->get('tempstore.shared.arch_stock_in_cart'); $storage->deleteAll(); foreach ($products as $product_id => $quantity) { $this->setQuantityInCarts($product_id, $quantity); } foreach ($owner_counts as $owner => $cart_products) { foreach ($cart_products as $product_id => $owner_product_quantity) { $this->setOwnerQuantity($owner, $product_id, $owner_product_quantity); } } } }