TYPO3 v15 dev-main snapshot ()

This commit is contained in:
2026-08-10 22:31:09 +02:00
commit af8cc155b5
6818 changed files with 642608 additions and 0 deletions
@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Core\Package\Initialization;
use Psr\Log\LoggerInterface;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\EventDispatcher\ListenerProvider;
use TYPO3\CMS\Core\Package\Event\PackageInitializationEvent;
use TYPO3\CMS\Core\Package\Exception\ImportRequirementsException;
use TYPO3\CMS\Impexp\Initialization\ImportContentOnPackageInitialization;
use TYPO3\CMS\Impexp\Initialization\ImportSiteConfigurationsOnPackageInitialization;
/**
* Listener to check import requirements in case an extension contains data to be imported
*/
final readonly class CheckForImportRequirements
{
public function __construct(
private ListenerProvider $listenerProvider,
private LoggerInterface $logger,
) {}
#[AsEventListener]
public function __invoke(PackageInitializationEvent $event): void
{
$packagePath = $event->getPackage()->getPackagePath();
$importFiles = [];
foreach (['t3d', 'xml'] as $importFileExtension) {
if (file_exists(($importFile = $packagePath . 'Initialisation/data.' . $importFileExtension))) {
$importFiles[] = $importFile;
}
}
$siteInitialisationDirectoryExists = is_dir($packagePath . 'Initialisation/Site');
if ($importFiles === [] && !$siteInitialisationDirectoryExists) {
return;
}
foreach ($this->listenerProvider->getListenersForEvent($event) as $listener) {
if ($listener instanceof \Closure || !isset($listener[0])) {
continue;
}
if (($importFiles !== [] && $listener[0] instanceof ImportContentOnPackageInitialization)
|| ($siteInitialisationDirectoryExists && $listener[0] instanceof ImportSiteConfigurationsOnPackageInitialization)
) {
return;
}
}
// Add a exception which might be thrown by other listeners
$missingImportComponentException = new ImportRequirementsException(
$event->getExtensionKey() . ' contains data to be imported, but the required component is not installed. Make sure to define corresponding requirements.',
1706287389
);
$this->logger->warning(
$missingImportComponentException->getMessage(),
[
'exception' => $missingImportComponentException,
'extensionKey' => $event->getExtensionKey(),
'packageKey' => $event->getPackage()->getPackageKey(),
'importFiles' => $importFiles,
'siteInitialisationDirectoryExists' => $siteInitialisationDirectoryExists,
]
);
$event->addStorageEntry(
__CLASS__,
[
'exception' => $missingImportComponentException,
'importFiles' => $importFiles,
'siteInitialisationDirectoryExists' => $siteInitialisationDirectoryExists,
]
);
}
}
@@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Core\Package\Initialization;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Package\Event\PackageInitializationEvent;
use TYPO3\CMS\Core\Registry;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Listener to import extension data after package activation
*/
final readonly class ImportExtensionDataOnPackageInitialization
{
public function __construct(
private Registry $registry,
) {}
#[AsEventListener]
public function __invoke(PackageInitializationEvent $event): void
{
$package = $event->getPackage();
$extensionKey = $event->getExtensionKey();
$importFolder = $package->getPackagePath() . 'Initialisation/Files';
$registryKey = $extensionKey . ':Initialisation/Files';
if ($this->registry->get('extensionDataImport', $registryKey) || !file_exists($importFolder)) {
return;
}
$destinationAbsolutePath = GeneralUtility::getFileAbsFileName($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . $extensionKey);
if (!file_exists($destinationAbsolutePath) && GeneralUtility::isAllowedAbsPath($destinationAbsolutePath)) {
GeneralUtility::mkdir($destinationAbsolutePath);
}
GeneralUtility::copyDirectory($importFolder, $destinationAbsolutePath);
$this->registry->set('extensionDataImport', $registryKey, 1);
$event->addStorageEntry(__CLASS__, $destinationAbsolutePath);
}
}
@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Core\Package\Initialization;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Database\Schema\SchemaMigrator;
use TYPO3\CMS\Core\Database\Schema\SqlReader;
use TYPO3\CMS\Core\Package\Event\PackageInitializationEvent;
use TYPO3\CMS\Core\Registry;
/**
* Listener to import static sql data ("ext_tables_static+adt.sql") after package activation
*/
final readonly class ImportStaticSqlDataOnPackageInitialization
{
public function __construct(
private Registry $registry,
private SqlReader $sqlReader,
private SchemaMigrator $schemaMigrator,
) {}
#[AsEventListener(after: ImportExtensionDataOnPackageInitialization::class)]
public function __invoke(PackageInitializationEvent $event): void
{
$extTablesStaticSqlFile = $event->getPackage()->getPackagePath() . 'ext_tables_static+adt.sql';
$registryKey = $event->getExtensionKey() . ':ext_tables_static+adt.sql';
$oldFileHash = $this->registry->get('extensionDataImport', $registryKey);
$currentFileHash = '';
// We used to only store "1" in the database when data was imported
$needsUpdate = !$oldFileHash || $oldFileHash === 1;
if (file_exists($extTablesStaticSqlFile)) {
$currentFileHash = hash_file('xxh3', $extTablesStaticSqlFile);
$needsUpdate = $oldFileHash !== $currentFileHash;
if ($needsUpdate) {
$extTablesStaticSqlContent = (string)file_get_contents($extTablesStaticSqlFile);
$statements = $this->sqlReader->getStatementArray($extTablesStaticSqlContent);
$this->schemaMigrator->importStaticData($statements, true);
}
}
if ($needsUpdate) {
$this->registry->set('extensionDataImport', $registryKey, $currentFileHash);
$event->addStorageEntry(__CLASS__, $extTablesStaticSqlFile);
}
}
}
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Core\Package\Initialization;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Package\Event\PackageInitializationEvent;
use TYPO3\CMS\Core\SystemResource\Publishing\SystemResourcePublisherInterface;
/**
* Listener to publish assets after package activation
*/
final readonly class PublishAssetsOnPackageInitialization
{
public function __construct(
private SystemResourcePublisherInterface $publisher,
) {}
#[AsEventListener]
public function __invoke(PackageInitializationEvent $event): void
{
$this->publisher->publishResources($event->getPackage());
}
}