Skip to content

Commit e9d1545

Browse files
authored
[Bug]: Deleting objects/assets does not update generic data index (#204)
* fix: pass correct operation and remove element from index after deletion * add functional test
1 parent d4a0b02 commit e9d1545

File tree

8 files changed

+91
-22
lines changed

8 files changed

+91
-22
lines changed

src/EventSubscriber/AssetIndexUpdateSubscriber.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,6 @@ public function deleteAsset(AssetEvent $event): void
7777
processSynchronously: $this->synchronousProcessing->isEnabled()
7878
)
7979
->commit();
80-
80+
$this->queueMessagesDispatcher->dispatchQueueMessages();
8181
}
8282
}

src/EventSubscriber/DataObjectIndexUpdateSubscriber.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public static function getSubscribedEvents(): array
4747
return [
4848
DataObjectEvents::POST_UPDATE => 'updateDataObject',
4949
DataObjectEvents::POST_ADD => 'updateDataObject',
50-
DataObjectEvents::PRE_DELETE => 'deleteDataObject',
50+
DataObjectEvents::POST_DELETE => 'deleteDataObject',
5151
];
5252
}
5353

src/Service/SearchIndex/IndexQueue/EnqueueService.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,13 +193,14 @@ public function enqueueDocuments(): EnqueueService
193193
*/
194194
public function enqueueRelatedItemsOnUpdate(
195195
ElementInterface $element,
196-
bool $includeElement
196+
bool $includeElement,
197+
string $operation
197198
): void {
198199
$subQuery = $this->typeAdapterService
199200
->getTypeAdapter($element)
200201
->getRelatedItemsOnUpdateQuery(
201202
element: $element,
202-
operation: IndexQueueOperation::UPDATE->value,
203+
operation: $operation,
203204
operationTime: $this->timeService->getCurrentMillisecondTimestamp(),
204205
includeElement: $includeElement,
205206
);

src/Service/SearchIndex/IndexQueue/EnqueueServiceInterface.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ public function enqueueDocuments(): self;
5757
*/
5858
public function enqueueRelatedItemsOnUpdate(
5959
ElementInterface $element,
60-
bool $includeElement
60+
bool $includeElement,
61+
string $operation
6162
): void;
6263

6364
public function dispatchQueueMessages(bool $synchronously = false): void;

src/Service/SearchIndex/IndexQueueService.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public function __construct(
4646
private readonly IndexQueueRepository $indexQueueRepository,
4747
private readonly EnqueueServiceInterface $enqueueService,
4848
private readonly ElementServiceInterface $elementService,
49+
private readonly SearchIndexConfigServiceInterface $searchIndexConfigService
4950
) {
5051
}
5152

@@ -63,7 +64,8 @@ public function updateIndexQueue(
6364

6465
$this->enqueueService->enqueueRelatedItemsOnUpdate(
6566
element: $element,
66-
includeElement: !$processSynchronously
67+
includeElement: !$processSynchronously,
68+
operation: $operation
6769
);
6870

6971
if ($element instanceof Asset) {
@@ -101,10 +103,7 @@ public function handleIndexQueueEntries(array $entries): void
101103
$entry->getElementId(),
102104
$entry->getElementType()
103105
));
104-
$element = $this->elementService->getElementByType($entry->getElementId(), $entry->getElementType());
105-
if ($element) {
106-
$this->doHandleIndexData($element, $entry->getOperation());
107-
}
106+
$this->handleEntryByOperation($entry->getOperation(), $entry);
108107
}
109108

110109
$this->bulkOperationService->commit();
@@ -141,6 +140,23 @@ private function doHandleIndexData(ElementInterface $element, string $operation)
141140
}
142141
}
143142

143+
private function handleEntryByOperation(string $operation, IndexQueue $entry): void
144+
{
145+
if ($operation === IndexQueueOperation::DELETE->value) {
146+
$this->indexService->deleteFromSpecificIndex(
147+
$this->searchIndexConfigService->getIndexName($entry->getElementIndexName()),
148+
$entry->getElementId()
149+
);
150+
151+
return;
152+
}
153+
154+
$element = $this->elementService->getElementByType($entry->getElementId(), $entry->getElementType());
155+
if ($element) {
156+
$this->doHandleIndexData($element, $entry->getOperation());
157+
}
158+
}
159+
144160
/**
145161
* @throws IndexDataException
146162
*/

src/Service/SearchIndex/IndexService/IndexService.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ public function deleteFromIndex(ElementInterface $element): IndexService
105105

106106
$elementId = $element->getId();
107107

