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
Push — master ( 83566b...c23467 )
by
unknown
08:40 queued 05:01
created

BaseCommand::getSolrCores()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 14
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 22
rs 9.7998
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\Command;
14
15
use Kitodo\Dlf\Common\AbstractDocument;
16
use Kitodo\Dlf\Common\Helper;
17
use Kitodo\Dlf\Common\Indexer;
18
use Kitodo\Dlf\Domain\Repository\CollectionRepository;
19
use Kitodo\Dlf\Domain\Repository\DocumentRepository;
20
use Kitodo\Dlf\Domain\Repository\LibraryRepository;
21
use Kitodo\Dlf\Domain\Repository\StructureRepository;
22
use Kitodo\Dlf\Domain\Model\Collection;
23
use Kitodo\Dlf\Domain\Model\Document;
24
use Kitodo\Dlf\Domain\Model\Library;
25
use Symfony\Component\Console\Command\Command;
26
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
27
use TYPO3\CMS\Core\Utility\GeneralUtility;
28
use TYPO3\CMS\Core\Utility\MathUtility;
29
use TYPO3\CMS\Core\Database\ConnectionPool;
30
use TYPO3\CMS\Core\Database\Connection;
31
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
32
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
33
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
34
35
/**
36
 * Base class for CLI Command classes.
37
 *
38
 * @package TYPO3
39
 * @subpackage dlf
40
 *
41
 * @access public
42
 */
