Skip to content

Commit

Permalink
[!!!][FEATURE] Migrate IndexQueue hooks to PSR-14 events
Browse files Browse the repository at this point in the history
More hooks have been removed:

The hook :php:`$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessIndexQueueInitialization']` and its
interface :php:`ApacheSolrForTypo3\Solr\IndexQueue\InitializationPostProcessor` are now superseded
by the PSR-14 event :php:`ApacheSolrForTypo3\Solr\Event\IndexQueue\AfterIndexQueueHasBeenInitializedEvent`

The hook :php:`$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessFetchRecordsForIndexQueueItem']` is now superseded
by the PSR-14 event :php:`ApacheSolrForTypo3\Solr\Event\IndexQueue\AfterRecordsForIndexQueueItemsHaveBeenRetrievedEvent`

Tests have been added and documentation has been adapted.

Fixes: #3666
  • Loading branch information
bmack authored and sfroemkenjw committed Jun 2, 2023
1 parent 4e7970e commit a0e2ba7
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 84 deletions.
31 changes: 11 additions & 20 deletions Classes/Domain/Index/Queue/QueueInitializationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
namespace ApacheSolrForTypo3\Solr\Domain\Index\Queue;

use ApacheSolrForTypo3\Solr\Domain\Site\Site;
use ApacheSolrForTypo3\Solr\IndexQueue\InitializationPostProcessor;
use ApacheSolrForTypo3\Solr\Event\IndexQueue\AfterIndexQueueHasBeenInitializedEvent;
use ApacheSolrForTypo3\Solr\IndexQueue\Initializer\AbstractInitializer;
use ApacheSolrForTypo3\Solr\IndexQueue\Queue;
use Doctrine\DBAL\ConnectionException;
use Doctrine\DBAL\Exception as DBALException;
use Psr\EventDispatcher\EventDispatcherInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use UnexpectedValueException;

/**
* The queue initialization service is responsible to run the initialization of the index queue for a combination of sites
Expand All @@ -36,10 +36,12 @@
class QueueInitializationService
{
protected Queue $queue;
protected EventDispatcherInterface $eventDispatcher;

public function __construct(Queue $queue)
public function __construct(Queue $queue, EventDispatcherInterface $eventDispatcher = null)
{
$this->queue = $queue;
$this->eventDispatcher = $eventDispatcher ?? GeneralUtility::makeInstance(EventDispatcherInterface::class);
}

/**
Expand Down Expand Up @@ -85,6 +87,8 @@ public function initializeBySitesAndConfigurations(array $sites, array $indexing
* Initializes a set of index configurations for a given site.
* If one of the indexing configuration names is a * (wildcard) all configurations are used,
*
* @param array<int, string> $indexingConfigurationNames
* @return array<string, bool>
* @throws ConnectionException
* @throws DBALException
*/
Expand All @@ -97,20 +101,6 @@ public function initializeBySiteAndIndexConfigurations(Site $site, array $indexi
foreach ($indexingConfigurationNames as $indexingConfigurationName) {
$initializationStatus[$indexingConfigurationName] = $this->applyInitialization($site, (string)$indexingConfigurationName);
}

if (!isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessIndexQueueInitialization'])) {
return $initializationStatus;
}

foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessIndexQueueInitialization'] as $classReference) {
$indexQueueInitializationPostProcessor = GeneralUtility::makeInstance($classReference);
if ($indexQueueInitializationPostProcessor instanceof InitializationPostProcessor) {
$indexQueueInitializationPostProcessor->postProcessIndexQueueInitialization($site, $indexingConfigurationNames, $initializationStatus);
} else {
throw new UnexpectedValueException(get_class($indexQueueInitializationPostProcessor) . ' must implement interface ' . InitializationPostProcessor::class, 1345815561);
}
}

return $initializationStatus;
}

