[TASK] Use @inject annotation in extensionmanager
[Packages/TYPO3.CMS.git] / typo3 / sysext / extensionmanager / Classes / Utility / InstallUtility.php
1 <?php
2 namespace TYPO3\CMS\Extensionmanager\Utility;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2012-2013 Susanne Moog <susanne.moog@typo3.org>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29 /**
30 * Extension Manager Install Utility
31 *
32 * @author Susanne Moog <susanne.moog@typo3.org>
33 */
34 class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
35
36 /**
37 * @var \TYPO3\CMS\Extbase\Object\ObjectManager
38 * @inject
39 */
40 public $objectManager;
41
42 /**
43 * @var \TYPO3\CMS\Install\Service\SqlSchemaMigrationService
44 * @inject
45 */
46 public $installToolSqlParser;
47
48 /**
49 * @var \TYPO3\CMS\Extensionmanager\Utility\DependencyUtility
50 * @inject
51 */
52 protected $dependencyUtility;
53
54 /**
55 * @var \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility
56 * @inject
57 */
58 protected $fileHandlingUtility;
59
60 /**
61 * @var \TYPO3\CMS\Extensionmanager\Utility\ListUtility
62 * @inject
63 */
64 protected $listUtility;
65
66 /**
67 * @var \TYPO3\CMS\Extensionmanager\Utility\DatabaseUtility
68 * @inject
69 */
70 protected $databaseUtility;
71
72 /**
73 * @var \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository
74 * @inject
75 */
76 public $extensionRepository;
77
78 /**
79 * __construct
80 */
81 public function __construct() {
82 $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
83 /** @var $installToolSqlParser \TYPO3\CMS\Install\Service\SqlSchemaMigrationService */
84 $this->installToolSqlParser = $this->objectManager->get('TYPO3\\CMS\\Install\\Service\\SqlSchemaMigrationService');
85 $this->dependencyUtility = $this->objectManager->get('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility');
86 }
87
88 /**
89 * Helper function to install an extension
90 * also processes db updates and clears the cache if the extension asks for it
91 *
92 * @param string $extensionKey
93 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
94 * @return void
95 */
96 public function install($extensionKey) {
97 $extension = $this->enrichExtensionWithDetails($extensionKey);
98 $this->processDatabaseUpdates($extension);
99 $this->ensureConfiguredDirectoriesExist($extension);
100 if ($extension['clearcacheonload']) {
101 $GLOBALS['typo3CacheManager']->flushCaches();
102 }
103 if (!$this->isLoaded($extensionKey)) {
104 $this->loadExtension($extensionKey);
105 }
106 $this->reloadCaches();
107 $this->processCachingFrameworkUpdates();
108 $this->saveDefaultConfiguration($extension['key']);
109 }
110
111 /**
112 * Helper function to uninstall an extension
113 *
114 * @param string $extensionKey
115 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
116 * @return void
117 */
118 public function uninstall($extensionKey) {
119 $dependentExtensions = $this->dependencyUtility->findInstalledExtensionsThatDependOnMe($extensionKey);
120 if (is_array($dependentExtensions) && count($dependentExtensions) > 0) {
121 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(
122 \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate(
123 'extensionList.uninstall.dependencyError',
124 'extensionmanager',
125 array($extensionKey, implode(',', $dependentExtensions))
126 ),
127 1342554622
128 );
129 } else {
130 $this->unloadExtension($extensionKey);
131 }
132 }
133
134 /**
135 * Wrapper function to check for loaded extensions
136 *
137 * @param string $extensionKey
138 * @return boolean TRUE if extension is loaded
139 */
140 public function isLoaded($extensionKey) {
141 return \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($extensionKey);
142 }
143
144 /**
145 * Wrapper function for loading extensions
146 *
147 * @param string $extensionKey
148 * @return void
149 */
150 protected function loadExtension($extensionKey) {
151 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::loadExtension($extensionKey);
152 }
153
154 /**
155 * Wrapper function for unloading extensions
156 *
157 * @param string $extensionKey
158 * @return void
159 */
160 protected function unloadExtension($extensionKey) {
161 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::unloadExtension($extensionKey);
162 }
163
164 /**
165 * Checks if an extension is available in the system
166 *
167 * @param $extensionKey
168 * @return boolean
169 */
170 public function isAvailable($extensionKey) {
171 $availableExtensions = $this->listUtility->getAvailableExtensions();
172 return array_key_exists($extensionKey, $availableExtensions);
173 }
174
175 /**
176 * Fetch additional information for an extension key
177 *
178 * @param string $extensionKey
179 * @access private
180 * @return array
181 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
182 */
183 public function enrichExtensionWithDetails($extensionKey) {
184 $availableExtensions = $this->listUtility->getAvailableExtensions();
185 if (isset($availableExtensions[$extensionKey])) {
186 $extension = $availableExtensions[$extensionKey];
187 } else {
188 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Extension ' . $extensionKey . ' is not available', 1342864081);
189 }
190 $availableAndInstalledExtensions = $this->listUtility->enrichExtensionsWithEmConfAndTerInformation(array($extensionKey => $extension));
191 return $availableAndInstalledExtensions[$extensionKey];
192 }
193
194 /**
195 * Creates directories as requested in ext_emconf.php
196 *
197 * @param array $extension
198 */
199 protected function ensureConfiguredDirectoriesExist(array $extension) {
200 $this->fileHandlingUtility->ensureConfiguredDirectoriesExist($extension);
201 }
202
203 /**
204 * Gets the content of the ext_tables.sql and ext_tables_static+adt.sql files
205 * Additionally adds the table definitions for the cache tables
206 *
207 * @param array $extension
208 */
209 public function processDatabaseUpdates(array $extension) {
210 $extTablesSqlFile = PATH_site . $extension['siteRelPath'] . '/ext_tables.sql';
211 $extTablesSqlContent = '';
212 if (file_exists($extTablesSqlFile)) {
213 $extTablesSqlContent .= \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($extTablesSqlFile);
214 }
215 if ($extTablesSqlContent !== '') {
216 $this->updateDbWithExtTablesSql($extTablesSqlContent);
217 }
218 $extTablesStaticSqlFile = PATH_site . $extension['siteRelPath'] . '/ext_tables_static+adt.sql';
219 if (file_exists($extTablesStaticSqlFile)) {
220 $extTablesStaticSqlContent = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($extTablesStaticSqlFile);
221 $this->importStaticSql($extTablesStaticSqlContent);
222 }
223 }
224
225 /**
226 * Gets all registered caches and creates required caching framework tables.
227 *
228 * @return void
229 */
230 protected function processCachingFrameworkUpdates() {
231 $extTablesSqlContent = '';
232
233 // @TODO: This should probably moved to TYPO3\CMS\Core\Cache\Cache->getDatabaseTableDefinitions ?!
234 $GLOBALS['typo3CacheManager']->setCacheConfigurations($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
235 $extTablesSqlContent .= \TYPO3\CMS\Core\Cache\Cache::getDatabaseTableDefinitions();
236
237 if ($extTablesSqlContent !== '') {
238 $this->updateDbWithExtTablesSql($extTablesSqlContent);
239 }
240 }
241
242 /**
243 * Reload Cache files and Typo3LoadedExtensions
244 *
245 * @return void
246 */
247 public function reloadCaches() {
248 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::removeCacheFiles();
249 // Set new extlist / extlistArray for extension load changes at runtime
250 /** @var $configurationManager \TYPO3\CMS\Core\Configuration\ConfigurationManager */
251 $configurationManager = $this->objectManager->get('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager');
252 $localConfiguration = $configurationManager->getLocalConfiguration();
253 $GLOBALS['TYPO3_CONF_VARS']['EXT']['extListArray'] = $localConfiguration['EXT']['extListArray'];
254 $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList'] = implode(',', $GLOBALS['TYPO3_CONF_VARS']['EXT']['extListArray']);
255 \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->reloadTypo3LoadedExtAndClassLoaderAndExtLocalconf();
256 }
257
258 /**
259 * Save default configuration of an extension
260 *
261 * @param string $extensionKey
262 * @return void
263 */
264 protected function saveDefaultConfiguration($extensionKey) {
265 /** @var $configUtility \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility */
266 $configUtility = $this->objectManager->get('TYPO3\\CMS\\Extensionmanager\\Utility\\ConfigurationUtility');
267 $configUtility->saveDefaultConfiguration($extensionKey);
268 }
269
270 /**
271 * Update database / process db updates from ext_tables
272 *
273 * @param string $rawDefinitions The raw SQL statements from ext_tables.sql
274 * @return void
275 */
276 public function updateDbWithExtTablesSql($rawDefinitions) {
277 $fieldDefinitionsFromFile = $this->installToolSqlParser->getFieldDefinitions_fileContent($rawDefinitions);
278 if (count($fieldDefinitionsFromFile)) {
279 $fieldDefinitionsFromCurrentDatabase = $this->installToolSqlParser->getFieldDefinitions_database();
280 $diff = $this->installToolSqlParser->getDatabaseExtra($fieldDefinitionsFromFile, $fieldDefinitionsFromCurrentDatabase);
281 $updateStatements = $this->installToolSqlParser->getUpdateSuggestions($diff);
282 foreach ((array) $updateStatements['add'] as $string) {
283 $GLOBALS['TYPO3_DB']->admin_query($string);
284 }
285 foreach ((array) $updateStatements['change'] as $string) {
286 $GLOBALS['TYPO3_DB']->admin_query($string);
287 }
288 foreach ((array) $updateStatements['create_table'] as $string) {
289 $GLOBALS['TYPO3_DB']->admin_query($string);
290 }
291 }
292 }
293
294 /**
295 * Import static SQL data (normally used for ext_tables_static+adt.sql)
296 *
297 * @param string $rawDefinitions
298 * @return void
299 */
300 public function importStaticSql($rawDefinitions) {
301 $statements = $this->installToolSqlParser->getStatementarray($rawDefinitions, 1);
302 list($statementsPerTable, $insertCount) = $this->installToolSqlParser->getCreateTables($statements, 1);
303 // Traverse the tables
304 foreach ($statementsPerTable as $table => $query) {
305 $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS ' . $table);
306 $GLOBALS['TYPO3_DB']->admin_query($query);
307 if ($insertCount[$table]) {
308 $insertStatements = $this->installToolSqlParser->getTableInsertStatements($statements, $table);
309 foreach ($insertStatements as $statement) {
310 $GLOBALS['TYPO3_DB']->admin_query($statement);
311 }
312 }
313 }
314 }
315
316 /**
317 * Remove an extension (delete the directory)
318 *
319 * @param string $extension
320 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
321 * @return void
322 */
323 public function removeExtension($extension) {
324 $absolutePath = $this->fileHandlingUtility->getAbsoluteExtensionPath($extension);
325 if ($this->fileHandlingUtility->isValidExtensionPath($absolutePath)) {
326 $this->fileHandlingUtility->removeDirectory($absolutePath);
327 } else {
328 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('No valid extension path given.', 1342875724);
329 }
330 }
331
332 /**
333 * Get the data dump for an extension
334 *
335 * @param string $extension
336 * @return array
337 */
338 public function getExtensionSqlDataDump($extension) {
339 $extension = $this->enrichExtensionWithDetails($extension);
340 $filePrefix = PATH_site . $extension['siteRelPath'];
341 $sqlData['extTables'] = $this->getSqlDataDumpForFile($filePrefix . '/ext_tables.sql');
342 $sqlData['staticSql'] = $this->getSqlDataDumpForFile($filePrefix . '/ext_tables_static+adt.sql');
343 return $sqlData;
344 }
345
346 /**
347 * Gets the sql data dump for a specific sql file (for example ext_tables.sql)
348 *
349 * @param string $sqlFile
350 * @return string
351 */
352 protected function getSqlDataDumpForFile($sqlFile) {
353 $sqlData = '';
354 if (file_exists($sqlFile)) {
355 $sqlContent = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($sqlFile);
356 $fieldDefinitions = $this->installToolSqlParser->getFieldDefinitions_fileContent($sqlContent);
357 $sqlData = $this->databaseUtility->dumpStaticTables($fieldDefinitions);
358 }
359 return $sqlData;
360 }
361
362 /**
363 * Checks if an update for an extension is available
364 *
365 * @internal
366 * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extensionData
367 * @return boolean
368 */
369 public function isUpdateAvailable(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extensionData) {
370 // Only check for update for TER extensions
371 $version = $extensionData->getIntegerVersion();
372 /** @var $highestTerVersionExtension \TYPO3\CMS\Extensionmanager\Domain\Model\Extension */
373 $highestTerVersionExtension = $this->extensionRepository->findHighestAvailableVersion($extensionData->getExtensionKey());
374 if ($highestTerVersionExtension instanceof \TYPO3\CMS\Extensionmanager\Domain\Model\Extension) {
375 $highestVersion = $highestTerVersionExtension->getIntegerVersion();
376 if ($highestVersion > $version) {
377 return TRUE;
378 }
379 }
380 return FALSE;
381 }
382
383 }
384
385
386 ?>