43
class BaseCommand extends Command
44
{
45
    /**
46
     * @access protected
47
     * @var CollectionRepository
48
     */
49
    protected CollectionRepository $collectionRepository;
50
51
    /**
52
     * @access protected
53
     * @var DocumentRepository
54
     */
55
    protected DocumentRepository $documentRepository;
56
57
    /**
58
     * @access protected
59
     * @var LibraryRepository
60
     */
61
    protected LibraryRepository $libraryRepository;
62
63
    /**
64
     * @access protected
65
     * @var StructureRepository
66
     */
67
    protected StructureRepository $structureRepository;
68
69
    /**
70
     * @access protected
71
     * @var int
72
     */
73
    protected int $storagePid;
74
75
    /**
76
     * @access protected
77
     * @var Library|null
78
     */
79
    protected ?Library $owner;
80
81
    /**
82
     * @access protected
83
     * @var array
84
     */
85
    protected array $extConf;
86
87
    /**
88
     * @var ConfigurationManager
89
     */
90
    protected ConfigurationManager $configurationManager;
91
92
    public function __construct(
93
        CollectionRepository $collectionRepository,
94
        DocumentRepository $documentRepository,
95
        LibraryRepository $libraryRepository,
96
        StructureRepository $structureRepository,
97
        ConfigurationManager $configurationManager
98
    ) {
99
        parent::__construct();
100
101
        $this->collectionRepository = $collectionRepository;
102
        $this->documentRepository = $documentRepository;
103
        $this->libraryRepository = $libraryRepository;
104
        $this->structureRepository = $structureRepository;
105
        $this->configurationManager = $configurationManager;
106
    }
107
108
    /**
109
     * Initialize the extbase repository based on the given storagePid.
110
     *
111
     * TYPO3 10+: Find a better solution e.g. based on Symfony Dependency Injection.
112
     *
113
     * @access protected
114
     *
115
     * @param int $storagePid The storage pid
116
     *
117
     * @return bool
118
     */
119
    protected function initializeRepositories(int $storagePid): bool
120
    {
121
        if (MathUtility::canBeInterpretedAsInteger($storagePid)) {
122
            $frameworkConfiguration = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
123
124
            $frameworkConfiguration['persistence']['storagePid'] = MathUtility::forceIntegerInRange((int) $storagePid, 0);
125
            $this->configurationManager->setConfiguration($frameworkConfiguration);
126
127
            // Get extension configuration.
128
            $this->extConf = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('dlf');
129
        } else {
130
            return false;
131
        }
132
        $this->storagePid = MathUtility::forceIntegerInRange((int) $storagePid, 0);
133
134
        return true;
135
    }
136
137
    /**
138
     * Return matching uid of Solr core depending on the input value.
139
     *
140
     * @access protected
141
     *
142
     * @param array $solrCores array of the valid Solr cores
143
     * @param string|bool|null $inputSolrId possible uid or name of Solr core
144
     *
145
     * @return int matching uid of Solr core
146
     */
147
    protected function getSolrCoreUid(array $solrCores, $inputSolrId): int
148
    {
149
        if (MathUtility::canBeInterpretedAsInteger($inputSolrId)) {
150
            $solrCoreUid = MathUtility::forceIntegerInRange((int) $inputSolrId, 0);
151
        } else {
152
            $solrCoreUid = $solrCores[$inputSolrId];
153
        }
154
        return $solrCoreUid;
155
    }
156
157
    /**
158
     * Fetches all Solr cores on given page.
159
     *
160
     * @access protected
161
     *
162
     * @param int $pageId The UID of the Solr core or 0 to disable indexing
163
     *
164
     * @return array Array of valid Solr cores
165
     */
166
    protected function getSolrCores(int $pageId): array
167
    {
168
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
169
            ->getQueryBuilderForTable('tx_dlf_solrcores');
170
171
        $solrCores = [];
172
        $result = $queryBuilder
173
            ->select('uid', 'index_name')
174
            ->from('tx_dlf_solrcores')
175
            ->where(
176
                $queryBuilder->expr()->eq(
177
                    'pid',
178
                    $queryBuilder->createNamedParameter((int) $pageId, Connection::PARAM_INT)
179
                )
180
            )
181
            ->execute();
182
183
        while ($record = $result->fetchAssociative()) {
184
            $solrCores[$record['index_name']] = $record['uid'];
185
        }
186
187
        return $solrCores;
188
    }
189
190
    /**
191
     * Update or insert document to database
192
     *
193
     * @access protected
194
     *
195
     * @param Document $document The document instance
196
     *
197
     * @return bool true on success, false otherwise
198
     */
199
    protected function saveToDatabase(Document $document): bool
200
    {
201
        $doc = $document->getCurrentDocument();
202
        if ($doc === null) {
203
            return false;
204
        }
205
        $persistenceManager = GeneralUtility::makeInstance(PersistenceManager::class);
206
        $doc->cPid = $this->storagePid;
207
208
        $metadata = $doc->getToplevelMetadata($this->storagePid);
209
210
        // set title data
211
        $document->setTitle($metadata['title'][0] ? : '');
212
        $document->setTitleSorting($metadata['title_sorting'][0] ? : '');
213
        $document->setPlace(implode('; ', $metadata['place']));
214
        $document->setYear(implode('; ', $metadata['year']));
215
216
        // Remove appended "valueURI" from authors' names for storing in database.
217
        foreach ($metadata['author'] as $i => $author) {
218
            $splitName = explode(chr(31), $author);
219
            $metadata['author'][$i] = $splitName[0];
220
        }
221
        $document->setAuthor($this->getAuthors($metadata['author']));
222
        $document->setThumbnail($doc->thumbnail ? : '');
223
        $document->setMetsLabel($metadata['mets_label'][0] ? : '');
224
        $document->setMetsOrderlabel($metadata['mets_orderlabel'][0] ? : '');
225
226
        $structure = $this->structureRepository->findOneByIndexName($metadata['type'][0]);
0 ignored issues
show
Bug introduced by
The method findOneByIndexName() does not exist on Kitodo\Dlf\Domain\Repository\StructureRepository. 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

226
        /** @scrutinizer ignore-call */ 
227
        $structure = $this->structureRepository->findOneByIndexName($metadata['type'][0]);
Loading history...
227
        $document->setStructure($structure);
228
229
        if (is_array($metadata['collection'])) {
230
            $this->addCollections($document, $metadata['collection'], $persistenceManager);
231
        }
232
233
        // set identifiers
234
        $document->setProdId($metadata['prod_id'][0] ? : '');
235
        $document->setOpacId($metadata['opac_id'][0] ? : '');
236
        $document->setUnionId($metadata['union_id'][0] ? : '');
237
238
        $document->setRecordId($metadata['record_id'][0] ? : ''); // (?) $doc->recordId
239
        $document->setUrn($metadata['urn'][0] ? : '');
240
        $document->setPurl($metadata['purl'][0] ? : '');
241
        $document->setDocumentFormat($metadata['document_format'][0] ? : '');
242
243
        // set access
244
        $document->setLicense($metadata['license'][0] ? : '');
245
        $document->setTerms($metadata['terms'][0] ? : '');
246
        $document->setRestrictions($metadata['restrictions'][0] ? : '');
247
        $document->setOutOfPrint($metadata['out_of_print'][0] ? : '');
248
        $document->setRightsInfo($metadata['rights_info'][0] ? : '');
249
        $document->setStatus(0);
250
251
        $this->setOwner($metadata['owner'][0]);
252
        $document->setOwner($this->owner);
253
254
        // set volume data
255
        $document->setVolume($metadata['volume'][0] ? : '');
256
        $document->setVolumeSorting($metadata['volume_sorting'][0] ? : $metadata['mets_order'][0] ? : '');
257
258
        // Get UID of parent document.
259
        if ($document->getDocumentFormat() === 'METS') {
260
            $document->setPartof($this->getParentDocumentUidForSaving($document));
261
        }
262
263
        if ($document->getUid() === null) {
264
            // new document
265
            $this->documentRepository->add($document);
266
        } else {
267
            // update of existing document
268
            $this->documentRepository->update($document);
269
        }
270
271
        $persistenceManager->persistAll();
272
273
        return true;
274
    }
275
276
    /**
277
     * Get the ID of the parent document if the current document has one.
278
     * Currently only applies to METS documents.
279
     *
280
     * @access protected
281
     *
282
     * @param Document $document for which parent UID should be taken
283
     *
284
     * @return int The parent document's id.
285
     */
286
    protected function getParentDocumentUidForSaving(Document $document): int
287
    {
288
        $doc = $document->getCurrentDocument();
289
290
        if ($doc !== null && !empty($doc->parentHref)) {
0 ignored issues
show
Bug Best Practice introduced by
The property parentHref does not exist on Kitodo\Dlf\Common\AbstractDocument. Since you implemented __get, consider adding a @property annotation.
Loading history...
291
            // find document object by record_id of parent
292
            $parent = AbstractDocument::getInstance($doc->parentHref, ['storagePid' => $this->storagePid]);
293
294
            if ($parent->recordId) {
295
                $parentDocument = $this->documentRepository->findOneByRecordId($parent->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

295
                /** @scrutinizer ignore-call */ 
296
                $parentDocument = $this->documentRepository->findOneByRecordId($parent->recordId);
Loading history...
296
297
                if ($parentDocument === null) {
298
                    // create new Document object
299
                    $parentDocument = GeneralUtility::makeInstance(Document::class);
300
                }
301
302
                $parentDocument->setOwner($this->owner);
0 ignored issues
show
Bug introduced by
The method setOwner() 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

302
                $parentDocument->/** @scrutinizer ignore-call */ 
303
                                 setOwner($this->owner);

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...
303
                $parentDocument->setCurrentDocument($parent);
0 ignored issues
show
Bug introduced by
The method setCurrentDocument() 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

303
                $parentDocument->/** @scrutinizer ignore-call */ 
304
                                 setCurrentDocument($parent);

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...
304
                $parentDocument->setLocation($doc->parentHref);
0 ignored issues
show
Bug introduced by
The method setLocation() 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

304
                $parentDocument->/** @scrutinizer ignore-call */ 
305
                                 setLocation($doc->parentHref);

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...
305
                $parentDocument->setSolrcore($document->getSolrcore());
0 ignored issues
show
Bug introduced by
The method setSolrcore() 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

305
                $parentDocument->/** @scrutinizer ignore-call */ 
306
                                 setSolrcore($document->getSolrcore());

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...
306
307
                $success = $this->saveToDatabase($parentDocument);
308
309
                if ($success === true) {
310
                    // add to index
311
                    Indexer::add($parentDocument, $this->documentRepository);
312
                    return $parentDocument->getUid();
0 ignored issues
show
Bug introduced by
The method getUid() 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

312
                    return $parentDocument->/** @scrutinizer ignore-call */ getUid();

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...
313
                }
314
            }
315
        }
316
317
        return 0;
318
    }
319
320
    /**
321
     * Add collections.
322
     *
323
     * @access private
324
     * 
325
     * @param Document &$document
326
     * @param array $collections
327
     * @param PersistenceManager $persistenceManager
328
     *
329
     * @return void
330
     */
331
    private function addCollections(Document &$document, array $collections, PersistenceManager $persistenceManager): void
332
    {
333
        foreach ($collections as $collection) {
334
            $documentCollection = $this->collectionRepository->findOneByIndexName($collection);
0 ignored issues
show
Bug introduced by
The method findOneByIndexName() does not exist on Kitodo\Dlf\Domain\Repository\CollectionRepository. 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

334
            /** @scrutinizer ignore-call */ 
335
            $documentCollection = $this->collectionRepository->findOneByIndexName($collection);
Loading history...
335
            if (!$documentCollection) {
336
                // create new Collection object
337
                $documentCollection = GeneralUtility::makeInstance(Collection::class);
338
                $documentCollection->setIndexName($collection);
339
                $documentCollection->setLabel($collection);
340
                $documentCollection->setOaiName((!empty($this->extConf['publishNewCollections']) ? Helper::getCleanString($collection) : ''));
341
                $documentCollection->setIndexSearch('');
342
                $documentCollection->setDescription('');
343
                // add to CollectionRepository
344
                $this->collectionRepository->add($documentCollection);
345
                // persist collection to prevent duplicates
346
                $persistenceManager->persistAll();
347
            }
348
            // add to document
349
            $document->addCollection($documentCollection);
350
        }
351
    }
352
353
    /**
354
     * Get authors considering that database field can't accept
355
     * more than 255 characters.
356
     *
357
     * @access private
358
     * 
359
     * @param array $metadataAuthor
360
     *
361
     * @return string
362
     */
363
    private function getAuthors(array $metadataAuthor): string
364
    {
365
        $authors = '';
366
        $delimiter = '; ';
367
        $ellipsis = 'et al.';
368
369
        $count = count($metadataAuthor);
370
371
        for ($i = 0; $i < $count; $i++) {
372
            // Build the next part to add
373
            $nextPart = ($i === 0 ? '' : $delimiter) . $metadataAuthor[$i];
374
            // Check if adding this part and ellipsis in future would exceed the character limit
375
            if (strlen($authors . $nextPart . $delimiter . $ellipsis) > 255) {
376
                // Add ellipsis and stop adding more authors
377
                $authors .= $delimiter . $ellipsis;
378
                break;
379
            }
380
            // Add the part to the main string
381
            $authors .= $nextPart;
382
        }
383
384
        return $authors;
385
    }
386
387
    /**
388
     * If owner is not set set but found by metadata, take it or take default library, if nothing found in database then create new owner.
389
     *
390
     * @access private
391
     *
392
     * @param ?string $owner
393
     *
394
     * @return void
395
     */
396
    private function setOwner($owner): void
397
    {
398
        if (empty($this->owner)) {
399
            // owner is not set set but found by metadata --> take it or take default library
400
            $owner = $owner ? : 'default';
401
            $this->owner = $this->libraryRepository->findOneByIndexName($owner);
0 ignored issues
show
Bug introduced by
The method findOneByIndexName() does not exist on Kitodo\Dlf\Domain\Repository\LibraryRepository. 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

401
            /** @scrutinizer ignore-call */ 
402
            $this->owner = $this->libraryRepository->findOneByIndexName($owner);
Loading history...
402
            if (empty($this->owner)) {
403
                // create library
404
                $this->owner = GeneralUtility::makeInstance(Library::class);
405
                $this->owner->setLabel($owner);
0 ignored issues
show
Bug introduced by
The method setLabel() does not exist on null. ( Ignorable by Annotation )

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

405
                $this->owner->/** @scrutinizer ignore-call */ 
406
                              setLabel($owner);

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...
406
                $this->owner->setIndexName($owner);
407
                $this->libraryRepository->add($this->owner);
408
            }
409
        }
410
    }
411
}
412