Shopware 6.4.x:如何获取流动作触发页面的URI?
针对你在Newsletter注册Flow自定义动作中需要获取注册来源的需求,以下是几个无需依赖$_SERVER['HTTP_REFERER']的Shopware原生解决方案:
方案1:通过RequestStack获取当前请求路径
在自定义Flow动作中注入Symfony的RequestStack,直接获取触发注册请求的路径信息。该方案适用于同步触发的Flow场景(Newsletter注册通常属于此类)。
代码示例:
<?php namespace YourPlugin\Core\Content\Flow\Action; use Shopware\Core\Framework\Event\FlowEvent; use Shopware\Core\Framework\Flow\Action\FlowAction; use Symfony\Component\HttpFoundation\RequestStack; class NewsletterSourceAction extends FlowAction { private RequestStack $requestStack; public function __construct(RequestStack $requestStack) { $this->requestStack = $requestStack; } public static function getName(): string { return 'your_plugin.action.newsletter_source'; } public function handle(FlowEvent $event): void { $request = $this->requestStack->getCurrentRequest(); if (!$request) { return; } // 获取当前请求路径,如/checkout/register、/account/edit等 $sourcePath = $request->getPathInfo(); // 这里可以将$sourcePath存储到客户实体、日志或其他需要的位置 // 例如更新客户的自定义字段: $customer = $event->getData('customer'); if ($customer) { $customer->setCustomField('newsletter_source', $sourcePath); } } }
方案2:在注册表单中添加隐藏字段传递来源
在不同场景的注册表单模板中添加隐藏字段,手动传递当前页面的路由或路径,再在Flow中读取该值。这种方案更可控,避免异步场景下RequestStack失效的问题。
步骤1:修改模板添加隐藏字段
例如在账户注册模板storefront/page/account/register/index.html.twig中添加:
{# 在表单内添加隐藏字段 #} <input type="hidden" name="newsletter_source" value="{{ app.request.pathInfo }}">
同理,在结账注册模板storefront/page/checkout/register/index.html.twig、客户编辑页模板storefront/page/account/profile/index.html.twig中添加相同字段。
步骤2:在Flow触发时传递来源数据
监听NewsletterRegisterEvent,获取表单提交的来源值并传递到Flow上下文:
<?php namespace YourPlugin\Core\Content\Newsletter\Subscriber; use Shopware\Core\Content\Newsletter\Event\NewsletterRegisterEvent; use Shopware\Core\Framework\Event\FlowEventDispatcher; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class NewsletterSourceSubscriber implements EventSubscriberInterface { private FlowEventDispatcher $flowEventDispatcher; public function __construct(FlowEventDispatcher $flowEventDispatcher) { $this->flowEventDispatcher = $flowEventDispatcher; } public static function getSubscribedEvents(): array { return [ NewsletterRegisterEvent::class => 'onNewsletterRegister', ]; } public function onNewsletterRegister(NewsletterRegisterEvent $event): void { $source = $event->getRequest()->request->get('newsletter_source'); if (!$source) { return; } // 将来源数据注入Flow上下文 $this->flowEventDispatcher->dispatch( 'newsletter.register', // 原生Newsletter注册Flow事件 $event->getContext(), ['newsletterSource' => $source] ); } }
步骤3:在自定义Flow动作中读取来源
public function handle(FlowEvent $event): void { $source = $event->getData('newsletterSource'); if ($source) { // 使用来源数据进行后续处理 } }
方案3:通过Flow事件的触发场景区分来源
不同的Newsletter注册场景对应不同的触发事件或上下文数据,可以直接通过这些特征判断来源:
- 账户注册场景:Flow通常由
customer.register事件触发,且上下文包含新注册的客户数据 - 结账注册场景:Flow关联
checkout.finish或customer.register事件,同时上下文包含订单数据 - 客户编辑页注册:Flow由
customer.update事件触发,上下文包含已登录的客户数据
代码示例:
public function handle(FlowEvent $event): void { $eventName = $event->getEventName(); switch ($eventName) { case 'customer.register': // 判断是否来自结账:检查上下文是否有订单数据 $order = $event->getData('order'); $source = $order ? 'checkout_register' : 'account_register'; break; case 'customer.update': $source = 'account_edit'; break; default: $source = 'unknown'; } // 使用$source进行后续处理 }
内容的提问来源于stack exchange,提问作者EldoRay
相关产品推荐
相关产品推荐

