Transform form field value in Symfony

Viewed 2151

I'm using a table column to store "date_of_creation" (or created_at) in Unix timestamp format (basically an integer with length 11).

In the meanwhile I'd like to treat this value with DateTime format "d-m-Y" in my create/edit webform (Bootstrap Datepicker).

Here is the question:

What's the best way to convert and persist the value passed in DateTime format on a table column which is expecting to receive an integer and, viceversa, override the form field default value "timestamp format" with its corresponding DateTime format (to make it recognisable by DatePicker)?

I'm using Symfony 3.3.5 and Twig.

Here is an example:

I have used a workaround to reach the scope but I am not 100% sure it's a good practice...

The FormType.php add a text field with the class to hook the DatePicker widget:

->add('createdAt', TextType::class, [
            'attr' => [
                'class' => 'js-datepicker'
            ],
        ])

The Entity setter looks like that:

/**
 * @param mixed $createdAt
 */
public function setCreatedAt($createdAt, $stringToTime = true)
{
    $this->createdAt = ($stringToTime) ? strtotime($createdAt) : $createdAt;
}

The real trick here is the extra $stringToTime parameter.

And finally the controllerAction:

/**
 * @Route("/content/edit/{id}", name="admin_content_edit")
 */
public function editContentAction(Request $request, Content $content)
{
    $date = new \DateTime();
    $date->setTimestamp($content->getCreatedAt());
    $content->setCreatedAt($date->format('d-m-Y'), false);

    $form = $this->createForm(ContentType::class, $content);

    $form->handleRequest($request);
    if ($form->isSubmitted()){
        if ($form->isValid()) {

            $content = $form->getData();

            $em = $this->getDoctrine()->getManager();
            $em->persist($content);
            $em->flush();

            $this->addFlash('success', 'Content updated');

            return $this->redirectToRoute('admin_content_show');
        }
    }


    return $this->render('RootgearBundle:Default:editContent.html.twig', array(
        'contentForm' => $form->createView()
    ));
}

The key part is this:

$date = new \DateTime();
$date->setTimestamp($content->getCreatedAt());
$content->setCreatedAt($date->format('d-m-Y'), false);

This is what I have done and it works like a charm. But I don't know if it is the right approach or if there are better solutions.

Thanks in advance for very welcome remarks :)

============= NEW SOLUTION BASED ON SUGGESTION BY Alain Tiemblo

After reading a bit documentation about Data Transformer I finally figured out how to play with my "Date" value

I have applied changes only to my formType class by using CallbackTransformer and addModelTranformer object with closures.

That's the result which work like a charm as well :)

$builder->get('createdAt')
      ->addModelTransformer(new CallbackTransformer(
        function($dateTime) {
          $date = new \DateTime();
          $date->setTimestamp($dateTime);
          return $date->format('d-m-Y');
        },
        function($timestamp) {
          return $timestamp;
        }
      ));
2 Answers
Related