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 (188)

Classes/Command/IndexCommand.php (7 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
    }
80
81
    /**
82
     * Executes the command to index the given document to DB and SOLR.
83
     *
84
     * @access protected
85
     *
86
     * @param InputInterface $input The input parameters
87
     * @param OutputInterface $output The Symfony interface for outputs on console
88
     *
89
     * @return int
90
     */
91
    protected function execute(InputInterface $input, OutputInterface $output): int
92
    {
93
        $dryRun = $input->getOption('dry-run') != false ? true : false;
94
95
        $io = new SymfonyStyle($input, $output);
96
        $io->title($this->getDescription());
97
98
        $this->initializeRepositories($input->getOption('pid'));
99
100
        if ($this->storagePid == 0) {
101
            $io->error('ERROR: No valid PID (' . $this->storagePid . ') given.');
102
            return BaseCommand::FAILURE;
103
        }
104
105
        if (
106
            !empty($input->getOption('solr'))
107
            && !is_array($input->getOption('solr'))
108
        ) {
109
            $allSolrCores = $this->getSolrCores($this->storagePid);
110
            $solrCoreUid = $this->getSolrCoreUid($allSolrCores, $input->getOption('solr'));
111
112
            // Abort if solrCoreUid is empty or not in the array of allowed solr cores.
113
            if (empty($solrCoreUid) || !in_array($solrCoreUid, $allSolrCores)) {
114
                $output_solrCores = [];
115
                foreach ($allSolrCores as $index_name => $uid) {
116
                    $output_solrCores[] = $uid . ' : ' . $index_name;
117
                }
118
                if (empty($output_solrCores)) {
119
                    $io->error('ERROR: No valid Solr core ("' . $input->getOption('solr') . '") given. No valid cores found on PID ' . $this->storagePid . ".\n");
120
                    return BaseCommand::FAILURE;
121
                } else {
122
                    $io->error('ERROR: No valid Solr core ("' . $input->getOption('solr') . '") given. ' . "Valid cores are (<uid>:<index_name>):\n" . implode("\n", $output_solrCores) . "\n");
123
                    return BaseCommand::FAILURE;
124
                }
125
            }
126
        } else {
127
            $io->error('ERROR: Required parameter --solr|-s is missing or array.');
128
            return BaseCommand::FAILURE;
129
        }
130
131
        if (
132
            empty($input->getOption('doc'))
133
            || is_array($input->getOption('doc'))
134
            || (
135
                !MathUtility::canBeInterpretedAsInteger($input->getOption('doc'))
136
                && !GeneralUtility::isValidUrl($input->getOption('doc'))
137
            )
138
        ) {
139
            $io->error('ERROR: Required parameter --doc|-d is not a valid document UID or URL.');
140
            return BaseCommand::FAILURE;
141
        }
142
143
        if (!empty($input->getOption('owner'))) {
144
            if (MathUtility::canBeInterpretedAsInteger($input->getOption('owner'))) {
145
                $this->owner = $this->libraryRepository->findByUid(MathUtility::forceIntegerInRange((int) $input->getOption('owner'), 1));
146
            } else {
147
                $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

147
                /** @scrutinizer ignore-call */ 
148
                $this->owner = $this->libraryRepository->findOneByIndexName((string) $input->getOption('owner'));
Loading history...
148
            }
149
        } else {
150
            $this->owner = null;
151
        }
152
153
        $document = null;
154
        $doc = null;
155
156
        // Try to find existing document in database
157
        if (MathUtility::canBeInterpretedAsInteger($input->getOption('doc'))) {
158
159
            $document = $this->documentRepository->findByUid($input->getOption('doc'));
160
161
            if ($document === null) {
162
                $io->error('ERROR: Document with UID "' . $input->getOption('doc') . '" could not be found on PID ' . $this->storagePid . ' .');
163
                exit(1);
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return integer. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
164
            } else {
165
                $doc = AbstractDocument::getInstance($document->getLocation(), ['storagePid' => $this->storagePid], true);
166
            }
167
168
        } else if (GeneralUtility::isValidUrl($input->getOption('doc'))) {
169
            $doc = AbstractDocument::getInstance($input->getOption('doc'), ['storagePid' => $this->storagePid], true);
170
171
            $document = $this->getDocumentFromUrl($doc, $input->getOption('doc'));
172
        }
173
174
        if ($doc === null) {
175
            $io->error('ERROR: Document "' . $input->getOption('doc') . '" could not be loaded.');
176
            return BaseCommand::FAILURE;
177
        }
178
179
        $document->setSolrcore($solrCoreUid);
180
181
        if ($dryRun) {
182
            $io->section('DRY RUN: Would index ' . $document->getUid() . ' ("' . $document->getLocation() . '") on PID ' . $this->storagePid . ' and Solr core ' . $solrCoreUid . '.');
183
        } else {
184
            if ($io->isVerbose()) {
185
                $io->section('Indexing ' . $document->getUid() . ' ("' . $document->getLocation() . '") on PID ' . $this->storagePid . ' and Solr core ' . $solrCoreUid . '.');
186
            }
187
            $document->setCurrentDocument($doc);
188
            // save to database
189
            $this->saveToDatabase($document);
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

189
            $this->saveToDatabase(/** @scrutinizer ignore-type */ $document);
Loading history...
190
            // add to index
191
            Indexer::add($document, $this->documentRepository);
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

191
            Indexer::add(/** @scrutinizer ignore-type */ $document, $this->documentRepository);
Loading history...
192
        }
193
194
        $io->success('All done!');
195
196
        return BaseCommand::SUCCESS;
197
    }
198
199
    /**
200
     * Get document from given URL. Find it in database, if not found create the new one.
201
     *
202
     * @access private
203
     *
204
     * @param AbstractDocument $doc
205
     * @param string $url
206
     *
207
     * @return Document
208
     */
209
    private function getDocumentFromUrl($doc, string $url): Document
210
    {
211
        $document = null;
212
213
        if ($doc->recordId) {
214
            $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

214
            /** @scrutinizer ignore-call */ 
215
            $document = $this->documentRepository->findOneByRecordId($doc->recordId);
Loading history...
215
        } else {
216
            $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

216
            /** @scrutinizer ignore-call */ 
217
            $document = $this->documentRepository->findOneByLocation($url);
Loading history...
217
        }
218
219
        if ($document === null) {
220
            // create new Document object
221
            $document = GeneralUtility::makeInstance(Document::class);
222
        }
223
224
        // now there must exist a document object
225
        if ($document) {
226
            $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

226
            $document->/** @scrutinizer ignore-call */ 
227
                       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...
227
        }
228
229
        return $document;
230
    }
231
}
232