THELIA Forum

Welcome to the THELIA support and discusssion forum

Announcement

Rejoignez la communauté sur le Discord Thelia : https://discord.gg/YgwpYEE3y3

Offline


Hello tout le monde!

J'ai développé un module qui permet de restreindre l'achat de certains produits selon le type de client (je vous passe les détails).

Tout fonctionne correctement :
- le formulaire d'ajout au panier ne s'affiche pas si le client n'a pas les droits.
- si le client s'amuse à modifier le formulaire en mettant l'ID d'un produit restreint alors qu'il n'a pas les droits, ça ne s'ajoute pas au panier (vérifié via CART_ADDITEM).

Par contre, si un client ajoute des produits restreints à son panier (il a les droits) qu'il se déconnecte et se re-connecte avec un compte qui n'a pas les droits, il faudrait que ça supprime les produits restreints du panier.

J'ai essayé de le faire via :
- CUSTOMER_LOGIN (en 64)
- CUSTOMER_LOGOUT (en 256)

Mais ça ne marche pas.

Pour CUSTOMER_LOGOUT, je force (dans le code) le customer à null : ça supprime bien du panier mais ma redirection prend le dessus sur la déconnexion :

public function checkProducts($logout=false)
{
	$redirect = false;
	$cart = $this->request->getSession()->getSessionCart();
	if(null != $cart){
		$cartItems = $cart->getCartItems();
		foreach ($cartItems as $cartItem) {
			$itemId = $cartItem->getId();
			$product = $cartItem->getProduct();
			$canBuy = $this->checkRestriction($product,$logout);
			if(!$canBuy){
				$redirect = true;
				CartItemQuery::create()
					->filterByCartId($cart->getId())
					->filterById($itemId)
					->delete();
				$cart->clearCartItems();
			}
		}
		if($redirect){
			throw new RedirectException(URL::getInstance()->absoluteUrl("/cart", ["restriction_error"=>1]));
		}
	}
}

Je peux toujours supprimer la redirection à ce niveau, s'il n'y a pas d'autre solution.

Pour CUSTOMER_LOGIN, j'obtiens cette erreur :

Désolé. Une erreur s'est produite : In this context (no cart in session), an EventDispatcher should be provided to Session::getSessionCart().

Une idée pour améliorer ça ?

Sinon il faudrait que je laisse comme ça mais que je vérifie le panier AVANT le passage de commande ?

Last edited by Elyos (12-04-2024 10:08:35)


Aide les autres, ils t'aideront en retour.

Offline


Pour Login, passe une RequestStack à ton listener, et pas une Request. Tu récupères ensuite le cart avec $this->requestStack->getCurrentRequest()->getSession()->getSessionCart()

Pour Logout, lever une exception interrompe le traitement des évènements, donc la déconnexion n'est pas effectuée. Si tu veux absolument rediriger vers /cart, tu peux dans un méthode avec priorité 256 positionner un flag dans la session, et dans une méthode avec priorité 1 controler si ce flag existe, et rediriger le cas échéant. Ainsi le process de logout aura bien été effectué.

Tu devras sans doute supprimer le cookie "Remember me" pour éviter une reconnexion automatique (c'est ce que fait le CustomerController dans logoutAction()


OpenStudio Toulouse

Offline


Finalement je n'ai pas mis de check au login.
Au logout, je ne fais pas de redirection.

Pour le login, mon request provient déjà de

$this->request = $requestStack->getCurrentRequest();

dans __construct

Last edited by Elyos (09-04-2024 07:44:23)


Aide les autres, ils t'aideront en retour.

Offline


Il faut utiliser partout $this->requestStack->getCurrentRequest(), et pas l'affecter à un attribut dans le contructeur.


OpenStudio Toulouse

Offline


Ah ok ! wink


Aide les autres, ils t'aideront en retour.

Offline


Pas mieux... sad

public function __construct(RequestStack $requestStack, SecurityContext $securityContext)
{

	$this->requestStack = $requestStack;
	$this->customer = $securityContext->getCustomerUser();
	$this->translator = Translator::getInstance();
}
TheliaEvents::CUSTOMER_LOGIN => ['checkCartLogin', 64],
public function checkCartLogin(CustomerLoginEvent $event)
{
	$this->checkProducts();
}
public function checkProducts($logout=false)
{
	$redirect = false;
	$cart = $this->requestStack->getCurrentRequest()->getSession()->getSessionCart();
	if(null != $cart){
		$cartItems = $cart->getCartItems();
		foreach ($cartItems as $cartItem) {
			$itemId = $cartItem->getId();
			$product = $cartItem->getProduct();
			$canBuy = $this->checkRestriction($product,$logout);
			if(!$canBuy){
				$redirect = true;
				CartItemQuery::create()
					->filterByCartId($cart->getId())
					->filterById($itemId)
					->delete();
				$cart->clearCartItems();
			}
		}
		if($redirect && !$logout){
			throw new RedirectException(URL::getInstance()->absoluteUrl("/cart", ["restriction_error"=>1]));
		}
	}
}

Désolé. Une erreur s'est produite : In this context (no cart in session), an EventDispatcher should be provided to Session::getSessionCart().


Aide les autres, ils t'aideront en retour.

Offline


Et je viens de remarquer que si j'accède au site directement via la page panier ça fait pareil... (TheliaEvents::VIEW_CHECK)

Donc il faudrait que j'utilise un event qui s'exécute après la récupération de la session...?


Aide les autres, ils t'aideront en retour.

Offline


Bon... j'ai suivi bêtement l'erreur que me retournait Thelia...

J'ai ajouté un EventDispatcherInterface dans ma fonction __construct

Et dans fonction checkProducts, j'ai rajouté le dispatcher :

$cart = $this->requestStack->getCurrentRequest()->getSession()->getSessionCart($this->dispatcher);

Du coup ça semble fonctionner.

Comme quoi... on ne lit jamais vraiment bien les erreurs retournées big_smile


Aide les autres, ils t'aideront en retour.