![](https://habrastorage.org/files/764/069/086/7640690867bf4e95bfcb9acd9e1e58fc.png)
Навигация по частям руководства
Страница с контактной информацией: валидаторы, формы и электронная почта
В этой части:
1. Валидаторы
2. Формы
3. Конфигурация Бандла
Проект на Github
Узнать как установить нужную вам часть руководства, можно в описании к репозиторию по ссылке. (Например, если вы хотите начать с это урока не проходя предыдущий)
Страница контактов
Маршрутизация
Как и со страницей “About” созданной в предыдущей главе, мы начнем с определения маршрута для страницы контактов. Откройте файл маршрутизации BloggerBlogBundle расположенный в
src/Blogger/BlogBundle/Resources/config/routing.yml
и добавьте следующее правило маршрутизации.
# src/Blogger/BlogBundle/Resources/config/routing.yml
BloggerBlogBundle_contact:
path: /contact
defaults: { _controller: "BloggerBlogBundle:Page:contact" }
requirements:
methods: GET
Здесь нет ничего нового, правило действует для шаблона /contact, метод HTTP GET и выполняет функцию contactAction в контроллере Page в нашем бандле BloggerBlog.
Контроллер
Давайте добавим функцию для страницы Контактов в контроллер Page нашего бандла BloggerBlog который находится в
src/Blogger/BlogBundle/Controller/PageController.php
class PageController extends Controller
{
//..
public function contactAction()
{
return $this->render('BloggerBlogBundle:Page:contact.html.twig');
}
}
Сейчас эта функция очень проста, она лишь выводит шаблон для страницы контактов. Мы вернемся к контроллеру позже.
Отображение
Создайте шаблон:
src/Blogger/BlogBundle/Resources/views/Page/contact.html.twig
И добавьте следующее содержание:
{# src/Blogger/BlogBundle/Resources/views/Page/contact.html.twig #}
{% extends 'BloggerBlogBundle::layout.html.twig' %}
{% block title %}Contact{% endblock%}
{% block body %}
<header>
<h1>Contact symblog</h1>
</header>
<p>Want to contact symblog?</p>
{% endblock %}
Этот шаблон также довольно прост. Он расширяет шаблон layout, переопределяет заголовок и определяет некоторый контент для блока body.
Cсылки на страницы
Наконец, мы должны обновить ссылки в шаблоне приложения, чтобы добавить ссылку на страницу контактов
app/Resources/views/base.html.twig
#app/Resources/views/base.html.twig
{% block navigation %}
<nav>
<ul class="navigation">
<li><a href="{{ path('BloggerBlogBundle_homepage') }}">Home</a></li>
<li><a href="{{ path('BloggerBlogBundle_about') }}">About</a></li>
<li><a href="{{ path('BloggerBlogBundle_contact') }}">Contact</a></li>
</ul>
</nav>
{% endblock %}
Если вы перейдёте по адресу http://localhost:8000 и нажмёте на ссылку «Contact» в навигационной панели, вы увидите очень простую страницу контактов. Теперь у нас есть правильно настроенная страница и самое время, поработать с формой. Это включает в себя 2 отдельные части: Валидаторы и непосредственно сама Форма. Прежде чем мы сможем обратиться к концепции Валидаторов и Форм, мы должны подумать о том, как мы будем обрабатывать данные из запроса.
Сущность Contact
Давайте начнём с создания класса, который представляет запрос от пользователя. Мы хотим, принять некоторую базовую информацию, такую как имя, тема и тело запроса. Создайте новый файл
src/Blogger/BlogBundle/Entity/Enquiry.php
и вставьте в следующее содержание:<?php
// src/Blogger/BlogBundle/Entity/Enquiry.php
namespace Blogger\BlogBundle\Entity;
class Enquiry
{
protected $name;
protected $email;
protected $subject;
protected $body;
/**
* @return mixed
*/
public function getName()
{
return $this->name;
}
/**
* @param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @return mixed
*/
public function getEmail()
{
return $this->email;
}
/**
* @param mixed $email
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* @return mixed
*/
public function getSubject()
{
return $this->subject;
}
/**
* @param mixed $subject
*/
public function setSubject($subject)
{
$this->subject = $subject;
}
/**
* @return mixed
*/
public function getBody()
{
return $this->body;
}
/**
* @param mixed $body
*/
public function setBody($body)
{
$this->body = $body;
}
}
Совет (если вы используете IDE PHPStorm)
У вас есть возможность генерировать геттеры и сеттеры автоматически.
Для этого:
1. Нажмите на правую кнопку мыши в файле (или комбинацию alt+insert), выберите Generate
![](https://habrastorage.org/r/w1560/files/894/4a5/c30/8944a5c3005a49e9ab0290488371fe3a.png)
2. Далее Getters and Setters
![](https://habrastorage.org/r/w1560/files/1fa/e33/16e/1fae3316e5154a1b9e2d34cba0ed60bd.png)
3. Выделите все и нажмите ОК.
![](https://habrastorage.org/r/w1560/files/56f/cf8/9ea/56fcf89ea1fc49f9afa188c5ebc71a62.png)
Для этого:
1. Нажмите на правую кнопку мыши в файле (или комбинацию alt+insert), выберите Generate
![](https://habrastorage.org/files/894/4a5/c30/8944a5c3005a49e9ab0290488371fe3a.png)
2. Далее Getters and Setters
![](https://habrastorage.org/files/1fa/e33/16e/1fae3316e5154a1b9e2d34cba0ed60bd.png)
3. Выделите все и нажмите ОК.
![](https://habrastorage.org/files/56f/cf8/9ea/56fcf89ea1fc49f9afa188c5ebc71a62.png)
Как вы можете видеть этот класс просто определяет некоторые защищенные переменные и методы доступа к ним. Там нет ничего, что определяет, как мы будем валидировать переменные или как переменные относятся к элементам формы. Мы вернемся к этому позже.
Заметка
Давайте поговорим о том, как используются пространства имён в Symfony2. Класс сущности который мы создали задаёт пространство имёнBlogger\BlogBundle\Entity
. Так как Symfony2 поддерживает стандарт автозагрузки PSR-0 пространство имён указывает непосредственно на структуру файлов бандла. Класс сущности Enquiry находится вsrc/Blogger/BlogBundle/Entity/Enquiry.php
, что обеспечивает Symfony2 правильную автозагрузку класса.
Каким образом Symfony2 автозагрузчик понимает, что пространство имен Blogger находится в каталоге src? Это обеспечивается благодаря конфигурациям автозагрузчикаapp/autoload.php
/** * @var ClassLoader $loader */ $loader = require __DIR__.'/../vendor/autoload.php'; AnnotationRegistry::registerLoader(array($loader, 'loadClass')); return $loader;
Он регистрирует все пространства имён которые не были зарегистрированы. Так как пространство имен Blogger не зарегистрировано, Symfony2 автозагрузчик будет искать необходимые файлы в директории src.
Автозагрузчик и пространство имен очень мощная концепция в Symfony2. Если вы получаете ошибки, где PHP не может найти классы, вероятно, у вас есть ошибка в вашем пространстве имен или в структуре папок. Вы не должны поддаваться искушению исправить это с помощью РНР require или include включения.
Формы
Давайте создадим форму.
Symfony2 поставляется с очень мощным инструментом для работы с формами. Как и все компоненты Symfony2, он может быть использован за пределами Symfony2 в других проектах. Компонент работы с Формами доступен на GitHub. Мы начнем с создания AbstractType класса, который представляет форму запроса. Мы могли бы создать форму непосредственно в контроллере, а не возиться с этим классом, однако отделение формы в отдельный класс позволяет повторно использовать форму во всем приложении. Он так же позволяет не загромождать контроллер. Контроллер должен быть простым.
EnquiryType
Создайте новый файл
src/Blogger/BlogBundle/Form/EnquiryType.php
и добавьте следующее содержание:<?php
namespace Blogger\BlogBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class EnquiryType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name', TextType::class);
$builder->add('email', EmailType::class);
$builder->add('subject', TextType::class);
$builder->add('body', TextareaType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
}
public function getBlockPrefix()
{
return 'contact';
}
}
Совет (если вы используете IDE PHPStorm)
Если вы используете IDE PHPStorm c плагином Symfony то создание класса EnquiryType будет еще проще
Нажмите правой кнопкой мыши на папке бандла, выберите New -> Form (или нажмите комбинацию Alt + Insert и выберите Form)
![](https://habrastorage.org/r/w1560/files/3f7/d6e/e0d/3f7d6ee0d1524eeeb64c1b8f29ba1b4d.png)
затем введите название EnquiryType и добавьте недостающие строки как описано выше ( обратите внимание, последний метод должен быть getBlockPrefix )
Нажмите правой кнопкой мыши на папке бандла, выберите New -> Form (или нажмите комбинацию Alt + Insert и выберите Form)
![](https://habrastorage.org/files/3f7/d6e/e0d/3f7d6ee0d1524eeeb64c1b8f29ba1b4d.png)
затем введите название EnquiryType и добавьте недостающие строки как описано выше ( обратите внимание, последний метод должен быть getBlockPrefix )
Класс EnquiryType представляет интерфейс FormBuilderInterface. Этот интерфейс используется классом FormBuilder. Класс FormBuilder это ваш лучший друг, когда дело доходит до создания форм. Он способен упростить процесс определения полей на основе метаданных. Поскольку наша сущность Enquiry очень простая мы не будет пока определять метаданные, так что FormBuilder будет выводить значения по умолчанию.
Заметка
Здесь нужно упомянуть, что метод getBlockPrefix должен возвращать уникальный идентификатор.
Создание формы в контроллере
Мы определили сущности Enquiry и EnquiryType, теперь мы можем обновить функцию contact, чтобы использовать их. Замените содержимое функции, расположенной
src/Blogger/BlogBundle/Controller/PageController.php
следующим:// src/Blogger/BlogBundle/Controller/PageController.php
public function contactAction(Request $request)
{
$enquiry = new Enquiry();
$form = $this->createForm(EnquiryType::class, $enquiry);
if ($request->isMethod($request::METHOD_POST)) {
$form->handleRequest($request);
if ($form->isValid()) {
// Perform some action, such as sending an email
// Redirect - This is important to prevent users re-posting
// the form if they refresh the page
return $this->redirect($this->generateUrl('BloggerBlogBundle_contact'));
}
}
return $this->render('BloggerBlogBundle:Page:contact.html.twig', array(
'form' => $form->createView()
));
}
Мы начнём с создания экземпляра сущности Enquiry. Эта сущность представляет данные о contact запросе. Далее мы создадим форму. Определим EnquiryType, который мы создали ранее, и передадим нашему enquiry entity object.
Так как эти действия контроллера будут иметь дело с отображением и обработкой отправленной формы, мы должны проверить метод HTTP. Формы, как правило, передаются через метод POST, и наша форма не будет исключением. Если метод запроса будет POST, вызов
submit($request)
превратит отправленные данные обратно в элементы нашего $enquiry object. На данный момент объект $enquiry содержит представление о том, что отправил пользователь. Далее мы сделаем проверку, чтобы убедиться, что форма заполнена верно. Так как мы не указали ни одного валидатора на этот момент, форма всегда будет действительна. И наконец мы укажем шаблон для визуализации. Мы должны импортировать пространства имен в наш контроллер т.к. используем новые классы. Обновите файл контроллера, расположенный в
src/Blogger/BlogBundle/Controller/PageController.php
Заявления должны быть размещены под уже имеющимися.
<?php
// src/Blogger/BlogBundle/Controller/PageController.php
namespace Blogger\BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
// Import new namespaces
use Symfony\Component\HttpFoundation\Request;
use Blogger\BlogBundle\Entity\Enquiry;
use Blogger\BlogBundle\Form\EnquiryType;
class PageController extends Controller
{
//..
Отображение формы
Благодаря шаблонизатору Twig вывод форм очень прост. Twig предоставляет многоуровневую систему для вывода форм, что позволяет выводить форму как одну целую сущность или в виде отдельных ошибок и элементов, в зависимости от уровня настройки которая вам требуется. Чтобы продемонстрировать мощь методов Twig выведем всю форму, следующим фрагментом кода:
<form action="{{ path('BloggerBlogBundle_contact') }}" method="post" >
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
<input type="submit" />
</form>
В то время как, это очень просто для создания прототипов и простых форм, это имеет и свои ограничения, когда необходимы расширенные настройки, что часто бывает с формами.
Для нашей контактной формы, мы выберем золотую середину. Замените код шаблона, расположенный в
src/Blogger/BlogBundle/Resources/views/Page/contact.html.twig
{# src/Blogger/BlogBundle/Resources/views/Page/contact.html.twig #}
{% extends 'BloggerBlogBundle::layout.html.twig' %}
{% block title %}Contact{% endblock%}
{% block body %}
<header>
<h1>Contact symblog</h1>
</header>
<p>Want to contact symblog?</p>
{{ form_start(form, { 'action': path('BloggerBlogBundle_contact'), 'method': 'POST', 'attr': {'class': 'blogger'} }) }}
{{ form_errors(form) }}
{{ form_row(form.name) }}
{{ form_row(form.email) }}
{{ form_row(form.subject) }}
{{ form_row(form.body) }}
{{ form_rest(form) }}
<input type="submit" value="Submit" />
{% endblock %}
Как вы можете видеть, мы используем 4 новых метода Twig для вывода формы.
Первый метод form_start (вид, переменные) выводит тег начала формы. Этот помощник заботится о выводе метода конфигурации и action в форме. Он также будет включать в себя правильное значение ENCTYPE если форма содержит поля загрузки.
Второй метод form_errors будет выводить ошибки формы в том случае, если проверка не удалась.
Третий метод form_row выводит целые элементы, связанные с каждой областью формы. Это включает в себя какие-либо ошибки в поле, label поля и актуальный элемент поля.
Наконец мы используем метод form_rest. Это безопасный вариант, чтобы использовать метод в конце формы, чтобы сделать какие-либо поля которые вы возможно забыли, в том числе скрытые поля и Symfony2 Form CSRF token.
Заметка
Подделка запроса cross-site (CSRF) объясняется подробно в главе Формы книги Symfony2.
Стилизация формы
Давайте добавим некоторые стили, чтобы улучшить вид формы. Так как эти стили являются специфическими в пределах нашего бандла мы создадим стили в новом файле стилей внутри самого бандла. Создайте новый файл
src/Blogger/BlogBundle/Resources/public/css/blog.css
и вставьте стили..blogger-notice { text-align: center; padding: 10px; background: #DFF2BF; border: 1px solid; color: #4F8A10; margin-bottom: 10px; }
form.blogger { font-size: 16px; }
form.blogger div { clear: left; margin-bottom: 10px; }
form.blogger label { float: left; margin-right: 10px; text-align: right; width: 100px; font-weight: bold; vertical-align: top; padding-top: 10px; }
form.blogger input[type="text"],
form.blogger input[type="email"]
{ width: 500px; line-height: 26px; font-size: 20px; min-height: 26px; }
form.blogger textarea { width: 500px; height: 150px; line-height: 26px; font-size: 20px; }
form.blogger input[type="submit"] { margin-left: 110px; width: 508px; line-height: 26px; font-size: 20px; min-height: 26px; }
form.blogger ul li { color: #ff0000; margin-bottom: 5px; }
Нам нужно, чтобы приложение знало, что мы хотим использовать эту таблицу стилей. Мы могли бы подключить таблицы стилей в шаблон страницы Контакты, но так как другие шаблоны будут также использовать эти стили позже, имеет смысл, импортировать стили в layout Blogger BlogBundle который мы создали в первой части. Откройте BloggerBlogBundle layout
src/Blogger/BlogBundle/Resources/views/layout.html.twig
и замените содержание следующим:{# src/Blogger/BlogBundle/Resources/views/layout.html.twig #}
{% extends '::base.html.twig' %}
{% block stylesheets %}
{{ parent() }}
<link href="{{ asset('bundles/bloggerblog/css/blog.css') }}" type="text/css" rel="stylesheet" />
{% endblock %}
{% block sidebar %}
Sidebar content
{% endblock %}
Вы можете видеть, что мы вывели блок стилей для его переопределения, который в свою очередь определен в родительском шаблоне. Важно заметить, что вызывается родительский метод. Это будет подключать файлы стилей, которые определены в
app/Resources/base.html.twig
, и позволяет добавить наш новый файл стилей. Мы не хотим, переопределять уже существующие таблицы стилей.Для того, чтобы функция asset правильно поключала файлы, нам нужно скопировать или связать ресурсы бандла в папке web нашего приложения. Это может быть сделано следующей командой в консоли:
php app/console assets:install web --symlink
Теперь, если вы обновите страницу форма будет выглядеть намного привлекательнее.
![](https://habrastorage.org/files/4cb/837/a92/4cb837a926d148938d1288e190de169b.png)
Давайте изменим маршрут, расположенный
src/Blogger/BlogBundle/Resources/config/routing.yml
для обработки POST запросов.
# src/Blogger/BlogBundle/Resources/config/routing.yml
BloggerBlogBundle_contact:
path: /contact
defaults: { _controller: "BloggerBlogBundle:Page:contact" }
requirements:
methods: GET|POST
Заметка
Теперь, когда вы отправите форму она должна функционировать как, ожидается, однако страница будет просто перенаправлять вас обратно в контактную форму.
Валидаторы
Symfony2 валидатор позволяет нам выполнять проверку данных. Проверка, является распространённой задачей при работе с данными из формы. Проверка данных также должна быть выполнена, прежде чем они будут отправлены в базу данных.
Symfony2 валидатор позволяет отделить нашу логику проверки от компонентов, которые могут использовать его, например, компонента формы или компонента базы данных. Этот подход означает, что мы имеем один набор правил для валидации объекта.
Давайте начнем с обновления сущности Enquiry, расположенной в
src/Blogger/BlogBundle/Entity/Enquiry.php
укажем несколько валидаторов. Убедитесь, что вы добавили 4 новых заявления в верхней части файла.<?php
// src/Blogger/BlogBundle/Entity/Enquiry.php
namespace Blogger\BlogBundle\Entity;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\Length;
class Enquiry
{
public static function loadValidatorMetadata(ClassMetadata $metadata)
{
$metadata->addPropertyConstraint('name', new NotBlank());
$metadata->addPropertyConstraint('email', new Email());
$metadata->addPropertyConstraint('subject', new Length(array(
'max' => 50
)));
$metadata->addPropertyConstraint('body', new Length(array(
'min' => 50
)));
}
//..
Чтобы определить валидаторы, мы должны реализовать статический метод loadValidatorMetadata. Он даст нам объект ClassMetadata. Мы можем использовать этот объект, чтобы установить ограничения на элементы наших сущностей.
Первое заявление NotBlank применяется к элементу name. NotBlank валидатор проверяет не является ли поле пустым.
Далее мы проверяем правильно ли пользователь ввёл свой e-mail. Служба Symfony2 предоставляет валидатор который проверяет правильность заполнения поля e-mail включая проверку домена.
Мы хотим, чтобы поле темы не было пустым и содержало не более 50 символов, а сообщение не менее 50 символов.
Вы можете применить столько валидаторов к одному полю сколько вам необходимо.
Полный список валидаторов предоставляется в справочных документах Symfony2. Также можно создавать и пользовательские валидаторы.
Теперь, при отправке формы, ваши данные будут проходить валидацию. Попробуйте ввести неправильный адрес электронной почты. Вы должны увидеть сообщение об ошибке, информирующее о том, что адрес электронной почты является недействительным. Каждый валидатор выводит сообщение по умолчанию, которое может быть переопределено, если требуется. Например, чтобы изменить сообщения e-mail валидатора вы можете сделать следующее:
$metadata->addPropertyConstraint('email', new Email(array(
'message' => 'symblog does not like invalid emails. Give me a real one!'
)));
Заметка
Если вы используете браузер, который поддерживает HTML5, вам будут выведены сообщения HTML5 определенных ограничений. Это проверка на стороне клиента и Symfony2 установит подходящие ограничения HTML5 на основе метаданных Entity. Вы можете увидеть это на элементе email. Отображение HTML
<input type="email" id="contact_email" name="contact[email]" required="required">
Он использовал один из новых типов полей HTML5, email и поставил требуемый атрибут. Проверка на стороне клиента является большим плюсом потому что она не требует запросов на сервер, чтобы проверить форму. Однако проверка на стороне клиента не должна использоваться в одиночку. Вы всегда должны проверять представленные на сторону сервера данные, так как довольно легко обойти проверку на стороне клиента.
Отправка Email
В то время как наша форма контактов позволяет пользователям отправлять запросы, ничего на самом деле пока не происходит. Давайте обновим контроллер, чтобы отправить письмо веб-мастеру блога. Symfony2 поставляется в комплекте с библиотекой SwiftMailer для отправки электронной почты. Swift Mailer является очень мощной библиотекой, мы только лишь прикоснёмся к тому, что эта библиотека может выполнять.
Конфигурация настроек SwiftMailer
Swift Mailer уже настроен из коробки работать в Symfony2, однако нам нужно настроить некоторые параметры, касающиеся способов отправки и полномочий. Откройте файл параметров, расположенный в
app/config/parameters.yml
и найдите настройки с префиксом mailer_.mailer_transport: smtp
mailer_host: 127.0.0.1
mailer_user: null
mailer_password: null
Swift Mailer предоставляет ряд методов для отправки электронной почты, в том числе с использованием сервера SMTP, используя ‘местную' установку Sendmail, или даже с помощью учетной записи Gmail. Для простоты мы будем использовать учетную запись Gmail. Обновите параметры, подставив свой логин и пароль.
mailer_transport: gmail
mailer_encryption: ssl
mailer_auth_mode: login
mailer_host: smtp.gmail.com
mailer_user: ваш_логин
mailer_password: ваш_пароль
Важно !
Будьте осторожны, если вы используете систему контроля версий (VCS) как Git для вашего проекта, особенно если ваше хранилище общедоступно. Вы должны убедиться, что файл приложения
app/config/parameters.yml
добавлен в список игнорируемых вашего VCS.
Контроллер
Обновите Page контроллер расположенный
src/Blogger/BlogBundle/Controller/PageController.php
скопировав в него следующий код:if ($form->isValid()) {
$message = \Swift_Message::newInstance()
->setSubject('Contact enquiry from symblog')
->setFrom('enquiries@symblog.co.uk')
->setTo('email@email.com')
->setBody($this->renderView('BloggerBlogBundle:Page:contactEmail.txt.twig', array('enquiry' => $enquiry)));
$this->get('mailer')->send($message);
$this->get('session')->getFlashBag()->add('blogger-notice', 'Your contact enquiry was successfully sent. Thank you!');
// Redirect - This is important to prevent users re-posting
// the form if they refresh the page
return $this->redirect($this->generateUrl('BloggerBlogBundle_contact'));
}
Когда вы используете библиотеку SwiftMailer чтобы создать Swift_Message, он может быть отправлен в виде электронной почты.
Заметка
Так как библиотека Swift Mailer не использует пространства имен, мы должны поставить префикс перед классом Swift Mailer \. Это говорит PHP, вернуться обратно в глобальное пространство. Вам нужно будет добавить префикс всем классам и функциям, которые не имеют пространство имен с \. Если вы не разместите этот префикс перед классом Swift_Message PHP будет виден для класса в текущем пространстве имен, которое в этом примере является Blogger\BlogBundle\Controller, в результате чего будет выведена ошибка.
Мы также установили flash сообщение в сессии. Flash сообщения представляют собой сообщения, которые сохраняются в течение одного запроса. После этого они автоматически очищаются из Symfony2. Сообщение flash будет показано в шаблоне контакта, чтобы сообщить пользователю что запрос был отправлен. Так как flash сообщение сохраняется только в течение одного запроса, оно идеально подходит для уведомления пользователя об успехе предыдущих действий.
Для отображения flash сообщения нам необходимо обновить шаблон контактов, расположенный
src/Blogger/BlogBundle/Resources/views/Page/contact.html.twig
обновите содержание шаблона://..
<header>
<h1>Contact symblog</h1>
</header>
{% for flashMessage in app.session.flashbag.get('blogger-notice') %}
<div class="blogger-notice">
{{ flashMessage }}
</div>
{% endfor %}
<p>Want to contact symblog?</p>
//..
Этот код проверяет, является ли flash сообщение с идентификатором blogger-notice установленным и выведено.
Регистрация email’а веб-мастера
Symfony2 предоставляет систему конфигурации, которую мы можем использовать, чтобы определить наши собственные настройки. Мы будем использовать эту систему для установки электронной почты веб-мастера, а не жесткого кодирования адреса в контроллере выше. Таким образом, мы можем легко повторно использовать это значение в других местах без дублирования кода. Кроме того, когда ваш блог вызывает столько трафика которого стало слишком много для вас, вы можете легко обновить адрес электронной почты, чтобы передать письма вашему помощнику. Создайте новый файл
src/Blogger/BlogBundle/Resources/config/config.yml
и вставьте следующее:parameters:
# Blogger contact email address
blogger_blog.emails.contact_email: contact@email.com
При определении параметров хорошей практикой является разделение имен параметров на количество компонентов. Первая часть должна быть в нижнем регистре и использовать нижнее подчеркивание для разделения слов. В нашем примере мы превратили бандл BloggerBlogBundle в blogger_blog… Оставшаяся часть имени параметра может содержать любое количество частей разделенных. (Точкой). Это позволяет логически группировать параметры.
Для того, чтобы приложение Symfony2 использовало новые параметры, мы должны импортировать конфигурацию в главный файл конфигурации приложения,
app/config/config.yml
для этого, добавьте следующее:# app/config/config.yml
imports:
# .. existing import here
- { resource: "@BloggerBlogBundle/Resources/config/config.yml"}
Путь импорта – это физическое расположение файла на диске.
Наконец давайте обновим функцию contactAction для использования параметра.
// src/Blogger/BlogBundle/Controller/PageController.php
public function contactAction(Request $request)
{
$enquiry = new Enquiry();
$form = $this->createForm(EnquiryType::class, $enquiry);
if ($request->isMethod($request::METHOD_POST)) {
$form->handleRequest($request);
if ($form->isValid()) {
$message = \Swift_Message::newInstance()
->setSubject('Contact enquiry from symblog')
->setFrom('enquiries@symblog.co.uk')
->setTo($this->container->getParameter('blogger_blog.emails.contact_email'))
->setBody($this->renderView('BloggerBlogBundle:Page:contactEmail.txt.twig', array('enquiry' => $enquiry)));
$this->get('mailer')->send($message);
$this->get('session')->getFlashBag()->add('blogger-notice', 'Your contact enquiry was successfully sent. Thank you!');
// Redirect - This is important to prevent users re-posting
// the form if they refresh the page
return $this->redirect($this->generateUrl('BloggerBlogBundle_contact'));
}
}
return $this->render('BloggerBlogBundle:Page:contact.html.twig', array(
'form' => $form->createView()
));
}
Совет
Так как конфигурационный файл импортируется в верхнюю часть файла конфигурации приложения мы можем легко переопределить любой из импортируемых параметров в приложении. Например, добавив следующую строку в нижнюю частьapp/config/config.yml
будет переопределено значение параметра.
# app/config/config.yml parameters: # Blogger contact email address blogger_blog.emails.contact_email: assistant@email.com
Создание шаблона e-mail
Тело нашего email, выводит шаблон. Создайте этот шаблон в
src/Blogger/BlogBundle/Resources/views/Page/contactEmail.txt.twig
и добавьте следующее:
{# src/Blogger/BlogBundle/Resources/views/Page/contactEmail.txt.twig #}
A contact enquiry was made by {{ enquiry.name }} at {{ "now" | date("Y-m-d H:i") }}.
Reply-To: {{ enquiry.email }}
Subject: {{ enquiry.subject }}
Body:
{{ enquiry.body }}
Вы может так же заметили, что расширение этого шаблона отличается от других шаблонов, которые мы создали. Он использует расширение .txt.twig. Первой частью расширения, .txt определяется формат файла для генерации. Общие форматы включают, .txt, .html, .css, .js, XML и .json. В последней части расширения определяет, какой движок шаблона использовать, в данном случае Twig. Расширение .php использовало бы PHP для отображения шаблона.
Теперь, когда Вы отправили запрос письмо будет отправлено на адрес, указанный в параметре blogger_blog.emails.contact_email.
Совет
Symfony2 позволяет настроить поведение библиотеки SwiftMailer при работе в различных средах Symfony2. Мы уже видим это в использовании для тестовой среды. По умолчанию, Symfony 2 настраивает SwiftMailer не посылать электронную почту, когда работает в тестовой среде. Это устанавливается в конфигурационном файлеapp/config/config_test.yml
swiftmailer: disable_delivery: true
Это может быть полезно, чтобы продублировать эту функциональность для среды Dev. В конце концов, вы наверняка не хотите, случайно отправить письмо по неправильному адресу при разработке. Для достижения этой цели, добавьте вышеуказанную конфигурацию в файл конфигурации Dev, расположенногоapp/config/config_dev.yml
Вы будете удивлены, как вы можете проверить, что письма были отправлены. Symfony2 имеет решение для этого с помощью панели инструментов разработчика. Когда письмо будет отправлено значок-уведомление электронной почты появится в панели инструментов, который имеет всю информацию о письме.
Если вы выполняете перенаправление после отправки электронной почты, как мы делаем для контактной формы, вам нужно будет установить intercept_redirects настройки
app/config/config_dev.yml
в значение true для того, чтобы увидеть уведомление электронной почты на панели инструментов.![](https://habrastorage.org/files/65f/11b/37e/65f11b37e56c46faa51b842a78417cee.jpg)
Мы могли бы настроить SwiftMailer для отправки всех писем на определенный адрес электронной почты в среде Dev, поместив следующий параметр в конфигурационном файле Dev, расположенного
app/config/config_dev.yml
swiftmailer:
delivery_address: development@symblog.dev
Вывод
Мы продемонстрировали концепции, для создания одной из самых фундаментальных частей любого веб-сайта: формы.
Далее мы рассмотрим большую часть этого руководства, Модель. Расскажем о Doctrine 2 и используем его для определения blog Model. А также исследуем концепцию Data fixtures.
Источники и вспомогательные материалы:
https://symfony.com/
http://tutorial.symblog.co.uk/
http://twig.sensiolabs.org/
http://www.doctrine-project.org/
https://getcomposer.org/
Post Scriptum
Всем спасибо за внимание и замечания сделанные по проекту, если у вас возникли сложности или вопросы, отписывайтесь в комментарии или личные сообщения, добавляйтесь в друзья.
Часть 1 — Конфигурация Symfony2 и шаблонов
Часть 3 — Doctrine 2 и Фикстуры данных
Часть 4 — Модель комментариев, Репозиторий и Миграции Doctrine 2
Часть 5 — Twig расширения, Боковая панель(sidebar) и Assetic
Часть 6 — Модульное и Функциональное тестирование
Также, если Вам понравилось руководство вы можете поставить звезду репозиторию проекта или подписаться. Спасибо.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Пожалуйста, оцените качество руководства
61.63% Отлично53
20.93% Очень хорошо18
16.28% Хорошо14
0% Плохо0
1.16% Очень плохо1
Проголосовали 86 пользователей. Воздержались 10 пользователей.