Symfony2,博客文章,评论由匿名/用户分隔(表单构建和评论列表)

时间:2013-10-17 14:31:24

标签: php symfony

我成功地为我的博客创建了工作包,包括管理文章,但我坚持使用评论。我想用户和匿名用户分开评论。如果用户被登录,那么他将不会看到作者的字段,他将看不到验证码。 我认为,我可以通过表单构建器中的一个 if 来解决这个问题(如果用户已完全通过身份验证),然后在我的TWIG模板中。但是,这是一个很好的解决方案吗? 有没有更简单的方法? 所以我的 Comment.php 将具有以下形式:

<?php

namespace Acme\BlogBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @ORM\Table(name="comments") 
 */
class Comment
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;              

    /**
     * @ORM\Column(type="string", length=200)    
     * @Assert\NotBlank(
     *      message = "Name cannot be blank"      
     * )    
     * @Assert\Length(
     *      min = "3",
     *      minMessage = "Name is too short"         
     * )     
     */     
    private $author;

    /**
     * @ORM\ManyToOne(targetEntity="\Acme\UserBundle\Entity\User")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")       
     */
    private $user_id;

    /**
     * @ORM\Column(type="string", length=200)
     * @Assert\NotBlank(
     *      message = "E-mail cannot be blank"      
     * )    
     * @Assert\Length(
     *      min = "3",
     *      minMessage = "E-mail is too short"         
     * )
     */
    private $email;              

    /**
     * @ORM\Column(type="text")
     * @Assert\NotBlank(
     *      message = "Message cannot be blank"
     * )     
     * @Assert\Length(
     *      min = "3",
     *      minMessage = "Message is too short"         
     * )     
     */
    private $content;

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

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

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

        return $this;
    }

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

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

        return $this;
    }

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

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

        return $this;
    }

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

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

        return $this;
    }

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

    /**
     * Set user_id
     *
     * @param \Acme\UserBundle\Entity\User $userId
     * @return Comment
     */
    public function setUserId(\Acme\UserBundle\Entity\User $userId = null)
    {
        $this->user_id = $userId;

        return $this;
    }

    /**
     * Get user_id
     *
     * @return \Acme\UserBundle\Entity\User 
     */
    public function getUserId()
    {
        return $this->user_id;
    }

这是我的第一个问题,然后是我看到显示评论的第二个问题(而不是作者姓名)。我不确定如何在我的Controller中的$comments属性中创建新值(如果属性user_id 不是NULL ,则从用户对象加载有关此ID的此用户的信息,如果为NULL ,则使用author属性。如果是User的评论,则作者姓名将带下划线。此外,它适用于我的控制器,或者我可以在我的TWIG模板中执行此操作?

我的问题简短:

  • 哪个是显示“编写您的评论”表单构建的最佳方法,其中包含已记录和未记录的用户(最有效,不确定在我的表单构建器和我的TWIG中使用if模板)
  • 如何通过匿名/注册用户分隔评论,如果是注册用户的评论,他的名字将加下划线

2 个答案:

答案 0 :(得分:0)

我希望您使用 FormBuilder 来创建表单。

添加到您的 CommentType 构造函数新参数,例如 $ user

private $user;

public function __construct($user) {
    $this->user = $user;
}

public function buildForm(FormBuilderInterface $builder, array $options) {
    if(!is_null($this->user)) {
        $builder->add(); ...
    }
}

在您的控制器中:

$user = null;
$securityContext = $this->container->get('security.context');
if( $securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED') ){
    // authenticated REMEMBERED, FULLY will imply REMEMBERED (NON anonymous)
    $user = $this->user();
}

$form = $this->createForm(new CommentType($user), $comment);

第二个问题:

你应该只检查user_id是否为null,非null时 - > undeline,为null - &gt;不是未定期。

答案 1 :(得分:0)

所以我使用了@Dawid Sajdak的答案并尝试将其放入我的代码中。首先,我编辑了我的 Comment.php 实体,在那里我添加了验证组:

<?php

namespace Acme\BlogBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass="Acme\BlogBundle\Entity\CommentRepository")
 * @ORM\Table(name="comments") 
 */
