Symfony formbuilder DateTime shows wrong date - symfony

I want to set the default value of date as current date, but I'm getting 2013.01.01 instead of current date.
$builder->add(
'date',
DateTimeType::class,
[
'input' => 'datetime',
'empty_data'=> new \DateTime(),
'date_format' => 'y-M-d H:i',
'required' => true,])
How to set default date value as the current date when I submit the form? and if I want to edit the form, set that date to the existing value in my entity?

Try to construct new \DateTime() in your entity itself. Since you are not manually entering the current date value, you don't need to add the 'date' field in your form builder.
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="datetime", nullable=false)
*/
private $date;
/**
* YourEntity constructor.
*
*/
public function __construct()
{
$this->setdate(new \DateTime());
}
/**
* Set date
*
* #param \DateTime $date
*
* #return YourEntity
*/
public function setdate($date)
{
$this->date = $date;
return $this;
}

Related

Symfony FormType filed EntityType from two separate Bundles gives error cannot convert to INT

I have interesting problem for forms in Symfony 3.2.14.
Have two bundles AppBundle and UserBundle.
In AppBundle have entity, with appropriate repository, and working formType.
If I create a form which has EntityType::class, field and I'm in AppBundle - form works (generated in controller on action etc.) but If I'm trying to use Entity located in AppBundle in formType created in UserBundle and creating a field in
$builder ->add ('columnName',
EntityType::class, [
'label' => 'Country',
'class' => ProdCountry::class,
'choice_value' => 'id',
'choice_label' => 'name',
'expanded' => false,
'multiple' => false,
])]
- when upgrading or inserting data - have error: AppBundle\Entity\EntityName.php - cannot be converted to INT
in form type - datasource is entity in current UserBundle, and one of fields that I'm trying to fill is just an id from other entity (int in database)
yes, INT not STRING
Post data from form is correct and entity field passes number like 2, or 5 or any different id from db as it is configured in choice_value
and as I have said - EntityType field works fine if it is created in formType in same bundle as entity come from.
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class ProdCountry
* #package AppBundle\Entity
* #ORM\Entity(repositoryClass="AppBundle\Repository\ProdCountryRepository")
* #ORM\Table(name="prod_country")
*/
class ProdCountry
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", options={"comment":"nazwa kraju po polsku", "default":"NULL"})
* #Assert\Valid()
* #Assert\NotBlank()
* #Assert\NotNull()
*/
private $polishCountryName;
/**
* #ORM\Column(type="string", nullable=true)
*/
private $iso3166code;
/**
* #ORM\Column(type="string", nullable=true)
*/
private $internetDomain;
/**
* #ORM\Column(type="string", nullable=true)
*/
private $carCode;
/**
* #ORM\Column(type="string", nullable=true)
*/
private $airplaneCode;
/**
* #ORM\Column(type="integer", nullable=true)
*/
private $phoneCode;
/**
* #ORM\Column(type="integer", nullable=false)
* #Assert\Valid()
* #Assert\NotNull()
* #Assert\NotBlank()
*/
private $orderField;
/**
* #ORM\Column(type="string", options={"comment":"nazwa kraju w języku oryginalnym", "default":"NULL"})
*/
private $nativeCountryName;
/**
* #ORM\Column(type="string", options={"comment":"nazwa kraju w języku angielskim", "default":"NULL"})
*/
private $englishCountryName;
/**
* #return mixed
*/
public function __toString()
{
return (string)$this->id;
}
/**
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* #return mixed
*/
public function getPolishCountryName()
{
return $this->polishCountryName;
}
/**
* #return mixed
*/
public function getIso3166code()
{
return $this->iso3166code;
}
/**
* #return mixed
*/
public function getInternetDomain()
{
return $this->internetDomain;
}
/**
* #return mixed
*/
public function getCarCode()
{
return $this->carCode;
}
/**
* #return mixed
*/
public function getAirplaneCode()
{
return $this->airplaneCode;
}
/**
* #return mixed
*/
public function getPhoneCode()
{
return $this->phoneCode;
}
/**
* #param mixed $polishCountryName
*/
public function setPolishCountryName($polishCountryName)
{
$this->polishCountryName = $polishCountryName;
}
/**
* #param mixed $iso3166code
*/
public function setIso3166code($iso3166code)
{
$this->iso3166code = $iso3166code;
}
/**
* #param mixed $internetDomain
*/
public function setInternetDomain($internetDomain)
{
$this->internetDomain = $internetDomain;
}
/**
* #param mixed $carCode
*/
public function setCarCode($carCode)
{
$this->carCode = $carCode;
}
/**
* #param mixed $airplaneCode
*/
public function setAirplaneCode($airplaneCode)
{
$this->airplaneCode = $airplaneCode;
}
/**
* #param mixed $phoneCode
*/
public function setPhoneCode($phoneCode)
{
$this->phoneCode = $phoneCode;
}
/**
* #return mixed
*/
public function getOrderField()
{
return $this->orderField;
}
/**
* #param mixed $orderField
*/
public function setOrderField($orderField)
{
$this->orderField = $orderField;
}
/**
* #return mixed
*/
public function getNativeCountryName()
{
return $this->nativeCountryName;
}
/**
* #param mixed $nativeCountryName
*/
public function setNativeCountryName($nativeCountryName)
{
$this->nativeCountryName = $nativeCountryName;
}
/**
* #return mixed
*/
public function getEnglishCountryName()
{
return $this->englishCountryName;
}
/**
* #param mixed $englishCountryName
*/
public function setEnglishCountryName($englishCountryName)
{
$this->englishCountryName = $englishCountryName;
}
}
Finally I have found the solution.
No Relation is defined in Entities User and Country
It depends on type of field in form - exactly - EntityType
EntityType::class,
[
'label' => 'userCountry',
'class' => ProdCountry::class,
'choice_value' => 'id', //not needed
'choice_label' => 'yourEntityProdCountryAttribute',
'expanded' => false,
'multiple' => false,
])
When both - Entity and FormType for that entity are in the same bundle - field in the database can be vchar or int and this will work fine.
When Entity is for example in AppBundle, but FormType is in OtherBundle processing the form will cause an error described above.
Solution is to change field in Entity you writing data to as vchar
or change EntityType field in form to ChoiceType
Solution is just to give different names for forms in src/Forms/YourNameFormType.php
by setting
public function getBlockPrefix()
{
return 'your_form_name_ver';
}
it will make any form unique
and then just ask for a proper form in the controler and view

