Failed Conditions
Push — master ( 5f60a5...9b80eb )
by Rafael
21:42
created

Classes/IndexQueue/Indexer.php (1 issue)

Labels
Severity
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 Apache_Solr_Document;
28
use Apache_Solr_Response;
29
use ApacheSolrForTypo3\Solr\ConnectionManager;
30
use ApacheSolrForTypo3\Solr\Domain\Search\ApacheSolrDocument\Builder;
31
use ApacheSolrForTypo3\Solr\FieldProcessor\Service;
32
use ApacheSolrForTypo3\Solr\NoSolrConnectionFoundException;
33
use ApacheSolrForTypo3\Solr\Site;
34
use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager;
35
use ApacheSolrForTypo3\Solr\System\Records\Pages\PagesRepository;
36
use ApacheSolrForTypo3\Solr\System\Solr\SolrConnection;
37
use ApacheSolrForTypo3\Solr\Util;
38
use TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider;
0 ignored issues
show
The type TYPO3\CMS\Backend\Config...onConfigurationProvider was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
39
use TYPO3\CMS\Core\Utility\GeneralUtility;
40
use TYPO3\CMS\Frontend\Page\PageRepository;
41
42
/**
43
 * A general purpose indexer to be used for indexing of any kind of regular
44
 * records like tt_news, tt_address, and so on.
45
 * Specialized indexers can extend this class to handle advanced stuff like
46
 * category resolution in tt_news or file indexing.
47
 *
48
 * @author Ingo Renner <[email protected]>
49
 */
