Cannot Change String To Date Formate in Symfony 2.7 - php

OK, tried to debug this problem for a few days and now i give up.
I have the followig form builder
Builder
->add('passDate', 'hidden', array('data'=>null, 'empty_data'=> date('Y-m-d',strtotime('1950-10-10'))))
->add('TDVLFirstIssue', 'hidden', array('data'=>null, 'empty_data'=> date('Y-m-d',strtotime('1950-10-10'))))
->add('TDVLExpiryDate', 'hidden', array('data'=>null, 'empty_data'=> date('Y-m-d',strtotime('2017-10-10'))));
and this is my entity
/**
* #var \DateTime
*
* #ORM\Column(name="passDate", type="date")
* #Assert\NotBlank()
*/
private $passDate;
/**
* #var \DateTime
*
* #ORM\Column(name="tdvlIssue", type="date")
* #Assert\NotBlank()
*/
private $TDVLFirstIssue;
/**
* #var \DateTime
*
* #Assert\GreaterThan(value = "+1 day midnight", message="Your TDVL require at least 1 month validity.")
* #ORM\Column(name="tdvlExpiry", type="date")
* #Assert\NotBlank()
*/
private $TDVLExpiryDate;
public function setPassDate($passDate)
{
$this->passDate = $passDate;
return $this;
}
/**
* Get passDate
*
* #return \DateTime
*/
public function getPassDate()
{
return $this->passDate;
}
public function setTDVLFirstIssue($tDVLFirstIssue)
{
$this->TDVLFirstIssue = $tDVLFirstIssue;
return $this;
}
/**
* Get tDVLFirstIssue
*
* #return \DateTime
*/
public function getTDVLFirstIssue()
{
return $this->TDVLFirstIssue;
}
**
* Set tDVLExpiryDate
*
* #param \DateTime $tDVLExpiryDate
*
* #return User
*/
public function setTDVLExpiryDate($tDVLExpiryDate)
{
$this->TDVLExpiryDate = $tDVLExpiryDate;
return $this;
}
/**
* Get tDVLExpiryDate
*
* #return \DateTime
*/
public function getTDVLExpiryDate()
{
return $this->TDVLExpiryDate;
}
And here is my controller
$entity = new User();
$form = $this->createSystemUserForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity->setTDVLFirstIssue(date('Y-m-d',strtotime('1950-10-10')));
$entity->setTDVLExpiryDate(date('Y-m-d',strtotime('2018-10-10')));
$entity->setPassDate(date('Y-m-d',strtotime('1950-10-10')));
}
What i am trying to do is i want to pass default date to the database. so i tried with vanilla php format converting function data and format . But when i submit the form, it throw me this error which is
Error: Call to a member function format() on string
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return ($value !== null)
? $value->format($platform->getDateFormatString()) : null;
}
. I understood that $passDate, $TDVLFirstIssue and $TDVLExpiryDate cannot be blank , which defined in entity as NotBlank(). I suspect that it is because of unsuccessful string to date conversion. So can help me about this problem? thanks in advance.
Note: Please take note that i am using symfony 2.7.

I change my builder date as follow and it works.
builder
->add('passDate', 'hidden', array('data'=>null, 'empty_data'=> date_create('1950-10-10')))
->add('TDVLFirstIssue', 'hidden', array('data'=>null, 'empty_data'=> date_create('1950-10-10')))
->add('TDVLExpiryDate', 'hidden', array('data'=>null, 'empty_data'=> date_create('2017-10-10')));
Hope it helps.

Related

Serialization of 'Symfony\Component\HttpFoundation\File\File' is not allowed

