Skip to content

Commit

Permalink
Merge pull request #2106 from dpfaffenbauer/features/index-messenger
Browse files Browse the repository at this point in the history
[IndexBundle] process Index Messages async
  • Loading branch information
dpfaffenbauer authored Nov 15, 2022
2 parents e7e32b8 + 5c7326d commit cacdad5
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 48 deletions.
5 changes: 5 additions & 0 deletions config/packages/test/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ framework:
handler_id: ~
storage_id: session.storage.mock_file
name: MOCKSESSID
messenger:
transports:
coreshop_index: 'sync://'
routing:
'CoreShop\Bundle\IndexBundle\Messenger\IndexMessage': coreshop_index

monolog:
handlers:
Expand Down
1 change: 1 addition & 0 deletions src/CoreShop/Behat/Context/Setup/PimcoreClassContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Behat\Gherkin\Node\TableNode;
use CoreShop\Behat\Service\ClassStorageInterface;
use CoreShop\Behat\Service\SharedStorageInterface;
use CoreShop\Component\Index\Model\IndexableInterface;
use CoreShop\Component\Pimcore\DataObject\BrickDefinitionUpdate;
use CoreShop\Component\Pimcore\DataObject\ClassUpdate;
use CoreShop\Component\Pimcore\DataObject\ClassUpdateInterface;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,75 +18,48 @@

namespace CoreShop\Bundle\IndexBundle\EventListener;

use CoreShop\Bundle\IndexBundle\Messenger\IndexMessage;
use CoreShop\Component\Index\Model\IndexableInterface;
use CoreShop\Component\Index\Service\IndexUpdaterServiceInterface;
use CoreShop\Component\Pimcore\DataObject\InheritanceHelper;
use Pimcore\Event\Model\DataObjectEvent;
use Pimcore\Event\Model\ElementEventInterface;
use Pimcore\Model\DataObject\AbstractObject;
use Pimcore\Model\DataObject\ClassDefinition;
use Symfony\Component\Messenger\MessageBusInterface;