50
class Indexer extends AbstractIndexer
51
{
52
53
    # TODO change to singular $document instead of plural $documents
54
55
    /**
56
     * A Solr service instance to interact with the Solr server
57
     *
58
     * @var SolrConnection
59
     */
60
    protected $solr;
61
62
    /**
63
     * @var ConnectionManager
64
     */
65
    protected $connectionManager;
66
67
    /**
68
     * Holds options for a specific indexer
69
     *
70
     * @var array
71
     */
72
    protected $options = [];
73
74
    /**
75
     * To log or not to log... #Shakespeare
76
     *
77
     * @var bool
78
     */
79
    protected $loggingEnabled = false;
80
81
    /**
82
     * @var \ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager
83
     */
84
    protected $logger = null;
85
86
    /**
87
     * @var PagesRepository
88
     */
89
    protected $pagesRepository;
90
91
    /**
92
     * @var Builder
93
     */
94
    protected $documentBuilder;
95
96
    /**
97
     * Constructor
98
     *
99
     * @param array $options array of indexer options
100
     * @param PagesRepository|null $pagesRepository
101
     * @param Builder|null $documentBuilder
102
     */
103 25
    public function __construct(array $options = [], PagesRepository $pagesRepository = null, Builder $documentBuilder = null)
104
    {
105 25
        $this->logger = GeneralUtility::makeInstance(SolrLogManager::class, __CLASS__);
106 25
        $this->options = $options;
107 25
        $this->connectionManager = GeneralUtility::makeInstance(ConnectionManager::class);
108 25
        $this->pagesRepository = isset($pagesRepository) ? $pagesRepository : GeneralUtility::makeInstance(PagesRepository::class);
109 25
        $this->documentBuilder = isset($documentBuilder) ? $documentBuilder : GeneralUtility::makeInstance(Builder::class);
110 25
    }
111
112
    /**
113
     * Indexes an item from the indexing queue.
114
     *
115
     * @param Item $item An index queue item
116
     * @return bool returns true when indexed, false when not
117
     */
118 19
    public function index(Item $item)
119
    {
120 19
        $indexed = true;
121
122 19
        $this->type = $item->getType();
123 19
        $this->setLogging($item);
124
125 19
        $solrConnections = $this->getSolrConnectionsByItem($item);
126 19
        foreach ($solrConnections as $systemLanguageUid => $solrConnection) {
127 19
            $this->solr = $solrConnection;
128
129 19
            if (!$this->indexItem($item, $systemLanguageUid)) {
130
                /*
131
                 * A single language voting for "not indexed" should make the whole
132
                 * item count as being not indexed, even if all other languages are
133
                 * indexed.
134
                 * If there is no translation for a single language, this item counts
135
                 * as TRUE since it's not an error which that should make the item
136
                 * being reindexed during another index run.
137
                 */
138 19
                $indexed = false;
139
            }
140
        }
141
142 19
        return $indexed;
143
    }
144
145
    /**
146
     * Creates a single Solr Document for an item in a specific language.
147
     *
148
     * @param Item $item An index queue item to index.
149
     * @param int $language The language to use.
150
     * @return bool TRUE if item was indexed successfully, FALSE on failure
151
     */
152 19
    protected function indexItem(Item $item, $language = 0)
153
    {
154 19
        $itemIndexed = false;
155 19
        $documents = [];
156
157 19
        $itemDocument = $this->itemToDocument($item, $language);
158 19
        if (is_null($itemDocument)) {
159
            /*
160
             * If there is no itemDocument, this means there was no translation
161
             * for this record. This should not stop the current item to count as
162
             * being valid because not-indexing not-translated items is perfectly
163
             * fine.
164
             */
165 1
            return true;
166
        }
167
168 19
        $documents[] = $itemDocument;
169 19
        $documents = array_merge($documents, $this->getAdditionalDocuments($item, $language, $itemDocument));
170 19
        $documents = $this->processDocuments($item, $documents);
171 19
        $documents = $this->preAddModifyDocuments($item, $language, $documents);
172
173 19
        $response = $this->solr->getWriteService()->addDocuments($documents);
174 19
        if ($response->getHttpStatus() == 200) {
175 19
            $itemIndexed = true;
176
        }
177
178 19
        $this->log($item, $documents, $response);
179
180 19
        return $itemIndexed;
181
    }
182
183
    /**
184
     * Gets the full item record.
185
     *
186
     * This general record indexer simply gets the record from the item. Other
187
     * more specialized indexers may provide more data for their specific item
188
     * types.
189
     *
190
     * @param Item $item The item to be indexed
191
     * @param int $language Language Id (sys_language.uid)
192
     * @return array|NULL The full record with fields of data to be used for indexing or NULL to prevent an item from being indexed
193
     */
194 19
    protected function getFullItemRecord(Item $item, $language = 0)
195
    {
196 19
        Util::initializeTsfe($item->getRootPageUid(), $language);
197
198 19
        $systemLanguageContentOverlay = $GLOBALS['TSFE']->sys_language_contentOL;
199 19
        $itemRecord = $this->getItemRecordOverlayed($item, $language, $systemLanguageContentOverlay);
200
201
        /*
202
         * Skip disabled records. This happens if the default language record
203
         * is hidden but a certain translation isn't. Then the default language
204
         * document appears here but must not be indexed.
205
         */
206 19
        if (!empty($GLOBALS['TCA'][$item->getType()]['ctrl']['enablecolumns']['disabled'])
207 19
            && $itemRecord[$GLOBALS['TCA'][$item->getType()]['ctrl']['enablecolumns']['disabled']]
208
        ) {
209
            $itemRecord = null;
210
        }
211
212
        /*
213
         * Skip translation mismatching records. Sometimes the requested language
214
         * doesn't fit the returned language. This might happen with content fallback
215
         * and is perfectly fine in general.
216
         * But if the requested language doesn't match the returned language and
217
         * the given record has no translation parent, the indexqueue_item most
218
         * probably pointed to a non-translated language record that is dedicated
219
         * to a very specific language. Now we have to avoid indexing this record
220
         * into all language cores.
221
         */
222 19
        $translationOriginalPointerField = 'l10n_parent';
223 19
        if (!empty($GLOBALS['TCA'][$item->getType()]['ctrl']['transOrigPointerField'])) {
224 18
            $translationOriginalPointerField = $GLOBALS['TCA'][$item->getType()]['ctrl']['transOrigPointerField'];
225
        }
226
227 19
        $languageField = $GLOBALS['TCA'][$item->getType()]['ctrl']['languageField'];
228 19
        if ($itemRecord[$translationOriginalPointerField] == 0
229 19
            && $systemLanguageContentOverlay != 1
230 19
            && !empty($languageField)
231 19
            && $itemRecord[$languageField] != $language
232 19
            && $itemRecord[$languageField] != '-1'
233
        ) {
234 1
            $itemRecord = null;
235
        }
236
237 19
        if (!is_null($itemRecord)) {
238 19
            $itemRecord['__solr_index_language'] = $language;
239
        }
240
241 19
        return $itemRecord;
242
    }
243
244
    /**
245
     * Returns the overlayed item record.
246
     *
247
     * @param Item $item
248
     * @param int $language
249
     * @param string|null $systemLanguageContentOverlay
250
     * @return array|mixed|null
251
     */
252 19
    protected function getItemRecordOverlayed(Item $item, $language, $systemLanguageContentOverlay)
253
    {
254 19
        $itemRecord = $item->getRecord();
255
256 19
        if ($language > 0) {
257 6
            $page = GeneralUtility::makeInstance(PageRepository::class);
258 6
            $page->init(false);
259 6
            $itemRecord = $page->getRecordOverlay($item->getType(), $itemRecord, $language, $systemLanguageContentOverlay);
260
        }
261
262 19
        if (!$itemRecord) {
263
            $itemRecord = null;
264
        }
265
266 19
        return $itemRecord;
267
    }
268
269
    /**
270
     * Gets the configuration how to process an item's fields for indexing.
271
     *
272
     * @param Item $item An index queue item
273
     * @param int $language Language ID
274
     * @throws \RuntimeException
275
     * @return array Configuration array from TypoScript
276
     */
277 19
    protected function getItemTypeConfiguration(Item $item, $language = 0)
278
    {
279 19
        $indexConfigurationName = $item->getIndexingConfigurationName();
280 19
        $fields = $this->getFieldConfigurationFromItemRecordPage($item, $language, $indexConfigurationName);
281 19
        if (count($fields) === 0) {
282 1
            $fields = $this->getFieldConfigurationFromItemRootPage($item, $language, $indexConfigurationName);
283 1
            if (count($fields) === 0) {
284
                throw new \RuntimeException('The item indexing configuration "' . $item->getIndexingConfigurationName() .
285
                    '" on root page uid ' . $item->getRootPageUid() . ' could not be found!', 1455530112);
286
            }
287
        }
288
289 19
        return $fields;
290
    }
291
292
    /**
293
     * The method retrieves the field configuration of the items record page id (pid).
294
     *
295
     * @param Item $item
296
     * @param integer $language
297
     * @param string $indexConfigurationName
298
     * @return array
299
     */
300 19
    protected function getFieldConfigurationFromItemRecordPage(Item $item, $language, $indexConfigurationName)
301
    {
302
        try {
303 19
            $solrConfiguration = Util::getSolrConfigurationFromPageId($item->getRecordPageId(), true, $language);
304 18
            return $solrConfiguration->getIndexQueueFieldsConfigurationByConfigurationName($indexConfigurationName, []);
305 1
        } catch (\Exception $e) {
306 1
            return [];
307
        }
308
    }
309
310
    /**
311
     * The method returns the field configuration of the items root page id (uid of the related root page).
312
     *
313
     * @param Item $item
314
     * @param integer $language
315
     * @param string $indexConfigurationName
316
     * @return array
317
     */
318 1
    protected function getFieldConfigurationFromItemRootPage(Item $item, $language, $indexConfigurationName)
319
    {
320 1
        $solrConfiguration = Util::getSolrConfigurationFromPageId($item->getRootPageUid(), true, $language);
321 1
        if (empty($solrConfiguration->getIndexQueueAdditionalPageIdsByConfigurationName($indexConfigurationName))) {
322
            return [];
323
        }
324
325 1
        return $solrConfiguration->getIndexQueueFieldsConfigurationByConfigurationName($indexConfigurationName, []);
326
    }
327
328
    /**
329
     * Converts an item array (record) to a Solr document by mapping the
330
     * record's fields onto Solr document fields as configured in TypoScript.
331
     *
332
     * @param Item $item An index queue item
333
     * @param int $language Language Id
334
     * @return Apache_Solr_Document The Solr document converted from the record
335
     */
336 19
    protected function itemToDocument(Item $item, $language = 0)
337
    {
338 19
        $document = null;
339
340 19
        $itemRecord = $this->getFullItemRecord($item, $language);
341 19
        if (!is_null($itemRecord)) {
342 19
            $itemIndexingConfiguration = $this->getItemTypeConfiguration($item, $language);
343 19
            $document = $this->getBaseDocument($item, $itemRecord);
344 19
            $document = $this->addDocumentFieldsFromTyposcript($document, $itemIndexingConfiguration, $itemRecord);
345
        }
346
347 19
        return $document;
348
    }
349
350
    /**
351
     * Creates a Solr document with the basic / core fields set already.
352
     *
353
     * @param Item $item The item to index
354
     * @param array $itemRecord The record to use to build the base document
355
     * @return Apache_Solr_Document A basic Solr document
356
     */
357 19
    protected function getBaseDocument(Item $item, array $itemRecord)
358
    {
359 19
        $type = $item->getType();
360 19
        $rootPageUid = $item->getRootPageUid();
361 19
        $accessRootLine = $this->getAccessRootline($item);
362 19
        return $this->documentBuilder->fromRecord($itemRecord, $type, $rootPageUid, $accessRootLine);
363
    }
364
365
    /**
366
     * Generates an Access Rootline for an item.
367
     *
368
     * @param Item $item Index Queue item to index.
369
     * @return string The Access Rootline for the item
370
     */
371 19
    protected function getAccessRootline(Item $item)
372
    {
373 19
        $accessRestriction = '0';
374 19
        $itemRecord = $item->getRecord();
375
376
        // TODO support access restrictions set on storage page
377
378 19
        if (isset($GLOBALS['TCA'][$item->getType()]['ctrl']['enablecolumns']['fe_group'])) {
379 1
            $accessRestriction = $itemRecord[$GLOBALS['TCA'][$item->getType()]['ctrl']['enablecolumns']['fe_group']];
380
381 1
            if (empty($accessRestriction)) {
382
                // public
383 1
                $accessRestriction = '0';
384
            }
385
        }
386
387 19
        return 'r:' . $accessRestriction;
388
    }
389
390
    /**
391
     * Sends the documents to the field processing service which takes care of
392
     * manipulating fields as defined in the field's configuration.
393
     *
394
     * @param Item $item An index queue item
395
     * @param array $documents An array of Apache_Solr_Document objects to manipulate.
396
     * @return array Array of manipulated Apache_Solr_Document objects.
397
     */
398 19
    protected function processDocuments(Item $item, array $documents)
399
    {
400
        // needs to respect the TS settings for the page the item is on, conditions may apply
401 19
        $solrConfiguration = Util::getSolrConfigurationFromPageId($item->getRootPageUid());
402 19
        $fieldProcessingInstructions = $solrConfiguration->getIndexFieldProcessingInstructionsConfiguration();
403
404
        // same as in the FE indexer
405 19
        if (is_array($fieldProcessingInstructions)) {
406 19
            $service = GeneralUtility::makeInstance(Service::class);
407 19
            $service->processDocuments($documents, $fieldProcessingInstructions);
408
        }
409
410 19
        return $documents;
411
    }
412
413
    /**
414
     * Allows third party extensions to provide additional documents which
415
     * should be indexed for the current item.
416
     *
417
     * @param Item $item The item currently being indexed.
418
     * @param int $language The language uid currently being indexed.
419
     * @param Apache_Solr_Document $itemDocument The document representing the item for the given language.
420
     * @return array An array of additional Apache_Solr_Document objects to index.
421
     */
422 23
    protected function getAdditionalDocuments(Item $item, $language, Apache_Solr_Document $itemDocument)
423
    {
424 23
        $documents = [];
425
426 23
        if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['IndexQueueIndexer']['indexItemAddDocuments'])) {
427 4
            foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['IndexQueueIndexer']['indexItemAddDocuments'] as $classReference) {
428 4
                if (!class_exists($classReference)) {
429 2
                    throw new \InvalidArgumentException('Class does not exits' . $classReference, 1490363487);
430
                }
431 2
                $additionalIndexer = GeneralUtility::makeInstance($classReference);
432 2
                if ($additionalIndexer instanceof AdditionalIndexQueueItemIndexer) {
433 1
                    $additionalDocuments = $additionalIndexer->getAdditionalItemDocuments($item, $language, $itemDocument);
434
435 1
                    if (is_array($additionalDocuments)) {
436 1
                        $documents = array_merge($documents,
437 1
                            $additionalDocuments);
438
                    }
439
                } else {
440 1
                    throw new \UnexpectedValueException(
441 1
                        get_class($additionalIndexer) . ' must implement interface ' . AdditionalIndexQueueItemIndexer::class,
442 2
                        1326284551
443
                    );
444
                }
445
            }
