The problem is the following.
I log in as a user that has role to switch user. Then I switch user with ?_switch_user and make an order but when I finish the order is places with the customer of the original auntheticated user, not the switched user.
Yes I have the same problem, in version 0.18, I could switch by customer and to simulate a payment from my computer... now, If I switch user, the Order belong to me
I thing one way to solve it is to add a Listener that listens to SecurityEvents::SWITCH_USER event.
Then try to recover the las order with cart state for the user and set it in session the id of the cart.
The problem I see is you can not know the cart is abandoned.
Another solution is to add a context to the CompositeContext that gets the cart from the database and just in case the user is not authenticated get the cart from session.
@pjedrzejewski I paste here the solution used in our project (changing namspaces) in case it is usefull.
The listener for switch user
<?php
namespace Acme\EventListener;
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Http\Event\SwitchUserEvent;
use Symfony\Component\Security\Http\SecurityEvents;
class UserSwitchedListener implements EventSubscriberInterface
{
/**
* @var SessionInterface
*/
protected $session;
protected $sessionKeyName;
/**
* @var ChannelContextInterface
*/
protected $channelContext;
/**
* @var OrderRepositoryInterface
*/
protected $orderRepository;
/**
* UserSwitchedListener constructor.
* @param CartContextInterface $catContext
*/
public function __construct(
SessionInterface $session,
$sessionKeyName,
ChannelContextInterface $channelContext,
OrderRepositoryInterface $orderRepository
)
{
$this->session = $session;
$this->sessionKeyName = $sessionKeyName;
$this->channelContext = $channelContext;
$this->orderRepository = $orderRepository;
}
/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2')))
*
* @return array The event names to listen to
*/
public static function getSubscribedEvents()
{
return array(
SecurityEvents::SWITCH_USER => 'userSwitched'
);
}
public function userSwitched(SwitchUserEvent $switchUserEvent)
{
$customer = $switchUserEvent->getTargetUser()->getCustomer();
$customerCart = $this->orderRepository->findLatestCartOfCustomer($customer);
if($customerCart != null){
$this->setSessionCartId($customerCart->getId());
}
}
protected function setSessionCartId($cartId)
{
$sessionCartKey = $this->getSessionCartKey();
$this->session->set($sessionCartKey, $cartId);
}
protected function getSessionCartKey()
{
$channel = $this->channelContext->getChannel();
return sprintf('%s.%s', $this->sessionKeyName, $channel->getCode());
}
}
' ' '
In a custom OrderRepositoy I added the following method:
```php
public function findLatestCartOfCustomer($customer)
{
return $this->createQueryBuilder('o')
->andWhere('o.state = :state')
->andWhere('o.customer = :customer')
->setMaxResults(1)
->orderBy('o.id', 'desc')
->setParameter('state', OrderInterface::STATE_CART)
->setParameter('customer', $customer->getId())
->getQuery()
->getOneOrNullResult()
;
}
Then I register the service the following way:
acme.event_listener.user_switched_listener:
class: Acme\EventListener\UserSwitchedListener
arguments: ['@session', '_sylius.cart', '@sylius.context.channel.cached', '@sylius.repository.order']
tags:
- { name: kernel.event_subscriber }
I'm sorry not making a pull request, I'm fixing it on alpha.2 versi贸n since we are using it in production.
@jdeveloper Thanks for reporting!
This is still a problem, and the jdeveloper's solution still works.
Most helpful comment
@pjedrzejewski I paste here the solution used in our project (changing namspaces) in case it is usefull.
The listener for switch user
Then I register the service the following way:
I'm sorry not making a pull request, I'm fixing it on alpha.2 versi贸n since we are using it in production.