Expand All @@ -136,8 +126,6 @@ protected function applyInitialization(Site $site, string $indexingConfiguration

/**
* Executes desired initializer
*
* @throws DBALException
*/
protected function executeInitializer(
Site $site,
Expand All @@ -153,6 +141,9 @@ protected function executeInitializer(
$initializer->setIndexingConfigurationName($indexingConfigurationName);
$initializer->setIndexingConfiguration($indexConfiguration);

return $initializer->initialize();
$isInitialized = $initializer->initialize();
$event = new AfterIndexQueueHasBeenInitializedEvent($initializer, $site, $indexingConfigurationName, $type, $indexConfiguration, $isInitialized);
$event = $this->eventDispatcher->dispatch($event);
return $event->isInitialized();
}
}
23 changes: 7 additions & 16 deletions Classes/Domain/Index/Queue/QueueItemRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
namespace ApacheSolrForTypo3\Solr\Domain\Index\Queue;

use ApacheSolrForTypo3\Solr\Domain\Site\Site;
use ApacheSolrForTypo3\Solr\Event\IndexQueue\AfterRecordsForIndexQueueItemsHaveBeenRetrievedEvent;
use ApacheSolrForTypo3\Solr\IndexQueue\Item;
use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager;
use ApacheSolrForTypo3\Solr\System\Records\AbstractRepository;
use ApacheSolrForTypo3\Solr\System\Util\SiteUtility;
use Doctrine\DBAL\Exception as DBALException;
use PDO;
use Psr\EventDispatcher\EventDispatcherInterface;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
Expand All @@ -38,13 +40,15 @@ class QueueItemRepository extends AbstractRepository
protected string $table = 'tx_solr_indexqueue_item';

protected SolrLogManager $logger;
protected EventDispatcherInterface $eventDispatcher;

public function __construct(SolrLogManager $logManager = null)
public function __construct(SolrLogManager $logManager = null, EventDispatcherInterface $eventDispatcher = null)
{
$this->logger = $logManager ?? GeneralUtility::makeInstance(
SolrLogManager::class,
__CLASS__
);
$this->eventDispatcher = $eventDispatcher ?? GeneralUtility::makeInstance(EventDispatcherInterface::class);
}

/**
Expand Down Expand Up @@ -699,26 +703,13 @@ protected function getAllQueueItemRecordsByUidsGroupedByTable(array $indexQueueI
}

$tableRecords[$table] = $records;
$this->hookPostProcessFetchRecordsForIndexQueueItem($table, $uids, $tableRecords);
$event = $this->eventDispatcher->dispatch(new AfterRecordsForIndexQueueItemsHaveBeenRetrievedEvent($table, $uids, $records));
$tableRecords[$table] = $event->getRecords();
}

return $tableRecords;
}

/**
* Calls defined in postProcessFetchRecordsForIndexQueueItem hook method.
*/
protected function hookPostProcessFetchRecordsForIndexQueueItem(string $table, array $uids, array &$tableRecords): void
{
if (!is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessFetchRecordsForIndexQueueItem'] ?? null)) {
return;
}
$params = ['table' => $table, 'uids' => $uids, 'tableRecords' => &$tableRecords];
foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessFetchRecordsForIndexQueueItem'] as $reference) {
GeneralUtility::callUserFunction($reference, $params, $this);
}
}