446
        }
447 20
        return $documents;
448
    }
449
450
    /**
451
     * Provides a hook to manipulate documents right before they get added to
452
     * the Solr index.
453
     *
454
     * @param Item $item The item currently being indexed.
455
     * @param int $language The language uid of the documents
456
     * @param array $documents An array of documents to be indexed
457
     * @return array An array of modified documents
458
     */
459 19
    protected function preAddModifyDocuments(Item $item, $language, array $documents)
460
    {
461 19
        if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['IndexQueueIndexer']['preAddModifyDocuments'])) {
462
            foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['IndexQueueIndexer']['preAddModifyDocuments'] as $classReference) {
463
                $documentsModifier = GeneralUtility::makeInstance($classReference);
464
465
                if ($documentsModifier instanceof PageIndexerDocumentsModifier) {
466
                    $documents = $documentsModifier->modifyDocuments($item, $language, $documents);
467
                } else {
468
                    throw new \RuntimeException(
469
                        'The class "' . get_class($documentsModifier)
470
                        . '" registered as document modifier in hook
471
							preAddModifyDocuments must implement interface
472
							ApacheSolrForTypo3\Solr\IndexQueue\PageIndexerDocumentsModifier',
473
                        1309522677
474
                    );
475
                }
476
            }
477
        }
