2017-02-24 40 views
0

私は、ユーザー、コメント、記事の3つのエンティティを持っています。ユーザーはコメント/記事を作成できます。埋め込みフォームPHP/Symfonyで検証を実行するにはどうすればよいですか?

私の記事コントローラには、コメントフォームを返すと思われるcommentActionというメソッドがあります。私は、このコントローラを記事ショーテンプレートで呼んでいます。それは動作しますが、フォームを検証しようとすると問題が発生します。

ユーザーを記事の表示ページに戻して、コメントフォームのエラーが表示されるようにしたいとします。

2つの問題:フォームには私たちがコメントを取る動作をし、showActionに戻ることはありません。また、何らかの理由で検証エラーが表示されることはありませんでした。

私はフォワーダを組み込んでいました(とにかくうまく動作しないようです)。誰かが私にこれを得る正しい方法を教えてもらえますか?

ありがとうございます!

P.S.私はSymfonで新しくなっていますので、あなたが私に知らせるなら、私がそれを感謝するベストプラクティスに違反しているかどうか私に警告することができます:)。

コメントエンティティ:

<?php 

namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 
use Symfony\Component\Validator\Constraints as Assert; 
/** 
* Comment 
* 
* @ORM\Table(name="comment") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\CommentRepository") 
*/ 
class Comment 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var int $rating 
    * 
    * @ORM\Column(name="rating", type="smallint") 
    * @Assert\NotBlank() 
    */ 
    private $rating; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="title", type="string", length=255) 
    */ 
    private $title; 

    /** 
    * @ORM\ManyToOne(targetEntity="User", inversedBy="comments") 
    * @ORM\JoinColumn(name="user_id", referencedColumnName="id") 
    */ 
    private $user; 

    /** 
    * @ORM\ManyToOne(targetEntity="Article", inversedBy="comments") 
    * @ORM\JoinColumn(name="article_id", referencedColumnName="id") 
    */ 
    private $article; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="comment", type="text", nullable=true) 
    */ 
    private $comment; 


    /** 
    * Get id 
    * 
    * @return int 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set rating 
    * 
    * @param integer $rating 
    * 
    * @return Comment 
    */ 
    public function setRating($rating) 
    { 
     $this->rating = $rating; 

     return $this; 
    } 

    /** 
    * Get rating 
    * 
    * @return int 
    */ 
    public function getRating() 
    { 
     return $this->rating; 
    } 

    /** 
    * Set title 
    * 
    * @param string $title 
    * 
    * @return Comment 
    */ 
    public function setTitle($title) 
    { 
     $this->title = $title; 

     return $this; 
    } 

    /** 
    * Get title 
    * 
    * @return string 
    */ 
    public function getTitle() 
    { 
     return $this->title; 
    } 

    /** 
    * Set userId 
    * 
    * @param integer $userId 
    * 
    * @return Comment 
    */ 
    public function setUserId($userId) 
    { 
     $this->userId = $userId; 

     return $this; 
    } 

    /** 
    * Get userId 
    * 
    * @return int 
    */ 
    public function getUserId() 
    { 
     return $this->userId; 
    } 

    /** 
    * Set comment 
    * 
    * @param string $comment 
    * 
    * @return Comment 
    */ 
    public function setComment($comment) 
    { 
     $this->comment = $comment; 

     return $this; 
    } 

    /** 
    * Get comment 
    * 
    * @return string 
    */ 
    public function getComment() 
    { 
     return $this->comment; 
    } 

    /** 
    * Set user 
    * 
    * @param \AppBundle\Entity\User $user 
    * 
    * @return Comment 
    */ 
    public function setUser(\AppBundle\Entity\User $user = null) 
    { 
     $this->user = $user; 

     return $this; 
    } 

    /** 
    * Get user 
    * 
    * @return \AppBundle\Entity\User 
    */ 
    public function getUser() 
    { 
     return $this->user; 
    } 

    /** 
    * Set article 
    * 
    * @param \AppBundle\Entity\Article $article 
    * 
    * @return Comment 
    */ 
    public function setArticle(\AppBundle\Entity\Article $article = null) 
    { 
     $this->article = $article; 

     return $this; 
    } 

    /** 
    * Get article 
    * 
    * @return \AppBundle\Entity\User 
    */ 
    public function getArticle() 
    { 
     return $this->article; 
    } 
} 

条コントローラ

<?php 

namespace AppBundle\Controller; 

use AppBundle\Entity\Article; 
use AppBundle\Entity\Comment; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Symfony\Component\HttpFoundation\Request; 
use AppBundle\General\HelperClass; 

use AppBundle\Form\CommentType; 
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; 

/** 
* Article controller. 
* 
* @Route("article") 
*/ 
class ArticleController extends Controller 
{ 
    /** 
    * Show all article entities. 
    * 
    * @Route("/", name="article_index") 
    * @Method("GET") 
    */ 
    public function indexAction(Request $request) 
    { 
     return $this->render('article/index.html.twig'); 
    } 

