A free and open-source book on ZF3 for beginners


12.10. Editing Existing Post

In this section, we will implement the Edit Post page which contains the form allowing to edit the data of existing post, send new data to server and apply changes to database. Site visitor will be able to see the page by entering the following URL in browser's navigation bar: http://localhost/posts/edit/<id>, where <id> is the unique identifier of the post.

To implement this page we need the following things:

12.10.1. Modifying PostManager

First, we add the updatePost() and convertTagsToString() methods to the PostManager service model as follows:

<?php
//...
class PostManager
{
    //...
	
    // This method allows to update data of a single post.
    public function updatePost($post, $data) 
    {
        $post->setTitle($data['title']);
        $post->setContent($data['content']);
        $post->setStatus($data['status']);
        
        // Add tags to post
        $this->addTagsToPost($data['tags'], $post);
        
        // Apply changes to database.
        $this->entityManager->flush();
    }
        
    // Converts tags of the given post to comma separated list (string).
    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;
    }    
}

Above, we have the updatePost() method (lines 8-19) that takes an existing Post entity, the new title, content, status and the list of tags. It then updates entity's properties and saves changes to database using flush() method.

Note that the updatePost() method doesn't use the persist() method of entity manager, because here we have existing post, not a new one.

Then, we have the convertTagsToString() method (lines 22-36) which takes the post, goes through Tag entities associated with the post and formats and returns the comma-separated list of tags.

12.10.2. Adding Controller Action and View Template

Next, add the editAction() to PostController controller class as follows:

<?php
namespace Application\Controller;
//...
use Application\Form\PostForm;
use Application\Entity\Post;

class PostController extends AbstractActionController 
{
  // This action displays the page allowing to edit a post.
  public function editAction() 
  {
    // Create the form.
    $form = new PostForm();
    
    // Get post ID.    
    $postId = $this->params()->fromRoute('id', -1);
    
    // Find existing post in the database.    
    $post = $this->entityManager->getRepository(Post::class)
                ->findOneById($postId);        
    if ($post == null) {
      $this->getResponse()->setStatusCode(404);
      return;                        
    } 
        
    // Check whether this post is a POST request.
    if ($this->getRequest()->isPost()) {
            
      // Get POST data.
      $data = $this->params()->fromPost();
            
      // Fill form with data.
      $form->setData($data);
      if ($form->isValid()) {
                                
        // Get validated form data.
        $data = $form->getData();
                
        // Use post manager service to add new post to database.                
        $this->postManager->updatePost($post, $data);
                
        // Redirect the user to "admin" page.
        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);
    }
        
    // Render the view template.
    return new ViewModel([
            'form' => $form,
            'post' => $post
        ]);  
  }
}

In the code above, we extract the post ID using the fromRoute() method of the params() controller plugin. Then we search for post having such ID using the findOneBy() method provided by the entity repository.

Then we check if this is a POST request. If this is the POST request, we fill in and validate the form with POST data. Then we use the updatePost() method of the PostManager service.

Finally, create the application/post/edit.phtml file under the module's view directory. Place the following content there:

<?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>   

Now, if you open the URL http://localhost/posts/edit/<id> in your web browser, you should be able to see the Edit Post page that allows to edit an existing post (see the figure 12.8 below):

Figure 12.8. Edit Post page Figure 12.8. Edit Post page

Clicking the Save button results in saving the changes to database.


Top