Search code examples
phpsymfonysymfony-3.2

Accessing to nested comments in a Symfony Blog


I'm working on a project which implements a public feed. I have a Comment entity which let's users to submit comments to each feed. However, I want users to be able to submit responses to the comments as well.

For that purpose I have $response property in my Comment entity. I assume that saving the response is same as with saving the comment since response is also a comment.

But, I'm not sure about how I can access to a comment without its id and save the response for that comment.

In my FeedController I save a comment like this;

 $commentForm = $this->createForm(CommentType::class);
    $commentForm->handleRequest($request);
    if ($commentForm->isSubmitted() && $commentForm->isValid()) {
        $content = $commentForm->get('content')->getData();
        $feed_id = $feed;

        $comment= EntityBuilder::newComment($content, $user, $feed_id);

        $commentService->saveEntity($comment);

        if(!is_null($comment)){
            $this->addFlash(
                'commentsuccess',
                'Your reply was successfully posted!'
            );
        }

        return $this->redirect($this->generateUrl('showFeed', array('slug' => $feed->getSlug()), UrlGeneratorInterface::ABSOLUTE_URL));

    }

Here is the Comment entity;

/**
* Class Comment
* @package AppBundle\Entity
* @ORM\Entity(repositoryClass="AppBundle\Repository\CommentRepository")
* @ORM\Table(name="comment")
* @ORM\HasLifecycleCallbacks()
*
*/
class Comment
{

/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Feed", inversedBy="comments")
 * @ORM\JoinColumn(name="feedid", referencedColumnName="id")
 */
private $feedid;

/**
 * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="comments")
 * @ORM\JoinColumn(name="createdby", referencedColumnName="id")
 */
private $createdby;

/**
 * @ORM\Column(type="string")
 * @Assert\NotBlank(message="Please fill in the description")
 */
private $content;

/**
 * @ORM\OneToOne(targetEntity="Comment")
 */
protected $response;


/**
 * @ORM\Column(type="datetime")
 */
private $createdAt;

/**
 * @ORM\Column(type="datetime")
 */
private $updatedAt;


/**
 * Constructor
 */
public function __construct()
{
    $this->createdAt= new \DateTime();
    $this->updatedAt= new \DateTime();
}

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

/**
 * 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 feedid
 *
 * @param \AppBundle\Entity\Feed $feedid
 *
 * @return Comment
 */
public function setFeedid(\AppBundle\Entity\Feed $feedid = null)
{
    $this->feedid = $feedid;

    return $this;
}

/**
 * Get feedid
 *
 * @return \AppBundle\Entity\Feed
 */
public function getFeedid()
{
    return $this->feedid;
}

/**
 * Set createdby
 *
 * @param \AppBundle\Entity\User $createdby
 *
 * @return Comment
 */
public function setCreatedby(\AppBundle\Entity\User $createdby = null)
{
    $this->createdby = $createdby;

    return $this;
}

/**
 * Get createdby
 *
 * @return \AppBundle\Entity\User
 */
public function getCreatedby()
{
    return $this->createdby;
}

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

    return $this;
}

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

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

    return $this;
}

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


/**
 * Set response
 *
 * @param \AppBundle\Entity\Comment $response
 *
 * @return Comment
 */
public function setResponse(\AppBundle\Entity\Comment $response = null)
{
    $this->response = $response;

    return $this;
}

/**
 * Get response
 *
 * @return \AppBundle\Entity\Comment
 */
public function getResponse()
{
    return $this->response;
}

}

Even if I create another form type for responses, I'm still not sure about how I can save a response for a specific comment.


Solution

  • My recomendation is to implement a Parent/Children approach, adding a (ManyToOne) $parent field to the Comment entity and its inversed (OneToMany) $children property. Later, you could add a CollectionType form field into CommentType for $children property, so you might need more than one response per comment.

    Don't worry about parent id, the CollectionType does the work for you. See more about how CollectionType works here.