简体   繁体   中英

Sylius - Dynamic change of channels from the client group

I come from Magento and I now use Sylius to modernize things a bit and have access to a less xml oriented platform because I find it really painful in 2022...
Unfortunately I did not find anything in Sylius regarding the management of prices according to the client currently logged.
So I want to use groups and channels: I added a channel relation to a user group to be able to use a channel according to the logged in user.

/**
 * @ORM\Entity
 * @ORM\Table(name="sylius_customer_group")
 */
class CustomerGroup extends BaseCustomerGroup
{
    /**
     * @ORM\ManyToOne(targetEntity=Channel::class)
     */
    private $channel;

    public function getChannel(): ?Channel
    {
        return $this->channel;
    }

    public function setChannel(?Channel $channel): self
    {
        $this->channel = $channel;

        return $this;
    }
}

Here is what I am trying to do with a service

services:
    ChangingContextWithCustomerGroup:
        class: App\Context\RequestQueryChannelContext
        arguments:
            - '@sylius.repository.channel'
            - '@request_stack'
            - '@sylius.context.customer'
        tags:
            - { name: sylius.context.channel, priority: 150 }
    // src/Context/RequestQueryChannelContext.php
    public function getChannel(): ChannelInterface
    {
        $request = $this->requestStack->getMainRequest();

        if (!$request) {
            throw new ChannelNotFoundException('Request Not Found!');
        }
        $customer = $this->customerContext->getCustomer();
        if (!$customer instanceof Customer) {
            throw new ChannelNotFoundException('Customer Not Found!');
        }
        $group = $customer->getGroup();
        if (!$group instanceof CustomerGroup) {
            throw new ChannelNotFoundException('Group Not Found!');
        }
        $channel = $group->getChannel();
        if (!$channel instanceof ChannelInterface) {
            throw new ChannelNotFoundException('Channel Not Found!');
        }
        return $channel;
    }

My problem is that I can't get the customer on the mainRequest. It is null, so I cant have the customer => group => channel.

It works very well when I force the channel like this:

public function getChannel(): ChannelInterface
{
    // ...
    return $this->channelRepository->findOneByCode('fooBar');
}

so my system doesn't work. Is there a better solution?
thanks

The problem here is that the Channel context is called from the Sylius\Bundle\ShopBundle\EventListener\NonChannelLocaleListener which has priority 10 on the kernel.request event. In the channel context you want to use the customer context class, which in turn uses the TokenStorage to retrieve the user information. The token however is not yet populated in the token storage at that point, because that happens in the firewall listener ( Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener in dev environments), which has priority 8.

The solution I found is to lower the priority of the NonChannelLocaleListener to 7. That will make sure that the token is available and that the customer context can be used to retrieve the customer/shop user information.

Lowering the priority of that listener can be done by overriding the service definition in config/services.yaml :

services:
    ...

    sylius.listener.non_channel_request_locale:
        class: Sylius\Bundle\ShopBundle\EventListener\NonChannelLocaleListener
        arguments:
            - '@router'
            - '@sylius.locale_provider'
            - '@security.firewall.map'
            - ['%sylius_shop.firewall_context_name%']
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: restrictRequestLocale, priority: 7 }

Please note that this is on Sylius 1.10, so it might be possible that on other Sylius versions the priority of these listeners are slightly different. In that case, just use the bin/console debug:event-dispatcher command to figure out what the right priority should be.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM