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/Controller/Backend/NewTenantController.php (1 issue)

1
<?php
2
/**
3
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
4
 *
5
 * This file is part of the Kitodo and TYPO3 projects.
6
 *
7
 * @license GNU General Public License version 3 or later.
8
 * For the full copyright and license information, please read the
9
 * LICENSE.txt file that was distributed with this source code.
10
 */
11
12
namespace Kitodo\Dlf\Controller\Backend;
13
14
use Kitodo\Dlf\Common\Helper;
15
use Kitodo\Dlf\Common\Solr\Solr;
16
use Kitodo\Dlf\Controller\AbstractController;
17
use Kitodo\Dlf\Domain\Model\Format;
18
use Kitodo\Dlf\Domain\Model\SolrCore;
19
use Kitodo\Dlf\Domain\Repository\FormatRepository;
20
use Kitodo\Dlf\Domain\Repository\MetadataRepository;
21
use Kitodo\Dlf\Domain\Repository\SolrCoreRepository;
22
use Kitodo\Dlf\Domain\Repository\StructureRepository;
23
use Psr\Http\Message\ResponseInterface;
24
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
25
use TYPO3\CMS\Backend\Utility\BackendUtility;
26
use TYPO3\CMS\Core\Core\Environment;
27
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
28
use TYPO3\CMS\Core\Localization\LocalizationFactory;
29
use TYPO3\CMS\Core\Messaging\FlashMessageService;
30
use TYPO3\CMS\Core\Page\PageRenderer;
31
use TYPO3\CMS\Core\Resource\ResourceFactory;
32
use TYPO3\CMS\Core\Site\Entity\NullSite;
33
use TYPO3\CMS\Core\Site\SiteFinder;
34
use TYPO3\CMS\Core\Utility\GeneralUtility;
35
use TYPO3\CMS\Extbase\Mvc\Request;
36
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
37
use TYPO3\CMS\Fluid\View\TemplateView;
38
use TYPO3Fluid\Fluid\View\ViewInterface;
39
40
/**
41
 * Controller class for the backend module 'New Tenant'.
42
 *
43
 * @package TYPO3
44
 * @subpackage dlf
45
 *
46
 * @access public
47
 */