    /** 
    * Lists all article entities, optionally sorted. 
    * 
    * @Route("/list", name="article_list") 
    * @Method("GET") 
    */ 
    public function listAction(Request $request) 
    { 
     //if we're passing a sort_by it'll be an embed in twig template. 
     $sortBy = $request->get('sort_by'); 

     $em = $this->getDoctrine()->getManager(); 

     if('average-rating' === $sortBy){ 
      $sortBy = "avg_rating"; 
      $articles = $em->getRepository('AppBundle:Article')->getArticlesByAverageRating($sortBy); 
     } else { 
      $sortBy = "name"; 
      $articles = $em->getRepository('AppBundle:Article')->getArticlesByAverageRating($sortBy); 
     } 

     return $this->render('article/list.html.twig', array(
      'articles' => $articles, 
     )); 
    } 

    protected function getComment(\AppBundle\Entity\User $user, \AppBundle\Entity\Article $article, \AppBundle\Entity\Comment $comment){ 

     $em = $this->getDoctrine()->getManager(); 
     $userId = $user->getId(); 

     $existingComment = $em->getRepository('AppBundle:Comment')->getCommentByUserIdAndArticleId($user, $article); 

     if($existingComment) { 
      $existingComment->setRating($comment->getRating()); 
      $existingComment->setTitle($comment->getTitle()); 
      $existingComment->setComment($comment->getComment()); 
      $comment = $existingComment; 
     } 

     return $comment; 

    } 

    /** 
    * Creates a new article entity. 
    * 
    * @Route("/new", name="article_new") 
    * @Method({"GET", "POST"}) 
    */ 
    public function newAction(Request $request) 
    { 
     $article = new Article(); 
     $form = $this->createForm('AppBundle\Form\ArticleType', $article); 



     $form->handleRequest($request); 

     if ($form->isSubmitted() && $form->isValid()) { 



      $em = $this->getDoctrine()->getManager(); 
      $user = $this->getUser(); 
      //Set the user 
      $article = $form->getData(); 
      $article->setUser($user); 
      //Set Created Date 
      $date = new \DateTime("now"); 
      $article->setCreatedDate($date); 
      $em->persist($article); 
      $em->flush($article); 




      return $this->redirectToRoute('article_show', array('id' => $article->getId())); 

     } 

     return $this->render('article/new.html.twig', array(
      'article' => $article, 
      'form' => $form->createView(), 
     )); 
    } 

    /** 
    * Finds and displays a article entity. 
    * 
    * @Route("/{id}", name="article_show") 
    * @Method("GET") 
    */ 
    public function showAction(Article $article) 
    { 

     $deleteForm = $this->createDeleteForm($article); 

     return $this->render('article/show.html.twig', array(
      'article' => $article, 
      'delete_form' => $deleteForm->createView(), 
     )); 
    } 

    /** 
    * The comment form for articles 
    * 
    * @Route("/{id}/comment", name="article_comment") 
    * @Method({"GET", "POST"}) 
    */ 
    public function commentAction(Request $request, Article $article) 
    { 
     $comment = new Comment(); 
     //Build the comment form. 

     $commentForm = $this->createFormBuilder($comment) 
      ->add('comment', CommentType::class, array("label" => FALSE)) 
      ->setAction($this->generateUrl('article_comment', array('id' =>$article->getId()))) 
      ->getForm(); 

     $commentForm->handleRequest($request); 

//THIS IS MY FORWARDER BUT I SEEM TO LOSE ALL FORM DATA WHEN I DO THIS SO I DON"T THINK IT"S RIGHT!! 
     if ($commentForm->isSubmitted() && !$commentForm->isValid()) { 
      return $this->forward(
       'AppBundle:Article:show', 
       array(
        'form' => $commentForm->createView(), 
        'article' => $article, 
       ) 
      ); 
     } 

     if ($commentForm->isSubmitted() && $commentForm->isValid()) { 

      //Update existing user or create new 
      $em = $this->getDoctrine()->getManager(); 
      $comment = $commentForm->getData()->getComment(); 
      $user = $this->getUser(); 

      $comment = $this->getComment($user, $article, $comment); 

      //Set the user and article for the comment. 
      $comment->setUser($user); 
      $comment->setArticle($article); 

      $em->persist($comment); 
      $em->flush($comment); 

      $this->getDoctrine()->getManager()->flush(); 
      return $this->redirectToRoute('article_show', array('id' => $article->getId())); 
     } 

     return $this->render('article/comment.html.twig', array(
      'form' => $commentForm->createView(), 
     )); 
    } 

