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.

Issues (210)

Classes/Command/IndexCommand.php (6 issues)

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\Command\BaseCommand;
17
use Kitodo\Dlf\Common\Indexer;
18
use Kitodo\Dlf\Domain\Model\Document;
19
use Symfony\Component\Console\Input\InputInterface;
20
use Symfony\Component\Console\Input\InputOption;
21
use Symfony\Component\Console\Output\OutputInterface;
22
use Symfony\Component\Console\Style\SymfonyStyle;
23
use TYPO3\CMS\Core\Utility\GeneralUtility;
24
use TYPO3\CMS\Core\Utility\MathUtility;
25
26
/**
27
 * CLI Command for indexing single documents into database and Solr.
28
 *
29
 * @package TYPO3
30
 * @subpackage dlf
31
 *
32
 * @access public
33
 */
34
class IndexCommand extends BaseCommand
35
{
36
37
    /**
38
     * Configure the command by defining the name, options and arguments
39
     *
40
     * @access public
41
     *
42
     * @return void
43
     */
44
    public function configure(): void
45
    {
46
        $this
47
            ->setDescription('Index single document into database and Solr.')
48
            ->setHelp('')
49
            ->addOption(
50
                'dry-run',
51
                null,
52
                InputOption::VALUE_NONE,
53
                'If this option is set, the files will not actually be processed but the location URI is shown.'
54
            )
55
            ->addOption(
56
                'doc',
57
                'd',
58
                InputOption::VALUE_REQUIRED,
59
                'UID or URL of the document.'
60
            )
61
            ->addOption(
62
                'pid',
63
                'p',
64
                InputOption::VALUE_REQUIRED,
65
                'UID of the page the document should be added to.'
66
            )
67
            ->addOption(
68
                'solr',
69
                's',
70
                InputOption::VALUE_REQUIRED,
71
                '[UID|index_name] of the Solr core the document should be added to.'
72
            )
73
            ->addOption(
74
                'owner',
75
                'o',
76
                InputOption::VALUE_OPTIONAL,
77
                '[UID|index_name] of the Library which should be set as owner of the document.'
78
            )
79
            ->addOption(
80
                'softCommit',
81
                null,
82
                InputOption::VALUE_NONE,
83
                'If this option is set, documents are just added to the index by a soft commit.'
84
            );
85
    }
86
87
    /**
88
     * Executes the command to index the given document to DB and SOLR.
89
     *
90
     * @access protected
91
     *
92
     * @param InputInterface $input The input parameters
93
     * @param OutputInterface $output The Symfony interface for outputs on console
94
     *
95
     * @return int
96
     */
97
    protected function execute(InputInterface $input, OutputInterface $output): int
98
    {
99
        $dryRun = $input->getOption('dry-run') != false ? true : false;
100
101
        $io = new SymfonyStyle($input, $output);
102
        $io->title($this->getDescription());
103
104
        $this->initializeRepositories((int) $input->getOption('pid'));
105
106
        if ($this->storagePid == 0) {
107
            $io->error('ERROR: No valid PID (' . $this->storagePid . ') given.');
108
            return BaseCommand::FAILURE;
109
        }
110
111
        if (
112
            !empty($input->getOption('solr'))
113
            && !is_array($input->getOption('solr'))
114
        ) {
115
            $allSolrCores = $this->getSolrCores($this->storagePid);
116
            $solrCoreUid = $this->getSolrCoreUid($allSolrCores, $input->getOption('solr'));
117
118
            // Abort if solrCoreUid is empty or not in the array of allowed solr cores.
119
            if (empty($solrCoreUid) || !in_array($solrCoreUid, $allSolrCores)) {
120
                $outputSolrCores = [];
121
                foreach ($allSolrCores as $indexName => $uid) {
122
                    $outputSolrCores[] = $uid . ' : ' . $indexName;
123
                }
124
                if (empty($outputSolrCores)) {
125
                    $io->error('ERROR: No valid Solr core ("' . $input->getOption('solr') . '") given. No valid cores found on PID ' . $this->storagePid . ".\n");
126
                    return BaseCommand::FAILURE;
127
                } else {
128
                    $io->error('ERROR: No valid Solr core ("' . $input->getOption('solr') . '") given. ' . "Valid cores are (<uid>:<index_name>):\n" . implode("\n", $outputSolrCores) . "\n");
129
                    return BaseCommand::FAILURE;
130
                }
131
            }
132
        } else {
133
            $io->error('ERROR: Required parameter --solr|-s is missing or array.');
134
            return BaseCommand::FAILURE;
135
        }
136
137
        if (
138
            empty($input->getOption('doc'))
139
            || is_array($input->getOption('doc'))
140
            || (
141
                !MathUtility::canBeInterpretedAsInteger($input->getOption('doc'))
142
                && !GeneralUtility::isValidUrl($input->getOption('doc'))
143
            )
144
        ) {
145
            $io->error('ERROR: Required parameter --doc|-d is not a valid document UID or URL.');
146
            return BaseCommand::FAILURE;
147
        }
148
149
        if (!empty($input->getOption('owner'))) {
150
            if (MathUtility::canBeInterpretedAsInteger($input->getOption('owner'))) {
151
                $this->owner = $this->libraryRepository->findByUid(MathUtility::forceIntegerInRange((int) $input->getOption('owner'), 1));
152
            } else {
153
                $this->owner = $this->libraryRepository->findOneByIndexName((string) $input->getOption('owner'));
0 ignored issues
show
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

153
                /** @scrutinizer ignore-call */ 
154
                $this->owner = $this->libraryRepository->findOneByIndexName((string) $input->getOption('owner'));
Loading history...
154
            }
155
        } else {
156
            $this->owner = null;
157
        }
158
159
        $document = null;
160
        $doc = null;
161
162
        // Try to find existing document in database
163
        if (MathUtility::canBeInterpretedAsInteger($input->getOption('doc'))) {
164
165
            $document = $this->documentRepository->findByUid($input->getOption('doc'));
166
167
            if ($document === null) {
168
                $io->error('ERROR: Document with UID "' . $input->getOption('doc') . '" could not be found on PID ' . $this->storagePid . ' .');
169
                return BaseCommand::FAILURE;
170
            } else {
171
                $doc = AbstractDocument::getInstance($document->getLocation(), ['storagePid' => $this->storagePid], true);
172
            }
173
174
        } else if (GeneralUtility::isValidUrl($input->getOption('doc'))) {
175
            $doc = AbstractDocument::getInstance($input->getOption('doc'), ['storagePid' => $this->storagePid], true);
176
177
            $document = $this->getDocumentFromUrl($doc, $input->getOption('doc'));
178
        }
179
180
        if ($doc === null) {
181
            $io->error('ERROR: Document "' . $input->getOption('doc') . '" could not be loaded.');
182
            return BaseCommand::FAILURE;
183
        }
184
185
        $document->setSolrcore($solrCoreUid);
186
187
        if ($dryRun) {
188
            $io->section('DRY RUN: Would index ' . $document->getUid() . ' ("' . $document->getLocation() . '") on PID ' . $this->storagePid . ' and Solr core ' . $solrCoreUid . '.');
189
            $io->success('All done!');
190
            return BaseCommand::SUCCESS;
191
        } else {
192
            $document->setCurrentDocument($doc);
193
194
            if ($io->isVerbose()) {
195
                $io->section('Indexing ' . $document->getUid() . ' ("' . $document->getLocation() . '") on PID ' . $this->storagePid . '.');
196
            }
197
            $isSaved = $this->saveToDatabase($document, $input->getOption('softCommit'));
0 ignored issues
show
It seems like $document can also be of type null; however, parameter $document of Kitodo\Dlf\Command\BaseCommand::saveToDatabase() does only seem to accept Kitodo\Dlf\Domain\Model\Document, maybe add an additional type check? ( Ignorable by Annotation )

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

197
            $isSaved = $this->saveToDatabase(/** @scrutinizer ignore-type */ $document, $input->getOption('softCommit'));
Loading history...
198
199
            if ($isSaved) {
200
                if ($io->isVerbose()) {
201
                    $io->section('Indexing ' . $document->getUid() . ' ("' . $document->getLocation() . '") on Solr core ' . $solrCoreUid . '.');
202
                }
203
                $isSaved = Indexer::add($document, $this->documentRepository, $input->getOption('softCommit'));
0 ignored issues
show
It seems like $document can also be of type null; however, parameter $document of Kitodo\Dlf\Common\Indexer::add() does only seem to accept Kitodo\Dlf\Domain\Model\Document, maybe add an additional type check? ( Ignorable by Annotation )

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

203
                $isSaved = Indexer::add(/** @scrutinizer ignore-type */ $document, $this->documentRepository, $input->getOption('softCommit'));
Loading history...
204
            } else {
205
                $io->error('ERROR: Document with UID "' . $document->getUid() . '" could not be indexed on PID ' . $this->storagePid . ' . There are missing mandatory fields (at least one of those: ' . $this->extConf['general']['requiredMetadataFields'] . ') in this document.');
206
                return BaseCommand::FAILURE;
207
            }
208
209
            if ($isSaved) {
210
                $io->success('All done!');
211
                return BaseCommand::SUCCESS;
212
            }
213
214
            $io->error('ERROR: Document with UID "' . $document->getUid() . '" could not be indexed on Solr core ' . $solrCoreUid . ' . There are missing mandatory fields (at least one of those: ' . $this->extConf['general']['requiredMetadataFields'] . ') in this document.');
215
            $io->info('INFO: Document with UID "' . $document->getUid() . '" is already in database. If you want to keep the database and index consistent you need to remove it.');
216
            return BaseCommand::FAILURE;
217
        }
218
    }
219
220
    /**
221
     * Get document from given URL. Find it in database, if not found create the new one.
222
     *
223
     * @access private
224
     *
225
     * @param AbstractDocument $doc
226
     * @param string $url
227
     *
228
     * @return Document
229
     */
230
    private function getDocumentFromUrl($doc, string $url): Document
231
    {
232
        $document = null;
233
234
        if ($doc->recordId) {
235
            $document = $this->documentRepository->findOneByRecordId($doc->recordId);
0 ignored issues
show
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

235
            /** @scrutinizer ignore-call */ 
236
            $document = $this->documentRepository->findOneByRecordId($doc->recordId);
Loading history...
236
        } else {
237
            $document = $this->documentRepository->findOneByLocation($url);
0 ignored issues
show
The method findOneByLocation() 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

237
            /** @scrutinizer ignore-call */ 
238
            $document = $this->documentRepository->findOneByLocation($url);
Loading history...
238
        }
239
240
        if ($document === null) {
241
            // create new Document object
242
            $document = GeneralUtility::makeInstance(Document::class);
243
        }
244
245
        // now there must exist a document object
246
        if ($document) {
247
            $document->setLocation($url);
0 ignored issues
show
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

247
            $document->/** @scrutinizer ignore-call */ 
248
                       setLocation($url);

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...
248
        }
249
250
        return $document;
251
    }
252
}
253