如何在Shopware6的事件中通过编程方式发送邮件
Shopware6 客户映射事件中编程发送邮件的实现方案
核心实现逻辑
Shopware6 基于 Symfony 邮件组件完成邮件发送,通过事件订阅器监听目标客户映射事件,在事件触发时调用内置的MailService发送模板化邮件,以下是具体步骤:
1. 编写事件订阅器
创建订阅类监听你的目标客户映射事件(替换为你实际使用的事件类,比如CustomerMappingEvent):
<?php namespace YourPluginNamespace\Subscriber; use Shopware\Core\Content\Mail\Service\MailService; use Shopware\Core\Framework\Event\CustomerMappingEvent; use Shopware\Core\Framework\Context; use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\DependencyInjection\ContainerInterface; class CustomerMappingMailSubscriber implements EventSubscriberInterface { private MailService $mailService; private LoggerInterface $logger; private ContainerInterface $container; public function __construct( MailService $mailService, LoggerInterface $logger, ContainerInterface $container ) { $this->mailService = $mailService; $this->logger = $logger; $this->container = $container; } public static function getSubscribedEvents(): array { // 绑定需要监听的客户映射事件 return [ CustomerMappingEvent::class => 'sendMappingNotification' ]; } public function sendMappingNotification(CustomerMappingEvent $event): void { $customer = $event->getCustomer(); $context = $event->getContext(); // 构建邮件发送参数 $mailParams = [ 'recipients' => [ $customer->getEmail() => sprintf('%s %s', $customer->getFirstName(), $customer->getLastName()) ], 'sender' => [ 'name' => '你的店铺名称', 'email' => 'support@yourstore.com' ], 'subject' => '客户映射完成通知', 'templateId' => $this->getMailTemplateId($context), 'salesChannelId' => $context->getSource()->getSalesChannelId(), 'data' => [ 'customer' => $customer->jsonSerialize(), // 可添加模板需要的自定义变量 ] ]; try { $this->mailService->send($mailParams, $context); } catch (\Exception $e) { // 记录错误日志,避免中断事件流程 $this->logger->error('客户映射邮件发送失败: ' . $e->getMessage(), ['exception' => $e]); } } private function getMailTemplateId(Context $context): string { // 通过模板名称获取ID,避免硬编码 $repo = $this->container->get('mail_template.repository'); $template = $repo->search( (new \Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria()) ->addFilter(new \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter('name', 'customer_mapping_notification')), $context )->first(); return $template ? $template->getId() : throw new \RuntimeException('对应邮件模板未找到'); } }
2. 注册订阅器服务
在插件的src/Resources/config/services.xml中注册该订阅器:
<service id="YourPluginNamespace\Subscriber\CustomerMappingMailSubscriber"> <argument type="service" id="Shopware\Core\Content\Mail\Service\MailService"/> <argument type="service" id="logger"/> <argument type="service" id="service_container"/> <tag name="kernel.event_subscriber"/> </service>
3. 配置邮件模板
在Shopware后台创建对应邮件模板:
- 进入 设置 > 邮件模板 > 新建模板
- 设置模板名称为
customer_mapping_notification,填写主题、HTML/纯文本内容,示例:
HTML内容:
<h3>您好,{{ customer.firstName }}!</h3> <p>您的客户信息已完成映射,感谢您的使用。</p>
4. 优化建议
- 异步发送:若邮件发送耗时较长,建议改用异步队列避免阻塞事件处理,只需将
send方法替换为异步消息:// 注入MessageBus private \Symfony\Component\Messenger\MessageBusInterface $messageBus; // 构造函数初始化 public function __construct(..., \Symfony\Component\Messenger\MessageBusInterface $messageBus) { ... $this->messageBus = $messageBus; } // 发送异步邮件消息 $this->messageBus->dispatch(new \Shopware\Core\Content\Mail\Event\MailSendEvent($mailParams, $context)); - 多语言适配:在邮件模板中使用翻译变量,适配不同语言环境
- 权限校验:确保事件触发时的上下文拥有读取邮件模板和发送邮件的权限
内容的提问来源于stack exchange,提问作者Muhammad Zahoor
相关产品推荐
相关产品推荐