class Comment
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;              

    /**
     * @ORM\Column(type="string", length=200, nullable=true)    
     * @Assert\NotBlank(
     *      message = "Name cannot be blank",
     *      groups = {"not_logged"}           
     * )    
     * @Assert\Length(
     *      min = "3",
     *      minMessage = "Name is too short",
     *      groups = {"not_logged"}              
     * )     
     */     
    private $author;

    /**
     * @ORM\ManyToOne(targetEntity="\Acme\UserBundle\Entity\User")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")       
     */
    private $user_id;

    /**
     * @ORM\Column(type="string", length=200, nullable=true)
     * @Assert\NotBlank(
     *      message = "E-mail cannot be blank",
     *      groups = {"not_logged"}           
     * )    
     * @Assert\Email(
     *      message = "E-mail is not valid",
     *      groups = {"not_logged"}     
     * )     
     */
    private $email;

    /**
     * @ORM\Column(type="datetime")   
     */
    protected $published;              

    /**
     * @ORM\Column(type="text")
     * @Assert\NotBlank(
     *      message = "Message cannot be blank"
     * )     
     * @Assert\Length(
     *      min = "3",
     *      minMessage = "Message is too short"         
     * )     
     */
    private $content;

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

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

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

        return $this;
    }

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

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

        return $this;
    }

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

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

        return $this;
    }

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

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

        return $this;
    }

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

    /**
     * Set user_id
     *
     * @param \Acme\UserBundle\Entity\User $userId
     * @return Comment
     */
    public function setUserId(\Acme\UserBundle\Entity\User $userId = null)
    {
        $this->user_id = $userId;

        return $this;
    }

    /**
     * Get user_id
     *
     * @return \Acme\UserBundle\Entity\User 
     */
    public function getUserId()
    {
        return $this->user_id;
    }

    /**
     * Set published
     *
     * @param \DateTime $published
     * @return Comment
     */
    public function setPublished($published)
    {
        $this->published = $published;

        return $this;
    }

    /**
     * Get published
     *
     * @return \DateTime 
     */
    public function getPublished()
    {
        return $this->published;
    }
}

我使用过验证组,因为没有它们,如果您是管理员,则不会看到“姓名和电子邮件”字段,在提交表单后,您将收到错误消息:“名称不能为空”< / strong> ...

下一步是创建一个新的 CommentType.php

<?php

namespace Acme\BlogBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class CommentType extends AbstractType
{
    private $user;

    public function __construct($user) {
        $this->user = $user;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Acme\BlogBundle\Entity\Comment',
            'csrf_protection' => true,
        ));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        if(is_null($this->user)) {
            $builder->add('author', 'text', array('label' => 'Author', 'validation_groups' => array('not_logged')))
                    ->add('email', 'text', array('label' => 'E-mail (will not show)', 'validation_groups' => array('not_logged')));
        }        
            $builder->add('content', 'textarea', array('label' => 'Text',))
                    ->add('save', 'submit', array('label' => 'Submit'));
    }

    public function getName()
    {
        return 'comment';
    }
}

然后有一个 DefaultController.php ,我添加了一些逻辑问题,如果用户是否被记录:

public function showAction($slug, Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $article = $em->getRepository('AcmeBlogBundle:Article')->findOneBySlug($slug);

    if(!$article)
    {
        throw $this->createNotFoundException('This article does not exists');
    }

    $user = null;
    if(true === $this->get('security.context')->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
        $user = $this->getUser();  // get $user object
    }

    $comment = new Comment();
    $comment->setArticle($article);

    $form = $this->createForm(new CommentType($user), $comment);
    $form->handleRequest($request);

    if($form->isValid())
    {
        $comment->setPublished(new \DateTime('now')); // don't forget to set publish date

        if($user) {
            $comment->setUserId($user); // set User_id
        }

        $em = $this->getDoctrine()->getManager();
        $em->persist($comment);
        try {
            $em->flush();
        } catch (\PDOException $e) {
            // sth
        }
        $this->get('session')->getFlashBag()->add(
            'success',
            'Your comment was succesfully added'
        );
        return $this->redirect($this->generateUrl('default_blog_show', array('slug' => $slug)).'#comments'); // redirect  
    }

    return $this->render('AcmeBlogBundle:Default:show.html.twig', array('article' => $article, 'form' => $form->createView()));
}

现在,我们需要准备 show.html.twig 来显示我们的评论和表单以获得新评论:

{% for comment in article.comments %}
  <div style="border: 1px solid black; margin: 10px 0; padding: 5px;">
      <div style="border-bottom: 1px solid black;">
          {% if app.user %}{% if comment.userId is null %}{{ comment.email }}{% else %}{{ comment.userId.email }}{% endif %}{% endif %}<p>Written by: {% if comment.userId is null %}{{ comment.author }}{% else %}<strong>{{ comment.userId.username }}</strong>{% endif %} at {{ comment.published|date('d.n.Y H:i:s') }}</p>
      </div>
      <p>{{ comment.content }}</p>
  </div>
{% else %}
<h2>No comments, be first!</h2>
{% endfor %}
<hr />
<fieldset style="padding: 10px; margin: 10px; border: 1px solid black;">
    <legend style="background-color: skyblue; padding: 5px;">New comment</legend>
{{ form(form) }}
</fieldset>

它已经完成了。最后,如果要按发布日期ASC对注释进行排序,则必须在$comments属性上添加注释到 Article.php 实体:

/**
 * @ORM\OneToMany(targetEntity="Comment", mappedBy="article")
 * @ORM\OrderBy({"published" = "ASC"})     
 */
private $comments;