[TASK] Fix CGL errors
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Updates / AbstractDownloadExtensionUpdate.php
1 <?php
2 namespace TYPO3\CMS\Install\Updates;
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\Utility\GeneralUtility;
18 use TYPO3\CMS\Extbase\Object\ObjectManager;
19 use TYPO3\CMS\Extensionmanager\Utility\Connection\TerUtility;
20 use TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility;
21 use TYPO3\CMS\Extensionmanager\Utility\InstallUtility;
22 use TYPO3\CMS\Extensionmanager\Utility\ListUtility;
23
24 /**
25 * Download extension from TER
26 */
27 abstract class AbstractDownloadExtensionUpdate extends AbstractUpdate
28 {
29 /**
30 * @var string
31 */
32 protected $title = 'Install an Extension from the Extension Repository';
33
34 /**
35 * See subclasses for more information
36 * @var array
37 */
38 protected $extensionDetails = [];
39
40 /**
41 * @var string
42 */
43 protected $repositoryUrl = 'https://typo3.org/fileadmin/ter/@filename';
44
45 /**
46 * This method can be called to install an extension following all proper processes
47 * (e.g. installing in extList, respecting priority, etc.)
48 *
49 * @param string $extensionKey
50 * @param mixed $customMessages
51 * @return bool whether the installation worked or not
52 */
53 protected function installExtension($extensionKey, &$customMessages)
54 {
55 $updateSuccessful = true;
56 /** @var $objectManager ObjectManager */
57 $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
58
59 /** @var $extensionListUtility ListUtility */
60 $extensionListUtility = $objectManager->get(ListUtility::class);
61
62 $availableExtensions = $extensionListUtility->getAvailableExtensions();
63 $availableAndInstalledExtensions = $extensionListUtility->getAvailableAndInstalledExtensions($availableExtensions);
64
65 // Extension is not downloaded yet.
66 if (!is_array($availableAndInstalledExtensions[$extensionKey])) {
67 /** @var $extensionTerUtility TerUtility */
68 $extensionTerUtility = $objectManager->get(TerUtility::class);
69 $extensionDetails = $this->getExtensionDetails($extensionKey);
70 if (empty($extensionDetails)) {
71 $updateSuccessful = false;
72 $customMessages .= 'No version information for extension ' . $extensionKey . ' found. Can not install the extension.';
73 }
74 $t3xContent = $this->fetchExtension($extensionKey, $extensionDetails['versionString']);
75 if (empty($t3xContent)) {
76 $updateSuccessful = false;
77 $customMessages .= 'The extension ' . $extensionKey . ' could not be downloaded.';
78 }
79 $t3xExtracted = $extensionTerUtility->decodeExchangeData($t3xContent);
80 if (empty($t3xExtracted) || !is_array($t3xExtracted) || empty($t3xExtracted['extKey'])) {
81 $updateSuccessful = false;
82 $customMessages .= 'The extension ' . $extensionKey . ' could not be extracted.';
83 }
84
85 /** @var $extensionFileHandlingUtility FileHandlingUtility */
86 $extensionFileHandlingUtility = $objectManager->get(FileHandlingUtility::class);
87 $extensionFileHandlingUtility->unpackExtensionFromExtensionDataArray($t3xExtracted);
88
89 // The listUtility now needs to have the regenerated list of packages
90 $extensionListUtility->reloadAvailableExtensions();
91 }
92
93 if ($updateSuccessful !== false) {
94 /** @var $extensionInstallUtility InstallUtility */
95 $extensionInstallUtility = $objectManager->get(InstallUtility::class);
96 $extensionInstallUtility->install($extensionKey);
97 }
98 return $updateSuccessful;
99 }
100
101 /**
102 * Returns the details of a local or external extension
103 *
104 * @param string $extensionKey Key of the extension to check
105 *
106 * @return array Extension details
107 */
108 protected function getExtensionDetails($extensionKey)
109 {
110 if (array_key_exists($extensionKey, $this->extensionDetails)) {
111 return $this->extensionDetails[$extensionKey];
112 }
113
114 return [];
115 }
116
117 /**
118 * Fetch extension from repository
119 *
120 * @param string $extensionKey The extension key to fetch
121 * @param string $version The version to fetch
122 *
123 * @throws \InvalidArgumentException
124 * @return string T3X file content
125 */
126 protected function fetchExtension($extensionKey, $version)
127 {
128 if (empty($extensionKey) || empty($version)) {
129 throw new \InvalidArgumentException('No extension key for fetching an extension was given.',
130 1344687432);
131 }
132
133 $filename = $extensionKey[0] . '/' . $extensionKey[1] . '/' . $extensionKey . '_' . $version . '.t3x';
134 $url = str_replace('@filename', $filename, $this->repositoryUrl);
135
136 return $this->fetchUrl($url);
137 }
138
139 /**
140 * Open an URL and return the response
141 *
142 * This wrapper method is required to try several download methods if
143 * the configuration is not valid or initially written by the installer.
144 *
145 * @param string $url The URL to file
146 *
147 * @throws \Exception
148 * @throws \InvalidArgumentException
149 * @return string File content
150 */
151 protected function fetchUrl($url)
152 {
153 if (empty($url)) {
154 throw new \InvalidArgumentException('No URL for downloading an extension given.',
155 1344687436);
156 }
157
158 $fileContent = GeneralUtility::getUrl($url, 0, array(TYPO3_user_agent));
159
160 // Can not fetch url, throw an exception
161 if ($fileContent === false) {
162 throw new \RuntimeException('Can not fetch URL "' . $url . '". Possible reasons are network problems or misconfiguration.',
163 1344685036);
164 }
165
166 return $fileContent;
167 }
168 }