Passed
Push — master ( 5e006b...ff2100 )
by Timo
21:14
created

Indexer::log()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 28
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 14.0742

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 28
ccs 3
cts 21
cp 0.1429
rs 9.7333
c 0
b 0
f 0
cc 4
nc 5
nop 3
crap 14.0742
1
<?php
2
namespace ApacheSolrForTypo3\Solr\IndexQueue;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2009-2015 Ingo Renner <[email protected]>
8
 *  All rights reserved
9
 *
10
 *  This script is part of the TYPO3 project. The TYPO3 project is
11
 *  free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 3 of the License, or
14
 *  (at your option) any later version.
15
 *
16
 *  The GNU General Public License can be found at
17
 *  http://www.gnu.org/copyleft/gpl.html.
18
 *
19
 *  This script is distributed in the hope that it will be useful,
20
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 *  GNU General Public License for more details.
23
 *
24
 *  This copyright notice MUST APPEAR in all copies of the script!
25
 ***************************************************************/
26
27
use ApacheSolrForTypo3\Solr\ConnectionManager;
28
use ApacheSolrForTypo3\Solr\Domain\Search\ApacheSolrDocument\Builder;
29
use ApacheSolrForTypo3\Solr\FieldProcessor\Service;
30
use ApacheSolrForTypo3\Solr\FrontendEnvironment;
31
use ApacheSolrForTypo3\Solr\NoSolrConnectionFoundException;
32
use ApacheSolrForTypo3\Solr\Domain\Site\Site;
33
use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager;
34
use ApacheSolrForTypo3\Solr\System\Records\Pages\PagesRepository;
35
use ApacheSolrForTypo3\Solr\System\Solr\Document\Document;
36
use ApacheSolrForTypo3\Solr\System\Solr\ResponseAdapter;
37
use ApacheSolrForTypo3\Solr\System\Solr\SolrConnection;
38
use Solarium\Exception\HttpException;
39
use TYPO3\CMS\Core\Context\LanguageAspectFactory;
40
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
41
use TYPO3\CMS\Core\Site\SiteFinder;
42
use TYPO3\CMS\Core\Utility\GeneralUtility;
43
use TYPO3\CMS\Core\Utility\RootlineUtility;
44
use TYPO3\CMS\Frontend\Page\PageRepository;
45
46
/**
47
 * A general purpose indexer to be used for indexing of any kind of regular
48
 * records like tt_news, tt_address, and so on.
49
 * Specialized indexers can extend this class to handle advanced stuff like
50
 * category resolution in tt_news or file indexing.
51
 *
52
 * @author Ingo Renner <[email protected]>
53
 */
