Skip to content

Commit ad25480

Browse files
committed
[BUGFIX] Fix monitoring of mounted pages
EXT:solr fails to detect changes on mounted pages correctly in some special occasions: * mounted pages not considered during garbage removal / ce updates * no_search_sub_entries flag not respected by GarbageRemover strategies * existing queue items of mounted pages not updated By adjusting the monitoring related components the issues are fixed, affected components: * GarbageRemover strategies * page initializer * RecordMonitor * DataUpdateHandler Fixes: #4275 Ports: #4276
1 parent 1f3a281 commit ad25480

File tree

9 files changed

+475
-26
lines changed

9 files changed

+475
-26
lines changed

Classes/Domain/Index/Queue/GarbageRemover/AbstractStrategy.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
use ApacheSolrForTypo3\Solr\IndexQueue\Queue;
2424
use ApacheSolrForTypo3\Solr\IndexQueue\QueueInterface;
2525
use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager;
26+
use ApacheSolrForTypo3\Solr\Traits\SkipRecordByRootlineConfigurationTrait;
2627
use Doctrine\DBAL\Exception as DBALException;
28+
use TYPO3\CMS\Backend\Utility\BackendUtility;
2729
use TYPO3\CMS\Core\Utility\GeneralUtility;
2830
use UnexpectedValueException;
2931