48
class NewTenantController extends AbstractController
49
{
50
    /**
51
     * @access protected
52
     * @var int
53
     */
54
    protected int $pid;
55
56
    /**
57
     * @access protected
58
     * @var array
59
     */
60
    protected array $pageInfo;
61
62
    /**
63
     * @access protected
64
     * @var array All configured site languages
65
     */
66
    protected array $siteLanguages;
67
68
    /**
69
     * @access protected
70
     * @var LocalizationFactory Language factory to get language key/values by our own.
71
     */
72
    protected LocalizationFactory $languageFactory;
73
74
    /**
75
     * @access protected
76
     * @var FormatRepository
77
     */
78
    protected FormatRepository $formatRepository;
79
80
    /**
81
     * @access public
82
     *
83
     * @param FormatRepository $formatRepository
84
     *
85
     * @return void
86
     */
87
    public function injectFormatRepository(FormatRepository $formatRepository): void
88
    {
89
        $this->formatRepository = $formatRepository;
90
    }
91
92
    /**
93
     * @access protected
94
     * @var MetadataRepository
95
     */
96
    protected MetadataRepository $metadataRepository;
97
98
    /**
99
     * @access public
100
     *
101
     * @param MetadataRepository $metadataRepository
102
     *
103
     * @return void
104
     */
105
    public function injectMetadataRepository(MetadataRepository $metadataRepository): void
106
    {
107
        $this->metadataRepository = $metadataRepository;
108
    }
109
110
    /**
111
     * @access protected
112
     * @var StructureRepository
113
     */
114
    protected StructureRepository $structureRepository;
115
116
    /**
117
     * @access public
118
     *
119
     * @param StructureRepository $structureRepository
120
     *
121
     * @return void
122
     */
123
    public function injectStructureRepository(StructureRepository $structureRepository): void
124
    {
125
        $this->structureRepository = $structureRepository;
126
    }
127
128
    /**
129
     * @access protected
130
     * @var SolrCoreRepository
131
     */
132
    protected SolrCoreRepository $solrCoreRepository;
133
134
    /**
135
     * @access public
136
     *
137
     * @param SolrCoreRepository $solrCoreRepository
138
     *
139
     * @return void
140
     */
141
    public function injectSolrCoreRepository(SolrCoreRepository $solrCoreRepository): void
142
    {
143
        $this->solrCoreRepository = $solrCoreRepository;
144
    }
145
146
    /**
147
     * Returns a response object with either the given html string or the current rendered view as content.
148
     * 
149
     * @access protected
150
     * 
151
     * @param ?string $html optional html
152
     * 
153
     * @return ResponseInterface the response
154
     */
155
    protected function htmlResponse(?string $html = null): ResponseInterface
156
    {
157
        $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
158
        $messageQueue = $flashMessageService->getMessageQueueByIdentifier();
159
160
        $moduleTemplateFactory = GeneralUtility::makeInstance(ModuleTemplateFactory::class);
161
        $moduleTemplate = $moduleTemplateFactory->create($this->request);
162
        $moduleTemplate->setContent($this->view->render());
163
        $moduleTemplate->setFlashMessageQueue($messageQueue);
164
        return parent::htmlResponse(($html ?? $moduleTemplate->renderContent()));
165
    }
166
167
    /**
168
     * Initialization for all actions
169
     *
170
     * @access protected
171
     *
172
     * @return void
173
     */
174
    protected function initializeAction(): void
175
    {
176
        // replace with $this->request->getQueryParams() when dropping support for Typo3 v11, see Deprecation-100596
177
        $this->pid = (int) GeneralUtility::_GP('id');
178
179
        $frameworkConfiguration = $this->configurationManager->getConfiguration($this->configurationManager::CONFIGURATION_TYPE_FRAMEWORK);
180
        $frameworkConfiguration['persistence']['storagePid'] = $this->pid;
181
        $this->configurationManager->setConfiguration($frameworkConfiguration);
182
183
        $this->languageFactory = GeneralUtility::makeInstance(LocalizationFactory::class);
184
185
        try {
186
            $site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($this->pid);
187
        } catch (SiteNotFoundException $e) {
188
            $site = new NullSite();
189
        }
190
        $this->siteLanguages = $site->getLanguages();
191
    }
192
193
194
    /**
195
     * Action adding formats records
196
     *
197
     * @access public
198
     *
199
     * @return ResponseInterface the response
200
     */
201
    public function addFormatAction(): ResponseInterface
202
    {
203
        // Include formats definition file.
204
        $formatsDefaults = $this->getRecords('Format');
205
206
        $frameworkConfiguration = $this->configurationManager->getConfiguration($this->configurationManager::CONFIGURATION_TYPE_FRAMEWORK);
207
        // tx_dlf_formats are stored on PID = 0
208
        $frameworkConfiguration['persistence']['storagePid'] = 0;
209
        $this->configurationManager->setConfiguration($frameworkConfiguration);
210
211
        $doPersist = false;
212
213
        foreach ($formatsDefaults as $type => $values) {
214
            // if default format record is not found, add it to the repository
215
            if ($this->formatRepository->findOneByType($type) === null) {
216
                $newRecord = GeneralUtility::makeInstance(Format::class);
217
                $newRecord->setType($type);
218
                $newRecord->setRoot($values['root']);
219
                $newRecord->setNamespace($values['namespace']);
220
                $newRecord->setClass($values['class']);
221
                $this->formatRepository->add($newRecord);
222
223
                $doPersist = true;
224
            }
225
        }
226
227
        // We must persist here, if we changed anything.
228
        if ($doPersist === true) {
229
            $persistenceManager = GeneralUtility::makeInstance(PersistenceManager::class);
230
            $persistenceManager->persistAll();
231
        }
232
233
        return $this->redirect('index');
234
    }
235
236
    /**
237
     * Action adding metadata records
238
     *
239
     * @access public
240
     *
241
     * @return ResponseInterface the response
242
     */
243
    public function addMetadataAction(): ResponseInterface
244
    {
245
        // Include metadata definition file.
246
        $metadataDefaults = $this->getRecords('Metadata');
247
248
        // load language file in own array
249
        $metadataLabels = $this->languageFactory->getParsedData('EXT:dlf/Resources/Private/Language/locallang_metadata.xlf', $this->siteLanguages[0]->getTypo3Language());
250
251
        $insertedFormats = $this->formatRepository->findAll();
252
253
        $availableFormats = [];
254
        foreach ($insertedFormats as $insertedFormat) {
255
            $availableFormats[$insertedFormat->getRoot()] = $insertedFormat->getUid();
256
        }
257
258
        $defaultWrap = BackendUtility::getTcaFieldConfiguration('tx_dlf_metadata', 'wrap')['default'];
259
260
        $data = [];
261
        foreach ($metadataDefaults as $indexName => $values) {
262
            $formatIds = [];
263
264
            foreach ($values['format'] as $format) {
265
                $format['encoded'] = $availableFormats[$format['format_root']];
266
                unset($format['format_root']);
267
                $formatIds[] = uniqid('NEW');
268
                $data['tx_dlf_metadataformat'][end($formatIds)] = $format;
269
                $data['tx_dlf_metadataformat'][end($formatIds)]['pid'] = $this->pid;
270
            }
271
272
            $data['tx_dlf_metadata'][uniqid('NEW')] = [
273
                'pid' => $this->pid,
274
                'label' => $this->getLLL('metadata.' . $indexName, $this->siteLanguages[0]->getTypo3Language(), $metadataLabels),
275
                'index_name' => $indexName,
276
                'format' => implode(',', $formatIds),
277
                'default_value' => $values['default_value'],
278
                'wrap' => !empty($values['wrap']) ? $values['wrap'] : $defaultWrap,
279
                'index_tokenized' => $values['index_tokenized'],
280
                'index_stored' => $values['index_stored'],
281
                'index_indexed' => $values['index_indexed'],
282
                'index_boost' => $values['index_boost'],
283
                'is_sortable' => $values['is_sortable'],
284
                'is_facet' => $values['is_facet'],
285
                'is_listed' => $values['is_listed'],
286
                'index_autocomplete' => $values['index_autocomplete'],
287
            ];
288
        }
289
290
        $metadataIds = Helper::processDatabaseAsAdmin($data, [], true);
291
292
        $insertedMetadata = [];
293
        foreach ($metadataIds as $id => $uid) {
294
            $metadata = $this->metadataRepository->findByUid($uid);
295
            // id array contains also ids of formats
296
            if ($metadata != null) {
297
                $insertedMetadata[$uid] = $metadata->getIndexName();
298
            }
299
        }
300
301
        foreach ($this->siteLanguages as $siteLanguage) {
302
            if ($siteLanguage->getLanguageId() === 0) {
303
                // skip default language
304
                continue;
305
            }
306
307
            $translateData = [];
308
            foreach ($insertedMetadata as $id => $indexName) {
309
                $translateData['tx_dlf_metadata'][uniqid('NEW')] = [
310
                    'pid' => $this->pid,
311
                    'sys_language_uid' => $siteLanguage->getLanguageId(),
312
                    'l18n_parent' => $id,
313
                    'label' => $this->getLLL('metadata.' . $indexName, $siteLanguage->getTypo3Language(), $metadataLabels),
314
                ];
315
            }
316
317
            Helper::processDatabaseAsAdmin($translateData);
318
        }
319
320
        return $this->redirect('index');
321
    }
322
323
    /**
324
     * Action adding Solr core records
325
     *
326
     * @access public
327
     *
328
     * @return ResponseInterface the response
329
     */
330
    public function addSolrCoreAction(): ResponseInterface
331
    {
332
        $doPersist = false;
333
334
        // load language file in own array
335
        $beLabels = $this->languageFactory->getParsedData('EXT:dlf/Resources/Private/Language/locallang_be.xlf', $this->siteLanguages[0]->getTypo3Language());
336
337
        if ($this->solrCoreRepository->findOneByPid($this->pid) === null) {
338
            $newRecord = GeneralUtility::makeInstance(SolrCore::class);
339
            $newRecord->setLabel($this->getLLL('flexform.solrcore', $this->siteLanguages[0]->getTypo3Language(), $beLabels). ' (PID ' . $this->pid . ')');
340
            $indexName = Solr::createCore('');
341
            if (!empty($indexName)) {
342
                $newRecord->setIndexName($indexName);
343
344
                $this->solrCoreRepository->add($newRecord);
345
346
                $doPersist = true;
347
            }
348
        }
349
350
        // We must persist here, if we changed anything.
351
        if ($doPersist === true) {
352
            $persistenceManager = GeneralUtility::makeInstance(PersistenceManager::class);
353
            $persistenceManager->persistAll();
354
        }
355
356
        return $this->redirect('index');
357
    }
358
359
    /**
360
     * Action adding structure records
361
     *
362
     * @access public
363
     *
364
     * @return ResponseInterface the response
365
     */
366
    public function addStructureAction(): ResponseInterface
367
    {
368
        // Include structure definition file.
369
        $structureDefaults = $this->getRecords('Structure');
370
371
        // load language file in own array
372
        $structureLabels = $this->languageFactory->getParsedData('EXT:dlf/Resources/Private/Language/locallang_structure.xlf', $this->siteLanguages[0]->getTypo3Language());
373
374
        $data = [];
375
        foreach ($structureDefaults as $indexName => $values) {
376
            $data['tx_dlf_structures'][uniqid('NEW')] = [
377
                'pid' => $this->pid,
378
                'toplevel' => $values['toplevel'],
379
                'label' => $this->getLLL('structure.' . $indexName, $this->siteLanguages[0]->getTypo3Language(), $structureLabels),
380
                'index_name' => $indexName,
381
                'oai_name' => $values['oai_name'],
382
                'thumbnail' => 0,
383
            ];
384
        }
385
        $structureIds = Helper::processDatabaseAsAdmin($data, [], true);
386
387
        $insertedStructures = [];
388
        foreach ($structureIds as $id => $uid) {
389
            $insertedStructures[$uid] = $this->structureRepository->findByUid($uid)->getIndexName();
390
        }
391
392
        foreach ($this->siteLanguages as $siteLanguage) {
393
            if ($siteLanguage->getLanguageId() === 0) {
394
                // skip default language
395
                continue;
396
            }
397
398
            $translateData = [];
399
            foreach ($insertedStructures as $id => $indexName) {
400
                $translateData['tx_dlf_structures'][uniqid('NEW')] = [
401
                    'pid' => $this->pid,
402
                    'sys_language_uid' => $siteLanguage->getLanguageId(),
403
                    'l18n_parent' => $id,
404
                    'label' => $this->getLLL('structure.' . $indexName, $siteLanguage->getTypo3Language(), $structureLabels),
405
                ];
406
            }
407
408
            Helper::processDatabaseAsAdmin($translateData);
409
        }
410
411
        return $this->redirect('index');
412
    }
413
414
    /**
415
     * Main function of the module
416
     *
417
     * @access public
418
     *
419
     * @return ResponseInterface the response
420
     */
421
    public function indexAction(): ResponseInterface
422
    {
423
        $recordInfos = [];
424
425
        $this->pageInfo = BackendUtility::readPageAccess($this->pid, $GLOBALS['BE_USER']->getPagePermsClause(1));
0 ignored issues
show
Documentation Bug introduced by
It seems like TYPO3\CMS\Backend\Utilit...>getPagePermsClause(1)) can also be of type false. However, the property $pageInfo is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
426
427
        if (!isset($this->pageInfo['doktype']) || $this->pageInfo['doktype'] != 254) {
428
            return $this->redirect('error');
429
        }
430
431
        $formatsDefaults = $this->getRecords('Format');
432
        $recordInfos['formats']['numCurrent'] = $this->formatRepository->countAll();
433
        $recordInfos['formats']['numDefault'] = count($formatsDefaults);
434
435
        $structuresDefaults = $this->getRecords('Structure');
436
        $recordInfos['structures']['numCurrent'] = $this->structureRepository->countByPid($this->pid);
437
        $recordInfos['structures']['numDefault'] = count($structuresDefaults);
438
439
        $metadataDefaults = $this->getRecords('Metadata');
440
        $recordInfos['metadata']['numCurrent'] = $this->metadataRepository->countByPid($this->pid);
441
        $recordInfos['metadata']['numDefault'] = count($metadataDefaults);
442
443
        $recordInfos['solrcore']['numCurrent'] = $this->solrCoreRepository->countByPid($this->pid);
444
445
        $this->view->assign('recordInfos', $recordInfos);
446
447
        return $this->htmlResponse();
448
    }
