1

How can I add company log in email twig using FOS UserBundle? I do want to do it with in the twig files and don't want to create a custom mailer class just to add an image.

I've done overriding the defaild template and enabling the swift mailer.

tried so far:

<img id="logo" src="{{ asset('bundles/demo/img/logo_login.png') }}" alt="test!" />

this does send the email, however the image path is incomplete (missing the host part)

When I do add the app.request.getSchemeAndHttpHost() for obtaining the host the mail will not be send

<img id="logo" src="{{ app.request.getSchemeAndHttpHost() ~ asset('bundles/demo/img/logo_login.png') }}" alt="test!" />

Does anyone have a sollution or idea that I could try?

thanks in advance

Greezer
  • 515
  • 2
  • 4
  • 18

2 Answers2

1

asset() will create an url to the image on your website. This will make a lot a spam filters ring the alarm and most email clients just block the image. Luckily you can embed images using the Swiftmailer.

I assume that you have already configured custom email templates as explained in Sending HTML mails.

First, create a class in your custom user bundle (when you have overwritten the FosUserBundle) or otherwise somewhere else, e.g. Foo/BarBundle/Mailer/CustomUserMailer.php:

namespace Foo\BarBundle\Mailer;

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

class CustomUserMailer extends BaseMailer
{
    public function __construct(
        \Swift_Mailer $mailer,
        UrlGeneratorInterface $router,
        \Twig_Environment $twig,
        array $parameters
    )
    {
        parent::__construct($mailer, $router, $twig, $parameters);
    }

    /**
     * @param string $templateName
     * @param array  $context
     * @param string $fromEmail
     * @param string $toEmail
     */
    protected function sendMessage($templateName, $context, $fromEmail, $toEmail)
    {
        // Create a new mail message.
        $message = \Swift_Message::newInstance();
        $mailImgDir = __DIR__ . '/../Resources/images';
        $context['company_logo_cid'] = $message->embed(\Swift_Image::fromPath($mailImgDir.'/your_fancy_logo.png'));

        $context = $this->twig->mergeGlobals($context);
        $template = $this->twig->loadTemplate($templateName);
        $subject = $template->renderBlock('subject', $context);
        $textBody = '';
        $htmlBody = $template->render($context);

        $message
            ->setSubject($subject)
            ->setFrom($fromEmail)
            ->setTo($toEmail);

        if (!empty($htmlBody)) {
            $message
                ->setBody($htmlBody, 'text/html')
                ->addPart($textBody, 'text/plain');
        } else {
            $message->setBody($textBody);
        }

        $this->mailer->send($message);
    }
}

And register this class in your services.yml:

# Service that extends the default twig mailer
foo_bar.custom_mailer:
    class: Foo\BarBundle\Mailer\CustomUserMailer
    public: false
    arguments:
        - '@mailer'
        - '@router'
        - '@twig'
        - template:
            confirmation: %fos_user.registration.confirmation.template%
            resetting: %fos_user.resetting.email.template%
          from_email:
            confirmation: %fos_user.registration.confirmation.from_email%
            resetting: %fos_user.resetting.email.from_email%

Next, let the FosUserBundle know that it should use this Mailer class by putting the following in your config.yml file:

fos_user:
    service:
        mailer: foo_bar.custom_mailer

Assuming that you have put your company logo in src/Foo/BarBundle/Resources/images/your_fancy_logo.png you can now reference the image in your mail templates:

<img width="xxx" height="xxx" border="0" alt="My fancy company logo" src="{{ company_logo_cid }}" />
Sander Toonen
  • 3,463
  • 35
  • 54
  • if my image is located in "web/assets/images", I use ../../web/assets/images or something else ?? plz – krachleur Aug 05 '16 at 11:22
  • @Krachleur You can inject the kernel rootdir into your mailer, and append "../web/assets/images" to that. See http://stackoverflow.com/a/21143137/3492835 – Sander Toonen Aug 05 '16 at 11:26
0

Here is a bit cleaner solution.

  1. CREATE A NEW SERVICE:
// AppBundle/Mailers/CustomFOSUserMailer.php

namespace AppBundle\Mailers;

use AppBundle\Services\StoreService;
use AppBundle\Services\ThemeService;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use FOS\UserBundle\Mailer\TwigSwiftMailer as BaseType;

/**
 * This class overrides default FOS User Mailer
 * We need this to pass some data from our services to the twig templates:
 * > Logo path
 * > Store Phone number & E-mail address
 */
class CustomFOSUserMailer extends BaseType
{
    /** @var ThemeService */
    protected $theme;

    /** @var StoreService */
    protected $store;

    /** @var ContainerInterface */
    protected $container;

    public function __construct(
        ThemeService $theme,
        StoreService $store,
        ContainerInterface $container,
        \Swift_Mailer $mailer,
        UrlGeneratorInterface $router,
        \Twig_Environment $twig,
        array $parameters)
    {
        parent::__construct($mailer, $router, $twig, $parameters);

        $this->theme     = $theme;
        $this->store     = $store;
        $this->container = $container;
    }

    /**
     * Overriding sendMessage of the parent class, so we can render our variables
     *
     * @param string $templateName
     * @param array  $context
     * @param string $fromEmail
     * @param string $toEmail
     */
    protected function sendMessage($templateName, $context, $fromEmail, $toEmail)
    {
        $request = $this->container->get('request');
        $baseurl = $request->getScheme() . '://' . $request->getHttpHost() . $request->getBasePath();

        $context = array_merge($context, [
            'storeLogoUrl'  => $baseurl . $this->theme->logoImage(),
            'storePhone'    => $this->store->getCurrentStore()->getPhone(),
            'storeEmail'    => $this->store->getCurrentStore()->getEmail(),
        ]);

        parent::sendMessage($templateName, $context, $fromEmail, $toEmail);
    }
}
  1. REGISTER SERVICE:
// services.yml
services:
    app.mailer.custom_fos_user_mailer:
        class: AppBundle\Mailers\CustomFOSUserMailer
        arguments:
            - @app.theme
            - @app.store
            - @service_container
            - @mailer
            - @router
            - @twig
            -
                template:
                    confirmation: %fos_user.registration.confirmation.template%
                    resetting: %fos_user.resetting.email.template%
                from_email:
                    confirmation: %fos_user.registration.confirmation.from_email%
                    resetting: %fos_user.resetting.email.from_email%
  1. OVERRIDE FOS DEFAULT MAILER
// config.yml    
fos_user:
    service:
        mailer: app.mailer.custom_fos_user_mailer

registration:
    confirmation:
        enabled: true
        template: AppBundle:emails/user:confirm.html.twig
  1. TWIG EXAMPLE:
<img src="{{ storeLogoUrl }}" height="50">