产品和注释之间的Doctrine查询生成器[symfony2]

时间:2016-08-06 11:13:23

标签: symfony doctrine-orm twig fosuserbundle query-builder

当我查看www.example.com/product/10时,此产品已链接至a User Id.现在,我只想显示与该产品Comment相关联的User id我正在观看。

Comment是表User的链接,因此每条评论都是用户ID。表Product(Post)也链接到表用户,每个产品都有用户ID。

现在,表格CommentProduct尚未链接,我认为它们应该可以执行查询,但我不确定。

我使用FosCommentBundle作为评论。

控制器:

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;
    }

}

添加

<?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();
    }
}

从评论到帖子(产品)的关系:

/**
 * @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;
}

控制器中的修改:

 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));

    }

错误:

  

控制器   &#34; FLY \ BookingsBundle \控制器\ PostController中:: productAction()&#34;   要求您为&#34; $ post&#34;提供价值。争论(因为   没有默认值,或者因为存在非可选参数   在此之后)。

1 个答案:

答案 0 :(得分:0)

考虑到Many-To-OneComment之间存在Product关联。以下是在CommentRepository中编写新方法以获取单个产品的注释列表的方法。

/**
 * 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();
}

您可以根据自己的要求添加任何其他条件。或者添加排序或分页等。

注意:我还没有添加用户关联。如果您还有其他需要,请告诉我。