When i'm viewing www.example.com/product/10 this product is link to a User Id. Now i would like to show only Comment that is link to the User id of the product a i'm viewing.
The table Comment is link to the table User, so each comment have is user id. The table Product (Post) is also link to the table user , each product have is user id.
For now the table Comment and Product are not yet link , i think they should be so i can perform a query, but i'm not sure.
I'm using FosCommentBundle for the comment.
Controller:
public function productAction($id, Request $request)
{
$session = $this->getRequest()->getSession();
$em = $this->getDoctrine()->getManager();
$findEntities = $em->getRepository('FLYBookingsBundle:Post')->findBy(array('id' => $id));
$entities = $this->get('knp_paginator')->paginate($findEntities, $this->get('request')->query->get('page', 1), 9
);
if ($session->has('cart'))
$cart = $session->get('cart');
else
$cart = false;
if (!$entities) {
throw $this->createNotFoundException('Unable to find Post entity.');
}
$id = 'thread_id';
$thread = $this->container->get('fos_comment.manager.thread')->findThreadById($id);
if (null === $thread) {
$thread = $this->container->get('fos_comment.manager.thread')->createThread();
$thread->setId($id);
$thread->setPermalink($request->getUri());
// Add the thread
$this->container->get('fos_comment.manager.thread')->saveThread($thread);
}
$comments = $this->container->get('fos_comment.manager.comment')->findCommentTreeByThread($thread);
return $this->render('FLYBookingsBundle:Post:product.html.twig', array('entity' => $entities,
'cart' => $cart,'comments' => $comments,
'thread' => $thread));
}
Product.html.twig
<div id="fos_comment_thread" data-thread="{{ thread.id }}">
{% include 'FOSCommentBundle:Thread:async.html.twig' with {
'comments': comments,
'thread': thread
} %}
Comment.php
<?php
namespace Application\Sonata\CommentBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\CommentBundle\Entity\Comment as BaseComment;
use FOS\CommentBundle\Model\SignedCommentInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Application\Sonata\UserBundle\Entity\User;
/**
* #ORM\Entity
* #ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT")
*/
class Comment extends BaseComment implements SignedCommentInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\generatedValue(strategy="AUTO")
*/
protected $id;
/**
* Thread of this comment
*
* #var Thread
* #ORM\ManyToOne(targetEntity="Application\Sonata\CommentBundle\Entity\Thread")
*/
protected $thread;
/**
* Author of the comment
*
* #ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User")
* #var User
*/
protected $author;
/**
* Sets the author of the Comment
*
* #param UserInterface $user
*/
public function setAuthor(UserInterface $author)
{
$this->author = $author;
}
/**
* Gets the author of the Comment
*
* #return UserInterface
*/
public function getAuthor()
{
return $this->author;
}
public function getAuthorName()
{
if (null === $this->getAuthor()) {
return 'Anonymous';
}
return $this->getAuthor()->getUsername();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Post.php
<?php
namespace FLY\BookingsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Application\Sonata\UserBundle\Entity\User;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use JMS\SecurityExtraBundle\Annotation\Secure;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Form\Type\VichImageType;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\Form\Extension\Core\Type\FileType;
/**
* Post
*
* #ORM\Table(name="post")
* #ORM\Entity(repositoryClass="FLY\BookingsBundle\Entity\PostRepository")
* #Vich\Uploadable
*/
class Post
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #Assert\Length(min=2, max=20)
*
* #ORM\Column(name="username", type="string", length=45, nullable=true)
*/
private $username;
/**
* #var string
*
* #Assert\Regex("/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+#[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/")
*
* #ORM\Column(name="email", type="string", length=45, nullable=false)
*/
private $email;
/**
* #ORM\ManyToOne(targetEntity="FLY\BookingsBundle\Entity\Tva")
* #ORM\joinColumn(onDelete="SET NULL")
*/
private $tva;
/**
* #ORM\ManyToOne(targetEntity="FLY\BookingsBundle\Entity\Media")
* #ORM\joinColumn(onDelete="SET NULL")
*/
private $image;
/**
* #var string
*
* #Assert\Length(max=350)
*
* #ORM\Column(name="description", type="text" , length=125, nullable=true)
*/
private $description;
/**
* #var float
*
* #Assert\NotBlank()
*
*
* #Assert\Regex(
* pattern= "/^[1-9]\d{0,7}(?:\.\d{1,4})?$/",
* message= "The First number can't start with 0"
* )
*
* #ORM\Column(name="price", type="float")
*/
private $price;
/**
*
*
* #ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User")
* #ORM\JoinColumn(onDelete="CASCADE")
* #Security("user.getId() == post.getUser()")
*/
private $user;
/**
* #ORM\OneToOne(targetEntity="Quantity", cascade={"remove"})
* #ORM\JoinColumn(name="sold_id", referencedColumnName="id")
*/
protected $sold;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* #param string $username
*
* #return Post
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set email
*
* #param string $email
*
* #return Post
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set price
*
* #param float $price
* #return Post
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* #return float
*/
public function getPrice()
{
return $this->price;
}
/**
* #return User
*/
public function getUser()
{
return $this->user;
}
/*
* #param User $user
*/
public function setUser(User $user)
{
$this->user = $user;
return $this;
}
/**
* Set tva
*
* #param \FLY\BookingsBundle\Entity\Tva $tva
* #return Post
*/
public function setTva(\FLY\BookingsBundle\Entity\Tva $tva)
{
$this->tva = $tva;
return $this;
}
/**
* Get tva
*
* #return \FLY\BookingsBundle\Entity\Tva
*/
public function getTva()
{
return $this->tva;
}
/**
* Set image
*
* #param \FLY\BookingsBundle\Entity\Media $image
* #return Post
*/
public function setImage(\FLY\BookingsBundle\Entity\Media $image)
{
$this->image = $image;
return $this;
}
/**
* Get image
*
* #return \FLY\BookingsBundle\Entity\Media
*/
public function getImage()
{
return $this->image;
}
/**
* Set description
*
* #param string $description
* #return Post
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set sold
*
* #param integer $sold
* #return Post
*/
public function setSold($sold)
{
$this->sold = $sold;
return $this;
}
/**
* Get sold
*
* #return integer
*/
public function getSold()
{
return $this->sold;
}
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* #Vich\UploadableField(mapping="product_image", fileNameProperty="imageName")
*
* #var File
*/
private $imageFile;
/**
* #ORM\Column(type="string", length=255)
*
* #var string
*/
private $imageName;
/**
* #ORM\Column(type="datetime")
*
* #var \DateTime
*/
private $updatedAt;
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* #param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*
* #return User
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTime('now');
}
return $this;
}
/**
* #return File
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* #param string $imageName
*
* #return User
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
return $this;
}
/**
* #return string
*/
public function getImageName()
{
return $this->imageName;
}
}
ADD:
<?php
namespace Application\Sonata\CommentBundle\Entity;
use FLY\BookingsBundle\Entity\Post;
use Application\Sonata\UserBundle\Entity\User;
use Doctrine\ORM\EntityRepository;
class CommentRepository extends EntityRepository
{
/**
* Get Comments for a single Product.
* #param Post $post
* #return mixed
*/
public function getCommentsForSinglePost(Post $post)
{
$qb = $this->createQueryBuilder('c')
->where('c.post = :postId')
->setParameter('postId', $post->getId());
$query = $qb->getQuery();
return $query->execute();
}
}
Relation from Comment to Post(Product):
/**
* #ORM\ManyToOne(targetEntity="FLY\BookingsBundle\Entity\Post")
* #ORM\JoinColumn(nullable=true)
*/
private $post;
/**
* Set post
*
* #param \FLY\BookingsBundle\Entity\Post $post
* #return Comment
*/
public function setUser(\FLY\BookingsBundle\Entity\Post $post = null)
{
$this->post = $post;
return $this;
}
/**
* Get post
*
* #return \FLY\BookingsBundle\Entity\Post
*/
public function getPost()
{
return $this->post;
}
modication in controller:
public function productAction($id, Request $request, $post)
{
$session = $this->getRequest()->getSession();
$em = $this->getDoctrine()->getManager();
$findEntities = $em->getRepository('FLYBookingsBundle:Post')->findBy(array('id' => $id));
$entities = $this->get('knp_paginator')->paginate($findEntities, $this->get('request')->query->get('page', 1), 9
);
if ($session->has('cart'))
$cart = $session->get('cart');
else
$cart = false;
if (!$entities) {
throw $this->createNotFoundException('Unable to find Post entity.');
}
$post = 'thread_id';
$thread = $em->getRepository('ApplicationSonataCommentBundle:Comment')->getCommentsForSinglePost($post);
if (null === $thread) {
$thread = $this->container->get('fos_comment.manager.thread')->createThread();
$thread->setId($post);
$thread->setPermalink($request->getUri());
// Add the thread
$this->container->get('fos_comment.manager.thread')->saveThread($thread);
}
$comments = $this->container->get('fos_comment.manager.comment')->findCommentTreeByThread($thread);
return $this->render('FLYBookingsBundle:Post:product.html.twig', array('entity' => $entities,
'cart' => $cart,'comments' => $comments,'post' => $post,
'thread' => $thread));
}
Error:
Controller
"FLY\BookingsBundle\Controller\PostController::productAction()"
requires that you provide a value for the "$post" argument (because
there is no default value or because there is a non optional argument
after this one).
Considering you have Many-To-One association from Comment to Product. Here is how you should write a new method in CommentRepository to get list of comments for a single product.
/**
* Get Comments for a single Product.
* #param Product $product
* #return mixed
*/
public function getCommentsForSingleProduct(Product $product)
{
$qb = $this->createQueryBuilder('c')
->where('c.product = :productId')
->setParameter('productId', $product->getId());
$query = $qb->getQuery();
return $query->execute();
}
You can add any other condition as per your requirement. or add sort, or pagination etc..
Note : I haven't added user association. Let me know if you need anything else.
Related
I am using Symfony and Doctrine.
I have two Entities, User and Pots.
Every logged User can create as many Post he want to.
Every Post is associated to one User.
Thats the Workflow: I log in with an User, this user create a Post. A New Post is saved in the Database with a foreigkey on the User wo create it.
Problem: when the User create the Post, the post ist create, but a new User is created too. The new Post is asssociate to the new Users and not to the logged User.
USER ENTITY:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\Post;
/**
* #ORM\Entity
* #ORM\Table(name= "User")
*/
class User
{
/**
* #ORM\Column(type = "integer")
* #ORM\Id
* #ORM\GeneratedValue("AUTO")
*/
private $id;
/**
* #ORM\Column(type = "string", length = 50)
*/
private $account;
/**
* #ORM\Column(type = "string", length = 22)
*/
private $password;
/**
* #ORM\Column(type = "string", length = 100)
*/
private $email;
/**
* #ORM\Column(type = "integer", length = 1)
*/
private $type;
/**
*
* #ORM\OneToMany(targetEntity="Post", mappedBy="user")
*/
private $posts;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set account
*
* #param string $account
*
* #return User
*/
public function setAccount($account)
{
$this->account = $account;
return $this;
}
/**
* Get account
*
* #return string
*/
public function getAccount()
{
return $this->account;
}
/**
* Set password
*
* #param string $password
*
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set mail
*
* #param string $mail
*
* #return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get mail
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set type
*
* #param integer $type
*
* #return User
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* #return integer
*/
public function getType()
{
return $this->type;
}
/**
* Constructor
*/
public function __construct()
{
$this->posts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add post
*
* #param \AppBundle\Entity\Post $post
*
* #return User
*/
public function addPost(\AppBundle\Entity\Post $post)
{
$this->posts[] = $post;
return $this;
}
/**
* Remove post
*
* #param \AppBundle\Entity\Post $post
*/
public function removePost(\AppBundle\Entity\Post $post)
{
$this->posts->removeElement($post);
}
/**
* Get posts
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getPosts()
{
return $this->posts;
}
}
POST ENTITY:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\User;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* #ORM\Entity
* #ORM\Table(name = "Post")
* #Vich\Uploadable
*/
class Post
{
/**
* #ORM\Column(type = "integer")
* #ORM\Id
* #ORM\GeneratedValue("AUTO")
*/
private $id;
/**
* #ORM\Column(type = "string", length = 25)
*/
private $title;
/**
* #ORM\Column(type = "string", length = 255)
*/
private $text;
/**
* #ORM\Column(type= "string", length = 250)
*/
private $pic;
/**
* #Vich\UploadableField(mapping="post_file", fileNameProperty="pic")
*
*/
private $picFile;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="posts", cascade={"persist"})
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
public function getPicFile(){
return $this->picFile;
}
public function setPicFile(File $picFile = null){
$this->picFile = $picFile;
return $this;
}
/**
* Set user
*
* #param \AppBundle\Entity\User $user
*
* #return Coach
*/
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 title
*
* #param string $title
*
* #return Post
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set text
*
* #param string $text
*
* #return Post
*/
public function setText($text)
{
$this->text = $text;
return $this;
}
/**
* Get text
*
* #return string
*/
public function getText()
{
return $this->text;
}
/**
* Set pic
*
* #param string $pic
*
* #return Post
*/
public function setPic($pic)
{
$this->pic = $pic;
return $this;
}
/**
* Get pic
*
* #return string
*/
public function getPic()
{
return $this->pic;
}
/**
* Set id
*
* #param integer $id
*
* #return Post
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
CONTROLLER:
NOTE: Here is take the logged User from the SESSION. This works, i output the id from the User i use and it was the correct id.
public function FrameCoachNewAction(Request $request)
{
$session = $request->getSession();
$session->start();
$user = $session->get('user');
$post = new Post();
$form = $this->createForm(PostType::class, $post);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$post = $form->getData();
$post->setUser($user);
$doct = $this->getDoctrine()->getManager();
$doct->persist($post);
$doct->flush();
//return New Response($post->getUser()->getId());
return $this->RedirectToRoute('app_frame_coach');
}else{
return $this->render('/frame/frame_coach_new.html.twig', array('form' => $form->createView(), 'user' => $user));
}
}
I left the Entity like you said, but i changed the Controller to. The Session User Object dind't work to associate it to the Post. So I just toke the ID from the Session and then search the user object again throw that id in the database and used this instade.
public function FrameCoachNewAction(Request $request)
{
$session = $request->getSession();
$session->start();
$users = $session->get('user');
$repo = $this->getDoctrine()->getRepository(User::class);
$user = $repo->find($users->getId());
$post = new Post();
$form = $this->createForm(PostType::class, $post);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$doct = $this->getDoctrine()->getManager();
$post = $form->getData();
$post->setUser($user);
$doct->persist($post);
$doct->flush();
//return New Response($post->getUser()->getId());
return $this->RedirectToRoute('app_frame_coach');
}else{
return $this->render('/frame/frame_coach_new.html.twig', array('form' => $form->createView(), 'user' => $user));
}
}
The user is the strong side so you should move the cascade={"persist"} option to user, then the user can save the post not the other way. It seems the cascade={"persist"} option is rewriting the setUser method. When you use the cascade={"persist"} option that entity would create the targetEntity.
In addition to #Juan I. Morales Pestana
class User
{
// ...
/**
*
* #ORM\OneToMany(
* targetEntity="Post",
* mappedBy="user",
* cascade={"persist"}
* )
*/
private $posts;
// ...
/**
* Constructor
*/
public function __construct()
{
$this->posts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add post
*
* #param \AppBundle\Entity\Post $post
*
* #return User
*/
public function addPost(\AppBundle\Entity\Post $post)
{
$this->posts[] = $post;
$post->setUser($this);
return $this;
}
I tried very hard to get the KNP Paginator to work.
I only want to oder an Entity to the id, but the pagination accept all the params but does noting with it!
HereĀ“s my code:
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
The Controller class:
class StartController extends Controller
{
public function indexAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$dql = "SELECT a FROM MainArtBundle:Art a";
$query = $em->createQuery($dql);
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$query,
$request->query->get('page', 1) /*page number*/,
8 /*limit per page*/
);
$pagination->setUsedRoute('homepage');
if (!$pagination) {
throw $this->createNotFoundException('Unable to find Art entities.');
}
return $this->render('MainShowBundle:Default:index.html.twig', array(
'pagination' => $pagination,
));
}
The Twig Template:
<li>{{ knp_pagination_sortable(pagination, 'Oldest', 'a.id', {'direction': 'desc'}) }}</li>
<li>{{ knp_pagination_sortable(pagination, 'Newest', 'a.id', {'direction': 'asc'}) }}</li>
The ArtEntity (the entire Entity because perhaps the mistake is caused by the entity, can it be)
<?php
namespace Main\ArtBundle\Entity;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
use Main\LikeBundle\Entity\Thumb;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\Request;
/**
* Art
*
* #ORM\Table(name="art")
* #ORM\Entity(repositoryClass="Main\ArtBundle\Entity\ArtRepository")
*/
class Art
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $locale
*
* #ORM\Column(name="locale", type="string", length=5, nullable=false)
*/
protected $locale;
/**
* #var arrayCollection $user
*
* #ORM\ManyToOne(targetEntity="Main\UserBundle\Entity\User", inversedBy="arts")
*
*/
protected $user;
/**
* #var \Doctrine\Common\Collections\ArrayCollection $visits
*
* #ORM\OneToMany(targetEntity="Main\ArtBundle\Entity\ArtVisit", mappedBy="art", fetch="EXTRA_LAZY")
*
*/
protected $visits;
/**
* #var \Doctrine\Common\Collections\ArrayCollection $tags
*
* #ORM\ManyToMany(targetEntity="Tags", inversedBy="arts", cascade={"persist"})
*/
protected $tags;
/**
* #var \Doctrine\Common\Collections\ArrayCollection $feature_partner
* #ORM\ManyToMany(targetEntity="Main\UserBundle\Entity\User", inversedBy="feature_partner")
*
*/
protected $feature_partner;
/**
* #var string $headline
*
* #Assert\NotBlank()
*
* #ORM\Column(type="string", length=255, unique=false, nullable=false)
*/
protected $headline;
/**
* #var \Main\StorageBundle\Entity\Image
*
* #ORM\OneToOne(targetEntity="Main\StorageBundle\Entity\Image")
* #ORM\Column(nullable=true)
*/
protected $image;
/**
* #var string $content
*
* #Assert\NotBlank()
*
* #ORM\Column(type="text", unique=false, nullable=false)
*/
protected $content;
/**
* #var string $description
*
* #ORM\Column(type="text", unique=false, nullable=true)
*/
protected $description;
/**
* #var datetime $created
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(type="datetime")
*/
private $created;
/**
* #var datetime $updated
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(type="datetime")
*/
private $updated;
/**
* #var datetime $contentChanged
*
* #ORM\Column(name="content_changed", type="datetime", nullable=true)
* #Gedmo\Timestampable(on="change", field={"headline", "content"})
*/
private $contentChanged;
/**
* #var integer $viewed
*
* #ORM\Column(name="viewed", type="integer", nullable=true)
*/
private $viewed;
/**
* #var object $CommentThread
*
*/
private $thread_id;
/**
* #var \Doctrine\Common\Collections\ArrayCollection $thumbs
*
* #ORM\OneToMany(targetEntity="Main\LikeBundle\Entity\Thumb", mappedBy="entity", fetch="EXTRA_LAZY")
*/
private $thumbs;
/**
* Constructor.
*/
public function __construct()
{
$this->tags = new \Doctrine\Common\Collections\ArrayCollection();
$this->feature_partner = new \Doctrine\Common\Collections\ArrayCollection();
$this->thumbs = new \Doctrine\Common\Collections\ArrayCollection();
$this->commentThread = new \Main\ArtBundle\Entity\CommentThread($this->getId());
/*$request = new Request();
$this->locale = $request->getLocale()*/;
}
/**
* #return string
*/
public function __toString()
{
return $this->getHeadline();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set user
*
* #param integer $userId
* #return Art
*/
public function setUserId($userId)
{
$this->user = $userId;
return $this;
}
/**
* Get user
*
* #return integer
*/
public function getUserId()
{
return $this->user;
}
/**
* Set tags
*
* #param integer $tags
* #return Art
*/
public function setTags($tags)
{
$this->tags = $tags;
return $this;
}
/**
* Get tags
*
* #return integer
*/
public function getTags()
{
return $this->tags;
}
/**
* Set headline
*
* #param string $headline
* #return Art
*/
public function setHeadline($headline)
{
$this->headline = $headline;
return $this;
}
/**
* Get headline
*
* #return string
*/
public function getHeadline()
{
return $this->headline;
}
/**
* Set content
*
* #param string $content
* #return Art
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* Get content
*
* #return string
*/
public function getContent()
{
return $this->content;
}
/**
* Set created
*
* #param \DateTime $created
* #return Art
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Get created
*
* #return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* Set updated
*
* #param \DateTime $updated
* #return Art
*/
public function setUpdated($updated)
{
$this->updated = $updated;
return $this;
}
/**
* Get updated
*
* #return \DateTime
*/
public function getUpdated()
{
return $this->updated;
}
/**
* Set contentChanged
*
* #param \DateTime $contentChanged
* #return Art
*/
public function setContentChanged($contentChanged)
{
$this->contentChanged = $contentChanged;
return $this;
}
/**
* Get contentChanged
*
* #return \DateTime
*/
public function getContentChanged()
{
return $this->contentChanged;
}
/**
* Set feature_partner
*
* #param integer $featurePartner
* #return Art
*/
public function setFeaturePartner($featurePartner)
{
$this->feature_partner = $featurePartner;
return $this;
}
/**
* Get feature_partner
*
* #return \Doctrine\Common\Collections\ArrayCollection
*/
public function getFeaturePartner()
{
return $this->feature_partner;
}
/**
* Add feature_partner
*
* #param \Main\UserBundle\Entity\User $featurePartner
* #return Art
*/
public function addFeaturePartner(\Main\UserBundle\Entity\User $featurePartner)
{
$this->feature_partner[] = $featurePartner;
return $this;
}
/**
* Remove feature_partner
*
* #param \Main\UserBundle\Entity\User $featurePartner
*/
public function removeFeaturePartner(\Main\UserBundle\Entity\User $featurePartner)
{
$this->feature_partner->removeElement($featurePartner);
}
/**
* Set description
*
* #param string $description
* #return Art
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set user
*
* #param \Main\UserBundle\Entity\User $user
* #return Art
*/
public function setUser(\Main\UserBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \Main\UserBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Add tags
*
* #param \Main\ArtBundle\Entity\Tags $tags
* #return Art
*/
public function addTag(\Main\ArtBundle\Entity\Tags $tags)
{
$this->tags[] = $tags;
return $this;
}
/**
* Remove tags
*
* #param \Main\ArtBundle\Entity\Tags $tags
*/
public function removeTag(\Main\ArtBundle\Entity\Tags $tags)
{
$this->tags->removeElement($tags);
}
/**
* Add visits
*
* #param \Main\ArtBundle\Entity\ArtVisit $visits
* #return Art
*/
public function addVisit(\Main\ArtBundle\Entity\ArtVisit $visits)
{
$this->visits[] = $visits;
return $this;
}
/**
* Remove visits
*
* #param \Main\ArtBundle\Entity\ArtVisit $visits
*/
public function removeVisit(\Main\ArtBundle\Entity\ArtVisit $visits)
{
$this->visits->removeElement($visits);
}
/**
* Get visits
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getVisits()
{
return $this->visits;
}
/**
* Set locale
*
* #param string $locale
* #return Art
*/
public function setLocale($locale)
{
$this->locale = $locale;
return $this;
}
/**
* Get locale
*
* #return string
*/
public function getLocale()
{
return $this->locale;
}
/**
* Set image
*
* #param \Main\StorageBundle\Entity\Image $image
* #return Art
*/
public function setImage(\Main\StorageBundle\Entity\Image $image = null)
{
$this->image = $image;
return $this;
}
/**
* Get image
*
* #return \Main\StorageBundle\Entity\Image
*/
public function getImage()
{
return $this->image;
}
/**
* Set viewed
*
* #param integer $viewed
* #return Art
*/
public function setViewed($viewed)
{
$this->viewed = $viewed;
return $this;
}
/**
* Get viewed
*
* #return integer
*/
public function getViewed()
{
return $this->viewed;
}
/**
* Set thumbs
*
* #param \Main\LikeBundle\Entity\Thumb $thumbs
* #return Art
*/
public function setThumbs(Thumb $thumbs = null)
{
$this->thumbs = $thumbs;
return $this;
}
/**
* Get thumbs
*
* #return \Doctrine\Common\Collections\ArrayCollection $thumbs
*/
public function getThumbs()
{
return $this->thumbs;
}
/**
* Add thumb
*
* #param \Main\LikeBundle\Entity\Thumb $thumb
* #return $this $thumbs
*/
public function addThumb(Thumb $thumb)
{
$this->thumbs[] = $thumb;
return $this;
}
/**
* Remove thumbs
*
* #param \Main\LikeBundle\Entity\Thumb $thumbs
*/
public function removeThumb(\Main\LikeBundle\Entity\Thumb $thumbs)
{
$this->thumbs->removeElement($thumbs);
}
/**
* Count all Thumbs of the piece of art.
*/
public function countAllThumbs() {
return $this->thumbs->count();
}
/**
* Check weather a user has thumbed a piece of art or not.
*/
public function isThumbed($user) {
// my first Closure :D
$p = function($key, $element) use ($user) {
return $element->getUser() == $user;
};
return $this->thumbs->exists($p);
}
/**
* Get the thumb object from a special user.
*/
public function getThumbFromUser ($user) {
$p = function($element) use ($user) {
return $element->getUser() == $user;
};
return $this->thumbs->filter($p);
}
}
The KNP Pagination Configuration (in config.yml)
knp_paginator:
page_range: 5 # default page range used in pagination control
default_options:
page_name: page # page query parameter name
sort_field_name: sort # sort field query parameter name
sort_direction_name: direction # sort direction query parameter name
distinct: true # ensure distinct results, useful when ORM queries are using GROUP BY statements
template:
pagination: ::Pagination\twitter_bootstrap_v3_pagination.html.twig # sliding pagination controls template
sortable: ::Pagination\sortable_link.html.twig # sort link template
I have dumped the pagination object in the controller and in the template as well. Everytime the params are there (direction= asc or desc) something like this is in the url:
?sort=a.id&direction=desc&page=1
but if I click on the link to change the direction: nothing change!!
I believe the knp pagination has a bug! Or I am very stupid ;)
If anyone can help me, I will be very happy!
Greetings Michael
For me, I created a new file knp_paginator.yaml and not knp_paginator.yml and I added this configuration and evrything works:
knp_paginator:
page_range: 5 # number of links shown in the pagination menu (e.g: you have 10 pages, a page_range of 3, on the 5th page you'll see links to page 4, 5, 6)
default_options:
page_name: page # page query parameter name
sort_field_name: sort # sort field query parameter name
sort_direction_name: direction # sort direction query parameter name
distinct: true # ensure distinct results, useful when ORM queries are using GROUP BY statements
filter_field_name: filterField # filter field query parameter name
filter_value_name: filterValue # filter value query parameter name
template:
pagination: '#KnpPaginator/Pagination/twitter_bootstrap_v4_pagination.html.twig' # sliding pagination controls template
sortable: '#KnpPaginator/Pagination/sortable_link.html.twig' # sort link template
filtration: '#KnpPaginator/Pagination/filtration.html.twig' # filters template
In my class I've got a UniqueEntity limitation on the "user" field (originally on the combination of "user" and "name"), which is derived from the fosuserbundle, if I put the constraint on "name" for example the constraint does its job and I get an error saying it's not unique. This does not happen on the user field however, I get no error and the entity is added to my database. Could someone point out the mistake I made?
namespace CB\DefaultBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* CustomList
*
* #ORM\Table()
* #ORM\Entity
* #UniqueEntity("user")
*/
class CustomList
{
/**
* #var integer
*
* #ORM\Column(name="Id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
* #Assert\NotBlank()
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255, nullable=true)
*/
private $description;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="customlists")
* #ORM\JoinColumn(name="user_id", referencedColumnName="Id")
*/
private $user;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="CB\DefaultBundle\Entity\Site", inversedBy="customlists")
* #ORM\JoinTable(name="customlist_site",
* joinColumns={
* #ORM\JoinColumn(name="customlist_id", referencedColumnName="Id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="site_id", referencedColumnName="Id")
* }
* )
*/
private $sites;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return CustomList
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* #param string $description
* #return CustomList
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set category
*
* #param \CB\DefaultBundle\Entity\Category $category
* #return CustomList
*/
public function setCategory(\CB\DefaultBundle\Entity\Category $category = null)
{
$this->category = $category;
return $this;
}
/**
* Get category
*
* #return \CB\DefaultBundle\Entity\Category
*/
public function getCategory()
{
return $this->category;
}
/**
* Set user
*
* #param \CB\DefaultBundle\Entity\User $user
* #return CustomList
*/
public function setUser(\CB\DefaultBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \CB\DefaultBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Constructor
*/
public function __construct()
{
$this->sites = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add sites
*
* #param \CB\DefaultBundle\Entity\Site $sites
* #return CustomList
*/
public function addSite(\CB\DefaultBundle\Entity\Site $sites)
{
$this->sites[] = $sites;
return $this;
}
/**
* Remove sites
*
* #param \CB\DefaultBundle\Entity\Site $sites
*/
public function removeSite(\CB\DefaultBundle\Entity\Site $sites)
{
$this->sites->removeElement($sites);
}
/**
* Get sites
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getSites()
{
return $this->sites;
}
}
Ok, I found my error, It was in my controller logic:
...
$list = new CustomList();
$form = $this->createForm(new CustomListType(), $list);
$form->submit($request);
$list = $form->getData();
$validator = $this->get('validator');
$errors = $validator->validate($list);
var_dump((string) $errors);
if ($form->isValid()){
$em = $this->getDoctrine()->getManager();
//set current user as user-value of this list
$list->setUser($this->getUser());
$em->persist($list);
$em->flush();
//prepare the response, e.g.
$response = array("code" => 100, "success" => true);
//you can return result as JSON , remember to 'use' Response!
return new Response(json_encode($response));
...
As you can see I set the user AFTER the form has been validated, meaning it would always validate the null values, as seen in the documentation here: UniqueEntity the default value of ignoreNull is true, meaning it would always pass the test.
Moving the $list->setUser($this->getUser()); line before my validation of the form fixed this problem!
I grab this kind of array.
This is a var_dump of my $tags variable.
array(2) { [0]=> string(1) "3" [1]=> string(1) "4" }
My entity
<?php
namespace Lan\CrmBundle\Entity;
use Doctrine\ORM\Mapping AS ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
*/
class Link
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=255, nullable=false)
* #Assert\NotBlank()
*/
private $url;
/**
* #ORM\Column(type="text", nullable=true)
*/
private $description;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $created_at;
/**
* #ORM\ManyToOne(targetEntity="Lan\SecurityBundle\Entity\User", inversedBy="links")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
/**
* #ORM\ManyToMany(targetEntity="Lan\CrmBundle\Entity\LinkTag", inversedBy="links")
* #ORM\JoinTable(
* name="LinkTagToLink",
* joinColumns={#ORM\JoinColumn(name="link_id", referencedColumnName="id", nullable=false)},
* inverseJoinColumns={#ORM\JoinColumn(name="link_tag_id", referencedColumnName="id", nullable=false)}
* )
*/
private $tags;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set url
*
* #param string $url
* #return Link
*/
public function setUrl($url)
{
$this->url = $url;
return $this;
}
/**
* Get url
*
* #return string
*/
public function getUrl()
{
return $this->url;
}
/**
* Set description
*
* #param string $description
* #return Link
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set created_at
*
* #param \DateTime $createdAt
* #return Link
*/
public function setCreatedAt($createdAt)
{
$this->created_at = $createdAt;
return $this;
}
/**
* Get created_at
*
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->created_at;
}
/**
* Set user
*
* #param \Lan\SecurityBundle\Entity\User $user
* #return Link
*/
public function setUser(\Lan\SecurityBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \Lan\SecurityBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Constructor
*/
public function __construct()
{
$this->tags = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add tags
*
* #param \Lan\CrmBundle\Entity\LinkTag $tags
* #return Link
*/
public function addTag(\Lan\CrmBundle\Entity\LinkTag $tags)
{
$this->tags[] = $tags;
return $this;
}
/**
* Remove tags
*
* #param \Lan\CrmBundle\Entity\LinkTag $tags
*/
public function removeTag(\Lan\CrmBundle\Entity\LinkTag $tags)
{
$this->tags->removeElement($tags);
}
/**
* Get tags
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTags()
{
return $this->tags;
}
}
My entire controller:
namespace Lan\CrmBundle\Controller;
use Lan\CrmBundle\Entity\Link;
use Lan\CrmBundle\Form\LinkType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class LinkController extends Controller {
public function indexAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$tags = $em->getRepository('LanCrmBundle:LinkTag')->findAll();
if($request->query->has('tags')) {
$tags = $request->query->get('tags');
//var_dump($tags); die();
$links = $em->getRepository('LanCrmBundle:Link')->findByTags($tags);
var_dump($links); die();
} else {
$links = $em->getRepository('LanCrmBundle:Link')->findBy(
array(),
array('id' => 'desc')
);
}
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$links,
$this->get('request')->query->get('page', 1),
4
);
return $this->render('LanCrmBundle:Link:index.html.twig', compact('pagination', 'tags'));
}
}
But I got this error:
ContextErrorException: Notice: Undefined index: joinColumns in ...
I think I can't use ->findByTags() like I want...
Thanks in advance!
I don't think you can findByTags because SF2 won't know if you want AND or OR for tags.
The only solution I can suggest you is that you need to query from link_tag table (use repository LanCrmBundle:LinkTag) manually to get all link.id then continue to retrieve link data using LanCrmBundle:Link.
I found a way but not really what I want :
public function findByUsersAndTags($users, $tags)
{
$queryBuilder = $this->createQueryBuilder('l')
->leftJoin('l.tags', 't')->addSelect('t')
->leftJoin('l.user', 'u')->addSelect('u')
->orderBy('l.id', 'desc');
if($users) {
foreach($users as $user_id) {
$queryBuilder->orHaving('u.id = :id')->setParameter('id', $user_id);
}
}
if($tags) {
foreach($tags as $tag_id) {
$queryBuilder->orHaving('t.id = :id')->setParameter('id', $tag_id);
}
}
return $queryBuilder->getQuery()->getResult();
}
Old Query in symfony 1.4 and doctrine 1.2
$user = Doctrine_Query::create()
->from('User.u')
->innerJoin('u.State s')
->where('u.id = ?', $id)
->andWhere('u.state_id = ?', $state_id)
->fetchOne();
Now my Query in symfony2:
$repository = $this->getDoctrine()
->getRepository('FrontendAccountBundle:User');
$user = $repository->findBy(array(
'activationId' => $activation_id),
array('state' => 3));
My error is comming up:
Unrecognized field: state
What is the problem?
Edit: reformatted code
Update
User-Entity:
namespace Frontend\AccountBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class User implements UserInterface, \Serializable
{
/**
* #var string
*
* #ORM\Column(name="activation_id", type="string", length=255, nullable=true)
*/
private $activationId;
/**
* #var \State
*
* #ORM\ManyToOne(targetEntity="State")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="state_id", referencedColumnName="id")
* })
*/
private $state;
/**
* Set activationId
*
* #param string $activationId
* #return User
*/
public function setActivationId($activationId)
{
$this->activationId = $activationId;
return $this;
}
/**
* Get activationId
*
* #return string
*/
public function getActivationId()
{
return $this->activationId;
}
/**
* Set state
*
* #param \Frontend\AccountBundle\Entity\State $state
* #return User
*/
public function setState(\Frontend\AccountBundle\Entity\State $state = null)
{
$this->state = $state;
return $this;
}
/**
* Get state
*
* #return \Frontend\AccountBundle\Entity\State
*/
public function getState()
{
return $this->state;
}
public function __construct()
{
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
}
/**
* #inheritDoc
*/
public function getUsername()
{
return $this->email;
}
/**
* #see \Serializable::serialize()
*/
public function serialize()
{
return serialize(array(
$this->id,
));
}
/**
* #see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id,
) = unserialize($serialized);
}
}
User-Entity:
namespace Frontend\AccountBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* State
*
* #ORM\Table(name="state")
* #ORM\Entity
*/
class State
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="state", type="string", length=255, nullable=false)
*/
private $state;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255, nullable=false)
*/
private $description;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set state
*
* #param string $state
* #return State
*/
public function setState($state)
{
$this->state = $state;
return $this;
}
/**
* Get state
*
* #return string
*/
public function getState()
{
return $this->state;
}
/**
* Set description
*
* #param string $description
* #return State
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
}
The problem is that the variable in the User entity is "state" not "stateId". You must always use the names from the entity, not the database. The join from User to State also needs to be done since the stateId is in the State entity.
When joins are needed you are probably better off using queryBuilder or DQL.
Here's a post about joins in Doctrine 2 queryBuilder: doctrine 2 query builder and join tables
Here's the documentation from the Symfony Book for Doctrine: http://symfony.com/doc/current/book/doctrine.html#entity-relationships-associations
Here's an example from my project that is very similar to your problem:
$uid = 2;
$rep = $this->getDoctrine()->getRepository('DevondevTrackRTimeBundle:Activity');
$q = $rep->createQueryBuilder('a')
->select ('a.activityId, a.startTime, a.endTime, u.username')
->join('a.login','u')
->where('u.id = :uid')
->setParameter('uid', $uid)
->getQuery();
$acts = $q->getResult();
If I didn't need anything from the user table the query could be written as
$uid = 2;
$rep = $this->getDoctrine()->getRepository('DevondevTrackRTimeBundle:Activity');
$q = $rep->createQueryBuilder('a')
->where('a.login = :uid')
->setParameter('uid', $uid)
->getQuery();
$acts = $q->getResult();
This is your query reworked in the same way:
$rep = $this->getDoctrine()->getRepository('FrontendAccountBundle:User');
$q = $rep->createQueryBuilder('u')
->join('u.state','s')
->where ('u.id = :uid')
->andWhere ('s.stateId = :sid')
->setParameters(array('uid' => $id, 'sid' => $state_id))
->getQuery();
$user = $q->getSingleResult();
Thanks to Peter to light me up a little bit!!!
If you don't want again a the stupid solution from symfony2(-docs) and doctrine2, because you need much more code than in symfony1.4, like that way http://symfony.com/doc/current/book/doctrine.html#joining-to-related-records. Try my solution.
Here is the result.
$em = $this->getDoctrine()->getEntityManager();
$user = $em->createQuery('SELECT u FROM FrontendAccountBundle:User u
INNER JOIN FrontendAccountBundle:State s
WHERE
u.activation_id=:activation_id
and
u.state=:state_id
')
->setParameter('activation_id', $activation_id)
->setParameter('state_id', 3)
->getSingleResult();