Sirius Sirius - 29 days ago 6
PHP Question

Allow user to vote only once for a comment [symfony2]

I have a table

vote
and
comment
I would to allow a user to vote only once for a
comment_id
. For now a user can vote multiple times for a comment.

I would like before to persist user in the table vote to verified if the current user_id has already voted for a specify
comment_id
, if yes the vote will not be persist.

Controller.php

public function voteAction($id)
{
$em = $this->getDoctrine()->getEntityManager();
$comment = $em->getRepository('ApplicationSonataUserBundle:Comment')->findOneBy(array('id' => $id));
$entity = new Vote();
$entity->setUser($this->get('security.token_storage')->getToken()->getUser());
$entity->setVotecomment($comment);
$entity->setCreatedAt(new \DateTime());
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('userShow', array(
'entity' => $entity->getVotecomment()->getRecipient(),
'slug' => $entity->getVotecomment()->getRecipient()->getId(),
)));
}


.

vote.php

<?php

namespace Application\Sonata\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;

/**
* @ORM\HasLifecycleCallbacks
* @ORM\Entity
* @ORM\Entity(repositoryClass="Application\Sonata\UserBundle\Entity\UserRepository")
* @ORM\Table(name="vote")
*
*/

class Vote
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;


/**
* @var User
* @ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User", inversedBy="likes")
*/
protected $user;

/**
* @var int
*
* @ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\Comment", inversedBy="votes", cascade={"persist"})
* @ORM\JoinColumn(name="votecomment_id", referencedColumnName="id")
*
*/
private $votecomment;

/**
* @ORM\Column(name="createdAt", type="datetime", nullable=false)
*/
protected $createdAt;


public function __construct()
{
$this->setCreatedAt(new \DateTime());

$this->votecomment = new ArrayCollection();
}

}


.

twig file

<a class="fa fa-thumbs-o-up" href="{{ path('likecomment', {'entity': entity ,'slug': entity.recipient.id ,'id': entity.id}) }}"></a><b class="text-color">&nbsp; &nbsp;{{ entity.votes|length }}</b>

Answer

Basically I needed just to check if the current user has already voted for a comment.

Below an example of how I did it :

   public function voteAction(Request $request,$id)
    {
        $em = $this->getDoctrine()->getEntityManager();


        $comment = $em->getRepository('ApplicationSonataUserBundle:Comment')->findOneBy(array('id' => $id));
        $voteExist = $em->getRepository('ApplicationSonataUserBundle:Vote')->findOneBy([
            'user' => $this->getUser(),
            'votecomment' => $comment
        ]);
        $vote = new Vote();
        if(!$voteExist) {

            $vote->setUser($this->get('security.token_storage')->getToken()->getUser());
            $vote->setVotecomment($comment);
            $vote->setCreatedAt(new \DateTime());
            $em->persist($vote);
            $em->flush();

            return $this->redirect($this->generateUrl('userShow', array(
                'entity' => $vote->getVotecomment()->getRecipient(),
                'slug' => $vote->getVotecomment()->getRecipient()->getId(),
            )));



        } else {

            $em->remove($voteExist);
            $em->flush();
            //$this->get('session')->getFlashBag()->add('notice', 'You have already voted!');

        }

        return $this->redirect($this->generateUrl('userShow', array(
            'entity' => $comment->getRecipient(),
            'slug' => $comment->getRecipient()->getId(),
        )));

    }
Comments