FosRest : Date change is impossible with put method

I'm working on a PUT method which allows user to update his profile. My problem is when I try to update the birthDate field, in the user entity:
/**
* #var \DateTime
*
* #ORM\Column(name="birth_date", type="date", nullable=true)
*
* #Expose
*/
private $birthDate;
With getters and setters:
/**
* Set birthDate
*
* #param \DateTime $birthDate
* #return User
*/
public function setBirthDate(\DateTime $birthDate)
{
$this->birthDate = $birthDate;
return $this;
}
/**
* Get birthDate
*
* #return \DateTime
*/
public function getBirthDate()
{
return $this->birthDate;
}
Here is my controller code sample:
$user = $this->getDoctrine()->getRepository('FTUserBundle:User')->find($user_id);
if(null == $user) {
$view = View::create("User not found", Codes::HTTP_NOT_FOUND);
return $this->handleView($view);
}
$form = $this->createForm(new UserProfileType(), $user, array('method' => 'PUT'));
The error is right here, when createForm is called:
{"error":{"code":500,"message":"Internal Server Error","exception":[{"message":"Unable to transform value for property path \"birthDate\": datefmt_format: string '' is not numeric, which would be required for it to be a valid date: U_ILLEGAL_ARGUMENT_ERROR"
Here's my UserProfileType:
$builder->add('birthDate', 'date', array(
'widget' => 'single_text',
'format' => 'dd-MM-yyyy'
));
The birthDate is correctly set in the database. If I replace the return of the birthDate getter by a static DateTime object, it works fine. When I call the $user->getBirthDate(), before building the form, it returns me a correct DateTime object.
My mistake was in my UserProfileType(). The birthDate field type must be "datetime", and not "date".

symfony2 twig template load checkboxes from many to many entity relationship

New Symfony2 User here. I have 2 entities that are related, one to many that is unidirectional. I'm doing it as ManyToMany as the doctrine documentation suggests, Article(one) and Tags(many). I'd like to have checkboxes show up that show the tag names on the article.new page and the article.edit page. On form submission the id of the tag entity is stored in the article_tags side table that the entity generator created for me.
Posting only relevant code.
Tag Entity AppBundle/Entity/Tag.php
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=20)
*/
public $name;
Article Entity AppBundle/Entity/Article.php
/**
* #ORM\ManyToMany(targetEntity="Tag")
* #ORM\JoinTable(
* name="article_tags",
* joinColumns={#ORM\JoinColumn(name="article_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="tag_id", referencedColumnName="id", unique=true)}
* )
*/
protected $tags;
/**
* Add tag
*
* #param \AppBundle\Entity\Tag $tag
*
* #return Article
*/
public function addTag(\AppBundle\Entity\Tag $tag)
{
$this->tags[] = $tag;
return $this;
}
/**
* Remove tag
*
* #param \AppBundle\Entity\Tag $tag
*/
public function removeTag(\AppBundle\Entity\Tag $tag)
{
$this->tags->removeElement($tag);
}
/**
* Get tags
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTags()
{
return $this->tags;
}
Article Form Type AppBundle/Form/ArticleType
$builder->add('title')
->add('body')
->add('author')
->add('tags', 'entity', array(
'class' => 'AppBundle\Entity\Tag',
'property' => 'name',
'expanded' => 'true', ));
ArticleController AppBundle/Controller/ArticleController.php
* #Template()
*/
public function newAction()
{
$entity = new Article();
$tags = new Tag();
$entity->addTag($tags);
$form = $this->createCreateForm($entity);
return array('entity' => $entity,'form' => $form->createView(), );
}
As of now the error I receive is...
Entities passed to the choice field must be managed. Maybe persist
them in the entity manager?
I'm not entirely sure I'm on the right track. I just want to attach tags to articles!
Thanks
In the controller, you create a blank Tag and add it to the new Article before creating the form. That doesn't make sense to me, and I suspect that's where the error is coming from.
If there are any tags in the database, Symfony will automatically get them and display them with a checkbox in the form. If the user checks a checkbox, this Tag will be added to the Article.
Just delete these two lines and you should be fine:
$tags = new Tag();
$entity->addTag($tags);

Create form with two choices fileds

I want create two choces field like that, because if i generate form i have problem with __toString() method, because i need to fields passed to the function.
/**
* #Route("/transport", name="transportAction")
* #Template("CoreBundle:Goods:transport.html.twig")
*/
public function transportAction()
{
$storageItems = new StorageItems();
$form = $this->createFormBuilder($storageItems)
->add('storageitems_to_deliveries', 'entity', [
'class' => 'ModelBundle:Deliveries',
'choices' => $storageItems->getStorageitemsToDeliveries()
])
->add('storageitems_to_strorage', 'entity', [
'class' => 'ModelBundle:Storages',
'choices' => $this->getDoctrine()->getRepository('ModelBundle:Storages')->findAll(),
//'property'=> 'secondStorage'
])
->getForm();
return array(
'form' => $form->createView()
);
}
In result i have error
Warning: Illegal offset type
What i do wrong? How fixed it?
P.S
class Deliveries
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Items", inversedBy="items_to_deliveries")
* #ORM\JoinColumn(name="items_to_deliveries_id", referencedColumnName="id", nullable=false)
*/
private $deliveries_to_items;
/**
* #ORM\ManyToOne(targetEntity="Workers", inversedBy="workers_to_deliveries")
* #ORM\JoinColumn(name="workers_to_deliveries_id", referencedColumnName="id", nullable=false)
*/
private $deliveries_to_workers;
/**
* #var ArrayCollection
* #ORM\OneToMany(targetEntity="StorageItems", mappedBy="storageitems_to_deliveries", cascade={"remove"})
*/
private $deliveries_to_storageitems;
public function __construct()
{
$this->deliveries_to_storageitems = new ArrayCollection();
}
public function __toString()
{
return $this->deliveries_to_workers;
}
I see three issues here (2 major, 1 minor):
$this->getDoctrine()->getRepository('ModelBundle:Deliveries')
This will return an array of Deliveries objects. Symfony2 has no way of determining the textual representation needed for label, unless you implement __toString() (major)
In addition, array will be numerically indexed. The values for form elements will be 0, 1, etc... This can cause some inexplicable behaviors and headaches along the way. You should consider returning array which uses object ID as it's key. (minor issue)
'data' => ''
Hit this wall a few times. data attribute will override everything and anything, be it a default entity member value or the value that came from Request. Be careful when using it ;) (major)
Hope this helps...

Symfony 2: ManyToMany Relation and Unique Objects

I'm learning SF2 - really impressed with the job done, faced my first real issue I can't solve myself.
I have two entities: Post and Tag. Shortened code below:
class Tag
{
/**
* #ORM\ManyToMany(targetEntity="Post", mappedBy="tags", cascade={"persist"})
*/
private $posts;
public function __construct()
{
$this->posts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #param \My\AppBundle\Entity\Snippet $posts
* #return Tag
*/
public function addSnippet(\My\AppBundle\Entity\Post $posts)
{
$this->posts[] = $posts;
return $this;
}
/**
* #param \My\AppBundle\Entity\Snippet $snippets
*/
public function removeSnippet(\My\AppBundle\Entity\Post $posts)
{
$this->posts->removeElement($posts);
}
/**
* #return \Doctrine\Common\Collections\Collection
*/
public function getSnippets()
{
return $this->posts;
}
}
class Post
{
/**
* #ORM\ManyToMany(targetEntity="Tag", inversedBy="posts", cascade={"persist"})
* #ORM\JoinTable(name="posts_tags",
* joinColumns={#ORM\JoinColumn(name="post_id", referencedColumnName="id", unique=true, onDelete="cascade")},
* inverseJoinColumns={#ORM\JoinColumn(name="tag_id", referencedColumnName="id", unique=true, onDelete="cascade")}
* )
*/
private $tags;
public function __construct()
{
$this->tags = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #param \My\AppBundle\Entity\Tag $tags
* #return Snippet
*/
public function addTag(\My\AppBundle\Entity\Tag $tags)
{
$this->tags[] = $tags;
return $this;
}
/**
* #param \My\AppBundle\Entity\Tag $tags
*/
public function removeTag(\My\AppBundle\Entity\Tag $tags)
{
$this->tags->removeElement($tags);
}
/**
* #return \Doctrine\Common\Collections\Collection
*/
public function getTags()
{
return $this->tags;
}
}
As you can see I have M:M relation between two entities.
I have also a form to add Post with embedded Tag collection:
$builder
->add('title')
->add('tags', 'collection', array(
'type' => new \My\AppBundle\Form\TagType(),
'allow_add' => true,
'by_reference' => false,
'prototype' => true
))
;
TagType form class:
$builder->add('name');
Everything works as expected. Except one thing: if there's a Tag object with the following name, I'm getting SQLSTATE[23000]: Integrity constraint violation MySQL error which is obvious. If I apply unique validation constraint I can add a tag to post (if it already exists in database).
It's obvious I need to check if following tag does exist in database and add it only if does not, but... how to do it Symfony way?
Any suggestions appreciated!
You can use UniqueEntity to handle this. I can't see your annotations on your tags class, or your declaration of 'name' but if you add something like the below it should give you a unique validation constraint based on name with an optional message to throw back.
/**
* #ORM\Entity
* #UniqueEntity(fields="name", message="This tag name already exists")
*/
class Tag...
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=255, unique=true)
*/
protected $name;

Resources