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