[BUGFIX] ClassLoader error after installing extension
[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 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 */
39 public $objectManager;
40
41 /**
42 * @var \TYPO3\CMS\Install\Sql\SchemaMigrator
43 */
44 public $installToolSqlParser;
45
46 /**
47 * @var \TYPO3\CMS\Extensionmanager\Utility\DependencyUtility
48 */
49 protected $dependencyUtility;
50
51 /**
52 * @var \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility
53 */
54 protected $fileHandlingUtility;
55
56 /**
57 * @var \TYPO3\CMS\Extensionmanager\Utility\ListUtility
58 */
59 protected $listUtility;
60
61 /**
62 * @var \TYPO3\CMS\Extensionmanager\Utility\DatabaseUtility
63 */
64 protected $databaseUtility;
65
66 /**
67 * @var \TYPO3\CMS\Core\Configuration\ConfigurationManager
68 */
69 protected $configurationManager;
70
71 /**
72 * @var \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository
73 */
74 public $extensionRepository;
75
76 /**
77 * @param \TYPO3\CMS\Extensionmanager\Utility\ListUtility $listUtility
78 * @return void
79 */
80 public function injectListUtility(\TYPO3\CMS\Extensionmanager\Utility\ListUtility $listUtility) {
81 $this->listUtility = $listUtility;
82 }
83
84 /**
85 * @param \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility $filehandlingUtility
86 * @return void
87 */
88 public function injectFileHandlingUtility(\TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility $fileHandlingUtility) {
89 $this->fileHandlingUtility = $fileHandlingUtility;
90 }
91
92 /**
93 * @param \TYPO3\CMS\Extensionmanager\Utility\DependencyUtility $dependencyUtility
94 * @return void
95 */
96 public function injectDependencyUtility(\TYPO3\CMS\Extensionmanager\Utility\DependencyUtility $dependencyUtility) {
97 $this->dependencyUtility = $dependencyUtility;
98 }
99
100 /**
101 * @param \TYPO3\CMS\Extensionmanager\Utility\DatabaseUtility $databaseUtility
102 * @return void
103 */
104 public function injectDatabaseUtility(\TYPO3\CMS\Extensionmanager\Utility\DatabaseUtility $databaseUtility) {
105 $this->databaseUtility = $databaseUtility;
106 }
107
108 /**
109 * Inject configuration manager
110 *
111 * @param \TYPO3\CMS\Core\Configuration\ConfigurationManager $configurationManager
112 * @return void
113 */
114 public function injectConfigurationManager(\TYPO3\CMS\Core\Configuration\ConfigurationManager $configurationManager) {
115 $this->configurationManager = $configurationManager;
116 }
117
118 /**
119 * Inject emConfUtility
120 *
121 * @param \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository $extensionRepository
122 * @return void
123 */
124 public function injectExtensionRepository(\TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository $extensionRepository) {
125 $this->extensionRepository = $extensionRepository;
126 }
127
128 /**
129 * __construct
130 */
131 public function __construct() {
132 $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
133 /** @var $installToolSqlParser \TYPO3\CMS\Install\Sql\SchemaMigrator */
134 $this->installToolSqlParser = $this->objectManager->get('TYPO3\\CMS\\Install\\Sql\\SchemaMigrator');
135 $this->dependencyUtility = $this->objectManager->get('TYPO3\\CMS\\Extensionmanager\\Utility\\DependencyUtility');
136 }
137
138 /**
139 * Helper function to install an extension
140 * also processes db updates and clears the cache if the extension asks for it
141 *
142 * @param string $extensionKey
143 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
144 * @return void
145 */
146 public function install($extensionKey) {
147 $extension = $this->enrichExtensionWithDetails($extensionKey);
148 $this->processDatabaseUpdates($extension);
149 $this->ensureConfiguredDirectoriesExist($extension);
150 if ($extension['clearcacheonload']) {
151 $GLOBALS['typo3CacheManager']->flushCaches();
152 }
153 if (!$this->isLoaded($extensionKey)) {
154 $this->loadExtension($extensionKey);
155 }
156 $this->reloadCaches();
157 $this->saveDefaultConfiguration($extension['key']);
158 }
159
160 /**
161 * Helper function to uninstall an extension
162 *
163 * @param string $extensionKey
164 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
165 * @return void
166 */
167 public function uninstall($extensionKey) {
168 $dependentExtensions = $this->dependencyUtility->findInstalledExtensionsThatDependOnMe($extensionKey);
169 if (is_array($dependentExtensions) && count($dependentExtensions) > 0) {
170 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Cannot deactivate extension ' . $extensionKey . ' - The extension(s) ' . implode(',', $dependentExtensions) . ' depend on it', 1342554622);
171 } else {
172 $this->unloadExtension($extensionKey);
173 }
174 }
175
176 /**
177 * Wrapper function to check for loaded extensions
178 *
179 * @param string $extensionKey
180 * @return boolean TRUE if extension is loaded
181 */
182 public function isLoaded($extensionKey) {
183 return \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($extensionKey);
184 }
185
186 /**
187 * Wrapper function for loading extensions
188 *
189 * @param string $extensionKey
190 * @return void
191 */
192 protected function loadExtension($extensionKey) {
193 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::loadExtension($extensionKey);
194 }
195
196 /**
197 * Wrapper function for unloading extensions
198 *
199 * @param string $extensionKey
200 * @return void
201 */
202 protected function unloadExtension($extensionKey) {
203 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::unloadExtension($extensionKey);
204 }
205
206 /**
207 * Checks if an extension is available in the system
208 *
209 * @param $extensionKey
210 * @return boolean
211 */
212 public function isAvailable($extensionKey) {
213 $availableExtensions = $this->listUtility->getAvailableExtensions();
214 return array_key_exists($extensionKey, $availableExtensions);
215 }
216
217 /**
218 * Fetch additional information for an extension key
219 *
220 * @param string $extensionKey
221 * @access private
222 * @return array
223 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
224 */
225 public function enrichExtensionWithDetails($extensionKey) {
226 $availableExtensions = $this->listUtility->getAvailableExtensions();
227 if (isset($availableExtensions[$extensionKey])) {
228 $extension = $availableExtensions[$extensionKey];
229 } else {
230 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Extension ' . $extensionKey . ' is not available', 1342864081);
231 }
232 $availableAndInstalledExtensions = $this->listUtility->enrichExtensionsWithEmConfAndTerInformation(array($extensionKey => $extension));
233 return $availableAndInstalledExtensions[$extensionKey];
234 }
235
236 /**
237 * Creates directories as requested in ext_emconf.php
238 *
239 * @param array $extension
240 */
241 protected function ensureConfiguredDirectoriesExist(array $extension) {
242 $this->fileHandlingUtility->ensureConfiguredDirectoriesExist($extension);
243 }
244
245 /**
246 * Gets the content of the ext_tables.sql and ext_tables_static+adt.sql files
247 * Additionally adds the table definitions for the cache tables
248 *
249 * @param array $extension
250 */
251 public function processDatabaseUpdates(array $extension) {
252 $extTablesSqlFile = PATH_site . $extension['siteRelPath'] . '/ext_tables.sql';
253 if (file_exists($extTablesSqlFile)) {
254 $extTablesSqlContent = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($extTablesSqlFile);
255 // @TODO: This should probably moved to TYPO3\CMS\Core\Cache\Cache->getDatabaseTableDefinitions ?!
256 $GLOBALS['typo3CacheManager']->setCacheConfigurations($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
257 $extTablesSqlContent .= \TYPO3\CMS\Core\Cache\Cache::getDatabaseTableDefinitions();
258 $this->updateDbWithExtTablesSql($extTablesSqlContent);
259 }
260 $extTablesStaticSqlFile = PATH_site . $extension['siteRelPath'] . '/ext_tables_static+adt.sql';
261 if (file_exists($extTablesStaticSqlFile)) {
262 $extTablesStaticSqlContent = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($extTablesStaticSqlFile);
263 $this->importStaticSql($extTablesStaticSqlContent);
264 }
265 }
266
267 /**
268 * Reload Cache files and Typo3LoadedExtensions
269 *
270 * @return void
271 */
272 public function reloadCaches() {
273 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::removeCacheFiles();
274 // Set new extlist / extlistArray for extension load changes at runtime
275 $localConfiguration = $this->configurationManager->getLocalConfiguration();
276 $GLOBALS['TYPO3_CONF_VARS']['EXT']['extListArray'] = $localConfiguration['EXT']['extListArray'];
277 $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList'] = implode(',', $GLOBALS['TYPO3_CONF_VARS']['EXT']['extListArray']);
278 \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->reloadTypo3LoadedExtAndClassLoaderAndExtLocalconf();
279 }
280
281 /**
282 * Save default configuration of an extension
283 *
284 * @param string $extensionKey
285 * @return void
286 */
287 protected function saveDefaultConfiguration($extensionKey) {
288 /** @var $configUtility \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility */
289 $configUtility = $this->objectManager->get('TYPO3\\CMS\\Extensionmanager\\Utility\\ConfigurationUtility');
290 $configUtility->saveDefaultConfiguration($extensionKey);
291 }
292
293 /**
294 * Update database / process db updates from ext_tables
295 *
296 * @param string $rawDefinitions The raw SQL statements from ext_tables.sql
297 * @return void
298 */
299 public function updateDbWithExtTablesSql($rawDefinitions) {
300 $fieldDefinitionsFromFile = $this->installToolSqlParser->getFieldDefinitions_fileContent($rawDefinitions);
301 if (count($fieldDefinitionsFromFile)) {
302 $fieldDefinitionsFromCurrentDatabase = $this->installToolSqlParser->getFieldDefinitions_database();
303 $diff = $this->installToolSqlParser->getDatabaseExtra($fieldDefinitionsFromFile, $fieldDefinitionsFromCurrentDatabase);
304 $updateStatements = $this->installToolSqlParser->getUpdateSuggestions($diff);
305 foreach ((array) $updateStatements['add'] as $string) {
306 $GLOBALS['TYPO3_DB']->admin_query($string);
307 }
308 foreach ((array) $updateStatements['change'] as $string) {
309 $GLOBALS['TYPO3_DB']->admin_query($string);
310 }
311 foreach ((array) $updateStatements['create_table'] as $string) {
312 $GLOBALS['TYPO3_DB']->admin_query($string);
313 }
314 }
315 }
316
317 /**
318 * Import static SQL data (normally used for ext_tables_static+adt.sql)
319 *
320 * @param string $rawDefinitions
321 * @return void
322 */
323 public function importStaticSql($rawDefinitions) {
324 $statements = $this->installToolSqlParser->getStatementarray($rawDefinitions, 1);
325 list($statementsPerTable, $insertCount) = $this->installToolSqlParser->getCreateTables($statements, 1);
326 // Traverse the tables
327 foreach ($statementsPerTable as $table => $query) {
328 $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS ' . $table);
329 $GLOBALS['TYPO3_DB']->admin_query($query);
330 if ($insertCount[$table]) {
331 $insertStatements = $this->installToolSqlParser->getTableInsertStatements($statements, $table);
332 foreach ($insertStatements as $statement) {
333 $GLOBALS['TYPO3_DB']->admin_query($statement);
334 }
335 }
336 }
337 }
338
339 /**
340 * Writes the TSstyleconf values to "localconf.php"
341 * Removes the temp_CACHED* files before return.
342 *
343 * @param string $extensionKey Extension key
344 * @param array $newConfiguration Configuration array to write back
345 * @return void
346 */
347 public function writeExtensionTypoScriptStyleConfigurationToLocalconf($extensionKey, $newConfiguration) {
348 $this->configurationManager->setLocalConfigurationValueByPath('EXT/extConf/' . $extensionKey, serialize($newConfiguration));
349 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::removeCacheFiles();
350 }
351
352 /**
353 * Remove an extension (delete the directory)
354 *
355 * @param string $extension
356 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
357 * @return void
358 */
359 public function removeExtension($extension) {
360 $absolutePath = $this->fileHandlingUtility->getAbsoluteExtensionPath($extension);
361 if ($this->fileHandlingUtility->isValidExtensionPath($absolutePath)) {
362 $this->fileHandlingUtility->removeDirectory($absolutePath);
363 } else {
364 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('No valid extension path given.', 1342875724);
365 }
366 }
367
368 /**
369 * Get the data dump for an extension
370 *
371 * @param string $extension
372 * @return array
373 */
374 public function getExtensionSqlDataDump($extension) {
375 $extension = $this->enrichExtensionWithDetails($extension);
376 $filePrefix = PATH_site . $extension['siteRelPath'];
377 $sqlData['extTables'] = $this->getSqlDataDumpForFile($filePrefix . '/ext_tables.sql');
378 $sqlData['staticSql'] = $this->getSqlDataDumpForFile($filePrefix . '/ext_tables_static+adt.sql');
379 return $sqlData;
380 }
381
382 /**
383 * Gets the sql data dump for a specific sql file (for example ext_tables.sql)
384 *
385 * @param string $sqlFile
386 * @return string
387 */
388 protected function getSqlDataDumpForFile($sqlFile) {
389 $sqlData = '';
390 if (file_exists($sqlFile)) {
391 $sqlContent = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($sqlFile);
392 $fieldDefinitions = $this->installToolSqlParser->getFieldDefinitions_fileContent($sqlContent);
393 $sqlData = $this->databaseUtility->dumpStaticTables($fieldDefinitions);
394 }
395 return $sqlData;
396 }
397
398 /**
399 * Checks if an update for an extension is available
400 *
401 * @internal
402 * @param \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extensionData
403 * @return boolean
404 */
405 public function isUpdateAvailable(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extensionData) {
406 // Only check for update for TER extensions
407 $version = $extensionData->getIntegerVersion();
408 /** @var $highestTerVersionExtension \TYPO3\CMS\Extensionmanager\Domain\Model\Extension */
409 $highestTerVersionExtension = $this->extensionRepository->findHighestAvailableVersion($extensionData->getExtensionKey());
410 if ($highestTerVersionExtension instanceof \TYPO3\CMS\Extensionmanager\Domain\Model\Extension) {
411 $highestVersion = $highestTerVersionExtension->getIntegerVersion();
412 if ($highestVersion > $version) {
413 return TRUE;
414 }
415 }
416 return FALSE;
417 }
418
419 }
420
421
422 ?>