54
class Indexer extends AbstractIndexer
55
{
56
57
    # TODO change to singular $document instead of plural $documents
58
59
    /**
60
     * A Solr service instance to interact with the Solr server
61
     *
62
     * @var SolrConnection
63
     */
64
    protected $solr;
65
66
    /**
67
     * @var ConnectionManager
68
     */
69
    protected $connectionManager;
70
71
    /**
72
     * Holds options for a specific indexer
73
     *
74
     * @var array
75
     */
76
    protected $options = [];
77
78
    /**
79
     * To log or not to log... #Shakespeare
80
     *
81
     * @var bool
82
     */
83
    protected $loggingEnabled = false;
84
85
    /**
86
     * @var SolrLogManager
87
     */
88
    protected $logger = null;
89
90
    /**
91
     * @var PagesRepository
92
     */
93
    protected $pagesRepository;
94
95
    /**
96
     * @var Builder
97
     */
98
    protected $documentBuilder;
99
100
    /**
101
     * @var FrontendEnvironment
102
     */
103
    protected $frontendEnvironment = null;
104
105
    /**
106
     * Constructor
107
     *
108
     * @param array $options array of indexer options
109
     * @param PagesRepository|null $pagesRepository
110
     * @param Builder|null $documentBuilder
111
     * @param SolrLogManager|null $logger
112
     * @param ConnectionManager|null $connectionManager
113
     * @param FrontendEnvironment|null $frontendEnvironment
114
     */
115 35
    public function __construct(
116
        array $options = [],
117
        PagesRepository $pagesRepository = null,
118
        Builder $documentBuilder = null,
119
        SolrLogManager $logger = null,
120
        ConnectionManager $connectionManager = null,
121
        FrontendEnvironment $frontendEnvironment = null
122
    )
123
    {
124 35
        $this->options = $options;
125 35
        $this->pagesRepository = $pagesRepository ?? GeneralUtility::makeInstance(PagesRepository::class);
126 35
        $this->documentBuilder = $documentBuilder ?? GeneralUtility::makeInstance(Builder::class);
127 35
        $this->logger = $logger ?? GeneralUtility::makeInstance(SolrLogManager::class, /** @scrutinizer ignore-type */ __CLASS__);
128 35
        $this->connectionManager = $connectionManager ?? GeneralUtility::makeInstance(ConnectionManager::class);
129 35
        $this->frontendEnvironment = $frontendEnvironment ?? GeneralUtility::makeInstance(FrontendEnvironment::class);
130 35
    }
131
132
    /**
133
     * Indexes an item from the indexing queue.
134
     *
135
     * @param Item $item An index queue item
136
     * @return bool returns true when indexed, false when not
137
     */
138 19
    public function index(Item $item)
139
    {
140 19
        $indexed = true;
141
142 19
        $this->type = $item->getType();
143 19
        $this->setLogging($item);
144
145 19
        $solrConnections = $this->getSolrConnectionsByItem($item);
146 19
        foreach ($solrConnections as $systemLanguageUid => $solrConnection) {
147 19
            $this->solr = $solrConnection;
148
149 19
            if (!$this->indexItem($item, $systemLanguageUid)) {
150
                /*
151
                 * A single language voting for "not indexed" should make the whole
152
                 * item count as being not indexed, even if all other languages are
153
                 * indexed.
154
                 * If there is no translation for a single language, this item counts
155
                 * as TRUE since it's not an error which that should make the item
156
                 * being reindexed during another index run.
157
                 */
158
                $indexed = false;
159
            }
160
        }
161
162 19
        return $indexed;
163
    }
164
165
    /**
166
     * Creates a single Solr Document for an item in a specific language.
167
     *
168
     * @param Item $item An index queue item to index.
169
     * @param int $language The language to use.
170
     * @return bool TRUE if item was indexed successfully, FALSE on failure
171
     */
172 19
    protected function indexItem(Item $item, $language = 0)
173
    {
174 19
        $itemIndexed = false;
175 19
        $documents = [];
176
177 19
        $itemDocument = $this->itemToDocument($item, $language);
178 19
        if (is_null($itemDocument)) {
179
            /*
180
             * If there is no itemDocument, this means there was no translation
181
             * for this record. This should not stop the current item to count as
182
             * being valid because not-indexing not-translated items is perfectly
183
             * fine.
184
             */
185
            return true;
186
        }
187
188 19
        $documents[] = $itemDocument;
189 19
        $documents = array_merge($documents, $this->getAdditionalDocuments($item, $language, $itemDocument));
190 19
        $documents = $this->processDocuments($item, $documents);
191 19
        $documents = $this->preAddModifyDocuments($item, $language, $documents);
192
193
        try {
194 19
            $response = $this->solr->getWriteService()->addDocuments($documents);
195 19
            if ($response->getHttpStatus() == 200) {
196 19
                $itemIndexed = true;
197
            }
198
        } catch (HttpException $e) {
199
            $response = new ResponseAdapter($e->getBody(), $httpStatus = 500, $e->getStatusMessage());
200
        }
201
202 19
        $this->log($item, $documents, $response);
203
204 19
        return $itemIndexed;
205
    }
206
207
    /**
208
     * Gets the full item record.
209
     *
210
     * This general record indexer simply gets the record from the item. Other
211
     * more specialized indexers may provide more data for their specific item
212
     * types.
213
     *
214
     * @param Item $item The item to be indexed
215
     * @param int $language Language Id (sys_language.uid)
216
     * @return array|NULL The full record with fields of data to be used for indexing or NULL to prevent an item from being indexed
217
     */
218 19
    protected function getFullItemRecord(Item $item, $language = 0)
219
    {
220 19
        $itemRecord = $this->getItemRecordOverlayed($item, $language);
221
222 19
        if (!is_null($itemRecord)) {
223 19
            $itemRecord['__solr_index_language'] = $language;
224
        }
225
226 19
        return $itemRecord;
227
    }
228
229
    /**
230
     * Returns the overlayed item record.
231
     *
232
     * @param Item $item
233
     * @param int $language
234
     * @param string|null $systemLanguageContentOverlay
235
     * @return array|mixed|null
236
     */
237 19
    protected function getItemRecordOverlayed(Item $item, $language)
238
    {
239 19
        $itemRecord = $item->getRecord();
240
241 19
        if ($language > 0) {
242 17
            $page = GeneralUtility::makeInstance(PageRepository::class);
243 17
            $itemRecord = $page->getLanguageOverlay($item->getType(), $itemRecord);
244
        }
245
246 19
        if (!$itemRecord) {
247
            $itemRecord = null;
248
        }
249
250 19
        return $itemRecord;
251
    }
252
253
    /**
254
     * Gets the configuration how to process an item's fields for indexing.
255
     *
256
     * @param Item $item An index queue item
257
     * @param int $language Language ID
258
     * @throws \RuntimeException
259
     * @return array Configuration array from TypoScript
260
     */
261 19
    protected function getItemTypeConfiguration(Item $item, $language = 0)
262
    {
263 19
        $indexConfigurationName = $item->getIndexingConfigurationName();
264 19
        $fields = $this->getFieldConfigurationFromItemRecordPage($item, $language, $indexConfigurationName);
265 19
        if (!$this->isRootPageIdPartOfRootLine($item) || count($fields) === 0) {
266 2
            $fields = $this->getFieldConfigurationFromItemRootPage($item, $language, $indexConfigurationName);
267 2
            if (count($fields) === 0) {
268
                throw new \RuntimeException('The item indexing configuration "' . $item->getIndexingConfigurationName() .
269
                    '" on root page uid ' . $item->getRootPageUid() . ' could not be found!', 1455530112);
270
            }
271
        }
272
273 19
        return $fields;
274
    }
275
276
    /**
277
     * The method retrieves the field configuration of the items record page id (pid).
278
     *
279
     * @param Item $item
280
     * @param integer $language
281
     * @param string $indexConfigurationName
282
     * @return array
283
     */
284 19
    protected function getFieldConfigurationFromItemRecordPage(Item $item, $language, $indexConfigurationName)
285
    {
286
        try {
287 19
            $pageId = $this->getPageIdOfItem($item);
288 19
            $solrConfiguration = $this->frontendEnvironment->getSolrConfigurationFromPageId($pageId, $language);
289 19
            return $solrConfiguration->getIndexQueueFieldsConfigurationByConfigurationName($indexConfigurationName, []);
290
        } catch (\Exception $e) {
291
            return [];
292
        }
293
    }
294
295
    /**
296
     * @param Item $item
297
     * @return int
298
     */
299 19
    protected function getPageIdOfItem(Item $item): int
300
    {
301 19
        if ($item->getType() === 'pages') {
302 2
            return (int)$item->getRecordUid();
303
        }
304 17
        return (int)$item->getRecordPageId();
305
    }
306
307
    /**
308
     * The method returns the field configuration of the items root page id (uid of the related root page).
309
     *
310
     * @param Item $item
311
     * @param integer $language
312
     * @param string $indexConfigurationName
313
     * @return array
314
     */
315 2
    protected function getFieldConfigurationFromItemRootPage(Item $item, $language, $indexConfigurationName)
316
    {
317 2
        $solrConfiguration = $this->frontendEnvironment->getSolrConfigurationFromPageId($item->getRootPageUid(), $language);
318 2
        if (empty($solrConfiguration->getIndexQueueAdditionalPageIdsByConfigurationName($indexConfigurationName))) {
319
            return [];
320
        }
321
322 2
        return $solrConfiguration->getIndexQueueFieldsConfigurationByConfigurationName($indexConfigurationName, []);
323
    }
324
325
    /**
326
     * In case of additionalStoragePid config recordPageId can be outsite of siteroot.
327
     * In that case we should not read TS config of foreign siteroot.
328
     *
329
     * @return bool
330
     */
331 19
    protected function isRootPageIdPartOfRootLine(Item $item)
332
    {
333 19
        $rootPageId = $item->getRootPageUid();
334 19
        $buildRootlineWithPid = $this->getPageIdOfItem($item);
335 19
        $rootlineUtility = GeneralUtility::makeInstance(RootlineUtility::class, $buildRootlineWithPid);
336 19
        $rootline = $rootlineUtility->get();
337
338
        $pageInRootline = array_filter($rootline, function($page) use ($rootPageId) {
339 19
            return (int)$page['uid'] === $rootPageId;
340 19
        });
341 19
        return !empty($pageInRootline);
342
    }
343
344
    /**
345
     * Converts an item array (record) to a Solr document by mapping the
346
     * record's fields onto Solr document fields as configured in TypoScript.
347
     *
348
     * @param Item $item An index queue item
349
     * @param int $language Language Id
350
     * @return Document The Solr document converted from the record
351
     */
352 19
    protected function itemToDocument(Item $item, $language = 0)
353
    {
354 19
        $document = null;
355 19
        if ($item->getType() === 'pages') {
356 2
            $this->frontendEnvironment->initializeTsfe($item->getRecordUid(), $language);
357
        } else {
358 17
            $this->frontendEnvironment->initializeTsfe($item->getRootPageUid(), $language);
359
        }
360
361 19
        $itemRecord = $this->getFullItemRecord($item, $language);
362 19
        if (!is_null($itemRecord)) {
363 19
            $itemIndexingConfiguration = $this->getItemTypeConfiguration($item, $language);
364 19
            $document = $this->getBaseDocument($item, $itemRecord);
365 19
            $document = $this->addDocumentFieldsFromTyposcript($document, $itemIndexingConfiguration, $itemRecord);
366
        }
367
368 19
        return $document;
369
    }
370
371
    /**
372
     * Creates a Solr document with the basic / core fields set already.
373
     *
374
     * @param Item $item The item to index
375
     * @param array $itemRecord The record to use to build the base document
376
     * @return Document A basic Solr document
377
     */
378 19
    protected function getBaseDocument(Item $item, array $itemRecord)
379
    {
380 19
        $type = $item->getType();
381 19
        $rootPageUid = $item->getRootPageUid();
382 19
        $accessRootLine = $this->getAccessRootline($item);
383 19
        return $this->documentBuilder->fromRecord($itemRecord, $type, $rootPageUid, $accessRootLine);
384
    }
385
386
    /**
387
     * Generates an Access Rootline for an item.
388
     *
389
     * @param Item $item Index Queue item to index.
390
     * @return string The Access Rootline for the item
391
     */
392 19
    protected function getAccessRootline(Item $item)
393
    {
394 19
        $accessRestriction = '0';
395 19
        $itemRecord = $item->getRecord();
396
397
        // TODO support access restrictions set on storage page
398
399 19
        if (isset($GLOBALS['TCA'][$item->getType()]['ctrl']['enablecolumns']['fe_group'])) {
400 2
            $accessRestriction = $itemRecord[$GLOBALS['TCA'][$item->getType()]['ctrl']['enablecolumns']['fe_group']];
401
402 2
            if (empty($accessRestriction)) {
403
                // public
404 2
                $accessRestriction = '0';
405
            }
406
        }
407
408 19
        return 'r:' . $accessRestriction;
409
    }
410
411
    /**
412
     * Sends the documents to the field processing service which takes care of
413
     * manipulating fields as defined in the field's configuration.
414
     *
415
     * @param Item $item An index queue item
416
     * @param array $documents An array of Apache_Solr_Document objects to manipulate.
417
     * @return Document[] array Array of manipulated Document objects.
418
     */
419 19
    protected function processDocuments(Item $item, array $documents)
420
    {
421
        // needs to respect the TS settings for the page the item is on, conditions may apply
422 19
        $solrConfiguration = $this->frontendEnvironment->getSolrConfigurationFromPageId($item->getRootPageUid());
423 19
        $fieldProcessingInstructions = $solrConfiguration->getIndexFieldProcessingInstructionsConfiguration();
424
425
        // same as in the FE indexer
426 19
        if (is_array($fieldProcessingInstructions)) {
0 ignored issues
show
introduced by
The condition is_array($fieldProcessingInstructions) is always true.
Loading history...
427 19
            $service = GeneralUtility::makeInstance(Service::class);
428 19
            $service->processDocuments($documents, $fieldProcessingInstructions);
429
        }
430
431 19
        return $documents;
432
    }
433
434
    /**
435
     * Allows third party extensions to provide additional documents which
436
     * should be indexed for the current item.
437
     *
438
     * @param Item $item The item currently being indexed.
439
     * @param int $language The language uid currently being indexed.
440
     * @param Document $itemDocument The document representing the item for the given language.
441
     * @return Document[] array An array of additional Document objects to index.
442
     */
443 23
    protected function getAdditionalDocuments(Item $item, $language, Document $itemDocument)
444
    {
445 23
        $documents = [];
446
447 23
        if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['IndexQueueIndexer']['indexItemAddDocuments'])) {
448 4
            foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['IndexQueueIndexer']['indexItemAddDocuments'] as $classReference) {
449 4
                if (!class_exists($classReference)) {
450 2
                    throw new \InvalidArgumentException('Class does not exits' . $classReference, 1490363487);
451
                }
452 2
                $additionalIndexer = GeneralUtility::makeInstance($classReference);
453 2
                if ($additionalIndexer instanceof AdditionalIndexQueueItemIndexer) {
454 1
                    $additionalDocuments = $additionalIndexer->getAdditionalItemDocuments($item, $language, $itemDocument);
455
456 1
                    if (is_array($additionalDocuments)) {
457 1
                        $documents = array_merge($documents,
458
                            $additionalDocuments);
459
                    }
460
                } else {
461 1
                    throw new \UnexpectedValueException(
462 1
                        get_class($additionalIndexer) . ' must implement interface ' . AdditionalIndexQueueItemIndexer::class,
463 1
                        1326284551
464
                    );
465
                }
466
            }