I'm making a Symfony project where user can upload a profile picture. I use VichUploaderBundle to manage image uploads.
I've made it in my entity like this :
/**
* #ORM\Entity(repositoryClass=UserRepository::class)
* #Vich\Uploadable
*/
class User implements UserInterface
/**
* #Vich\UploadableField(mapping="image_profile", fileNameProperty="image_profile_name", size="image_profile_size")
*
* #var File
*/
private $image_profile;
/**
* #ORM\Column(type="string", length=255)
*
* #var string
*/
private $image_profile_name;
/**
* #ORM\Column(type="integer")
*
* #var integer
*/
private $image_profile_size;
/**
* #ORM\Column(type="datetime", nullable=true)
*
* #var \DateTime
*/
private $updatedAt;
/**
* #return File
*/
public function getImageProfile()
{
return $this->image_profile;
}
/**
* #param File $image_profile
*/
public function setImageProfile(File $image_profile = null): void
{
$this->image_profile = $image_profile;
if (null !== $this->image_profile) {
// 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 \DateTimeImmutable();
}
}
/**
* #return string
*/
public function getImageProfileName(): string
{
return $this->image_profile_name;
}
/**
* #param string $image_profile_name
*/
public function setImageProfileName(string $image_profile_name): void
{
$this->image_profile_name = $image_profile_name;
}
/**
* #return \DateTime
*/
public function getUpdatedAt(): \DateTime
{
return $this->updatedAt;
}
/**
* #param \DateTime $updatedAt
*/
public function setUpdatedAt(\DateTime $updatedAt): void
{
$this->updatedAt = $updatedAt;
}
/**
* #return int
*/
public function getImageProfileSize(): int
{
return $this->image_profile_size;
}
/**
* #param int $image_profile_size
*/
public function setImageProfileSize(int $image_profile_size): void
{
$this->image_profile_size = $image_profile_size;
}
But when my user want to upload a new profile picte the following error appear :
Serialization of 'Symfony\Component\HttpFoundation\File\File' is not
allowed
What I don't understand is that the upload works well the new image is uploaded correctly even with the error.
To fix it I've tried to write the following searialize methods :
public function __serialize(): array
{
return [
'id' => $this->id,
'email' => $this->email,
'image_profile' => $this->image_profile,
];
}
public function __unserialize(array $serialized): User
{
$this->id = $serialized['id'];
$this->email = $serialized['email'];
$this->image_profile = $serialized['image_profile'];
return $this;
}
But even with this the error still persist.. Do you have any idea about what's wrong ? Thanks a lot.

Add new field to table and Edit Form Symfony