@@ -33,6 +35,8 @@
3335
*/
3436
abstract class AbstractStrategy
3537
{
38+
use SkipRecordByRootlineConfigurationTrait;
39+
3640
protected QueueInterface $queue;
3741
protected ConnectionManager $connectionManager;
3842
protected SiteRepository $siteRepository;
@@ -82,7 +86,15 @@ protected function deleteInSolrAndRemoveFromIndexQueue(string $table, int $uid):
8286
protected function deleteInSolrAndUpdateIndexQueue(string $table, int $uid): void
8387
{
8488
$this->deleteIndexDocuments($table, $uid);
85-
$this->queue->updateItem($table, $uid);
89+
90+
$record = BackendUtility::getRecord($table, $uid);
91+
if ($record === null) {
92+
return;
93+
}
94+
95+
if (!$this->skipRecordByRootlineConfiguration((int)($record['pid'] ?? 0))) {
96+
$this->queue->updateItem($table, $uid);
97+
}
8698
}
8799

88100
/**

Classes/Domain/Index/Queue/GarbageRemover/PageStrategy.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515

1616
namespace ApacheSolrForTypo3\Solr\Domain\Index\Queue\GarbageRemover;
1717

18+
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\RecordMonitor\Helper\MountPagesUpdater;
1819
use ApacheSolrForTypo3\Solr\Domain\Site\Exception\UnexpectedTYPO3SiteInitializationException;
1920
use Doctrine\DBAL\Exception as DBALException;
2021
use TYPO3\CMS\Backend\Utility\BackendUtility;
22+
use TYPO3\CMS\Core\Utility\GeneralUtility;
2123

2224
/**
2325
* Class PageStrategy
@@ -42,6 +44,23 @@ protected function removeGarbageOfByStrategy(string $table, int $uid): void
4244
}
4345
}
4446

47+
/**
48+
* Deletes a page from Solr and updates the item in the index queue
49+
* The MountPagesUpdater takes care of mounted pages
50+
*
51+
* @throws DBALException
52+
* @throws UnexpectedTYPO3SiteInitializationException
53+
*/
54+
protected function deleteInSolrAndUpdateIndexQueue(string $table, int $uid): void
55+
{
56+
parent::deleteInSolrAndUpdateIndexQueue($table, $uid);
57+
58+
if ($table === 'pages') {
59+
$mountPagesUpdater = GeneralUtility::makeInstance(MountPagesUpdater::class);
60+
$mountPagesUpdater->update($uid);
61+
}
62+
}
63+
4564
/**
4665
* Determines the relevant page id for a content element update. Deletes the page from solr and requeues the
4766
* page for a reindex.

Classes/Domain/Index/Queue/UpdateHandler/DataUpdateHandler.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager;
3131
use ApacheSolrForTypo3\Solr\System\Records\Pages\PagesRepository;
3232
use ApacheSolrForTypo3\Solr\System\TCA\TCAService;
33+
use ApacheSolrForTypo3\Solr\Traits\SkipRecordByRootlineConfigurationTrait;
3334
use ApacheSolrForTypo3\Solr\Util;
3435
use Doctrine\DBAL\Exception as DBALException;
3536
use Throwable;
@@ -45,6 +46,8 @@
4546
*/
4647
class DataUpdateHandler extends AbstractUpdateHandler
4748
{
49+
use SkipRecordByRootlineConfigurationTrait;
50+
4851
/**
4952
* List of fields in the update field array that
5053
* are required for processing
@@ -381,7 +384,9 @@ protected function processPageRecord(int $uid, int $pid, array $updatedFields =
381384
}
382385
$rootPageIds = [$configurationPageId];
383386

384-
$this->processRecord('pages', $uid, $rootPageIds);
387+
if (!$this->skipRecordByRootlineConfiguration($uid)) {
388+
$this->processRecord('pages', $uid, $rootPageIds);
389+
}
385390

386391
$this->updateCanonicalPages($uid);
387392
$this->mountPageUpdater->update($uid);

Classes/IndexQueue/Initializer/Page.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Doctrine\DBAL\Exception as DBALException;
2323
use Throwable;
2424
use TYPO3\CMS\Backend\Utility\BackendUtility;
25+
use TYPO3\CMS\Core\Context\Context;
2526
use TYPO3\CMS\Core\Database\Connection;
2627
use TYPO3\CMS\Core\Database\ConnectionPool;
2728
use TYPO3\CMS\Core\Messaging\FlashMessage;
@@ -223,8 +224,22 @@ protected function addMountedPagesToIndexQueue(array $mountedPages, array $mount
223224
{
224225
$mountPointIdentifier = $this->getMountPointIdentifier($mountProperties);
225226
$mountPointPageIsWithExistingQueueEntry = $this->queueItemRepository->findPageIdsOfExistingMountPagesByMountIdentifier($mountPointIdentifier);
226-
$mountedPagesThatNeedToBeAdded = array_diff($mountedPages, $mountPointPageIsWithExistingQueueEntry);
227227

228+
// update existing queue entries to trigger reindexing
229+
array_walk(
230+
$mountPointPageIsWithExistingQueueEntry,
231+
function (int $pageUid): void {
232+
$tstamp = GeneralUtility::makeInstance(Context::class)
233+
->getPropertyFromAspect('date', 'timestamp') ?? time();
234+
$items = $this->queueItemRepository->findItemsByItemTypeAndItemUid('pages', $pageUid);
235+
foreach ($items as $item) {
236+
$this->queueItemRepository->updateChangedTimeByItem($item, $tstamp);
237+
}
238+
}
239+
);
240+
241+
// add new items if necessary
242+
$mountedPagesThatNeedToBeAdded = array_diff($mountedPages, $mountPointPageIsWithExistingQueueEntry);
228243
if (count($mountedPagesThatNeedToBeAdded) === 0) {
229244
//nothing to do
230245
return;

Classes/IndexQueue/RecordMonitor.php

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@
2222
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\Events\RecordUpdatedEvent;
2323
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\UpdateHandler\Events\VersionSwappedEvent;
2424
use ApacheSolrForTypo3\Solr\Traits\SkipMonitoringTrait;
25+
use ApacheSolrForTypo3\Solr\Traits\SkipRecordByRootlineConfigurationTrait;
2526
use ApacheSolrForTypo3\Solr\Util;
2627
use Psr\EventDispatcher\EventDispatcherInterface;
2728
use TYPO3\CMS\Backend\Utility\BackendUtility;
2829
use TYPO3\CMS\Core\DataHandling\DataHandler;
29-
use TYPO3\CMS\Core\Exception\Page\PageNotFoundException;
3030
use TYPO3\CMS\Core\Utility\GeneralUtility;
3131
use TYPO3\CMS\Core\Utility\MathUtility;
32-
use TYPO3\CMS\Core\Utility\RootlineUtility;
3332

3433
/**
3534
* A class that monitors changes to the records so that the changed record get
@@ -38,6 +37,7 @@
3837
class RecordMonitor
3938
{
4039
use SkipMonitoringTrait;
40+
use SkipRecordByRootlineConfigurationTrait;
4141

4242
protected array $trackedRecords = [];
4343
protected EventDispatcherInterface $eventDispatcher;
@@ -144,7 +144,11 @@ public function processDatamap_afterDatabaseOperations(
144144
$recordPid = $recordInfo['pid'] ?? null;
145145
}
146146
}
147-
if (!is_null($recordPid) && $this->skipRecordByRootlineConfiguration((int)$recordPid)) {
147+
if (
148+
!is_null($recordPid)
149+
&& !GeneralUtility::inList('pages,tt_content', $table)
150+
&& $this->skipRecordByRootlineConfiguration((int)$recordPid)
151+
) {
148152
return;
149153
}
150154

@@ -164,24 +168,4 @@ public function processDatamap_afterDatabaseOperations(
164168
new RecordUpdatedEvent((int)$recordUid, $table, $fields)
165169
);
166170
}
167-
168-
/**
169-
* Check if at least one page in the record's rootline is configured to exclude sub-entries from indexing
170-
*/
171-
protected function skipRecordByRootlineConfiguration(int $pid): bool
172-
{
173-
/** @var RootlineUtility $rootlineUtility */
174-
$rootlineUtility = GeneralUtility::makeInstance(RootlineUtility::class, $pid);
175-
try {
176-
$rootline = $rootlineUtility->get();
177-
} catch (PageNotFoundException) {
178-
return true;
179-
}
180-
foreach ($rootline as $page) {
181-
if (isset($page['no_search_sub_entries']) && $page['no_search_sub_entries']) {
182-
return true;
183-
}
184-
}
185-
return false;
186-
}
187171
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the TYPO3 CMS project.
7+
*
8+
* It is free software; you can redistribute it and/or modify it under
9+
* the terms of the GNU General Public License, either version 2
10+
* of the License, or any later version.
11+
*
12+
* For the full copyright and license information, please read the
13+
* LICENSE.txt file that was distributed with this source code.
14+
*
15+
* The TYPO3 project - inspiring people to share!
16+
*/
17+
18+
namespace ApacheSolrForTypo3\Solr\Traits;
19+
20+
use TYPO3\CMS\Core\Exception\Page\PageNotFoundException;
21+
use TYPO3\CMS\Core\Utility\GeneralUtility;
22+
use TYPO3\CMS\Core\Utility\RootlineUtility;
23+
24+
trait SkipRecordByRootlineConfigurationTrait
25+
{
26+
/**
27+
* Check if at least one page in the record's rootline is configured to exclude sub-entries from indexing
28+
*/
29+
protected function skipRecordByRootlineConfiguration(int $pid): bool
30+
{
31+
/** @var RootlineUtility $rootlineUtility */
32+
$rootlineUtility = GeneralUtility::makeInstance(RootlineUtility::class, $pid);
33+
try {
34+
$rootline = $rootlineUtility->get();
35+
} catch (PageNotFoundException) {
36+
return true;
37+
}
38+
foreach ($rootline as $page) {
39+
if (isset($page['no_search_sub_entries']) && $page['no_search_sub_entries']) {
40+
return true;
41+
}
42+
}
43+
return false;
44+
}
45+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"pages",
2+
,"uid","pid","tstamp","hidden","doktype","mount_pid","mount_pid_ol","slug","title","no_search_sub_entries"
3+
,2,1,1736145036,0,254,0,0,"/sysfolder","Sys folder (no_search_sub_entries)",1
4+
,20,2,1736145036,0,1,0,0,"/mounted-page-in-sysfolder","Mounted page in sysfolder",0
5+
,21,1,1736145036,0,1,0,0,"/mounted-page-on-root","Mounted page on root page",0
6+
,22,2,1736145036,0,1,0,0,"/another-mounted-page-in-sysfolder","Another mounted page in sysfolder",0
7+
,30,1,1736145036,0,7,20,1,"/mount-point-1","Mount point for page in sysfolder",0
8+
,31,1,1736145036,0,7,21,1,"/mount-point-2","Mount point for page on root page",0
9+
,32,1,1736145036,0,7,22,1,"/mount-point-3","Mount point for another page in sysfolder",0
10+
"tt_content",
11+
,"uid","pid","header","hidden"
12+
,20,20,"ce on mounted page",0
13+
,21,20,"hidden ce on mounted page",1
14+
,22,21,"ce on mounted page",0
15+
,23,21,"hidden ce on mounted page",1
16+
,24,22,"ce on another mounted page",0
17+
,25,22,"hidden ce on another mounted page",1
18+
"tx_solr_indexqueue_item"
19+
,"uid","root","item_type","item_uid","indexing_configuration","has_indexing_properties","pages_mountidentifier","errors"
20+
,1,1,"pages",22,"pages",1,"22-32-1",""
21+
"tx_solr_indexqueue_indexing_property"
22+
,"uid","root","item_id","property_key","property_value"
23+
,1,1,1,"mountPageSource",22
24+
,2,1,1,"mountPageDestination",32
25+
,3,1,1,"isMountedPage",1

0 commit comments

Comments
 (0)