467
        }
468 20
        return $documents;
469
    }
470
471
    /**
472
     * Provides a hook to manipulate documents right before they get added to
473
     * the Solr index.
474
     *
475
     * @param Item $item The item currently being indexed.
476
     * @param int $language The language uid of the documents
477
     * @param array $documents An array of documents to be indexed
478
     * @return array An array of modified documents
479
     */
480 19
    protected function preAddModifyDocuments(Item $item, $language, array $documents)
481
    {
482 19
        if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['IndexQueueIndexer']['preAddModifyDocuments'])) {
483
            foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['IndexQueueIndexer']['preAddModifyDocuments'] as $classReference) {
484
                $documentsModifier = GeneralUtility::makeInstance($classReference);
485
486
                if ($documentsModifier instanceof PageIndexerDocumentsModifier) {
487
                    $documents = $documentsModifier->modifyDocuments($item, $language, $documents);
488
                } else {
489
                    throw new \RuntimeException(
490
                        'The class "' . get_class($documentsModifier)
491
                        . '" registered as document modifier in hook
492
							preAddModifyDocuments must implement interface
493
							ApacheSolrForTypo3\Solr\IndexQueue\PageIndexerDocumentsModifier',
494
                        1309522677
495
                    );
496
                }
497
            }
498
        }
