Skip to content

Commit

Permalink
NGSTACK-836 parent child indexer
Browse files Browse the repository at this point in the history
  • Loading branch information
Katarina Miočić committed Mar 22, 2024
1 parent 9af5bf6 commit 047fd32
Show file tree
Hide file tree
Showing 36 changed files with 1,691 additions and 9 deletions.
13 changes: 13 additions & 0 deletions bundle/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public function getConfigTreeBuilder(): TreeBuilder
$this->addIndexableFieldTypeSection($rootNode);
$this->addSearchResultExtractorSection($rootNode);
$this->addAsynchronousIndexingSection($rootNode);
$this->addParentChildIndexingSection($rootNode);


return $treeBuilder;
}
Expand Down Expand Up @@ -73,4 +75,15 @@ private function addAsynchronousIndexingSection(ArrayNodeDefinition $nodeDefinit
->end()
->end();
}

private function addParentChildIndexingSection(ArrayNodeDefinition $nodeDefinition): void
{
$nodeDefinition
->children()
->booleanNode('use_parent_child_indexing')
->info('Use parent child indexing')
->defaultFalse()
->end()
->end();
}
}
1 change: 1 addition & 0 deletions lib/Container/Compiler/AsynchronousIndexingPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public function process(ContainerBuilder $container): void
->setDecoratedService(CoreContentEventSubscriber::class)
->setArguments([
new Reference('netgen.ibexa_search_extra.asynchronous_indexing.messenger.bus'),
new Reference('ibexa.api.service.location'),
]);

$container
Expand Down
18 changes: 10 additions & 8 deletions lib/Core/Search/Common/EventSubscriber/ContentEventSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Ibexa\Contracts\Core\Repository\Events\Content\PublishVersionEvent;
use Ibexa\Contracts\Core\Repository\Events\Content\RevealContentEvent;
use Ibexa\Contracts\Core\Repository\Events\Content\UpdateContentMetadataEvent;
use Ibexa\Contracts\Core\Repository\LocationService;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\CopyContent;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\DeleteContent;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\DeleteTranslation;
Expand All @@ -25,8 +26,11 @@

