Accessing to nested comments in a Symfony Blog - php

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.

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.

Related

Save copy of entity doctrine/symfony2

I want to keep the previous version of an entity. When the 'old' entity is updated I want to save it with the same id but with a different revision number so it looks something like this
id: 1 revision_number: 1
id: 1 revision_number: 2
This is the entity
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Form
*
* #ORM\Table()
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
*/
class Form
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="export_template", type="string", length=255, nullable = true)
*/
private $exportTemplate;
/**
* #var \DateTime
*
* #ORM\Column(name="revision", type="datetime", nullable = true)
*/
private $revision;
/**
* #var integer
*
* #ORM\Column(name="revision_number", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $revisionNumber;
/**
* #ORM\ManyToOne(targetEntity="Client", inversedBy="forms")
* #ORM\JoinColumn(name="form_id", referencedColumnName="id")
*/
protected $client;
/**
* #ORM\OneToMany(targetEntity="Section", mappedBy="form", cascade={"persist"})
*/
protected $sections;
/**
* #ORM\OneToMany(targetEntity="Inspection", mappedBy="form")
*/
protected $inspections;
public function __construct()
{
$this->sections = new ArrayCollection();
$this->inspections = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Form
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set exportTemplate
*
* #param string $exportTemplate
* #return Form
*/
public function setExportTemplate($exportTemplate)
{
$this->exportTemplate = $exportTemplate;
return $this;
}
/**
* Get exportTemplate
*
* #return string
*/
public function getExportTemplate()
{
return $this->exportTemplate;
}
/**
* Set revision
*
* #param \DateTime $revision
* #return Form
*/
public function setRevision($revision)
{
$this->revision = $revision;
return $this;
}
/**
* Get revision
*
* #return \DateTime
*/
public function getRevision()
{
return $this->revision;
}
/**
* #param $revisionNumber
* #return Form
*/
public function setRevisionNumber($revisionNumber)
{
$this->revisionNumber = $revisionNumber;
return $this;
}
/**
* #return int
*/
public function getRevisionNumber()
{
return $this->revisionNumber;
}
/**
* Set client
*
* #param \AppBundle\Entity\Client $client
* #return Form
*/
public function setClient(\AppBundle\Entity\Client $client = null)
{
$this->client = $client;
return $this;
}
/**
* Get client
*
* #return \AppBundle\Entity\Client
*/
public function getClient()
{
return $this->client;
}
/**
* Add sections
*
* #param \AppBundle\Entity\Section $sections
* #return Form
*/
public function addSection(\AppBundle\Entity\Section $sections)
{
$this->sections[] = $sections;
return $this;
}
/**
* Remove sections
*
* #param \AppBundle\Entity\Section $sections
*/
public function removeSection(\AppBundle\Entity\Section $sections)
{
$this->sections->removeElement($sections);
}
/**
* Get sections
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getSections()
{
return $this->sections;
}
/**
* Add inspections
*
* #param \AppBundle\Entity\Inspection $inspections
* #return Form
*/
public function addInspection(\AppBundle\Entity\Inspection $inspections)
{
$this->inspections[] = $inspections;
return $this;
}
/**
* Remove inspections
*
* #param \AppBundle\Entity\Inspection $inspections
*/
public function removeInspection(\AppBundle\Entity\Inspection $inspections)
{
$this->inspections->removeElement($inspections);
}
/**
* Get inspections
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getInspections()
{
return $this->inspections;
}
/**
*
* #ORM\PrePersist()
*/
public function preSetDate(){
$this->revision = new \DateTime();
}
}
Is there a way I can do what I described?
I think what you may need is Loggable extension for Doctrine. Check this link:
https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/loggable.md
Loggable behavior tracks your record changes and is able to manage versions.
Using loggable behavior you can revert version from your repository with revert() method. You can find many examples on site I gave you the link above.
If you dont fancy using a 3rd party bundle for this:
your ID's will still have to be unique. If you need to track where the copy originated from then you could add a new parameter.
Once you have decided upon this, I would simply clone it, alter the revision number and add the original id if thats which way you want to go and then persist it.
class Form {
// ....
$orig_id = null;
// any getters/setters you need
// .....
}
then in the controller:
public function copyEntity($entity) {
$new_ent = clone $entity;
$new_ent->setOrigId( $entity->getId() );
$new_ent->setRevision( true ); // I would probably bin this as origId being !== null would do the same job
$this->entityManager->persist( $new_ent );
$this->entityManager->flush();
// .....
}