499
500 19
        return $documents;
501
    }
502
503
    // Initialization
504
505
    /**
506
     * Gets the Solr connections applicable for an item.
507
     *
508
     * The connections include the default connection and connections to be used
509
     * for translations of an item.
510
     *
511
     * @param Item $item An index queue item
512
     * @return array An array of ApacheSolrForTypo3\Solr\System\Solr\SolrConnection connections, the array's keys are the sys_language_uid of the language of the connection
513
     */
514 21
    protected function getSolrConnectionsByItem(Item $item)
515
    {
516 21
        $solrConnections = [];
517
518 21
        $rootPageId = $item->getRootPageUid();
519 21
        if ($item->getType() === 'pages') {
520 4
            $pageId = $item->getRecordUid();
521
        } else {
522 17
            $pageId = $item->getRecordPageId();
523
        }
524
525
        // Solr configurations possible for this item
526 21
        $site = $item->getSite();
527 21
        $solrConfigurationsBySite = $site->getAllSolrConnectionConfigurations();
528 21
        $siteLanguages = [];
529 21
        foreach ($solrConfigurationsBySite as $solrConfiguration) {
530 21
            $siteLanguages[] = $solrConfiguration['language'];
531
        }
532
533 21
        $defaultLanguageUid = $this->getDefaultLanguageUid($item, $site->getRootPage(), $siteLanguages);
534 21
        $translationOverlays = $this->getTranslationOverlaysWithConfiguredSite((int)$pageId, $site, (array)$siteLanguages);
535
536 21
        $defaultConnection = $this->connectionManager->getConnectionByPageId($rootPageId, $defaultLanguageUid, $item->getMountPointIdentifier());
537 21
        $translationConnections = $this->getConnectionsForIndexableLanguages($translationOverlays);
538
539 21
        if ($defaultLanguageUid == 0) {
540 19
            $solrConnections[0] = $defaultConnection;
541
        }
542
543 21
        foreach ($translationConnections as $systemLanguageUid => $solrConnection) {
544 19
            $solrConnections[$systemLanguageUid] = $solrConnection;
545
        }
546 21
        return $solrConnections;
547
    }