108+
return $this->deleteFromSpecificIndex($indexName, $elementId);
109+
}
110+
111+
public function deleteFromSpecificIndex(string $indexName, int $elementId): IndexService
112+
{
108113
$this->bulkOperationService->addDeletion(
109114
$indexName,
110115
$elementId

src/Service/SearchIndex/IndexService/IndexServiceInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,7 @@ public function updateIndexData(ElementInterface $element): IndexService;
3232

3333
public function deleteFromIndex(ElementInterface $element): IndexService;
3434

35+
public function deleteFromSpecificIndex(string $indexName, int $elementId): IndexService;
36+
3537
public function updateAssetDependencies(Asset $asset): array;
3638
}

tests/Functional/SearchIndex/IndexQueueTest.php

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,34 @@
1515

1616
namespace Functional\SearchIndex;
1717

18+
use Codeception\Test\Unit;
19+
use Exception;
1820
use OpenSearch\Common\Exceptions\Missing404Exception;
1921
use Pimcore\Bundle\GenericDataIndexBundle\Enum\SearchIndex\ElementType;
2022
use Pimcore\Bundle\GenericDataIndexBundle\Enum\SearchIndex\IndexName;
2123
use Pimcore\Bundle\GenericDataIndexBundle\Enum\SearchIndex\IndexQueueOperation;
2224
use Pimcore\Bundle\GenericDataIndexBundle\Repository\IndexQueueRepository;
2325
use Pimcore\Bundle\GenericDataIndexBundle\Service\SearchIndex\SearchIndexConfigServiceInterface;
26+
use Pimcore\Bundle\GenericDataIndexBundle\Tests\IndexTester;
2427
use Pimcore\Db;
28+
use Pimcore\Model\Element\ElementInterface;
2529
use Pimcore\Tests\Support\Util\TestHelper;
2630

27-
class IndexQueueTest extends \Codeception\Test\Unit
31+
class IndexQueueTest extends Unit
2832
{
29-
/**
30-
* @var \Pimcore\Bundle\GenericDataIndexBundle\Tests\IndexTester
31-
*/
32-
protected $tester;
33+
protected IndexTester $tester;
34+
35+
private SearchIndexConfigServiceInterface $searchIndexConfigService;
36+
37+
private const ASSET_INDEX_NAME = 'asset';
38+
39+
private const DOCUMENT_INDEX_NAME = 'document';
3340

3441
protected function _before()
3542
{
43+
$this->searchIndexConfigService = $this->tester->grabService(
44+
SearchIndexConfigServiceInterface::class
45+
);
3646
$this->tester->disableSynchronousProcessing();
3747
$this->tester->clearQueue();
3848
}
@@ -94,11 +104,7 @@ public function testIndexQueueRepository(): void
94104

95105
public function testAssetSaveNotEnqueued(): void
96106
{
97-
/**
98-
* @var SearchIndexConfigServiceInterface $searchIndexConfigService
99-
*/
100-
$searchIndexConfigService = $this->tester->grabService(SearchIndexConfigServiceInterface::class);
101-
$indexName = $searchIndexConfigService->getIndexName('asset');
107+
$indexName = $this->searchIndexConfigService->getIndexName(self::ASSET_INDEX_NAME);
102108

103109
$asset = TestHelper::createImageAsset();
104110

@@ -112,7 +118,7 @@ public function testAssetSaveProcessQueue(): void
112118
* @var SearchIndexConfigServiceInterface $searchIndexConfigService
113119
*/
114120
$searchIndexConfigService = $this->tester->grabService(SearchIndexConfigServiceInterface::class);
115-
$indexName = $searchIndexConfigService->getIndexName('asset');
121+
$indexName = $searchIndexConfigService->getIndexName(self::ASSET_INDEX_NAME);
116122

117123
$asset = TestHelper::createImageAsset();
118124

@@ -123,8 +129,46 @@ public function testAssetSaveProcessQueue(): void
123129
)
124130
);
125131

126-
$this->tester->runCommand('messenger:consume', ['--limit'=>2], ['pimcore_generic_data_index_queue']);
132+
$this->consume();
127133
$result = $this->tester->checkIndexEntry($asset->getId(), $indexName);
128134
$this->assertEquals($asset->getId(), $result['_source']['system_fields']['id']);
129135
}
136+
137+
/**
138+
* @throws Exception
139+
*/
140+
public function testElementDeleteWithQueue(): void
141+
{
142+
$this->checkAndDeleteElement(
143+
TestHelper::createImageAsset(),
144+
$this->searchIndexConfigService->getIndexName(self::ASSET_INDEX_NAME)
145+
);
146+
147+
$this->checkAndDeleteElement(
148+
TestHelper::createEmptyDocument(),
149+
$this->searchIndexConfigService->getIndexName(self::DOCUMENT_INDEX_NAME)
150+
);
151+
152+
$object = TestHelper::createEmptyObject('', false);
153+
$this->checkAndDeleteElement(
154+
$object,
155+
$this->searchIndexConfigService->getIndexName($object->getClassName())
156+
);
157+
}
158+
159+
private function checkAndDeleteElement(ElementInterface $element, string $indexName): void
160+
{
161+
$this->consume();
162+
$this->tester->checkIndexEntry($element->getId(), $indexName);
163+
164+
$element->delete();
165+
$this->consume();
166+
$this->expectException(Missing404Exception::class);
167+
$this->tester->checkIndexEntry($element->getId(), $indexName);
168+
}
169+
170+
private function consume(): void
171+
{
172+
$this->tester->runCommand('messenger:consume', ['--limit'=>2], ['pimcore_generic_data_index_queue']);
173+
}
130174
}

0 commit comments

Comments
 (0)