Calculate percentage in Symfony2

I have two entities, Projects and Tasks with their respective repositories.
I am trying to create a function that will calculate the totalNumberOfTasks() , totalNumberOfCompletedTasks() and getPercentComplete().
totalNumberOfTasks() basically will fetch all the data related with a specific project_id from the tasks table.
totalNumberOfCompletedTasks() will query all the data relevant with specific project_id but only those marked as COMPLETED from the tasks table.
getPercentComplete() will calculate the percent based on the totalNumberOfTasks() and totalNumberOfCompletedTasks() functions and print in the view file.
I have tried doing {{ project.tasks|length }} % in Twig file which fetched only the total number of tasks relating to that specific id. How do I get total number of tasks and completed tasks, find the percentage then show it in the view file where every projects are shown?
Sorry for my english. I am just not being able to make the question more understandable.
Project entity:
<?php
namespace TaskManagerBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Projects
* #ORM\Table()
* #ORM\Entity(repositoryClass="TaskManagerBundle\Entity\Repository\ProjectsRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Projects
{
/**
*
* #ORM\OneToMany(targetEntity="Tasks", mappedBy="projects")
*/
protected $tasks;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=30)
*/
private $title;
/**
* #var boolean
*
* #ORM\Column(name="completed", type="boolean")
*/
private $completed;
/**
* #var \Date
*
* #ORM\Column(name="due_date", type="date")
*/
private $dueDate;
/**
* #var \Date
*
* #ORM\Column(name="created", type="date")
*/
private $created;
/**
* #var \Date
*
* #ORM\Column(name="updated", type="date")
*/
private $updated;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* #param string $title
* #return Projects
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set completed
*
* #param boolean $completed
* #return Projects
*/
public function setCompleted($completed)
{
$this->completed = $completed;
return $this;
}
/**
* Get completed
*
* #return boolean
*/
public function getCompleted()
{
return $this->completed;
}
/**
* Set dueDate
*
* #param \Date $dueDate
* #return Projects
*/
public function setDueDate($dueDate)
{
$this->dueDate = $dueDate;
return $this;
}
/**
* Get dueDate
*
* #return \Date
*/
public function getDueDate()
{
return $this->dueDate;
}
/**
* Set created
*
* #param \Date $created
* #return Projects
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Get created
*
* #return \date
*/
public function getCreated()
{
return $this->created;
}
/**
* Set updated
*
* #param \Date $updated
* #return Projects
*/
public function setUpdated($updated)
{
$this->updated = $updated;
return $this;
}
/**
* Get updated
*
* #return \Date
*/
public function getUpdated()
{
return $this->updated;
}
/**
* #ORM\PrePersist
*/
public function setCreatedValue()
{
$this->created = new \DateTime();
}
/**
* #ORM\PreUpdate
*/
public function setUpdatedValue()
{
$this->updated = new \DateTime();
}
public function getNumberOfTasks()
{
}
/**
* Constructor
*/
public function __construct()
{
$this->tasks = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add tasks
*
* #param \TaskManagerBundle\Entity\Tasks $tasks
* #return Projects
*/
public function addTask(\TaskManagerBundle\Entity\Tasks $tasks)
{
$this->tasks[] = $tasks;
return $this;
}
/**
* Remove tasks
*
* #param \TaskManagerBundle\Entity\Tasks $tasks
*/
public function removeTask(\TaskManagerBundle\Entity\Tasks $tasks)
{
$this->tasks->removeElement($tasks);
}
/**
* Get tasks
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTasks()
{
return $this->tasks;
}
}
Tasks entity:
namespace TaskManagerBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Tasks
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="TaskManagerBundle\Entity\Repository\TasksRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Tasks
{
/**
*
* #ORM\ManyToOne(targetEntity="Projects", inversedBy="tasks")
* #ORM\JoinColumn(name="projects_id", referencedColumnName="id")
*/
protected $projects;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=30)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="description", type="text")
*/
private $description;
/**
* #var \DateTime
*
* #ORM\Column(name="updated", type="date")
*/
private $updated;
/**
* #var \DateTime
*
* #ORM\Column(name="created", type="date")
*/
private $created;
/**
* #var \DateTime
*
* #ORM\Column(name="due_date", type="date")
*/
private $dueDate;
/**
* #var boolean
*
* #ORM\Column(name="completed", type="boolean")
*/
private $completed;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* #param string $title
* #return Tasks
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set description
*
* #param string $description
* #return Tasks
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set updated
*
* #param \DateTime $updated
* #return Tasks
*/
public function setUpdated($updated)
{
$this->updated = $updated;
return $this;
}
/**
* Get updated
*
* #return \DateTime
*/
public function getUpdated()
{
return $this->updated;
}
/**
* Set created
*
* #param \DateTime $created
* #return Tasks
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Get created
*
* #return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* Set dueDate
*
* #param \DateTime $dueDate
* #return Tasks
*/
public function setDueDate($dueDate)
{
$this->dueDate = $dueDate;
return $this;
}
/**
* Get dueDate
*
* #return \DateTime
*/
public function getDueDate()
{
return $this->dueDate;
}
/**
* Set completed
*
* #param boolean $completed
* #return Tasks
*/
public function setCompleted($completed)
{
$this->completed = $completed;
return $this;
}
/**
* Get completed
*
* #return boolean
*/
public function getCompleted()
{
return $this->completed;
}
/**
* Set projects
*
* #param \TaskManagerBundle\Entity\Projects $projects
* #return Tasks
*/
public function setProjects(\TaskManagerBundle\Entity\Projects $projects = null)
{
$this->projects = $projects;
return $this;
}
/**
* Get projects
*
* #return \TaskManagerBundle\Entity\Projects
*/
public function getProjects()
{
return $this->projects;
}
}
Controller:
<?php
namespace TaskManagerBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use TaskManagerBundle\Entity\Projects;
use TaskManagerBundle\Form\ProjectType;
class DefaultController extends Controller
{
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('TestBundle:Projects')->findAll();
return $this->render('TestBundle:Default:index.html.twig', 'projects' => $entities]);
}
}
you can archive this problem using the Doctrine Criteria instead of make a custom Repository method. As Example you can add the following method to your Projects Entity class:
use Doctrine\Common\Collections\Criteria; // IMPORT THIS!
use Doctrine\ORM\Mapping as ORM;
/**
* Projects
* #ORM\Table()
* #ORM\Entity(repositoryClass="TaskManagerBundle\Entity\Repository\ProjectsRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Projects
{
...
public function getCompleteTasks()
{
$expr = Criteria::expr();
$criteria = Criteria::create();
$criteria->where($expr->eq('completed', true));
return $this->getTasks()->matching($criteria);
}
public function getNumberOfTasks()
{
return $this->getTasks()->count();
}
public function getPercentComplete()
{
$percentage = 0;
$totalSize = $this->getNumberOfTasks();
if ($totalSize>0)
{
$completedSize = $this->getCompleteTasks()->count();
$percentage = $completedSize / $totalSize * 100;
}
return $percentage;
}
...
}
Then you can use in your Twig template as follow:
{{ project.percentComplete|number_format(2, '.', ',') }}
Hope this help.

symfony 2 Fixtures for many to many relationship

How to set up fixtures for symfony 2 in for many to many relationship,
Following 2 entities are made by command lines,
And then added some lines for many to many relationship
Entity 1: Blog Class
<?php
namespace Acme\MainBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Blog
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Acme\MainBundle\Entity\BlogRepository")
*/
class Blog {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToMany(targetEntity="tag", inversedBy="blogs")
* #ORM\JoinTable(name="blog_tag",
* joinColumns={#ORM\JoinColumn(name="blog_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="tag_id", referencedColumnName="id")}
* )
**/
protected $tags;
public function __construct()
{
$this->tags = new ArrayCollection();
}
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="subTitle", type="text")
*/
private $subTitle;
/**
* #var string
*
* #ORM\Column(name="author", type="string", length=255)
*/
private $author;
/**
* #var \DateTime
*
* #ORM\Column(name="createdAt", type="datetime")
*/
private $createdAt;
/**
* #var \DateTime
*
* #ORM\Column(name="updatedAt", type="datetime")
*/
private $updatedAt;
/**
* #var string
*
* #ORM\Column(name="content", type="text")
*/
private $content;
/**
* #var boolean
*
* #ORM\Column(name="isPublished", type="boolean")
*/
private $isPublished;
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set title
*
* #param string $title
* #return Blog
*/
public function setTitle($title) {
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle() {
return $this->title;
}
/**
* Set author
*
* #param string $author
* #return Blog
*/
public function setAuthor($author) {
$this->author = $author;
return $this;
}
/**
* Get author
*
* #return string
*/
public function getAuthor() {
return $this->author;
}
/**
* Set createdAt
*
* #param \DateTime $createdAt
* #return Blog
*/
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 Blog
*/
public function setUpdatedAt($updatedAt) {
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt
*
* #return \DateTime
*/
public function getUpdatedAt() {
return $this->updatedAt;
}
/**
* Set content
*
* #param string $content
* #return Blog
*/
public function setContent($content) {
$this->content = $content;
return $this;
}
/**
* Get content
*
* #return string
*/
public function getContent() {
return $this->content;
}
/**
* Set isPublished
*
* #param boolean $isPublished
* #return Blog
*/
public function setIsPublished($isPublished) {
$this->isPublished = $isPublished;
return $this;
}
/**
* Get isPublished
*
* #return boolean
*/
public function getIsPublished() {
return $this->isPublished;
}
public function __toString() {
return strval($this->id);
}
/**
* Set subTitle
*
* #param string $subTitle
* #return Blog
*/
public function setSubTitle($subTitle)
{
$this->subTitle = $subTitle;
return $this;
}
/**
* Get subTitle
*
* #return string
*/
public function getSubTitle()
{
return $this->subTitle;
}
/**
* Add tags
*
* #param \Acme\MainBundle\Entity\tag $tags
* #return Blog
*/
public function addTag(\Acme\MainBundle\Entity\tag $tags)
{
$this->tags[] = $tags;
$tags->addBlog($this);
return $this;
}
/**
* Remove tags
*
* #param \Acme\MainBundle\Entity\tag $tags
*/
public function removeTag(\Acme\MainBundle\Entity\tag $tags)
{
$this->tags->removeElement($tags);
}
/**
* Get tags
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTags()
{
return $this->tags;
}
}
Entity 2: Tag Class
<?php
namespace Acme\MainBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Tag
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Acme\MainBundle\Entity\TagRepository")
*/
class Tag {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToMany(targetEntity="blog", mappedBy="tags")
**/
protected $blogs;
/**
* #var string
*
* #ORM\Column(name="tag", type="string", length=255)
*/
private $tag;
/**
* #var boolean
*
* #ORM\Column(name="isPublished", type="boolean")
*/
private $isPublished;
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set tag
*
* #param string $tag
* #return Tag
*/
public function setTag($tag) {
$this->tag = $tag;
return $this;
}
/**
* Get tag
*
* #return string
*/
public function getTag() {
return $this->tag;
}
/**
* Set isPublished
*
* #param boolean $isPublished
* #return Tag
*/
public function setIsPublished($isPublished) {
$this->isPublished = $isPublished;
return $this;
}
/**
* Get isPublished
*
* #return boolean
*/
public function getIsPublished() {
return $this->isPublished;
}
public function __toString() {
return strval($this->id);
}
/**
* Constructor
*/
public function __construct()
{
$this->blogs = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add blogs
*
* #param \Acme\MainBundle\Entity\blog $blogs
* #return Tag
*/
public function addBlog(\Acme\MainBundle\Entity\blog $blogs)
{
$this->blogs[] = $blogs;
$blogs->addTag($this);
return $this;
}
/**
* Remove blogs
*
* #param \Acme\MainBundle\Entity\blog $blogs
*/
public function removeBlog(\Acme\MainBundle\Entity\blog $blogs)
{
$this->blogs->removeElement($blogs);
}
/**
* Get blogs
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getBlogs()
{
return $this->blogs;
}
}
Attention!!!
You have a circular reference in your code!!!
When you add a tag to a blog, it call add blog to tag and so on, please fix it in like this:
Blog
/**
* Add tags
*
* #param \Acme\MainBundle\Entity\tag $tags
* #return Blog
*/
public function addTag(\Acme\MainBundle\Entity\tag $tags)
{
if (!$this->tags->contains($tags))
{
$this->tags[] = $tags;
$tags->addBlog($this);
}
return $this;
}
Tag
/**
* Add blogs
*
* #param \Acme\MainBundle\Entity\blog $blogs
* #return Tag
*/
public function addBlog(\Acme\MainBundle\Entity\blog $blogs)
{
if (!$this->blogs->contains($blogs))
{
$this->blogs[] = $blogs;
$blogs->addTag($this);
}
return $this;
}
For your question:
First, install and configure the DoctrineFixturesBundle.
Use the ordered fixture features to load first the tag then the blog.
Then I write for you this example fixtures:
TagFixtures
<?php
namespace Acme\MainBundle\DataFixtures\ORM;
use Acme\MainBundle Bundle\Entity\Tag;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
class TagFixtures extends AbstractFixture implements OrderedFixtureInterface {
/**
* Load data fixtures with the passed EntityManager
*
* #param \Doctrine\Common\Persistence\ObjectManager $manager
*/
function load(ObjectManager $manager)
{
$tag1 = new Tag();
$tag1->setTag("tag name 1");
$tag1->setIsPublished(true);
$tag2 = new Tag();
$tag2->setTag("tag name 2");
$tag2->setIsPublished(true);
$manager->persist($tag1);
$manager->persist($tag2);
$this->addReference('tag-tag_1', $tag1);
$this->addReference('tag-tag_2', $tag2);
$manager->flush();
}
/**
* Get the order of this fixture
*
* #return integer
*/
function getOrder()
{
return 1;
}
}
BlogFixtures
<?php
namespace Acme\MainBundle\DataFixtures\ORM;
use Acme\MainBundle\Entity\Blog;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
class BlogFixtures extends AbstractFixture implements OrderedFixtureInterface {
/**
* Load data fixtures with the passed EntityManager
*
* #param \Doctrine\Common\Persistence\ObjectManager $manager
*/
function load(ObjectManager $manager)
{
$blog = new Blog();
$blog->setTitle('Happy new year');
$blog->setAuthor("me");
$blog->setIsPublished(true);
$blog->setContent("Happy new year");
$blog->setSubTitle("2015");
$blog->setCreatedAt(new \DateTime('now'));
$blog->setUpdatedAt(new \DateTime('now'));
$blog->addTag($this->getReference('tag-tag_1'));
// $blog->addTag($this->getReference('tag-tag_2'));
$manager->persist($blog);
// $this->addReference('blog-blog_1', $blog);
$manager->flush();
}
/**
* Get the order of this fixture
*
* #return integer
*/
function getOrder()
{
return 2;
}
}
Hope this help and happy new year!
For simple cases I create my fixtures like:
Acme/DemoBundle/Entity/Tag.php
public function addBlog(\Acme\MainBundle\Entity\blog $blog)
{
$this->blogs[] = $blog;
return $this;
}
Acme/DemoBundle/Entity/Blog.php
public function addTag(\Acme\MainBundle\Entity\tag $tags)
{
$this->tags[] = $tags;
$tags->addBlog($this);
return $this;
}
Acme/DemoBundle/DataFixtures/ORM/TagBlogFixture.php
class TagBlogFixture extends AbstractFixture implements OrderedFixtureInterface {
function load(ObjectManager $manager)
{
$tag1 = new Tag();
// setters
$tag2 = new Tag();
// setters
$blog1 = new Blog();
// setters
$blog1
->addTag($tag1)
->addTag($tag2)
;
$blog2 = new Blog();
// setters
$blog2->addTag($tag2);
$manager->persist($tag1);
$manager->persist($tag2);
$manager->persist($blog1);
$manager->persist($blog2);
$manager->flush();
}
function getOrder()
{
return 1;
}
}
This doesn't share any references between objects, creates them in single file..

Symfony2 forms collection

I have, two entities, Topic and TopicContent are relation by topic_id.
topic_id in topic table is autoincremet , in topic_content it's not autoincrement.
Because, i need to get topic_id from Topic entity when query it's ok, and then insert data in topic_content table. Help me please, how to do this in symfony with orm. thanks.
TopicContent
namespace Socialist\ClubBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="topic_content")
*/
class TopicContent
{
/**
*
* #ORM\Column(name="topic_id", type="integer")
* #ORM\Id
*
*/
protected $topic_id;
/**
*
* #ORM\Column(name="topic_text", type="text", nullable=false)
*/
protected $topic_text;
/**
* #ORM\OneToOne(targetEntity="Topic", inversedBy="topicContent", cascade={"persist", "remove"})
* #ORM\JoinColumn(name="topic_id", referencedColumnName="topic_id", onDelete="CASCADE")
*/
private $topic;
/**
* Set topic_id
*
* #param integer $topicId
* #return TopicContent
*/
public function setTopicId($topicId)
{
$this->topic_id = $topicId;
return $this;
}
/**
* Get topic_id
*
* #return integer
*/
public function getTopicId()
{
return $this->topic_id;
}
/**
* Set topic_text
*
* #param string $topicText
* #return TopicContent
*/
public function setTopicText($topicText)
{
$this->topic_text = $topicText;
return $this;
}
/**
* Get topic_text
*
* #return string
*/
public function getTopicText()
{
return $this->topic_text;
}
/**
* Set topic
*
* #param \Socialist\ClubBundle\Entity\Topic $topic
* #return TopicContent
*/
public function setTopic(\Socialist\ClubBundle\Entity\Topic $topic = null)
{
$this->topic = $topic;
return $this;
}
/**
* Get topic
*
* #return \Socialist\ClubBundle\Entity\Topic
*/
public function getTopic()
{
return $this->topic;
}
}
Topic
namespace Socialist\ClubBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="topic")
* #ORM\HasLifecycleCallbacks
*/
class Topic
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $topic_id;
/**
* #ORM\Column(type="string", length=200)
*/
protected $topic_title;
/**
* #ORM\Column(type="datetime")
*/
protected $topic_date_add;
/**
* #ORM\Column(type="datetime")
*/
protected $topic_date_edit;
/**
* Get topic_id
*
* #return integer
*/
public function getTopicId()
{
return $this->topic_id;
}
/**
* Set topic_title
*
* #param string $topicTitle
* #return Topic
*/
public function setTopicTitle($topicTitle)
{
$this->topic_title = $topicTitle;
return $this;
}
/**
* Get topic_title
*
* #return string
*/
public function getTopicTitle()
{
return $this->topic_title;
}
/**
* Set topic_date_add
*
* #param \DateTime $topicDateAdd
* #return Topic
*/
public function setTopicDateAdd($topicDateAdd)
{
$this->topic_date_add = $topicDateAdd;
return $this;
}
/**
* Get topic_date_add
*
* #return \DateTime
*/
public function getTopicDateAdd()
{
return $this->topic_date_add;
}
/**
* Set topic_date_edit
*
* #param \DateTime $topicDateEdit
* #return Topic
*/
public function setTopicDateEdit($topicDateEdit)
{
$this->topic_date_edit = $topicDateEdit;
return $this;
}
/**
* Get topic_date_edit
*
* #return \DateTime
*/
public function getTopicDateEdit()
{
return $this->topic_date_edit;
}
/**
* #ORM\PrePersist
*/
public function setTopicDateAddValue() {
if (!$this->getTopicDateAdd())
{
$this->topic_date_add = new \DateTime();
}
}
/**
* #ORM\PreUpdate
*/
public function setTopicDateEditValue()
{
$this->topic_date_edit = new \DateTime();
}
public function __construct()
{
$this->setTopicDateAdd(new \DateTime());
$this->setTopicDateEdit(new \DateTime());
}
/**
* #ORM\OneToOne(targetEntity="TopicContent", mappedBy="topic", cascade={"persist", "remove"})
*/
private $topicContent;
/**
* Set topicContent
*
* #param \Socialist\ClubBundle\Entity\TopicContent $topicContent
* #return Topic
*/
public function setTopicContent(\Socialist\ClubBundle\Entity\TopicContent $topicContent = null)
{
$this->topicContent = $topicContent;
return $this;
}
/**
* Get topicContent
*
* #return \Socialist\ClubBundle\Entity\TopicContent
*/
public function getTopicContent()
{
return $this->topicContent;
}
}
Topic Entity
public function __construct()
{
$this->topicContent = new \Doctrine\Common\Collections\ArrayCollection();
$this->setTopicDateAdd(new \DateTime());
$this->setTopicDateEdit(new \DateTime());
}
/**
* Set topicContent
*
* #param \Socialist\ClubBundle\Entity\TopicContent $topicContent
* #return Topic
*/
public function setTopicContent(\Socialist\ClubBundle\Entity\TopicContent $topicContent = null)
{
$this->topicContent = $topicContent;
return $this;
}
Topic Controller
public function createAction(Request $request)
{
$entity = new Topic();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('topic_show', array('id' => $entity->getTopicId())));
}
return $this->render('SocialistClubBundle:Topic:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
After persisting your Topic Entity, you will get LastInserted topic id from your Topic entity
for example,
$em = $this->getDoctrine()->getManager();
$topic = new \Acme\TestBundle\Entity\Topic();
$topic->setTopicTitle('Your Title');
$em->persist($topic);
$em->flush(); //insert data into table
If insertion is ok $topic entity hold new row object inserted
You can get new topic id by getting
$newTopicId= $topic->getTopicId();
For Topic content Entity,
$topicContent= new new \Acme\TestBundle\Entity\TopicContent();
$topicContent->setTopicId($newTopicId);
$topicContent->setTopicText('Your topic text');
For avoid more confusion Please change your Topic Content Entity as follows,
namespace Socialist\ClubBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="topic_content")
*/
class TopicContent
{
/**
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*
*/
protected $id;
/**
*
* #ORM\Column(name="topic_text", type="text", nullable=false)
*/
protected $topic_text;
/**
* #ORM\OneToOne(targetEntity="Topic", inversedBy="topicContent", cascade={"persist", "remove"})
* #ORM\JoinColumn(name="topic_id", referencedColumnName="topic_id", onDelete="CASCADE")
*/
private $topic;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set topic_text
*
* #param string $topicText
* #return TopicContent
*/
public function setTopicText($topicText)
{
$this->topic_text = $topicText;
return $this;
}
/**
* Get topic_text
*
* #return string
*/
public function getTopicText()
{
return $this->topic_text;
}
/**
* Set topic
*
* #param \Socialist\ClubBundle\Entity\Topic $topic
* #return TopicContent
*/
public function setTopic(\Socialist\ClubBundle\Entity\Topic $topic = null)
{
$this->topic = $topic;
return $this;
}
/**
* Get topic
*
* #return \Socialist\ClubBundle\Entity\Topic
*/
public function getTopic()
{
return $this->topic;
}
}`
The id should be primary key and autoincrement
this will resolve your all 'topic_id' burdens

error upon flushing an object with array of objects in association

i'm receiving the following error message upon persisting and flushing an object with its associations:
Catchable Fatal Error: Argument 1 passed to
Doctrine\Common\Collections\ArrayCollection::__construct() must be of
the type array, object given, called in
.../vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 519 and defined in
.../vendor/doctrine/common/lib/Doctrine/Common/Collections/ArrayCollection.php line 48
what i have is a single table inheritance with this as the base object:
use Doctrine\ORM\Mapping as ORM;
/**
* ObjectData
*
* #ORM\Table(name="object_data")
* #ORM\Entity(repositoryClass="Edexp\CoreBundle\Entity\ObjectDataRepository")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="entity_name", type="string")
* #ORM\DiscriminatorMap({
* "request" = "Edexp\MessageBundle\Entity\RequestData"
* })
* #ORM\HasLifecycleCallbacks
*/
class ObjectData
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \DateTime
*
* #ORM\Column(name="created_at", type="datetime")
*/
private $created_at;
/**
* #var User
*
* #ORM\OneToMany(targetEntity="User", mappedBy="data")
*/
private $user;
/**
* #var string
*
* #ORM\Column(name="`key`", type="string", length=255)
*/
private $key;
/**
* #var string
*
* #ORM\Column(name="data", type="blob")
*/
private $data;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set created_at
*
* #param \DateTime $createdAt
* #return ObjectData
*/
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 User $user
* #return ObjectData
*/
public function setUser($user)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return User
*/
public function getUser()
{
return $this->user;
}
/**
* Set key
*
* #param string $key
* #return ObjectData
*/
public function setKey($key)
{
$this->key = $key;
return $this;
}
/**
* Get key
*
* #return string
*/
public function getKey()
{
return $this->key;
}
/**
* Set data
*
* #param string $data
* #return ObjectData
*/
public function setData($data)
{
$this->data = $data;
return $this;
}
/**
* Get data
*
* #return string
*/
public function getData()
{
return $this->data;
}
/**
* #ORM\PrePersist
*/
public function prepareForPersist()
{
$this->created_at = new \DateTime();
}
}
and an additional object that inherits from ObjectData:
use Doctrine\ORM\Mapping as ORM;
use MyProject\CoreBundle\Entity\ObjectData;
/**
* RequestData
*
* #ORM\Entity()
*/
class RequestData extends ObjectData
{
/**
* var Request $request
*
* #ORM\ManyToOne(targetEntity="Request", inversedBy="data")
* #ORM\JoinColumn(name="object_id", referencedColumnName="id")
*/
private $request;
/**
* Set request
*
* #param Request $request
* #return RequestData
*/
public function setRequest($request)
{
$this->request = $request;
return $this;
}
/**
* Get request
*
* #return Request
*/
public function getRequest()
{
return $this->request;
}
}
and here's the object that utilizes the RequestData entity:
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Request
*
* #ORM\Table(name="requests")
* #ORM\Entity(repositoryClass="RequestRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Request
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Message $message
*
* #ORM\ManyToOne(targetEntity="Message", inversedBy="requests")
*/
private $message;
/**
* #var RequestType $type
*
* #ORM\ManyToOne(targetEntity="RequestType")
* #ORM\JoinColumn(name="type_id", referencedColumnName="id")
*/
private $type;
/**
* #var ArrayCollection $data
*
* #ORM\OneToMany(
* targetEntity="RequestData",
* mappedBy="request",
* cascade={"persist","remove"}
* )
*/
private $data;
/**
* #var datetime $created_at
*
* #ORM\Column(name="created_at", type="datetime")
*/
private $created_at;
/**
* #var text $comment
*
* #ORM\Column(name="comment", type="text")
*/
private $comment;
/**
* #var ArrayCollection $responses
*
* #ORM\OneToMany(
* targetEntity="Response",
* mappedBy="request",
* cascade={"persist","remove"}
* )
*/
private $responses;
public function __construct()
{
$this->data = new ArrayCollection();
$this->responses = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set message
*
* #param Message $message
*/
public function setMessage($message)
{
$this->message = $message;
}
/**
* Get message
*
* #return Message
*/
public function getMessage()
{
return $this->message;
}
/**
* Set type
*
* #param RequestType $type
*/
public function setType($type)
{
$this->type = $type;
}
/**
* Get type
*
* #return RequestType
*/
public function getType()
{
return $this->type;
}
/**
* Set created_at
*
* #param datetime $createdAt
*/
public function setCreatedAt($createdAt)
{
$this->created_at = $createdAt;
}
/**
* Get created_at
*
* #return datetime
*/
public function getCreatedAt()
{
return $this->created_at;
}
/**
* Set comment
*
* #param text $comment
*/
public function setComment($comment)
{
$this->comment = $comment;
}
/**
* Get comment
*
* #return text
*/
public function getComment()
{
return $this->comment;
}
/**
* Add response
*
* #param Response $response
*/
public function addResponse($response)
{
foreach ( $this->responses as $r ) {
if ( $r->getUser() == $response->getUser() )
return;
}
$this->responses->add($response);
}
/**
* Get responses
*
* #return ArrayCollection
*/
public function getResponses()
{
return $this->responses;
}
public function hasResponse($user)
{
foreach ( $this->responses as $r ) {
if ( $r->getUser() == $user )
return $r;
}
return null;
}
public function addData($data)
{
$data->setRequest($this);
$this->data->add($data);
}
public function getData()
{
return $this->data;
}
/**
* #ORM\PrePersist
*/
public function prePersist()
{
$this->created_at = new \DateTime();
}
}
and finally the code that results in an error:
use MyProject\MessageBundle\Entity\Request as MyRequest;
$data = new RequestData();
$data->setUser($user);
$data->setKey('user_id');
$data->setData(6);
$req = new MyRequest();
$req->setMessage($message);
$req->setComment('bla');
$req->setType($doctrine->getRepository('MessageBundle:RequestType')->find(1));
$req->addData($data);
$em->persist($req);
$em->flush();
any suggestions as to what might be wrong here?
cheers
so here's what i had to do in order to make it work.
i had to change the association in ObjectData from:
#ORM\OneToMany(targetEntity="User", mappedBy="data")
to
#ORM\ManyToOne(targetEntity="User", inversedBy="data")
added the data field to the User entity accordingly.
/**
* #var ArrayCollection $data
*
* #ORM\OneToMany(targetEntity="ObjectData", mappedBy="user")
*/
private $data;
and voila, it worked.
Try:
$req->addData(array($data));
Explanation:
arrayCollection constructor type hints an array as its parameter, so you need to always pass it an array.

Categories