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 (#746)
by Alexander
03:49 queued 01:03
created

BaseCommand::saveToDatabase()   D

Complexity

Conditions 27
Paths 49

Size

Total Lines 103
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 27
eloc 60
c 1
b 0
f 0
nc 49
nop 1
dl 0
loc 103
rs 4.1666

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\Command;
14
15
use Kitodo\Dlf\Common\Doc;
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\Model\Document;
22
use Kitodo\Dlf\Domain\Model\Library;
23
use Symfony\Component\Console\Command\Command;
24
use TYPO3\CMS\Core\Utility\GeneralUtility;
25
use TYPO3\CMS\Core\Utility\MathUtility;
26
use TYPO3\CMS\Core\Database\ConnectionPool;
27
use TYPO3\CMS\Core\Database\Connection;
28
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
29
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
30
31
/**
32
 * Base class for CLI Command classes.
33
 *
34
 * @author Beatrycze Volk <[email protected]>
35
 * @package TYPO3
36
 * @subpackage dlf
37
 * @access public
38
 */
39
class BaseCommand extends Command
40
{
41
    /**
42
     * @var CollectionRepository
43
     */
44
    protected $collectionRepository;
45
46
    /**
47
     * @var DocumentRepository
48
     */
49
    protected $documentRepository;
50
51
    /**
52
     * @var LibraryRepository
53
     */
54
    protected $libraryRepository;
55
56
    /**
57
     * @var int
58
     */
59
    protected $storagePid;
60
61
    /**
62
     * @var \Kitodo\Dlf\Domain\Model\Library
63
     */
64
    protected $owner;
65
66
    /**
67
     * Initialize the extbase repository based on the given storagePid.
68
     *
69
     * TYPO3 10+: Find a better solution e.g. based on Symfonie Dependancy Injection.
70
     *
71
     * @param int $storagePid The storage pid
72
     *
73
     * @return bool
74
     */
75
    protected function initializeRepositories($storagePid)
76
    {
77
        if (MathUtility::canBeInterpretedAsInteger($storagePid)) {
78
            $configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class);
79
            $frameworkConfiguration = $configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
80
81
            $frameworkConfiguration['persistence']['storagePid'] = MathUtility::forceIntegerInRange((int) $storagePid, 0);
82
            $configurationManager->setConfiguration($frameworkConfiguration);
83
84
            $this->collectionRepository = GeneralUtility::makeInstance(CollectionRepository::class);
85
            $this->documentRepository = GeneralUtility::makeInstance(DocumentRepository::class);
86
            $this->libraryRepository = GeneralUtility::makeInstance(LibraryRepository::class);
87
        } else {
88
            return false;
89
        }
90
        $this->storagePid = MathUtility::forceIntegerInRange((int) $storagePid, 0);
91
92
        return true;
93
    }
94
95
    /**
96
     * Return matching uid of Solr core depending on the input value.
97
     *
98
     * @param array $solrCores array of the valid Solr cores
99
     * @param string|bool|null $inputSolrId possible uid or name of Solr core
100
     *
101
     * @return int matching uid of Solr core
102
     */
103
    protected function getSolrCoreUid(array $solrCores, $inputSolrId): int
104
    {
105
        if (MathUtility::canBeInterpretedAsInteger($inputSolrId)) {
106
            $solrCoreUid = MathUtility::forceIntegerInRange((int) $inputSolrId, 0);
107
        } else {
108
            $solrCoreUid = $solrCores[$inputSolrId];
109
        }
110
        return $solrCoreUid;
111
    }
112
113
    /**
114
     * Fetches all Solr cores on given page.
115
     *
116
     * @param int $pageId The UID of the Solr core or 0 to disable indexing
117
     *
118
     * @return array Array of valid Solr cores
119
     */
120
    protected function getSolrCores(int $pageId): array
121
    {
122
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
123
            ->getQueryBuilderForTable('tx_dlf_solrcores');
124
125
        $solrCores = [];
126
        $result = $queryBuilder
127
            ->select('uid', 'index_name')
128
            ->from('tx_dlf_solrcores')
129
            ->where(
130
                $queryBuilder->expr()->eq(
131
                    'pid',
132
                    $queryBuilder->createNamedParameter((int) $pageId, Connection::PARAM_INT)
133
                )
134
            )
135
            ->execute();
136
137
        while ($record = $result->fetch()) {
138
            $solrCores[$record['index_name']] = $record['uid'];
139
        }
140
141
        return $solrCores;
142
    }
143
144
    /**
145
     * Load XML file / IIIF resource from URL
146
     *
147
     * @access protected
148
     *
149
     * @param string $location: The URL of the file to load
150
     *
151
     * @return string|bool the found xml as string or false on failure
152
     */
153
    protected function loadLocation($location)
154
    {
155
        // Load XML / JSON-LD file.
156
        if (GeneralUtility::isValidUrl($location)) {
157
            // Load extension configuration
158
            // $extConf = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get(self::$extKey);
159
            // // Set user-agent to identify self when fetching XML / JSON-LD data.
160
            // if (!empty($extConf['useragent'])) {
161
            //     @ini_set('user_agent', $extConf['useragent']);
162
            // }
163
            $fileResource = GeneralUtility::getUrl($location);
164
            if ($fileResource !== false) {
165
                $xml = Helper::getXmlFileAsString($fileResource);
166
                if ($xml !== false) {
167
                    return $xml;
168
                }
169
            }
170
        } else {
171
            $this->logger->error('Invalid file location "' . $location . '" for document loading');
0 ignored issues
show
Bug Best Practice introduced by
The property logger does not exist on Kitodo\Dlf\Command\BaseCommand. Did you maybe forget to declare it?
Loading history...
172
        }
173
        return false;
174
    }
175
176
    /**
177
     * Update or insert document to database
178
     *
179
     * @param int|string $doc The document uid from DB OR the location of a mets document.
180
     *
181
     * @return bool true on success
182
     */
183
    protected function saveToDatabase(Document $document)
184
    {
185
        $success = false;
186
187
        $doc = $document->getDoc();
188
        if ($doc === null) {
189
            return $success;
190
        }
191
        $doc->cPid = $this->storagePid;
192
193
        $metadata = $doc->getTitledata($this->storagePid);
194
195
        // set title data
196
        $document->setTitle($metadata['title'][0] ? : '');
197
        $document->setTitleSorting($metadata['title_sorting'][0]);
198
        $document->setPlace(implode('; ', $metadata['place']));
199
        $document->setYear(implode('; ', $metadata['year']));
200
201
        // Remove appended "valueURI" from authors' names for storing in database.
202
        foreach ($metadata['author'] as $i => $author) {
203
            $splitName = explode(chr(31), $author);
204
            $metadata['author'][$i] = $splitName[0];
205
        }
206
        $document->setAuthor(implode('; ', $metadata['author']));
207
        $document->setThumbnail($doc->thumbnail ? : '');
208
        $document->setMetsLabel($metadata['mets_label'][0] ? : '');
209
        $document->setMetsOrderlabel($metadata['mets_orderlabel'][0] ? : '');
210
211
        $document->setStructure(Helper::getUidFromIndexName($metadata['type'][0], 'tx_dlf_structures') ? : 0);
212
213
        $collections = $this->collectionRepository->findCollectionsBySettings(['index_name' => $metadata['collection']]);
214
        if ($collections) {
0 ignored issues
show
introduced by
$collections is of type TYPO3\CMS\Extbase\Persistence\QueryResultInterface, thus it always evaluated to true.
Loading history...
215
            foreach ($collections as $collection) {
216
                $document->addCollection($collection);
217
            }
218
        }
219
220
        // set identifiers
221
        $document->setProdId($metadata['prod_id'][0] ? : '');
222
        $document->setOpacId($metadata['opac_id'][0] ? : '');
223
        $document->setUnionId($metadata['union_id'][0] ? : '');
224
225
        $document->setRecordId($metadata['record_id'][0] ? : ''); // (?) $doc->recordId
226
        $document->setUrn($metadata['urn'][0] ? : '');
227
        $document->setPurl($metadata['purl'][0] ? : '');
228
        $document->setDocumentFormat($metadata['document_format'][0] ? : '');
229
230
        // set access
231
        $document->setLicense($metadata['license'][0] ? : '');
232
        $document->setTerms($metadata['terms'][0] ? : '');
233
        $document->setRestrictions($metadata['restrictions'][0] ? : '');
234
        $document->setOutOfPrint($metadata['out_of_print'][0] ? : '');
235
        $document->setRightsInfo($metadata['rights_info'][0] ? : '');
236
        $document->setStatus(0);
237
238
        if ($this->owner) {
239
            // library / owner is set by parameter --> take it.
240
            $document->setOwner($this->owner);
241
        } else {
242
            // owner is not set set but found by metadata --> take it or take default library
243
            $owner = $metadata['owner'][0] ? : 'default';
244
            $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

244
            /** @scrutinizer ignore-call */ 
245
            $this->owner = $this->libraryRepository->findOneByIndexName($owner);
Loading history...
245
            if ($this->owner) {
246
                $document->setOwner($this->owner);
247
            } else {
248
                // create library
249
                $this->owner = GeneralUtility::makeInstance(Library::class);
250
251
                $this->owner->setLabel($owner);
252
                $this->owner->setIndexName($owner);
253
                $this->libraryRepository->add($this->owner);
254
                $document->setOwner($this->owner);
255
            }
256
        }
257
258
        // to be still (re-) implemented
259
        // 'metadata' => serialize($listed),
260
        // 'metadata_sorting' => serialize($sortable),
261
        // 'volume' => $metadata['volume'][0],
262
        // 'volume_sorting' => $metadata['volume_sorting'][0],
263
264
        // Get UID of parent document.
265
        if ($document->getDocumentFormat() === 'METS') {
266
            $document->setPartof($this->getParentDocumentUidForSaving($document));
267
        }
268
269
        $document->setMetadata('');
270
        $document->setMetadataSorting('');
271
272
        if ($document->getUid() === null) {
273
            // new document
274
            $this->documentRepository->add($document);
275
        } else {
276
            // update of existing document
277
            $this->documentRepository->update($document);
278
        }
279
280
        $persistenceManager = GeneralUtility::makeInstance(PersistenceManager::class);
281
        $persistenceManager->persistAll();
282
283
        $success = true;
284
285
        return $success;
286
    }
287
288
    /**
289
     * Get the ID of the parent document if the current document has one.
290
     * Currently only applies to METS documents.
291
     *
292
     * @access protected
293
     *
294
     * @return int The parent document's id.
295
     */
296
    protected function getParentDocumentUidForSaving(Document $document)
297
    {
298
        $doc = $document->getDoc();
299
300
        if ($doc !== null) {
301
            // Get the closest ancestor of the current document which has a MPTR child.
302
            $parentMptr = $doc->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@ID="' . $doc->toplevelId . '"]/ancestor::mets:div[./mets:mptr][1]/mets:mptr');
0 ignored issues
show
Bug introduced by
The method xpath() 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

302
            /** @scrutinizer ignore-call */ 
303
            $parentMptr = $doc->mets->xpath('./mets:structMap[@TYPE="LOGICAL"]//mets:div[@ID="' . $doc->toplevelId . '"]/ancestor::mets:div[./mets:mptr][1]/mets:mptr');

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...
Bug Best Practice introduced by
The property mets does not exist on Kitodo\Dlf\Common\Doc. Since you implemented __get, consider adding a @property annotation.
Loading history...
303
            if (!empty($parentMptr)) {
304
                $parentLocation = (string) $parentMptr[0]->attributes('http://www.w3.org/1999/xlink')->href;
305
306
                // find document object by record_id of parent
307
                $parentDoc = Doc::getInstance($parentLocation, ['storagePid' => $this->storagePid]);
308
309
                if ($parentDoc->recordId) {
310
                    $parentDocument = $this->documentRepository->findOneByRecordId($parentDoc->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

310
                    /** @scrutinizer ignore-call */ 
311
                    $parentDocument = $this->documentRepository->findOneByRecordId($parentDoc->recordId);
Loading history...
311
312
                    if ($parentDocument === null) {
313
                        // create new Document object
314
                        $parentDocument = GeneralUtility::makeInstance(Document::class);
315
                    }
316
317
                    $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

317
                    $parentDocument->/** @scrutinizer ignore-call */ 
318
                                     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...
318
                    $parentDocument->setDoc($parentDoc);
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

318
                    $parentDocument->/** @scrutinizer ignore-call */ 
319
                                     setDoc($parentDoc);

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...
319
                    $parentDocument->setLocation($parentLocation);
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

319
                    $parentDocument->/** @scrutinizer ignore-call */ 
320
                                     setLocation($parentLocation);

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...
320
                    $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

320
                    $parentDocument->/** @scrutinizer ignore-call */ 
321
                                     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...
321
322
                    $success = $this->saveToDatabase($parentDocument);
323
324
                    if ($success === true) {
325
                        // add to index
326
                        Indexer::add($parentDocument);
327
                        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

327
                        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...
328
                    }
329
                }
330
            }
331
        }
332
333
        return 0;
334
    }
335
336
}
337