Akeneo 2.2.8:如何获取akeneo.storage.pre_save事件中的原始属性数据?
Akeneo 2.2.8 : How can I get the original attribute data in the akeneo.storage.pre_save event?
我正在使用 Akeneo 2.2.8,我正在尝试使用 akeneo.storage.pre_save
-事件将原始产品数据与提供的新数据进行比较。我通过订阅 akeneo.storage.pre_save
-事件来做到这一点:
在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()
-语句,数据是不会存入数据库的。所以看起来存储库 returns 内存模型或类似的东西。
任何人都可以指出我正确的方向吗?还是我使用了错误的方法来比较新输入的数据和已有的数据?
Now when I run this code, I expect the second echo-statement to give
the original data (since I've loaded that anew). However, the original
product I load from the repository also has the new data.
这可能是因为该对象在学说的工作单元中被引用。因此,当您使用存储库获取您认为是原始对象的内容时,实际上可能是您已更新的同一对象。
Another thing to note here is that if I add a die()-statement, the
data is not stored in the database. So it seems that the repository
returns the in-memory model or something like that.
那是因为您的订阅者正在侦听 PRE_SAVE 事件,更新后的产品尚未刷新到数据库中。以这种方式保存产品:
- PRE_SAVE 事件抛出
- 提交/刷新
- POST_SAVE 事件抛出
因此,如果您在 PRE_SAVE 事件期间调用 die,则不会调用 COMMIT / FLUSH。
Can anyone point me in the right direction? Or am I using the wrong
approach to compare newly-entered data with already existing data?
我不知道您的具体用例,但您可能想使用查询函数(请参阅 https://github.com/akeneo/pim-community-dev/blob/2.2/src/Pim/Bundle/CatalogBundle/Doctrine/ORM/Query/FindAttributesForFamily.php)。它的目的是直接在数据库中获取您需要的数据(它将是原始值,因为产品尚未在 PRE_SAVE 刷新到数据库中)
希望对您有所帮助。
我正在使用 Akeneo 2.2.8,我正在尝试使用 akeneo.storage.pre_save
-事件将原始产品数据与提供的新数据进行比较。我通过订阅 akeneo.storage.pre_save
-事件来做到这一点:
在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()
-语句,数据是不会存入数据库的。所以看起来存储库 returns 内存模型或类似的东西。
任何人都可以指出我正确的方向吗?还是我使用了错误的方法来比较新输入的数据和已有的数据?
Now when I run this code, I expect the second echo-statement to give the original data (since I've loaded that anew). However, the original product I load from the repository also has the new data.
这可能是因为该对象在学说的工作单元中被引用。因此,当您使用存储库获取您认为是原始对象的内容时,实际上可能是您已更新的同一对象。
Another thing to note here is that if I add a die()-statement, the data is not stored in the database. So it seems that the repository returns the in-memory model or something like that.
那是因为您的订阅者正在侦听 PRE_SAVE 事件,更新后的产品尚未刷新到数据库中。以这种方式保存产品:
- PRE_SAVE 事件抛出
- 提交/刷新
- POST_SAVE 事件抛出
因此,如果您在 PRE_SAVE 事件期间调用 die,则不会调用 COMMIT / FLUSH。
Can anyone point me in the right direction? Or am I using the wrong approach to compare newly-entered data with already existing data?
我不知道您的具体用例,但您可能想使用查询函数(请参阅 https://github.com/akeneo/pim-community-dev/blob/2.2/src/Pim/Bundle/CatalogBundle/Doctrine/ORM/Query/FindAttributesForFamily.php)。它的目的是直接在数据库中获取您需要的数据(它将是原始值,因为产品尚未在 PRE_SAVE 刷新到数据库中)
希望对您有所帮助。