0

Let's say I have the following response coming from an API call:

[
  {
    "AgreementNumber": 20266,
    "StartDate": "2005-07-01T00:00:00",
    "EndDate": "2006-06-30T00:00:00",
    "AgreementTypeId": 1,
    "CfProgramLevelId": 2,
    "TamFlag": 0,
    "ParentAgreementNumber": null,
    "DistributorId": 16,
    "CustomerSiteId": 232,
    "RowId": 100,
    "Source": "Wonderware",
    "ActiveFlg": 1
  },
  ...
]

I am mapping that result to a Agreement entity as follow:

$propertyNameConverter = new PropertyNameConverter();
$encoders              = [new XmlEncoder(), new JsonEncoder()];
$normalizers           = [new ObjectNormalizer(null, $propertyNameConverter), new ArrayDenormalizer(),];
$serializer            = new Serializer($normalizers, $encoders);

$entities = $serializer->deserialize($data, "QuoteBundle\\Entity\\Agreement[]", 'json');

This is how the entity looks like:

class Agreement
{
    /**
     * @var \DateTime
     * @ORM\Column(name="StartDate", type="string", nullable=false)
     */
    private $startDate;

    /**
     * @ORM\OneToOne(targetEntity="QuoteBundle\Entity\AgreementType")
     * @ORM\JoinColumn(name="AgreementTypeID", referencedColumnName="AgreementTypeID")
     */
    private $agreementType;

    /**
     * @param \DateTime $startDate
     */
    public function setStartDate(\DateTime $startDate)
    {
        $this->startDate = $startDate;
    }

    /**
     * @param AgreementType $agreementType
     */
    public function setAgreementType(AgreementType $agreementType)
    {
        $this->agreementType = $agreementType;
    }
}

Each time I try to map the data I got the following error:

Expected argument of type "DateTime", "string" given

And it's fine since I am expecting a DateTime as the startDate. The solution here is to transform|normalize the data before map it to the entity.

I have read here but I can't find how to apply this "callback" to a given property since the example is a simple use case and not a complex one.

I have tried the following code:

$dateTimeNormalizer = new GetSetMethodNormalizer();
$dateTimeCallback   = function ($dateTime) {
    return $dateTime instanceof \DateTime ? $dateTime->format(\DateTime::ATOM) : '';
};

$dateTimeNormalizer->setCallbacks(['startDate' => $dateTimeCallback, 'endDate' => $dateTimeCallback]);

$normalizers = [
    new ObjectNormalizer(null, $propertyNameConverter),
    new ArrayDenormalizer(),
    $dateTimeNormalizer,
];

$serializer = new Serializer($normalizers, $encoders);

But is not working since I am still getting the same error as above. I know there is a DateTimeNormalizer but adding it as a new entry on the $normalizers array doesn't make it to work. The result is the same meaning same error as above.

Also I need a callback to normalize the property AgreementTypeId as agreementType since I am pretty sure it will fails as well. (In fact is not being mapped currently and I think the problem is because a name mismatch)

Can any one help me to figure this out?

ReynierPM
  • 17,594
  • 53
  • 193
  • 363

1 Answers1

1

Answer was few lines below - Recursive Denormalization and Type Safety

    $encoder = new JsonEncoder();

    $normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
    $serializer = new Serializer(array(new DateTimeNormalizer(), $normalizer, new ArrayDenormalizer()), [$encoder]);

    $entities = $serializer->deserialize($data, "QuoteBundle\\Entity\\Agreement[]", 'json');
Michael
  • 26
  • 2