symfony - Akeneo 2.2.8 : How can I get the original attribute data in the akeneo. storage.pre_save 事件?

标签 symfony doctrine akeneo

我正在使用 Akeneo 2.2.8,并且尝试使用 akeneo.storage.pre_save 事件将原始产品数据与提供的新数据进行比较。我通过订阅 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() 语句,数据不会存储在数据库中。所以看来存储库返回了内存中模型或类似的东西。

有人能指出我正确的方向吗?或者我是否使用了错误的方法来比较新输入的数据与现有数据?

最佳答案

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.

这可能是因为该对象在 Doctrine 的工作单元中被引用。因此,当您使用存储库来获取您认为是原始对象的内容时,实际上可能是您更新后的同一对象。

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 时尚未刷新到数据库中)

我希望这会有所帮助。

关于symfony - Akeneo 2.2.8 : How can I get the original attribute data in the akeneo. storage.pre_save 事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50910497/

相关文章:

php - 如何映射 Doctrine 实体

php - doctrine2 使用过多的 SQL 查询加载一对多关联

php - 安装错误: Overwrite Akeneo ProductController

Akeneo:克隆产品

hadoop-yarn - Akeneo 安装/NODE_PATH=node_modules not recognized/yarn run webpack Error

php - 是否有使用 Symfony 框架创建新 Controller 的命令?

php - 如何从 Symfony3 的应用程序 Controller 中的包运行命令?

php - 如何在 Doctrine 中使用 CONVERT() 函数 MySQL

php - 如何为 Symfony2 中的所有 Controller 添加一些路由前缀?

php - 自动生成 Doctrine 的 get set 方法