A free and open-source book on ZF3 for beginners


12.10. Изменение существующего поста

В этом разделе мы реализуем страницу Edit Post, которая будет содержать форму, позволяющую изменять данные существующего поста, отправлять новые данные на сервер и применять изменения к базе данных. Посетитель сайта сможет перейти на эту страницу, набрав в адресной строке своего браузера URL http://localhost/posts/edit/<id>, где <id> - уникальный идентификатор поста.

Для реализации этой страницы нам надо сделать следующее:

12.10.1. Изменение PostManager

Сперва добавим методы 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, связанных с этим постом, а затем форматирует и возвращает список тегов, разделенных запятыми.

12.10.2. Добавление действия контроллера и шаблона представления

Далее, добавьте действие 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 ниже):

Рисунок 12.8. Страница Edit Post Рисунок 12.8. Страница Edit Post

Нажав кнопку Save, вы сохраните изменения в базе данных.


Top