Symfony2 - adding Swiftmailer as a service

I would like to move my email code from my controller to a service.

I did the following:

  • created an entry in services.yml

  • created EmailManager.php file inside acme / demobundle / services / EmailManager.php

Can I use some help on what to go into EmailManager.php and how to call it in the controller?

services.yml

services:
email_manager:
    class: Acme\DemoBundle\Services\EmailManager
    arguments: [@request_stack, @mailer]
            scope: request

      

EmailManager.php

<?php
// src/Acme/DemoBundle/Services/EmailManager.php

namespace Acme\DemoBundle\Services;

class EmailManager
{
private $mailer;
private $request;

public function __construct(RequestStack $requestStack, $mailer)
{
    $this->request = $requestStack->getCurrentRequest();
    $this->mailer  = $mailer;
}

What needs to go here? Do I just copy/paste the code from the contactAction below into here?

}

      

Controller code with contactAction that I would like to move from controller to EmailManager service:

/**
 * @Route("/", name="contact")
 * @Template("AcmeDemoBundle:Default:index.html.twig")
 */
public function contactAction(Request $request)
{
$form = $this->createForm(new ContactType());

if ($request->isMethod('POST')) {
    $form->submit($request);

    if ($form->isValid()) {
        $message = \Swift_Message::newInstance()
            ->setSubject($form->get('subject')->getData())
            ->setFrom($form->get('email')->getData())
            ->setTo('example@gmail.com')
            ->setBody(
                $this->renderView(
                    'AcmeDemoBundle:Default:index.html.twig',
                    array(
                        'ip' => $request->getClientIp(),
                        'name' => $form->get('name')->getData(),
                        'message' => $form->get('message')->getData()
                    )
                )
            );

        $this->get('mailer')->send($message);

        $request->getSession()->getFlashBag()->add('success', 'Your email has been sent! Thanks!');

        return $this->redirect($this->generateUrl('contact'));
    }
}

return array(
    'form' => $form->createView()
);
}

      

ContactType form

class ContactType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
    ->add('name', 'text', array(
    'attr' => array(
        'placeholder' => 'What\ your name?',
        'pattern'     => '.{2,}' //minlength
    )
))
    ->add('email', 'email', array(
        'attr' => array(
            'placeholder' => 'So I can get back to you.'
        )
    ))
    ->add('subject', 'text', array(
        'attr' => array(
            'placeholder' => 'The subject of your message.',
            'pattern'     => '.{3,}' //minlength
        )
    ))
    ->add('message', 'textarea', array(
        'attr' => array(
            'cols' => 90,
            'rows' => 10,
            'placeholder' => 'And your message to me...'
        )
    ));
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $collectionConstraint = new Collection(array(
        'name' => array(
            new NotBlank(array('message' => 'Name should not be blank.')),
            new Length(array('min' => 2))
        ),
        'email' => array(
            new NotBlank(array('message' => 'Email should not be blank.')),
            new Email(array('message' => 'Invalid email address.'))
        ),
        'subject' => array(
            new NotBlank(array('message' => 'Subject should not be blank.')),
            new Length(array('min' => 3))
        ),
        'message' => array(
            new NotBlank(array('message' => 'Message should not be blank.')),
            new Length(array('min' => 5))
        )
    ));

    $resolver->setDefaults(array(
        'constraints' => $collectionConstraint
    ));
}

public function getName()
{
    return 'contact';
}
}

      

+3


source to share


1 answer


You can customize this as you like, but this is a general idea and a very quick project to help you:

public function send($subject, $recipientName, $recipientEmail, $bodyHtml, $bodyText)
{
    /* @var $mailer \Swift_Mailer */
    if(!$this->mailer->getTransport()->isStarted()){
        $this->mailer->getTransport()->start();
    }

    /* @var $message \Swift_Message */
    $message = $this->mailer->createMessage();
    $message->setSubject($subject);

    $message->setBody($bodyHtml, 'text/html');
    $message->addPart($bodyText, 'text/plain', 'UTF8');

    $message->addTo($recipientEmail, $recipientName);
    $message->setFrom( array('example@gmail.com' => 'Chance') );

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

      


Room for improvement

You may have:

  • email data model

    Which will contain the fields required for e-mail (for example $subject

    , $recipientEmail

    ...)
  • A that will compose your email from your request composer

  • A that will send your email sender

EMAIL MODEL will look something like this:

/**
 * Email Data Model
 */
class Email implements EmailInterface
{
    /**
     * The text part of the message.
     *
     * @var string
     */
    protected $bodyText;

    // etc...etc..

}

      



You will also have EmailInterface:

/**
 * Email interface
 */
interface EmailInterface
{

    /**
     * @return string
     */
    public function getBodyText();

    // etc...etc..

}

      

THE SENDER would look like this (if stored inside the EmailManager):

public function send(EmailInterface $email)
{
    //...
}

      

THE COMPOSER would look like this (if stored inside the EmailManager):

public function composeEmail(Request $request)
{
    //...

    return $email;
}

      

Note. Composer and Sender can also be a separate service for better reuse, which is up to you, I think. This is how they would look if there were only functions in the EmailManager.

+7


source







All Articles