Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Pull Request — dev-extbase-fluid (#754)
by Alexander
02:42
created

DocumentRepository::fetchMetadataFromSolr()   B

Complexity

Conditions 11
Paths 5

Size

Total Lines 51
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 28
c 0
b 0
f 0
nc 5
nop 3
dl 0
loc 51
rs 7.3166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
5
 *
6
 * This file is part of the Kitodo and TYPO3 projects.
7
 *
8
 * @license GNU General Public License version 3 or later.
9
 * For the full copyright and license information, please read the
10
 * LICENSE.txt file that was distributed with this source code.
11
 */
12
13
namespace Kitodo\Dlf\Domain\Repository;
14
15
use Kitodo\Dlf\Common\Doc;
16
use Kitodo\Dlf\Common\Helper;
17
use Kitodo\Dlf\Common\Solr;
18
use Kitodo\Dlf\Domain\Model\Document;
19
use TYPO3\CMS\Core\Database\ConnectionPool;
20
use TYPO3\CMS\Core\Database\Connection;
21
use TYPO3\CMS\Core\Utility\GeneralUtility;
22
use TYPO3\CMS\Core\Utility\MathUtility;
23
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
24
25
class DocumentRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
26
{
27
    /**
28
     * Find one document by given parameters
29
     *
30
     * GET parameters may be:
31
     *
32
     * - 'id': the uid of the document
33
     * - 'location': the URL of the location of the XML file
34
     * - 'recordId': the record_id of the document
35
     *
36
     * @param array $parameters
37
     *
38
     * @return \Kitodo\Dlf\Domain\Model\Document|null
39
     */
40
    public function findOneByParameters($parameters)
41
    {
42
        $doc = null;
43
        $document = null;
44
45
        if (isset($parameters['id']) && MathUtility::canBeInterpretedAsInteger($parameters['id'])) {
46
47
            $document = $this->findOneByIdAndSettings($parameters['id']);
48
49
        } else if (isset($parameters['recordId'])) {
50
51
            $document = $this->findOneByRecordId($parameters['recordId']);
0 ignored issues
show
Bug introduced by
The method findOneByRecordId() does not exist on Kitodo\Dlf\Domain\Repository\DocumentRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

51
            /** @scrutinizer ignore-call */ 
52
            $document = $this->findOneByRecordId($parameters['recordId']);
Loading history...
52
53
        } else if (isset($parameters['location']) && GeneralUtility::isValidUrl($parameters['location'])) {
54
55
            $doc = Doc::getInstance($parameters['location'], [], true);
56
57
            if ($doc->recordId) {
58
                $document = $this->findOneByRecordId($doc->recordId);
59
            }
60
61
            if ($document === null) {
62
                // create new (dummy) Document object
63
                $document = GeneralUtility::makeInstance(Document::class);
64
                $document->setLocation($parameters['location']);
65
            }
66
67
        }
68
69
        if ($document !== null && $doc === null) {
70
            $doc = Doc::getInstance($document->getLocation(), [], true);
0 ignored issues
show
Bug introduced by
The method getLocation() does not exist on TYPO3\CMS\Extbase\Persistence\QueryResultInterface. ( Ignorable by Annotation )

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

70
            $doc = Doc::getInstance($document->/** @scrutinizer ignore-call */ getLocation(), [], true);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
71
        }
72
73
        if ($doc !== null) {
74
            $document->setDoc($doc);
0 ignored issues
show
Bug introduced by
The method setDoc() does not exist on TYPO3\CMS\Extbase\Persistence\QueryResultInterface. ( Ignorable by Annotation )

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

74
            $document->/** @scrutinizer ignore-call */ 
75
                       setDoc($doc);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
75
        }
76
77
        return $document;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $document also could return the type TYPO3\CMS\Extbase\Persis...y<mixed,object>|integer which is incompatible with the documented return type Kitodo\Dlf\Domain\Model\Document|null.
Loading history...
78
79
    }
80
81
82
    public function findByUidAndPartOf($uid, $partOf)
83
    {
84
        $query = $this->createQuery();
85
86
        $query->matching($query->equals('uid', $uid));
87
        $query->matching($query->equals('partof', $partOf));
88
89
        return $query->execute();
90
    }
91
92
    /**
93
     * Find the oldest document
94
     *
95
     * @return \Kitodo\Dlf\Domain\Model\Document|null
96
     */
97
    public function findOldestDocument()
98
    {
99
        $query = $this->createQuery();
100
101
        $query->setOrderings(['tstamp' => QueryInterface::ORDER_ASCENDING]);
102
        $query->setLimit(1);
103
104
        return $query->execute()->getFirst();
105
    }
106
107
    /**
108
     * @param int $partOf
109
     * @param string $structure
110
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
111
     */
112
    public function getChildrenOfYearAnchor($partOf, $structure)
113
    {
114
        $query = $this->createQuery();
115
116
        $query->matching($query->equals('structure', Helper::getUidFromIndexName($structure, 'tx_dlf_structures')));
117
        $query->matching($query->equals('partof', $partOf));
118
119
        $query->setOrderings([
120
            'mets_orderlabel' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
121
        ]);
122
123
        return $query->execute();
124
    }
125
126
    /**
127
     * Finds all documents for the given settings
128
     *
129
     * @param int $uid
130
     * @param array $settings
131
     *
132
     * @return \Kitodo\Dlf\Domain\Model\Document|null
133
     */
134
    public function findOneByIdAndSettings($uid, $settings = [])
0 ignored issues
show
Unused Code introduced by
The parameter $settings 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

134
    public function findOneByIdAndSettings($uid, /** @scrutinizer ignore-unused */ $settings = [])

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...
135
    {
136
        $settings = ['documentSets' => $uid];
137
138
        return $this->findDocumentsBySettings($settings)->getFirst();
139
    }
140
141
    /**
142
     * Finds all documents for the given settings
143
     *
144
     * @param array $settings
145
     *
146
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
147
     */
148
    public function findDocumentsBySettings($settings = [])
149
    {
150
        $query = $this->createQuery();
151
152
        $constraints = [];
153
154
        if ($settings['documentSets']) {
155
            $constraints[] = $query->in('uid', GeneralUtility::intExplode(',', $settings['documentSets']));
156
        }
157
158
        if (isset($settings['excludeOther']) && (int) $settings['excludeOther'] === 0) {
159
            $query->getQuerySettings()->setRespectStoragePage(false);
160
        }
161
162
        if (count($constraints)) {
163
            $query->matching(
164
                $query->logicalAnd($constraints)
165
            );
166
        }
167
168
        return $query->execute();
169
    }
170
171
    /**
172
     * Finds all documents for the given collections
173
     *
174
     * @param array $collections
175
     * @param int $limit
176
     *
177
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
178
     */
179
    public function findAllByCollectionsLimited($collections, $limit = 50)
180
    {
181
        $query = $this->createQuery();
182
183
        // order by start_date -> start_time...
184
        $query->setOrderings(
185
            ['tstamp' => QueryInterface::ORDER_DESCENDING]
186
        );
187
188
        $constraints = [];
189
        if ($collections) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $collections of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
190
            $constraints[] = $query->in('collections.uid', $collections);
191
        }
192
193
        if (count($constraints)) {
194
            $query->matching(
195
                $query->logicalAnd($constraints)
196
            );
197
        }
198
199
        if ($limit > 0) {
200
            $query->setLimit((int) $limit);
201
        }
202
203
        return $query->execute();
204
    }
205
206
    /**
207
     * Find all the titles
208
     *
209
     * documents with partof == 0
210
     *
211
     * @param array $settings
212
     *
213
     * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
214
     */
215
    public function findAllTitles($settings = [])
216
    {
217
        $query = $this->createQuery();
218
219
        $constraints = [];
220
        $constraints[] = $query->equals('partof', 0);
221
222
        if ($settings['collections']) {
223
            $constraints[] = $query->in('collections.uid', GeneralUtility::intExplode(',', $settings['collections']));
224
        }
225
226
        if (count($constraints)) {
227
            $query->matching(
228
                $query->logicalAnd($constraints)
229
            );
230
        }
231
232
        return $query->execute();
233
    }
234
235
    /**
236
     * Count the titles
237
     *
238
     * documents with partof == 0
239
     *
240
     * @param array $settings
241
     *
242
     * @return int
243
     */
244
    public function countAllTitles($settings = [])
245
    {
246
        return $this->findAllTitles($settings)->count();
247
    }
248
249
    /**
250
     * Count the volumes
251
     *
252
     * documents with partof != 0
253
     *
254
     * @param array $settings
255
     *
256
     * @return int
257
     */
258
    public function countAllVolumes($settings = [])
259
    {
260
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
261
            ->getQueryBuilderForTable('tx_dlf_documents');
262
        $subQueryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
263
            ->getQueryBuilderForTable('tx_dlf_documents');
264
265
        $subQuery = $subQueryBuilder
266
            ->select('tx_dlf_documents.partof')
267
            ->from('tx_dlf_documents')
268
            ->where(
269
                $subQueryBuilder->expr()->neq('tx_dlf_documents.partof', 0)
270
            )
271
            ->groupBy('tx_dlf_documents.partof')
272
            ->getSQL();
273
274
        $countVolumes = $queryBuilder
275
            ->count('tx_dlf_documents.uid')
276
            ->from('tx_dlf_documents')
277
            ->where(
278
                $queryBuilder->expr()->eq('tx_dlf_documents.pid', intval($settings['pages'])),
279
                $queryBuilder->expr()->notIn('tx_dlf_documents.uid', $subQuery)
280
            )
281
            ->execute()
282
            ->fetchColumn(0);
283
284
        return $countVolumes;
285
    }
286
287
    public function getStatisticsForSelectedCollection($settings)
288
    {
289
        // Include only selected collections.
290
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
291
            ->getQueryBuilderForTable('tx_dlf_documents');
292
293
        $countTitles = $queryBuilder
294
            ->count('tx_dlf_documents.uid')
295
            ->from('tx_dlf_documents')
296
            ->innerJoin(
297
                'tx_dlf_documents',
298
                'tx_dlf_relations',
299
                'tx_dlf_relations_joins',
300
                $queryBuilder->expr()->eq(
301
                    'tx_dlf_relations_joins.uid_local',
302
                    'tx_dlf_documents.uid'
303
                )
304
            )
305
            ->innerJoin(
306
                'tx_dlf_relations_joins',
307
                'tx_dlf_collections',
308
                'tx_dlf_collections_join',
309
                $queryBuilder->expr()->eq(
310
                    'tx_dlf_relations_joins.uid_foreign',
311
                    'tx_dlf_collections_join.uid'
312
                )
313
            )
314
            ->where(
315
                $queryBuilder->expr()->eq('tx_dlf_documents.pid', intval($settings['pages'])),
316
                $queryBuilder->expr()->eq('tx_dlf_collections_join.pid', intval($settings['pages'])),
317
                $queryBuilder->expr()->eq('tx_dlf_documents.partof', 0),
318
                $queryBuilder->expr()->in('tx_dlf_collections_join.uid',
319
                    $queryBuilder->createNamedParameter(GeneralUtility::intExplode(',',
320
                        $settings['collections']), Connection::PARAM_INT_ARRAY)),
321
                $queryBuilder->expr()->eq('tx_dlf_relations_joins.ident',
322
                    $queryBuilder->createNamedParameter('docs_colls'))
323
            )
324
            ->execute()
325
            ->fetchColumn(0);
326
327
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
328
            ->getQueryBuilderForTable('tx_dlf_documents');
329
        $subQueryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
330
            ->getQueryBuilderForTable('tx_dlf_documents');
331
332
        $subQuery = $subQueryBuilder
333
            ->select('tx_dlf_documents.partof')
334
            ->from('tx_dlf_documents')
335
            ->where(
336
                $subQueryBuilder->expr()->neq('tx_dlf_documents.partof', 0)
337
            )
338
            ->groupBy('tx_dlf_documents.partof')
339
            ->getSQL();
340
341
        $countVolumes = $queryBuilder
342
            ->count('tx_dlf_documents.uid')
343
            ->from('tx_dlf_documents')
344
            ->innerJoin(
345
                'tx_dlf_documents',
346
                'tx_dlf_relations',
347
                'tx_dlf_relations_joins',
348
                $queryBuilder->expr()->eq(
349
                    'tx_dlf_relations_joins.uid_local',
350
                    'tx_dlf_documents.uid'
351
                )
352
            )
353
            ->innerJoin(
354
                'tx_dlf_relations_joins',
355
                'tx_dlf_collections',
356
                'tx_dlf_collections_join',
357
                $queryBuilder->expr()->eq(
358
                    'tx_dlf_relations_joins.uid_foreign',
359
                    'tx_dlf_collections_join.uid'
360
                )
361
            )
362
            ->where(
363
                $queryBuilder->expr()->eq('tx_dlf_documents.pid', intval($settings['pages'])),
364
                $queryBuilder->expr()->eq('tx_dlf_collections_join.pid', intval($settings['pages'])),
365
                $queryBuilder->expr()->notIn('tx_dlf_documents.uid', $subQuery),
366
                $queryBuilder->expr()->in('tx_dlf_collections_join.uid',
367
                    $queryBuilder->createNamedParameter(GeneralUtility::intExplode(',',
368
                        $settings['collections']), Connection::PARAM_INT_ARRAY)),
369
                $queryBuilder->expr()->eq('tx_dlf_relations_joins.ident',
370
                    $queryBuilder->createNamedParameter('docs_colls'))
371
            )
372
            ->execute()
373
            ->fetchColumn(0);
374
375
        return ['titles' => $countTitles, 'volumes' => $countVolumes];
376
    }
377
378
    public function getTableOfContentsFromDb($uid, $pid, $settings)
379
    {
380
        // Build table of contents from database.
381
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
382
            ->getQueryBuilderForTable('tx_dlf_documents');
383
384
        $excludeOtherWhere = '';
385
        if ($settings['excludeOther']) {
386
            $excludeOtherWhere = 'tx_dlf_documents.pid=' . intval($settings['pages']);
387
        }
388
        // Check if there are any metadata to suggest.
389
        $result = $queryBuilder
390
            ->select(
391
                'tx_dlf_documents.uid AS uid',
392
                'tx_dlf_documents.title AS title',
393
                'tx_dlf_documents.volume AS volume',
394
                'tx_dlf_documents.mets_label AS mets_label',
395
                'tx_dlf_documents.mets_orderlabel AS mets_orderlabel',
396
                'tx_dlf_structures_join.index_name AS type'
397
            )
398
            ->innerJoin(
399
                'tx_dlf_documents',
400
                'tx_dlf_structures',
401
                'tx_dlf_structures_join',
402
                $queryBuilder->expr()->eq(
403
                    'tx_dlf_structures_join.uid',
404
                    'tx_dlf_documents.structure'
405
                )
406
            )
407
            ->from('tx_dlf_documents')
408
            ->where(
409
                $queryBuilder->expr()->eq('tx_dlf_documents.partof', intval($uid)),
410
                $queryBuilder->expr()->eq('tx_dlf_structures_join.pid', intval($pid)),
411
                $excludeOtherWhere
412
            )
413
            ->addOrderBy('tx_dlf_documents.volume_sorting')
414
            ->addOrderBy('tx_dlf_documents.mets_orderlabel')
415
            ->execute();
416
        return $result;
417
    }
418
419
    /**
420
     * Find one document by given settings and identifier
421
     *
422
     * @param array $settings
423
     * @param array $parameters
424
     *
425
     * @return array The found document object
426
     */
427
    public function getOaiRecord($settings, $parameters)
428
    {
429
        $where = '';
430
431
        if (!$settings['show_userdefined']) {
432
            $where .= 'AND tx_dlf_collections.fe_cruser_id=0 ';
433
        }
434
435
        $connection = GeneralUtility::makeInstance(ConnectionPool::class)
436
            ->getConnectionForTable('tx_dlf_documents');
437
438
        $sql = 'SELECT `tx_dlf_documents`.*, GROUP_CONCAT(DISTINCT `tx_dlf_collections`.`oai_name` ORDER BY `tx_dlf_collections`.`oai_name` SEPARATOR " ") AS `collections` ' .
439
            'FROM `tx_dlf_documents` ' .
440
            'INNER JOIN `tx_dlf_relations` ON `tx_dlf_relations`.`uid_local` = `tx_dlf_documents`.`uid` ' .
441
            'INNER JOIN `tx_dlf_collections` ON `tx_dlf_collections`.`uid` = `tx_dlf_relations`.`uid_foreign` ' .
442
            'WHERE `tx_dlf_documents`.`record_id` = ? ' .
443
            'AND `tx_dlf_relations`.`ident`="docs_colls" ' .
444
            $where;
445
446
        $values = [
447
            $parameters['identifier']
448
        ];
449
450
        $types = [
451
            Connection::PARAM_STR
452
        ];
453
454
        // Create a prepared statement for the passed SQL query, bind the given params with their binding types and execute the query
455
        $statement = $connection->executeQuery($sql, $values, $types);
456
457
        return $statement->fetch();
458
    }
459
460
    /**
461
     * Finds all documents for the given settings
462
     *
463
     * @param array $settings
464
     * @param array $documentsToProcess
465
     *
466
     * @return array The found document objects
467
     */
468
    public function getOaiDocumentList($settings, $documentsToProcess)
0 ignored issues
show
Unused Code introduced by
The parameter $settings 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

468
    public function getOaiDocumentList(/** @scrutinizer ignore-unused */ $settings, $documentsToProcess)

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...
469
    {
470
        $connection = GeneralUtility::makeInstance(ConnectionPool::class)
471
            ->getConnectionForTable('tx_dlf_documents');
472
473
        $sql = 'SELECT `tx_dlf_documents`.*, GROUP_CONCAT(DISTINCT `tx_dlf_collections`.`oai_name` ORDER BY `tx_dlf_collections`.`oai_name` SEPARATOR " ") AS `collections` ' .
474
            'FROM `tx_dlf_documents` ' .
475
            'INNER JOIN `tx_dlf_relations` ON `tx_dlf_relations`.`uid_local` = `tx_dlf_documents`.`uid` ' .
476
            'INNER JOIN `tx_dlf_collections` ON `tx_dlf_collections`.`uid` = `tx_dlf_relations`.`uid_foreign` ' .
477
            'WHERE `tx_dlf_documents`.`uid` IN ( ? ) ' .
478
            'AND `tx_dlf_relations`.`ident`="docs_colls" ' .
479
            'AND ' . Helper::whereExpression('tx_dlf_collections') . ' ' .
480
            'GROUP BY `tx_dlf_documents`.`uid` ';
481
482
        $values = [
483
            $documentsToProcess,
484
        ];
485
486
        $types = [
487
            Connection::PARAM_INT_ARRAY,
488
        ];
489
490
        // Create a prepared statement for the passed SQL query, bind the given params with their binding types and execute the query
491
        $documents = $connection->executeQuery($sql, $values, $types);
492
493
        return $documents;
494
    }
495
496
    /**
497
     * Finds all documents with given uids
498
     *
499
     * @param string $uids separated by comma
500
     *
501
     * @return objects
0 ignored issues
show
Bug introduced by
The type Kitodo\Dlf\Domain\Repository\objects 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...
502
     */
503
    private function findAllByUids($uids)
504
    {
505
        // get all documents from db we are talking about
506
        $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
507
        $queryBuilder = $connectionPool->getQueryBuilderForTable('tx_dlf_documents');
508
        // Fetch document info for UIDs in $documentSet from DB
509
        $kitodoDocuments = $queryBuilder
510
            ->select(
511
                'tx_dlf_documents.uid AS uid',
512
                'tx_dlf_documents.title AS title',
513
                'tx_dlf_documents.structure AS structure',
514
                'tx_dlf_documents.thumbnail AS thumbnail',
515
                'tx_dlf_documents.volume_sorting AS volumeSorting',
516
                'tx_dlf_documents.mets_orderlabel AS metsOrderlabel',
517
                'tx_dlf_documents.partof AS partOf'
518
            )
519
            ->from('tx_dlf_documents')
520
            ->where(
521
                $queryBuilder->expr()->in('tx_dlf_documents.pid', $this->settings['storagePid']),
522
                $queryBuilder->expr()->in('tx_dlf_documents.uid', $uids)
523
            )
524
            ->addOrderBy('tx_dlf_documents.volume_sorting', 'asc')
525
            ->addOrderBy('tx_dlf_documents.mets_orderlabel', 'asc')
526
            ->execute();
527
528
        $allDocuments = [];
529
        $documentStructures = Helper::getDocumentStructures($this->settings['storagePid']);
530
        // Process documents in a usable array structure
531
        while ($resArray = $kitodoDocuments->fetch()) {
532
            $resArray['structure'] = $documentStructures[$resArray['structure']];
533
            $allDocuments[$resArray['uid']] = $resArray;
534
        }
535
536
        return $allDocuments;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $allDocuments returns the type array which is incompatible with the documented return type Kitodo\Dlf\Domain\Repository\objects.
Loading history...
537
    }
538
539
    /**
540
     * Find all documents with given collection from Solr
541
     *
542
     * @param \TYPO3\CMS\Extbase\Persistence\Generic\QueryResult $collections
543
     * @param array $settings
544
     * @param array $searchParams
545
     * @param \TYPO3\CMS\Extbase\Persistence\Generic\QueryResult $listedMetadata
546
     * @return array
547
     */
548
    public function findSolrByCollection($collections, $settings, $searchParams, $listedMetadata = null) {
0 ignored issues
show
Unused Code introduced by
The parameter $collections 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

548
    public function findSolrByCollection(/** @scrutinizer ignore-unused */ $collections, $settings, $searchParams, $listedMetadata = null) {

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...
549
550
        $this->settings = $settings;
0 ignored issues
show
Bug Best Practice introduced by
The property settings does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
551
552
        // Instantiate search object.
553
        $solr = Solr::getInstance($settings['solrcore']);
554
        if (!$solr->ready) {
555
            $this->logger->error('Apache Solr not available');
0 ignored issues
show
Bug Best Practice introduced by
The property logger does not exist on Kitodo\Dlf\Domain\Repository\DocumentRepository. Did you maybe forget to declare it?
Loading history...
556
            return [];
557
        }
558
559
        // Prepare query parameters.
560
        $params = [];
561
        $matches = [];
562
        // Set search query.
563
        if (
564
            (!empty($settings['fulltext']) && !empty($searchParams['fulltext']))
565
            || preg_match('/fulltext:\((.*)\)/', trim($searchParams['query']), $matches)
566
        ) {
567
            // If the query already is a fulltext query e.g using the facets
568
            $searchParams['query'] = empty($matches[1]) ? $searchParams['query'] : $matches[1];
569
            // Search in fulltext field if applicable. Query must not be empty!
570
            if (!empty($searchParams['query'])) {
571
                $query = 'fulltext:(' . Solr::escapeQuery(trim($searchParams['query'])) . ')';
572
            }
573
            $params['fulltext'] = true;
574
575
        } else {
576
            // Retain given search field if valid.
577
            // ABTODO: the storagePid won't be available here
578
            $query = Solr::escapeQueryKeepField(trim($searchParams['query']), $settings['storagePid']);
579
        }
580
581
        // Set some query parameters.
582
        $params['query'] = !empty($query) ? $query : '*';
583
        $params['start'] = 0;
584
        $params['rows'] = 10000;
585
586
        // order the results as given or by title as default
587
        if (!empty($searchParams['orderBy'])) {
588
            $querySort = [
589
                $searchParams['orderBy'] => $searchParams['order']
590
            ];
591
        } else {
592
            $querySort = [
593
                'year' => 'asc',
594
                'title' => 'asc'
595
            ];
596
        }
597
598
        $params['sort'] = $querySort;
599
        $params['listMetadataRecords'] = [];
600
601
        // Restrict the fields to the required ones.
602
        $params['fields'] = 'uid,id,page,title,thumbnail,partof,toplevel,type';
603
604
        if ($listedMetadata) {
605
            foreach ($listedMetadata as $metadata) {
606
                if ($metadata->getIndexStored() || $metadata->getIndexIndexed()) {
607
                    $listMetadataRecord = $metadata->getIndexName() . '_' . ($metadata->getIndexTokenized() ? 't' : 'u') . ($metadata->getIndexStored() ? 's' : 'u') . ($metadata->getIndexIndexed() ? 'i' : 'u');
608
                    $params['fields'] .= ',' . $listMetadataRecord;
609
                    $params['listMetadataRecords'][$metadata->getIndexName()] = $listMetadataRecord;
610
                }
611
            }
612
        }
613
614
        // Perform search.
615
        $result = $solr->search_raw($params);
616
617
        $numberOfToplevels = 0;
618
        $documents = [];
619
620
        if ($result['numFound'] > 0) {
621
            // Initialize array
622
            $documentSet = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $documentSet is dead and can be removed.
Loading history...
623
            // flat array with uids from Solr search
624
            $documentSet = array_unique(array_column($result['documents'], 'uid'));
625
626
            if (empty($documentSet)) {
627
                // return nothing found
628
                return ['solrResults' => [], 'documents' => []];
629
            }
630
631
            // get the Extbase document objects for all uids
632
            $allDocuments = $this->findAllByUids($documentSet);
0 ignored issues
show
Bug introduced by
$documentSet of type array is incompatible with the type string expected by parameter $uids of Kitodo\Dlf\Domain\Reposi...sitory::findAllByUids(). ( Ignorable by Annotation )

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

632
            $allDocuments = $this->findAllByUids(/** @scrutinizer ignore-type */ $documentSet);
Loading history...
633
            $children = $this->findByPartof($documentSet);
0 ignored issues
show
Bug introduced by
The method findByPartof() does not exist on Kitodo\Dlf\Domain\Repository\DocumentRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

633
            /** @scrutinizer ignore-call */ 
634
            $children = $this->findByPartof($documentSet);
Loading history...
634
635
            foreach ($result['documents'] as $doc) {
636
                if (empty($documents[$doc['uid']]) && $allDocuments[$doc['uid']]) {
637
                    $documents[$doc['uid']] = $allDocuments[$doc['uid']];
638
                }
639
                if ($documents[$doc['uid']]) {
640
                    if ($doc['toplevel'] === false) {
641
                        // this maybe a chapter, article, ..., year
642
                        if ($doc['type'] === 'year') {
643
                            continue;
644
                        }
645
                        if (!empty($doc['page'])) {
646
                            // it's probably a fulltext or metadata search
647
                            $searchResult = [];
648
                            $searchResult['page'] = $doc['page'];
649
                            $searchResult['thumbnail'] = $doc['thumbnail'];
650
                            $searchResult['structure'] = $doc['type'];
651
                            $searchResult['title'] = $doc['title'];
652
                            foreach ($params['listMetadataRecords'] as $indexName => $solrField) {
653
                                if (isset($doc['metadata'][$indexName])) {
654
                                    $documents[$doc['uid']]['metadata'][$indexName] = $doc['metadata'][$indexName];
655
                                }
656
                            }
657
                            if ($searchParams['fulltext'] == '1') {
658
                                $searchResult['snippet'] = $doc['snippet'];
659
                                $searchResult['highlight'] = $doc['highlight'];
660
                                $searchResult['highlight_word'] = $searchParams['query'];
661
                            }
662
                            $documents[$doc['uid']]['searchResults'][] = $searchResult;
663
                        }
664
                    } else if ($doc['toplevel'] === true) {
665
                        $numberOfToplevels++;
666
                        foreach ($params['listMetadataRecords'] as $indexName => $solrField) {
667
                            if (isset($doc['metadata'][$indexName])) {
668
                                $documents[$doc['uid']]['metadata'][$indexName] = $doc['metadata'][$indexName];
669
                            }
670
                        }
671
                        if ($searchParams['fulltext'] != '1') {
672
                            $documents[$doc['uid']]['page'] = 1;
673
                            if (empty($searchParams['query'])) {
674
                                // find all child documents but not on active search
675
                                if (is_array($children[$documents[$doc['uid']]['uid']])) {
676
                                    $documents[$doc['uid']]['children'] = $this->findAllByUids($children[$documents[$doc['uid']]['uid']]);
677
                                }
678
                            }
679
                        }
680
                    }
681
                    if (empty($documents[$doc['uid']]['metadata'])) {
682
                        $documents[$doc['uid']]['metadata'] = $this->fetchMetadataFromSolr($doc['uid'], $settings, $listedMetadata);
683
                    }
684
                    // get title of parent if empty
685
                    if (empty($documents[$doc['uid']]['title']) && ($documents[$doc['uid']]['partOf'] > 0)) {
686
                        $parentDocument = $this->findByUid($documents[$doc['uid']]['partOf']);
687
                        if ($parentDocument) {
688
                            $documents[$doc['uid']]['title'] = $parentDocument->getTitle();
689
                        }
690
                    }
691
                }
692
            }
693
        }
694
695
        return ['solrResults' => $result, 'numberOfToplevels' => $numberOfToplevels, 'documents' => $documents];
696
    }
697
698
    /**
699
     * Find all documents with given collection from Solr
700
     *
701
     * @param int $uid the uid of the document
702
     * @param array $settings
703
     * @param \TYPO3\CMS\Extbase\Persistence\Generic\QueryResult $listedMetadata
704
     * @return array
705
     */
706
    protected function fetchMetadataFromSolr($uid, $settings, $listedMetadata = []) {
707
708
        $this->settings = $settings;
0 ignored issues
show
Bug Best Practice introduced by
The property settings does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
709
710
        // Instantiate search object.
711
        $solr = Solr::getInstance($settings['solrcore']);
712
        if (!$solr->ready) {
713
            $this->logger->error('Apache Solr not available');
0 ignored issues
show
Bug Best Practice introduced by
The property logger does not exist on Kitodo\Dlf\Domain\Repository\DocumentRepository. Did you maybe forget to declare it?
Loading history...
714
            return [];
715
        }
716
717
        // Prepare query parameters.
718
        $params = [];
719
        $matches = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $matches is dead and can be removed.
Loading history...
720
721
        // Set some query parameters.
722
        $params['query'] = 'uid:' . $uid;
723
        $params['start'] = 0;
724
        $params['rows'] = 1;
725
        $params['sort'] = ['score' => 'desc'];
726
        $params['listMetadataRecords'] = [];
727
728
        // Restrict the fields to the required ones.
729
        $params['fields'] = 'uid,toplevel';
730
731
        if ($listedMetadata) {
732
            foreach ($listedMetadata as $metadata) {
733
                if ($metadata->getIndexIndexed()) {
734
                    $listMetadataRecord = $metadata->getIndexName() . '_' . ($metadata->getIndexTokenized() ? 't' : 'u') . ($metadata->getIndexStored() ? 's' : 'u') . 'i';
735
                    $params['fields'] .= ',' . $listMetadataRecord;
736
                    $params['listMetadataRecords'][$metadata->getIndexName()] = $listMetadataRecord;
737
                }
738
            }
739
        }
740
        // Set filter query to just get toplevel documents.
741
        $params['filterquery'][] = ['query' => 'toplevel:true'];
742
743
        // Perform search.
744
        $result = $solr->search_raw($params);
745
746
        if ($result['numFound'] > 0) {
747
            $searchResult = [];
748
            foreach ($result['documents'] as $doc) {
749
                foreach ($params['listMetadataRecords'] as $indexName => $solrField) {
750
                    if (isset($doc['metadata'][$solrField])) {
751
                        $searchResult[$indexName] = $doc['metadata'][$solrField];
752
                    }
753
                }
754
            }
755
        }
756
        return $searchResult;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $searchResult does not seem to be defined for all execution paths leading up to this point.
Loading history...
757
    }
758
}
759