Files
cake-carts/src/Controller/Component/ShoppingCartComponent.php

169 lines
4.8 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
namespace CakeCarts\Controller\Component;
use Cake\Controller\Component;
use Cake\Core\Configure;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\Exception\RecordNotFoundException;
use Cake\Event\EventInterface;
use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
use CakeCarts\Model\Entity\CartItem;
use CakeCarts\Model\Enum\CartTypeId;
use CakeCarts\Model\Table\CartsTable;
/**
* ShoppingCart component
*/
class ShoppingCartComponent extends Component
{
/**
* @var string $userIdField
*/
protected string $userIdField;
/**
* @var CartsTable|Table $Carts
*/
protected CartsTable|Table $Carts;
public function initialize(array $config): void
{
parent::initialize($config); // TODO: Change the autogenerated stub
$this->userIdField = Configure::readOrFail('CakeCarts.Users.user_id') === 'uuid' ? 'user_id_uuid' : 'user_id';
$this->Carts = TableRegistry::getTableLocator()->get(Configure::readOrFail('CakeCarts.Carts.table'));
}
/**
* Default configuration.
*
* @var array<string, mixed>
*/
protected array $_defaultConfig = [];
public function beforeFilter(EventInterface $event): void
{
if (!$this->_isActionEnabled()) {
return;
}
$sessionId = $this->getSessionId();
$cart = $this->findExistingCartOrCreate($sessionId);
$this->getController()->set(compact('cart'));
}
/**
* @param string $cartId
*
* @return mixed
*/
public function getCartForUserById(string $cartId)
{
$identity = $this->getController()->getRequest()->getAttribute('identity');
$sessionId = $this->getSessionId();
$cartsQ = $this->Carts
->find()
->contain(['CartItems'])
->where(['Carts.id' => $cartId]);
if ($identity) {
$cartsQ->where([$this->userIdField => $identity->getIdentifier()]);
} else {
$cartsQ->where(['session_id' => $sessionId]);
}
return $cartsQ->firstOrFail();
}
public function findExistingCartOrCreate(string $sessionId, int $cartTypeId = null)
{
$identity = $this->getController()->getRequest()->getAttribute('identity');
$cartTypeId = $cartTypeId ?? CartTypeId::Cart->value;
$cart = $this->Carts
->findBySessionId($sessionId)
->contain(['CartItems'])
->where(['cart_type_id' => $cartTypeId])
->first();
if (isset($cart) && isset($identity) && !isset($cart[$this->userIdField])) {
$cart = $this->Carts->patchEntity([
$this->userIdField => $identity->getIdentifier(),
]);
$cart = $this->Carts->saveOrFail($cart);
}
if (!isset($cart)) {
$cart = $this->Carts->newEntity([
'cart_type_id' => $cartTypeId,
'session_id' => $sessionId,
$this->userIdField => isset($identity) ? $identity->getIdentifier() : null,
'num_items' => 0,
'cart_items' => [],
]);
$cart = $this->Carts->saveOrFail($cart);
}
return $cart;
}
public function getUserIdField()
{
return $this->userIdField;
}
/**
* @return string
*/
public function getSessionId(): string
{
if (!$this->getController()->getRequest()->getSession()->started()) {
$this->getController()->getRequest()->getSession()->start();
}
if (!$this->getController()->getRequest()->getSession()->check('CakeCarts.session_id')) {
$this->getController()->getRequest()->getSession()->write('CakeCarts.session_id', $this->getController()->getRequest()->getSession()->id());
}
return $this->getController()->getRequest()->getSession()->read('CakeCarts.session_id');
}
/**
* @param EntityInterface $cart
* @throws RecordNotFoundException
*
* @return void
*/
public function checkIfIsOwnCart(EntityInterface $cart): void
{
$identity = $this->getController()->getRequest()->getAttribute('identity');
if (!isset($identity) && isset($cart->session_id) && ($cart->session_id != $this->getSessionId())) {
throw new RecordNotFoundException();
}
if (isset($identity) && $identity->getIdentifier() != $cart->get($this->getUserIdField())) {
throw new RecordNotFoundException();
}
}
/**
* @return bool
*/
protected function _isActionEnabled(): bool
{
$actions = $this->getConfig('actions');
if (is_bool($actions)) {
return $actions;
}
return in_array($this->getController()->getRequest()->getParam('action'), (array)$actions, true);
}
}