class ContentEventSubscriber implements EventSubscriberInterface
{
private array $contentParentLocations = [];
public function __construct(
private readonly MessageBusInterface $messageBus,
private readonly LocationService $locationService,

) {}

public static function getSubscribedEvents(): array
Expand Down Expand Up @@ -55,26 +59,24 @@ public function onCopyContent(CopyContentEvent $event): void

public function onBeforeDeleteContent(BeforeDeleteContentEvent $event): void
{
$contentLocations = $this->locationService->loadLocations($event->getContentInfo());
try {
$event->getContentInfo()->getMainLocation()?->parentLocationId;
foreach ($contentLocations as $contentLocation){
$this->contentParentLocations[] = $contentLocation->parentLocationId;
}
} catch (Throwable) {
// does nothing
}
}

public function onDeleteContent(DeleteContentEvent $event): void
{
try {
$mainLocationParentLocationId = $event->getContentInfo()->getMainLocation()?->parentLocationId;
} catch (Throwable) {
$mainLocationParentLocationId = null;
}

$parentLocationIds = $this->contentParentLocations ?? [];
$this->messageBus->dispatch(
new DeleteContent(
$event->getContentInfo()->id,
$event->getLocations(),
$mainLocationParentLocationId,
$parentLocationIds,
),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ final class DeleteContent
public function __construct(
public readonly int $contentId,
public readonly array $locationIds,
public readonly ?int $mainLocationParentLocationId,
public readonly ?array $parentLocationIds,
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

declare(strict_types=1);

namespace Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\MessageHandler\Search\ParentChildIndexing;

use Netgen\IbexaSearchExtra\Core\Search\Solr\ParentChildReindexAncestorResolver;
use Ibexa\Contracts\Core\Persistence\Content\Handler as ContentHandler;
use Ibexa\Contracts\Core\Persistence\Content\Location;
use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
use Ibexa\Contracts\Core\Search\VersatileHandler;

final class AncestorIndexer
{
public function __construct(
private readonly VersatileHandler $searchHandler,
private readonly ContentHandler $contentHandler,
private readonly ParentChildReindexAncestorResolver $ancestorResolver,
) {}

public function indexSingle(Location $location): void
{
$ancestor = $this->ancestorResolver->resolveAncestor($location);


if ($ancestor === null) {
return;
}

try {
$content = $this->contentHandler->load($ancestor->contentId);
} catch (NotFoundException) {
return;
}

$this->searchHandler->indexContent($content);
$this->searchHandler->indexLocation($ancestor);
}

/**
* @param \Ibexa\Contracts\Core\Persistence\Content\Location $location
*/
public function indexSingleForDeleteContent(Location $location): void
{
$ancestor = $this->ancestorResolver->resolveAncestorForDeleteContent($location);

if ($ancestor === null) {
return;
}

try {
$content = $this->contentHandler->load($ancestor->contentId);
} catch (NotFoundException) {
return;
}

$this->searchHandler->indexContent($content);
$this->searchHandler->indexLocation($ancestor);
}

/**
* @param \Ibexa\Contracts\Core\Persistence\Content\Location[] $locations
*/
public function indexMultiple(array $locations): void
{
foreach ($locations as $location) {
$this->indexSingle($location);
}
}

/***
* @param \Ibexa\Contracts\Core\Persistence\Content\Location[] $locations
*/
public function indexMultipleForDeleteContent(array $locations): void
{
$this->indexMultiple($locations);

foreach ($locations as $location) {
$this->indexSingleForDeleteContent($location);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\MessageHandler\Search\ParentChildIndexing\Content;

use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\MessageHandler\Search\ParentChildIndexing\AncestorIndexer;
use Ibexa\Contracts\Core\Persistence\Content\Location\Handler as LocationHandler;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\CopyContent;

final class CopyContentHandler
{
public function __construct(
private readonly LocationHandler $locationHandler,
private readonly AncestorIndexer $ancestorIndexer,
) {}

public function __invoke(CopyContent $message): void
{
$this->ancestorIndexer->indexMultiple(
$this->locationHandler->loadLocationsByContent(
$message->contentId,
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\MessageHandler\Search\ParentChildIndexing\Content;

use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\MessageHandler\Search\ParentChildIndexing\AncestorIndexer;
use Ibexa\Contracts\Core\Persistence\Content\Location\Handler as LocationHandler;
use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\DeleteContent;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;

use function sprintf;

final class DeleteContentHandler
{
public function __construct(
private readonly LocationHandler $locationHandler,
private readonly AncestorIndexer $ancestorIndexer,
private readonly LoggerInterface $logger = new NullLogger(),
) {}

public function __invoke(DeleteContent $message): void
{
if ($message->parentLocationIds === []) {
$this->logger->info(
sprintf(
'%s: Could not find main Location parent Location ID for deleted Content #%d, aborting',
$this::class,
$message->contentId,
),
);

return;
}
$locations = [];
foreach ($message->parentLocationIds as $locationId) {
try {
$locations[] = $this->locationHandler->load($locationId);
} catch (NotFoundException) {
$this->logger->info(
sprintf(
'%s: Location #%d is gone, aborting',
$this::class,
$locationId,
),
);
}
}
$this->ancestorIndexer->indexMultipleForDeleteContent($locations);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);

namespace Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\MessageHandler\Search\ParentChildIndexing\Content;

use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\MessageHandler\Search\ParentChildIndexing\AncestorIndexer;
use Ibexa\Contracts\Core\Persistence\Content\ContentInfo;
use Ibexa\Contracts\Core\Persistence\Content\Handler as ContentHandler;
use Ibexa\Contracts\Core\Persistence\Content\Location\Handler as LocationHandler;
use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\DeleteTranslation;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

use function sprintf;

final class DeleteTranslationHandler
{
public function __construct(
private readonly ContentHandler $contentHandler,
private readonly LocationHandler $locationHandler,
private readonly AncestorIndexer $ancestorIndexer,
private readonly LoggerInterface $logger = new NullLogger(),
) {}

public function __invoke(DeleteTranslation $message): void
{
try {
$contentInfo = $this->contentHandler->loadContentInfo(
$message->contentId,
);
} catch (NotFoundException) {
$this->logger->info(
sprintf(
'%s: Content #%d is gone, aborting',
$this::class,
$message->contentId,
),
);

return;
}

if ($contentInfo->status !== ContentInfo::STATUS_PUBLISHED) {
return;
}

$this->ancestorIndexer->indexMultiple(
$this->locationHandler->loadLocationsByContent(
$message->contentId,
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\MessageHandler\Search\ParentChildIndexing\Content;

use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\MessageHandler\Search\ParentChildIndexing\AncestorIndexer;
use Ibexa\Contracts\Core\Persistence\Content\Location\Handler as LocationHandler;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\HideContent;

final class HideContentHandler
{
public function __construct(
private readonly LocationHandler $locationHandler,
private readonly AncestorIndexer $ancestorIndexer,
) {}

public function __invoke(HideContent $message): void
{
$this->ancestorIndexer->indexMultiple(
$this->locationHandler->loadLocationsByContent(
$message->contentId,
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\MessageHandler\Search\ParentChildIndexing\Content;

use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\MessageHandler\Search\ParentChildIndexing\AncestorIndexer;
use Ibexa\Contracts\Core\Persistence\Content\Location\Handler as LocationHandler;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\PublishVersion;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

final class PublishVersionHandler
{
public function __construct(
private readonly LocationHandler $locationHandler,
private readonly AncestorIndexer $ancestorIndexer,
) {}

public function __invoke(PublishVersion $message): void
{
$this->ancestorIndexer->indexMultiple(
$this->locationHandler->loadLocationsByContent(
$message->contentId,
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\MessageHandler\Search\ParentChildIndexing\Content;

use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\MessageHandler\Search\ParentChildIndexing\AncestorIndexer;
use Ibexa\Contracts\Core\Persistence\Content\Location\Handler as LocationHandler;
use Netgen\IbexaSearchExtra\Core\Search\Common\Messenger\Message\Search\Content\RevealContent;

final class RevealContentHandler
{
public function __construct(
private readonly LocationHandler $locationHandler,
private readonly AncestorIndexer $ancestorIndexer,
) {}

public function __invoke(RevealContent $message): void
{
$this->ancestorIndexer->indexMultiple(
$this->locationHandler->loadLocationsByContent(
$message->contentId,
),
);
}
}
Loading

0 comments on commit 047fd32

Please sign in to comment.