I am new to Symfony and have inherited a project that was originally php custom and is now half and half with Symfony 3.
I have very little knowledge of Symfony but work a good amount in php.
I wanted to add a field to the products table named "majoritem"
I have added majoritem to the Products class, added it to the form builder, added it to the table through phpmyadmin.
I can see the new form item when the app builds the form.
If I change the field in the database manually it does not reflect in the form.
My assumption is I am not binding the field to a form field?
Any help would be much appreciated.
In the form builder I have the following now (shortened..):
public function buildForm(FormBuilderInterface $builder, array $options)
{
$companyId = $builder->getData()->getCompanyId();
$builder
->add('productCode')
->add('name')
->add('productType', ChoiceType::class, [
'choices' => [
'Primary' => 'Primary',
'Secondary' => 'Secondary'
]
])
->add('majoritem', ChoiceType::class, [
'choices' => [
'No' => '0',
'Yes' => '1'
]
])
]);
}
The Update action for the form is as follows:
public function updateAction(Request $request, $productId)
{
$product = $this->getDoctrine()->getRepository('EcoModelBundle:Products')
->find($productId);
if (!$product)
{
throw new NotFoundHttpException('The requested product could not be found');
}
$form = $this->createForm(ProductsType::class, $product);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
{
$product = $form->getData();
try
{
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();
$request->getSession()->getFlashBag()->add('success', 'Product updated successfully');
}
catch (\Exception $e)
{
$request->getSession()->getFlashBag()->add('error', 'There was an error while saving the product. '
. $e->getMessage());
}
}
else if ($form->isSubmitted() && !$form->isValid())
{
$request->getSession()->getFlashBag()->add('error', 'The submitted data is invalid');
}
return $this->render('#EcoProducts/Product/update.html.twig', [
'product' => $product,
'form' => $form->createView()
]);
}
Finally, the Products class is as follows:
class Products
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var integer
*
* #ORM\Column(name="company_id", type="integer", nullable=false)
*/
private $companyId;
/**
* #var string
*
* #ORM\Column(name="product_code", type="string", length=255, nullable=false)
*/
private $productCode;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=100, nullable=false)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="description", type="text", length=65535, nullable=false)
*/
private $description;
/**
* #var integer
*
* #ORM\Column(name="majoritem", type="integer", nullable=false)
*/
private $majoritem;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set companyId
*
* #param integer $companyId
*
* #return Products
*/
public function setCompanyId($companyId)
{
$this->companyId = $companyId;
return $this;
}
/**
* Get companyId
*
* #return integer
*/
public function getCompanyId()
{
return $this->companyId;
}
/**
* Set productCode
*
* #param string $productCode
*
* #return Products
*/
public function setProductCode($productCode)
{
$this->productCode = $productCode;
return $this;
}
/**
* Get productCode
*
* #return string
*/
public function getProductCode()
{
return $this->productCode;
}
/**
* Set name
*
* #param string $name
*
* #return Products
*/
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 Products
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set majoritem
*
* #param integer $majoritem
*
* #return Products
*/
public function setMajoritem($majoritem)
{
$this->majoritem = $majoritem;
return $this;
}
/**
* Get majoritem
*
* #return integer
*/
public function getMajoritem()
{
return $this->majoritem;
}
/**
* Constructor
*/
public function __construct()
{
$this->details = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add detail
*
* #param \EcoModelBundle\Entity\ProjectDetails $detail
*
* #return Products
*/
public function addDetail(\EcoModelBundle\Entity\ProjectDetails $detail)
{
$this->details[] = $detail;
return $this;
}
/**
* Remove detail
*
* #param \EcoModelBundle\Entity\ProjectDetails $detail
*/
public function removeDetail(\EcoModelBundle\Entity\ProjectDetails $detail)
{
$this->details->removeElement($detail);
}
/**
* Get details
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getDetails()
{
return $this->details;
}
}
So, interestingly I made a couple of changes..
the following is within my products class
/**
* Set majoritem
*
* #param integer $majoritem
*
* #return Products
*/
public function setMajoritem($majoritem)
{
$this->majoritem = $majoritem;
return $this;
}
/**
* Get majoritem
*
* #return integer
*/
public function getMajoritem()
{
return $this->majoritem;
}
Those do not seem to be working, or at least maybe I should say the getMajoritem is not?
If I change the form field to a simple text field as opposed to a dropdown, the form shows up as blank when the underlying data of the field is a zero.
However if I enter a 1 and submit the form it updates the database field to a 1.
So I am wondering if my issue is actually that the form builder is not retrieving the field value and adding it to the form?
Check if the mapping is correct using doctrine with the following command:
php bin/console doctrine:schema:validate.
If it is correct, you can update the database schema with the schema, which we have previously validated, with the following command:
php bin/console doctrine:schema:update --force.
This will ensure that the mapping is being done through Doctrine and if there is an error in the medium, the ORM Doctrine will take care of notifying you.
Also I suggest that you change the schema by using migrations, check if your project is doing it and maybe you should update the schema through migrations:
php bin/console doctrine:migrations:diff
That will create a file in src/Migrations/Version[timestamp].php
And to update the schema of the database you must do it in the following way:
php bin/console doctrine:migrations:execute --up [timestamp]
And if you want to reverse the schema update you do it with:
php bin/console doctrine:migrations:execute --down [timestamp].
The advantage between using schema:update and migrations is that with the latter you can reverse the schema update operation
Try integer values for your form instead of string values as the mapped field in the entity is of type integer:
->add('majoritem', ChoiceType::class, [
'choices' => [
'No' => 0, // <--- instead of '0'
'Yes' => 1 // <--- instead of '1'
]
])

upgrade symfony from 2.3 to 2.7 issues with form that do not retrieve the entity

I am retrieving the code of an old application that have not been updated for a few years now. Our sysadmin have put the code in a php7 server (it was working correctly on a php5 previously). The code worked quite good. I wanted to make some updates and the first one I did was to upgrade symfony from 2.3 to 2.7.*. And of course, now the problems arise.
I have a form that is correctly rendered (all the fields are OK even the ones from the database). Here is my builer:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('object','text',array(
"required"=>false,
"attr"=>array(
"placeholder"=>"Object"
)
))
->add('date','date',array(
'widget'=>'single_text',
))
->add('contact', 'entity', array(
'label'=>'Contact',
'class'=>'MyApp\AppliBundle\Entity\Contact',
'choice_translation_domain' => true,
'placeholder'=>'initials',
'choice_label' => 'initials',
'multiple'=>true
))
->add('text','redactor',array(
"required"=>false,
"redactor"=>"default"
))
;
}
Here is my controller:
public function editMeetingAction($id,Request $request)
{
$em = $this->getDoctrine()->getManager();
$meeting = $em->getRepository('MyAPPAppliBundle:Meeting')-
>findOneById($id);
$form = $this->createForm(new MeetingType, $meeting);
$form->handleRequest($request);
if ($form->isValid()) {
$em->persist($meeting);
$em->flush();
$this->get('session')->getFlashBag()->add('success', 'Meeting
edited successfully');
return $this->redirect($this-
>generateUrl('myapp_appli_manage_editmeeting', array("id" => $id)));
}
return array(
"form" => $form->createView(),
"id" => $id,
);
}
Now when I try to save the form, I have the following error:
[Syntax Error] line 0, col -1: Error: Expected Literal, got end of string.
[1/2] QueryException: SELECT e FROM MyApp\AppliBundle\Entity\Contact e WHERE
It seems that the app is not able to retrieve the Contact being selected in the form.
I have no idea what is wrong here as it worked correctly in the previous version. I followed the steps in this website to help me with the migration and modified already some fields in the form (placeholder, choices_as_values etc)
https://gist.github.com/mickaelandrieu/5211d0047e7a6fbff925
It would be much appreciated if you could help me.
[EDIT1]: the form was working properly before I updated symfony from 2.3 to 2.7
[EDIT2]: Entity Contact:
<?php
namespace MyApp\AppliBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\EntityRepository;
/**
* Contact
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="MyApp\AppliBundle\Entity\ContactRepository")
*/
class Contact
{
/**
* #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="Email", type="string", length=255)
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="Initials", type="string", length=255)
*/
private $initials;
/**
* #var integer
*
* #ORM\Column(name="id_binome", type="integer")
*/
private $id_binome;
/**
* #var string
*
* #ORM\Column(name="JobTitles", type="string", length=255)
*/
private $jobtitle;
/**
* Tostring method
*
*/
public function __toString()
{
return $this->name;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Contact
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set email
*
* #param string $email
* #return Contact
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set initials
*
* #param string $initials
* #return Contact
*/
public function setInitials($initials)
{
$this->initials = $initials;
return $this;
}
/**
* Get initials
*
* #return string
*/
public function getInitials()
{
return $this->initials;
}
/**
* Get id_binome
*
* #return integer
*/
public function getIdBinome()
{
return $this->id_binome;
}
/**
* Set id_binome
*
* #param integer $id
* #return Contact
*/
public function setIdBinome($id)
{
$this->id_binome = $id;
return $this;
}
/**
* Get jobtitle
*
* #return string
*/
public function getjobtitle()
{
return $this->jobtitle;
}
/**
* Set jobtitle
*
* #param string $jobtitle
* #return Contact
*/
public function setjobtitle($jobtitle)
{
$this->jobtitle = $jobtitle;
return $this;
}
}
class ContactRepository extends EntityRepository
{
public function findEmailBinome($id_binome)
{
$querybuilder = $this->createQueryBuilder("Contact")
->select("Contact.email")
->where("Contact.id = :idbinome")
->setParameter('idbinome',$id_binome)
;
return $querybuilder
->getQuery()
->getSingleResult()
;
}
}
[EDIT getter setter]
/**
* Add contacts
*
* #param \MyApp\AppliBundle\Entity\Contact $contacts
* #return Meeting
*/
public function addContact(\MyApp\AppliBundle\Entity\Contact $contacts)
{
$this->contacts[] = $contacts;
return $this;
}
/**
* Remove contacts
*
* #param \MyApp\AppliBundle\Entity\Contact $contacts
*/
public function removeContact(\MyApp\AppliBundle\Entity\Contact $contacts)
{
$this->contacts->removeElement($contacts);
}
/**
* Get contacts
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getContacts()
{
return $this->contacts;
}
I think I found the solution. As it was a problem related to the db connection I suspected dotrine/orm to be guilty! I update the composer.json by changing :
"doctrine/orm": "=2.2.*"
to
"doctrine/orm": ">=2.2.3"
When I tried composer update doctrine/orm it did not solve the problem. However when I simply tried composer update then my app worked again.
Thanks a lot for your help

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.
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.

Persist an entity and relate it to another entity without persiting the second again

I am building a front-end app with Durandal/Knockoutjs and a web service back-end with Symfony2 and I use Doctrine to access the database.
I have two entities that are in association of one-to-many, like this
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name = "drew_cat_door")
*/
class Door
{
public function __construct()
{
//$this->setAddTime(new \DateTime(date('Y-m-d H:i:s')));
if ($this->getAddTime() == null)
$this->setAddTime(new \DateTime(date('Y-m-d H:i:s')));
else
$this->setUpdateTime(new \DateTime(date('Y-m-d H:i:s')));
}
/**
* #ORM\Id
* #ORM\Column(type = "integer")
* #ORM\GeneratedValue(strategy = "AUTO")
*/
protected $id;
/**
* #ORM\Column(type = "string", length = 30)
*/
protected $name;
/**
* #ORM\ManyToOne(targetEntity = "DoorType", inversedBy = "doors")
* #ORM\JoinColumn(name = "type_id", referencedColumnName = "id")
*/
protected $type;
/**
* #ORM\Column(type = "string", length = 30, nullable = true)
*/
protected $filename;
/**
* #ORM\Column(type = "string", length = 100, nullable = true)
*/
protected $description;
/**
* #ORM\Column(type = "integer", nullable = true)
*/
protected $views;
/**
* #ORM\Column(type = "datetime")
*/
protected $add_time;
/**
* #ORM\Column(type = "datetime", nullable = true)
*/
protected $update_time;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Door
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set filename
*
* #param string $filename
* #return Door
*/
public function setFilename($filename)
{
$this->filename = $filename;
return $this;
}
/**
* Get filename
*
* #return string
*/
public function getFilename()
{
return $this->filename;
}
/**
* Set description
*
* #param string $description
* #return Door
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set views
*
* #param integer $views
* #return Door
*/
public function setViews($views)
{
$this->views = $views;
return $this;
}
/**
* Get views
*
* #return integer
*/
public function getViews()
{
return $this->views;
}
/**
* Set add_time
*
* #param \DateTime $addTime
* #return Door
*/
public function setAddTime($addTime)
{
$this->add_time = $addTime;
return $this;
}
/**
* Get add_time
*
* #return \DateTime
*/
public function getAddTime()
{
return $this->add_time;
}
/**
* Set update_time
*
* #param \DateTime $updateTime
* #return Door
*/
public function setUpdateTime($updateTime)
{
$this->update_time = $updateTime;
return $this;
}
/**
* Get update_time
*
* #return \DateTime
*/
public function getUpdateTime()
{
return $this->update_time;
}
/**
* Set type
*
* #param \Drewkol\AdminBundle\Entity\DoorType $type
* #return Door
*/
public function setType(\Drewkol\AdminBundle\Entity\DoorType $type = null)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* #return \Drewkol\AdminBundle\Entity\DoorType
*/
public function getType()
{
return $this->type;
}
}
/**
* #ORM\Entity
* #ORM\Table(name = "drew_cat_doortype")
*/
class DoorType
{
public function __construct()
{
$this->doors = new ArrayCollection();
if ($this->getAddTime() == null)
$this->setAddTime(new \DateTime(date('Y-m-d H:i:s')));
else
$this->setUpdateTime(new \DateTime(date('Y-m-d H:i:s')));
}
/**
* #ORM\Id
* #ORM\Column(type = "integer")
* #ORM\GeneratedValue
*/
protected $id;
/**
* #ORM\Column(type = "string", length = 30)
*/
protected $name;
/**
* #ORM\OneToMany(targetEntity = "Door", mappedBy = "type")
*/
protected $doors;
/**
* #ORM\Column(type = "datetime")
*/
protected $add_time;
/**
* #ORM\Column(type = "datetime", nullable = true)
*/
protected $update_time;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return DoorType
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set add_time
*
* #param \DateTime $addTime
* #return DoorType
*/
public function setAddTime($addTime)
{
if ($addTime != null)
$this->add_time = $addTime;
return $this;
}
/**
* Get add_time
*
* #return \DateTime
*/
public function getAddTime()
{
return $this->add_time;
}
/**
* Set update_time
*
* #param \DateTime $updateTime
* #return DoorType
*/
public function setUpdateTime($updateTime)
{
$this->update_time = $updateTime;
return $this;
}
/**
* Get update_time
*
* #return \DateTime
*/
public function getUpdateTime()
{
return $this->update_time;
}
/**
* Add doors
*
* #param \Drewkol\AdminBundle\Entity\Door $doors
* #return DoorType
*/
public function addDoor(\Drewkol\AdminBundle\Entity\Door $doors)
{
$this->doors[] = $doors;
return $this;
}
/**
* Remove doors
*
* #param \Drewkol\AdminBundle\Entity\Door $doors
*/
public function removeDoor(\Drewkol\AdminBundle\Entity\Door $doors)
{
$this->doors->removeElement($doors);
}
/**
* Get doors
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getDoors()
{
return $this->doors;
}
}
Sorry for not ommiting any code. As you can see, a Door has a DoorType.
As it is easy, when adding a door, I post a JSON that goes
{"name":"nowe","type":{"id":5,"name":"loluk","add_time":"2013-09-25T01:05:05+0200"},"description":"hehe\n","filename":"hehe.jpg"}
and is a full door entity model with a type that has already been around. When I try to add this entity with doctrine with this code
$json_door = $this->get("request")->getContent();
if (empty($json_door))
return $this->createBadRequestException();
$door = $this->container->get("serializer")
->deserialize($json_door, "Drewkol\\AdminBundle\\Entity\\Door", "json");
$door->setAddTime(new \DateTime(date('Y-m-d H:i:s')));
$manager = $this->getDoctrine()->getManager();
$manager->persist($door);
$manager->flush();
I get an error that says
A new entity was found through the relationship 'Drewkol\AdminBundle\Entity\Door#type' that was not configured to cascade persist operations for entity: Drewkol\AdminBundle\Entity\DoorType#000000002d1b74500000000063b1c8fb. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example #ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'Drewkol\AdminBundle\Entity\DoorType#__toString()' to get a clue.
My question is: what is the most clean and efficient way to add door with a type that has already been added?
Is there any way to tell Doctrine to try and resolve if the type given in the entity being added is already in the database (as it must have been added before) or do I have to fetch and remove the type from the JSON deserialized entity to prevent it from being persisted (with the suggested cascade option) and then fetch the type with Doctrine and then set it as a type of my brand new deserialized door entity so Doctrine is aware of the type? I mean I like the data model generated by knockoutjs and transfered with JSON and it seems to me to be a general drawback not being able to do it the way I presented.
I recommend using the Doctrine prePersist event to handle this. In the prePersist event you need to write some logic that checks the database to determine if the doorType exists.
If it exists, then fetch the doorType from the database and use that instead of the doorType object that was created when you unserialized your knockout JSON.
If it does not exist, persist the doorType that was created from your unserialized knockout JSON and then persist your Door.
http://docs.doctrine-project.org/en/latest/reference/events.html

Categories