‪TYPO3CMS  11.5
UploadExtensionFileController.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use Psr\Http\Message\ResponseInterface;
29 
35 {
37 
40 
44  protected ‪$extensionBackupPath = '';
45 
49  protected ‪$removeFromOriginalPath = false;
50 
51  public function ‪__construct(
54  ) {
55  $this->fileHandlingUtility = ‪$fileHandlingUtility;
56  $this->managementService = ‪$managementService;
57  }
58 
62  public function ‪__destruct()
63  {
64  $this->‪removeBackupFolder();
65  }
66 
70  public function ‪formAction(): ResponseInterface
71  {
73  throw new ExtensionManagerException(
74  'Composer mode is active. You are not allowed to upload any extension file.',
75  1444725828
76  );
77  }
78 
79  return $this->‪htmlResponse();
80  }
81 
88  public function ‪extractAction($overwrite = false)
89  {
91  throw new ExtensionManagerException(
92  'Composer mode is active. You are not allowed to upload any extension file.',
93  1444725853
94  );
95  }
96  $file = $_FILES['tx_extensionmanager_tools_extensionmanagerextensionmanager'];
97  $fileName = pathinfo($file['name']['extensionFile'], PATHINFO_BASENAME);
98  try {
99  // If the file name isn't valid an error will be thrown
100  $this->‪checkFileName($fileName);
101  if (!empty($file['tmp_name']['extensionFile'])) {
102  $tempFile = GeneralUtility::upload_to_tempfile($file['tmp_name']['extensionFile']);
103  } else {
104  throw new ExtensionManagerException(
105  'Creating temporary file failed. Check your upload_max_filesize and post_max_size limits.',
106  1342864339
107  );
108  }
109  // Remove version and extension from filename to determine the extension key
110  $extensionKey = $this->‪getExtensionKeyFromFileName($fileName);
111  if (empty($extensionKey)) {
112  throw new ExtensionManagerException(
113  'Could not extract extension key from uploaded file name. File name must be something like "my_extension_4.2.2.zip".',
114  1603087515
115  );
116  }
117  $this->‪extractExtensionFromZipFile($tempFile, $extensionKey, (bool)$overwrite);
118  $isAutomaticInstallationEnabled = (bool)GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('extensionmanager', 'automaticInstallation');
119  if (!$isAutomaticInstallationEnabled) {
120  $this->‪addFlashMessage(
121  $this->‪translate('extensionList.uploadFlashMessage.message', [$extensionKey]),
122  $this->‪translate('extensionList.uploadFlashMessage.title'),
124  );
125  } else {
126  if ($this->‪activateExtension($extensionKey)) {
127  $this->‪addFlashMessage(
128  $this->‪translate('extensionList.installedFlashMessage.message', [$extensionKey]),
129  '',
131  );
132  } else {
133  // @deprecated since v11, change to return $this->redirect()
134  $this->‪redirect('unresolvedDependencies', 'List', null, ['extensionKey' => $extensionKey]);
135  }
136  }
137  } catch (StopActionException $exception) {
138  // @deprecated since v11, will be removed in v12: redirect() will no longer throw in v12, drop this catch block
139  throw $exception;
140  } catch (InvalidFileException $exception) {
141  $this->‪addFlashMessage($exception->getMessage(), '', ‪FlashMessage::ERROR);
142  } catch (\Exception $exception) {
143  $this->‪removeExtensionAndRestoreFromBackup($fileName);
144  $this->‪addFlashMessage($exception->getMessage(), '', ‪FlashMessage::ERROR);
145  }
146  // @deprecated since v11, change to return $this->redirect()
147  $this->‪redirect('index', 'List', null, [
148  self::TRIGGER_RefreshModuleMenu => true,
149  self::TRIGGER_RefreshTopbar => true,
150  ]);
151  }
152 
159  protected function ‪checkFileName($fileName)
160  {
161  if (empty($fileName)) {
162  throw new InvalidFileException('No file given.', 1342858852);
163  }
164  $fileExtension = pathinfo($fileName, PATHINFO_EXTENSION);
165  if ($fileExtension !== 'zip') {
166  throw new InvalidFileException('Wrong file format "' . $fileExtension . '" given. Only .zip files are allowed.', 1342858853);
167  }
168  }
169 
174  protected function ‪activateExtension($extensionKey)
175  {
176  $this->managementService->reloadPackageInformation($extensionKey);
177  $extension = $this->managementService->getExtension($extensionKey);
178  return is_array($this->managementService->installExtension($extension));
179  }
180 
190  protected function ‪extractExtensionFromZipFile(string $uploadedFile, string $extensionKey, bool $overwrite = false): string
191  {
192  $isExtensionAvailable = $this->managementService->isAvailable($extensionKey);
193  if (!$overwrite && $isExtensionAvailable) {
194  throw new ExtensionManagerException('Extension is already available and overwriting is disabled.', 1342864311);
195  }
196  if ($isExtensionAvailable) {
197  $this->‪copyExtensionFolderToTempFolder($extensionKey);
198  }
199  $this->removeFromOriginalPath = true;
200  $this->fileHandlingUtility->unzipExtensionFromFile($uploadedFile, $extensionKey);
201  return $extensionKey;
202  }
203 
214  protected function ‪getExtensionKeyFromFileName($fileName)
215  {
216  return (string)preg_replace('/_(\\d+)(\\.|\\-)(\\d+)(\\.|\\-)(\\d+).*/i', '', strtolower(substr($fileName, 0, -4)));
217  }
218 
225  protected function ‪copyExtensionFolderToTempFolder($extensionKey)
226  {
227  $this->extensionBackupPath = ‪Environment::getVarPath() . '/transient/' . $extensionKey . substr(sha1($extensionKey . microtime()), 0, 7) . '/';
228  ‪GeneralUtility::mkdir($this->extensionBackupPath);
229  GeneralUtility::copyDirectory(
230  $this->fileHandlingUtility->getExtensionDir($extensionKey),
231  $this->extensionBackupPath
232  );
233  }
234 
241  protected function ‪removeExtensionAndRestoreFromBackup($fileName)
242  {
243  $extDirPath = $this->fileHandlingUtility->getExtensionDir($this->‪getExtensionKeyFromFileName($fileName));
244  if ($this->removeFromOriginalPath && is_dir($extDirPath)) {
245  ‪GeneralUtility::rmdir($extDirPath, true);
246  }
247  if (!empty($this->extensionBackupPath)) {
248  ‪GeneralUtility::mkdir($extDirPath);
249  GeneralUtility::copyDirectory($this->extensionBackupPath, $extDirPath);
250  }
251  }
252 
256  protected function ‪removeBackupFolder()
257  {
258  if (!empty($this->extensionBackupPath)) {
259  ‪GeneralUtility::rmdir($this->extensionBackupPath, true);
260  $this->extensionBackupPath = '';
261  }
262  }
263 }
‪TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
Definition: StopActionException.php:37
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\formAction
‪formAction()
Definition: UploadExtensionFileController.php:67
‪TYPO3\CMS\Extensionmanager\Controller\AbstractController\translate
‪string translate($key, $arguments=null)
Definition: AbstractController.php:44
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\htmlResponse
‪ResponseInterface htmlResponse(string $html=null)
Definition: ActionController.php:1067
‪TYPO3\CMS\Core\Package\Exception
Definition: Exception.php:21
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController
Definition: UploadExtensionFileController.php:35
‪TYPO3\CMS\Core\Configuration\ExtensionConfiguration
Definition: ExtensionConfiguration.php:45
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\__destruct
‪__destruct()
Definition: UploadExtensionFileController.php:59
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\copyExtensionFolderToTempFolder
‪copyExtensionFolderToTempFolder($extensionKey)
Definition: UploadExtensionFileController.php:222
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\__construct
‪__construct(FileHandlingUtility $fileHandlingUtility, ExtensionManagementService $managementService)
Definition: UploadExtensionFileController.php:48
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\removeExtensionAndRestoreFromBackup
‪removeExtensionAndRestoreFromBackup($fileName)
Definition: UploadExtensionFileController.php:238
‪TYPO3\CMS\Extensionmanager\Controller
Definition: AbstractController.php:16
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\addFlashMessage
‪addFlashMessage($messageBody, $messageTitle='', $severity=AbstractMessage::OK, $storeInSession=true)
Definition: ActionController.php:828
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\extractAction
‪extractAction($overwrite=false)
Definition: UploadExtensionFileController.php:85
‪TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility
Definition: FileHandlingUtility.php:36
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\$managementService
‪ExtensionManagementService $managementService
Definition: UploadExtensionFileController.php:38
‪TYPO3\CMS\Extensionmanager\Exception\InvalidFileException
Definition: InvalidFileException.php:23
‪TYPO3\CMS\Core\Security\BlockSerializationTrait
Definition: BlockSerializationTrait.php:28
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\getExtensionKeyFromFileName
‪string getExtensionKeyFromFileName($fileName)
Definition: UploadExtensionFileController.php:211
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\extractExtensionFromZipFile
‪string extractExtensionFromZipFile(string $uploadedFile, string $extensionKey, bool $overwrite=false)
Definition: UploadExtensionFileController.php:187
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\activateExtension
‪bool activateExtension($extensionKey)
Definition: UploadExtensionFileController.php:171
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\$removeFromOriginalPath
‪bool $removeFromOriginalPath
Definition: UploadExtensionFileController.php:46
‪TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
Definition: ExtensionManagerException.php:23
‪TYPO3\CMS\Extensionmanager\Controller\AbstractController
Definition: AbstractController.php:26
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\$extensionBackupPath
‪string $extensionBackupPath
Definition: UploadExtensionFileController.php:42
‪TYPO3\CMS\Core\Messaging\AbstractMessage\OK
‪const OK
Definition: AbstractMessage.php:29
‪TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService
Definition: ExtensionManagementService.php:36
‪TYPO3\CMS\Core\Core\Environment\isComposerMode
‪static bool isComposerMode()
Definition: Environment.php:152
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:26
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\removeBackupFolder
‪removeBackupFolder()
Definition: UploadExtensionFileController.php:253
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:43
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\checkFileName
‪checkFileName($fileName)
Definition: UploadExtensionFileController.php:156
‪TYPO3\CMS\Core\Utility\GeneralUtility\rmdir
‪static bool rmdir($path, $removeNonEmpty=false)
Definition: GeneralUtility.php:1961
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\redirect
‪never redirect($actionName, $controllerName=null, $extensionName=null, array $arguments=null, $pageUid=null, $_=null, $statusCode=303)
Definition: ActionController.php:940
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Utility\GeneralUtility\mkdir
‪static bool mkdir($newFolder)
Definition: GeneralUtility.php:1891
‪TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController\$fileHandlingUtility
‪FileHandlingUtility $fileHandlingUtility
Definition: UploadExtensionFileController.php:37
‪TYPO3\CMS\Core\Messaging\AbstractMessage\ERROR
‪const ERROR
Definition: AbstractMessage.php:31
‪TYPO3\CMS\Core\Core\Environment\getVarPath
‪static string getVarPath()
Definition: Environment.php:218