Вчера мы добавили веб-сервис для Jobeet. Партнеры теперь могут создать аккаунт, но он нуждается в активировании администратором, прежде чем он может быть использован. Поскольку партнеры должны получать свои токены (token), мы по-прежнему нуждаемся в том, чтобы реализовать email-уведомления. Это то, чем мы сегодня займемся.
Фреймворк Symfony поставляется с одним из лучших решений PHP для электронной почты: Swift Mailer. Конечно, библиотека полностью интегрирована в Symfony, с несколькими полезными возможностями, ставшими первыми в списке основных возможностей.
note
Symfony 1.3/1.4 использует Swift Mailer версии 4.1.
Отправка простых email-сообщений
Давайте начнем с отправки простого email-сообщения, чтобы уведомить партнера, что его аккаунт подтвержден и дать ему партнерский токен.
Заменим действие activate следующим кодом:
// apps/backend/modules/affiliate/actions/actions.class.php class affiliateActions extends autoAffiliateActions { public function executeListActivate() { $affiliate = $this->getRoute()->getObject(); $affiliate->activate(); // send an email to the affiliate $message = $this->getMailer()->compose( array('jobeet@example.com' => 'Jobeet Bot'), $affiliate->getEmail(), 'Jobeet affiliate token', <<<EOF Your Jobeet affiliate account has been activated. Your token is {$affiliate->getToken()}. The Jobeet Bot. EOF ); $this->getMailer()->send($message); $this->redirect('jobeet_affiliate'); } // ... }
note
Чтобы код работал правильно, Вы должны заменить адрес jobeet@example.com
на реальный.
Управление почтой в Symfony централизовано вокруг объекта Mailer, который может
быть получен в любом действии контроллера при помощи метода getMailer().
Метод compose() принимает четыре параметра и возвращает объект email
сообщения:
- email-адрес отправителя (
from); - email-адрес(а) получателя (
to); - тема сообщения;
- текст сообщения.
Затем, отправка сообщения делается простым вызовом метода send()
экземпляра объекта Mailer с объектом email-сообщения в качестве аргумента. Более быстрый способ -
создать и отправить email одним действием путем вызова метода composeAndSend().
tip
Email-сообщение является экземпляром класса Swift_Message. Обратитесь
к официальной документации Swift Mailer, чтобы
узнать больше об этом объекте, и о том, как использовать более продвинутые возможности,
например, отправку файлов.
Настройка
По умолчанию метод send() пытается использовать локальный SMTP-сервер, чтобы отправить
сообщение получателю. Разумеется, как и многое в Symfony, это полностью настраиваемо.
Фабрики (Factories)
В течение предыдущих дней, мы уже говорили об основополагающих объектах Symfony
таких, как пользователь (user), запрос (request), ответ (response) или
маршрутизация (routing). Эти объекты автоматически
создаются, настраиваются и управляются фреймворком Symfony. Они всегда
доступны благодаря объекту sfContext, и как многие вещи во фреймворке
они настраиваются в конфигурационном файле:
factories.yml. Этот файл содержит настройки для различных окружений.
Когда объект sfContext инициализирует основные фабрики, он читает файл
factories.yml, чтобы определить имена классов (class) и параметры
(param), которые будут переданы в конструктор:
response:
class: sfWebResponse
param:
send_http_headers: false
В приведенном фрагменте, чтобы создать фабрику запросов, Symfony создает
объекты sfWebResponse и передает значение опции send_http_headers
в качестве параметра.
Стратегия отправки
Так же, как многие другие основныек объекты Symfony, Mailer - это фабрика. Таким образом,
она настраивается в файле factories.yml. Конфигурация по умолчанию выглядит так:
mailer:
class: sfMailer
param:
logging: %SF_LOGGING_ENABLED%
charset: %SF_CHARSET%
delivery_strategy: realtime
transport:
class: Swift_SmtpTransport
param:
host: localhost
port: 25
encryption: ~
username: ~
password: ~
Когда создается новое приложение, локальный конфигурационный файл factories.yml перекрывает
конфигурацию по умолчанию некоторыми более специфическими настройками для сред env и test:
test:
mailer:
param:
delivery_strategy: none
dev:
mailer:
param:
delivery_strategy: none
Настройка delivery_strategy говорит Symfony, как отправлять почту. По
умолчанию, Symfony содержит четыре разных стратегии:
realtime: Сообщения отправляются в реальном времени.single_address: Сообщения отправляются на один адрес.spool: Сообщения ставятся в очередь на отправку.none: Сообщения просто игнорируются.
Какой бы ни была стратегия, электронные сообщения всегда логгируются и доступны на вкладке "mailer" панели web-дебага.
Почтовый транспорт
Почтовые сообщения отправляются посредством транспорта. Транспорт настраивается в
конфигурационном файле factories.yml, и конфигурация по умолчанию использует
SMTP-сервер локальной машины:
transport:
class: Swift_SmtpTransport
param:
host: localhost
port: 25
encryption: ~
username: ~
password: ~
Swift Mailer поставляется с тремя стандартными классами транспорта:
Swift_SmtpTransport: Использует SMTP-сервер для отправки сообщений.Swift_SendmailTransport: Использует объектsendmailдля отправки сообщений.Swift_MailTransport: Использует стандартную функцию PHPmail()для отправки сообщений.
tip
Секция "Типы транспорта" официальной документации Swift Mailer описывает все, что Вам нужно знать о встроенных классах транспорта и их разнообразных параметрах.
Тестирование работы с почтой
Теперь, поскольку мы увидели, как отправить email при помощи Symfony, давайте
напишем функциональные тесты, чтобы убедиться, что все сделали правильно. По умолчанию,
Symfony регистрирует тестер mailer (sfMailerTester) для облегчения тестирования
работы с почтой в функциональных тестах.
First, change the mailer factory configuration for the test environment if your web server does not have a local SMTP server. We have to replace the current Swift_SmtpTransport class by Swift_MailTransport:
# apps/backend/config/factories.yml
test:
# ...
mailer:
param:
delivery_strategy: none
transport:
class: Swift_MailTransport
Then, add a new test/fixtures/administrators.yml file containing the following YAML definition:
sfGuardUser:
admin:
email_address: admin@example.com
username: admin
password: admin
first_name: Fabien
last_name: Potencier
is_super_admin: true
Finally, replace the affiliate functional test file for the backend application with the following code:
// test/functional/backend/affiliateActionsTest.php include(dirname(__FILE__).'/../../bootstrap/functional.php'); $browser = new JobeetTestFunctional(new sfBrowser()); $browser->loadData(); $browser-> info('1 - Authentication')-> get('/affiliate')-> click('Signin', array( 'signin' => array('username' => 'admin', 'password' => 'admin'), array('_with_csrf' => true) ))-> with('response')->isRedirected()-> followRedirect()-> info('2 - When validating an affiliate, an email must be sent with its token')-> click('Activate', array(), array('position' => 1))-> with('mailer')->begin()-> checkHeader('Subject', '/Jobeet affiliate token/')-> checkBody('/Your token is symfony/')-> end() ;
Каждое отправленное email-сообщение может быть протестировано при помощи методов
checkHeader() и checkBody(). Второй аргумент checkHeader() и первый аргумент
checkBody() может иметь одно из следующих значений:
строка, чтобы проверить точное совпадение;
регулярное выражение, которому должно удовлетворять значение;
обратное регулярное выражение (регулярное выражение, начинающееся с
"!"), чтобы легко указать, с чем не должно совпадать значение.
note
По умолчанию, проверки выполняются для первого отправленного сообщения. Если несколько
сообщений отправлено, Вы можете выбрать одно, которое хотите протестировать методом withMessage().
Метод withMessage() принимает адрес получателя в качестве первого аргумента. Также
он принимает и второй аргумент, для указания, какое сообщение Вы хотите тестировать, если
одному получателю отправлено несколько сообщений.
tip
Так же, как и для других встроенных тестеров, Вы можете увидеть полное сообщение, вызвав метод
debug().
Увидимся завтра!
Завтра мы реализуем последнюю заявленную возможность сайта Jobeet - поисковый движок.
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.