You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony:为FosUserBundle多用户类型配置独立邮件模板

解决方案:为不同用户类型配置独立FOSUser邮件模板

我之前在Symfony项目里用FosUserBundle+PugxMultiUserBundle实现多用户类型时,也碰到过这个全局模板配置的问题。其实核心思路就是替换FOSUserBundle默认的邮件发送服务,根据用户类型动态加载对应的模板。下面是具体步骤:

1. 创建自定义邮件发送器

首先写一个继承自FOSUserBundle默认Mailer的自定义类,重写需要区分模板的邮件发送方法(比如密码重置、注册确认):

// src/Mailer/CustomUserMailer.php
namespace App\Mailer;

use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Mailer\TwigSwiftMailer;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class CustomUserMailer extends TwigSwiftMailer
{
    public function sendResettingEmailMessage(UserInterface $user): void
    {
        // 根据用户实体类判断使用对应模板
        if ($user instanceof \App\Entity\CmsUser) {
            $template = '@FOSUser/Resetting/email_cms.html.twig';
        } else { // 平台玩家用户类
            $template = '@FOSUser/Resetting/email_player.html.twig';
        }

        $url = $this->router->generate('fos_user_resetting_reset', [
            'token' => $user->getConfirmationToken(),
        ], UrlGeneratorInterface::ABSOLUTE_URL);

        $context = [
            'user' => $user,
            'confirmationUrl' => $url,
        ];

        $this->sendMessage($template, $context, $this->parameters['from_email']['resetting'], $user->getEmail());
    }

    public function sendConfirmationEmailMessage(UserInterface $user): void
    {
        // 同样逻辑处理注册确认邮件
        if ($user instanceof \App\Entity\CmsUser) {
            $template = '@FOSUser/Registration/email_cms.html.twig';
        } else {
            $template = '@FOSUser/Registration/email_player.html.twig';
        }

        $url = $this->router->generate('fos_user_registration_confirm', [
            'token' => $user->getConfirmationToken(),
        ], UrlGeneratorInterface::ABSOLUTE_URL);

        $context = [
            'user' => $user,
            'confirmationUrl' => $url,
        ];

        $this->sendMessage($template, $context, $this->parameters['from_email']['confirmation'], $user->getEmail());
    }
}

2. 替换默认的FOS邮件服务

在config/services.yaml里把FOSUserBundle的mailer服务替换成我们自定义的类:

services:
    # 覆盖FOSUserBundle默认的邮件发送服务
    FOS\UserBundle\Mailer\MailerInterface:
        class: App\Mailer\CustomUserMailer
        arguments:
            - '@twig'
            - '@swiftmailer.mailer'
            - '@router'
            - '%fos_user.mailer%'

3. 准备对应用户类型的邮件模板

按照我们在自定义邮件器里指定的路径,创建不同的模板文件:

  • templates/bundles/FOSUserBundle/Resetting/email_cms.html.twig(CMS用户的密码重置模板)
  • templates/bundles/FOSUserBundle/Resetting/email_player.html.twig(平台玩家的密码重置模板)
  • 同理,注册确认的模板放在Registration目录下

模板内容可以基于FOSUserBundle的默认模板修改,比如调整问候语、专属提示信息等。

额外优化:参数化模板路径

如果不想在代码里硬写模板路径,可以在config/packages/fos_user.yaml里为每个用户类型添加模板配置:

fos_user:
    # ... 其他全局配置
    cms_user:
        resetting:
            template: '@FOSUser/Resetting/email_cms.html.twig'
        registration:
            template: '@FOSUser/Registration/email_cms.html.twig'
    player_user:
        resetting:
            template: '@FOSUser/Resetting/email_player.html.twig'
        registration:
            template: '@FOSUser/Registration/email_player.html.twig'

然后在自定义邮件器里通过参数获取这些配置:

// 在CustomUserMailer的构造函数里注入ParameterBagInterface
public function __construct(\Twig\Environment $twig, \Swift_Mailer $mailer, UrlGeneratorInterface $router, array $parameters, \Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface $parameterBag)
{
    parent::__construct($twig, $mailer, $router, $parameters);
    $this->parameterBag = $parameterBag;
}

// 然后在发送方法里获取对应模板
$template = $this->parameterBag->get('fos_user.cms_user.resetting.template');

这样后续修改模板路径不需要改动代码,维护起来更灵活。


内容的提问来源于stack exchange,提问作者billy tzez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:53:59