I have entities Travel , Favorite and User , each user can add a travel to his list of favorites.
When display list of all travels, I'd like that if travel is already in lis of user favorites so show button (remove) and if is not in list, so show (add to favorite).
In the action controller I have done a queryBuilder to get list of all favorites of current authenticated user and I put the result in ($favorite).
public function listAction($page, Request $request)
{
$em = $this->getDoctrine()->getManager();
// code of boutton add to or remove from favorite
$user = $this->getUser(); // this is a function to verify if user is AUTHENTICATED_REMEMBERED
if($user) {
$favorite = $em->getRepository('ProjectTravelBundle:Favorite')->getFavoriteByUser($user);
}
else{
$favorite = '';
}
$paginator = $this->get('knp_paginator');
$qb = $em->getRepository('ProjectTravelBundle:Travel')->getListTravelsFrontend();
$nb = $qb->getQuery()->getResult();
$pagination = $paginator->paginate(
$qb,
$request->query->get('page', $page),10);
return $this->render('ProjectFrontendBundle:Travel:travel-list-view.html.twig',array(
'pagination' => $pagination,
'nb' => $nb,
'favorite' =>$favorite, // list of favorites of current user
));
}
The solution that I think about is to test if travel is in array(favorite) so show boutton remove and if not, then show boutton add , but I failed to do this in the show.twig
{% for travel in pagination %}
//..................
{% if is_granted('IS_AUTHENTICATED_REMEMBERED') %}
{% if travel.id not in favorite %}
<span><a href="{{ path('frontend_travel_add_favorite', {'id': travel.id} ) }}" class="pull-right button btn-small red">Add to favorite</a></span>
{% else %}
<span><a href="{{ path('frontend_travel_delete_favorite', {'id': favorite.id} ) }}" class="pull-right button btn-small red">Remove from</a></span>
{% endif %}
// if user is not AUTHENTICATED_REMEMBERED
{% else %}
<span><a href="{{ path('frontend_travel_add_favorite', {'id': travel.id} ) }}" class="pull-right button btn-small red">Add to favorite</a></span>
{% endif %}
//..........
{% endfor %}
Repository: queryBuilder
// get list of favorite of current user
public function getFavoriteByUser($user)
{
$qb = $this->createQueryBuilder('f')
->Where('f.user = '.$user);
return $qb->getQuery()->getResult();
}
UPDATED
FavoriteEntity
class Favorite
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Project\UserBundle\Entity\User")
* @ORM\JoinColumn(nullable=false)
*/
protected $user;
/**
* @ORM\ManyToOne(targetEntity="Project\TravelBundle\Entity\Travel", inversedBy="favorites")
* @ORM\JoinColumn(nullable=false)
*/
protected $travel;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set user
*
* @param \Project\UserBundle\Entity\User $user
* @return Favorite
*/
public function setUser(\Project\UserBundle\Entity\User $user)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* @return \Project\UserBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Set travel
*
* @param \Project\TravelBundle\Entity\Travel $travel
* @return Favorite
*/
public function setTravel(\Project\TravelBundle\Entity\Travel $travel)
{
$this->travel = $travel;
return $this;
}
/**
* Get travel
*
* @return \Project\TravelBundle\Entity\Travel
*/
public function getTravel()
{
return $this->travel;
}
}
TravelEntity
class Travel
{
/....
/**
* @ORM\OneToMany(targetEntity="Project\TravelBundle\Entity\Favorite", mappedBy="travel", cascade={"remove"})
*/
private $favorites;
public function __construct()
{
$this->favorites = new \Doctrine\Common\Collections\ArrayCollection();
}
/...........
/**
* Add favorites
*
* @param \Project\TravelBundle\Entity\Favorite $favorites
* @return Travel
*/
public function addFavorite(\Project\TravelBundle\Entity\Favorite $favorites)
{
$this->favorites[] = $favorites;
$favorites->setTravel($this);
return $this;
}
/**
* Remove favorites
*
* @param \Project\TravelBundle\Entity\Favorite $favorites
*/
public function removeFavorite(\Project\TravelBundle\Entity\Favorite $favorites)
{
$this->favorites->removeElement($favorites);
}
/**
* Get favorites
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getFavorites()
{
return $this->favorites;
}
Well you could try this:
In your controller:
if($user) {
$favorite = $em->getRepository('ProjectTravelBundle:Favorite')->getFavoriteByUser($user);
$ids = array_map(function($entity) { return $entity->getTravel()->getId(); }, $favorite);
} else{
$favorite = '';
$ids = array();
}
...
return $this->render('ProjectFrontendBundle:Travel:travel-list-view.html.twig',array(
'ids' => $ids,
'pagination' => $pagination,
'nb' => $nb,
'favorite' =>$favorite, // list of favorites of current user
));
In your template:
{% if travel.id not in ids %}
<span><a href="{{ path('frontend_travel_add_favorite', {'id': travel.id} ) }}" class="pull-right button btn-small red">Add to favorite</a></span>
{% else %}
<span><a href="{{ path('frontend_travel_delete_favorite', {'id': favorite.id} ) }}" class="pull-right button btn-small red">Remove from</a></span>
{% endif %}
Hope it helps.