我有一个具有多个关系的实体,这里有一个简化的示例:
class Api
{
/**
* @ORM\OneToMany(targetEntity="App\Entity\Score", mappedBy="api")
*/
private $scores;
public function __construct()
{
$this->scores = new ArrayCollection();
}
/**
* @ORM\Column(type="string", length=400, nullable=true)
*/
private $apiKey;
/**
* @return mixed
*/
public function getApiKey() {
return $this->apiKey;
}
/**
* @param mixed $apiKey
*/
public function setApiKey( $apiKey ): void {
$this->apiKey = $apiKey;
}
OneToMany的另一面是这样的:
class Score
{
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Api", inversedBy="scores")
* @ORM\JoinColumn(nullable=true)
*/
private $api;
/**
* @ORM\Column(type="decimal", precision=2, scale=5, nullable=true)
*/
private $highScore;
/**
* @return mixed
*/
public function getHighScore()
{
return $this->highScore;
}
/**
* @param mixed $highScore
*/
public function setHighScore($highScore): void
{
$this->highScore= $highScore;
}
所有这些都很好,但是我想对API密钥进行一些简单的加密,所以我使用openssl\u encrypt和openssl\u decrypt在编码时将iv存储在API表中,以便能够解码。为了自动执行此操作,我设置了一个EventListener,如下所示:
class ApiSubscriber implements EventSubscriber
{
private $encryption;
public function __construct(Encryption $encryption) {
$this->encryption = $encryption;
}
public function getSubscribedEvents()
{
return array(
'prePersist',
'preUpdate',
'postLoad'
);
}
public function prePersist(LifecycleEventArgs $args)
{
$this->index($args);
}
public function preUpdate(LifecycleEventArgs $args)
{
$this->index($args);
}
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getObject();
if ($entity instanceof Api) {
$apiSecret = $entity->getApiSecret();
$iv = $entity->getIv();
$encodedSecret = $this->encryption->decrypt($apiSecret, $iv);
$entity->setApiSecret($encodedSecret);
}
}
public function index(LifecycleEventArgs $args)
{
$entity = $args->getObject();
if ($entity instanceof Api) {
$apiSecret = $entity->getApiKey();
$encodedSecret = $this->encryption->encrypt($apiSecret);
$entity->setApiSecret($encodedSecret['encodedString']);
$entity->setIv($encodedSecret['iv']);
if($encodedSecret['success'])
{
$entity->setApiKey($encodedSecret['encodedString']);
$entity->setIv($encodedSecret['iv']);
}
}
}
}
同样,所有这些都非常好,但是当我更新分数实体时,我的问题来了。看起来似乎是因为它与Api有多通关系,所以会调用订阅者并使用新的iv密钥将ApiKey更新为新的编码值。
这通常很好,但我需要在CLI命令中使用它,它在Api实体中循环并使用它们调用Api服务,但此更新会导致循环使用旧的过时信息并失败。
您知道如何仅在直接修改Api实体时调用订阅者,而不是与之有关系的实体吗?