478
479 19
        return $documents;
480
    }
481
482
    // Initialization
483
484
    /**
485
     * Gets the Solr connections applicable for an item.
486
     *
487
     * The connections include the default connection and connections to be used
488
     * for translations of an item.
489
     *
490
     * @param Item $item An index queue item
491
     * @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
492
     */
493 21
    protected function getSolrConnectionsByItem(Item $item)
494
    {
495 21
        $solrConnections = [];
496
497 21
        $pageId = $item->getRootPageUid();
498 21
        if ($item->getType() === 'pages') {
499 3
            $pageId = $item->getRecordUid();
500
        }
501
502
        // Solr configurations possible for this item
503 21
        $site = $item->getSite();
504
505 21
        $solrConfigurationsBySite = $this->connectionManager->getConfigurationsBySite($site);
506 21
        $siteLanguages = [];
507 21
        foreach ($solrConfigurationsBySite as $solrConfiguration) {
508 21
            $siteLanguages[] = $solrConfiguration['language'];
509
        }
510
511 21
        $defaultLanguageUid = $this->getDefaultLanguageUid($item, $site->getRootPage(), $siteLanguages);
512 21
        $translationOverlays = $this->getTranslationOverlaysWithConfiguredSite($pageId, $site, $defaultLanguageUid, $siteLanguages);
513
514 21
        $defaultConnection = $this->connectionManager->getConnectionByPageId($pageId, 0, $item->getMountPointIdentifier());
515 21
        $translationConnections = $this->getConnectionsForIndexableLanguages($translationOverlays);
516
517 21
        if ($defaultLanguageUid == 0) {
518 20
            $solrConnections[0] = $defaultConnection;
519
        }
520
521 21
        foreach ($translationConnections as $systemLanguageUid => $solrConnection) {
522 7
            $solrConnections[$systemLanguageUid] = $solrConnection;
523
        }
524 21
        return $solrConnections;
525
    }
