[BUGFIX] Let Extension Manager API also create folders
[Packages/TYPO3.CMS.git] / typo3 / sysext / extensionmanager / Classes / Utility / InstallUtility.php
1 <?php
2 namespace TYPO3\CMS\Extensionmanager\Utility;
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\Service\OpcodeCacheService;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19 use TYPO3\CMS\Extensionmanager\Domain\Model\Extension;
20 use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException;
21 use TYPO3\CMS\Impexp\Utility\ImportExportUtility;
22
23 /**
24 * Extension Manager Install Utility
25 */
26 class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface
27 {
28 /**
29 * @var \TYPO3\CMS\Extbase\Object\ObjectManager
30 */
31 public $objectManager;
32
33 /**
34 * @var \TYPO3\CMS\Install\Service\SqlSchemaMigrationService
35 */
36 public $installToolSqlParser;
37
38 /**
39 * @var \TYPO3\CMS\Extensionmanager\Utility\DependencyUtility
40 */
41 protected $dependencyUtility;
42
43 /**
44 * @var \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility
45 */
46 protected $fileHandlingUtility;
47
48 /**
49 * @var \TYPO3\CMS\Extensionmanager\Utility\ListUtility
50 */
51 protected $listUtility;
52
53 /**
54 * @var \TYPO3\CMS\Extensionmanager\Utility\DatabaseUtility
55 */
56 protected $databaseUtility;
57
58 /**
59 * @var \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository
60 */
61 public $extensionRepository;
62
63 /**
64 * @var \TYPO3\CMS\Core\Package\PackageManager
65 */
66 protected $packageManager;
67
68 /**
69 * @var \TYPO3\CMS\Core\Cache\CacheManager
70 */
71 protected $cacheManager;
72
73 /**
74 * @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
75 */
76 protected $signalSlotDispatcher;
77
78 /**
79 * @var \TYPO3\CMS\Core\Registry
80 */
81 protected $registry;
82
83 /**
84 * @param \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager
85 */
86 public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManager $objectManager)
87 {
88 $this->objectManager = $objectManager;
89 }
90
91 /**
92 * @param \TYPO3\CMS\Install\Service\SqlSchemaMigrationService $installToolSqlParser
93 */
94 public function injectInstallToolSqlParser(\TYPO3\CMS\Install\Service\SqlSchemaMigrationService $installToolSqlParser)
95 {
96 $this->installToolSqlParser = $installToolSqlParser;
97 }
98
99 /**
100 * @param \TYPO3\CMS\Extensionmanager\Utility\DependencyUtility $dependencyUtility
101 */
102 public function injectDependencyUtility(\TYPO3\CMS\Extensionmanager\Utility\DependencyUtility $dependencyUtility)
103 {
104 $this->dependencyUtility = $dependencyUtility;
105 }
106
107 /**
108 * @param \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility $fileHandlingUtility
109 */
110 public function injectFileHandlingUtility(\TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility $fileHandlingUtility)
111 {
112 $this->fileHandlingUtility = $fileHandlingUtility;
113 }
114
115 /**
116 * @param \TYPO3\CMS\Extensionmanager\Utility\ListUtility $listUtility
117 */
118 public function injectListUtility(\TYPO3\CMS\Extensionmanager\Utility\ListUtility $listUtility)
119 {
120 $this->listUtility = $listUtility;
121 }
122
123 /**
124 * @param \TYPO3\CMS\Extensionmanager\Utility\DatabaseUtility $databaseUtility
125 */
126 public function injectDatabaseUtility(\TYPO3\CMS\Extensionmanager\Utility\DatabaseUtility $databaseUtility)
127 {
128 $this->databaseUtility = $databaseUtility;
129 }
130
131 /**
132 * @param \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository $extensionRepository
133 */
134 public function injectExtensionRepository(\TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository $extensionRepository)
135 {
136 $this->extensionRepository = $extensionRepository;
137 }
138
139 /**
140 * @param \TYPO3\CMS\Core\Package\PackageManager $packageManager
141 */
142 public function injectPackageManager(\TYPO3\CMS\Core\Package\PackageManager $packageManager)
143 {
144 $this->packageManager = $packageManager;
145 }
146
147 /**
148 * @param \TYPO3\CMS\Core\Cache\CacheManager $cacheManager
149 */
150 public function injectCacheManager(\TYPO3\CMS\Core\Cache\CacheManager $cacheManager)
151 {
152 $this->cacheManager = $cacheManager;
153 }
154
155 /**
156 * @param \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher
157 */
158 public function injectSignalSlotDispatcher(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher)
159 {
160 $this->signalSlotDispatcher = $signalSlotDispatcher;
161 }
162
163 /**
164 * @param \TYPO3\CMS\Core\Registry $registry
165 */
166 public function injectRegistry(\TYPO3\CMS\Core\Registry $registry)
167 {
168 $this->registry = $registry;
169 }
170
171 /**
172 * Helper function to install an extension
173 * also processes db updates and clears the cache if the extension asks for it
174 *
175 * @param string $extensionKey
176 * @throws ExtensionManagerException
177 * @return void
178 */
179 public function install($extensionKey)
180 {
181 $extension = $this->enrichExtensionWithDetails($extensionKey, false);
182 $this->loadExtension($extensionKey);
183 if (!empty($extension['clearcacheonload']) || !empty($extension['clearCacheOnLoad'])) {
184 $this->cacheManager->flushCaches();
185 } else {
186 $this->cacheManager->flushCachesInGroup('system');
187 }
188 $this->reloadCaches();
189 $this->processExtensionSetup($extensionKey);
190
191 $this->emitAfterExtensionInstallSignal($extensionKey);
192 }
193
194 /**
195 * @param string $extensionKey
196 */
197 public function processExtensionSetup($extensionKey)
198 {
199 $extension = $this->enrichExtensionWithDetails($extensionKey, false);
200 $this->ensureConfiguredDirectoriesExist($extension);
201 $this->importInitialFiles($extension['siteRelPath'], $extensionKey);
202 $this->processDatabaseUpdates($extension);
203 $this->processRuntimeDatabaseUpdates($extensionKey);
204 $this->saveDefaultConfiguration($extensionKey);
205 }
206
207 /**
208 * Helper function to uninstall an extension
209 *
210 * @param string $extensionKey
211 * @throws ExtensionManagerException
212 * @return void
213 */
214 public function uninstall($extensionKey)
215 {
216 $dependentExtensions = $this->dependencyUtility->findInstalledExtensionsThatDependOnMe($extensionKey);
217 if (is_array($dependentExtensions) && !empty($dependentExtensions)) {
218 throw new ExtensionManagerException(
219 \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate(
220 'extensionList.uninstall.dependencyError',
221 'extensionmanager',
222 [$extensionKey, implode(',', $dependentExtensions)]
223 ),
224 1342554622
225 );
226 } else {
227 $this->unloadExtension($extensionKey);
228 }
229 }
230
231 /**
232 * Wrapper function to check for loaded extensions
233 *
234 * @param string $extensionKey
235 * @return bool TRUE if extension is loaded
236 */
237 public function isLoaded($extensionKey)
238 {
239 return $this->packageManager->isPackageActive($extensionKey);
240 }
241
242 /**
243 * Reset and reload the available extensions
244 */
245 public function reloadAvailableExtensions()
246 {
247 $this->listUtility->reloadAvailableExtensions();
248 }
249
250 /**
251 * Wrapper function for loading extensions
252 *
253 * @param string $extensionKey
254 * @return void
255 */
256 protected function loadExtension($extensionKey)
257 {
258 $this->packageManager->activatePackage($extensionKey);
259 }
260
261 /**
262 * Wrapper function for unloading extensions
263 *
264 * @param string $extensionKey
265 * @return void
266 */
267 protected function unloadExtension($extensionKey)
268 {
269 $this->packageManager->deactivatePackage($extensionKey);
270 $this->emitAfterExtensionUninstallSignal($extensionKey);
271 $this->cacheManager->flushCachesInGroup('system');
272 }
273
274 /**
275 * Emits a signal after an extension has been installed
276 *
277 * @param string $extensionKey
278 */
279 protected function emitAfterExtensionInstallSignal($extensionKey)
280 {
281 $this->signalSlotDispatcher->dispatch(__CLASS__, 'afterExtensionInstall', [$extensionKey, $this]);
282 }
283
284 /**
285 * Emits a signal after an extension has been uninstalled
286 *
287 * @param string $extensionKey
288 */
289 protected function emitAfterExtensionUninstallSignal($extensionKey)
290 {
291 $this->signalSlotDispatcher->dispatch(__CLASS__, 'afterExtensionUninstall', [$extensionKey, $this]);
292 }
293
294 /**
295 * Checks if an extension is available in the system
296 *
297 * @param string $extensionKey
298 * @return bool
299 */
300 public function isAvailable($extensionKey)
301 {
302 return $this->packageManager->isPackageAvailable($extensionKey);
303 }
304
305 /**
306 * Reloads the package information, if the package is already registered
307 *
308 * @param string $extensionKey
309 * @throws \TYPO3\CMS\Core\Package\Exception\InvalidPackageStateException if the package isn't available
310 * @throws \TYPO3\CMS\Core\Package\Exception\InvalidPackageKeyException if an invalid package key was passed
311 * @throws \TYPO3\CMS\Core\Package\Exception\InvalidPackagePathException if an invalid package path was passed
312 * @throws \TYPO3\CMS\Core\Package\Exception\InvalidPackageManifestException if no extension configuration file could be found
313 */
314 public function reloadPackageInformation($extensionKey)
315 {
316 if ($this->packageManager->isPackageAvailable($extensionKey)) {
317 $this->reloadOpcache();
318 $this->packageManager->reloadPackageInformation($extensionKey);
319 }
320 }
321
322 /**
323 * Fetch additional information for an extension key
324 *
325 * @param string $extensionKey
326 * @param bool $loadTerInformation
327 * @access private
328 * @return array
329 * @throws ExtensionManagerException
330 */
331 public function enrichExtensionWithDetails($extensionKey, $loadTerInformation = true)
332 {
333 $extension = $this->getExtensionArray($extensionKey);
334 if (!$loadTerInformation) {
335 $availableAndInstalledExtensions = $this->listUtility->enrichExtensionsWithEmConfInformation([$extensionKey => $extension]);
336 } else {
337 $availableAndInstalledExtensions = $this->listUtility->enrichExtensionsWithEmConfAndTerInformation([$extensionKey => $extension]);
338 }
339
340 if (!isset($availableAndInstalledExtensions[$extensionKey])) {
341 throw new ExtensionManagerException(
342 'Please check your uploaded extension "' . $extensionKey . '". The configuration file "ext_emconf.php" seems to be invalid.',
343 1391432222
344 );
345 }
346
347 return $availableAndInstalledExtensions[$extensionKey];
348 }
349
350 /**
351 * @param string $extensionKey
352 * @return array
353 * @throws ExtensionManagerException
354 */
355 protected function getExtensionArray($extensionKey)
356 {
357 $availableExtensions = $this->listUtility->getAvailableExtensions();
358 if (isset($availableExtensions[$extensionKey])) {
359 return $availableExtensions[$extensionKey];
360 } else {
361 throw new ExtensionManagerException('Extension ' . $extensionKey . ' is not available', 1342864081);
362 }
363 }
364
365 /**
366 * Creates directories as requested in ext_emconf.php
367 *
368 * @param array $extension
369 */
370 protected function ensureConfiguredDirectoriesExist(array $extension)
371 {
372 $this->fileHandlingUtility->ensureConfiguredDirectoriesExist($extension);
373 }
374
375 /**
376 * Gets the content of the ext_tables.sql and ext_tables_static+adt.sql files
377 * Additionally adds the table definitions for the cache tables
378 *
379 * @param array $extension
380 */
381 public function processDatabaseUpdates(array $extension)
382 {
383 $extTablesSqlFile = PATH_site . $extension['siteRelPath'] . 'ext_tables.sql';
384 $extTablesSqlContent = '';
385 if (file_exists($extTablesSqlFile)) {
386 $extTablesSqlContent .= GeneralUtility::getUrl($extTablesSqlFile);
387 }
388 if ($extTablesSqlContent !== '') {
389 $this->updateDbWithExtTablesSql($extTablesSqlContent);
390 }
391
392 $this->importStaticSqlFile($extension['siteRelPath']);
393 $this->importT3DFile($extension['siteRelPath']);
394 }
395
396 /**
397 * Gets all database updates due to runtime configuration, like caching framework or
398 * category api for example
399 *
400 * @param string $extensionKey
401 */
402 protected function processRuntimeDatabaseUpdates($extensionKey)
403 {
404 $sqlString = $this->emitTablesDefinitionIsBeingBuiltSignal($extensionKey);
405 if (!empty($sqlString)) {
406 $this->updateDbWithExtTablesSql(implode(LF . LF . LF . LF, $sqlString));
407 }
408 }
409
410 /**
411 * Emits a signal to manipulate the tables definitions
412 *
413 * @param string $extensionKey
414 * @return mixed
415 * @throws ExtensionManagerException
416 */
417 protected function emitTablesDefinitionIsBeingBuiltSignal($extensionKey)
418 {
419 $signalReturn = $this->signalSlotDispatcher->dispatch(__CLASS__, 'tablesDefinitionIsBeingBuilt', [[], $extensionKey]);
420 // This is important to support old associated returns
421 $signalReturn = array_values($signalReturn);
422 $sqlString = $signalReturn[0];
423 if (!is_array($sqlString)) {
424 throw new ExtensionManagerException(
425 sprintf(
426 'The signal %s of class %s returned a value of type %s, but array was expected.',
427 'tablesDefinitionIsBeingBuilt',
428 __CLASS__,
429 gettype($sqlString)
430 ),
431 1382360258
432 );
433 }
434 return $sqlString;
435 }
436
437 /**
438 * Reload Cache files and Typo3LoadedExtensions
439 *
440 * @return void
441 */
442 public function reloadCaches()
443 {
444 $this->reloadOpcache();
445 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::loadExtLocalconf(false);
446 \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->loadExtensionTables(false);
447 }
448
449 /**
450 * Reloads PHP opcache
451 */
452 protected function reloadOpcache()
453 {
454 GeneralUtility::makeInstance(OpcodeCacheService::class)->clearAllActive();
455 }
456
457 /**
458 * Save default configuration of an extension
459 *
460 * @param string $extensionKey
461 * @return void
462 */
463 protected function saveDefaultConfiguration($extensionKey)
464 {
465 /** @var $configUtility \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility */
466 $configUtility = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility::class);
467 $configUtility->saveDefaultConfiguration($extensionKey);
468 }
469
470 /**
471 * Update database / process db updates from ext_tables
472 *
473 * @param string $rawDefinitions The raw SQL statements from ext_tables.sql
474 * @return void
475 */
476 public function updateDbWithExtTablesSql($rawDefinitions)
477 {
478 $fieldDefinitionsFromFile = $this->installToolSqlParser->getFieldDefinitions_fileContent($rawDefinitions);
479 if (!empty($fieldDefinitionsFromFile)) {
480 $fieldDefinitionsFromCurrentDatabase = $this->installToolSqlParser->getFieldDefinitions_database();
481 $diff = $this->installToolSqlParser->getDatabaseExtra($fieldDefinitionsFromFile, $fieldDefinitionsFromCurrentDatabase);
482 $updateStatements = $this->installToolSqlParser->getUpdateSuggestions($diff);
483 $db = $this->getDatabaseConnection();
484 foreach ((array)$updateStatements['add'] as $string) {
485 $db->admin_query($string);
486 }
487 foreach ((array)$updateStatements['change'] as $string) {
488 $db->admin_query($string);
489 }
490 foreach ((array)$updateStatements['create_table'] as $string) {
491 $db->admin_query($string);
492 }
493 }
494 }
495
496 /**
497 * Import static SQL data (normally used for ext_tables_static+adt.sql)
498 *
499 * @param string $rawDefinitions
500 * @return void
501 */
502 public function importStaticSql($rawDefinitions)
503 {
504 $statements = $this->installToolSqlParser->getStatementarray($rawDefinitions, 1);
505 list($statementsPerTable, $insertCount) = $this->installToolSqlParser->getCreateTables($statements, 1);
506 $db = $this->getDatabaseConnection();
507 // Traverse the tables
508 foreach ($statementsPerTable as $table => $query) {
509 $db->admin_query('DROP TABLE IF EXISTS ' . $table);
510 $db->admin_query($query);
511 if ($insertCount[$table]) {
512 $insertStatements = $this->installToolSqlParser->getTableInsertStatements($statements, $table);
513 foreach ($insertStatements as $statement) {
514 $db->admin_query($statement);
515 }
516 }
517 }
518 }
519
520 /**
521 * Remove an extension (delete the directory)
522 *
523 * @param string $extension
524 * @throws ExtensionManagerException
525 * @return void
526 */
527 public function removeExtension($extension)
528 {
529 $absolutePath = $this->fileHandlingUtility->getAbsoluteExtensionPath($extension);
530 if ($this->fileHandlingUtility->isValidExtensionPath($absolutePath)) {
531 if ($this->packageManager->isPackageAvailable($extension)) {
532 // Package manager deletes the extension and removes the entry from PackageStates.php
533 $this->packageManager->deletePackage($extension);
534 } else {
535 // The extension is not listed in PackageStates.php, we can safely remove it
536 $this->fileHandlingUtility->removeDirectory($absolutePath);
537 }
538 } else {
539 throw new ExtensionManagerException('No valid extension path given.', 1342875724);
540 }
541 }
542
543 /**
544 * Get the data dump for an extension
545 *
546 * @param string $extension
547 * @return array
548 */
549 public function getExtensionSqlDataDump($extension)
550 {
551 $extension = $this->enrichExtensionWithDetails($extension);
552 $filePrefix = PATH_site . $extension['siteRelPath'];
553 $sqlData['extTables'] = $this->getSqlDataDumpForFile($filePrefix . 'ext_tables.sql');
554 $sqlData['staticSql'] = $this->getSqlDataDumpForFile($filePrefix . 'ext_tables_static+adt.sql');
555 return $sqlData;
556 }
557
558 /**
559 * Gets the sql data dump for a specific sql file (for example ext_tables.sql)
560 *
561 * @param string $sqlFile
562 * @return string
563 */
564 protected function getSqlDataDumpForFile($sqlFile)
565 {
566 $sqlData = '';
567 if (file_exists($sqlFile)) {
568 $sqlContent = GeneralUtility::getUrl($sqlFile);
569 $fieldDefinitions = $this->installToolSqlParser->getFieldDefinitions_fileContent($sqlContent);
570 $sqlData = $this->databaseUtility->dumpStaticTables($fieldDefinitions);
571 }
572 return $sqlData;
573 }
574
575 /**
576 * Checks if an update for an extension is available which also resolves dependencies.
577 *
578 * @internal
579 * @param Extension $extensionData
580 * @return bool
581 */
582 public function isUpdateAvailable(Extension $extensionData)
583 {
584 return (bool)$this->getUpdateableVersion($extensionData);
585 }
586
587 /**
588 * Returns the updateable version for an extension which also resolves dependencies.
589 *
590 * @internal
591 * @param Extension $extensionData
592 * @return bool|Extension FALSE if no update available otherwise latest possible update
593 */
594 public function getUpdateableVersion(Extension $extensionData)
595 {
596 // Only check for update for TER extensions
597 $version = $extensionData->getIntegerVersion();
598
599 /** @var $extensionUpdates[] \TYPO3\CMS\Extensionmanager\Domain\Model\Extension */
600 $extensionUpdates = $this->extensionRepository->findByVersionRangeAndExtensionKeyOrderedByVersion(
601 $extensionData->getExtensionKey(),
602 $version,
603 0,
604 false
605 );
606 if ($extensionUpdates->count() > 0) {
607 foreach ($extensionUpdates as $extensionUpdate) {
608 try {
609 $this->dependencyUtility->checkDependencies($extensionUpdate);
610 if (!$this->dependencyUtility->hasDependencyErrors()) {
611 return $extensionUpdate;
612 }
613 } catch (ExtensionManagerException $e) {
614 }
615 }
616 }
617 return false;
618 }
619
620 /**
621 * Uses the export import extension to import a T3D or XML file to PID 0
622 * Execution state is saved in the this->registry, so it only happens once
623 *
624 * @param string $extensionSiteRelPath
625 * @return void
626 */
627 protected function importT3DFile($extensionSiteRelPath)
628 {
629 $registryKeysToCheck = [
630 $extensionSiteRelPath . 'Initialisation/data.t3d',
631 $extensionSiteRelPath . 'Initialisation/dataImported',
632 ];
633 foreach ($registryKeysToCheck as $registryKeyToCheck) {
634 if ($this->registry->get('extensionDataImport', $registryKeyToCheck)) {
635 // Data was imported before => early return
636 return;
637 }
638 }
639 $importFileToUse = null;
640 $possibleImportFiles = [
641 $extensionSiteRelPath . 'Initialisation/data.t3d',
642 $extensionSiteRelPath . 'Initialisation/data.xml'
643 ];
644 foreach ($possibleImportFiles as $possibleImportFile) {
645 if (!file_exists(PATH_site . $possibleImportFile)) {
646 continue;
647 }
648 $importFileToUse = $possibleImportFile;
649 }
650 if ($importFileToUse !== null) {
651 /** @var ImportExportUtility $importExportUtility */
652 $importExportUtility = $this->objectManager->get(ImportExportUtility::class);
653 try {
654 $importResult = $importExportUtility->importT3DFile(PATH_site . $importFileToUse, 0);
655 $this->registry->set('extensionDataImport', $extensionSiteRelPath . 'Initialisation/dataImported', 1);
656 $this->emitAfterExtensionT3DImportSignal($importFileToUse, $importResult);
657 } catch (\ErrorException $e) {
658 /** @var \TYPO3\CMS\Core\Log\Logger $logger */
659 $logger = $this->objectManager->get(\TYPO3\CMS\Core\Log\LogManager::class)->getLogger(__CLASS__);
660 $logger->log(\TYPO3\CMS\Core\Log\LogLevel::WARNING, $e->getMessage());
661 }
662 }
663 }
664
665 /**
666 * Emits a signal after an t3d file was imported
667 *
668 * @param string $importFileToUse
669 * @param int $importResult
670 */
671 protected function emitAfterExtensionT3DImportSignal($importFileToUse, $importResult)
672 {
673 $this->signalSlotDispatcher->dispatch(__CLASS__, 'afterExtensionT3DImport', [$importFileToUse, $importResult, $this]);
674 }
675
676 /**
677 * Imports a static tables SQL File (ext_tables_static+adt)
678 * Execution state is saved in the this->registry, so it only happens once
679 *
680 * @param string $extensionSiteRelPath
681 * @return void
682 */
683 protected function importStaticSqlFile($extensionSiteRelPath)
684 {
685 $extTablesStaticSqlRelFile = $extensionSiteRelPath . 'ext_tables_static+adt.sql';
686 if (!$this->registry->get('extensionDataImport', $extTablesStaticSqlRelFile)) {
687 $extTablesStaticSqlFile = PATH_site . $extTablesStaticSqlRelFile;
688 if (file_exists($extTablesStaticSqlFile)) {
689 $extTablesStaticSqlContent = GeneralUtility::getUrl($extTablesStaticSqlFile);
690 $this->importStaticSql($extTablesStaticSqlContent);
691 }
692 $this->registry->set('extensionDataImport', $extTablesStaticSqlRelFile, 1);
693 $this->emitAfterExtensionStaticSqlImportSignal($extTablesStaticSqlRelFile);
694 }
695 }
696
697 /**
698 * Emits a signal after a static sql file was imported
699 *
700 * @param string $extTablesStaticSqlRelFile
701 */
702 protected function emitAfterExtensionStaticSqlImportSignal($extTablesStaticSqlRelFile)
703 {
704 $this->signalSlotDispatcher->dispatch(__CLASS__, 'afterExtensionStaticSqlImport', [$extTablesStaticSqlRelFile, $this]);
705 }
706
707 /**
708 * Imports files from Initialisation/Files to fileadmin
709 * via lowlevel copy directory method
710 *
711 * @param string $extensionSiteRelPath relative path to extension dir
712 * @param string $extensionKey
713 */
714 protected function importInitialFiles($extensionSiteRelPath, $extensionKey)
715 {
716 $importRelFolder = $extensionSiteRelPath . 'Initialisation/Files';
717 if (!$this->registry->get('extensionDataImport', $importRelFolder)) {
718 $importFolder = PATH_site . $importRelFolder;
719 if (file_exists($importFolder)) {
720 $destinationRelPath = $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . $extensionKey;
721 $destinationAbsolutePath = PATH_site . $destinationRelPath;
722 if (!file_exists($destinationAbsolutePath) &&
723 GeneralUtility::isAllowedAbsPath($destinationAbsolutePath)
724 ) {
725 GeneralUtility::mkdir($destinationAbsolutePath);
726 }
727 GeneralUtility::copyDirectory($importRelFolder, $destinationRelPath);
728 $this->registry->set('extensionDataImport', $importRelFolder, 1);
729 $this->emitAfterExtensionFileImportSignal($destinationAbsolutePath);
730 }
731 }
732 }
733
734 /**
735 * Emits a signal after extension files were imported
736 *
737 * @param string $destinationAbsolutePath
738 */
739 protected function emitAfterExtensionFileImportSignal($destinationAbsolutePath)
740 {
741 $this->signalSlotDispatcher->dispatch(__CLASS__, 'afterExtensionFileImport', [$destinationAbsolutePath, $this]);
742 }
743
744 /**
745 * @return \TYPO3\CMS\Core\Database\DatabaseConnection
746 */
747 protected function getDatabaseConnection()
748 {
749 return $GLOBALS['TYPO3_DB'];
750 }
751 }