<?php declare(strict_types=1);
namespace App\GlobalFav\Service;
use App\GlobalFav\Object\FavItem;
use DateTime;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
/**
* Stateful service!
*/
class GlobalFav
{
private GlobalFavStoreRequester $storeRequester;
/**
* Runtime cache
*
* @var FavItem[]
*/
protected ?array $list = null;
public const FAV_USER_SESSION_KEY = 'GLOBAL_FAV_USER_ID';
public int $cookieLifetime = (183 * 24 * 60 * 60);
private LoggerInterface $logger;
private RequestStack $requestStack;
public function __construct(
RequestStack $requestStack,
GlobalFavStoreRequester $storeRequester,
LoggerInterface $logger,
) {
$this->storeRequester = $storeRequester;
$this->logger = $logger;
$this->requestStack = $requestStack;
}
public function getUserId(): ?string
{
$request = $this->requestStack->getCurrentRequest();
$session = $request->getSession();
$userId = $request->cookies->get(self::FAV_USER_SESSION_KEY);
if (!$userId) {
$userId = $session->get(self::FAV_USER_SESSION_KEY);
}
return $userId;
}
public function getUserIdForCookieUpdate(): ?string
{
$request = $this->requestStack->getCurrentRequest();
if (!$request) {
return null;
}
$session = $request->getSession();
$userId = $request->cookies->get(self::FAV_USER_SESSION_KEY);
// Если userId уже есть в куках, их не надо обновлять
if ($userId) {
return null;
}
// Если есть в сессии, но нет в куках - обновляем
$userId = $session->get(self::FAV_USER_SESSION_KEY);
if ($userId) {
return $userId;
}
// Ваще нигде нет, ахтунг, надо обновить
return $this->refreshUser();
}
public function setUserId(string $userId): void
{
$request = $this->requestStack->getCurrentRequest();
$session = $request->getSession();
$session->set(self::FAV_USER_SESSION_KEY, $userId);
}
/**
* @return FavItem[]
*/
public function getFavList(): array
{
$userId = $this->getUserId();
if (!$userId) {
return [];
}
if ($this->list === null) {
$this->list = $this->storeRequester->getList($userId);
}
return $this->list;
}
public function add(FavItem $favItem): bool
{
if (!$this->getUserId()) {
$this->logger->notice('Global Fav: Trying to add favorite without userId');
return false;
}
return $this->storeRequester->add($this->getUserId(), $favItem);
}
public function remove(FavItem $favItem): bool
{
if (!$this->getUserId()) {
$this->logger->notice('Global Fav: Trying to remove favorite without userId');
return false;
}
return $this->storeRequester->remove($this->getUserId(), $favItem);
}
public function view(FavItem $favItem): bool
{
if (!$this->getUserId()) {
$this->logger->notice('Global Fav: Trying to view favorite without userId');
return false;
}
return $this->storeRequester->view($this->getUserId(), $favItem);
}
public function refreshUser(): ?string
{
$userId = $this->storeRequester->createUser();
if ($userId) {
$this->setUserId($userId);
} else {
$this->logger->notice('Global Fav: Could not refresh user id');
}
return $userId ?: null;
}
public function updateCookie(Response $response): void
{
$userId = $this->getUserIdForCookieUpdate();
if ($userId) {
$response->headers->setCookie(
Cookie::create(
self::FAV_USER_SESSION_KEY,
$userId,
(new DateTime('now'))->modify("+183 day")
)
);
}
}
}