我正在使用Gedmo SoftDeletable过滤器来制作Symfony2和Doctrine(https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/softdeleteable.md(
我还使用 JMSSerializerBundle 为我的 REST API 序列化对 JSON 的响应。
如何告诉 jms 序列化程序注释组有关软删除过滤器的信息?
当我的响应包含与字段不为空的实体有关系deleted_at
我有错误
Entity of type 'AppBundleEntityCourses' for IDs id(2) was not found
因为sub_cources
,示例 ID 1 与示例 ID 2 中的courses
有关系,而 ID 为 2 的 courses
没有空deleted_at - 已删除实体
我有的例子
/**
* @ORMHasLifecycleCallbacks
* @ORMTable(name="sub_cources")
*@ORMEntity(repositoryClass="AppBundleEntityRepositorySubCoursesRepository")
* @GedmoSoftDeleteable(fieldName="deletedAt")
* @AssertBridgeUniqueEntity(
* groups={"post_sub_course", "put_sub_course"},
* fields="name",
* errorPath="not valid",
* message="This name is already in use."
* )
*/
class SubCourses
/**
* @var Courses
*
* @ORMManyToOne(targetEntity="AppBundleEntityCourses", inversedBy="subCourses")
* @AnnotationGroups({
* "get_sub_courses"
* })
* @AnnotationType("AppBundleEntityCourses")
*/
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 序列化程序注释组有关软删除过滤器的信息?
我使用的此问题的解决方案是使用序列化程序事件进行序列化前和序列化后。
我做的第一件事是让我的实体实现 \Gedmo\SoftDeleteable\SoftDeleteable 接口。
我创建了一个容器感知侦听器,并在预序列化事件中检查了该对象是否可软删除。 如果是,那么我禁用了软可删除过滤器。在序列化后,我确保过滤器重新打开。
这仅适用于延迟加载/代理关系。 如果您的关系提取设置为 EAGER,这将不起作用
订阅者类:
<?php
namespace AppBundleEventSubscriber;
use GedmoSoftDeleteableSoftDeleteable;
use JMSSerializerEventDispatcherEventSubscriberInterface as JmsEventSubscriberInterface;
use JMSSerializerEventDispatcherObjectEvent;
use SymfonyComponentDependencyInjectionContainerInterface;
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;
}
}
服务.xml:
<services>
...
<service id="my.serializer.event_subscriber" class="AppBundleEventSubscriberJsonSerializerSubscriber">
<call method="setContainer">
<argument type="service" id="service_container"/>
</call>
<tag name="jms_serializer.event_subscriber" />
</service>
...
</services>
实体类(使用 op 的示例(:
class SubCourses implements GedmoSoftDeleteableSoftDeleteable
{
...
}