Passed
Push — master ( ce34db...aabc2a )
by
unknown
13:08
created

ExtensionComposerStatusController   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 16
eloc 74
c 1
b 0
f 0
dl 0
loc 150
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getLanguageService() 0 3 1
A detailAction() 0 14 3
A registerDocHeaderButtons() 0 11 2
A getComposerManifestMarkup() 0 30 2
A initializeAction() 0 6 2
A __construct() 0 10 1
A initializeView() 0 4 1
A listAction() 0 20 2
A getExtensionIcon() 0 4 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace TYPO3\CMS\Extensionmanager\Controller;
19
20
use TYPO3\CMS\Backend\Form\FormResultCompiler;
21
use TYPO3\CMS\Backend\Form\NodeFactory;
22
use TYPO3\CMS\Core\Core\Environment;
23
use TYPO3\CMS\Core\Imaging\Icon;
24
use TYPO3\CMS\Core\Package\ComposerDeficitDetector;
25
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
use TYPO3\CMS\Core\Utility\MathUtility;
28
use TYPO3\CMS\Core\Utility\PathUtility;
29
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
30
use TYPO3\CMS\Extensionmanager\Service\ComposerManifestProposalGenerator;
31
use TYPO3\CMS\Extensionmanager\Utility\ListUtility;
32
33
/**
34
 * Provide information about extensions' composer status
35
 *
36
 * @internal This class is a specific controller implementation and is not considered part of the Public TYPO3 API.
37
 */
