Answer the question
In order to leave comments, you need to log in
How to work with custom serialization/normalization?
Based on my previous question, I want to clarify how it is correct.
There is a NearEarthObject entity and a PaginatedCollection pagination class that stores an array of these entities.
If I created a normalizer for PaginatedCollection and called serialization in the controller like
$serializer = new Serializer([new PaginatedCollectionNormalizer], [new JsonEncoder]);
$serializer->serialize($paginatedCollection);
{
"items": [
{
"id": 39,
"name": "523707 (2014 JM25)",
"reference": 2523707,
"speed": 11950.225447854,
"is_hazardous": false,
"date": {
"date": "2020-08-08 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
}
},
{
"id": 49,
"name": "9162 Kwiila (1987 OA)",
"reference": 2009162,
"speed": 81164.553763328,
"is_hazardous": false,
"date": {
"date": "2020-08-07 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
}
},
{
"id": 53,
"name": "468730 (2010 MN51)",
"reference": 2468730,
"speed": 58929.965618653,
"is_hazardous": false,
"date": {
"date": "2020-08-06 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
}
},
{
"id": 54,
"name": "510073 (2010 JF88)",
"reference": 2510073,
"speed": 62117.643247045,
"is_hazardous": false,
"date": {
"date": "2020-08-06 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
}
},
{
"id": 68,
"name": "494713 (2005 OU2)",
"reference": 2494713,
"speed": 78875.305112096,
"is_hazardous": false,
"date": {
"date": "2020-08-05 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
}
},
{
"id": 70,
"name": "228502 (2001 TE2)",
"reference": 2228502,
"speed": 64971.943374331,
"is_hazardous": false,
"date": {
"date": "2020-08-05 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
}
},
{
"id": 71,
"name": "36284 (2000 DM8)",
"reference": 2036284,
"speed": 109370.58384093,
"is_hazardous": false,
"date": {
"date": "2020-08-04 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
}
},
{
"id": 72,
"name": "(2002 CB19)",
"reference": 3114030,
"speed": 32990.860071831,
"is_hazardous": false,
"date": {
"date": "2020-08-04 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
}
},
{
"id": 74,
"name": "68347 (2001 KB67)",
"reference": 2068347,
"speed": 34199.451888508,
"is_hazardous": true,
"date": {
"date": "2020-08-04 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
}
},
{
"id": 82,
"name": "512245 (2016 AU8)",
"reference": 2512245,
"speed": 32235.678141793,
"is_hazardous": false,
"date": {
"date": "2020-08-03 00:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
}
}
],
"total": 66,
"count": 10,
"links": {
"self": "/neo/hazardous?page=1",
"first": "/neo/hazardous?page=1",
"last": "/neo/hazardous?page=7",
"next": "/neo/hazardous?page=2"
}
}
Answer the question
In order to leave comments, you need to log in
Many thanks to BoShurik for commenting on the package symfony/property-info
Solution for non-serializable nested elements inside an object:
Install all packages
symfony/serializer
symfony/property-access
symfony/property-info
phpdocumentor/reflection-docblock
<?php
namespace App\Pagination;
use App\Entity\NearEarthObject;
class PaginatedCollection
{
/**
* @param NearEarthObject[] $items
*/
private $items;
...
$extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]);
$converter = new CamelCaseToSnakeCaseNameConverter();
$normalizers = [
new DateTimeNormalizer([DateTimeNormalizer::FORMAT_KEY => 'Y-m-d']),
new ArrayDenormalizer(),
new ObjectNormalizer(null, $converter, null, $extractor),
];
$encoders = [new JsonEncoder()];
$serializer = new Serializer($normalizers, $encoders);
$serializedPaginatedCollection = $serializer->serialize($paginatedCollection, 'json');
<?php
namespace App\Controller;
use App\Entity\NearEarthObject;
use App\Pagination\PaginationFactory;
use App\Repository\NearEarthObjectRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
class NearEarthObjectController extends AbstractController
{
private EntityManagerInterface $entityManager;
/**
* @var PaginationFactory
*/
private $paginationFactory;
public function __construct(EntityManagerInterface $entityManager, PaginationFactory $paginationFactory)
{
$this->entityManager = $entityManager;
$this->paginationFactory = $paginationFactory;
}
/**
* @Route("/neo/hazardous", name="neo_hazardous", methods={"GET"})
*/
public function hazardousAction(Request $request, ObjectNormalizer $objectNormalizer)
{
/**
* @var NearEarthObjectRepository $nearEarthObjectRepository
*/
$nearEarthObjectRepository = $this
->entityManager
->getRepository(NearEarthObject::class);
//TODO: add getting is_hazardous=1
$queryBuilder = $nearEarthObjectRepository->findAllQueryBuilder();
$paginatedCollection = $this
->paginationFactory
->createCollection($queryBuilder, $request, 'neo_hazardous');
$extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]);
$converter = new CamelCaseToSnakeCaseNameConverter();
$normalizers = [
new DateTimeNormalizer([DateTimeNormalizer::FORMAT_KEY => 'Y-m-d']),
new ArrayDenormalizer(),
new ObjectNormalizer(null, $converter, null, $extractor),
];
$encoders = [new JsonEncoder()];
$serializer = new Serializer($normalizers, $encoders);
$serializedPaginatedCollection = $serializer->serialize($paginatedCollection, 'json');
return new Response($serializedPaginatedCollection, 200, [
'Content-Type' => 'application/json',
]);
}
}
symfony/serializer-pack
, then all packages will be installed immediately, the annotation @param NearEarthObject[] $items
is not needed, but a piece$extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]);
$converter = new CamelCaseToSnakeCaseNameConverter();
$normalizers = [
new DateTimeNormalizer([DateTimeNormalizer::FORMAT_KEY => 'Y-m-d']),
new ArrayDenormalizer(),
new ObjectNormalizer(null, $converter, null, $extractor),
];
$encoders = [new JsonEncoder()];
$serializer = new Serializer($normalizers, $encoders);
$serializedPaginatedCollection = $serializer->serialize($paginatedCollection, 'json');
return new Response($serializedPaginatedCollection, 200, [
'Content-Type' => 'application/json',
]);
return $this->json($paginatedCollection);
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question