2 namespace TYPO3\CMS\Extensionmanager\Controller
;
5 * This file is part of the TYPO3 CMS project.
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.
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
14 * The TYPO3 project - inspiring people to share!
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
;
30 * Controller for extension listings (TER or local extensions)
32 class ListController
extends AbstractModuleController
35 * @var \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository
37 protected $extensionRepository;
40 * @var \TYPO3\CMS\Extensionmanager\Utility\ListUtility
42 protected $listUtility;
45 * @var \TYPO3\CMS\Core\Page\PageRenderer
47 protected $pageRenderer;
50 * @var \TYPO3\CMS\Extensionmanager\Utility\DependencyUtility
52 protected $dependencyUtility;
55 * @var \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility
57 protected $configurationUtility;
60 * @param \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository $extensionRepository
62 public function injectExtensionRepository(\TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository
$extensionRepository)
64 $this->extensionRepository
= $extensionRepository;
68 * @param \TYPO3\CMS\Extensionmanager\Utility\ListUtility $listUtility
70 public function injectListUtility(\TYPO3\CMS\Extensionmanager\Utility\ListUtility
$listUtility)
72 $this->listUtility
= $listUtility;
76 * @param \TYPO3\CMS\Core\Page\PageRenderer $pageRenderer
78 public function injectPageRenderer(\TYPO3\CMS\Core\Page\PageRenderer
$pageRenderer)
80 $this->pageRenderer
= $pageRenderer;
84 * @param \TYPO3\CMS\Extensionmanager\Utility\DependencyUtility $dependencyUtility
86 public function injectDependencyUtility(\TYPO3\CMS\Extensionmanager\Utility\DependencyUtility
$dependencyUtility)
88 $this->dependencyUtility
= $dependencyUtility;
92 * @param \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility $configurationUtility
94 public function injectConfigurationUtility(\TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility
$configurationUtility)
96 $this->configurationUtility
= $configurationUtility;
100 * Add the needed JavaScript files for all actions
102 public function initializeAction()
104 $this->pageRenderer
->addInlineLanguageLabelFile('EXT:extensionmanager/Resources/Private/Language/locallang.xlf');
105 if ($this->configurationUtility
->getCurrentConfiguration('extensionmanager')['offlineMode']['value']) {
106 $this->settings
['offlineMode'] = true;
111 * Set up the doc header properly here
113 * @param ViewInterface $view
116 protected function initializeView(ViewInterface
$view)
118 if ($view instanceof BackendTemplateView
) {
119 /** @var BackendTemplateView $view */
120 parent
::initializeView($view);
121 $this->generateMenu();
122 $this->registerDocheaderButtons();
127 * Adds an information about composer mode
129 protected function addComposerModeNotification()
131 if (Bootstrap
::usesComposerClassLoading()) {
132 $this->addFlashMessage(
133 LocalizationUtility
::translate(
134 'composerMode.message',
137 LocalizationUtility
::translate(
138 'composerMode.title',
141 FlashMessage
::WARNING
147 * Shows list of extensions present in the system
151 public function indexAction()
153 $this->addComposerModeNotification();
154 $availableAndInstalledExtensions = $this->listUtility
->getAvailableAndInstalledExtensionsWithAdditionalInformation();
155 ksort($availableAndInstalledExtensions);
156 $this->view
->assign('extensions', $availableAndInstalledExtensions);
157 $this->handleTriggerArguments();
161 * Shows a list of unresolved dependency errors with the possibility to bypass the dependency check
163 * @param string $extensionKey
164 * @throws ExtensionManagerException
167 public function unresolvedDependenciesAction($extensionKey)
169 $availableExtensions = $this->listUtility
->getAvailableExtensions();
170 if (isset($availableExtensions[$extensionKey])) {
171 $extensionArray = $this->listUtility
->enrichExtensionsWithEmConfAndTerInformation(
173 $extensionKey => $availableExtensions[$extensionKey]
176 /** @var ExtensionModelUtility $extensionModelUtility */
177 $extensionModelUtility = $this->objectManager
->get(ExtensionModelUtility
::class);
178 $extension = $extensionModelUtility->mapExtensionArrayToModel($extensionArray[$extensionKey]);
180 throw new ExtensionManagerException('Extension ' . $extensionKey . ' is not available', 1402421007);
182 $this->dependencyUtility
->checkDependencies($extension);
183 $this->view
->assign('extension', $extension);
184 $this->view
->assign('unresolvedDependencies', $this->dependencyUtility
->getDependencyErrors());
188 * Shows extensions from TER
189 * Either all extensions or depending on a search param
191 * @param string $search
194 public function terAction($search = '')
196 $this->addComposerModeNotification();
197 $search = trim($search);
198 if (!empty($search)) {
199 $extensions = $this->extensionRepository
->findByTitleOrAuthorNameOrExtensionKey($search);
201 $extensions = $this->extensionRepository
->findAll();
203 $availableAndInstalledExtensions = $this->listUtility
->getAvailableAndInstalledExtensions($this->listUtility
->getAvailableExtensions());
204 $this->view
->assign('extensions', $extensions)
205 ->assign('search', $search)
206 ->assign('availableAndInstalled', $availableAndInstalledExtensions);
210 * Action for listing all possible distributions
212 * @param bool $showUnsuitableDistributions
215 public function distributionsAction($showUnsuitableDistributions = false)
217 $this->addComposerModeNotification();
218 $importExportInstalled = ExtensionManagementUtility
::isLoaded('impexp');
219 if ($importExportInstalled) {
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();
229 } catch (ExtensionManagerException
$e) {
230 $this->addFlashMessage($e->getMessage(), $e->getCode(), FlashMessage
::ERROR
);
233 $officialDistributions = $this->extensionRepository
->findAllOfficialDistributions();
234 $communityDistributions = $this->extensionRepository
->findAllCommunityDistributions();
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);
242 $this->view
->assign('officialDistributions', $officialDistributions);
243 $this->view
->assign('communityDistributions', $communityDistributions);
246 $this->view
->assign('enableDistributionsView', $importExportInstalled);
247 $this->view
->assign('showUnsuitableDistributions', $showUnsuitableDistributions);
251 * Shows all versions of a specific extension
253 * @param string $extensionKey
256 public function showAllVersionsAction($extensionKey)
258 $currentVersion = $this->extensionRepository
->findOneByCurrentVersionByExtensionKey($extensionKey);
259 $extensions = $this->extensionRepository
->findByExtensionKeyOrderedByVersion($extensionKey);
261 $this->view
->assignMultiple(
263 'extensionKey' => $extensionKey,
264 'currentVersion' => $currentVersion,
265 'extensions' => $extensions
271 * Registers the Icons into the docheader
273 * @throws \InvalidArgumentException
275 protected function registerDocheaderButtons()
277 if (Bootstrap
::usesComposerClassLoading()) {
281 if (!in_array($this->actionMethodName
, ['indexAction', 'terAction', 'showAllVersionsAction'], true)) {
285 /** @var ButtonBar $buttonBar */
286 $buttonBar = $this->view
->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
287 $uriBuilder = $this->controllerContext
->getUriBuilder();
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
);
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';
300 $button = $buttonBar->makeLinkButton()
303 ->setClasses($classes)
305 $buttonBar->addButton($button, ButtonBar
::BUTTON_POSITION_LEFT
);