Reputation: 552
I need return full response with Document
model. I have response but there are absent some fields, which are defined in entity. For example I need to have in response both 'campaign' and 'template' properties - but actually 'campaign' is absent.
Below are my controller and entity.
I have such action in my controller:
/**
* @REST\View(serializerGroups={"Default", "DocumentDetails"})
* @REST\Get("/{id}", requirements={"id" = "\d+"})
* @ParamConverter("document", class="AppBundle:Document");
*/
public function showAction(Request $request, Document $document)
{
return $document;
}
But the Document entity has relations:
/**
* Document entity
*
* @ORM\Entity(repositoryClass="AppBundle\Repository\DocumentRepository")
* @ORM\Table(name="document")
* @ORM\HasLifecycleCallbacks()
*
* @Serializer\ExclusionPolicy("all")
*/
class Document
{
.......
/**
* @var campaign
* @ORM\ManyToOne(targetEntity="Campaign", inversedBy="documents")
* @ORM\JoinColumn(name="campaign", referencedColumnName="id")
*
* @Serializer\Expose()
*/
protected $campaign; // **THIS FIELD IS ABSENT - WHY !???**
/**
* @var DocumentTemplate Szablon dokumentu
*
* @ORM\ManyToOne(targetEntity="DocumentTemplate")
* @ORM\JoinColumn(name="template_id", referencedColumnName="id")
*
* @Serializer\Expose()
*/
protected $template; // **THIS PROPERTY IS DISPLAYED**
.......
$document->template
is present in $document response. But $document->campaign
is absent. What is wrong ? Probably it is related somehow to serializerGroups
?? Thanks for any help.
Upvotes: 1
Views: 69
Reputation: 552
Solved ! Thanks everyone for the help. The issue was related to JMSSerializer.
There was need to set this serializer in config file services.yml
at first:
app.serializer.listener.document:
class: AppBundle\EventListener\Serializer\DocumentSerializationListener
tags:
- { name: jms_serializer.event_subscriber }
And then create this listener which is creating form child-field campaign
and inserting there Campaign object:
<?php
namespace AppBundle\EventListener\Serializer;
use AppBundle\Entity\Campaign;
use AppBundle\Entity\Document;
use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
use JMS\Serializer\EventDispatcher\ObjectEvent;
class DocumentSerializationListener implements EventSubscriberInterface
{
/**
* @param ObjectEvent $event
* @return void
*/
public function onPostSerialize(ObjectEvent $event)
{
$entity = $event->getObject();
if (!($entity instanceof Document)) {
return ;
}
$groups = $event->getContext()->attributes->get('groups')->getOrElse([]);
if (in_array('DocumentDetails', $groups)) {
$visitor = $event->getVisitor();
$campaign = $this->getCampaignClone($entity->getCampaign());
if ($visitor->hasData('campaign')) {
$visitor->setData('campaign', $campaign);
} else {
$visitor->addData('campaign', $campaign);
}
}
}
/**
* @inheritdoc
*/
public static function getSubscribedEvents()
{
return [
[
'event' => 'serializer.post_serialize',
'class' => 'AppBundle\Entity\Document',
'method' => 'onPostSerialize'
]
];
}
private function getCampaignClone(Campaign $documentCampaign)
{
$campaign = new \stdClass();
$campaign->id = $documentCampaign->getId();
$campaign->title = $documentCampaign->getTitle();
$campaign->status = $documentCampaign->getStatus();
$campaign->rows = $documentCampaign->getRows();
$campaign->createdAt = $documentCampaign->getCreatedAt()->format(DATE_W3C);
$campaign->updatedAt = $documentCampaign->getUpdated()->format(DATE_W3C);
return $campaign;
}
}
This looks weird I know - but this only solution I found to force inserting the Entity into the form request.
Upvotes: 1