Symfony2 - Adding Swiftmailer as a service

故事扮演 提交于 2019-12-13 14:29:13

问题


I'd like to move my email code from my controller into a service.

I've done the following thus far:

  • created the entry in services.yml

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

Could use some help on what needs to go into the 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 out of the controller into 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\'s 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';
}
}

回答1:


You can customize this as you see fit, but that's a general idea and a very quick draft to guide 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 could have:

  • An email data model that would contain the fields necessary for an email (like $subject, $recipientEmail, ...)
  • A composer that would compose your email from your request
  • A sender that would send your email

EMAIL MODEL would look something like this:

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

    // etc...etc..

}

You'd have an EmailInterface too:

/**
 * Email interface
 */
interface EmailInterface
{

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

    // etc...etc..

}

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

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

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

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

    return $email;
}

Note: Composer and Sender could also be a separate service for better reuse, that's up to you I guess. Here is what they would look like if there were just functions in your EmailManager



来源:https://stackoverflow.com/questions/25518215/symfony2-adding-swiftmailer-as-a-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!