Antoine Galluet
Antoine Galluet

Reputation: 320

Pass a timestamp to symfony form in a DataTime field

I have an entity with a DateTime attribute :

/**
 * Poll
 *
 * @ORM\Table(name="poll")
 * @ORM\Entity(repositoryClass="Hubup\CoreBundle\Repository\PollRepository")
 */
class Poll
{


/**
 * @var \DateTime
 *
 * @ORM\Column(name="expiration_date", type="datetime")
 *
 * @Groups({"basic"})
 * @Type("DateTime<'U'>")
 *
 */
    private $expirationDate;
...

With a corresponding form like this :

class PollType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ...
            ->add('expirationDate', DateTimeType::class)
            ...
            ;
    }

I post a request with a json body :

{
    "expirationDate": 1549706072
}

And I want my expirationDate to be mapped as a DateTime like a string date can be.

I tried options like add 'input' => 'timestamp' to the form (described here) but I didn't find a way to make it work.

When I have a case like this I usually get the data from the form and create the DateTime in the controller manually, but I think there is a better way to do it just with form.

Hope I can find help.

Upvotes: 1

Views: 5179

Answers (3)

gabrielrincon
gabrielrincon

Reputation: 896

You have to use a Transform. (https://symfony.com/doc/current/form/data_transformers.html)

  1. You have to set like a NUmberType your field form.

eg.

->add('opening', NumberType::class)

  1. In the form folder make a new folder called DataTransformer

  2. Make a new file called TimestampToDateTimeTransformer.php

and put the next code

<?php

namespace AppBundle\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;

class TimestampToDateTimeTransformer implements DataTransformerInterface
{

    /**
     * @param \DateTime $dateTime
     */
    public function transform($dateTime)
    {
        if($dateTime === null)
        {
            return (new \DateTime('now'))->getTimestamp();
        }
        return $dateTime->getTimestamp();
    }

    public function reverseTransform($timestamp)
    {
        return (new \DateTime())->setTimestamp($timestamp);
    }

}
  1. In the form add in the buildForm to end to method the next code:

    $builder ->get('opening') ->addModelTransformer(new TimestampToDateTimeTransformer()) ;

  2. Thats all.

Thanks very much to: https://codereviewvideos.com/course/beginner-s-guide-to-symfony-3-forms/video/timestamps-on-symfony-forms

He explain very simple!

Upvotes: 4

Tarjei Huse
Tarjei Huse

Reputation: 1291

The problem here is that the Symfony DateTimeType does not use the format options from PHPs date handling, but from ICU, which you can find here: http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax.

Notably missing from that syntax is timestamps.

Thus you got two options:

  1. Create your own Transformer
  2. Use another input format.

Upvotes: 3

Matteo
Matteo

Reputation: 39450

Try something like:

    ->add(expirationDate', DateTimeType::class, [
        'widget' => 'single_text',
        'date_format' => 'U',
    ]);

NB: I use it with:

        'date_format' => "yyyy-MM-dd'T'HH:mm:ss.SSS",

Hope this help

Upvotes: -1

Related Questions