In my Symfony 3 app, I'm using a normalizer and a serializer to format a result set as JSON. By default all the doctrine Datetimes are rendered in the format:
"maintenanceStart":{
"timezone":{"name":"Australia\/Melbourne",
"location":{"country_code":"AU","latitude":-37.81667,"longitude":144.96666,
"comments":"Victoria"}},
"offset":36000,"timestamp":1372892400}
I can output this in an ISO date format on a per-field basis by setting a callback on the normalizer as follows:
$callback = function ($dateTime) {
return $dateTime instanceof \DateTime ? $dateTime->format ( \DateTime::ISO8601 ) : '';
};
$normalizer->setCallbacks ( array (
'maintenanceStart' => $callback
) );
But I'd like to apply this change to all Timestamps without having to specify each field. Is there a straightforward way to do this?
Entity definition:
/**
* @var \DateTime
*
* @ORM\Column(name="MAINTENANCE_START", type="datetime", nullable=true)
*/
private $maintenanceStart;
Controller code:
public function dataAction(Request $request) {
$doc = $this->get ( 'doctrine' );
$repo = $doc->getRepository ( 'AppBundle:Customer' );
$result = $repo->createQueryBuilder ( 'c' )->getQuery ()->getResult ();
$encoder = new JsonEncoder ();
$normalizer = new GetSetMethodNormalizer ();
$callback = function ($dateTime) {
return $dateTime instanceof \DateTime ? $dateTime->format ( \DateTime::ISO8601 ) : '';
};
$normalizer->setCallbacks ( array (
'maintenanceStart' => $callback
) );
$serializer = new Serializer ( array (
$normalizer, new \AppBundle\DateTimeNormalizer()
), array (
$encoder
) );
$json = $serializer->serialize ( $result, 'json' );
return $this->render ( 'default/data.json.twig', [
'data' => $json,
'base_dir' => realpath ( $this->getParameter ( 'kernel.root_dir' ) . '/..' )
] );
}
In trying to follow the prescribed method (posted here https://stackoverflow.com/a/33149890/403614), I neglected to observe that the Array of Normalizers passed into the Serializer is order-dependent.
So, the problem and fix for my code above is to reverse the order so that the DateTime Normalizer applies first:
$normalizer = new GetSetMethodNormalizer ();
$serializer = new Serializer ( array (
new \AppBundle\DateTimeNormalizer(), $normalizer
), array (
$encoder
) );
You can create your own normalizer, and declare it as a service.
You can use the exact code of the response: https://stackoverflow.com/a/33149890/403614
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With