<?php
namespace App\Service\Wishlist;
use Doctrine\DBAL\Query\QueryBuilder;
use Pimcore\Model\DataObject\CoreShopProduct;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Session\Session;
class SessionWishlistManager implements WishlistManagerInterface
{
private const SESSION_ID = 'GUEST_WISHLIST_STORAGE';
public function __construct(
private readonly Session $session,
private readonly LoggerInterface $logger,
private readonly bool $wishlistLog = false,
)
{
}
public function addItem(CoreShopProduct $product): void
{
if (!$this->hasItem($product)) {
$storage = $this->getSessionStorage();
$storage[] = $product->getId();
$this->session->set(self::SESSION_ID, $storage);
$this->log($product, self::ACTION_ADD);
}
}
public function removeItem(CoreShopProduct $product): void
{
if ($this->hasItem($product)) {
$this->session->set(self::SESSION_ID, array_diff($this->getSessionStorage(), [$product->getId()]));
$this->log($product, self::ACTION_REMOVE);
}
}
public function hasItem(CoreShopProduct $product): bool
{
return in_array($product->getId(), $this->getSessionStorage(), true);
}
public function getList(): CoreShopProduct\Listing
{
$storage = $this->getSessionStorage();
$listing = new CoreShopProduct\Listing();
$listing->onCreateQueryBuilder(function (QueryBuilder $queryBuilder) use ($storage) {
$queryBuilder->andWhere($queryBuilder->expr()->in('oo_id', $storage));
$queryBuilder->orderBy(sprintf("FIELD(`oo_id`, %s)", implode(', ', $storage)));
});
return $listing;
}
public function count(): int
{
return count($this->getSessionStorage());
}
private function getSessionStorage(): array
{
if (!$this->session->has(self::SESSION_ID) || !is_array($this->session->get(self::SESSION_ID))) {
$this->session->set(self::SESSION_ID, []);
return [];
}
return $this->session->get(self::SESSION_ID);
}
public function truncateStorage(): void
{
$this->session->remove(self::SESSION_ID);
}
private function log(CoreShopProduct $product, string $action): void
{
if (!$this->wishlistLog) {
return;
}
$this->logger->info(sprintf("Guest\nAction: %s\nProduct: %s (%d)\nDatetime: %s",
$action,
$product->getSku(),
$product->getId(),
date('Y-m-d H:i:s')
), ['component' => 'wishlist']);
}
}