symfony - Akeneo 2.2.8:如何在 akeneo.storage.pre_save 事件中获取原始属性数据?
问题描述
我正在使用 Akeneo 2.2.8 并尝试使用akeneo.storage.pre_save
-event 将原始产品数据与提供的新数据进行比较。我通过订阅akeneo.storage.pre_save
-event 来做到这一点:
在event_subscribers.yml
:
parameters:
vendor.bundle.event_subscriber.product_save.class: Vendor\Bundle\CustomBundle\EventSubscriber\ProductSaveSubscriber
services:
vendor.bundle.event_subscriber.product_save:
class: '%vendor.bundle.event_subscriber.product_save.class%'
arguments:
- '@pim_catalog.repository.product'
tags:
- { name: kernel.event_listener, event: akeneo.storage.pre_save, method: onPreSave, priority: 255 }
在ProductSaveSubscriber.php
:
/**
* @var ProductRepositoryInterface
*/
protected $productRepository;
public function __construct(ProductRepositoryInterface $productRepository)
{
$this->productRepository = $productRepository;
}
public function onPreSave(GenericEvent $event)
{
/** @var Product $subject */
$subject = $event->getSubject();
if ($subject instanceof Product) {
$originalProduct = $this->productRepository->findOneByIdentifier($subject->getIdentifier());
foreach ($subject->getAttributes() as $attribute) {
if ($attribute->getReadOnly()) {
echo "{$attribute->getCode()} : {$subject->getValue($attribute->getCode())}\n";
echo "{$attribute->getCode()} : {$originalProduct->getValue($attribute->getCode())}\n";
}
}
}
}
现在,当我运行此代码时,我希望第二个echo
语句提供原始数据(因为我已经重新加载了该数据)。但是,我从存储库加载的原始产品也有新数据。
这里要注意的另一件事是,如果我添加die()
- 语句,则数据不会存储在数据库中。因此,存储库似乎返回了内存模型或类似的东西。
谁能指出我正确的方向?还是我使用错误的方法将新输入的数据与现有数据进行比较?
解决方案
现在,当我运行此代码时,我希望第二个回显语句提供原始数据(因为我已经重新加载了该数据)。但是,我从存储库加载的原始产品也有新数据。
这可能是因为该对象在学说的工作单元中被引用。因此,当您使用存储库获取您认为是原始对象的内容时,实际上可能与您更新的对象相同。
这里要注意的另一件事是,如果我添加 die() 语句,则数据不会存储在数据库中。因此,存储库似乎返回了内存模型或类似的东西。
这是因为由于您的订阅者正在侦听 PRE_SAVE 事件,因此更新的产品尚未刷新到数据库中。保存产品是这样的:
- 引发 PRE_SAVE 事件
- 提交/刷新
- POST_SAVE 事件抛出
因此,如果您在 PRE_SAVE 事件期间调用 die,则不会调用 COMMIT / FLUSH。
谁能指出我正确的方向?还是我使用错误的方法将新输入的数据与现有数据进行比较?
我不知道您的特定用例,但您可能想要使用查询功能(请参阅https://github.com/akeneo/pim-community-dev/blob/2.2/src/Pim/Bundle/CatalogBundle/Doctrine/ ORM/查询/FindAttributesForFamily.php)。它的目的是直接在数据库中获取您需要的数据(它将是原始值,因为产品尚未在 PRE_SAVE 上刷新到数据库中)
我希望这有帮助。
推荐阅读
- sql - 如何获取每行 SQL 的最新版本?
- python - 我可以要求导入的模块修改 main.py 的全局变量吗?
- javascript - 单击 div 时更改 div 文本和 CSS,并在再次单击时反转更改
- kubernetes - 服务帐户的最佳做法是什么?
- c# - 'Cannot put Window in Style' 错误,即使视图位于 DataTemplate 中
- protractor - 无法读取量角器中的表格元素
- r - 根据 R 中的查找值将值分配给不同的列
- javascript - 从 url 解析 json 文件的 javascript botton 不起作用
- node.js - 协会不适用于 Sequelize
- c# - 低效的 LINQ - 知道 SQL 应该是什么 - 无法到达那里