526
527
    /**
528
     * Retrieves only translation overlays where a solr site is configured.
529
     *
530
     * @param int $pageId
531
     * @param Site $site
532
     * @param int $defaultLanguageUid
533
     * @param $siteLanguages
534
     * @return array
535
     */
536 21
    protected function getTranslationOverlaysWithConfiguredSite($pageId, Site $site, $defaultLanguageUid, $siteLanguages)
537
    {
538 21
        $translationOverlays = $this->getTranslationOverlaysForPage($pageId, $site->getSysLanguageMode($defaultLanguageUid));
539
540 21
        foreach ($translationOverlays as $key => $translationOverlay) {
541 7
            if (!in_array($translationOverlay['sys_language_uid'], $siteLanguages)) {
542 7
                unset($translationOverlays[$key]);
543
            }
544
        }
545
546 21
        return $translationOverlays;
547
    }
548
549
    /**
550
     * @param Item $item An index queue item
551
     * @param array $rootPage
552
     * @param array $siteLanguages
553
     *
554
     * @return int
555
     * @throws \Apache_Solr_Exception
556
     */
557 21
    private function getDefaultLanguageUid(Item $item, array $rootPage, array $siteLanguages)
558
    {
559 21
        $defaultLanguageUid = 0;
560 21
        if (($rootPage['l18n_cfg'] & 1) == 1 && count($siteLanguages) > 1) {
561 1
            unset($siteLanguages[array_search('0', $siteLanguages)]);
562 1
            $defaultLanguageUid = $siteLanguages[min(array_keys($siteLanguages))];
563 20
        } elseif (($rootPage['l18n_cfg'] & 1) == 1 && count($siteLanguages) == 1) {
564
            $message = 'Root page ' . (int)$item->getRootPageUid() . ' is set to hide default translation, but no other language is configured!';
565
            throw new \Apache_Solr_Exception($message);
566
        }
567
568 21
        return $defaultLanguageUid;
569
    }
