Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

symfony - Normalize object in a Akeneo EventListener

I'm currently trying to normalize an object (product in this scenario) in an Akeneo Event listener. The main goal is to be able to publish as an event the full edited product on a RabbitMQ queue when a modification occurs.

I'm currently struggling with normalization, I would like to obtain a "flat object" with all the object's fields and value inside but it's doesn't go very well.

I firstly set an event listener in the services configuration: (services.yml)

parameters:
    pim_ce_dev_src_folder_location: '%kernel.project_dir%/vendor/akeneo/pim-community-dev'
services:
    my.listener:
        class: AcmeBundleAppBundleEventListenerProductModificationListener
        arguments:
            - '@swiftmailer.mailer'
            - '@logger'
            - '@pim_catalog.normalizer.standard.product'
        tags:
            - { name: kernel.event_listener, event: akeneo.storage.post_save, method: onPostSave }

And defined the listener service:

<?php

namespace AcmeBundleAppBundleEventListener;

use SymfonyComponentEventDispatcherGenericEvent;
use AkeneoPimEnrichmentComponentProductModelProduct;
use PsrLogLoggerInterface;
use AkeneoPimEnrichmentComponentProductNormalizerStandardProductNormalizer;

class ProductModificationListener
{
    private $mailer;
    private $logger;
    private $normalizer;

    public function __construct(Swift_Mailer $mailer, LoggerInterface $logger, ProductNormalizer $normalizer)
    {
        $this->normalizer = $normalizer;
        $this->mailer = $mailer;
        $this->logger = $logger;
    }

    public function onPostSave(GenericEvent $event)
    {
        $subject = $event->getSubject();

        if (!$subject instanceof Product) {
            // don't do anything if it's not a product
            return;
        }

        $this->logger->info($subject->getId());

        $normalizedObject = $this->normalizer->normalize($subject);
        $this->logger->info($normalizedObject);
    }
}

When I try to normalize the product (after a product edition), I got this error:

[2021-01-27 15:54:54] app.INFO: 1207 [] []
[2021-01-27 15:54:54] app.INFO: 1207 [] []
[2021-01-27 15:54:54] request.CRITICAL: Uncaught PHP Exception SymfonyComponentSerializerExceptionNotNormalizableValueException: "Could not normalize object of type "AkeneoPimEnrichmentComponentProductValueScalarValue", no supporting normalizer found." at /srv/pim/vendor/symfony/serializer/Serializer.php line 178 {"exception":"[object] (Symfony\Component\Serializer\Exception\NotNormalizableValueException(code: 0): Could not normalize object of type "Akeneo\Pim\Enrichment\Component\Product\Value\ScalarValue", no supporting normalizer found. at /srv/pim/vendor/symfony/serializer/Serializer.php:178)"} []
[2021-01-27 15:54:54] request.CRITICAL: Uncaught PHP Exception SymfonyComponentSerializerExceptionNotNormalizableValueException: "Could not normalize object of type "AkeneoPimEnrichmentComponentProductValueScalarValue", no supporting normalizer found." at /srv/pim/vendor/symfony/serializer/Serializer.php line 178 {"exception":"[object] (Symfony\Component\Serializer\Exception\NotNormalizableValueException(code: 0): Could not normalize object of type "Akeneo\Pim\Enrichment\Component\Product\Value\ScalarValue", no supporting normalizer found. at /srv/pim/vendor/symfony/serializer/Serializer.php:178)"} []

Is it the best approach to use normalization and if yes, how can I implement it? (quite sure I'm just missing an argument or something like that)

Thanks a lot!

question from:https://stackoverflow.com/questions/65921036/normalize-object-in-a-akeneo-eventlistener

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

So, I find the good Normalizer, it's the "AkeneoPimEnrichmentComponentProductNormalizerInternalApiProductNormalizer "

That code is working:

parameters:
    pim_ce_dev_src_folder_location: '%kernel.project_dir%/vendor/akeneo/pim-community-dev'
services:
    my.listener:
        class: AcmeBundleAppBundleEventListenerProductModificationListener
        arguments:
            - '@swiftmailer.mailer'
            - '@logger'
            - '@pim_enrich.normalizer.product'
        tags:
            - { name: kernel.event_listener, event: akeneo.storage.post_save, method: onPostSave }
<?php

namespace AcmeBundleAppBundleEventListener;

use SymfonyComponentEventDispatcherGenericEvent;
use AkeneoPimEnrichmentComponentProductModelProduct;
use PsrLogLoggerInterface;
use AkeneoPimEnrichmentComponentProductNormalizerInternalApiProductNormalizer;

class ProductModificationListener
{
    private $mailer;
    private $logger;
    private $normalizer;

    public function __construct(Swift_Mailer $mailer, LoggerInterface $logger, ProductNormalizer $normalizer)
    {
        $this->normalizer = $normalizer;
        $this->mailer = $mailer;
        $this->logger = $logger;
    }

    public function onPostSave(GenericEvent $event)
    {
        $subject = $event->getSubject();

        if (!$subject instanceof Product) {
            // don't do anything if it's not a product
            return;
        }

        $this->logger->info($subject->getId());

        $normalizedObject = $this->normalizer->normalize($subject, 'json');
        $json = json_encode($normalizedObject);
        $this->logger->info($json);
    }
}

And this is the output: https://jsonblob.com/1bd43ac3-60e6-11eb-a1e4-25c2119d0903


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...