Вчера мы добавили веб-сервис для 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.