38
class ExtensionComposerStatusController extends AbstractModuleController
39
{
40
    /**
41
     * @var ComposerDeficitDetector
42
     */
43
    protected $composerDeficitDetector;
44
45
    /**
46
     * @var ComposerDeficitDetector
47
     */
48
    protected $composerManifestProposalGenerator;
49
50
    /**
51
     * @var NodeFactory
52
     */
53
    protected $nodeFactory;
54
55
    /**
56
     * @var ListUtility
57
     */
58
    protected $listUtility;
59
60
    /**
61
     * @var string
62
     */
63
    protected $returnUrl = '';
64
65
    public function __construct(
66
        ComposerDeficitDetector $composerDeficitDetector,
67
        ComposerManifestProposalGenerator $composerManifestProposalGenerator,
68
        NodeFactory $nodeFactory,
69
        ListUtility $listUtility
70
    ) {
71
        $this->composerDeficitDetector = $composerDeficitDetector;
72
        $this->composerManifestProposalGenerator = $composerManifestProposalGenerator;
0 ignored issues
show
Documentation Bug introduced by
It seems like $composerManifestProposalGenerator of type TYPO3\CMS\Extensionmanag...nifestProposalGenerator is incompatible with the declared type TYPO3\CMS\Core\Package\ComposerDeficitDetector of property $composerManifestProposalGenerator.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
73
        $this->nodeFactory = $nodeFactory;
74
        $this->listUtility = $listUtility;
75
    }
76
77
    protected function initializeAction(): void
78
    {
79
        parent::initializeAction();
80
        if ($this->request->hasArgument('returnUrl')) {
81
            $this->returnUrl = GeneralUtility::sanitizeLocalUrl(
82
                (string)$this->request->getArgument('returnUrl')
83
            );
84
        }
85
    }
86
87
    protected function initializeView(ViewInterface $view): void
88
    {
89
        parent::initializeView($view);
90
        $this->registerDocHeaderButtons();
91
    }
92
93
    public function listAction(): void
94
    {
95
        $extensions = [];
96
        $basePackagePath = Environment::getExtensionsPath() . '/';
97
        $detailLinkReturnUrl = $this->uriBuilder->reset()->uriFor('list', array_filter(['returnUrl' => $this->returnUrl]));
98
        foreach ($this->composerDeficitDetector->getExtensionsWithComposerDeficit() as $extensionKey => $deficit) {
99
            $extensionPath = $basePackagePath . $extensionKey . '/';
100
            $extensions[$extensionKey] = [
101
                'deficit' => $deficit,
102
                'packagePath' => $extensionPath,
103
                'icon' => $this->getExtensionIcon($extensionPath),
104
                'detailLink' => $this->uriBuilder->reset()->uriFor('detail', [
105
                    'extensionKey' => $extensionKey,
106
                    'returnUrl' => $detailLinkReturnUrl
107
                ])
108
            ];
109
        }
110
        ksort($extensions);
111
        $this->view->assign('extensions', $this->listUtility->enrichExtensionsWithEmConfInformation($extensions));
112
        $this->generateMenu();
113
    }
114
115
    public function detailAction(string $extensionKey): void
116
    {
117
        if ($extensionKey === '') {
118
            $this->redirect('list');
119
        }
120
121
        $deficit = $this->composerDeficitDetector->checkExtensionComposerDeficit($extensionKey);
122
        $this->view->assignMultiple([
123
            'extensionKey' => $extensionKey,
124
            'deficit' => $deficit
125
        ]);
126
127
        if ($deficit !== ComposerDeficitDetector::EXTENSION_COMPOSER_MANIFEST_VALID) {
128
            $this->view->assign('composerManifestMarkup', $this->getComposerManifestMarkup($extensionKey));
129
        }
130
    }
131
132
    protected function getComposerManifestMarkup(string $extensionKey): string
133
    {
134
        $formResultCompiler = GeneralUtility::makeInstance(FormResultCompiler::class);
135
        $composerManifest = $this->composerManifestProposalGenerator->getComposerManifestProposal($extensionKey);
0 ignored issues
show
Bug introduced by
The method getComposerManifestProposal() does not exist on TYPO3\CMS\Core\Package\ComposerDeficitDetector. ( Ignorable by Annotation )

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

135
        /** @scrutinizer ignore-call */ 
136
        $composerManifest = $this->composerManifestProposalGenerator->getComposerManifestProposal($extensionKey);

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...
136
        if ($composerManifest === '') {
137
            return '';
138
        }
139
        $rows = MathUtility::forceIntegerInRange(count(explode(LF, $composerManifest)), 1, PHP_INT_MAX);
140
        $fakeFieldTca = [
141
            'renderType' => 't3editor',
142
            'tableName' => $extensionKey,
143
            'fieldName' => 'composer.json',
144
            'effectivePid' => 0,
145
            'parameterArray' => [
146
                'itemFormElName' => 'composerManifest-' . $extensionKey,
147
                'itemFormElValue' => $composerManifest,
148
                'fieldConf' => [
149
                    'config' => [
150
                        'readOnly' => true,
151
                        'rows' => ++$rows,
152
                        'codeMirrorFirstLineNumber' => 1,
153
                    ]
154
                ]
155
            ]
156
        ];
157
        $resultArray = $this->nodeFactory->create($fakeFieldTca)->render();
158
        $formResultCompiler->mergeResult($resultArray);
159
        $formResultCompiler->addCssFiles();
160
        $formResultCompiler->printNeededJSFunctions();
161
        return $resultArray['html'];
162
    }
163
164
    protected function registerDocHeaderButtons(): void
165
    {
166
        $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
167
        if ($this->returnUrl !== '') {
168
            $buttonBar->addButton(
169
                $buttonBar
170
                    ->makeLinkButton()
171
                    ->setHref($this->returnUrl)
172
                    ->setClasses('typo3-goBack')
173
                    ->setTitle($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
174
                    ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL))
175
            );
176
        }
177
    }
178
179
    protected function getExtensionIcon(string $extensionPath): string
180
    {
181
        $icon = ExtensionManagementUtility::getExtensionIcon($extensionPath);
182
        return $icon ? PathUtility::getAbsoluteWebPath($extensionPath . $icon) : '';
183
    }
184
185
    protected function getLanguageService()
186
    {
187
        return $GLOBALS['LANG'];
188
    }
189
}
190