Passed
Push — task/2976_TYPO3.11_compatibili... ( 3bf19d...d7dfd0 )
by Rafael
21:28
created

Queue::getItemsToIndex()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 2
crap 1
1
<?php
2
3
namespace ApacheSolrForTypo3\Solr\IndexQueue;
4
5
/***************************************************************
6
 *  Copyright notice
7
 *
8
 *  (c) 2009-2015 Ingo Renner <[email protected]>
9
 *  All rights reserved
10
 *
11
 *  This script is part of the TYPO3 project. The TYPO3 project is
12
 *  free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by
14
 *  the Free Software Foundation; either version 3 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  The GNU General Public License can be found at
18
 *  http://www.gnu.org/copyleft/gpl.html.
19
 *
20
 *  This script is distributed in the hope that it will be useful,
21
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 *  GNU General Public License for more details.
24
 *
25
 *  This copyright notice MUST APPEAR in all copies of the script!
26
 ***************************************************************/
27
28
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\QueueInitializationService;
29
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\QueueItemRepository;
30
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\RecordMonitor\Helper\ConfigurationAwareRecordService;
31
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\RecordMonitor\Helper\RootPageResolver;
32
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\Statistic\QueueStatistic;
33
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\Statistic\QueueStatisticsRepository;
34
use ApacheSolrForTypo3\Solr\Domain\Site\Site;
35
use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository;
36
use ApacheSolrForTypo3\Solr\FrontendEnvironment;
37
use ApacheSolrForTypo3\Solr\System\Cache\TwoLevelCache;
38
use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager;
39
use TYPO3\CMS\Backend\Utility\BackendUtility;
40
use TYPO3\CMS\Core\Utility\GeneralUtility;
41
42
/**
43
 * The Indexing Queue. It allows us to decouple from frontend indexing and
44
 * reacting to changes faster.
45
 *
46
 * @author Ingo Renner <[email protected]>
47
 */
