В этом разделе мы реализуем страницу Edit Post, которая будет содержать форму, позволяющую изменять данные существующего поста, отправлять новые данные на сервер и применять изменения к базе данных. Посетитель сайта сможет перейти на эту страницу, набрав в адресной строке своего браузера URL http://localhost/posts/edit/<id>, где <id> - уникальный идентификатор поста.
Для реализации этой страницы нам надо сделать следующее:
PostForm
, созданную ранее (мы просто переименуем
надпись кнопки Create в Save).updatePost()
к сервису PostManager
. Этот метод будет находить пост
по его ID в базе данных и обновлять его данные;convertTagsToString()
к сервису PostManager
. Этот метод будет принимать
сущность поста и возвращать строку, содержащую список разделенных запятыми тегов;PostController::editAction()
, который будет принимать введенные
пользователем данные, передавать их моделям и возвращать данные для визуализации;Сперва добавим методы updatePost()
и convertTagsToString()
к модели сервиса PostManager
следующим образом:
<?php
//...
class PostManager
{
//...
// Этот метод позволяет обновлять данные одного поста.
public function updatePost($post, $data)
{
$post->setTitle($data['title']);
$post->setContent($data['content']);
$post->setStatus($data['status']);
// Добавляем теги к посту.
$this->addTagsToPost($data['tags'], $post);
// Применяем изменения к базе данных.
$this->entityManager->flush();
}
// Преобразовывает теги заданного поста в разделенный запятыми список (строку).
public function convertTagsToString($post)
{
$tags = $post->getTags();
$tagCount = count($tags);
$tagsStr = '';
$i = 0;
foreach ($tags as $tag) {
$i ++;
$tagsStr .= $tag->getName();
if ($i < $tagCount)
$tagsStr .= ', ';
}
return $tagsStr;
}
}
Метод updatePost()
во фрагменте выше (строки 8-19) принимает уже имеющуюся сущность Post
, новые заголовок,
содержимое, статус и список тегов. Затем этот метод обновляет свойства сущности и сохраняет
изменения в базе данных, используя метод flush()
.
Обратите внимание, метод
updatePost()
не использует метод менеджера сущностейpersist()
, потому что в данном случае сущность не новая, а уже существующая.
Затем, в строках 22-36, находится метод convertTagsToString()
, который принимает пост, проходит
по сущностям Tag
, связанных с этим постом, а затем форматирует и возвращает список тегов, разделенных
запятыми.
Далее, добавьте действие editAction
к классу контроллера PostController
как показано ниже:
<?php
namespace Application\Controller;
//...
use Application\Form\PostForm;
use Application\Entity\Post;
class PostController extends AbstractActionController
{
// Это действие отображает страницу, позволяющую отредактировать пост.
public function editAction()
{
// Создаем форму.
$form = new PostForm();
// Получаем ID поста.
$postId = $this->params()->fromRoute('id', -1);
// Находим существующий пост в базе данных.
$post = $this->entityManager->getRepository(Post::class)
->findOneById($postId);
if ($post == null) {
$this->getResponse()->setStatusCode(404);
return;
}
// Проверяем, является ли пост POST-запросом.
if ($this->getRequest()->isPost()) {
// Получаем POST-данные.
$data = $this->params()->fromPost();
// Заполняем форму данными.
$form->setData($data);
if ($form->isValid()) {
// Получаем валидированные данные формы.
$data = $form->getData();
// Используем менеджер постов, чтобы добавить новый пост в базу данных.
$this->postManager->updatePost($post, $data);
// Перенаправляем пользователя на страницу "admin".
return $this->redirect()->toRoute('posts', ['action'=>'admin']);
}
} else {
$data = [
'title' => $post->getTitle(),
'content' => $post->getContent(),
'tags' => $this->postManager->convertTagsToString($post),
'status' => $post->getStatus()
];
$form->setData($data);
}
// Визуализируем шаблон представления.
return new ViewModel([
'form' => $form,
'post' => $post
]);
}
}
В куске кода выше мы извлекаем ID поста с помощью метода fromRoute()
плагина контроллера
params()
Затем мы ищем пост с этим ID, используя метод findOneBy()
, предоставляемый
репозиторием сущности.
После этого мы проверяем, является ли пост POST-запросом. Если это так, заполняем
форму POST-данными и валидируем ее. Затем мы используем метод updatePost()
сервиса
PostManager
.
Наконец, создайте файл application/post/edit.phtml под каталогом модуля view. Поместите в него следующее содержимое:
<?php
$form = $this->form;
$form->get('title')->setAttributes([
'class'=>'form-control',
'placeholder'=>'Enter post title here'
]);
$form->get('content')->setAttributes([
'class'=>'form-control',
'placeholder'=>'Type content here',
'rows'=>6
]);
$form->get('tags')->setAttributes([
'class'=>'form-control',
'placeholder'=>'comma, separated, list, of, tags'
]);
$form->get('status')->setAttributes([
'class'=>'form-control'
]);
$form->get('submit')->setAttributes(['class'=>'btn btn-primary']);
$form->get('submit')->setValue('Save');
$form->prepare();
?>
<h1>Edit Post</h1>
<p>
Please fill out the following form and click the *Save* button.
</p>
<div class="row">
<div class="col-md-6">
<?= $this->form()->openTag($form); ?>
<div class="form-group">
<?= $this->formLabel($form->get('title')); ?>
<?= $this->formElement($form->get('title')); ?>
<?= $this->formElementErrors($form->get('title')); ?>
</div>
<div class="form-group">
<?= $this->formLabel($form->get('content')); ?>
<?= $this->formElement($form->get('content')); ?>
<?= $this->formElementErrors($form->get('content')); ?>
</div>
<div class="form-group">
<?= $this->formLabel($form->get('tags')); ?>
<?= $this->formElement($form->get('tags')); ?>
<?= $this->formElementErrors($form->get('tags')); ?>
<p class="help-block">Separate tags with comma.</p>
</div>
<div class="form-group">
<?= $this->formLabel($form->get('status')); ?>
<?= $this->formElement($form->get('status')); ?>
<?= $this->formElementErrors($form->get('status')); ?>
</div>
<?= $this->formElement($form->get('submit')); ?>
<?= $this->form()->closeTag(); ?>
</div>
</div>
Если вы теперь откроете в своем браузере URL http://localhost/posts/edit/<id>, вы должны будете увидеть страницу Edit Post, которая позволяет редактировать имеющиеся посты (см. рисунок 12.8 ниже):
Нажав кнопку Save, вы сохраните изменения в базе данных.