570
571
    /**
572
     * Finds the alternative page language overlay records for a page based on
573
     * the sys_language_mode.
574
     *
575
     * Possible Language Modes:
576
     * 1) content_fallback --> all languages
577
     * 2) strict --> available languages with page overlay
578
     * 3) ignore --> available languages with page overlay
579
     * 4) unknown mode or blank --> all languages
580
     *
581
     * @param int $pageId Page ID.
582
     * @param string $languageMode
583
     * @return array An array of translation overlays (or fake overlays) found for the given page.
584
     */
585 21
    protected function getTranslationOverlaysForPage($pageId, $languageMode)
586
    {
587 21
        $translationOverlays = [];
588 21
        $pageId = intval($pageId);
589
590 21
        $languageModes = ['content_fallback', 'strict', 'ignore'];
591 21
        $hasOverlayMode = in_array($languageMode, $languageModes,
592 21
            true);
593 21
        $isContentFallbackMode = ($languageMode === 'content_fallback');
594
595 21
        if ($hasOverlayMode && !$isContentFallbackMode) {
596 6
            $translationOverlays = $this->pagesRepository->findTranslationOverlaysByPageId($pageId);
597
        } else {
598
            // ! If no sys_language_mode is configured, all languages will be indexed !
599 15
            $languages = $this->getSystemLanguages();
600 15
            foreach ($languages as $language) {
601 15
                if ($language['uid'] <= 0) {
602 15
                    continue;
603
                }
604 1
                $translationOverlays[] = [
605 1
                    'pid' => $pageId,
606 1
                    'l10n_parent' => $pageId,
607 1
                    'sys_language_uid' => $language['uid'],
608
                ];
609
            }
610
        }
611
612 21
        return $translationOverlays;
613
    }