548
549
    /**
550
     * @param int $pageId
551
     * @param Site $site
552
     * @param array $siteLanguages
553
     * @return array
554
     */
555 21
    protected function getTranslationOverlaysWithConfiguredSite(int $pageId, Site $site, array $siteLanguages): array
556
    {
557 21
        $translationOverlays = $this->pagesRepository->findTranslationOverlaysByPageId($pageId);
558 21
        $translatedLanguages = [];
559 21
        foreach ($translationOverlays as $key => $translationOverlay) {
560 7
            if (!in_array($translationOverlay['sys_language_uid'], $siteLanguages)) {
561
                unset($translationOverlays[$key]);
562
            } else {
563 7
                $translatedLanguages[] = (int)$translationOverlay['sys_language_uid'];
564
            }
565
        }
566
567 21
        if (count($translationOverlays) + 1 !== count($siteLanguages)) {
568
            // not all Languages are translated
569
            // add Language Fallback
570 21
            foreach ($siteLanguages as $languageId) {
571 21
                if ($languageId !== 0 && !in_array((int)$languageId, $translatedLanguages, true)) {
572 21
                    $fallbackLanguageIds = $this->getFallbackOrder($site, (int)$languageId, (int)$pageId);
573 21
                    foreach ($fallbackLanguageIds as $fallbackLanguageId) {
574 20
                        if ($fallbackLanguageId === 0 || in_array((int)$fallbackLanguageId, $translatedLanguages, true)) {
575
                            $translationOverlay = [
576 13
                                'pid' => $pageId,
577 13
                                'sys_language_uid' => $languageId,
578 13
                                'l10n_parent' => $pageId
579
                            ];
580 13
                            $translationOverlays[] = $translationOverlay;
581 13
                            continue 2;
582
                        }
583
                    }
584
                }
585
            }
586
        }
587 21
        return $translationOverlays;
588
    }
