我正在使用Gdmo SoftDeletable过滤器用于Symfony2和Doctrine(https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/softdeleteable.md)
我也在使用JMSSerializerBundle为我的REST API序列化对JSON的响应。
如何告诉jms序列化程序注释组关于softdeleteable过滤器?
当我的回复包含与deleted_at
字段不为空的实体有关系的实体时,我有错误
Entity of type 'AppBundle\Entity\Courses' for IDs id(2) was not found
因为sub_cources
,示例ID 1与示例ID 2中的courses
有关系,courses
与id 2的关系不是空的deleted_at - 已移除的实体
例子我有
/**
* @ORM\HasLifecycleCallbacks
* @ORM\Table(name="sub_cources")
*@ORM\Entity(repositoryClass="AppBundle\Entity\Repository\SubCoursesRepository")
* @Gedmo\SoftDeleteable(fieldName="deletedAt")
* @AssertBridge\UniqueEntity(
* groups={"post_sub_course", "put_sub_course"},
* fields="name",
* errorPath="not valid",
* message="This name is already in use."
* )
*/
class SubCourses
/**
* @var Courses
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Courses", inversedBy="subCourses")
* @Annotation\Groups({
* "get_sub_courses"
* })
* @Annotation\Type("AppBundle\Entity\Courses")
*/
private $courses;
我的行动
return $this->createSuccessResponse(
[
'sub_courses' => $subCourses->getEntitiesByParams($paramFetcher),
'total' => $subCourses->getEntitiesByParams($paramFetcher, true),
],
['get_sub_courses'],
true
);
我的回答看起来像
/**
* @param $data
* @param null|array $groups
* @param null|bool $withEmptyField
*
* @return View
*/
protected function createSuccessResponse($data, array $groups = null, $withEmptyField = null)
{
$context = SerializationContext::create()->enableMaxDepthChecks();
if ($groups) {
$context->setGroups($groups);
}
if ($withEmptyField) {
$context->setSerializeNull(true);
}
return View::create()
->setStatusCode(self::HTTP_STATUS_CODE_OK)
->setData($data)
->setSerializationContext($context);
}
如何告诉jms序列化程序注释组关于softdeleteable过滤器?
答案 0 :(得分:3)
我使用的解决此问题的方法是使用序列化器事件进行前后序列化。
我做的第一件事是让我的实体实现 \ Gedmo \ SoftDeleteable \ SoftDeleteable 接口。
我创建了一个容器感知的侦听器,并在pre serialize事件上检查了该对象是否可软删除。如果是,那么我禁用了可删除的软过滤器。在后期序列化中,我确保重新打开过滤器。
这仅适用于延迟加载/代理关系。如果您的关系获取设置为 EAGER ,这将无效有效
订户类别:
<?php
namespace AppBundle\Event\Subscriber;
use Gedmo\SoftDeleteable\SoftDeleteable;
use JMS\Serializer\EventDispatcher\EventSubscriberInterface as JmsEventSubscriberInterface;
use JMS\Serializer\EventDispatcher\ObjectEvent;
use Symfony\Component\DependencyInjection\ContainerInterface;
class JsonSerializerSubscriber implements JmsEventSubscriberInterface, EventSubscriberInterface
{
/**
* @var ContainerInterface
*/
protected $container;
public static function getSubscribedEvents()
{
return [
[
'event' => 'serializer.pre_serialize',
'method' => 'onPreSerialize',
],
[
'event' => 'serializer.post_serialize',
'method' => 'onPostSerialize',
],
];
}
public function onPreSerialize(ObjectEvent $objectEvent)
{
// before serializing; turn off soft-deleteable
$object = $objectEvent->getObject();
if ($object instanceof SoftDeleteable) {
$em = $this->container->get('doctrine.orm.default_entity_manager');
if ($em->getFilters()->isEnabled('softdeleteable')) {
$em->getFilters()->disable('softdeleteable');
}
}
}
public function onPostSerialize(ObjectEvent $objectEvent)
{
// after serializing; make sure that softdeletable filter is turned back on
$em = $this->container->get('doctrine.orm.default_entity_manager');
if (!$em->getFilters()->isEnabled('softdeleteable')) {
$em->getFilters()->enable('softdeleteable');
}
}
/**
* @param ContainerInterface $container
*/
public function setContainer(ContainerInterface $container)
{
$this->container = $container;
}
}
services.xml:
<services>
...
<service id="my.serializer.event_subscriber" class="AppBundle\Event\Subscriber\JsonSerializerSubscriber">
<call method="setContainer">
<argument type="service" id="service_container"/>
</call>
<tag name="jms_serializer.event_subscriber" />
</service>
...
</services>
实体类(以op的示例为例):
class SubCourses implements \Gedmo\SoftDeleteable\SoftDeleteable
{
...
}