    /** 
    * Displays a form to edit an existing article entity. 
    * 
    * @Route("/{id}/edit", name="article_edit") 
    * @Method({"GET", "POST"}) 
    */ 
    public function editAction(Request $request, Article $article) 
    { 
     $deleteForm = $this->createDeleteForm($article); 
     $editForm = $this->createForm('AppBundle\Form\ArticleType', $article); 
     $editForm->handleRequest($request); 

     if ($editForm->isSubmitted() && $editForm->isValid()) { 
      $this->getDoctrine()->getManager()->flush(); 

      return $this->redirectToRoute('article_edit', array('id' => $article->getId())); 
     } 

     return $this->render('article/edit.html.twig', array(
      'article' => $article, 
      'edit_form' => $editForm->createView(), 
      'delete_form' => $deleteForm->createView(), 
     )); 
    } 

    /** 
    * Deletes a article entity. 
    * 
    * @Route("/{id}", name="article_delete") 
    * @Method("DELETE") 
    */ 
    public function deleteAction(Request $request, Article $article) 
    { 
     $form = $this->createDeleteForm($article); 
     $form->handleRequest($request); 

     if ($form->isSubmitted() && $form->isValid()) { 
      $em = $this->getDoctrine()->getManager(); 
      $em->remove($article); 
      $em->flush($article); 
     } 

     return $this->redirectToRoute('article_index'); 
    } 

    /** 
    * Creates a form to delete a article entity. 
    * 
    * @param Article $article The article entity 
    * 
    * @return \Symfony\Component\Form\Form The form 
    */ 
    private function createDeleteForm(Article $article) 
    { 
     return $this->createFormBuilder() 
      ->setAction($this->generateUrl('article_delete', array('id' => $article->getId()))) 
      ->setMethod('DELETE') 
      ->getForm() 
     ; 
    } 
} 

ショー条小枝

{% extends 'base.html.twig' %} 
{% block body_id 'articlepage' %} 
{% block body %} 

<h1>Article: {{ article.name }}</h1> 

<div class="well"><div class="media"> 
    <div class="media-left media-top"> 
     <img class="media-object" src="{{ article.thumbnail }}"> 
    </div> 
    <div class="media-body"> 

     <h4 class="media-heading">{{ article.name }}</h4> 
     <p>{{ article.description }}</p> 
    </div> 
</div></div> 

{{ render(controller('AppBundle:Comment:index', {'article_id': article.id})) }} 

{% if is_granted('ROLE_USER') -%} 
    <h2>Submit a new comment:</h2> 
    {{ render(controller('AppBundle:Article:comment', {'id': article.id})) }} 
{% else %} 
    <h3>Log In To Leave A Comment!</h3> 
    <p>Click <a href="{{ path('fos_user_security_login') }}">here</a> to log in or <a href="{{ path('fos_user_registration_register') }}">here</a> to register</p> 
{% endif %} 

{% endblock %} 

コメント条小枝

{% extends 'base.html.twig' %} 
{% form_theme form 'form/fields.html.twig' %} 

{% block body %} 
    {{ form_start(form) }}{{ form_errors(form.comment.comment) }}{{form_errors(form.comment.title) }} 
    <div class="form-group">{{ form_row(form.comment.title) }}</div> 
    <div class="form-group">{{ form_row(form.comment.rating) }}</div> 
    <div class="form-group">{{ form_row(form.comment.comment) }}</div> 
    <input class="btn btn-default" type="submit" value="Create" /> 
    {{ form_end(form) }} 
{% endblock %} 

答えて

0

であなたのshowアクション入れて - あなたが現在それを持っているように、あなたのcreateFormBuilderの代わりに、あなたのコメントのアクションで> SetActionは()を。

->setAction($this->generateUrl('article_show', array('id' =>$article->getId()))) 

代わりに、表示アクションでフォームの解析を処理する必要があります。エラーバブリングを使用して、ページ上部のすべてのエラーを表示することをおすすめします。あなたのcreateFormBuilderではちょうどあなたのアドオンを変更します。

>add('comment', CommentType::class, array("label" => false, 'error_bubbling' => true)) 

その後、このフォーム上のあなたの小枝の場所に:

{% if form_errors(form)|length > 10 %} 
    <div class="col-md-10 col-md-offset-1"> 
     <div class="alert alert-danger fade-in"> 
      {{ form_errors(form) }} 
     </div> 
    </div> 
{% endif %} 
0

私はあなたが記事に多くのコメントを追加することができますと仮定します。次に、これらのエンティティの間にのの一対多の関係があります。これは、注釈を使用するエンティティの宣言で定義する必要があります。詳細については、この記事を参照してください。http://symfony.com/doc/current/doctrine/associations.html

この定義では、エンティティコメント用に別のフォームタイプを作成できます。エンティティアーティクルのフォームタイプでは、項目「コメント」をコレクションタイプと定義します。 symfonyはエンティティコメントにフォームタイプを使用して、エンティティ記事のフィールドコメントを表示します。詳細については、この記事を参照してください。https://symfony.com/doc/current/form/form_collections.html

関連する問題