589
590
    /**
591
     * @param Site $site
592
     * @param int $languageId
593
     * @param int $pageId
594
     * @return array
595
     */
596 21
    protected function getFallbackOrder(Site $site,  int $languageId, int $pageId): array
0 ignored issues
show
Unused Code introduced by
The parameter $pageId is not used and could be removed. ( Ignorable by Annotation )

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

596
    protected function getFallbackOrder(Site $site,  int $languageId, /** @scrutinizer ignore-unused */ int $pageId): array

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
597
    {
598 21
        $fallbackChain = [];
599 21
        $siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
600
        try {
601 21
            $site = $siteFinder->getSiteByRootPageId($site->getRootPageId());
602 20
            $languageAspect = LanguageAspectFactory::createFromSiteLanguage($site->getLanguageById($languageId));
603 20
            $fallbackChain = $languageAspect->getFallbackChain();
604 1
        } catch (SiteNotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
605
606
        }
607 21
        return $fallbackChain;
608
    }
609
610
611
    /**
612
     * @param Item $item An index queue item
613
     * @param array $rootPage
614
     * @param array $siteLanguages
615
     *
616
     * @return int
617
     * @throws \RuntimeException
618
     */
619 21
    protected function getDefaultLanguageUid(Item $item, array $rootPage, array $siteLanguages)