48
class Queue
49
{
50
    /**
51
     * @var RootPageResolver
52
     */
53
    protected $rootPageResolver;
54
55
    /**
56
     * @var ConfigurationAwareRecordService
57
     */
58
    protected $recordService;
59
60
    /**
61
     * @var \ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager
62
     */
63
    protected $logger = null;
64
65
    /**
66
     * @var QueueItemRepository
67
     */
68
    protected $queueItemRepository;
69
70
    /**
71
     * @var QueueStatisticsRepository
72
     */
73
    protected $queueStatisticsRepository;
74
75
    /**
76
     * @var QueueInitializationService
77
     */
78
    protected $queueInitializationService;
79
80
    /**
81
     * @var FrontendEnvironment
82
     */
83
    protected $frontendEnvironment = null;
84
85
    /**
86
     * Queue constructor.
87
     * @param RootPageResolver|null $rootPageResolver
88
     * @param ConfigurationAwareRecordService|null $recordService
89
     * @param QueueItemRepository|null $queueItemRepository
90
     * @param QueueStatisticsRepository|null $queueStatisticsRepository
91
     * @param QueueInitializationService|null $queueInitializationService
92
     */
93 121
    public function __construct(
94
        RootPageResolver $rootPageResolver = null,
95
        ConfigurationAwareRecordService $recordService = null,
96
        QueueItemRepository $queueItemRepository = null,
97
        QueueStatisticsRepository $queueStatisticsRepository = null,
98
        QueueInitializationService $queueInitializationService = null,
99
        FrontendEnvironment $frontendEnvironment = null
100
    ) {
101 121
        $this->logger = GeneralUtility::makeInstance(SolrLogManager::class, /** @scrutinizer ignore-type */ __CLASS__);
102 121
        $this->rootPageResolver = $rootPageResolver ?? GeneralUtility::makeInstance(RootPageResolver::class);
103 121
        $this->recordService = $recordService ?? GeneralUtility::makeInstance(ConfigurationAwareRecordService::class);
104 121
        $this->queueItemRepository = $queueItemRepository ?? GeneralUtility::makeInstance(QueueItemRepository::class);
105 121
        $this->queueStatisticsRepository = $queueStatisticsRepository ??  GeneralUtility::makeInstance(QueueStatisticsRepository::class);
106 121
        $this->queueInitializationService = $queueInitializationService ?? GeneralUtility::makeInstance(QueueInitializationService::class, /** @scrutinizer ignore-type */ $this);
107 121
        $this->frontendEnvironment = $frontendEnvironment ?? GeneralUtility::makeInstance(FrontendEnvironment::class);
108 121
    }
109
110
    // FIXME some of the methods should be renamed to plural forms
111
    // FIXME singular form methods should deal with exactly one item only
112
113
    /**
114
     * Returns the timestamp of the last indexing run.
115
     *
116
     * @param int $rootPageId The root page uid for which to get
117
     *      the last indexed item id
118
     * @return int Timestamp of last index run.
119
     */
120 2
    public function getLastIndexTime($rootPageId)
121
    {
122 2
        $lastIndexTime = 0;
123
124 2
        $lastIndexedRow = $this->queueItemRepository->findLastIndexedRow($rootPageId);
125
126 2
        if ($lastIndexedRow[0]['indexed']) {
127 1
            $lastIndexTime = $lastIndexedRow[0]['indexed'];
128
        }
129
130 2
        return $lastIndexTime;
131
    }
132
133
    /**
134
     * Returns the uid of the last indexed item in the queue
135
     *
136
     * @param int $rootPageId The root page uid for which to get
137
     *      the last indexed item id
138
     * @return int The last indexed item's ID.
139
     */
140 3
    public function getLastIndexedItemId($rootPageId)
141
    {
142 3
        $lastIndexedItemId = 0;
143
144 3
        $lastIndexedItemRow = $this->queueItemRepository->findLastIndexedRow($rootPageId);
145 3
        if ($lastIndexedItemRow[0]['uid']) {
146 2
            $lastIndexedItemId = $lastIndexedItemRow[0]['uid'];
147
        }
148
149 3
        return $lastIndexedItemId;
150
    }
151
152
    /**
153
     * @return QueueInitializationService
154
     */
155 6
    public function getInitializationService()
156
    {
157 6
        return $this->queueInitializationService;
158
    }
159
160
    /**
161
     * Marks an item as needing (re)indexing.
162
     *
163
     * Like with Solr itself, there's no add method, just a simple update method
164
     * that handles the adds, too.
165
     *
166
     * The method creates or updates the index queue items for all related rootPageIds.
167
     *
168
     * @param string $itemType The item's type, usually a table name.
169
     * @param string $itemUid The item's uid, usually an integer uid, could be a different value for non-database-record types.
170
     * @param int $forcedChangeTime The change time for the item if set, otherwise value from getItemChangedTime() is used.
171
     * @return int Number of updated/created items
172
     */
173 65
    public function updateItem($itemType, $itemUid, $forcedChangeTime = 0)
174
    {
175 65
        $updateCount = $this->updateOrAddItemForAllRelatedRootPages($itemType, $itemUid, $forcedChangeTime);
176 64
        $updateCount = $this->postProcessIndexQueueUpdateItem($itemType, $itemUid, $updateCount, $forcedChangeTime);
0 ignored issues
show
Bug introduced by
$itemUid of type string is incompatible with the type integer expected by parameter $itemUid of ApacheSolrForTypo3\Solr\...sIndexQueueUpdateItem(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

176
        $updateCount = $this->postProcessIndexQueueUpdateItem($itemType, /** @scrutinizer ignore-type */ $itemUid, $updateCount, $forcedChangeTime);
Loading history...
177
178 64
        return $updateCount;
179
    }
180
181
    /**
182
     * Updates or add's the item for all relevant root pages.
183
     *
184
     * @param string $itemType The item's type, usually a table name.
185
     * @param string $itemUid The item's uid, usually an integer uid, could be a different value for non-database-record types.
186
     * @param int $forcedChangeTime The change time for the item if set, otherwise value from getItemChangedTime() is used.
187
     * @return int
188
     */
189 63
    protected function updateOrAddItemForAllRelatedRootPages($itemType, $itemUid, $forcedChangeTime): int
190
    {
191 63
        $updateCount = 0;
192 63
        $rootPageIds = $this->rootPageResolver->getResponsibleRootPageIds($itemType, $itemUid);
0 ignored issues
show
Bug introduced by
$itemUid of type string is incompatible with the type integer expected by parameter $uid of ApacheSolrForTypo3\Solr\...esponsibleRootPageIds(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

192
        $rootPageIds = $this->rootPageResolver->getResponsibleRootPageIds($itemType, /** @scrutinizer ignore-type */ $itemUid);
Loading history...
193 62
        foreach ($rootPageIds as $rootPageId) {
194 62
            $skipInvalidRootPage = $rootPageId === 0;
195 62
            if ($skipInvalidRootPage) {
196
                continue;
197
            }
198
199
            /* @var SiteRepository $siteRepository */
200 62
            $siteRepository = GeneralUtility::makeInstance(SiteRepository::class);
201 62
            $solrConfiguration = $siteRepository->getSiteByRootPageId($rootPageId)->getSolrConfiguration();
202 62
            $indexingConfiguration = $this->recordService->getIndexingConfigurationName($itemType, $itemUid, $solrConfiguration);
0 ignored issues
show
Bug introduced by
$itemUid of type string is incompatible with the type integer expected by parameter $recordUid of ApacheSolrForTypo3\Solr\...xingConfigurationName(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

202
            $indexingConfiguration = $this->recordService->getIndexingConfigurationName($itemType, /** @scrutinizer ignore-type */ $itemUid, $solrConfiguration);
Loading history...
203 62
            if ($indexingConfiguration === null) {
204 2
                continue;
205
            }
206 61
            $itemInQueueForRootPage = $this->containsItemWithRootPageId($itemType, $itemUid, $rootPageId);
207 61
            if ($itemInQueueForRootPage) {
208
                // update changed time if that item is in the queue already
209 13
                $changedTime = ($forcedChangeTime > 0) ? $forcedChangeTime : $this->getItemChangedTime($itemType, $itemUid);
210 13
                $updatedRows = $this->queueItemRepository->updateExistingItemByItemTypeAndItemUidAndRootPageId($itemType, $itemUid, $rootPageId, $changedTime, $indexingConfiguration);
0 ignored issues
show
Bug introduced by
$itemUid of type string is incompatible with the type integer expected by parameter $itemUid of ApacheSolrForTypo3\Solr\...dItemUidAndRootPageId(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

210
                $updatedRows = $this->queueItemRepository->updateExistingItemByItemTypeAndItemUidAndRootPageId($itemType, /** @scrutinizer ignore-type */ $itemUid, $rootPageId, $changedTime, $indexingConfiguration);
Loading history...
211
            } else {
212
                // add the item since it's not in the queue yet
213 55
                $updatedRows = $this->addNewItem($itemType, $itemUid, $indexingConfiguration, $rootPageId);
214
            }
215
216 61
            $updateCount += $updatedRows;
217
        }
218
219 62
        return $updateCount;
220
    }
221
222
    /**
223
     * Executes the updateItem post processing hook.
224
     *
225
     * @param string $itemType
226
     * @param int $itemUid
227
     * @param int $updateCount
228
     * @param int $forcedChangeTime
229
     * @return int
230
     */
231 64
    protected function postProcessIndexQueueUpdateItem($itemType, $itemUid, $updateCount, $forcedChangeTime = 0)
232
    {
233 64
        if (!isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessIndexQueueUpdateItem'])
234 64
            || !is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessIndexQueueUpdateItem'])) {
235 63
            return $updateCount;
236
        }
237
238 1
        foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['postProcessIndexQueueUpdateItem'] as $classReference) {
239 1
            $updateHandler = $this->getHookImplementation($classReference);
240 1
            $updateCount = $updateHandler->postProcessIndexQueueUpdateItem($itemType, $itemUid, $updateCount, $forcedChangeTime);
241
        }
242
243 1
        return $updateCount;
244
    }
245
246
    /**
247
     * @param string $classReference
248
     * @return object
249
     */
250
    protected function getHookImplementation($classReference)
251
    {
252
        return GeneralUtility::makeInstance($classReference);
253
    }
254
255
    /**
256
     * Finds indexing errors for the current site
257
     *
258
     * @param Site $site
259
     * @return array Error items for the current site's Index Queue
260
     */
261 3
    public function getErrorsBySite(Site $site)
262
    {
263 3
        return $this->queueItemRepository->findErrorsBySite($site);
264
    }
265
266
    /**
267
     * Resets all the errors for all index queue items.
268
     *
269
     * @return mixed
270
     */
271 1
    public function resetAllErrors()
272
    {
273 1
        return $this->queueItemRepository->flushAllErrors();
274
    }
275
276
    /**
277
     * Resets the errors in the index queue for a specific site
278
     *
279
     * @param Site $site
280
     * @return mixed
281
     */
282 1
    public function resetErrorsBySite(Site $site)
283
    {
284 1
        return $this->queueItemRepository->flushErrorsBySite($site);
285
    }
286
287
    /**
288
     * Resets the error in the index queue for a specific item
289
     *
290
     * @param Item $item
291
     * @return mixed
292
     */
293 1
    public function resetErrorByItem(Item $item)
294
    {
295 1
        return $this->queueItemRepository->flushErrorByItem($item);
296
    }
297
298
    /**
299
     * Adds an item to the index queue.
300
     *
301
     * Not meant for public use.
302
     *
303
     * @param string $itemType The item's type, usually a table name.
304
     * @param string $itemUid The item's uid, usually an integer uid, could be a
305
     *      different value for non-database-record types.
306
     * @param string $indexingConfiguration The item's indexing configuration to use.
307
     *      Optional, overwrites existing / determined configuration.
308
     * @param $rootPageId
309
     * @return int
310
     */
311 55
    private function addNewItem($itemType, $itemUid, $indexingConfiguration, $rootPageId)
312
    {
313 55
        $additionalRecordFields = '';
314 55
        if ($itemType === 'pages') {
315 32
            $additionalRecordFields = ', doktype, uid';
316
        }
317
318 55
        $record = $this->getRecordCached($itemType, $itemUid, $additionalRecordFields);
319
320 55
        if (empty($record) || ($itemType === 'pages' && !$this->frontendEnvironment->isAllowedPageType($record, $indexingConfiguration))) {
321
            return 0;
322
        }
323
324 55
        $changedTime = $this->getItemChangedTime($itemType, $itemUid);
325
326 55
        return $this->queueItemRepository->add($itemType, $itemUid, $rootPageId, $changedTime, $indexingConfiguration);
0 ignored issues
show
Bug introduced by
$itemUid of type string is incompatible with the type integer expected by parameter $itemUid of ApacheSolrForTypo3\Solr\...ueItemRepository::add(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

326
        return $this->queueItemRepository->add($itemType, /** @scrutinizer ignore-type */ $itemUid, $rootPageId, $changedTime, $indexingConfiguration);
Loading history...
327
    }
328
329
    /**
330
     * Get record to be added in addNewItem
331
     *
332
     * @param string $itemType The item's type, usually a table name.
333
     * @param string $itemUid The item's uid, usually an integer uid, could be a
334
     *      different value for non-database-record types.
335
     * @param string $additionalRecordFields for sql-query
336
     *
337
     * @return array|NULL
338
     */
339 55
    protected function getRecordCached($itemType, $itemUid, $additionalRecordFields)
340
    {
341 55
        $cache = GeneralUtility::makeInstance(TwoLevelCache::class, /** @scrutinizer ignore-type */ 'runtime');
342 55
        $cacheId = md5('Queue' . ':' . 'getRecordCached' . ':' . $itemType . ':' . $itemUid . ':' . 'pid' . $additionalRecordFields);
343
344 55
        $record = $cache->get($cacheId);
345 55
        if (empty($record)) {
346 55
            $record = BackendUtility::getRecord($itemType, $itemUid, 'pid' . $additionalRecordFields);
347 55
            $cache->set($cacheId, $record);
348
        }
349
350 55
        return $record;
351
    }
352
353
    /**
354
     * Determines the time for when an item should be indexed. This timestamp
355
     * is then stored in the changed column in the Index Queue.
356
     *
357
     * The changed timestamp usually is now - time(). For records which are set
358
     * to published at a later time, this timestamp is the start time. So if a
359
     * future start time has been set, that will be used to delay indexing
360
     * of an item.
361
     *
362
     * @param string $itemType The item's table name.
363
     * @param string $itemUid The item's uid, usually an integer uid, could be a
364
     *      different value for non-database-record types.
365
     * @return int Timestamp of the item's changed time or future start time
366
     */
367 61
    protected function getItemChangedTime($itemType, $itemUid)
368
    {
369 61
        $itemTypeHasStartTimeColumn = false;
370 61
        $changedTimeColumns = $GLOBALS['TCA'][$itemType]['ctrl']['tstamp'];
371 61
        $startTime = 0;
372 61
        $pageChangedTime = 0;
373
374 61
        if (!empty($GLOBALS['TCA'][$itemType]['ctrl']['enablecolumns']['starttime'])) {
375 61
            $itemTypeHasStartTimeColumn = true;
376 61
            $changedTimeColumns .= ', ' . $GLOBALS['TCA'][$itemType]['ctrl']['enablecolumns']['starttime'];
377
        }
378 61
        if ($itemType === 'pages') {
379
            // does not carry time information directly, but needed to support
380
            // canonical pages
381 38
            $changedTimeColumns .= ', content_from_pid';
382
        }
383
384 61
        $record = BackendUtility::getRecord($itemType, $itemUid, $changedTimeColumns);
385 61
        $itemChangedTime = $record[$GLOBALS['TCA'][$itemType]['ctrl']['tstamp']];
386
387 61
        if ($itemTypeHasStartTimeColumn) {
388 61
            $startTime = $record[$GLOBALS['TCA'][$itemType]['ctrl']['enablecolumns']['starttime']];
389
        }
390
391 61
        if ($itemType === 'pages') {
392 38
            $record['uid'] = $itemUid;
393
            // overrule the page's last changed time with the most recent
394
            //content element change
395 38
            $pageChangedTime = $this->getPageItemChangedTime($record);
0 ignored issues
show
Bug introduced by
It seems like $record can also be of type null; however, parameter $page of ApacheSolrForTypo3\Solr\...etPageItemChangedTime() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

395
            $pageChangedTime = $this->getPageItemChangedTime(/** @scrutinizer ignore-type */ $record);
Loading history...
396
        }
397
398 61
        $localizationsChangedTime = $this->queueItemRepository->getLocalizableItemChangedTime($itemType, (int)$itemUid);
399
400
        // if start time exists and start time is higher than last changed timestamp
401
        // then set changed to the future start time to make the item
402
        // indexed at a later time
403 61
        $changedTime = max(
404 61
            $itemChangedTime,
405
            $pageChangedTime,
406
            $localizationsChangedTime,
407
            $startTime
408
        );
409
410 61
        return $changedTime;
411
    }
412
413
    /**
414
     * Gets the most recent changed time of a page's content elements
415
     *
416
     * @param array $page Partial page record
417
     * @return int Timestamp of the most recent content element change
418
     */
419 38
    protected function getPageItemChangedTime(array $page)
420
    {
421 38
        if (!empty($page['content_from_pid'])) {
422
            // canonical page, get the original page's last changed time
423
            return $this->queueItemRepository->getPageItemChangedTimeByPageUid((int)$page['content_from_pid']);
424
        }
425 38
        return $this->queueItemRepository->getPageItemChangedTimeByPageUid((int)$page['uid']);
426
    }
427
428
    /**
429
     * Checks whether the Index Queue contains a specific item.
430
     *
431
     * @param string $itemType The item's type, usually a table name.
432
     * @param string $itemUid The item's uid, usually an integer uid, could be a
433
     *      different value for non-database-record types.
434
     * @return bool TRUE if the item is found in the queue, FALSE otherwise
435
     */
436 8
    public function containsItem($itemType, $itemUid)
437
    {
438 8
        return $this->queueItemRepository->containsItem($itemType, (int)$itemUid);
439
    }
440
441
    /**
442
     * Checks whether the Index Queue contains a specific item.
443
     *
444
     * @param string $itemType The item's type, usually a table name.
445
     * @param string $itemUid The item's uid, usually an integer uid, could be a
446
     *      different value for non-database-record types.
447
     * @param integer $rootPageId
448
     * @return bool TRUE if the item is found in the queue, FALSE otherwise
449
     */
450 61
    public function containsItemWithRootPageId($itemType, $itemUid, $rootPageId)
451
    {
452 61
        return $this->queueItemRepository->containsItemWithRootPageId($itemType, (int)$itemUid, (int)$rootPageId);
453
    }
454
455
    /**
456
     * Checks whether the Index Queue contains a specific item that has been
457
     * marked as indexed.
458
     *
459
     * @param string $itemType The item's type, usually a table name.
460
     * @param string $itemUid The item's uid, usually an integer uid, could be a
461
     *      different value for non-database-record types.
462
     * @return bool TRUE if the item is found in the queue and marked as
463
     *      indexed, FALSE otherwise
464
     */
465 2
    public function containsIndexedItem($itemType, $itemUid)
466
    {
467 2
        return $this->queueItemRepository->containsIndexedItem($itemType, (int)$itemUid);
468
    }
469
470
    /**
471
     * Removes an item from the Index Queue.
472
     *
473
     * @param string $itemType The type of the item to remove, usually a table name.
474
     * @param int $itemUid The uid of the item to remove
475
     */
476 34
    public function deleteItem($itemType, $itemUid)
477
    {
478 34
        $this->queueItemRepository->deleteItem($itemType, (int)$itemUid);
479 34
    }
480
481
    /**
482
     * Removes all items of a certain type from the Index Queue.
483
     *
484
     * @param string $itemType The type of items to remove, usually a table name.
485
     */
486 1
    public function deleteItemsByType($itemType)
487
    {
488 1
        $this->queueItemRepository->deleteItemsByType($itemType);
489 1
    }
490
491
    /**
492
     * Removes all items of a certain site from the Index Queue. Accepts an
493
     * optional parameter to limit the deleted items by indexing configuration.
494
     *
495
     * @param Site $site The site to remove items for.
496
     * @param string $indexingConfigurationName Name of a specific indexing
497
     *      configuration
498
     */
499 6
    public function deleteItemsBySite(Site $site, $indexingConfigurationName = '')
500
    {
501 6
        $this->queueItemRepository->deleteItemsBySite($site, $indexingConfigurationName);
502 6
    }
503
504
    /**
505
     * Removes all items from the Index Queue.
506
     *
507
     */
508 1
    public function deleteAllItems()
509
    {
510 1
        $this->queueItemRepository->deleteAllItems();
511 1
    }
512
513
    /**
514
     * Gets a single Index Queue item by its uid.
515
     *
516
     * @param int $itemId Index Queue item uid
517
     * @return Item|null The request Index Queue item or NULL if no item with $itemId was found
518
     */
519 26
    public function getItem(int $itemId): ?Item
520
    {
521 26
        return $this->queueItemRepository->findItemByUid($itemId);
522
    }
523
524
    /**
525
     * Gets Index Queue items by type and uid.
526
     *
527
     * @param string $itemType item type, usually  the table name
528
     * @param int $itemUid item uid
529
     * @return Item[] An array of items matching $itemType and $itemUid
530
     */
531 39
    public function getItems($itemType, $itemUid)
532
    {
533 39
        return $this->queueItemRepository->findItemsByItemTypeAndItemUid($itemType, (int)$itemUid);
534
    }
535
536
    /**
537
     * Returns all items in the queue.
538
     *
539
     * @return Item[] An array of items
540
     */
541
    public function getAllItems()
542
    {
543
        return $this->queueItemRepository->findAll();
544
    }
545
546
    /**
547
     * Returns the number of items for all queues.
548
     *
549
     * @return int
550
     */
551 79
    public function getAllItemsCount()
552
    {
553 79
        return $this->queueItemRepository->count();
554
    }
555
556
    /**
557
     * Extracts the number of pending, indexed and erroneous items from the
558
     * Index Queue.
559
     *
560
     * @param Site $site
561
     * @param string $indexingConfigurationName
562
     *
563
     * @return QueueStatistic
564
     */
565 5
    public function getStatisticsBySite(Site $site, $indexingConfigurationName = '')
566
    {
567 5
        return $this->queueStatisticsRepository->findOneByRootPidAndOptionalIndexingConfigurationName($site->getRootPageId(), $indexingConfigurationName);
568
    }
569
570
    /**
571
     * Gets $limit number of items to index for a particular $site.
572
     *
573
     * @param Site $site TYPO3 site
574
     * @param int $limit Number of items to get from the queue
575
     * @return Item[] Items to index to the given solr server
576
     */
577 3
    public function getItemsToIndex(Site $site, $limit = 50)
578
    {
579 3
        return $this->queueItemRepository->findItemsToIndex($site, $limit);
580
    }
581
582
    /**
583
     * Marks an item as failed and causes the indexer to skip the item in the
584
     * next run.
585
     *
586
     * @param int|Item $item Either the item's Index Queue uid or the complete item
587
     * @param string $errorMessage Error message
588
     */
589 6
    public function markItemAsFailed($item, $errorMessage = '')
590
    {
591 6
        $this->queueItemRepository->markItemAsFailed($item, $errorMessage);
592 6
    }
593
594
    /**
595
     * Sets the timestamp of when an item last has been indexed.
596
     *
597
     * @param Item $item
598
     */
599 2
    public function updateIndexTimeByItem(Item $item)
600
    {
601 2
        $this->queueItemRepository->updateIndexTimeByItem($item);
602 2
    }
603
604
    /**
605
     * Sets the change timestamp of an item.
606
     *
607
     * @param Item $item
608
     * @param int $forcedChangeTime The change time for the item
609
     */
610
    public function setForcedChangeTimeByItem(Item $item, $forcedChangeTime)
611
    {
612
        $this->queueItemRepository->updateChangedTimeByItem($item, $forcedChangeTime);
613
    }
614
}
615