我需要使用Document
模型返回完整回复。我有回应,但没有一些字段,这些字段在实体中定义。例如,我需要回应“广告系列”和“模板”属性 - 但实际上“广告系列”不存在。
以下是我的控制器和实体。
我在我的控制器中有这样的动作:
/**
* @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;
}
但是Document实体有关系:
/**
* 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
出现在$ document响应中。但$document->campaign
缺席。怎么了 ?可能它与某种方式有关serializerGroups
??谢谢你的帮助。
答案 0 :(得分:1)
解决了!谢谢大家的帮助。该问题与JMSSerializer有关。
首先需要在配置文件services.yml
中设置此序列化程序:
app.serializer.listener.document:
class: AppBundle\EventListener\Serializer\DocumentSerializationListener
tags:
- { name: jms_serializer.event_subscriber }
然后创建这个创建表单子字段campaign
并在其中插入Campaign对象的侦听器:
<?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;
}
}
我知道这看起来很奇怪 - 但我发现只有这个解决方案强制将实体插入到表单请求中。