620
    {
621 21
        $defaultLanguageUid = 0;
622 21
        if (($rootPage['l18n_cfg'] & 1) == 1 && count($siteLanguages) == 1 && $siteLanguages[min(array_keys($siteLanguages))] > 0) {
623
            $defaultLanguageUid = $siteLanguages[min(array_keys($siteLanguages))];
624 21
        } elseif (($rootPage['l18n_cfg'] & 1) == 1 && count($siteLanguages) > 1) {
625 2
            unset($siteLanguages[array_search('0', $siteLanguages)]);
626 2
            $defaultLanguageUid = $siteLanguages[min(array_keys($siteLanguages))];
627 19
        } elseif (($rootPage['l18n_cfg'] & 1) == 1 && count($siteLanguages) == 1) {
628
            $message = 'Root page ' . (int)$item->getRootPageUid() . ' is set to hide default translation, but no other language is configured!';
629
            throw new \RuntimeException($message);
630
        }
631
632 21
        return $defaultLanguageUid;
633
    }
634
635
    /**
636
     * Checks for which languages connections have been configured and returns
637
     * these connections.
638
     *
639
     * @param array $translationOverlays An array of translation overlays to check for configured connections.
640
     * @return array An array of ApacheSolrForTypo3\Solr\System\Solr\SolrConnection connections.
641
     */
642 21
    protected function getConnectionsForIndexableLanguages(array $translationOverlays)
643
    {
644 21
        $connections = [];
645
646 21
        foreach ($translationOverlays as $translationOverlay) {
647 20
            $pageId = $translationOverlay['l10n_parent'];
648 20
            $languageId = $translationOverlay['sys_language_uid'];
649
650
            try {
651 20
                $connection = $this->connectionManager->getConnectionByPageId($pageId, $languageId);
652 19
                $connections[$languageId] = $connection;
653 1
            } catch (NoSolrConnectionFoundException $e) {
654
                // ignore the exception as we seek only those connections
655
                // actually available
656
            }
657
        }
658
659 21
        return $connections;
660
    }
661
662
    // Utility methods
663
664
    // FIXME extract log() and setLogging() to ApacheSolrForTypo3\Solr\IndexQueue\AbstractIndexer
665
    // FIXME extract an interface Tx_Solr_IndexQueue_ItemInterface
666
667
    /**
668
     * Enables logging dependent on the configuration of the item's site
669
     *
670
     * @param Item $item An item being indexed
671
     * @return    void
672
     */
673 19
    protected function setLogging(Item $item)
674
    {
675 19
        $solrConfiguration = $this->frontendEnvironment->getSolrConfigurationFromPageId($item->getRootPageUid());
676 19
        $this->loggingEnabled = $solrConfiguration->getLoggingIndexingQueueOperationsByConfigurationNameWithFallBack(
677 19
            $item->getIndexingConfigurationName()
678
        );
679 19
    }
680
681
    /**
682
     * Logs the item and what document was created from it
683
     *
684
     * @param Item $item The item that is being indexed.
685
     * @param array $itemDocuments An array of Solr documents created from the item's data
686
     * @param ResponseAdapter $response The Solr response for the particular index document
687
     */
688 19
    protected function log(Item $item, array $itemDocuments, ResponseAdapter $response)
689
    {
690 19
        if (!$this->loggingEnabled) {
691 19
            return;
692
        }
693
694
        $message = 'Index Queue indexing ' . $item->getType() . ':' . $item->getRecordUid() . ' - ';
695
696
        // preparing data
697
        $documents = [];
698
        foreach ($itemDocuments as $document) {
699
            $documents[] = (array)$document;
700
        }
701
702
        $logData = ['item' => (array)$item, 'documents' => $documents, 'response' => (array)$response];
703
704
        if ($response->getHttpStatus() == 200) {
705
            $severity = SolrLogManager::NOTICE;
706
            $message .= 'Success';
707
        } else {
708
            $severity = SolrLogManager::ERROR;
709
            $message .= 'Failure';
710
711
            $logData['status'] = $response->getHttpStatus();
712
            $logData['status message'] = $response->getHttpStatusMessage();
713
        }
714
715
        $this->logger->log($severity, $message, $logData);
716
    }
717
}
718