diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c689855..8827529 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -90,6 +90,10 @@ jobs: typo3-version: '^12.4' - php-version: '8.3' typo3-version: '^12.4' + - php-version: '8.2' + typo3-version: '^13.4' + - php-version: '8.3' + typo3-version: '^13.4' steps: - uses: actions/checkout@v3 @@ -119,6 +123,10 @@ jobs: typo3-version: '^12.4' - php-version: '8.3' typo3-version: '^12.4' + - php-version: '8.2' + typo3-version: '^13.4' + - php-version: '8.3' + typo3-version: '^13.4' steps: - uses: actions/checkout@v3 diff --git a/Classes/Caching/PageCacheTimeout.php b/Classes/Caching/PageCacheTimeout.php index 1492e89..1d309b6 100644 --- a/Classes/Caching/PageCacheTimeout.php +++ b/Classes/Caching/PageCacheTimeout.php @@ -26,7 +26,6 @@ namespace WerkraumMedia\Events\Caching; use DateTime; use DateTimeImmutable; use InvalidArgumentException; -use TYPO3\CMS\Core\Cache\CacheManager; use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface; use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\SingletonInterface; @@ -44,13 +43,10 @@ class PageCacheTimeout implements SingletonInterface { private ?DateTimeImmutable $timeout = null; - private FrontendInterface $runtimeCache; - public function __construct( - CacheManager $cacheManager, - private readonly Context $context + private readonly FrontendInterface $runtimeCache, + private readonly Context $context, ) { - $this->runtimeCache = $cacheManager->getCache('runtime'); } public function modifyCacheLifetimeForPage(ModifyCacheLifetimeForPageEvent $event): void diff --git a/Classes/Controller/AbstractController.php b/Classes/Controller/AbstractController.php index b674565..cfe7ac9 100644 --- a/Classes/Controller/AbstractController.php +++ b/Classes/Controller/AbstractController.php @@ -25,13 +25,14 @@ namespace WerkraumMedia\Events\Controller; use TYPO3\CMS\Core\Http\PropagateResponseException; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\View\ViewInterface; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3\CMS\Frontend\Controller\ErrorController; -use TYPO3Fluid\Fluid\View\ViewInterface; +use TYPO3Fluid\Fluid\View\ViewInterface as FluidStandaloneViewInterface; use WerkraumMedia\Events\Caching\CacheManager; -class AbstractController extends ActionController +abstract class AbstractController extends ActionController { /** * @var CacheManager @@ -60,17 +61,13 @@ class AbstractController extends ActionController /** * Extend original to also add data from current cobject if available. */ - protected function resolveView(): ViewInterface + protected function initializeView(ViewInterface|FluidStandaloneViewInterface $view): void { - $view = parent::resolveView(); - $view->assign('data', []); $cObject = $this->request->getAttribute('currentContentObject'); if ($cObject instanceof ContentObjectRenderer && is_array($cObject->data)) { $view->assign('data', $cObject->data); } - - return $view; } protected function trigger404(string $message): void diff --git a/Classes/Domain/DestinationData/ImportFactory.php b/Classes/Domain/DestinationData/ImportFactory.php index 9bd5a56..30101e6 100644 --- a/Classes/Domain/DestinationData/ImportFactory.php +++ b/Classes/Domain/DestinationData/ImportFactory.php @@ -5,13 +5,13 @@ declare(strict_types=1); namespace WerkraumMedia\Events\Domain\DestinationData; use Exception; -use PDO; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Resource\Folder; use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper; use TYPO3\CMS\Extbase\Persistence\Generic\Session; use WerkraumMedia\Events\Domain\Model\Import; +use WerkraumMedia\Events\Service\ExtbaseConfigurationManagerService; final class ImportFactory { @@ -24,7 +24,8 @@ final class ImportFactory private readonly ConnectionPool $connectionPool, private readonly Session $extbasePersistenceSession, private readonly DataMapper $dataMapper, - private readonly ResourceFactory $resourceFactory + private readonly ResourceFactory $resourceFactory, + private readonly ExtbaseConfigurationManagerService $extbaseConfigurationManagerService, ) { } @@ -49,14 +50,14 @@ final class ImportFactory $qb = $this->connectionPool->getQueryBuilderForTable('tx_events_domain_model_import'); $qb->select('*'); $qb->from('tx_events_domain_model_import'); - $qb->where($qb->expr()->eq('uid', $qb->createNamedParameter($uid, PDO::PARAM_INT))); + $qb->where($qb->expr()->eq('uid', $qb->createNamedParameter($uid))); - $result = $qb->executeQuery()->fetch(); + $result = $qb->executeQuery()->fetchAssociative(); if (is_array($result) === false) { throw new Exception('Could not fetch import record with uid "' . $uid . '".', 1643267492); } - $result = array_map('strval', $result); + $result = array_map(strval(...), $result); return $result; } @@ -67,13 +68,13 @@ final class ImportFactory $qb->select('*'); $qb->from('tx_events_domain_model_import'); - $result = $qb->executeQuery()->fetchAll(); + $result = $qb->executeQuery()->fetchAllAssociative(); if (count($result) === 0) { throw new Exception('Could not fetch any import record.', 1643267492); } foreach ($result as $key => $entry) { - $result[$key] = array_map('strval', $entry); + $result[$key] = array_map(strval(...), $entry); } return $result; @@ -94,6 +95,7 @@ final class ImportFactory { $this->folderInstance = $this->resourceFactory->getFolderObjectFromCombinedIdentifier($data['files_folder']); $this->extbasePersistenceSession->registerObject($this->folderInstance, $data['files_folder']); + $this->extbaseConfigurationManagerService->configureForBackend(); } private function cleanupWorkarounds(): void diff --git a/Classes/Domain/Repository/CategoryRepository.php b/Classes/Domain/Repository/CategoryRepository.php index 9838152..ddf3758 100644 --- a/Classes/Domain/Repository/CategoryRepository.php +++ b/Classes/Domain/Repository/CategoryRepository.php @@ -75,7 +75,7 @@ final class CategoryRepository extends Repository return $this->dataMapper->map( Category::class, - $qb->executeQuery()->fetchAll() + $qb->executeQuery()->fetchAllAssociative() ); } diff --git a/Classes/Domain/Repository/DateRepository.php b/Classes/Domain/Repository/DateRepository.php index 0905bf6..0c5bc3e 100644 --- a/Classes/Domain/Repository/DateRepository.php +++ b/Classes/Domain/Repository/DateRepository.php @@ -304,7 +304,7 @@ final class DateRepository extends Repository )->orderBy('tx_events_domain_model_date.start') ; - return $statement->executeQuery()->fetchAll(); + return $statement->executeQuery()->fetchAllAssociative(); } private function createEventConstraint( diff --git a/Classes/Domain/Repository/OrganizerRepository.php b/Classes/Domain/Repository/OrganizerRepository.php index a07c0cb..202d685 100644 --- a/Classes/Domain/Repository/OrganizerRepository.php +++ b/Classes/Domain/Repository/OrganizerRepository.php @@ -18,7 +18,18 @@ namespace WerkraumMedia\Events\Domain\Repository; */ use TYPO3\CMS\Extbase\Persistence\Repository; +use WerkraumMedia\Events\Domain\Model\Organizer; final class OrganizerRepository extends Repository { + public function findOneByName(string $name): ?Organizer + { + $organizer = $this->findOneBy(['name' => $name]); + + if ($organizer instanceof Organizer) { + return $organizer; + } + + return null; + } } diff --git a/Classes/Extbase/AddSpecialProperties.php b/Classes/Extbase/AddSpecialProperties.php index 344713d..b752a5f 100644 --- a/Classes/Extbase/AddSpecialProperties.php +++ b/Classes/Extbase/AddSpecialProperties.php @@ -72,7 +72,7 @@ final class AddSpecialProperties $qb->where($qb->expr()->eq('postponed_date', $uidOfReferencedDate)); $qb->setMaxResults(1); - $result = $qb->executeQuery()->fetch(); + $result = $qb->executeQuery()->fetchAssociative(); if ($result === false) { return null; diff --git a/Classes/Service/CategoryService.php b/Classes/Service/CategoryService.php index b42cb0c..9117b17 100644 --- a/Classes/Service/CategoryService.php +++ b/Classes/Service/CategoryService.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace WerkraumMedia\Events\Service; +use RuntimeException; use TYPO3\CMS\Core\Cache\CacheManager; use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface; use TYPO3\CMS\Core\Database\Connection; @@ -13,9 +14,9 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; final class CategoryService { - private TimeTracker $timeTracker; + private readonly TimeTracker $timeTracker; - private FrontendInterface $cache; + private readonly FrontendInterface $cache; public function __construct() { @@ -77,17 +78,18 @@ final class CategoryService ->executeQuery() ; - while ($row = $res->fetch()) { - if (is_array($row) === false) { - continue; - } - + foreach ($res->fetchAllAssociative() as $row) { $counter++; if ($counter > 10000) { $this->timeTracker->setTSlogMessage('EXT:dd_events: one or more recursive categories where found'); return implode(',', $result); } - $subcategories = $this->getChildrenCategoriesRecursive($row['uid'], $counter); + $uid = $row['uid']; + if (is_numeric($uid) === false) { + throw new RuntimeException('Given uid was not numeric, which we never expect as UID column within DB is numeric.', 1728998121); + } + + $subcategories = $this->getChildrenCategoriesRecursive((string)$uid, $counter); $result[] = $row['uid'] . ($subcategories ? ',' . $subcategories : ''); } @@ -100,11 +102,10 @@ final class CategoryService */ protected function getUidListFromRecords(string $idList): string { - $list = []; $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('sys_category') ; - $rows = $queryBuilder + $uids = $queryBuilder ->select('uid') ->from('sys_category') ->where($queryBuilder->expr()->in( @@ -112,16 +113,9 @@ final class CategoryService $queryBuilder->createNamedParameter(explode(',', $idList), Connection::PARAM_INT_ARRAY) )) ->executeQuery() - ->fetchAll() + ->fetchFirstColumn() ; - foreach ($rows as $row) { - if (is_array($row) === false) { - continue; - } - $list[] = $row['uid']; - } - - return implode(',', $list); + return implode(',', $uids); } } diff --git a/Classes/Service/Cleanup/Database.php b/Classes/Service/Cleanup/Database.php index 4a6e642..9bb409e 100644 --- a/Classes/Service/Cleanup/Database.php +++ b/Classes/Service/Cleanup/Database.php @@ -24,7 +24,6 @@ namespace WerkraumMedia\Events\Service\Cleanup; */ use DateTimeImmutable; -use PDO; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; @@ -88,7 +87,7 @@ final class Database $recordUids = $queryBuilder->select('event.uid') ->from(self::EVENT_TABLE, 'event') ->leftJoin('event', self::DATE_TABLE, 'date', $queryBuilder->expr()->eq('date.event', 'event.uid'))->where($queryBuilder->expr()->isNull('date.uid'))->executeQuery() - ->fetchAll(PDO::FETCH_COLUMN) + ->fetchFirstColumn() ; $queryBuilder = $this->connectionPool->getQueryBuilderForTable(self::EVENT_TABLE); diff --git a/Classes/Service/Cleanup/Files.php b/Classes/Service/Cleanup/Files.php index d5fd979..70f5919 100644 --- a/Classes/Service/Cleanup/Files.php +++ b/Classes/Service/Cleanup/Files.php @@ -23,7 +23,7 @@ namespace WerkraumMedia\Events\Service\Cleanup; * 02110-1301, USA. */ -use PDO; +use RuntimeException; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Resource\StorageRepository; @@ -84,16 +84,12 @@ final class Files $referencesQuery->orderBy('tablenames'); $referencesQuery->addOrderBy('uid_foreign'); - $references = $referencesQuery->executeQuery(); + $references = $referencesQuery->executeQuery()->fetchAllAssociative(); $uidsPerTable = []; $referenceUidsToMarkAsDeleted = []; - while ($reference = $references->fetch()) { - if (is_array($reference) === false) { - continue; - } - + foreach ($references as $reference) { if ($reference['tablenames'] === '') { $referenceUidsToMarkAsDeleted[] = $reference['uid']; continue; @@ -112,7 +108,7 @@ final class Files ...$referenceUidsToMarkAsDeleted, ...array_keys(array_diff( $records, - $queryBuilder->executeQuery()->fetchAll(PDO::FETCH_COLUMN) + $queryBuilder->executeQuery()->fetchFirstColumn() )), ]; } @@ -249,11 +245,16 @@ final class Files foreach ($queryBuilder->executeQuery()->iterateAssociative() as $reference) { $file = []; $fileUid = (int)$reference['uid_local']; + $tableNames = $reference['tablenames']; + + if (is_string($tableNames) === false) { + throw new RuntimeException('Fetched "tablenames" was not of type string. But it should be a string within the db.', 1728998600); + } if ( ( - str_starts_with((string)$reference['tablenames'], 'tx_events_domain_model_') - || $reference['tablenames'] === '' + str_starts_with($tableNames, 'tx_events_domain_model_') + || $tableNames === '' ) && $reference['deleted'] == 1 ) { $file = $files[$fileUid] ?? []; diff --git a/Classes/Service/DataProcessingForModels.php b/Classes/Service/DataProcessingForModels.php index a25d963..e72a223 100644 --- a/Classes/Service/DataProcessingForModels.php +++ b/Classes/Service/DataProcessingForModels.php @@ -113,7 +113,14 @@ final class DataProcessingForModels implements SingletonInterface private function getData(AbstractEntity $entity): array { - $row = $this->connection->select(['*'], $this->getTable($entity), ['uid' => $entity->getUid()])->fetch(); + $row = $this->connection + ->select( + ['*'], + $this->getTable($entity), + ['uid' => $entity->getUid()] + ) + ->fetchAssociative() + ; if (is_array($row)) { return $row; } diff --git a/Classes/Service/DestinationDataImportService.php b/Classes/Service/DestinationDataImportService.php index 36df56c..edf57a0 100644 --- a/Classes/Service/DestinationDataImportService.php +++ b/Classes/Service/DestinationDataImportService.php @@ -38,14 +38,8 @@ final class DestinationDataImportService private Event $tmpCurrentEvent; - /** - * @var Logger - */ - private $logger; + private readonly Logger $logger; - /** - * ImportService constructor. - */ public function __construct( private readonly EventRepository $eventRepository, private readonly OrganizerRepository $organizerRepository, @@ -60,8 +54,10 @@ final class DestinationDataImportService private readonly Slugger $slugger, private readonly CacheManager $cacheManager, private readonly DataHandler $dataHandler, - private readonly EventDispatcher $eventDispatcher + private readonly EventDispatcher $eventDispatcher, + LogManager $logManager, ) { + $this->logger = $logManager->getLogger(self::class); } public function import( @@ -83,7 +79,6 @@ final class DestinationDataImportService // Set Configuration $this->configurationManager->setConfiguration(array_merge($frameworkConfiguration, $persistenceConfiguration)); - $this->logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(self::class); $this->logger->info('Starting Destination Data Import Service'); try { @@ -412,7 +407,7 @@ final class DestinationDataImportService private function getOrCreateEvent(string $globalId, string $title): Event { - $event = $this->eventRepository->findOneByGlobalId($globalId); + $event = $this->eventRepository->findOneBy(['globalId' => $globalId]); if ($event instanceof Event) { $this->logger->info( diff --git a/Classes/Service/DestinationDataImportService/ArrayBasedConfigurationService.php b/Classes/Service/DestinationDataImportService/ArrayBasedConfigurationService.php new file mode 100644 index 0000000..35dc4cc --- /dev/null +++ b/Classes/Service/DestinationDataImportService/ArrayBasedConfigurationService.php @@ -0,0 +1,43 @@ +<?php + +declare(strict_types=1); + +namespace WerkraumMedia\Events\Service\DestinationDataImportService; + +final class ArrayBasedConfigurationService implements ConfigurationServiceInterface +{ + public function __construct( + private readonly array $settings + ) { + } + + public function getLicenseKey(): string + { + return $this->settings['license'] ?? ''; + } + + public function getRestType(): string + { + return $this->settings['restType'] ?? ''; + } + + public function getRestMode(): string + { + return $this->settings['restMode'] ?? ''; + } + + public function getRestLimit(): string + { + return $this->settings['restLimit'] ?? ''; + } + + public function getRestTemplate(): string + { + return $this->settings['restTemplate'] ?? ''; + } + + public function getRestUrl(): string + { + return $this->settings['restUrl'] ?? ''; + } +} diff --git a/Classes/Service/DestinationDataImportService/ConfigurationServiceInterface.php b/Classes/Service/DestinationDataImportService/ConfigurationServiceInterface.php new file mode 100644 index 0000000..6724bbe --- /dev/null +++ b/Classes/Service/DestinationDataImportService/ConfigurationServiceInterface.php @@ -0,0 +1,15 @@ +<?php + +declare(strict_types=1); + +namespace WerkraumMedia\Events\Service\DestinationDataImportService; + +interface ConfigurationServiceInterface +{ + public function getLicenseKey(): string; + public function getRestType(): string; + public function getRestMode(): string; + public function getRestLimit(): string; + public function getRestTemplate(): string; + public function getRestUrl(): string; +} diff --git a/Classes/Service/DestinationDataImportService/ExtbaseConfigurationService.php b/Classes/Service/DestinationDataImportService/ExtbaseConfigurationService.php new file mode 100644 index 0000000..44b7e65 --- /dev/null +++ b/Classes/Service/DestinationDataImportService/ExtbaseConfigurationService.php @@ -0,0 +1,66 @@ +<?php + +declare(strict_types=1); + +namespace WerkraumMedia\Events\Service\DestinationDataImportService; + +use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; +use WerkraumMedia\Events\Service\ExtbaseConfigurationManagerService; + +final class ExtbaseConfigurationService implements ConfigurationServiceInterface +{ + private array $settings = []; + + public function __construct( + private ExtbaseConfigurationManagerService $configurationManager + ) { + } + + public function getLicenseKey(): string + { + return $this->getSettings()['license'] ?? ''; + } + + public function getRestType(): string + { + return $this->getSettings()['restType'] ?? ''; + } + + public function getRestMode(): string + { + return $this->getSettings()['restMode'] ?? ''; + } + + public function getRestLimit(): string + { + return $this->getSettings()['restLimit'] ?? ''; + } + + public function getRestTemplate(): string + { + return $this->getSettings()['restTemplate'] ?? ''; + } + + public function getRestUrl(): string + { + return $this->getSettings()['restUrl'] ?? ''; + } + + private function getSettings(): array + { + if ($this->settings !== []) { + return $this->settings; + } + + $fullTypoScript = $this->configurationManager + ->getInstanceWithBackendContext() + ->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT) + ; + + $this->settings = $fullTypoScript['module.']['tx_events.']['settings.']['destinationData.'] + ?? $fullTypoScript['module.']['tx_events_pi1.']['settings.']['destinationData.'] + ?? []; + + return $this->settings; + } +} diff --git a/Classes/Service/DestinationDataImportService/FilesAssignment.php b/Classes/Service/DestinationDataImportService/FilesAssignment.php index 04c7c4d..306bb2a 100644 --- a/Classes/Service/DestinationDataImportService/FilesAssignment.php +++ b/Classes/Service/DestinationDataImportService/FilesAssignment.php @@ -27,7 +27,8 @@ use Exception; use Psr\Log\LoggerInterface; use SplFileInfo; use TYPO3\CMS\Core\Log\LogManager; -use TYPO3\CMS\Core\Resource\DuplicationBehavior; +use TYPO3\CMS\Core\Resource\DuplicationBehavior as OldDuplicationBehavior; +use TYPO3\CMS\Core\Resource\Enum\DuplicationBehavior; use TYPO3\CMS\Core\Resource\File; use TYPO3\CMS\Core\Resource\Folder; use TYPO3\CMS\Core\Resource\Index\MetaDataRepository; @@ -76,7 +77,14 @@ final class FilesAssignment $this->logger->info('File already exists.', [$orgFileNameSanitized]); } elseif ($filename = $this->loadFile($fileUrl)) { $this->logger->info('Adding file to FAL.', [$filename]); - $importFolder->addFile($filename, $orgFileNameSanitized, DuplicationBehavior::REPLACE); + + // TODO: typo3/cms-core:14.0 Remove the fallback to old behaviour, only use new one. + $behaviour = OldDuplicationBehavior::REPLACE; + if (class_exists(DuplicationBehavior::class)) { + $behaviour = DuplicationBehavior::REPLACE; + } + + $importFolder->addFile($filename, $orgFileNameSanitized, $behaviour); } else { continue; } diff --git a/Classes/Service/DestinationDataImportService/Slugger.php b/Classes/Service/DestinationDataImportService/Slugger.php index 2a068b1..d1bcdd9 100644 --- a/Classes/Service/DestinationDataImportService/Slugger.php +++ b/Classes/Service/DestinationDataImportService/Slugger.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace WerkraumMedia\Events\Service\DestinationDataImportService; use Generator; -use PDO; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\DataHandling\SlugHelper; @@ -61,18 +60,14 @@ final class Slugger ->from($tableName) ->where( $queryBuilder->expr()->or( - $queryBuilder->expr()->eq($slugColumn, $queryBuilder->createNamedParameter('', PDO::PARAM_STR)), + $queryBuilder->expr()->eq($slugColumn, $queryBuilder->createNamedParameter('')), $queryBuilder->expr()->isNull($slugColumn) ) ) ->executeQuery() ; - while ($record = $statement->fetch()) { - if (is_array($record) === false) { - continue; - } - + foreach ($statement->iterateAssociative() as $record) { yield $record; } } @@ -88,7 +83,7 @@ final class Slugger ->where( $queryBuilder->expr()->eq( 'uid', - $queryBuilder->createNamedParameter($record['uid'], PDO::PARAM_INT) + $queryBuilder->createNamedParameter((int)$record['uid']) ) ) ->set($sluggerType->getSlugColumn(), $slug) diff --git a/Classes/Service/DestinationDataImportService/UrlFactory.php b/Classes/Service/DestinationDataImportService/UrlFactory.php index 70117f5..9c1bd56 100644 --- a/Classes/Service/DestinationDataImportService/UrlFactory.php +++ b/Classes/Service/DestinationDataImportService/UrlFactory.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace WerkraumMedia\Events\Service\DestinationDataImportService; use TYPO3\CMS\Core\Http\Uri; -use TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager; use WerkraumMedia\Events\Domain\Model\Import; /** @@ -13,18 +12,9 @@ use WerkraumMedia\Events\Domain\Model\Import; */ final class UrlFactory { - /** - * @var array - */ - private $settings = []; - public function __construct( - BackendConfigurationManager $configurationManager + private readonly ConfigurationServiceInterface $configuration, ) { - $this->settings = $configurationManager->getConfiguration( - 'Events', - 'Pi1' - )['settings']['destinationData'] ?? []; } /** @@ -35,17 +25,17 @@ final class UrlFactory ): string { $parameter = [ 'experience' => $import->getRestExperience(), - 'licensekey' => $this->settings['license'] ?? '', - 'type' => $this->settings['restType'] ?? '', - 'mode' => $this->settings['restMode'] ?? '', - 'limit' => $this->settings['restLimit'] ?? '', - 'template' => $this->settings['restTemplate'] ?? '', + 'licensekey' => $this->configuration->getLicenseKey(), + 'type' => $this->configuration->getRestType(), + 'mode' => $this->configuration->getRestMode(), + 'limit' => $this->configuration->getRestLimit(), + 'template' => $this->configuration->getRestTemplate(), 'q' => $import->getSearchQuery(), ]; $parameter = array_filter($parameter); - $url = new Uri($this->settings['restUrl']); + $url = new Uri($this->configuration->getRestUrl()); $url = $url->withQuery(http_build_query($parameter)); return (string)$url; } diff --git a/Classes/Service/ExtbaseConfigurationManagerService.php b/Classes/Service/ExtbaseConfigurationManagerService.php new file mode 100644 index 0000000..b9fc337 --- /dev/null +++ b/Classes/Service/ExtbaseConfigurationManagerService.php @@ -0,0 +1,41 @@ +<?php + +declare(strict_types=1); + +namespace WerkraumMedia\Events\Service; + +use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; +use TYPO3\CMS\Core\Http\ServerRequest; +use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; + +final class ExtbaseConfigurationManagerService +{ + public function __construct( + private readonly ConfigurationManagerInterface $configurationManager + ) { + } + + /** + * The mapper uses queries, which rely an on the configuration manager. + * But import is without request, so we ensure it is properly initialized. + * + * This should vanish, see: Documentation/Maintenance.rst + */ + public function configureForBackend(): void + { + // TODO: typo3/cms-core:14.0 Remove condition as this method is provided since 13. + if (method_exists($this->configurationManager, 'setRequest') === false) { + return; + } + + $request = new ServerRequest(); + $request = $request->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_BE); + $this->configurationManager->setRequest($request); + } + + public function getInstanceWithBackendContext(): ConfigurationManagerInterface + { + $this->configureForBackend(); + return $this->configurationManager; + } +} diff --git a/Classes/Updates/MigrateOldLocations.php b/Classes/Updates/MigrateOldLocations.php index a1705ad..f5e92a8 100644 --- a/Classes/Updates/MigrateOldLocations.php +++ b/Classes/Updates/MigrateOldLocations.php @@ -234,9 +234,8 @@ class MigrateOldLocations implements UpgradeWizardInterface { $schema = $this->connectionPool ->getConnectionForTable('tx_events_domain_model_event') - ->getSchemaManager() - ->createSchema() - ->getTable('tx_events_domain_model_event') + ->getSchemaInformation() + ->introspectTable('tx_events_domain_model_event') ; foreach ($this->columnsToFetch() as $column) { diff --git a/Classes/Updates/MigratePluginsFromListToCtype.php b/Classes/Updates/MigratePluginsFromListToCtype.php new file mode 100644 index 0000000..4c25cb1 --- /dev/null +++ b/Classes/Updates/MigratePluginsFromListToCtype.php @@ -0,0 +1,59 @@ +<?php + +declare(strict_types=1); + +/* + * Copyright (C) 2024 Daniel Siepmann <daniel.siepmann@codappix.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +namespace WerkraumMedia\Events\Updates; + +use TYPO3\CMS\Install\Attribute\UpgradeWizard; +use TYPO3\CMS\Install\Updates\AbstractListTypeToCTypeUpdate; + +// TODO: typo3/cms-core:14.0 Remove condition as this class is provided since 13. +if (class_exists(AbstractListTypeToCTypeUpdate::class) === false) { + final class MigratePluginsFromListToCtype + { + } + return; +} + +#[UpgradeWizard(MigratePluginsFromListToCtype::class)] +final class MigratePluginsFromListToCtype extends AbstractListTypeToCTypeUpdate +{ + protected function getListTypeToCTypeMapping(): array + { + return [ + 'events_datelist' => 'events_datelist', + 'events_datesearch' => 'events_datesearch', + 'events_dateshow ' => 'events_dateshow', + 'events_selected ' => 'events_selected', + ]; + } + + public function getTitle(): string + { + return 'Migrate EXT:events content elements.'; + } + + public function getDescription(): string + { + return 'Migrate CType from list to dedicated plugins.'; + } +} diff --git a/Configuration/FlexForms/DateList.xml b/Configuration/FlexForms/DateList.xml index 9c000c9..886bdd7 100644 --- a/Configuration/FlexForms/DateList.xml +++ b/Configuration/FlexForms/DateList.xml @@ -2,127 +2,108 @@ <sheets> <sDEF> <ROOT> - <TCEforms> - <sheetTitle>Options</sheetTitle> - </TCEforms> + <sheetTitle>Options</sheetTitle> <type>array</type> <el> <settings.sortByDate> - <TCEforms> - <exclude>1</exclude> - <label>Sort By</label> - <config> - <type>select</type> - <renderType>selectSingle</renderType> - <items type="array"> - <numIndex index="0" type="array"> - <numIndex index="0">Start</numIndex> - <numIndex index="1">start</numIndex> - </numIndex> - <numIndex index="1" type="array"> - <numIndex index="0">End</numIndex> - <numIndex index="1">end</numIndex> - </numIndex> - </items> - </config> - </TCEforms> + <exclude>1</exclude> + <label>Sort By</label> + <config> + <type>select</type> + <renderType>selectSingle</renderType> + <items type="array"> + <numIndex index="0" type="array"> + <numIndex index="label">Start</numIndex> + <numIndex index="value">start</numIndex> + </numIndex> + <numIndex index="1" type="array"> + <numIndex index="label">End</numIndex> + <numIndex index="value">end</numIndex> + </numIndex> + </items> + </config> </settings.sortByDate> <settings.sortOrder> - <TCEforms> - <exclude>1</exclude> - <label>Sort Order</label> - <config> - <type>select</type> - <renderType>selectSingle</renderType> - <items type="array"> - <numIndex index="0" type="array"> - <numIndex index="0"> - Ascending - </numIndex> - <numIndex index="1">ASC</numIndex> + <exclude>1</exclude> + <label>Sort Order</label> + <config> + <type>select</type> + <renderType>selectSingle</renderType> + <items type="array"> + <numIndex index="0" type="array"> + <numIndex index="label"> + Ascending </numIndex> - <numIndex index="1" type="array"> - <numIndex index="0"> - Descending - </numIndex> - <numIndex index="1">DESC</numIndex> + <numIndex index="value">ASC</numIndex> + </numIndex> + <numIndex index="1" type="array"> + <numIndex index="label"> + Descending </numIndex> - </items> - <default>ASC</default> - </config> - </TCEforms> + <numIndex index="value">DESC</numIndex> + </numIndex> + </items> + <default>ASC</default> + </config> </settings.sortOrder> <settings.limit> - <TCEforms> - <exclude>1</exclude> - <label>Max Items</label> - <config> - <type>input</type> - <size>10</size> - <max>30</max> - <eval>trim</eval> - </config> - </TCEforms> + <exclude>1</exclude> + <label>Max Items</label> + <config> + <type>input</type> + <size>10</size> + <max>30</max> + <eval>trim</eval> + </config> </settings.limit> <settings.highlight> - <TCEforms> - <exclude>1</exclude> - <label>Highlights only</label> - <config> - <type>check</type> - <default>0</default> - </config> - </TCEforms> + <exclude>1</exclude> + <label>Highlights only</label> + <config> + <type>check</type> + <default>0</default> + </config> </settings.highlight> <settings.todayOnly> - <TCEforms> - <exclude>1</exclude> - <label>Today only</label> - <config> - <type>check</type> - <default>0</default> - </config> - </TCEforms> + <exclude>1</exclude> + <label>Today only</label> + <config> + <type>check</type> + <default>0</default> + </config> </settings.todayOnly> <settings.pagination> - <TCEforms> - <exclude>1</exclude> - <label>Show pagination</label> - <config> - <type>check</type> - <default>0</default> - </config> - </TCEforms> + <exclude>1</exclude> + <label>Show pagination</label> + <config> + <type>check</type> + <default>0</default> + </config> </settings.pagination> <settings.showPID> - <TCEforms> - <exclude>1</exclude> - <label>Detail page</label> - <config> - <type>group</type> - <internal_type>db</internal_type> - <allowed>pages</allowed> - <size>1</size> - <maxitems>1</maxitems> - <minitems>0</minitems> - <show_thumbs>1</show_thumbs> - </config> - </TCEforms> + <exclude>1</exclude> + <label>Detail page</label> + <config> + <type>group</type> + <allowed>pages</allowed> + <size>1</size> + <maxitems>1</maxitems> + <minitems>0</minitems> + <show_thumbs>1</show_thumbs> + </config> </settings.showPID> </el> </ROOT> </sDEF> <sTemplate> <ROOT> - <TCEforms> - <sheetTitle>Template</sheetTitle> - </TCEforms> + <sheetTitle>Template</sheetTitle> <type>array</type> <el> <settings.template> @@ -133,20 +114,20 @@ <renderType>selectSingle</renderType> <items type="array"> <numIndex index="0" type="array"> - <numIndex index="0">Default</numIndex> - <numIndex index="1">default</numIndex> + <numIndex index="label">Default</numIndex> + <numIndex index="value">default</numIndex> </numIndex> <numIndex index="1" type="array"> - <numIndex index="0">Costum</numIndex> - <numIndex index="1">costum</numIndex> + <numIndex index="label">Custom</numIndex> + <numIndex index="value">costum</numIndex> </numIndex> <numIndex index="2" type="array"> - <numIndex index="0">Table</numIndex> - <numIndex index="1">table</numIndex> + <numIndex index="label">Table</numIndex> + <numIndex index="value">table</numIndex> </numIndex> <numIndex index="3" type="array"> - <numIndex index="0">Grid</numIndex> - <numIndex index="1">grid</numIndex> + <numIndex index="label">Grid</numIndex> + <numIndex index="value">grid</numIndex> </numIndex> </items> <default>default</default> @@ -157,34 +138,29 @@ </sTemplate> <sConstrains> <ROOT> - <TCEforms> - <sheetTitle>Regions & Categories</sheetTitle> - </TCEforms> + <sheetTitle>Regions & Categories</sheetTitle> <type>array</type> <el> <settings.region> - <TCEforms> - <label>Region</label> - <config> - <type>select</type> - <renderType>selectSingle</renderType> - <items type="array"> - <numIndex index="0" type="array"> - <numIndex index="0">Alle</numIndex> - <numIndex index="1"></numIndex> - </numIndex> - </items> - <foreign_table>tx_events_domain_model_region</foreign_table> - <foreign_table_where>AND tx_events_domain_model_region.deleted = 0 AND tx_events_domain_model_region.hidden = 0</foreign_table_where> - <size>1</size> - <minitems>0</minitems> - <maxitems>1</maxitems> - </config> - </TCEforms> + <label>Region</label> + <config> + <type>select</type> + <renderType>selectSingle</renderType> + <items type="array"> + <numIndex index="0" type="array"> + <numIndex index="label">Alle</numIndex> + <numIndex index="value"></numIndex> + </numIndex> + </items> + <foreign_table>tx_events_domain_model_region</foreign_table> + <foreign_table_where>AND tx_events_domain_model_region.deleted = 0 AND tx_events_domain_model_region.hidden = 0</foreign_table_where> + <size>1</size> + <minitems>0</minitems> + <maxitems>1</maxitems> + </config> </settings.region> <settings.categoryCombination> - <TCEforms> <exclude>1</exclude> <label>Combination</label> <config> @@ -192,54 +168,49 @@ <renderType>selectSingle</renderType> <items type="array"> <numIndex index="0" type="array"> - <numIndex index="0">And</numIndex> - <numIndex index="1">0</numIndex> + <numIndex index="label">And</numIndex> + <numIndex index="value">0</numIndex> </numIndex> <numIndex index="1" type="array"> - <numIndex index="0">Or</numIndex> - <numIndex index="1">1</numIndex> + <numIndex index="label">Or</numIndex> + <numIndex index="value">1</numIndex> </numIndex> </items> <default>0</default> </config> - </TCEforms> </settings.categoryCombination> <settings.categories> - <TCEforms> - <exclude>1</exclude> - <label> - Category - </label> - <config> - <type>select</type> - <renderType>selectTree</renderType> - <autoSizeMax>20</autoSizeMax> - <foreign_table>sys_category</foreign_table> - <foreign_table_where> AND sys_category.sys_language_uid IN (-1, 0) ORDER BY sys_category.title ASC</foreign_table_where> - <maxitems>1</maxitems> - <renderMode>tree</renderMode> - <size>8</size> - <treeConfig> - <appearance> - <expandAll>1</expandAll> - <showHeader>1</showHeader> - </appearance> - <parentField>parent</parentField> - </treeConfig> - </config> - </TCEforms> + <exclude>1</exclude> + <label> + Category + </label> + <config> + <type>select</type> + <renderType>selectTree</renderType> + <autoSizeMax>20</autoSizeMax> + <foreign_table>sys_category</foreign_table> + <foreign_table_where> AND sys_category.sys_language_uid IN (-1, 0) ORDER BY sys_category.title ASC</foreign_table_where> + <maxitems>1</maxitems> + <renderMode>tree</renderMode> + <size>8</size> + <treeConfig> + <appearance> + <expandAll>1</expandAll> + <showHeader>1</showHeader> + </appearance> + <parentField>parent</parentField> + </treeConfig> + </config> </settings.categories> <settings.includeSubcategories> - <TCEforms> <exclude>1</exclude> <label>Include Subcategories</label> <config> <type>check</type> <default>0</default> </config> - </TCEforms> </settings.includeSubcategories> </el> </ROOT> diff --git a/Configuration/FlexForms/DateSearch.xml b/Configuration/FlexForms/DateSearch.xml index ae07a9f..9f1d25b 100644 --- a/Configuration/FlexForms/DateSearch.xml +++ b/Configuration/FlexForms/DateSearch.xml @@ -2,38 +2,31 @@ <sheets> <sSearch> <ROOT> - <TCEforms> - <sheetTitle>Options</sheetTitle> - </TCEforms> + <sheetTitle>Options</sheetTitle> <type>array</type> <el> <settings.pageUid> - <TCEforms> - <exclude>1</exclude> - <label>Results page</label> - <config> - <type>group</type> - <internal_type>db</internal_type> - <allowed>pages</allowed> - <size>1</size> - <maxitems>1</maxitems> - <minitems>0</minitems> - <show_thumbs>1</show_thumbs> - </config> - </TCEforms> + <exclude>1</exclude> + <label>Results page</label> + <config> + <type>group</type> + <allowed>pages</allowed> + <size>1</size> + <maxitems>1</maxitems> + <minitems>0</minitems> + <show_thumbs>1</show_thumbs> + </config> </settings.pageUid> <settings.showRegions> - <TCEforms> - <exclude>1</exclude> - <label>Show Regions</label> - <config> - <type>check</type> - <default>0</default> - </config> - </TCEforms> + <exclude>1</exclude> + <label>Show Regions</label> + <config> + <type>check</type> + <default>0</default> + </config> </settings.showRegions> </el> </ROOT> </sSearch> </sheets> -</T3DataStructure> \ No newline at end of file +</T3DataStructure> diff --git a/Configuration/FlexForms/DateShow.xml b/Configuration/FlexForms/DateShow.xml index b3eea3d..998671e 100644 --- a/Configuration/FlexForms/DateShow.xml +++ b/Configuration/FlexForms/DateShow.xml @@ -2,34 +2,27 @@ <sheets> <sDEF> <ROOT> - <TCEforms> - <sheetTitle>Options</sheetTitle> - </TCEforms> + <sheetTitle>Options</sheetTitle> <type>array</type> <el> <settings.backPID> - <TCEforms> <exclude>1</exclude> <label>Back page</label> <config> <type>group</type> - <internal_type>db</internal_type> <allowed>pages</allowed> <size>1</size> <maxitems>1</maxitems> <minitems>0</minitems> <show_thumbs>1</show_thumbs> - </config> - </TCEforms> + </config> </settings.backPID> </el> </ROOT> </sDEF> <sTemplate> <ROOT> - <TCEforms> - <sheetTitle>Template</sheetTitle> - </TCEforms> + <sheetTitle>Template</sheetTitle> <type>array</type> <el> <settings.template> @@ -39,12 +32,12 @@ <type>select</type> <items type="array"> <numIndex index="0" type="array"> - <numIndex index="0">Default</numIndex> - <numIndex index="1">default</numIndex> + <numIndex index="label">Default</numIndex> + <numIndex index="value">default</numIndex> </numIndex> <numIndex index="1" type="array"> - <numIndex index="0">Costum</numIndex> - <numIndex index="1">costum</numIndex> + <numIndex index="label">Custom</numIndex> + <numIndex index="value">costum</numIndex> </numIndex> </items> <default>default</default> @@ -54,4 +47,4 @@ </ROOT> </sTemplate> </sheets> -</T3DataStructure> \ No newline at end of file +</T3DataStructure> diff --git a/Configuration/FlexForms/Selected.xml b/Configuration/FlexForms/Selected.xml index d4a590e..43cb7e4 100644 --- a/Configuration/FlexForms/Selected.xml +++ b/Configuration/FlexForms/Selected.xml @@ -5,17 +5,14 @@ <type>array</type> <el> <settings.selectedRecords> - <TCEforms> - <exclude>1</exclude> - <label>LLL:EXT:events/Resources/Private/Language/de.locallang_db.xlf:tx_events.flexform.selected.selectedRecords</label> - <config> - <type>group</type> - <internal_type>db</internal_type> - <allowed>tx_events_domain_model_event</allowed> - <minitems>1</minitems> - <show_thumbs>1</show_thumbs> - </config> - </TCEforms> + <exclude>1</exclude> + <label>LLL:EXT:events/Resources/Private/Language/de.locallang_db.xlf:tx_events.flexform.selected.selectedRecords</label> + <config> + <type>group</type> + <allowed>tx_events_domain_model_event</allowed> + <minitems>1</minitems> + <show_thumbs>1</show_thumbs> + </config> </settings.selectedRecords> </el> </ROOT> diff --git a/Configuration/Icons.php b/Configuration/Icons.php new file mode 100644 index 0000000..3e2cb5d --- /dev/null +++ b/Configuration/Icons.php @@ -0,0 +1,16 @@ +<?php + +declare(strict_types=1); + +use TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider; + +return [ + 'events-plugin' => [ + 'provider' => SvgIconProvider::class, + 'source' => 'EXT:events/Resources/Public/Icons/Extension.svg', + ], + 'pages-module-events' => [ + 'provider' => SvgIconProvider::class, + 'source' => 'EXT:events/Resources/Public/Icons/Folder.svg', + ], +]; diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index a5090de..cf06b5a 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -43,7 +43,12 @@ services: WerkraumMedia\Events\Updates\MigrateOldLocations: public: true + WerkraumMedia\Events\Service\DestinationDataImportService\ConfigurationServiceInterface: + alias: 'WerkraumMedia\Events\Service\DestinationDataImportService\ExtbaseConfigurationService' + WerkraumMedia\Events\Caching\PageCacheTimeout: + arguments: + '$runtimeCache': '@cache.runtime' tags: - name: event.listener event: WerkraumMedia\Events\Events\Controller\DateListVariables diff --git a/Configuration/TCA/Overrides/tt_content.php b/Configuration/TCA/Overrides/tt_content.php index dcd3619..08a854a 100644 --- a/Configuration/TCA/Overrides/tt_content.php +++ b/Configuration/TCA/Overrides/tt_content.php @@ -7,54 +7,58 @@ use TYPO3\CMS\Extbase\Utility\ExtensionUtility; (function (string $extKey, string $table) { /* Search Plugin */ - ExtensionUtility::registerPlugin( + $pluginSignature = ExtensionUtility::registerPlugin( 'Events', 'DateSearch', 'Events: Date Search', - 'EXT:events/Resources/Public/Icons/Extension.svg' + 'events-plugin' ); - $GLOBALS['TCA'][$table]['types']['list']['subtypes_addlist']['events_datesearch'] = 'pi_flexform'; + ExtensionManagementUtility::addToAllTCAtypes($table, 'pi_flexform', $pluginSignature, 'after:subheader'); ExtensionManagementUtility::addPiFlexFormValue( - 'events_datesearch', - 'FILE:EXT:events/Configuration/FlexForms/DateSearch.xml' + '*', + 'FILE:EXT:events/Configuration/FlexForms/DateSearch.xml', + $pluginSignature, ); /* Date List Plugin */ - ExtensionUtility::registerPlugin( + $pluginSignature = ExtensionUtility::registerPlugin( 'Events', 'DateList', 'Events: Date List', - 'EXT:events/Resources/Public/Icons/Extension.svg' + 'events-plugin' ); - $GLOBALS['TCA'][$table]['types']['list']['subtypes_addlist']['events_datelist'] = 'pi_flexform'; + ExtensionManagementUtility::addToAllTCAtypes($table, 'pi_flexform', $pluginSignature, 'after:subheader'); ExtensionManagementUtility::addPiFlexFormValue( - 'events_datelist', - 'FILE:EXT:events/Configuration/FlexForms/DateList.xml' + '*', + 'FILE:EXT:events/Configuration/FlexForms/DateList.xml', + $pluginSignature, ); /* Date Show Plugin */ - ExtensionUtility::registerPlugin( + $pluginSignature = ExtensionUtility::registerPlugin( 'Events', 'DateShow', 'Events: Date Show', - 'EXT:events/Resources/Public/Icons/Extension.svg' + 'events-plugin' ); - $GLOBALS['TCA'][$table]['types']['list']['subtypes_addlist']['events_dateshow'] = 'pi_flexform'; + ExtensionManagementUtility::addToAllTCAtypes($table, 'pi_flexform', $pluginSignature, 'after:subheader'); ExtensionManagementUtility::addPiFlexFormValue( + '*', + 'FILE:EXT:events/Configuration/FlexForms/DateShow.xml', 'events_dateshow', - 'FILE:EXT:events/Configuration/FlexForms/DateShow.xml' ); /* Event Selected Plugin */ - ExtensionUtility::registerPlugin( + $pluginSignature = ExtensionUtility::registerPlugin( 'Events', 'Selected', 'Events: Show selected', - 'EXT:events/Resources/Public/Icons/Extension.svg' + 'events-plugin' ); - $GLOBALS['TCA'][$table]['types']['list']['subtypes_addlist']['events_selected'] = 'pi_flexform'; + ExtensionManagementUtility::addToAllTCAtypes($table, 'pi_flexform', $pluginSignature, 'after:subheader'); ExtensionManagementUtility::addPiFlexFormValue( + $pluginSignature, + 'FILE:EXT:events/Configuration/FlexForms/Selected.xml', 'events_selected', - 'FILE:EXT:events/Configuration/FlexForms/Selected.xml' ); })('events', 'tt_content'); diff --git a/Configuration/TCA/tx_events_domain_model_event.php b/Configuration/TCA/tx_events_domain_model_event.php index 5d4f135..f4b9f1d 100644 --- a/Configuration/TCA/tx_events_domain_model_event.php +++ b/Configuration/TCA/tx_events_domain_model_event.php @@ -346,7 +346,6 @@ return [ 'config' => [ 'type' => 'category', 'minitems' => 0, - 'multiple' => true, ], ], 'features' => [ @@ -355,7 +354,6 @@ return [ 'config' => [ 'type' => 'category', 'minitems' => 0, - 'multiple' => true, ], ], 'keywords' => [ @@ -409,6 +407,12 @@ return [ 'default' => 0, 'minitems' => 0, 'maxitems' => 1, + 'items' => [ + [ + 'value' => '0', + 'label' => $l10nPath . ':tx_events_domain_model_event.location.0', + ], + ], ], ], 'organizer' => [ @@ -421,6 +425,12 @@ return [ 'default' => 0, 'minitems' => 0, 'maxitems' => 1, + 'items' => [ + [ + 'value' => '0', + 'label' => $l10nPath . ':tx_events_domain_model_event.location.0', + ], + ], ], ], 'region' => [ @@ -433,6 +443,12 @@ return [ 'default' => 0, 'minitems' => 0, 'maxitems' => 1, + 'items' => [ + [ + 'value' => '0', + 'label' => $l10nPath . ':tx_events_domain_model_event.location.0', + ], + ], ], ], diff --git a/Configuration/TCA/tx_events_domain_model_import.php b/Configuration/TCA/tx_events_domain_model_import.php index e7f93cc..bd987ec 100644 --- a/Configuration/TCA/tx_events_domain_model_import.php +++ b/Configuration/TCA/tx_events_domain_model_import.php @@ -26,7 +26,7 @@ return [ '--palette--;;typo3_storage', '--palette--;;categories', '--palette--;;features', - '-palette--;;relations', + '--palette--;;relations', '--div--;LLL:EXT:events/Resources/Private/Language/locallang_csh_import.xlf:tx_events_domain_model_import.div.rest', 'rest_experience', 'rest_search_query', diff --git a/Configuration/TypoScript/constants.typoscript b/Configuration/TypoScript/constants.typoscript index 1f0ccc4..61310cd 100644 --- a/Configuration/TypoScript/constants.typoscript +++ b/Configuration/TypoScript/constants.typoscript @@ -14,7 +14,7 @@ plugin.tx_events { } settings { # cat=plugin.tx_events//a; type=string; label=Default Image - defaultImagePath = typo3conf/ext/events/Resources/Public/Images/default.jpg + defaultImagePath = EXT:events/Resources/Public/Images/default.jpg destinationData { # cat=plugin.tx_events//a; type=string; label=Rest Url restUrl = http://meta.et4.de/rest.ashx/search/ diff --git a/Documentation/Changelog/5.0.0.rst b/Documentation/Changelog/5.0.0.rst new file mode 100644 index 0000000..961363b --- /dev/null +++ b/Documentation/Changelog/5.0.0.rst @@ -0,0 +1,35 @@ +5.0.0 +===== + +Breaking +-------- + +* Only when being on 13.x or higher: + + Content elements are no longer registered as `list` but with their own CType. + An upgrade wizard is provided that can be executed to migrate existing database + entries. + + But custom TypoScript and modifications need to be adopted. + We recommend not to use the provided plugins but build your own tailored content + elements instead. + +Features +-------- + +* Add Support for TYPO3 v13.4 LTS. + +Fixes +----- + +Nothing + +Tasks +----- + +Nothing + +Deprecation +----------- + +Nothing diff --git a/Documentation/Index.rst b/Documentation/Index.rst index 1b1626a..2d56ff9 100644 --- a/Documentation/Index.rst +++ b/Documentation/Index.rst @@ -43,6 +43,8 @@ Table of Contents Settings Changelog + Maintenance + .. toctree:: :hidden: diff --git a/Documentation/Maintenance.rst b/Documentation/Maintenance.rst new file mode 100644 index 0000000..66b4621 --- /dev/null +++ b/Documentation/Maintenance.rst @@ -0,0 +1,16 @@ +Maintenance +=========== + +Migrate to SiteSets +------------------- + +We currently leverage TypoScript for some configuration during import. +This is a bad idea, TypoScript is not intended for this usage. + +We should migrate to Site Sets in the future. +The import should use the page uid for import records to resolve the site and fetch +corresponding settings. +That way the import can provide all the necessary information and can be passed down +to all classes. + + diff --git a/Documentation/Settings.cfg b/Documentation/Settings.cfg deleted file mode 100644 index d05053f..0000000 --- a/Documentation/Settings.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[general] -project = Events Extension -copyright = since 2019 by Dirk Koritnik and Daniel Siepmann - -[html_theme_options] -github_branch = main -github_repository = werkraum-media/events - -project_home = https://github.com/werkraum-media/events/ -project_issues = https://github.com/werkraum-media/events/issues -project_repository = https://github.com/werkraum-media/events/ diff --git a/Documentation/guides.xml b/Documentation/guides.xml new file mode 100644 index 0000000..5a76e16 --- /dev/null +++ b/Documentation/guides.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<guides + xmlns="https://www.phpdoc.org/guides" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="https://www.phpdoc.org/guides ../vendor/phpdocumentor/guides-cli/resources/schema/guides.xsd" + links-are-relative="true" +> + <extension + class="\T3Docs\Typo3DocsTheme\DependencyInjection\Typo3DocsThemeExtension" + project-home="https://github.com/werkraum-media/events/" + project-repository="https://github.com/werkraum-media/events/" + project-issues="https://github.com/werkraum-media/events/issues" + edit-on-github-branch="main" + edit-on-github="werkraum-media/events" + typo3-core-preferred="stable" + /> + <project + title="Events Extension" + copyright="since 2019 by Dirk Koritnik and Daniel Siepmann" + /> +</guides> diff --git a/Resources/Private/Language/de.locallang_csh_event.xlf b/Resources/Private/Language/de.locallang_csh_event.xlf index ef1cc27..149b3d2 100644 --- a/Resources/Private/Language/de.locallang_csh_event.xlf +++ b/Resources/Private/Language/de.locallang_csh_event.xlf @@ -123,14 +123,26 @@ <source>Location</source> <target>Veranstaltungsort</target> </trans-unit> + <trans-unit id="tx_events_domain_model_event.location.0"> + <source>None</source> + <target>Keine</target> + </trans-unit> <trans-unit id="tx_events_domain_model_event.organizer"> <source>Organizer</source> <target>Organisator</target> </trans-unit> + <trans-unit id="tx_events_domain_model_event.organizer.0"> + <source>None</source> + <target>Keiner</target> + </trans-unit> <trans-unit id="tx_events_domain_model_event.region"> <source>Region</source> <target>Region</target> </trans-unit> + <trans-unit id="tx_events_domain_model_event.region.0"> + <source>None</source> + <target>Keine</target> + </trans-unit> <trans-unit id="tx_events_domain_model_organizer"> <source>Organizer</source> <target>Organisator</target> diff --git a/Resources/Private/Language/locallang_csh_event.xlf b/Resources/Private/Language/locallang_csh_event.xlf index 9ef979d..bd1575c 100644 --- a/Resources/Private/Language/locallang_csh_event.xlf +++ b/Resources/Private/Language/locallang_csh_event.xlf @@ -93,12 +93,21 @@ <trans-unit id="tx_events_domain_model_event.location"> <source>Location</source> </trans-unit> + <trans-unit id="tx_events_domain_model_event.location.0"> + <source>None</source> + </trans-unit> <trans-unit id="tx_events_domain_model_event.organizer"> <source>Organizer</source> </trans-unit> + <trans-unit id="tx_events_domain_model_event.organizer.0"> + <source>None</source> + </trans-unit> <trans-unit id="tx_events_domain_model_event.region"> <source>Region</source> </trans-unit> + <trans-unit id="tx_events_domain_model_event.region.0"> + <source>None</source> + </trans-unit> <trans-unit id="tx_events_domain_model_event.partner"> <source>Partner</source> </trans-unit> diff --git a/Tests/Functional/AbstractFunctionalTestCase.php b/Tests/Functional/AbstractFunctionalTestCase.php index 536ac7c..92d57b0 100644 --- a/Tests/Functional/AbstractFunctionalTestCase.php +++ b/Tests/Functional/AbstractFunctionalTestCase.php @@ -149,6 +149,7 @@ abstract class AbstractFunctionalTestCase extends FunctionalTestCase array $argumentsAndOptions = ['configurationUid' => '1'], string $command = ImportDestinationDataViaConfigruationCommand::class ): CommandTester { + GeneralUtility::setContainer($this->getcontainer()); $subject = $this->get($command); self::assertInstanceOf(Command::class, $subject); diff --git a/Tests/Functional/Frontend/CacheTest.php b/Tests/Functional/Frontend/CacheTest.php index a2d7b32..c9a634d 100644 --- a/Tests/Functional/Frontend/CacheTest.php +++ b/Tests/Functional/Frontend/CacheTest.php @@ -68,8 +68,7 @@ class CacheTest extends AbstractFunctionalTestCase (new PhpDataSet())->import(['tt_content' => [[ 'uid' => '1', 'pid' => '1', - 'CType' => 'list', - 'list_type' => 'events_datelisttest', + 'CType' => 'events_datelisttest', 'header' => 'All Dates', ]]]); $this->setUpFrontendRendering(); @@ -306,7 +305,7 @@ class CacheTest extends AbstractFunctionalTestCase // We might be seconds off due to our created offset within the rendering. $value = (int)$value; $age = ((int)$end->format('U')) - time(); - self::assertLessThanOrEqual($age + 3, $value, 'Max age of cached response is higher than expected.'); + self::assertLessThanOrEqual($age + 4, $value, 'Max age of cached response is higher than expected.'); self::assertGreaterThanOrEqual($age - 3, $value, 'Max age of cached response is less than expected.'); } diff --git a/Tests/Functional/Frontend/DatesTestFixtures/DateMetaTags.php b/Tests/Functional/Frontend/DatesTestFixtures/DateMetaTags.php index e6d7eff..610be32 100644 --- a/Tests/Functional/Frontend/DatesTestFixtures/DateMetaTags.php +++ b/Tests/Functional/Frontend/DatesTestFixtures/DateMetaTags.php @@ -7,8 +7,7 @@ return [ 0 => [ 'uid' => '1', 'pid' => '1', - 'CType' => 'list', - 'list_type' => 'events_dateshow', + 'CType' => 'events_dateshow', 'header' => 'Singleview', ], ], diff --git a/Tests/Functional/Frontend/DatesTestFixtures/DateOpenGraphTags.php b/Tests/Functional/Frontend/DatesTestFixtures/DateOpenGraphTags.php index 845d7e1..dc6aad1 100644 --- a/Tests/Functional/Frontend/DatesTestFixtures/DateOpenGraphTags.php +++ b/Tests/Functional/Frontend/DatesTestFixtures/DateOpenGraphTags.php @@ -7,8 +7,7 @@ return [ 0 => [ 'uid' => '1', 'pid' => '1', - 'CType' => 'list', - 'list_type' => 'events_dateshow', + 'CType' => 'events_dateshow', 'header' => 'Singleview', ], ], diff --git a/Tests/Functional/Frontend/DatesTestFixtures/DatePageTitle.php b/Tests/Functional/Frontend/DatesTestFixtures/DatePageTitle.php index ce6fbfd..b0e07c7 100644 --- a/Tests/Functional/Frontend/DatesTestFixtures/DatePageTitle.php +++ b/Tests/Functional/Frontend/DatesTestFixtures/DatePageTitle.php @@ -7,8 +7,7 @@ return [ 0 => [ 'uid' => '1', 'pid' => '1', - 'CType' => 'list', - 'list_type' => 'events_dateshow', + 'CType' => 'events_dateshow', 'header' => 'Singleview', ], ], diff --git a/Tests/Functional/Frontend/DatesTestFixtures/DateSocialMediaTags.php b/Tests/Functional/Frontend/DatesTestFixtures/DateSocialMediaTags.php index f98a775..88269de 100644 --- a/Tests/Functional/Frontend/DatesTestFixtures/DateSocialMediaTags.php +++ b/Tests/Functional/Frontend/DatesTestFixtures/DateSocialMediaTags.php @@ -7,8 +7,7 @@ return [ 0 => [ 'uid' => '1', 'pid' => '1', - 'CType' => 'list', - 'list_type' => 'events_dateshow', + 'CType' => 'events_dateshow', 'header' => 'Singleview', ], ], diff --git a/Tests/Functional/Frontend/DatesTestFixtures/Returns404IfEventIsHidden.php b/Tests/Functional/Frontend/DatesTestFixtures/Returns404IfEventIsHidden.php index 76806af..27002f1 100644 --- a/Tests/Functional/Frontend/DatesTestFixtures/Returns404IfEventIsHidden.php +++ b/Tests/Functional/Frontend/DatesTestFixtures/Returns404IfEventIsHidden.php @@ -7,8 +7,7 @@ return [ 0 => [ 'uid' => '1', 'pid' => '1', - 'CType' => 'list', - 'list_type' => 'events_dateshow', + 'CType' => 'events_dateshow', 'header' => 'Singleview', ], ], diff --git a/Tests/Functional/Frontend/DatesTestFixtures/ReturnsDateWithinTimeSpan.php b/Tests/Functional/Frontend/DatesTestFixtures/ReturnsDateWithinTimeSpan.php index f45d593..91ef7af 100644 --- a/Tests/Functional/Frontend/DatesTestFixtures/ReturnsDateWithinTimeSpan.php +++ b/Tests/Functional/Frontend/DatesTestFixtures/ReturnsDateWithinTimeSpan.php @@ -7,8 +7,7 @@ return [ 0 => [ 'uid' => '1', 'pid' => '1', - 'CType' => 'list', - 'list_type' => 'events_datelist', + 'CType' => 'events_datelist', 'header' => 'All Dates', ], ], diff --git a/Tests/Functional/Frontend/DatesTestFixtures/ReturnsOnlyDatesWithAvailableEventByDemand.php b/Tests/Functional/Frontend/DatesTestFixtures/ReturnsOnlyDatesWithAvailableEventByDemand.php index b3d290a..147f48d 100644 --- a/Tests/Functional/Frontend/DatesTestFixtures/ReturnsOnlyDatesWithAvailableEventByDemand.php +++ b/Tests/Functional/Frontend/DatesTestFixtures/ReturnsOnlyDatesWithAvailableEventByDemand.php @@ -7,8 +7,7 @@ return [ 0 => [ 'uid' => '1', 'pid' => '1', - 'CType' => 'list', - 'list_type' => 'events_datelist', + 'CType' => 'events_datelist', 'header' => 'All Dates', ], ], diff --git a/Tests/Functional/Frontend/DatesTestFixtures/ReturnsUpcomingDates.php b/Tests/Functional/Frontend/DatesTestFixtures/ReturnsUpcomingDates.php index 44309cb..fec3e8c 100644 --- a/Tests/Functional/Frontend/DatesTestFixtures/ReturnsUpcomingDates.php +++ b/Tests/Functional/Frontend/DatesTestFixtures/ReturnsUpcomingDates.php @@ -7,8 +7,7 @@ return [ [ 'uid' => 1, 'pid' => 1, - 'CType' => 'list', - 'list_type' => 'events_datelist', + 'CType' => 'events_datelist', 'header' => 'Upcoming Dates', ], ], diff --git a/Tests/Functional/Frontend/EventsTestFixtures/EventMetaTags.php b/Tests/Functional/Frontend/EventsTestFixtures/EventMetaTags.php index 34e69ca..06950a1 100644 --- a/Tests/Functional/Frontend/EventsTestFixtures/EventMetaTags.php +++ b/Tests/Functional/Frontend/EventsTestFixtures/EventMetaTags.php @@ -7,8 +7,7 @@ return [ 0 => [ 'uid' => '1', 'pid' => '1', - 'CType' => 'list', - 'list_type' => 'events_eventshow', + 'CType' => 'events_eventshow', 'header' => 'Singleview', ], ], diff --git a/Tests/Functional/Frontend/EventsTestFixtures/EventOpenGraphTags.php b/Tests/Functional/Frontend/EventsTestFixtures/EventOpenGraphTags.php index d0a22e2..43baf91 100644 --- a/Tests/Functional/Frontend/EventsTestFixtures/EventOpenGraphTags.php +++ b/Tests/Functional/Frontend/EventsTestFixtures/EventOpenGraphTags.php @@ -7,8 +7,7 @@ return [ 0 => [ 'uid' => '1', 'pid' => '1', - 'CType' => 'list', - 'list_type' => 'events_eventshow', + 'CType' => 'events_eventshow', 'header' => 'Singleview', ], ], diff --git a/Tests/Functional/Frontend/EventsTestFixtures/EventPageTitle.php b/Tests/Functional/Frontend/EventsTestFixtures/EventPageTitle.php index 0d3ff66..65c25af 100644 --- a/Tests/Functional/Frontend/EventsTestFixtures/EventPageTitle.php +++ b/Tests/Functional/Frontend/EventsTestFixtures/EventPageTitle.php @@ -7,8 +7,7 @@ return [ 0 => [ 'uid' => '1', 'pid' => '1', - 'CType' => 'list', - 'list_type' => 'events_eventshow', + 'CType' => 'events_eventshow', 'header' => 'Singleview', ], ], diff --git a/Tests/Functional/Frontend/EventsTestFixtures/EventSocialMediaTags.php b/Tests/Functional/Frontend/EventsTestFixtures/EventSocialMediaTags.php index 76be838..cc7d1cc 100644 --- a/Tests/Functional/Frontend/EventsTestFixtures/EventSocialMediaTags.php +++ b/Tests/Functional/Frontend/EventsTestFixtures/EventSocialMediaTags.php @@ -7,8 +7,7 @@ return [ 0 => [ 'uid' => '1', 'pid' => '1', - 'CType' => 'list', - 'list_type' => 'events_eventshow', + 'CType' => 'events_eventshow', 'header' => 'Singleview', ], ], diff --git a/Tests/Functional/Frontend/Fixtures/Database/FilterByASingleLocationViaFlexform.php b/Tests/Functional/Frontend/Fixtures/Database/FilterByASingleLocationViaFlexform.php index 8b2b415..57dfb84 100644 --- a/Tests/Functional/Frontend/Fixtures/Database/FilterByASingleLocationViaFlexform.php +++ b/Tests/Functional/Frontend/Fixtures/Database/FilterByASingleLocationViaFlexform.php @@ -7,8 +7,7 @@ return [ [ 'pid' => '1', 'uid' => '1', - 'CType' => 'list', - 'list_type' => 'events_datelist', + 'CType' => 'events_datelist', 'header' => 'Kino Events', 'pi_flexform' => '<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <T3FlexForms> diff --git a/Tests/Functional/Frontend/Fixtures/Database/FilterByTwoLocationsViaFlexform.php b/Tests/Functional/Frontend/Fixtures/Database/FilterByTwoLocationsViaFlexform.php index 3c9f90c..ea24c42 100644 --- a/Tests/Functional/Frontend/Fixtures/Database/FilterByTwoLocationsViaFlexform.php +++ b/Tests/Functional/Frontend/Fixtures/Database/FilterByTwoLocationsViaFlexform.php @@ -7,8 +7,7 @@ return [ [ 'pid' => '1', 'uid' => '1', - 'CType' => 'list', - 'list_type' => 'events_datelist', + 'CType' => 'events_datelist', 'header' => 'Kino Events', 'pi_flexform' => '<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <T3FlexForms> diff --git a/Tests/Functional/Frontend/Fixtures/Database/FilterDatesByParentLocationViaFlexform.php b/Tests/Functional/Frontend/Fixtures/Database/FilterDatesByParentLocationViaFlexform.php index 1301ee4..ca2385e 100644 --- a/Tests/Functional/Frontend/Fixtures/Database/FilterDatesByParentLocationViaFlexform.php +++ b/Tests/Functional/Frontend/Fixtures/Database/FilterDatesByParentLocationViaFlexform.php @@ -7,8 +7,7 @@ return [ [ 'pid' => '1', 'uid' => '1', - 'CType' => 'list', - 'list_type' => 'events_datelist', + 'CType' => 'events_datelist', 'header' => 'Kino Events', 'pi_flexform' => '<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <T3FlexForms> diff --git a/Tests/Functional/Frontend/Fixtures/Extensions/example/Classes/UserFunc.php b/Tests/Functional/Frontend/Fixtures/Extensions/example/Classes/UserFunc.php index 2f0c82e..b7458bc 100644 --- a/Tests/Functional/Frontend/Fixtures/Extensions/example/Classes/UserFunc.php +++ b/Tests/Functional/Frontend/Fixtures/Extensions/example/Classes/UserFunc.php @@ -23,6 +23,10 @@ declare(strict_types=1); namespace WerkraumMedia\EventsExample; +use Psr\Http\Message\ServerRequestInterface; +use TYPO3\CMS\Core\Context\Context; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Frontend\Cache\CacheLifetimeCalculator; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; @@ -35,9 +39,24 @@ final class UserFunc $this->cObj = $cObj; } - public function accessTsfeTimeout(): string + public function accessTsfeTimeout(string $content, array $configuration, ServerRequestInterface $request): string { - return 'get_cache_timeout: ' . $this->getTsfe()->get_cache_timeout(); + // TODO: typo3/cms-core:14.0 Remove this code block as this won't work since v13.x anymore + if (is_callable([$this->getTsfe(), 'get_cache_timeout'])) { + return 'get_cache_timeout: ' . $this->getTsfe()->get_cache_timeout(); + } + + $pageInformation = $request->getAttribute('frontend.page.information'); + $typoScriptConfigArray = $request->getAttribute('frontend.typoscript')->getConfigArray(); + return 'get_cache_timeout: ' . GeneralUtility::makeInstance(CacheLifetimeCalculator::class) + ->calculateLifetimeForPage( + $pageInformation->getId(), + $pageInformation->getPageRecord(), + $typoScriptConfigArray, + 0, + GeneralUtility::makeInstance(Context::class) + ) + ; } public function sleep(string $content, array $configuration): string diff --git a/Tests/Functional/Frontend/Fixtures/Extensions/example/ext_localconf.php b/Tests/Functional/Frontend/Fixtures/Extensions/example/ext_localconf.php index bc08afe..19900d1 100644 --- a/Tests/Functional/Frontend/Fixtures/Extensions/example/ext_localconf.php +++ b/Tests/Functional/Frontend/Fixtures/Extensions/example/ext_localconf.php @@ -9,11 +9,15 @@ use WerkraumMedia\Events\Controller\EventController; ExtensionUtility::configurePlugin( 'Events', 'DateListTest', - [DateController::class => 'list'] + [DateController::class => 'list'], + [], + ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT, ); ExtensionUtility::configurePlugin( 'Events', 'EventShow', - [EventController::class => 'show'] + [EventController::class => 'show'], + [], + ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT, ); diff --git a/Tests/Functional/Import/DestinationDataTest/Fixtures/Database/FeaturesImportConfiguration.php b/Tests/Functional/Import/DestinationDataTest/Fixtures/Database/FeaturesImportConfiguration.php index 37a5e0a..4e22a76 100644 --- a/Tests/Functional/Import/DestinationDataTest/Fixtures/Database/FeaturesImportConfiguration.php +++ b/Tests/Functional/Import/DestinationDataTest/Fixtures/Database/FeaturesImportConfiguration.php @@ -11,6 +11,7 @@ return [ 'storage_pid' => '2', 'features_pid' => '3', 'features_parent' => '4', + 'files_folder' => '1:/staedte/beispielstadt/events/', ], ], 'pages' => [ diff --git a/Tests/Functional/Import/DestinationDataTest/Fixtures/Database/FirstDateOfRecurringDatesImportConfiguration.php b/Tests/Functional/Import/DestinationDataTest/Fixtures/Database/FirstDateOfRecurringDatesImportConfiguration.php index ff36a9d..7ad2dd2 100644 --- a/Tests/Functional/Import/DestinationDataTest/Fixtures/Database/FirstDateOfRecurringDatesImportConfiguration.php +++ b/Tests/Functional/Import/DestinationDataTest/Fixtures/Database/FirstDateOfRecurringDatesImportConfiguration.php @@ -9,6 +9,7 @@ return [ 'pid' => '2', 'title' => 'Example for test', 'storage_pid' => '2', + 'files_folder' => '1:/staedte/beispielstadt/events/', ], ], 'pages' => [ diff --git a/Tests/Functional/Import/DestinationDataTest/Fixtures/Database/MinimalImportConfiguration.php b/Tests/Functional/Import/DestinationDataTest/Fixtures/Database/MinimalImportConfiguration.php index 8b1c6f8..1af5812 100644 --- a/Tests/Functional/Import/DestinationDataTest/Fixtures/Database/MinimalImportConfiguration.php +++ b/Tests/Functional/Import/DestinationDataTest/Fixtures/Database/MinimalImportConfiguration.php @@ -10,6 +10,7 @@ return [ 'title' => 'Example import configuration', 'storage_pid' => '2', 'rest_experience' => 'beispielstadt', + 'files_folder' => '1:/staedte/beispielstadt/events/', ], ], ]; diff --git a/Tests/Unit/Domain/Model/Dto/DateDemandFactoryTest.php b/Tests/Unit/Domain/Model/Dto/DateDemandFactoryTest.php index a02cf6d..1a5ee43 100644 --- a/Tests/Unit/Domain/Model/Dto/DateDemandFactoryTest.php +++ b/Tests/Unit/Domain/Model/Dto/DateDemandFactoryTest.php @@ -37,7 +37,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function canBeCreated(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -52,7 +52,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function fromSettingsDoesNotThrowUndefinedArrayKeyWarnings(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -69,7 +69,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function searchWordIsSetByRequest(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -91,7 +91,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function synonymsAreSetBySettings(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -130,7 +130,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function categoriesAreSetByRequest(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -157,7 +157,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function featuresAreSetByRequest(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -184,7 +184,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function regionIsSetByRequest(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -212,7 +212,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function regionsAreSetByRequest(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -243,7 +243,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function startIsSetByRequest(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -273,7 +273,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function endIsSetByRequest(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -306,7 +306,7 @@ class DateDemandFactoryTest extends TestCase string $start, string $end ): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -344,7 +344,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function returnsEndsOnSameDayIfBothAreOnSameDay(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -366,7 +366,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function returnsEndsOnSameDayIfBothAreOnDifferentDays(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -389,7 +389,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function returnsHighlightIfSet(mixed $highlight): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -416,7 +416,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function returnsNoHighlightIfNotSet(mixed $highlight): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -443,7 +443,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function returnsOrganizersFromSettings(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService @@ -458,7 +458,7 @@ class DateDemandFactoryTest extends TestCase #[Test] public function returnsOrganizersFromRequest(): void { - $typoScriptService = $this->createStub(TypoScriptService::class); + $typoScriptService = self::createStub(TypoScriptService::class); $subject = new DateDemandFactory( $typoScriptService diff --git a/Tests/Unit/Domain/Model/EventTest.php b/Tests/Unit/Domain/Model/EventTest.php index 589da43..b2e4125 100644 --- a/Tests/Unit/Domain/Model/EventTest.php +++ b/Tests/Unit/Domain/Model/EventTest.php @@ -26,9 +26,9 @@ class EventTest extends TestCase #[Test] public function returnsSortedFeatures(): void { - $feature1 = $this->createStub(Category::class); + $feature1 = self::createStub(Category::class); $feature1->method('getSorting')->willReturn(10); - $feature2 = $this->createStub(Category::class); + $feature2 = self::createStub(Category::class); $feature2->method('getSorting')->willReturn(5); $storage = new ObjectStorage(); diff --git a/Tests/Unit/Domain/Model/ImportTest.php b/Tests/Unit/Domain/Model/ImportTest.php index 9becf22..a17c8da 100644 --- a/Tests/Unit/Domain/Model/ImportTest.php +++ b/Tests/Unit/Domain/Model/ImportTest.php @@ -16,7 +16,7 @@ class ImportTest extends TestCase #[Test] public function canBeCreated(): void { - $folder = $this->createStub(Folder::class); + $folder = self::createStub(Folder::class); $subject = new Import( $folder, @@ -33,7 +33,7 @@ class ImportTest extends TestCase #[Test] public function returnsRestExperience(): void { - $folder = $this->createStub(Folder::class); + $folder = self::createStub(Folder::class); $subject = new Import( $folder, @@ -50,7 +50,7 @@ class ImportTest extends TestCase #[Test] public function returnsStoragePid(): void { - $folder = $this->createStub(Folder::class); + $folder = self::createStub(Folder::class); $subject = new Import( $folder, @@ -67,8 +67,8 @@ class ImportTest extends TestCase #[Test] public function returnsRegion(): void { - $folder = $this->createStub(Folder::class); - $region = $this->createStub(Region::class); + $folder = self::createStub(Folder::class); + $region = self::createStub(Region::class); $subject = new Import( $folder, @@ -91,7 +91,7 @@ class ImportTest extends TestCase #[Test] public function returnsFilesFolder(): void { - $folder = $this->createStub(Folder::class); + $folder = self::createStub(Folder::class); $subject = new Import( $folder, @@ -108,7 +108,7 @@ class ImportTest extends TestCase #[Test] public function returnsCategoriesPid(): void { - $folder = $this->createStub(Folder::class); + $folder = self::createStub(Folder::class); $subject = new Import( $folder, @@ -127,8 +127,8 @@ class ImportTest extends TestCase #[Test] public function returnsCategoryParent(): void { - $category = $this->createStub(Category::class); - $folder = $this->createStub(Folder::class); + $category = self::createStub(Category::class); + $folder = self::createStub(Folder::class); $subject = new Import( $folder, @@ -148,7 +148,7 @@ class ImportTest extends TestCase #[Test] public function returnsFeaturesPid(): void { - $folder = $this->createStub(Folder::class); + $folder = self::createStub(Folder::class); $subject = new Import( $folder, @@ -169,8 +169,8 @@ class ImportTest extends TestCase #[Test] public function returnsFeaturesParent(): void { - $feature = $this->createStub(Category::class); - $folder = $this->createStub(Folder::class); + $feature = self::createStub(Category::class); + $folder = self::createStub(Folder::class); $subject = new Import( $folder, @@ -192,7 +192,7 @@ class ImportTest extends TestCase #[Test] public function returnsSearchQuery(): void { - $folder = $this->createStub(Folder::class); + $folder = self::createStub(Folder::class); $subject = new Import( $folder, diff --git a/Tests/Unit/Events/Controller/DateListVariablesTest.php b/Tests/Unit/Events/Controller/DateListVariablesTest.php index 89ccecb..87a2a6e 100644 --- a/Tests/Unit/Events/Controller/DateListVariablesTest.php +++ b/Tests/Unit/Events/Controller/DateListVariablesTest.php @@ -19,8 +19,8 @@ class DateListVariablesTest extends TestCase $subject = new DateListVariables( [], new DateDemand(), - $this->createStub(QueryResult::class), - $this->createStub(PaginationInterface::class) + self::createStub(QueryResult::class), + self::createStub(PaginationInterface::class) ); self::assertInstanceOf( @@ -37,8 +37,8 @@ class DateListVariablesTest extends TestCase 'executed' => '1', ], new DateDemand(), - $this->createStub(QueryResult::class), - $this->createStub(PaginationInterface::class) + self::createStub(QueryResult::class), + self::createStub(PaginationInterface::class) ); self::assertSame( @@ -57,8 +57,8 @@ class DateListVariablesTest extends TestCase [ ], $demand, - $this->createStub(QueryResult::class), - $this->createStub(PaginationInterface::class) + self::createStub(QueryResult::class), + self::createStub(PaginationInterface::class) ); self::assertSame( @@ -70,13 +70,13 @@ class DateListVariablesTest extends TestCase #[Test] public function returnsInitialDates(): void { - $dates = $this->createStub(QueryResult::class); + $dates = self::createStub(QueryResult::class); $subject = new DateListVariables( [ ], new DateDemand(), $dates, - $this->createStub(PaginationInterface::class) + self::createStub(PaginationInterface::class) ); self::assertSame( @@ -89,8 +89,8 @@ class DateListVariablesTest extends TestCase public function returnsInitialVariablesForView(): void { $demand = new DateDemand(); - $dates = $this->createStub(QueryResult::class); - $pagination = $this->createStub(PaginationInterface::class); + $dates = self::createStub(QueryResult::class); + $pagination = self::createStub(PaginationInterface::class); $subject = new DateListVariables( [ 'executed' => '1', @@ -117,8 +117,8 @@ class DateListVariablesTest extends TestCase public function returnsVariablesForViewWithAddedVariables(): void { $demand = new DateDemand(); - $dates = $this->createStub(QueryResult::class); - $pagination = $this->createStub(PaginationInterface::class); + $dates = self::createStub(QueryResult::class); + $pagination = self::createStub(PaginationInterface::class); $subject = new DateListVariables( [ 'executed' => '1', @@ -150,8 +150,8 @@ class DateListVariablesTest extends TestCase public function returnsVariablesForViewWithOverwrittenVariables(): void { $demand = new DateDemand(); - $dates = $this->createStub(QueryResult::class); - $pagination = $this->createStub(PaginationInterface::class); + $dates = self::createStub(QueryResult::class); + $pagination = self::createStub(PaginationInterface::class); $subject = new DateListVariables( [ 'executed' => '1', diff --git a/Tests/Unit/Events/Controller/DateSearchVariablesTest.php b/Tests/Unit/Events/Controller/DateSearchVariablesTest.php index cd82f1f..b61adc4 100644 --- a/Tests/Unit/Events/Controller/DateSearchVariablesTest.php +++ b/Tests/Unit/Events/Controller/DateSearchVariablesTest.php @@ -21,7 +21,7 @@ class DateSearchVariablesTest extends TestCase [ ], new DateDemand(), - $this->createStub(QueryResult::class), + self::createStub(QueryResult::class), [], [] ); @@ -42,7 +42,7 @@ class DateSearchVariablesTest extends TestCase [ ], new DateDemand(), - $this->createStub(QueryResult::class), + self::createStub(QueryResult::class), [], [] ); @@ -65,7 +65,7 @@ class DateSearchVariablesTest extends TestCase 'executed' => '1', ], new DateDemand(), - $this->createStub(QueryResult::class), + self::createStub(QueryResult::class), [], [] ); @@ -88,7 +88,7 @@ class DateSearchVariablesTest extends TestCase [ ], $demand, - $this->createStub(QueryResult::class), + self::createStub(QueryResult::class), [], [] ); @@ -102,7 +102,7 @@ class DateSearchVariablesTest extends TestCase #[Test] public function returnsInitialRegions(): void { - $regions = $this->createStub(QueryResult::class); + $regions = self::createStub(QueryResult::class); $subject = new DateSearchVariables( [ ], @@ -129,7 +129,7 @@ class DateSearchVariablesTest extends TestCase [ ], new DateDemand(), - $this->createStub(QueryResult::class), + self::createStub(QueryResult::class), [ ['example category'], ], @@ -153,7 +153,7 @@ class DateSearchVariablesTest extends TestCase [ ], new DateDemand(), - $this->createStub(QueryResult::class), + self::createStub(QueryResult::class), [ ], [ @@ -173,7 +173,7 @@ class DateSearchVariablesTest extends TestCase public function returnsInitialVariablesForView(): void { $demand = new DateDemand(); - $regions = $this->createStub(QueryResult::class); + $regions = self::createStub(QueryResult::class); $subject = new DateSearchVariables( [ ], @@ -212,7 +212,7 @@ class DateSearchVariablesTest extends TestCase public function returnsVariablesForViewWithAddedVariables(): void { $demand = new DateDemand(); - $regions = $this->createStub(QueryResult::class); + $regions = self::createStub(QueryResult::class); $subject = new DateSearchVariables( [ ], @@ -256,7 +256,7 @@ class DateSearchVariablesTest extends TestCase public function returnsVariablesForViewWithOverwrittenVariables(): void { $demand = new DateDemand(); - $regions = $this->createStub(QueryResult::class); + $regions = self::createStub(QueryResult::class); $subject = new DateSearchVariables( [ ], diff --git a/Tests/Unit/Service/DestinationDataImportService/DatesFactoryTest.php b/Tests/Unit/Service/DestinationDataImportService/DatesFactoryTest.php index 561cd42..0067893 100644 --- a/Tests/Unit/Service/DestinationDataImportService/DatesFactoryTest.php +++ b/Tests/Unit/Service/DestinationDataImportService/DatesFactoryTest.php @@ -22,13 +22,13 @@ class DatesFactoryTest extends TestCase private function createTestSubject( string $contextDate ): DatesFactory { - $logger = $this->createStub(Logger::class); - $logManager = $this->createStub(LogManager::class); + $logger = self::createStub(Logger::class); + $logManager = self::createStub(LogManager::class); $logManager->method('getLogger')->willReturn($logger); return new DatesFactory( $this->createContext(new DateTimeImmutable($contextDate)), - $this->createStub(ConfigurationManager::class), + self::createStub(ConfigurationManager::class), $logManager ); } diff --git a/Tests/Unit/Service/DestinationDataImportService/LocationAssignmentTest.php b/Tests/Unit/Service/DestinationDataImportService/LocationAssignmentTest.php index 7dae8ab..1d16aef 100644 --- a/Tests/Unit/Service/DestinationDataImportService/LocationAssignmentTest.php +++ b/Tests/Unit/Service/DestinationDataImportService/LocationAssignmentTest.php @@ -42,7 +42,7 @@ final class LocationAssignmentTest extends TestCase #[Test] public function canBeCreated(): void { - $repository = $this->createStub(LocationRepository::class); + $repository = self::createStub(LocationRepository::class); $subject = new LocationAssignment( $repository ); @@ -63,7 +63,7 @@ final class LocationAssignmentTest extends TestCase $latitude, $longitude ): void { - $repository = $this->createStub(LocationRepository::class); + $repository = self::createStub(LocationRepository::class); $repository->method('findOneByGlobalId')->willReturn(null); $subject = new LocationAssignment( diff --git a/Tests/Unit/Service/DestinationDataImportService/UrlFactoryTest.php b/Tests/Unit/Service/DestinationDataImportService/UrlFactoryTest.php index 8b9e678..df109fb 100644 --- a/Tests/Unit/Service/DestinationDataImportService/UrlFactoryTest.php +++ b/Tests/Unit/Service/DestinationDataImportService/UrlFactoryTest.php @@ -8,8 +8,8 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\Stub; use PHPUnit\Framework\TestCase; -use TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager; use WerkraumMedia\Events\Domain\Model\Import; +use WerkraumMedia\Events\Service\DestinationDataImportService\ArrayBasedConfigurationService; use WerkraumMedia\Events\Service\DestinationDataImportService\UrlFactory; class UrlFactoryTest extends TestCase @@ -17,8 +17,7 @@ class UrlFactoryTest extends TestCase #[Test] public function canBeCreated(): void { - $configurationManager = $this->createStub(BackendConfigurationManager::class); - $configurationManager->method('getConfiguration')->willReturn([]); + $configurationManager = new ArrayBasedConfigurationService([]); $subject = new UrlFactory( $configurationManager @@ -37,8 +36,7 @@ class UrlFactoryTest extends TestCase array $settings, string $expectedResult ): void { - $configurationManager = $this->createStub(BackendConfigurationManager::class); - $configurationManager->method('getConfiguration')->willReturn(['settings' => ['destinationData' => $settings]]); + $configurationManager = new ArrayBasedConfigurationService($settings); $subject = new UrlFactory( $configurationManager diff --git a/composer.json b/composer.json index 38ef959..2bce866 100644 --- a/composer.json +++ b/composer.json @@ -21,14 +21,14 @@ "require": { "php": "~8.1.0 || ~8.2.0 || ~8.3.0", "symfony/console": "^6.4 || ^7.0", - "symfony/dependency-injection": "^6.4 || ^7.0", - "typo3/cms-core": "^12.4", - "typo3/cms-extbase": "^12.4", - "typo3/cms-filelist": "^12.4", - "typo3/cms-filemetadata": "^12.4", - "typo3/cms-fluid": "^12.4", - "typo3/cms-frontend": "^12.4", - "typo3/cms-install": "^12.4" + "symfony/dependency-injection": "^6.4 || ^7.0 || ^7.1", + "typo3/cms-core": "^12.4 || ^13.4", + "typo3/cms-extbase": "^12.4 || ^13.4", + "typo3/cms-filelist": "^12.4 || ^13.4", + "typo3/cms-filemetadata": "^12.4 || ^13.4", + "typo3/cms-fluid": "^12.4 || ^13.4", + "typo3/cms-frontend": "^12.4 || ^13.4", + "typo3/cms-install": "^12.4 || ^13.4" }, "autoload": { "psr-4": { @@ -69,10 +69,11 @@ "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.10", "phpstan/phpstan-phpunit": "1.3.15", - "saschaegerer/phpstan-typo3": "1.9.0", - "typo3/cms-backend": "^12.4", - "typo3/cms-fluid-styled-content": "^12.4", - "typo3/cms-seo": "^12.4", + "saschaegerer/phpstan-typo3": "^1.10", + "staabm/phpstan-todo-by": "^0.1.28", + "typo3/cms-backend": "^12.4 || ^13.4", + "typo3/cms-fluid-styled-content": "^12.4 || ^13.4", + "typo3/cms-seo": "^12.4 || ^13.4", "typo3/testing-framework": "^8.0" }, "config": { diff --git a/ext_emconf.php b/ext_emconf.php index a79d2f2..87ecdb4 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -9,7 +9,7 @@ $EM_CONF['events'] = [ 'author' => 'Dirk Koritnik, Daniel Siepmann', 'author_email' => 'koritnik@werkraum-media.de, coding@daniel-siepmann.de', 'state' => 'stable', - 'version' => '4.2.1', + 'version' => '5.0.0', 'constraints' => [ 'depends' => [ 'typo3' => '', diff --git a/ext_localconf.php b/ext_localconf.php index 3f4aa83..c49e7a8 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -2,9 +2,6 @@ declare(strict_types=1); -use TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider; -use TYPO3\CMS\Core\Imaging\IconRegistry; -use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Utility\ExtensionUtility; use WerkraumMedia\Events\Controller\DateController; use WerkraumMedia\Events\Controller\EventController; @@ -16,27 +13,32 @@ call_user_func(function () { 'Events', 'DateSearch', [DateController::class => 'search'], - [DateController::class => 'search'] + [DateController::class => 'search'], + ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT ); ExtensionUtility::configurePlugin( 'Events', 'DateList', [DateController::class => 'list'], - [DateController::class => 'list'] + [DateController::class => 'list'], + ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT ); ExtensionUtility::configurePlugin( 'Events', 'DateShow', [DateController::class => 'show'], - [DateController::class => 'show'] + [DateController::class => 'show'], + ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT ); ExtensionUtility::configurePlugin( 'Events', 'Selected', - [EventController::class => 'list'] + [EventController::class => 'list'], + [], + ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT ); if ( @@ -47,16 +49,4 @@ call_user_func(function () { } $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = '^events_search'; - - $iconRegistry = GeneralUtility::makeInstance(IconRegistry::class); - $iconRegistry->registerIcon( - 'events-plugin', - SvgIconProvider::class, - ['source' => 'EXT:events/Resources/Public/Icons/Extension.svg'] - ); - $iconRegistry->registerIcon( - 'pages-module-events', - SvgIconProvider::class, - ['source' => 'EXT:events/Resources/Public/Icons/Folder.svg'] - ); }); diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index a19129b..0670f6e 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -6,13 +6,8 @@ parameters: path: Classes/Controller/DateController.php - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, 'strval' given\\.$#" - count: 1 - path: Classes/Domain/DestinationData/ImportFactory.php - - - - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" - count: 1 + message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(bool\\|float\\|int\\|resource\\|string\\|null\\)\\: string given\\.$#" + count: 2 path: Classes/Domain/DestinationData/ImportFactory.php -