[BUGFIX] Change EM composer mode message to info level
[Packages/TYPO3.CMS.git] / typo3 / sysext / extensionmanager / Classes / Controller / ListController.php
1 <?php
2 namespace TYPO3\CMS\Extensionmanager\Controller;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Backend\Template\Components\ButtonBar;
18 use TYPO3\CMS\Backend\View\BackendTemplateView;
19 use TYPO3\CMS\Core\Core\Bootstrap;
20 use TYPO3\CMS\Core\Imaging\Icon;
21 use TYPO3\CMS\Core\Messaging\FlashMessage;
22 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
23 use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
24 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
25 use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException;
26 use TYPO3\CMS\Extensionmanager\Utility\ExtensionModelUtility;
27 use TYPO3\CMS\Extensionmanager\Utility\Repository\Helper;
28
29 /**
30 * Controller for extension listings (TER or local extensions)
31 */
32 class ListController extends AbstractModuleController
33 {
34 /**
35 * @var \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository
36 */
37 protected $extensionRepository;
38
39 /**
40 * @var \TYPO3\CMS\Extensionmanager\Utility\ListUtility
41 */
42 protected $listUtility;
43
44 /**
45 * @var \TYPO3\CMS\Core\Page\PageRenderer
46 */
47 protected $pageRenderer;
48
49 /**
50 * @var \TYPO3\CMS\Extensionmanager\Utility\DependencyUtility
51 */
52 protected $dependencyUtility;
53
54 /**
55 * @var \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility
56 */
57 protected $configurationUtility;
58
59 /**
60 * @param \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository $extensionRepository
61 */
62 public function injectExtensionRepository(\TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository $extensionRepository)
63 {
64 $this->extensionRepository = $extensionRepository;
65 }
66
67 /**
68 * @param \TYPO3\CMS\Extensionmanager\Utility\ListUtility $listUtility
69 */
70 public function injectListUtility(\TYPO3\CMS\Extensionmanager\Utility\ListUtility $listUtility)
71 {
72 $this->listUtility = $listUtility;
73 }
74
75 /**
76 * @param \TYPO3\CMS\Core\Page\PageRenderer $pageRenderer
77 */
78 public function injectPageRenderer(\TYPO3\CMS\Core\Page\PageRenderer $pageRenderer)
79 {
80 $this->pageRenderer = $pageRenderer;
81 }
82
83 /**
84 * @param \TYPO3\CMS\Extensionmanager\Utility\DependencyUtility $dependencyUtility
85 */
86 public function injectDependencyUtility(\TYPO3\CMS\Extensionmanager\Utility\DependencyUtility $dependencyUtility)
87 {
88 $this->dependencyUtility = $dependencyUtility;
89 }
90
91 /**
92 * @param \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility $configurationUtility
93 */
94 public function injectConfigurationUtility(\TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility $configurationUtility)
95 {
96 $this->configurationUtility = $configurationUtility;
97 }
98
99 /**
100 * Add the needed JavaScript files for all actions
101 */
102 public function initializeAction()
103 {
104 $this->pageRenderer->addInlineLanguageLabelFile('EXT:extensionmanager/Resources/Private/Language/locallang.xlf');
105 if ($this->configurationUtility->getCurrentConfiguration('extensionmanager')['offlineMode']['value']) {
106 $this->settings['offlineMode'] = true;
107 }
108 }
109
110 /**
111 * Set up the doc header properly here
112 *
113 * @param ViewInterface $view
114 * @return void
115 */
116 protected function initializeView(ViewInterface $view)
117 {
118 if ($view instanceof BackendTemplateView) {
119 /** @var BackendTemplateView $view */
120 parent::initializeView($view);
121 $this->generateMenu();
122 $this->registerDocheaderButtons();
123 }
124 }
125
126 /**
127 * Adds an information about composer mode
128 */
129 protected function addComposerModeNotification()
130 {
131 if (Bootstrap::usesComposerClassLoading()) {
132 $this->addFlashMessage(
133 LocalizationUtility::translate(
134 'composerMode.message',
135 'extensionmanager'
136 ),
137 LocalizationUtility::translate(
138 'composerMode.title',
139 'extensionmanager'
140 ),
141 FlashMessage::INFO
142 );
143 }
144 }
145
146 /**
147 * Shows list of extensions present in the system
148 *
149 * @return void
150 */
151 public function indexAction()
152 {
153 $this->addComposerModeNotification();
154 $availableAndInstalledExtensions = $this->listUtility->getAvailableAndInstalledExtensionsWithAdditionalInformation();
155 ksort($availableAndInstalledExtensions);
156 $this->view->assign('extensions', $availableAndInstalledExtensions);
157 $this->handleTriggerArguments();
158 }
159
160 /**
161 * Shows a list of unresolved dependency errors with the possibility to bypass the dependency check
162 *
163 * @param string $extensionKey
164 * @throws ExtensionManagerException
165 * @return void
166 */
167 public function unresolvedDependenciesAction($extensionKey)
168 {
169 $availableExtensions = $this->listUtility->getAvailableExtensions();
170 if (isset($availableExtensions[$extensionKey])) {
171 $extensionArray = $this->listUtility->enrichExtensionsWithEmConfAndTerInformation(
172 [
173 $extensionKey => $availableExtensions[$extensionKey]
174 ]
175 );
176 /** @var ExtensionModelUtility $extensionModelUtility */
177 $extensionModelUtility = $this->objectManager->get(ExtensionModelUtility::class);
178 $extension = $extensionModelUtility->mapExtensionArrayToModel($extensionArray[$extensionKey]);
179 } else {
180 throw new ExtensionManagerException('Extension ' . $extensionKey . ' is not available', 1402421007);
181 }
182 $this->dependencyUtility->checkDependencies($extension);
183 $this->view->assign('extension', $extension);
184 $this->view->assign('unresolvedDependencies', $this->dependencyUtility->getDependencyErrors());
185 }
186
187 /**
188 * Shows extensions from TER
189 * Either all extensions or depending on a search param
190 *
191 * @param string $search
192 * @return void
193 */
194 public function terAction($search = '')
195 {
196 $this->addComposerModeNotification();
197 $search = trim($search);
198 if (!empty($search)) {
199 $extensions = $this->extensionRepository->findByTitleOrAuthorNameOrExtensionKey($search);
200 } else {
201 $extensions = $this->extensionRepository->findAll();
202 }
203 $availableAndInstalledExtensions = $this->listUtility->getAvailableAndInstalledExtensions($this->listUtility->getAvailableExtensions());
204 $this->view->assign('extensions', $extensions)
205 ->assign('search', $search)
206 ->assign('availableAndInstalled', $availableAndInstalledExtensions);
207 }
208
209 /**
210 * Action for listing all possible distributions
211 *
212 * @param bool $showUnsuitableDistributions
213 * @return void
214 */
215 public function distributionsAction($showUnsuitableDistributions = false)
216 {
217 $this->addComposerModeNotification();
218 $importExportInstalled = ExtensionManagementUtility::isLoaded('impexp');
219 if ($importExportInstalled) {
220 try {
221 /** @var $repositoryHelper Helper */
222 $repositoryHelper = $this->objectManager->get(Helper::class);
223 // Check if a TER update has been done at all, if not, fetch it directly
224 // Repository needs an update, but not because of the extension hash has changed
225 $isExtListUpdateNecessary = $repositoryHelper->isExtListUpdateNecessary();
226 if ($isExtListUpdateNecessary > 0 && ($isExtListUpdateNecessary & $repositoryHelper::PROBLEM_EXTENSION_HASH_CHANGED) === 0) {
227 $repositoryHelper->updateExtList();
228 }
229 } catch (ExtensionManagerException $e) {
230 $this->addFlashMessage($e->getMessage(), $e->getCode(), FlashMessage::ERROR);
231 }
232
233 $officialDistributions = $this->extensionRepository->findAllOfficialDistributions();
234 $communityDistributions = $this->extensionRepository->findAllCommunityDistributions();
235
236 if (!$showUnsuitableDistributions) {
237 $suitableOfficialDistributions = $this->dependencyUtility->getExtensionsSuitableForTypo3Version($officialDistributions);
238 $this->view->assign('officialDistributions', $suitableOfficialDistributions);
239 $suitableCommunityDistributions = $this->dependencyUtility->getExtensionsSuitableForTypo3Version($communityDistributions);
240 $this->view->assign('communityDistributions', $suitableCommunityDistributions);
241 } else {
242 $this->view->assign('officialDistributions', $officialDistributions);
243 $this->view->assign('communityDistributions', $communityDistributions);
244 }
245 }
246 $this->view->assign('enableDistributionsView', $importExportInstalled);
247 $this->view->assign('showUnsuitableDistributions', $showUnsuitableDistributions);
248 }
249
250 /**
251 * Shows all versions of a specific extension
252 *
253 * @param string $extensionKey
254 * @return void
255 */
256 public function showAllVersionsAction($extensionKey)
257 {
258 $currentVersion = $this->extensionRepository->findOneByCurrentVersionByExtensionKey($extensionKey);
259 $extensions = $this->extensionRepository->findByExtensionKeyOrderedByVersion($extensionKey);
260
261 $this->view->assignMultiple(
262 [
263 'extensionKey' => $extensionKey,
264 'currentVersion' => $currentVersion,
265 'extensions' => $extensions
266 ]
267 );
268 }
269
270 /**
271 * Registers the Icons into the docheader
272 *
273 * @throws \InvalidArgumentException
274 */
275 protected function registerDocheaderButtons()
276 {
277 if (Bootstrap::usesComposerClassLoading()) {
278 return;
279 }
280
281 if (!in_array($this->actionMethodName, ['indexAction', 'terAction', 'showAllVersionsAction'], true)) {
282 return;
283 }
284
285 /** @var ButtonBar $buttonBar */
286 $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
287 $uriBuilder = $this->controllerContext->getUriBuilder();
288
289 if ($this->actionMethodName === 'showAllVersionsAction') {
290 $uri = $uriBuilder->reset()->uriFor('ter', [], 'List');
291 $title = $this->translate('extConfTemplate.backToList');
292 $icon = $this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL);
293 $classes = '';
294 } else {
295 $uri = $uriBuilder->reset()->uriFor('form', [], 'UploadExtensionFile');
296 $title = $this->translate('extensionList.uploadExtension');
297 $icon = $this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-edit-upload', Icon::SIZE_SMALL);
298 $classes = 't3js-upload';
299 }
300 $button = $buttonBar->makeLinkButton()
301 ->setHref($uri)
302 ->setTitle($title)
303 ->setClasses($classes)
304 ->setIcon($icon);
305 $buttonBar->addButton($button, ButtonBar::BUTTON_POSITION_LEFT);
306 }
307 }