449
450
    /**
451
     * Error function - there is nothing to do at the moment.
452
     *
453
     * @access public
454
     *
455
     * @return void
456
     */
457
    // @phpstan-ignore-next-line
458
    public function errorAction(): ResponseInterface
459
    {
460
        return $this->htmlResponse();
461
    }
462
463
    /**
464
     * Get language label for given key and language.
465
     * 
466
     * @access private
467
     *
468
     * @param string $index
469
     * @param string $lang
470
     * @param array $langArray
471
     *
472
     * @return string
473
     */
474
    private function getLLL(string $index, string $lang, array $langArray): string
475
    {
476
        if (isset($langArray[$lang][$index][0]['target'])) {
477
            return $langArray[$lang][$index][0]['target'];
478
        } elseif (isset($langArray['default'][$index][0]['target'])) {
479
            return $langArray['default'][$index][0]['target'];
480
        } else {
481
            return 'Missing translation for ' . $index;
482
        }
483
    }
484
485
    /**
486
     * Get records from file for given record type.
487
     *
488
     * @access private
489
     *
490
     * @param string $recordType
491
     *
492
     * @return array
493
     */
494
    private function getRecords(string $recordType): array
495
    {
496
        $filePath = GeneralUtility::getFileAbsFileName('EXT:dlf/Resources/Private/Data/' . $recordType . 'Defaults.json');
497
        if (file_exists($filePath)) {
498
            $fileContents = file_get_contents($filePath);
499
            $records = json_decode($fileContents, true);
500
501
            if (json_last_error() === JSON_ERROR_NONE) {
502
                return $records;
503
            }
504
        }
505
        return [];
506
    }
507
}
508