[TASK] EM: Update extension to latest possible
[Packages/TYPO3.CMS.git] / typo3 / sysext / extensionmanager / Classes / Controller / DownloadController.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\Core\Messaging\FlashMessage;
18 use TYPO3\CMS\Extensionmanager\Domain\Model\Extension;
19
20 /**
21 * Controller for actions related to the TER download of an extension
22 *
23 * @author Susanne Moog, <typo3@susannemoog.de>
24 */
25 class DownloadController extends AbstractController {
26
27 /**
28 * @var \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository
29 * @inject
30 */
31 protected $extensionRepository;
32
33 /**
34 * @var \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility
35 * @inject
36 */
37 protected $fileHandlingUtility;
38
39 /**
40 * @var \TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService
41 * @inject
42 */
43 protected $managementService;
44
45 /**
46 * @var \TYPO3\CMS\Extensionmanager\Utility\InstallUtility
47 * @inject
48 */
49 protected $installUtility;
50
51 /**
52 * @var \TYPO3\CMS\Extensionmanager\Utility\DownloadUtility
53 * @inject
54 */
55 protected $downloadUtility;
56
57 /**
58 * @var \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility
59 * @inject
60 */
61 protected $configurationUtility;
62
63 /**
64 * Check extension dependencies
65 *
66 * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension
67 * @throws \Exception
68 */
69 public function checkDependenciesAction(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension) {
70 $message = '';
71 $title = '';
72 $hasDependencies = FALSE;
73 $hasErrors = FALSE;
74 try {
75 $dependencyTypes = $this->managementService->getAndResolveDependencies($extension);
76 if (count($dependencyTypes) > 0) {
77 $hasDependencies = TRUE;
78 $message = '<p>' . $this->translate('downloadExtension.dependencies.headline') . '</p>';
79 foreach ($dependencyTypes as $dependencyType => $dependencies) {
80 $extensions = '';
81 foreach ($dependencies as $extensionKey => $dependency) {
82 $extensions .= htmlspecialchars($extensionKey) . '<br />';
83 }
84 $message .= $this->translate('downloadExtension.dependencies.typeHeadline',
85 array(
86 $this->translate('downloadExtension.dependencyType.' . $dependencyType),
87 $extensions
88 )
89 );
90 }
91 $title = $this->translate('downloadExtension.dependencies.resolveAutomatically');
92 }
93 $this->view->assign('dependencies', $dependencyTypes);
94 } catch (\Exception $e) {
95 $hasErrors = TRUE;
96 $title = $this->translate('downloadExtension.dependencies.errorTitle');
97 $message = $e->getMessage();
98 }
99 $this->view->assign('extension', $extension)
100 ->assign('hasDependencies', $hasDependencies)
101 ->assign('hasErrors', $hasErrors)
102 ->assign('message', $message)
103 ->assign('title', $title);
104 }
105
106 /**
107 * Install an extension from TER action
108 *
109 * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension
110 * @param string $downloadPath
111 */
112 public function installFromTerAction(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension, $downloadPath) {
113 list($result, $errorMessages) = $this->installFromTer($extension, $downloadPath);
114 $emConfiguration = $this->configurationUtility->getCurrentConfiguration('extensionmanager');
115 $this->view
116 ->assign('result', $result)
117 ->assign('extension', $extension)
118 ->assign('installationTypeLanguageKey', (bool)$emConfiguration['automaticInstallation']['value'] ? '' : '.downloadOnly')
119 ->assign('unresolvedDependencies', $errorMessages);
120 }
121
122 /**
123 * Check extension dependencies with special dependencies
124 *
125 * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension
126 * @throws \Exception
127 */
128 public function installExtensionWithoutSystemDependencyCheckAction(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension) {
129 $this->managementService->setSkipSystemDependencyCheck(TRUE);
130 $this->forward('installFromTer', NULL, NULL, array('extension' => $extension, 'downloadPath' => 'Local'));
131 }
132
133 /**
134 * Action for installing a distribution -
135 * redirects directly to configuration after installing
136 *
137 * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension
138 * @return void
139 */
140 public function installDistributionAction(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension) {
141 if (!\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('impexp')) {
142 $this->forward('distributions', 'List');
143 }
144 list($result, $errorMessages) = $this->installFromTer($extension);
145 if ($errorMessages) {
146 foreach ($errorMessages as $extensionKey => $messages) {
147 foreach ($messages as $message) {
148 $this->addFlashMessage(
149 $message['message'],
150 \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate(
151 'distribution.error.headline',
152 'extensionmanager',
153 array($extensionKey)
154 ),
155 \TYPO3\CMS\Core\Messaging\AbstractMessage::ERROR
156 );
157 }
158 }
159
160 // Redirect back to distributions list action
161 $this->redirect(
162 'distributions',
163 'List'
164 );
165 } else {
166 // FlashMessage that extension is installed
167 $this->addFlashMessage(
168 \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('distribution.welcome.message', 'extensionmanager')
169 . ' <strong>' . $extension->getExtensionKey() . '</strong>',
170 \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('distribution.welcome.headline', 'extensionmanager')
171 );
172
173 // Redirect to show action
174 $this->redirect(
175 'show',
176 'Distribution',
177 NULL,
178 array('extension' => $extension)
179 );
180 }
181 }
182
183 /**
184 * Update an extension. Makes no sanity check but directly searches highest
185 * available version from TER and updates. Update check is done by the list
186 * already. This method should only be called if we are sure that there is
187 * an update.
188 *
189 * @return string
190 */
191 protected function updateExtensionAction() {
192 $extensionKey = $this->request->getArgument('extension');
193 $version = $this->request->getArgument('version');
194 $extension = $this->extensionRepository->findOneByExtensionKeyAndVersion($extensionKey, $version);
195 if (!$extension instanceof Extension) {
196 $extension = $this->extensionRepository->findHighestAvailableVersion($extensionKey);
197 }
198 try {
199 $this->managementService->downloadMainExtension($extension);
200 $this->addFlashMessage(
201 htmlspecialchars($this->translate('extensionList.updateFlashMessage.body', array($extensionKey))),
202 $this->translate('extensionList.updateFlashMessage.title')
203 );
204 } catch (\Exception $e) {
205 $this->addFlashMessage(htmlspecialchars($e->getMessage()), '', FlashMessage::ERROR);
206 }
207
208 return '';
209 }
210
211 /**
212 * Show update comments for extensions that can be updated.
213 * Fetches update comments for all versions between the current
214 * installed and the highest version.
215 *
216 * @return void
217 */
218 protected function updateCommentForUpdatableVersionsAction() {
219 $extensionKey = $this->request->getArgument('extension');
220 $versionStart = $this->request->getArgument('integerVersionStart');
221 $versionStop = $this->request->getArgument('integerVersionStop');
222 $updateComments = array();
223 /** @var Extension[] $updatableVersions */
224 $updatableVersions = $this->extensionRepository->findByVersionRangeAndExtensionKeyOrderedByVersion(
225 $extensionKey,
226 $versionStart,
227 $versionStop
228 );
229 $highestPossibleVersion = FALSE;
230
231 foreach ($updatableVersions as $updatableVersion) {
232 if ($highestPossibleVersion === FALSE) {
233 $highestPossibleVersion = $updatableVersion->getVersion();
234 }
235 $updateComments[$updatableVersion->getVersion()] = $updatableVersion->getUpdateComment();
236 }
237 $this->view->assign('updateComments', $updateComments)
238 ->assign('extensionKey', $extensionKey)
239 ->assign('version', $highestPossibleVersion);
240 }
241
242 /**
243 * Install an action from TER
244 * Downloads the extension, resolves dependencies and installs it
245 *
246 * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension
247 * @param string $downloadPath
248 * @return array
249 */
250 protected function installFromTer(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension, $downloadPath = 'Local') {
251 $result = FALSE;
252 $errorMessages = array();
253 try {
254 $this->downloadUtility->setDownloadPath($downloadPath);
255 $this->managementService->setAutomaticInstallationEnabled($this->configurationUtility->getCurrentConfiguration('extensionmanager')['automaticInstallation']['value']);
256 if (($result = $this->managementService->installExtension($extension)) === FALSE) {
257 $errorMessages = $this->managementService->getDependencyErrors();
258 }
259 } catch (\TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException $e) {
260 $errorMessages = array(
261 $extension->getExtensionKey() => array(
262 array(
263 'code' => $e->getCode(),
264 'message' => $e->getMessage(),
265 )
266 ),
267 );
268 }
269
270 return array($result, $errorMessages);
271 }
272
273 }