614
615
    /**
616
     * Returns an array of system languages.
617
     *
618
     * @return array
619
     */
620 15
    protected function getSystemLanguages()
621
    {
622 15
        return GeneralUtility::makeInstance(TranslationConfigurationProvider::class)->getSystemLanguages();
623
    }
624
625
    /**
626
     * Checks for which languages connections have been configured and returns
627
     * these connections.
628
     *
629
     * @param array $translationOverlays An array of translation overlays to check for configured connections.
630
     * @return array An array of ApacheSolrForTypo3\Solr\System\Solr\SolrConnection connections.
631
     */
632 21
    protected function getConnectionsForIndexableLanguages(array $translationOverlays)
633
    {
634 21
        $connections = [];
635
636 21
        foreach ($translationOverlays as $translationOverlay) {
637
            // @todo usage of pid can be removed when TYPO3 8 compatibility is dropped
638 7
            $pageId = (Util::getIsTYPO3VersionBelow9()) ? $translationOverlay['pid'] : $translationOverlay['l10n_parent'];
639 7
            $languageId = $translationOverlay['sys_language_uid'];
640
641
            try {
642 7
                $connection = $this->connectionManager->getConnectionByPageId($pageId, $languageId);
643 7
                $connections[$languageId] = $connection;
644 7
            } catch (NoSolrConnectionFoundException $e) {
645
                // ignore the exception as we seek only those connections
646
                // actually available
647
            }
648
        }
649
650 21
        return $connections;
651
    }
652
653
    // Utility methods
654
655
    // FIXME extract log() and setLogging() to ApacheSolrForTypo3\Solr\IndexQueue\AbstractIndexer
656
    // FIXME extract an interface Tx_Solr_IndexQueue_ItemInterface
657
658
    /**
659
     * Enables logging dependent on the configuration of the item's site
660
     *
661
     * @param Item $item An item being indexed
662
     * @return    void
663
     */
664 20
    protected function setLogging(Item $item)
665
    {
666 20
        $solrConfiguration = Util::getSolrConfigurationFromPageId($item->getRootPageUid());
667 20
        $this->loggingEnabled = $solrConfiguration->getLoggingIndexingQueueOperationsByConfigurationNameWithFallBack(
668 20
            $item->getIndexingConfigurationName()
669
        );
670 20
    }
671
672
    /**
673
     * Logs the item and what document was created from it
674
     *
675
     * @param Item $item The item that is being indexed.
676
     * @param array $itemDocuments An array of Solr documents created from the item's data
677
     * @param Apache_Solr_Response $response The Solr response for the particular index document
678
     */
679 19
    protected function log(Item $item, array $itemDocuments, Apache_Solr_Response $response)
680
    {
681 19
        if (!$this->loggingEnabled) {
682 19
            return;
683
        }
684
685
        $message = 'Index Queue indexing ' . $item->getType() . ':' . $item->getRecordUid() . ' - ';
686
687
        // preparing data
688
        $documents = [];
689
        foreach ($itemDocuments as $document) {
690
            $documents[] = (array)$document;
691
        }
692
693
        $logData = ['item' => (array)$item, 'documents' => $documents, 'response' => (array)$response];
694
695
        if ($response->getHttpStatus() == 200) {
696
            $severity = SolrLogManager::NOTICE;
697
            $message .= 'Success';
698
        } else {
699
            $severity = SolrLogManager::ERROR;
700
            $message .= 'Failure';
701
702
            $logData['status'] = $response->getHttpStatus();
703
            $logData['status message'] = $response->getHttpStatusMessage();
704
        }
705
706
        $this->logger->log($severity, $message, $logData);
707
    }
708
}
709