/**
* Instantiates a list of Item objects from database records.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

namespace ApacheSolrForTypo3\Solr\Event\IndexQueue;

use ApacheSolrForTypo3\Solr\Domain\Site\Site;
use ApacheSolrForTypo3\Solr\IndexQueue\Initializer\AbstractInitializer;

/**
* PSR-14 Event which is fired after a index queue has been (re-) initialized.
*
* Previously used via $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessIndexQueueInitialization']
* and InitializationPostProcessor interface.
*/
final class AfterIndexQueueHasBeenInitializedEvent
{
public function __construct(
private readonly AbstractInitializer $initializer,
private readonly Site $site,
private readonly string $indexingConfigurationName,
private readonly string $type,
private readonly array $indexingConfiguration,
private bool $isInitialized
) {
}

public function getInitializer(): AbstractInitializer
{
return $this->initializer;
}

public function getSite(): Site
{
return $this->site;
}

public function getIndexingConfigurationName(): string
{
return $this->indexingConfigurationName;
}

public function getType(): string
{
return $this->type;
}

public function getIndexingConfiguration(): array
{
return $this->indexingConfiguration;
}

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

public function setIsInitialized(bool $isInitialized): void
{
$this->isInitialized = $isInitialized;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

namespace ApacheSolrForTypo3\Solr\Event\IndexQueue;

/**
* PSR-14 Event which is fired after DB records have been fetched for the index queue.
*
* Previously used via $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessFetchRecordsForIndexQueueItem']
*/
final class AfterRecordsForIndexQueueItemsHaveBeenRetrievedEvent
{
public function __construct(
private readonly string $table,
private readonly array $uids,
private array $records
) {
}

public function getTable(): string
{
return $this->table;
}

public function getRecordUids(): array
{
return $this->uids;
}

public function getRecords(): array
{
return $this->records;
}

public function setRecords(array $records): void
{
$this->records = $records;
}
}
39 changes: 0 additions & 39 deletions Classes/IndexQueue/InitializationPostProcessor.php

This file was deleted.

10 changes: 10 additions & 0 deletions Documentation/Releases/solr-release-12-0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ The hook :php:`$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['Indexer']['indexP
interface :php:`ApacheSolrForTypo3\Solr\SubstitutePageIndexer` are now superseded
by the PSR-14 event :php:`ApacheSolrForTypo3\Solr\Event\Indexing\AfterPageDocumentIsCreatedForIndexingEvent`.

The hook :php:`$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessIndexQueueInitialization']` and its
interface :php:`ApacheSolrForTypo3\Solr\IndexQueue\InitializationPostProcessor` are now superseded
by the PSR-14 event :php:`ApacheSolrForTypo3\Solr\Event\IndexQueue\AfterIndexQueueHasBeenInitializedEvent`

The hook :php:`$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessFetchRecordsForIndexQueueItem']` is now superseded
by the PSR-14 event :php:`ApacheSolrForTypo3\Solr\Event\IndexQueue\AfterRecordsForIndexQueueItemsHaveBeenRetrievedEvent`

The hook :php:`$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['IndexQueuePageIndexer']['dataUrlModifier']`
and the according interface :php:`ApacheSolrForTypo3\Solr\IndexQueue\PageIndexerDataUrlModifier`
is now superseded by the PSR-14 event :php:`ApacheSolrForTypo3\Solr\Event\Indexing\AfterFrontendPageUriForIndexingHasBeenGeneratedEvent`

Contributors
============
Expand Down
29 changes: 29 additions & 0 deletions Tests/Integration/Domain/Index/Queue/QueueItemRepositoryTest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
Expand All @@ -17,8 +19,10 @@

use ApacheSolrForTypo3\Solr\Domain\Index\Queue\QueueItemRepository;
use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository;
use ApacheSolrForTypo3\Solr\Event\IndexQueue\AfterRecordsForIndexQueueItemsHaveBeenRetrievedEvent;
use ApacheSolrForTypo3\Solr\IndexQueue\Item;
use ApacheSolrForTypo3\Solr\Tests\Integration\IntegrationTest;
use TYPO3\CMS\Core\Tests\Unit\Fixtures\EventDispatcher\MockEventDispatcher;
use TYPO3\CMS\Core\Utility\GeneralUtility;

/**
Expand Down Expand Up @@ -111,6 +115,31 @@ public function canFindItems()
self::assertSame('pages', $firstItem->getType(), 'First item has unexpected type');
}

/**
* @test
*/
public function canFindItemsAndModifyViaEventListener(): void
{
$this->importCSVDataSet(__DIR__ . '/Fixtures/pages_and_news_queueitems.csv');
$eventDispatcher = new MockEventDispatcher();
$queueItemRepository = GeneralUtility::makeInstance(QueueItemRepository::class, null, $eventDispatcher);
$items = $queueItemRepository->findItems([], ['pages']);

/** @var Item $firstItem */
$firstItem = $items[0];
self::assertSame(2, count($items));
self::assertSame('pages', $firstItem->getType(), 'First item has unexpected type');

$eventDispatcher->addListener(function (AfterRecordsForIndexQueueItemsHaveBeenRetrievedEvent $event): void {
if ($event->getTable() === 'pages') {
$event->setRecords([]);
}
});

$items = $queueItemRepository->findItems([], ['pages']);
self::assertCount(0, $items);
}

/**
* @test
*/
Expand Down
Loading

0 comments on commit a0e2ba7

Please sign in to comment.