我想为n:m
关系中的实体创建一些虚拟属性。
我有一个User
,一个Achievment
和一个AchievementUser
实体。用户在成就中的值存储在字段value
实体AchievementUser
中。
User -------- 1:n -------- AchievementUser -------- n:1 -------- Achievement
name:String value:Integer name:String
[...] [...]
现在,我想将用户在成就中value
与成就本身一起返回。所以我需要一个虚拟属性和一个getValue()
在Achievement
实体中的方法,但要获取相应的AchievementUser
对象,我需要当前登录用户的 ID。
我怎样才能得到这个?还是有其他可能性来获取成就的用户价值?感谢您的帮助!
编辑:我只有一个基于API的应用程序。只有序列化程序执行 Getter 方法。这是我的序列化程序文件的内容:
virtual_properties:
getValue:
serialized_name: value
type: integer
groups: ['achievement_default']
您可以在成就实体中实现一种方法,并将当前经过身份验证的用户从 twig 模板的控制器传递到该方法中。
use DoctrineCommonCollectionsCriteria;
// ...
/**
* @return Collection
*/
public function getAchievementUsers(User $user)
{
$criteria = Criteria::create()->where(Criteria::expr()->eq('user', $user));
return $this->achievementUsers->matching($criteria);
}
在使用 JMS 序列化程序的情况下,可以通过定义序列化侦听器并注入 TokenStorage 来检索当前经过身份验证的用户,从而使用 getAchievementUsers 方法添加虚拟字段并用数据填充该字段。
<?php
namespace AppBundleListenerSerializer;
...
use JMSSerializerGenericSerializationVisitor;
use JMSSerializerEventDispatcherObjectEvent;
use SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorage;
class AchievementSerializerListener
{
/**
* @var User
*/
protected $currentUser;
/**
* @param TokenStorage $tokenStorage
*/
public function __construct(TokenStorage $tokenStorage)
{
$this->currentUser = $tokenStorage->getToken()->getUser();
}
/**
* @param ObjectEvent $event
*/
public function onAchievementSerialize(ObjectEvent $event)
{
if (!$this->currentUser) {
return;
}
/** @var Achievement $achievement */
$achievement = $event->getObject();
/** @var GenericSerializationVisitor $visitor */
$visitor = $event->getVisitor();
$visitor->setData(
'achievement_users',
$achievement->getAchievementUsers($this->currentUser)
);
}
}
服务.yml
app.listener.serializer.achievement:
class: AppBundleListenerSerializerAchievementSerializerListener
arguments:
- '@security.token_storage'
tags: [ { name: jms_serializer.event_listener, event: serializer.post_serialize, class: AppBundleEntityAchievement, method: onAchievementSerialize } ]