final class IndexObjectListener
{
private array $validObjectTypes = [AbstractObject::OBJECT_TYPE_OBJECT, AbstractObject::OBJECT_TYPE_VARIANT];

public function __construct(
private IndexUpdaterServiceInterface $indexUpdaterService,
private MessageBusInterface $messageBus,
) {
}

public function onPostUpdate(ElementEventInterface $event): void
{
if ($event instanceof DataObjectEvent) {
$object = $event->getObject();
if (!$event instanceof DataObjectEvent) {
return;
}

if (!$object instanceof IndexableInterface) {
return;
}
$object = $event->getObject();

$isVersionEvent = $event->hasArgument('saveVersionOnly') && true === $event->getArgument('saveVersionOnly');
if (!$object instanceof IndexableInterface) {
return;
}

InheritanceHelper::useInheritedValues(function () use ($object, $isVersionEvent) {
$this->indexUpdaterService->updateIndices($object, $isVersionEvent);
});
$isVersionEvent = $event->hasArgument('saveVersionOnly') && true === $event->getArgument('saveVersionOnly');

$classDefinition = ClassDefinition::getById($object->getClassId());
if ($classDefinition && ($classDefinition->getAllowInherit() || $classDefinition->getAllowVariants())) {
$this->updateInheritableChildren($object, $isVersionEvent);
}
}
$this->messageBus->dispatch(new IndexMessage($object->getId(), $isVersionEvent));
}

private function updateInheritableChildren(AbstractObject $object, bool $isVersionChange): void
public function onPreDelete(ElementEventInterface $event): void
{
if (!$object->hasChildren($this->validObjectTypes)) {
if (!$event instanceof DataObjectEvent) {
return;
}

$children = $object->getChildren($this->validObjectTypes);
/** @var AbstractObject $child */
foreach ($children as $child) {
if ($child instanceof IndexableInterface && $child::class === $object::class) {
InheritanceHelper::useInheritedValues(function () use ($child, $isVersionChange) {
$this->indexUpdaterService->updateIndices($child, $isVersionChange);
});
$this->updateInheritableChildren($child, $isVersionChange);
}
}
}

public function onPostDelete(ElementEventInterface $event): void
{
if ($event instanceof DataObjectEvent) {
$object = $event->getObject();
$object = $event->getObject();

if (!$object instanceof IndexableInterface) {
return;
}

InheritanceHelper::useInheritedValues(function () use ($object) {
$this->indexUpdaterService->removeIndices($object);
});
if (!$object instanceof IndexableInterface) {
return;
}

$this->messageBus->dispatch(new IndexMessage($object->getId(), false, true));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

/*
* CoreShop
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - CoreShop Commercial License (CCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) CoreShop GmbH (https://www.coreshop.org)
* @license https://www.coreshop.org/license GPLv3 and CCL
*
*/

namespace CoreShop\Bundle\IndexBundle\Messenger\Handler;

use CoreShop\Bundle\IndexBundle\Messenger\IndexMessage;
use CoreShop\Component\Index\Model\IndexableInterface;
use CoreShop\Component\Index\Service\IndexUpdaterServiceInterface;
use CoreShop\Component\Pimcore\DataObject\InheritanceHelper;
use Pimcore\Model\DataObject\AbstractObject;
use Pimcore\Model\DataObject\ClassDefinition;
use Pimcore\Model\DataObject\Concrete;
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Symfony\Component\Messenger\MessageBusInterface;

class IndexMessageHandler implements MessageHandlerInterface
{
private array $validObjectTypes = [AbstractObject::OBJECT_TYPE_OBJECT, AbstractObject::OBJECT_TYPE_VARIANT];

public function __construct(
private IndexUpdaterServiceInterface $indexUpdaterService,
private MessageBusInterface $messageBus,
) {
}

public function __invoke(IndexMessage $indexMessage)
{
$indexable = Concrete::getById($indexMessage->getIndexableId());

if (!$indexable instanceof IndexableInterface) {
throw new UnrecoverableMessageHandlingException('Indexable given does not implement IndexableInterface');
}

InheritanceHelper::useInheritedValues(function () use ($indexable, $indexMessage) {
if ($indexMessage->isDelete()) {
$this->indexUpdaterService->removeIndices($indexable);
return;
}

$this->indexUpdaterService->updateIndices($indexable, $indexMessage->isSaveVersionOnly());
});

$classDefinition = ClassDefinition::getById($indexable->getClassId());

if ($classDefinition && ($classDefinition->getAllowInherit() || $classDefinition->getAllowVariants())) {
$this->updateInheritableChildren($indexable, $indexMessage->isSaveVersionOnly());
}
}

private function updateInheritableChildren(AbstractObject $object, bool $isVersionChange): void
{
if (!$object->hasChildren($this->validObjectTypes)) {
return;
}

$children = $object->getChildren($this->validObjectTypes);

foreach ($children as $child) {
if ($child instanceof IndexableInterface && $child::class === $object::class) {
$this->messageBus->dispatch(new IndexMessage($child->getId(), $isVersionChange));
}
}
}
}
45 changes: 45 additions & 0 deletions src/CoreShop/Bundle/IndexBundle/Messenger/IndexMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

/*
* CoreShop
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - CoreShop Commercial License (CCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) CoreShop GmbH (https://www.coreshop.org)
* @license https://www.coreshop.org/license GPLv3 and CCL
*
*/

namespace CoreShop\Bundle\IndexBundle\Messenger;

class IndexMessage
{
public function __construct(
protected int $indexableId,
protected bool $saveVersionOnly = false,
protected bool $isDelete = false,
)
{
}

public function getIndexableId(): int
{
return $this->indexableId;
}

public function isSaveVersionOnly(): bool
{
return $this->saveVersionOnly;
}

public function isDelete(): bool
{
return $this->isDelete;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
imports:
- { resource: admin.yml }
- { resource: messenger.yml }

pimcore:
objects:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
framework:
messenger:
transports:
coreshop_index:
dsn: "doctrine://default?queue_name=coreshop_index"
routing:
'CoreShop\Bundle\IndexBundle\Messenger\IndexMessage': coreshop_index
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ imports:
- { resource: services/pimcore.yml }
- { resource: services/condition_renderer.yml }
- { resource: services/order_renderer.yml }
- { resource: services/messenger.yml }

services:
_defaults:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ services:

CoreShop\Bundle\IndexBundle\EventListener\IndexObjectListener:
arguments:
- '@CoreShop\Component\Index\Service\IndexUpdaterService'
- '@messenger.default_bus'
tags:
- { name: kernel.event_listener, event: pimcore.dataobject.postAdd, method: onPostUpdate }
- { name: kernel.event_listener, event: pimcore.dataobject.postUpdate, method: onPostUpdate }
- { name: kernel.event_listener, event: pimcore.dataobject.postDelete, method: onPostDelete }
- { name: kernel.event_listener, event: pimcore.dataobject.preDelete, method: onPreDelete }

CoreShop\Bundle\IndexBundle\EventListener\UpdateIndexListener:
arguments:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:
_defaults:
autoconfigure: false

CoreShop\Bundle\IndexBundle\Messenger\Handler\IndexMessageHandler:
arguments:
- '@CoreShop\Component\Index\Service\IndexUpdaterServiceInterface'
- '@messenger.default_bus'
tags:
- { name: messenger.message_handler }

0 comments on commit cacdad5

Please sign in to comment.