From 8a46930a4f50fe4f5b824b1c2d6d89e623f822e9 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Oct 2024 16:46:35 +0200 Subject: [PATCH 01/49] [TASK] Provide EXT:form in functional tests To workaround testing framework error: ``` TYPO3\TestingFramework\Core\Exception: Package "blog" depends on package "form" which does not exist. ``` --- Tests/Functional/AvatarProvider/GravatarProviderTest.php | 4 ++++ Tests/Functional/Hooks/DataHandlerHookTest.php | 4 ++++ Tests/Functional/Service/SetupServiceTest.php | 4 ++++ Tests/Functional/Updates/AuthorSlugUpdateTest.php | 4 ++++ Tests/Functional/Updates/AvatarProviderUpdateTest.php | 4 ++++ Tests/Functional/Updates/CategorySlugUpdateTest.php | 4 ++++ Tests/Functional/Updates/CategoryTypeUpdateTest.php | 4 ++++ Tests/Functional/Updates/CommentStatusUpdateTest.php | 4 ++++ Tests/Functional/Updates/DatabaseMonthYearUpdateTest.php | 4 ++++ Tests/Functional/Updates/DatabasePublishDateUpdateTest.php | 4 ++++ Tests/Functional/Updates/FeaturedImageUpdateTest.php | 4 ++++ Tests/Functional/Updates/TagSlugUpdateTest.php | 4 ++++ .../ViewHelpers/Data/ContentListOptionsViewHelperTest.php | 4 ++++ Tests/Functional/ViewHelpers/GravatarViewHelperTest.php | 4 ++++ Tests/Functional/ViewHelpers/Link/ArchiveViewHelperTest.php | 4 ++++ Tests/Functional/ViewHelpers/Link/AuthorViewHelperTest.php | 4 ++++ Tests/Functional/ViewHelpers/Link/Be/AuthorViewHelperTest.php | 4 ++++ .../Functional/ViewHelpers/Link/Be/CategoryViewHelperTest.php | 4 ++++ .../Functional/ViewHelpers/Link/Be/CommentViewHelperTest.php | 4 ++++ Tests/Functional/ViewHelpers/Link/Be/PostViewHelperTest.php | 4 ++++ Tests/Functional/ViewHelpers/Link/Be/TagViewHelperTest.php | 4 ++++ Tests/Functional/ViewHelpers/Link/CategoryViewHelperTest.php | 4 ++++ Tests/Functional/ViewHelpers/Link/PostViewHelperTest.php | 4 ++++ Tests/Functional/ViewHelpers/Link/TagViewHelperTest.php | 4 ++++ Tests/Functional/ViewHelpers/Uri/AvatarViewHelperTest.php | 4 ++++ 25 files changed, 100 insertions(+) diff --git a/Tests/Functional/AvatarProvider/GravatarProviderTest.php b/Tests/Functional/AvatarProvider/GravatarProviderTest.php index 38500dea..56588e3a 100644 --- a/Tests/Functional/AvatarProvider/GravatarProviderTest.php +++ b/Tests/Functional/AvatarProvider/GravatarProviderTest.php @@ -16,6 +16,10 @@ class GravatarProviderTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/Hooks/DataHandlerHookTest.php b/Tests/Functional/Hooks/DataHandlerHookTest.php index 3ab1134c..3cd7018d 100644 --- a/Tests/Functional/Hooks/DataHandlerHookTest.php +++ b/Tests/Functional/Hooks/DataHandlerHookTest.php @@ -20,6 +20,10 @@ final class DataHandlerHookTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/Service/SetupServiceTest.php b/Tests/Functional/Service/SetupServiceTest.php index d60a1ac1..033b10ca 100644 --- a/Tests/Functional/Service/SetupServiceTest.php +++ b/Tests/Functional/Service/SetupServiceTest.php @@ -20,6 +20,10 @@ final class SetupServiceTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/Updates/AuthorSlugUpdateTest.php b/Tests/Functional/Updates/AuthorSlugUpdateTest.php index 342bacd9..2f49e64c 100644 --- a/Tests/Functional/Updates/AuthorSlugUpdateTest.php +++ b/Tests/Functional/Updates/AuthorSlugUpdateTest.php @@ -19,6 +19,10 @@ */ final class AuthorSlugUpdateTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/Updates/AvatarProviderUpdateTest.php b/Tests/Functional/Updates/AvatarProviderUpdateTest.php index 3cf51217..92d74d2d 100644 --- a/Tests/Functional/Updates/AvatarProviderUpdateTest.php +++ b/Tests/Functional/Updates/AvatarProviderUpdateTest.php @@ -19,6 +19,10 @@ */ final class AvatarProviderUpdateTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/Updates/CategorySlugUpdateTest.php b/Tests/Functional/Updates/CategorySlugUpdateTest.php index ee137b68..179fa34f 100644 --- a/Tests/Functional/Updates/CategorySlugUpdateTest.php +++ b/Tests/Functional/Updates/CategorySlugUpdateTest.php @@ -19,6 +19,10 @@ */ final class CategorySlugUpdateTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/Updates/CategoryTypeUpdateTest.php b/Tests/Functional/Updates/CategoryTypeUpdateTest.php index 4a677b92..ad79f8c1 100644 --- a/Tests/Functional/Updates/CategoryTypeUpdateTest.php +++ b/Tests/Functional/Updates/CategoryTypeUpdateTest.php @@ -19,6 +19,10 @@ */ final class CategoryTypeUpdateTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/Updates/CommentStatusUpdateTest.php b/Tests/Functional/Updates/CommentStatusUpdateTest.php index 982604df..6220881a 100644 --- a/Tests/Functional/Updates/CommentStatusUpdateTest.php +++ b/Tests/Functional/Updates/CommentStatusUpdateTest.php @@ -19,6 +19,10 @@ */ final class CommentStatusUpdateTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/Updates/DatabaseMonthYearUpdateTest.php b/Tests/Functional/Updates/DatabaseMonthYearUpdateTest.php index 5153808f..1bcd16dc 100644 --- a/Tests/Functional/Updates/DatabaseMonthYearUpdateTest.php +++ b/Tests/Functional/Updates/DatabaseMonthYearUpdateTest.php @@ -19,6 +19,10 @@ */ final class DatabaseMonthYearUpdateTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/Updates/DatabasePublishDateUpdateTest.php b/Tests/Functional/Updates/DatabasePublishDateUpdateTest.php index 13046379..89339fc3 100644 --- a/Tests/Functional/Updates/DatabasePublishDateUpdateTest.php +++ b/Tests/Functional/Updates/DatabasePublishDateUpdateTest.php @@ -19,6 +19,10 @@ */ final class DatabasePublishDateUpdateTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/Updates/FeaturedImageUpdateTest.php b/Tests/Functional/Updates/FeaturedImageUpdateTest.php index 2cb638aa..618335d8 100644 --- a/Tests/Functional/Updates/FeaturedImageUpdateTest.php +++ b/Tests/Functional/Updates/FeaturedImageUpdateTest.php @@ -19,6 +19,10 @@ */ final class FeaturedImageUpdateTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/Updates/TagSlugUpdateTest.php b/Tests/Functional/Updates/TagSlugUpdateTest.php index 8aa64f67..88abf940 100644 --- a/Tests/Functional/Updates/TagSlugUpdateTest.php +++ b/Tests/Functional/Updates/TagSlugUpdateTest.php @@ -19,6 +19,10 @@ */ final class TagSlugUpdateTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/ViewHelpers/Data/ContentListOptionsViewHelperTest.php b/Tests/Functional/ViewHelpers/Data/ContentListOptionsViewHelperTest.php index dfe8cc50..f35ef3af 100644 --- a/Tests/Functional/ViewHelpers/Data/ContentListOptionsViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Data/ContentListOptionsViewHelperTest.php @@ -16,6 +16,10 @@ final class ContentListOptionsViewHelperTest extends SiteBasedTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + /** * @test */ diff --git a/Tests/Functional/ViewHelpers/GravatarViewHelperTest.php b/Tests/Functional/ViewHelpers/GravatarViewHelperTest.php index f2239ed4..c7624161 100644 --- a/Tests/Functional/ViewHelpers/GravatarViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/GravatarViewHelperTest.php @@ -17,6 +17,10 @@ final class GravatarViewHelperTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/ViewHelpers/Link/ArchiveViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/ArchiveViewHelperTest.php index c604c732..ff5d2662 100644 --- a/Tests/Functional/ViewHelpers/Link/ArchiveViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/ArchiveViewHelperTest.php @@ -17,6 +17,10 @@ final class ArchiveViewHelperTest extends SiteBasedTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + /** * @test * @dataProvider renderDataProvider diff --git a/Tests/Functional/ViewHelpers/Link/AuthorViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/AuthorViewHelperTest.php index a526e1e7..e8ca8f36 100644 --- a/Tests/Functional/ViewHelpers/Link/AuthorViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/AuthorViewHelperTest.php @@ -16,6 +16,10 @@ final class AuthorViewHelperTest extends SiteBasedTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + /** * @test * @dataProvider renderDataProvider diff --git a/Tests/Functional/ViewHelpers/Link/Be/AuthorViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/Be/AuthorViewHelperTest.php index cb6e6bf9..c1d90b43 100644 --- a/Tests/Functional/ViewHelpers/Link/Be/AuthorViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/Be/AuthorViewHelperTest.php @@ -23,6 +23,10 @@ final class AuthorViewHelperTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/ViewHelpers/Link/Be/CategoryViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/Be/CategoryViewHelperTest.php index aae85b54..4be80620 100644 --- a/Tests/Functional/ViewHelpers/Link/Be/CategoryViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/Be/CategoryViewHelperTest.php @@ -23,6 +23,10 @@ final class CategoryViewHelperTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/ViewHelpers/Link/Be/CommentViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/Be/CommentViewHelperTest.php index d5f56a17..0bf5a969 100644 --- a/Tests/Functional/ViewHelpers/Link/Be/CommentViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/Be/CommentViewHelperTest.php @@ -23,6 +23,10 @@ final class CommentViewHelperTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/ViewHelpers/Link/Be/PostViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/Be/PostViewHelperTest.php index 7742ce59..45e880f9 100644 --- a/Tests/Functional/ViewHelpers/Link/Be/PostViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/Be/PostViewHelperTest.php @@ -23,6 +23,10 @@ final class PostViewHelperTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/ViewHelpers/Link/Be/TagViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/Be/TagViewHelperTest.php index 2f5af745..77c51218 100644 --- a/Tests/Functional/ViewHelpers/Link/Be/TagViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/Be/TagViewHelperTest.php @@ -23,6 +23,10 @@ final class TagViewHelperTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; diff --git a/Tests/Functional/ViewHelpers/Link/CategoryViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/CategoryViewHelperTest.php index f51efed1..673e4ad5 100644 --- a/Tests/Functional/ViewHelpers/Link/CategoryViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/CategoryViewHelperTest.php @@ -17,6 +17,10 @@ final class CategoryViewHelperTest extends SiteBasedTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + /** * @test * @dataProvider renderDataProvider diff --git a/Tests/Functional/ViewHelpers/Link/PostViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/PostViewHelperTest.php index be656717..3134aa7e 100644 --- a/Tests/Functional/ViewHelpers/Link/PostViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/PostViewHelperTest.php @@ -17,6 +17,10 @@ final class PostViewHelperTest extends SiteBasedTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + /** * @test * @dataProvider renderDataProvider diff --git a/Tests/Functional/ViewHelpers/Link/TagViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/TagViewHelperTest.php index 1dad4429..c5188129 100644 --- a/Tests/Functional/ViewHelpers/Link/TagViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/TagViewHelperTest.php @@ -16,6 +16,10 @@ final class TagViewHelperTest extends SiteBasedTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + /** * @test * @dataProvider renderDataProvider diff --git a/Tests/Functional/ViewHelpers/Uri/AvatarViewHelperTest.php b/Tests/Functional/ViewHelpers/Uri/AvatarViewHelperTest.php index 4ebb89d8..b57dd44b 100644 --- a/Tests/Functional/ViewHelpers/Uri/AvatarViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Uri/AvatarViewHelperTest.php @@ -18,6 +18,10 @@ final class AvatarViewHelperTest extends FunctionalTestCase { + protected array $coreExtensionsToLoad = [ + 'form' + ]; + protected array $testExtensionsToLoad = [ 'typo3conf/ext/blog' ]; From f6c03ac5fac1a7ea56d54a04b37ee2f0b007b789 Mon Sep 17 00:00:00 2001 From: Benni Mack Date: Mon, 9 Sep 2024 09:45:41 +0200 Subject: [PATCH 02/49] [TASK] Prepare README.rst for v13 --- README.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.rst b/README.rst index 54aea493..84373519 100644 --- a/README.rst +++ b/README.rst @@ -53,6 +53,7 @@ Compatibility :header-rows: 1 * - + - v13 - v12 - v11 - v10 @@ -60,7 +61,17 @@ Compatibility - v8 - v7 + * - 13.0.x + - ✔️ + - ✔️ + - + - + - + - + - + * - 12.0.x + - - ✔️ - ✔️ - @@ -69,6 +80,7 @@ Compatibility - * - 11.0.x + - - - ✔️ - ✔️ @@ -77,6 +89,7 @@ Compatibility - * - 10.0.x + - - - - ✔️ @@ -88,6 +101,7 @@ Compatibility - - - + - - ✔️ - - @@ -96,6 +110,7 @@ Compatibility - - - + - - ✔️ - - @@ -105,6 +120,7 @@ Compatibility - - - + - - ✔️ - @@ -114,6 +130,7 @@ Compatibility - - - + - - ✔️ License From 466fc12ba9503bd8794fcb23929791ec76cab22e Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Oct 2024 16:24:10 +0200 Subject: [PATCH 03/49] [TASK] Update github workflows for v13 Do not test mysql 5.7 with v13, but add MySQL 8.4 LTS to the test matrix. --- .github/workflows/ci.yml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e5eb1d68..3f78cce4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,18 +15,14 @@ jobs: strategy: fail-fast: false matrix: - typo3: ['^11', '^12'] - php: ['7.4', '8.0', '8.1', '8.2'] - mysql: ['5.7', '8.0'] + typo3: ['^12', '^13'] + php: ['8.1', '8.2', '8.3'] + mysql: ['5.7', '8.0', '8.4'] exclude: - - typo3: '^11' - mysql: '8.0' - - typo3: '^12' + - typo3: '^13' mysql: '5.7' - - typo3: '^12' - php: '7.4' - - typo3: '^12' - php: '8.0' + - typo3: '^13' + php: '8.1' steps: - id: checkout name: Checkout Code From 02440f4deddd5b3b5ca34215ff1f014377148a5e Mon Sep 17 00:00:00 2001 From: Achim Fritz Date: Fri, 24 May 2024 15:47:06 +0200 Subject: [PATCH 04/49] [TASK] Start v13 migration --- .../Domain/Finisher/CommentFormFinisher.php | 8 +-- Classes/Service/SetupService.php | 13 ++-- Classes/Updates/AbstractUpdate.php | 2 +- Configuration/TCA/Overrides/pages.php | 20 +++--- .../TCA/tx_blog_domain_model_author.php | 34 +++++---- composer.json | 42 +++++------ ext_tables.php | 70 ------------------- 7 files changed, 58 insertions(+), 131 deletions(-) diff --git a/Classes/Domain/Finisher/CommentFormFinisher.php b/Classes/Domain/Finisher/CommentFormFinisher.php index d92d1ebf..f1bea71b 100644 --- a/Classes/Domain/Finisher/CommentFormFinisher.php +++ b/Classes/Domain/Finisher/CommentFormFinisher.php @@ -16,9 +16,9 @@ use T3G\AgencyPack\Blog\Notification\NotificationManager; use T3G\AgencyPack\Blog\Service\CacheService; use T3G\AgencyPack\Blog\Service\CommentService; -use TYPO3\CMS\Core\Messaging\AbstractMessage; use TYPO3\CMS\Core\Messaging\FlashMessage; use TYPO3\CMS\Core\Messaging\FlashMessageService; +use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; use TYPO3\CMS\Extbase\Service\ExtensionService; @@ -36,17 +36,17 @@ class CommentFormFinisher extends AbstractFinisher CommentService::STATE_ERROR => [ 'title' => 'message.addComment.error.title', 'text' => 'message.addComment.error.text', - 'severity' => AbstractMessage::ERROR, + 'severity' => ContextualFeedbackSeverity::ERROR, ], CommentService::STATE_MODERATION => [ 'title' => 'message.addComment.moderation.title', 'text' => 'message.addComment.moderation.text', - 'severity' => AbstractMessage::INFO, + 'severity' => ContextualFeedbackSeverity::INFO, ], CommentService::STATE_SUCCESS => [ 'title' => 'message.addComment.success.title', 'text' => 'message.addComment.success.text', - 'severity' => AbstractMessage::OK, + 'severity' => ContextualFeedbackSeverity::OK, ], ]; diff --git a/Classes/Service/SetupService.php b/Classes/Service/SetupService.php index ffae0e68..0c95ebf3 100644 --- a/Classes/Service/SetupService.php +++ b/Classes/Service/SetupService.php @@ -12,6 +12,7 @@ use T3G\AgencyPack\Blog\Constants; use TYPO3\CMS\Backend\Utility\BackendUtility; +use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\DataHandling\DataHandler; @@ -28,7 +29,7 @@ public function determineBlogSetups(): array ->select('pid') ->addSelectLiteral($queryBuilder->expr()->count('pid', 'cnt')) ->from('pages') - ->where($queryBuilder->expr()->eq('doktype', $queryBuilder->createNamedParameter(Constants::DOKTYPE_BLOG_POST, \PDO::PARAM_INT))) + ->where($queryBuilder->expr()->eq('doktype', $queryBuilder->createNamedParameter(Constants::DOKTYPE_BLOG_POST, Connection::PARAM_INT))) ->groupBy('pid') ->executeQuery() ->fetchAllAssociative(); @@ -39,7 +40,7 @@ public function determineBlogSetups(): array $title = $queryBuilder ->select('title') ->from('pages') - ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($blogUid, \PDO::PARAM_INT))) + ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($blogUid, Connection::PARAM_INT))) ->executeQuery() ->fetchOne(); $rootline = array_reverse(GeneralUtility::makeInstance(RootlineUtility::class, $blogUid)->get()); @@ -84,12 +85,12 @@ public function createBlogSetup(array $data = []): bool $record = $queryBuilder ->select('TSconfig') ->from('pages') - ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($blogRootUid, \PDO::PARAM_INT))) + ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($blogRootUid, Connection::PARAM_INT))) ->executeQuery() ->fetchAssociative(); $queryBuilder->update('pages') ->set('TSconfig', str_replace('NEW_blogFolder', (string)$blogFolderUid, $record['TSconfig'] ?? '')) - ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($blogRootUid, \PDO::PARAM_INT))) + ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($blogRootUid, Connection::PARAM_INT))) ->executeStatement(); $blogSetupRelations = GeneralUtility::getFileAbsFileName('EXT:blog/Configuration/DataHandler/BlogSetupRelations.php'); @@ -112,7 +113,7 @@ public function createBlogSetup(array $data = []): bool $record = $queryBuilder ->select('constants') ->from('sys_template') - ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($sysTemplateUid, \PDO::PARAM_INT))) + ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($sysTemplateUid, Connection::PARAM_INT))) ->executeQuery() ->fetchAssociative(); $queryBuilder @@ -122,7 +123,7 @@ public function createBlogSetup(array $data = []): bool $recordUidArray, $record['constants'] ?? '' )) - ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($sysTemplateUid, \PDO::PARAM_INT))) + ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($sysTemplateUid, Connection::PARAM_INT))) ->executeStatement(); } } diff --git a/Classes/Updates/AbstractUpdate.php b/Classes/Updates/AbstractUpdate.php index 0f564f6f..3ee3fc93 100644 --- a/Classes/Updates/AbstractUpdate.php +++ b/Classes/Updates/AbstractUpdate.php @@ -133,7 +133,7 @@ protected function updateRecord(string $table, int $uid, array $values): void { $queryBuilder = $this->createQueryBuilder($table); $queryBuilder->update($table) - ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT))); + ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid, Connection::PARAM_INT))); foreach ($values as $field => $value) { $queryBuilder->set($field, $value); diff --git a/Configuration/TCA/Overrides/pages.php b/Configuration/TCA/Overrides/pages.php index e57500ac..b813fa53 100644 --- a/Configuration/TCA/Overrides/pages.php +++ b/Configuration/TCA/Overrides/pages.php @@ -194,17 +194,15 @@ ], 'featured_image' => [ 'label' => $ll . 'pages.featured_image', - 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig( - 'featured_image', - [ - 'minitems' => 0, - 'maxitems' => 1, - 'behaviour' => [ - 'allowLanguageSynchronization' => true - ] - ], - $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] - ), + 'config' => [ + 'type' => 'file', + 'minitems' => 0, + 'maxitems' => 1, + 'allowed' => 'common-image-types', + 'behaviour' => [ + 'allowLanguageSynchronization' => true + ] + ], ], 'categories' => [ 'config' => [ diff --git a/Configuration/TCA/tx_blog_domain_model_author.php b/Configuration/TCA/tx_blog_domain_model_author.php index 57ac48ae..619d6752 100644 --- a/Configuration/TCA/tx_blog_domain_model_author.php +++ b/Configuration/TCA/tx_blog_domain_model_author.php @@ -115,27 +115,25 @@ 'image' => [ 'label' => $ll . 'tx_blog_domain_model_author.image', 'displayCond' => 'FIELD:avatar_provider:=:T3G\AgencyPack\Blog\AvatarProvider\ImageProvider', - 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig( - 'image', - [ - 'appearance' => [ - 'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference' - ], - 'overrideChildTca' => [ - 'types' => [ - \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [ - 'showitem' => ' - crop, - --palette--;;filePalette - ' - ], + 'config' => [ + 'type' => 'file', + 'appearance' => [ + 'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference' + ], + 'overrideChildTca' => [ + 'types' => [ + \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [ + 'showitem' => ' + crop, + --palette--;;filePalette + ' ], ], - 'minitems' => 0, - 'maxitems' => 1, ], - $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] - ), + 'minitems' => 0, + 'maxitems' => 1, + 'allowed' => 'common-image-types', + ], 'l10n_mode' => 'exclude', ], 'title' => [ diff --git a/composer.json b/composer.json index f012b655..efaa29c4 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ }, "extra": { "branch-alias": { - "dev-master": "12.0.x-dev" + "dev-master": "13.0.x-dev" }, "typo3/cms": { "extension-key": "blog", @@ -84,20 +84,20 @@ "typo3/cms-fluid-styled-content": "Content rendering definition based on fluid" }, "require": { - "php": "^7.4 || ^8.0", + "php": "^8.1", "ext-json": "*", "ext-pdo": "*", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0", - "typo3/cms-backend": "^11.5 || ^12.4", - "typo3/cms-core": "^11.5 || ^12.4", - "typo3/cms-extbase": "^11.5 || ^12.4", - "typo3/cms-extensionmanager": "^11.5 || ^12.4", - "typo3/cms-fluid": "^11.5 || ^12.4", - "typo3/cms-form": "^11.5 || ^12.4", - "typo3/cms-frontend": "^11.5 || ^12.4", - "typo3/cms-install": "^11.5 || ^12.4", + "psr/http-message": "^2.0", + "typo3/cms-backend": "^12.4 || ^13.1", + "typo3/cms-core": "^12.4 || ^13.1", + "typo3/cms-extbase": "^12.4 || ^13.1", + "typo3/cms-extensionmanager": "^12.4 || ^13.1", + "typo3/cms-fluid": "^12.4 || ^13.1", + "typo3/cms-form": "^12.4 || ^13.1", + "typo3/cms-frontend": "^12.4 || ^13.1", + "typo3/cms-install": "^12.4 || ^13.1", "typo3fluid/fluid": "^2.6" }, "require-dev": { @@ -110,15 +110,15 @@ "phpstan/phpstan-deprecation-rules": "^1.1", "phpstan/phpstan-phpunit": "^1.3", "phpstan/phpstan-strict-rules": "^1.5", - "typo3/cms-belog": "^11.5 || ^12.4", - "typo3/cms-beuser": "^11.5 || ^12.4", - "typo3/cms-filelist": "^11.5 || ^12.4", - "typo3/cms-fluid-styled-content": "^11.5 || ^12.4", - "typo3/cms-lowlevel": "^11.5 || ^12.4", - "typo3/cms-rte-ckeditor": "^11.5 || ^12.4", - "typo3/cms-seo": "^11.5 || ^12.4", - "typo3/cms-setup": "^11.5 || ^12.4", - "typo3/cms-tstemplate": "^11.5 || ^12.4", - "typo3/testing-framework": "^7.0 || ^8.0" + "typo3/cms-belog": "^12.4", + "typo3/cms-beuser": "^12.4", + "typo3/cms-filelist": "^12.4", + "typo3/cms-fluid-styled-content": "^12.4", + "typo3/cms-lowlevel": "^12.4", + "typo3/cms-rte-ckeditor": "^12.4", + "typo3/cms-seo": "^12.4", + "typo3/cms-setup": "^12.4", + "typo3/cms-tstemplate": "^12.4", + "typo3/testing-framework": "^8.0" } } diff --git a/ext_tables.php b/ext_tables.php index 2fdc61d8..7aa2f8e1 100644 --- a/ext_tables.php +++ b/ext_tables.php @@ -8,13 +8,10 @@ */ use T3G\AgencyPack\Blog\Constants; -use T3G\AgencyPack\Blog\Controller\BackendController; use TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider; use TYPO3\CMS\Core\Imaging\IconRegistry; -use TYPO3\CMS\Core\Information\Typo3Version; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Extbase\Utility\ExtensionUtility; if (!defined('TYPO3')) { die('Access denied.'); @@ -70,70 +67,3 @@ ExtensionManagementUtility::addUserTSConfig(' options.pageTree.doktypesToShowInNewPageDragArea := addToList(' . Constants::DOKTYPE_BLOG_POST . ') '); - -if ((GeneralUtility::makeInstance(Typo3Version::class))->getMajorVersion() < 12) { - ExtensionManagementUtility::allowTableOnStandardPages('tx_blog_domain_model_comment'); -} - -if ((GeneralUtility::makeInstance(Typo3Version::class))->getMajorVersion() < 12) { - // Main Blog - ExtensionManagementUtility::addModule( - 'blog', - '', - 'after:web', - null, - [ - 'labels' => 'LLL:EXT:blog/Resources/Private/Language/locallang_mod_blog.xlf', - 'name' => 'blog', - 'iconIdentifier' => 'module-blog', - ] - ); - - // Module Blog > Posts - ExtensionUtility::registerModule( - 'Blog', - 'blog', - 'blog_posts', - '', - [ - BackendController::class => 'posts', - ], - [ - 'labels' => 'LLL:EXT:blog/Resources/Private/Language/locallang_mod_blog_posts.xlf', - 'iconIdentifier' => 'module-blog-posts', - 'access' => 'user,group', - ] - ); - - // Module Blog > Comments - ExtensionUtility::registerModule( - 'Blog', - 'blog', - 'blog_comments', - '', - [ - BackendController::class => 'comments, updateCommentStatus', - ], - [ - 'labels' => 'LLL:EXT:blog/Resources/Private/Language/locallang_mod_blog_comments.xlf', - 'iconIdentifier' => 'module-blog-comments', - 'access' => 'user,group', - ] - ); - - // Module Blog > Setup - ExtensionUtility::registerModule( - 'Blog', - 'blog', - 'blog_setup', - '', - [ - BackendController::class => 'setupWizard, createBlog', - ], - [ - 'labels' => 'LLL:EXT:blog/Resources/Private/Language/locallang_mod_blog_setup.xlf', - 'iconIdentifier' => 'module-blog-setup', - 'access' => 'admin', - ] - ); -} From 964e3d56d10312c9eb6a4ec63b9ee377ca653b39 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Oct 2024 16:46:11 +0200 Subject: [PATCH 05/49] [TASK] Use typo3/testing-framework v9 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index efaa29c4..a40e39b8 100644 --- a/composer.json +++ b/composer.json @@ -119,6 +119,6 @@ "typo3/cms-seo": "^12.4", "typo3/cms-setup": "^12.4", "typo3/cms-tstemplate": "^12.4", - "typo3/testing-framework": "^8.0" + "typo3/testing-framework": "^8.0 || ^9.0" } } From e4f0f0ff455c6954588fdf01d073527114622a78 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Oct 2024 16:51:00 +0200 Subject: [PATCH 06/49] [TASK] Update v13 composer dependencies --- composer.json | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/composer.json b/composer.json index a40e39b8..c22010aa 100644 --- a/composer.json +++ b/composer.json @@ -90,18 +90,18 @@ "psr/http-client": "^1.0", "psr/http-factory": "^1.0", "psr/http-message": "^2.0", - "typo3/cms-backend": "^12.4 || ^13.1", - "typo3/cms-core": "^12.4 || ^13.1", - "typo3/cms-extbase": "^12.4 || ^13.1", - "typo3/cms-extensionmanager": "^12.4 || ^13.1", - "typo3/cms-fluid": "^12.4 || ^13.1", - "typo3/cms-form": "^12.4 || ^13.1", - "typo3/cms-frontend": "^12.4 || ^13.1", - "typo3/cms-install": "^12.4 || ^13.1", - "typo3fluid/fluid": "^2.6" + "typo3/cms-backend": "^12.4 || ^13.4", + "typo3/cms-core": "^12.4 || ^13.4", + "typo3/cms-extbase": "^12.4 || ^13.4", + "typo3/cms-extensionmanager": "^12.4 || ^13.4", + "typo3/cms-fluid": "^12.4 || ^13.4", + "typo3/cms-form": "^12.4 || ^13.4", + "typo3/cms-frontend": "^12.4 || ^13.4", + "typo3/cms-install": "^12.4 || ^13.4", + "typo3fluid/fluid": "^2.15 || ^4.0" }, "require-dev": { - "bk2k/bootstrap-package": "^13.0", + "bk2k/bootstrap-package": "^15.0", "bk2k/extension-helper": "^2.0", "friendsofphp/php-cs-fixer": "^3.14", "friendsoftypo3/phpstan-typo3": "^0.9.0", @@ -110,15 +110,15 @@ "phpstan/phpstan-deprecation-rules": "^1.1", "phpstan/phpstan-phpunit": "^1.3", "phpstan/phpstan-strict-rules": "^1.5", - "typo3/cms-belog": "^12.4", - "typo3/cms-beuser": "^12.4", - "typo3/cms-filelist": "^12.4", - "typo3/cms-fluid-styled-content": "^12.4", - "typo3/cms-lowlevel": "^12.4", - "typo3/cms-rte-ckeditor": "^12.4", - "typo3/cms-seo": "^12.4", - "typo3/cms-setup": "^12.4", - "typo3/cms-tstemplate": "^12.4", + "typo3/cms-belog": "^12.4 || ^13.4", + "typo3/cms-beuser": "^12.4 || ^13.4", + "typo3/cms-filelist": "^12.4 || ^13.4", + "typo3/cms-fluid-styled-content": "^12.4 || ^13.4", + "typo3/cms-lowlevel": "^12.4 || ^13.4", + "typo3/cms-rte-ckeditor": "^12.4 || ^13.4", + "typo3/cms-seo": "^12.4 || ^13.4", + "typo3/cms-setup": "^12.4 || ^13.4", + "typo3/cms-tstemplate": "^12.4 || ^13.4", "typo3/testing-framework": "^8.0 || ^9.0" } } From cf043e387c11952bc9231d90d1821d21389bf2b9 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 15:29:34 +0200 Subject: [PATCH 07/49] [TASK] Mark v13 as supported in ext_emconf --- ext_emconf.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext_emconf.php b/ext_emconf.php index 5317ec76..07bf2292 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -17,8 +17,8 @@ 'version' => '12.0.2', 'constraints' => [ 'depends' => [ - 'typo3' => '11.5.0-12.4.99', - 'form' => '11.5.0-12.4.99', + 'typo3' => '12.4.0-13.4.99', + 'form' => '12.4.0-13.4.99', ], 'conflicts' => [], 'suggests' => [], From 9dedafdb692dde8b39b597f7b4d4abc61b158af1 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 14:06:03 +0200 Subject: [PATCH 08/49] [TASK] Remove outdated post-autoload-dump script Extensions are registered in root automatically since typo3/cms-composer-installers v5 --- composer.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/composer.json b/composer.json index c22010aa..416042ae 100644 --- a/composer.json +++ b/composer.json @@ -50,10 +50,6 @@ } }, "scripts": { - "post-autoload-dump": [ - "[ -d .build/public/_assets ] || mkdir -p .build/public/typo3conf/ext/", - "[ -d .build/public/_assets ] || [ -L .build/public/typo3conf/ext/blog ] || ln -snvf ../../../../. .build/public/typo3conf/ext/blog" - ], "t3g:test:php:lint": [ "phplint" ], From 72506e5b4d7f2a1eb17b3f5641b5725fddfb91cf Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 14:00:26 +0200 Subject: [PATCH 09/49] [TASK] Replace deprecated php-cs-fixer setting function_typehint_space --- .php-cs-fixer.dist.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 5be47068..de19889c 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -54,7 +54,7 @@ 'no_blank_lines_after_phpdoc' => true, 'array_syntax' => ['syntax' => 'short'], 'whitespace_after_comma_in_array' => true, - 'function_typehint_space' => true, + 'type_declaration_spaces' => true, 'single_line_comment_style' => true, 'no_alias_functions' => true, 'lowercase_cast' => true, From 8f3c9ba3d76d54ee683a8c87681935d513cdd902 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 06:42:25 +0200 Subject: [PATCH 10/49] [TASK] Use Configuration/user.tsconfig in v13 ExtensionManagementUtility::addUserTSConfig() stays for v12. --- Configuration/user.tsconfig | 3 +++ ext_tables.php | 11 +++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 Configuration/user.tsconfig diff --git a/Configuration/user.tsconfig b/Configuration/user.tsconfig new file mode 100644 index 00000000..51f149c6 --- /dev/null +++ b/Configuration/user.tsconfig @@ -0,0 +1,3 @@ +# Allow backend users to drag and drop the new page type: +# 137 = T3G\AgencyPack\Blog\Constants::DOKTYPE_BLOG_POST +options.pageTree.doktypesToShowInNewPageDragArea := addToList(137) diff --git a/ext_tables.php b/ext_tables.php index 7aa2f8e1..a7016853 100644 --- a/ext_tables.php +++ b/ext_tables.php @@ -10,6 +10,7 @@ use T3G\AgencyPack\Blog\Constants; use TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider; use TYPO3\CMS\Core\Imaging\IconRegistry; +use TYPO3\CMS\Core\Information\Typo3Version; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -63,7 +64,9 @@ $iconRegistry->registerIcon($identifier, SvgIconProvider::class, ['source' => $path]); } -// Allow backend users to drag and drop the new page type: -ExtensionManagementUtility::addUserTSConfig(' - options.pageTree.doktypesToShowInNewPageDragArea := addToList(' . Constants::DOKTYPE_BLOG_POST . ') -'); +// Replaced with Configuration/user.tsconfig in v13 +if ((new Typo3Version())->getMajorVersion() < 13) { + ExtensionManagementUtility::addUserTSConfig(' + options.pageTree.doktypesToShowInNewPageDragArea := addToList(' . Constants::DOKTYPE_BLOG_POST . ') + '); +} From fc1590dac5524fc581c54ca37f9252ed178a6658 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 07:09:13 +0200 Subject: [PATCH 11/49] [TASK] Drop v11 drawHeaderHook registration v12 and v13 use the ModifyPageLayoutContent event listener instead. --- Classes/Hooks/PageLayoutHeaderHook.php | 32 -------------------------- Configuration/Services.yaml | 3 --- ext_localconf.php | 10 -------- 3 files changed, 45 deletions(-) delete mode 100644 Classes/Hooks/PageLayoutHeaderHook.php diff --git a/Classes/Hooks/PageLayoutHeaderHook.php b/Classes/Hooks/PageLayoutHeaderHook.php deleted file mode 100644 index bddc75ef..00000000 --- a/Classes/Hooks/PageLayoutHeaderHook.php +++ /dev/null @@ -1,32 +0,0 @@ -blogPostHeaderContentRenderer = $blogPostHeaderContentRenderer; - } - - /** - * @return string - */ - public function drawHeader() - { - $request = $GLOBALS['TYPO3_REQUEST']; - return $this->blogPostHeaderContentRenderer->render($request); - } -} diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index 01b09e35..f66000f5 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -10,9 +10,6 @@ services: T3G\AgencyPack\Blog\Domain\Factory\CommentFormFactory: public: true - T3G\AgencyPack\Blog\Hooks\PageLayoutHeaderHook: - public: true - T3G\AgencyPack\Blog\Listener\RenderAdditionalContentToRecordList: tags: - name: event.listener diff --git a/ext_localconf.php b/ext_localconf.php index 19f38d17..af1000e8 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -13,7 +13,6 @@ use T3G\AgencyPack\Blog\Controller\WidgetController; use T3G\AgencyPack\Blog\Hooks\CreateSiteConfigurationHook; use T3G\AgencyPack\Blog\Hooks\DataHandlerHook; -use T3G\AgencyPack\Blog\Hooks\PageLayoutHeaderHook; use T3G\AgencyPack\Blog\Notification\CommentAddedNotification; use T3G\AgencyPack\Blog\Notification\Processor\AdminNotificationProcessor; use T3G\AgencyPack\Blog\Notification\Processor\AuthorNotificationProcessor; @@ -29,9 +28,7 @@ use T3G\AgencyPack\Blog\Updates\TagSlugUpdate; use TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowInitializeNew; use TYPO3\CMS\Core\Hooks\CreateSiteConfiguration; -use TYPO3\CMS\Core\Information\Typo3Version; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; -use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Utility\ExtensionUtility; if (!defined('TYPO3')) { @@ -44,13 +41,6 @@ // Register "blogvh" as global fluid namespace $GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['namespaces']['blogvh'][] = 'T3G\\AgencyPack\\Blog\\ViewHelpers'; -// Register page layout hooks to display additional information for posts. -// Replaced with T3G\AgencyPack\Blog\Listener\ModifyPageLayoutContent in v12 -if ((GeneralUtility::makeInstance(Typo3Version::class))->getMajorVersion() < 12) { - $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/db_layout.php']['drawHeaderHook'][] - = PageLayoutHeaderHook::class . '->drawHeader'; -} - // Register new form data provider $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['tcaDatabaseRecord'][CategoryDefaultValueProvider::class] = [ 'depends' => [DatabaseRowInitializeNew::class], From 160190dbf53d0e83a48318801baf293400dfecf8 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Oct 2024 17:13:41 +0200 Subject: [PATCH 12/49] [TASK] Adapt CommentFormFactory for v13 --- Classes/Domain/Factory/CommentFormFactory.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/Domain/Factory/CommentFormFactory.php b/Classes/Domain/Factory/CommentFormFactory.php index 093ec3ed..d66348eb 100644 --- a/Classes/Domain/Factory/CommentFormFactory.php +++ b/Classes/Domain/Factory/CommentFormFactory.php @@ -10,6 +10,7 @@ namespace T3G\AgencyPack\Blog\Domain\Factory; +use Psr\Http\Message\ServerRequestInterface; use T3G\AgencyPack\Blog\Domain\Finisher\CommentFormFinisher; use T3G\AgencyPack\Blog\Domain\Validator\GoogleCaptchaValidator; use TYPO3\CMS\Core\Information\Typo3Version; @@ -35,7 +36,7 @@ class CommentFormFactory extends AbstractFormFactory * This example build a FormDefinition manually, * so $configuration and $prototypeName are unused. */ - public function build(array $configuration, string $prototypeName = null): FormDefinition + public function build(array $configuration, ?string $prototypeName = null, ?ServerRequestInterface $request = null): FormDefinition { $prototypeName = 'standard'; $formConfigurationService = GeneralUtility::makeInstance(ConfigurationService::class); From ee231e03b2961b25dcd9260573e9ea13d8adf0d3 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 13:55:32 +0200 Subject: [PATCH 13/49] [TASK] Replace TSFE->tmp->setup by frontend.typoscript attribute --- .../ViewHelpers/Link/ArchiveViewHelper.php | 35 ++++++++++++++++--- Classes/ViewHelpers/Link/AuthorViewHelper.php | 33 ++++++++++++++--- .../ViewHelpers/Link/CategoryViewHelper.php | 33 +++++++++++++---- Classes/ViewHelpers/Link/TagViewHelper.php | 33 +++++++++++++---- 4 files changed, 112 insertions(+), 22 deletions(-) diff --git a/Classes/ViewHelpers/Link/ArchiveViewHelper.php b/Classes/ViewHelpers/Link/ArchiveViewHelper.php index 731f2365..fc7f1b2b 100644 --- a/Classes/ViewHelpers/Link/ArchiveViewHelper.php +++ b/Classes/ViewHelpers/Link/ArchiveViewHelper.php @@ -10,9 +10,9 @@ namespace T3G\AgencyPack\Blog\ViewHelpers\Link; +use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder; -use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper; class ArchiveViewHelper extends AbstractTagBasedViewHelper @@ -40,7 +40,21 @@ public function render(): string $rssFormat = (bool)$this->arguments['rss']; $year = (int)$this->arguments['year']; $month = (int)$this->arguments['month']; - $pageUid = (int)$this->getTypoScriptFrontendController()->tmpl->setup['plugin.']['tx_blog.']['settings.']['archiveUid']; + // @todo migrate to site settings + $pageUid = (int)($this->getRequest()->getAttribute('frontend.typoscript')->getSetupTree() + ->getChildByName('plugin') + ?->getChildByName('tx_blog') + ?->getChildByName('settings') + ?->getChildByName('archiveUid') + ?->getValue() ?? 0); + + $rssTypeNum = (int)( + $this->getRequest()->getAttribute('frontend.typoscript')->getSetupTree() + ->getChildByName('blog_rss_archive') + ?->getChildByName('typeNum') + ?->getValue() ?? 0 + ); + $arguments = [ 'year' => $year ]; @@ -53,7 +67,7 @@ public function render(): string ->setTargetPageUid($pageUid); if ($rssFormat) { $uriBuilder - ->setTargetPageType((int)$this->getTypoScriptFrontendController()->tmpl->setup['blog_rss_archive.']['typeNum']); + ->setTargetPageType($rssTypeNum); } $uri = $uriBuilder->uriFor('listPostsByDate', $arguments, 'Post', 'Blog', 'Archive'); $linkText = $this->renderChildren() ?? implode('-', $arguments); @@ -68,8 +82,19 @@ public function render(): string return (string)$result; } - protected function getTypoScriptFrontendController(): TypoScriptFrontendController + protected function getRequest(): ServerRequestInterface { - return $GLOBALS['TSFE']; + $request = null; + if ($this->renderingContext->hasAttribute(ServerRequestInterface::class)) { + $request = $this->renderingContext->getAttribute(ServerRequestInterface::class); + } + $request ??= $GLOBALS['TYPO3_REQUEST'] ?? null; + if (!$request instanceof ServerRequestInterface) { + throw new \RuntimeException( + 'ViewHelper blogvh:link.archive needs a request implementing ServerRequestInterface.', + 1729082933 + ); + } + return $request; } } diff --git a/Classes/ViewHelpers/Link/AuthorViewHelper.php b/Classes/ViewHelpers/Link/AuthorViewHelper.php index ad603aa4..edfd6bab 100644 --- a/Classes/ViewHelpers/Link/AuthorViewHelper.php +++ b/Classes/ViewHelpers/Link/AuthorViewHelper.php @@ -10,10 +10,10 @@ namespace T3G\AgencyPack\Blog\ViewHelpers\Link; +use Psr\Http\Message\ServerRequestInterface; use T3G\AgencyPack\Blog\Domain\Model\Author; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder; -use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper; class AuthorViewHelper extends AbstractTagBasedViewHelper @@ -56,7 +56,13 @@ protected function buildUriFromDetailsPage(Author $author, bool $rssFormat): str protected function buildUriFromDefaultPage(Author $author, bool $rssFormat): string { - $uriBuilder = $this->getUriBuilder((int)$this->getTypoScriptFrontendController()->tmpl->setup['plugin.']['tx_blog.']['settings.']['authorUid'], [], $rssFormat); + $settings = $this->getRequest()->getAttribute('frontend.typoscript')->getSetupTree() + ->getChildByName('plugin') + ?->getChildByName('tx_blog') + ?->getChildByName('settings') + ?->toArray() ?? []; + $authorUid = (int)($settings['authorUid'] ?? 0); + $uriBuilder = $this->getUriBuilder($authorUid, [], $rssFormat); $arguments = [ 'author' => $author->getUid(), ]; @@ -71,8 +77,14 @@ protected function getUriBuilder(int $pageUid, array $additionalParams, bool $rs ->setTargetPageUid($pageUid) ->setArguments($additionalParams); if ($rssFormat) { + $rssTypeNum = (int)( + $this->getRequest()->getAttribute('frontend.typoscript')->getSetupTree() + ->getChildByName('blog_rss_author') + ?->getChildByName('typeNum') + ?->getValue() ?? 0 + ); $uriBuilder - ->setTargetPageType((int)$this->getTypoScriptFrontendController()->tmpl->setup['blog_rss_author.']['typeNum']); + ->setTargetPageType($rssTypeNum); } return $uriBuilder; @@ -90,8 +102,19 @@ protected function buildAnchorTag(string $uri, Author $author): string return $this->renderChildren(); } - protected function getTypoScriptFrontendController(): TypoScriptFrontendController + protected function getRequest(): ServerRequestInterface { - return $GLOBALS['TSFE']; + $request = null; + if ($this->renderingContext->hasAttribute(ServerRequestInterface::class)) { + $request = $this->renderingContext->getAttribute(ServerRequestInterface::class); + } + $request ??= $GLOBALS['TYPO3_REQUEST'] ?? null; + if (!$request instanceof ServerRequestInterface) { + throw new \RuntimeException( + 'ViewHelper blogvh:link.author needs a request implementing ServerRequestInterface.', + 1729082934 + ); + } + return $request; } } diff --git a/Classes/ViewHelpers/Link/CategoryViewHelper.php b/Classes/ViewHelpers/Link/CategoryViewHelper.php index cb133e6e..35cecdab 100644 --- a/Classes/ViewHelpers/Link/CategoryViewHelper.php +++ b/Classes/ViewHelpers/Link/CategoryViewHelper.php @@ -10,10 +10,10 @@ namespace T3G\AgencyPack\Blog\ViewHelpers\Link; +use Psr\Http\Message\ServerRequestInterface; use T3G\AgencyPack\Blog\Domain\Model\Category; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder; -use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper; class CategoryViewHelper extends AbstractTagBasedViewHelper @@ -40,7 +40,12 @@ public function render(): string $rssFormat = (bool)$this->arguments['rss']; /** @var Category $category */ $category = $this->arguments['category']; - $pageUid = (int)$this->getTypoScriptFrontendController()->tmpl->setup['plugin.']['tx_blog.']['settings.']['categoryUid']; + $pageUid = (int)($this->getRequest()->getAttribute('frontend.typoscript')->getSetupTree() + ->getChildByName('plugin') + ?->getChildByName('tx_blog') + ?->getChildByName('settings') + ?->getChildByName('categoryUid') + ?->getValue() ?? 0); $arguments = [ 'category' => $category->getUid(), ]; @@ -49,8 +54,13 @@ public function render(): string ->setRequest($this->renderingContext->getRequest()) ->setTargetPageUid($pageUid); if ($rssFormat) { - $uriBuilder - ->setTargetPageType((int)$this->getTypoScriptFrontendController()->tmpl->setup['blog_rss_category.']['typeNum']); + $rssTypeNum = (int)( + $this->getRequest()->getAttribute('frontend.typoscript')->getSetupTree() + ->getChildByName('blog_rss_category') + ?->getChildByName('typeNum') + ?->getValue() ?? 0 + ); + $uriBuilder->setTargetPageType($rssTypeNum); } $uri = $uriBuilder->uriFor('listPostsByCategory', $arguments, 'Post', 'Blog', 'Category'); @@ -66,8 +76,19 @@ public function render(): string return (string)$result; } - protected function getTypoScriptFrontendController(): TypoScriptFrontendController + protected function getRequest(): ServerRequestInterface { - return $GLOBALS['TSFE']; + $request = null; + if ($this->renderingContext->hasAttribute(ServerRequestInterface::class)) { + $request = $this->renderingContext->getAttribute(ServerRequestInterface::class); + } + $request ??= $GLOBALS['TYPO3_REQUEST'] ?? null; + if (!$request instanceof ServerRequestInterface) { + throw new \RuntimeException( + 'ViewHelper blogvh:link.category needs a request implementing ServerRequestInterface.', + 1729082935 + ); + } + return $request; } } diff --git a/Classes/ViewHelpers/Link/TagViewHelper.php b/Classes/ViewHelpers/Link/TagViewHelper.php index d6125a39..005af514 100644 --- a/Classes/ViewHelpers/Link/TagViewHelper.php +++ b/Classes/ViewHelpers/Link/TagViewHelper.php @@ -10,10 +10,10 @@ namespace T3G\AgencyPack\Blog\ViewHelpers\Link; +use Psr\Http\Message\ServerRequestInterface; use T3G\AgencyPack\Blog\Domain\Model\Tag; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder; -use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper; class TagViewHelper extends AbstractTagBasedViewHelper @@ -40,7 +40,12 @@ public function render(): string $rssFormat = (bool)$this->arguments['rss']; /** @var Tag $tag */ $tag = $this->arguments['tag']; - $pageUid = (int)$this->getTypoScriptFrontendController()->tmpl->setup['plugin.']['tx_blog.']['settings.']['tagUid']; + $pageUid = (int)($this->getRequest()->getAttribute('frontend.typoscript')->getSetupTree() + ->getChildByName('plugin') + ?->getChildByName('tx_blog') + ?->getChildByName('settings') + ?->getChildByName('tagUid') + ?->getValue() ?? 0); $arguments = [ 'tag' => $tag->getUid(), ]; @@ -49,8 +54,13 @@ public function render(): string ->setRequest($this->renderingContext->getRequest()) ->setTargetPageUid($pageUid); if ($rssFormat) { - $uriBuilder - ->setTargetPageType((int)$this->getTypoScriptFrontendController()->tmpl->setup['blog_rss_tag.']['typeNum']); + $rssTypeNum = (int)( + $this->getRequest()->getAttribute('frontend.typoscript')->getSetupTree() + ->getChildByName('blog_rss_tag') + ?->getChildByName('typeNum') + ?->getValue() ?? 0 + ); + $uriBuilder->setTargetPageType($rssTypeNum); } $uri = $uriBuilder->uriFor('listPostsByTag', $arguments, 'Post', 'Blog', 'Tag'); if ($uri !== '') { @@ -65,8 +75,19 @@ public function render(): string return (string)$result; } - protected function getTypoScriptFrontendController(): TypoScriptFrontendController + protected function getRequest(): ServerRequestInterface { - return $GLOBALS['TSFE']; + $request = null; + if ($this->renderingContext->hasAttribute(ServerRequestInterface::class)) { + $request = $this->renderingContext->getAttribute(ServerRequestInterface::class); + } + $request ??= $GLOBALS['TYPO3_REQUEST'] ?? null; + if (!$request instanceof ServerRequestInterface) { + throw new \RuntimeException( + 'ViewHelper blogvh:link.tag needs a request implementing ServerRequestInterface.', + 1729082936 + ); + } + return $request; } } From 2f272d2f20bae1e8e84c5ee09ae4fe399d70c786 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 11:43:21 +0200 Subject: [PATCH 14/49] [TASK] Register upgrade wizards via attribute --- Classes/Updates/AuthorSlugUpdate.php | 2 ++ Classes/Updates/AvatarProviderUpdate.php | 2 ++ Classes/Updates/CategorySlugUpdate.php | 2 ++ Classes/Updates/CategoryTypeUpdate.php | 2 ++ Classes/Updates/CommentStatusUpdate.php | 2 ++ Classes/Updates/DatabaseMonthYearUpdate.php | 2 ++ Classes/Updates/DatabasePublishDateUpdate.php | 2 ++ Classes/Updates/FeaturedImageUpdate.php | 2 ++ Classes/Updates/TagSlugUpdate.php | 2 ++ ext_localconf.php | 29 ------------------- 10 files changed, 18 insertions(+), 29 deletions(-) diff --git a/Classes/Updates/AuthorSlugUpdate.php b/Classes/Updates/AuthorSlugUpdate.php index 8144fd4d..3dfcff12 100644 --- a/Classes/Updates/AuthorSlugUpdate.php +++ b/Classes/Updates/AuthorSlugUpdate.php @@ -13,8 +13,10 @@ use TYPO3\CMS\Core\DataHandling\Model\RecordStateFactory; use TYPO3\CMS\Core\DataHandling\SlugHelper; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Install\Attribute\UpgradeWizard; use TYPO3\CMS\Install\Updates\UpgradeWizardInterface; +#[UpgradeWizard(AuthorSlugUpdate::class)] final class AuthorSlugUpdate extends AbstractUpdate implements UpgradeWizardInterface { protected string $title = 'EXT:blog: Generate Path-Segments for Authors'; diff --git a/Classes/Updates/AvatarProviderUpdate.php b/Classes/Updates/AvatarProviderUpdate.php index be3cf10c..428cd5ce 100644 --- a/Classes/Updates/AvatarProviderUpdate.php +++ b/Classes/Updates/AvatarProviderUpdate.php @@ -11,8 +11,10 @@ namespace T3G\AgencyPack\Blog\Updates; use T3G\AgencyPack\Blog\AvatarProvider\GravatarProvider; +use TYPO3\CMS\Install\Attribute\UpgradeWizard; use TYPO3\CMS\Install\Updates\UpgradeWizardInterface; +#[UpgradeWizard(AvatarProviderUpdate::class)] final class AvatarProviderUpdate extends AbstractUpdate implements UpgradeWizardInterface { protected string $title = 'EXT:blog: Migrate AvatarProvider'; diff --git a/Classes/Updates/CategorySlugUpdate.php b/Classes/Updates/CategorySlugUpdate.php index a05bcd64..3a7d7859 100644 --- a/Classes/Updates/CategorySlugUpdate.php +++ b/Classes/Updates/CategorySlugUpdate.php @@ -13,8 +13,10 @@ use TYPO3\CMS\Core\DataHandling\Model\RecordStateFactory; use TYPO3\CMS\Core\DataHandling\SlugHelper; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Install\Attribute\UpgradeWizard; use TYPO3\CMS\Install\Updates\UpgradeWizardInterface; +#[UpgradeWizard(CategorySlugUpdate::class)] final class CategorySlugUpdate extends AbstractUpdate implements UpgradeWizardInterface { protected string $title = 'EXT:blog: Generate Path-Segments for Categories'; diff --git a/Classes/Updates/CategoryTypeUpdate.php b/Classes/Updates/CategoryTypeUpdate.php index fadb21fe..098b2353 100644 --- a/Classes/Updates/CategoryTypeUpdate.php +++ b/Classes/Updates/CategoryTypeUpdate.php @@ -11,8 +11,10 @@ namespace T3G\AgencyPack\Blog\Updates; use T3G\AgencyPack\Blog\Constants; +use TYPO3\CMS\Install\Attribute\UpgradeWizard; use TYPO3\CMS\Install\Updates\UpgradeWizardInterface; +#[UpgradeWizard(CategoryTypeUpdate::class)] final class CategoryTypeUpdate extends AbstractUpdate implements UpgradeWizardInterface { protected string $title = 'EXT:blog: Use Blog-Type for Categories'; diff --git a/Classes/Updates/CommentStatusUpdate.php b/Classes/Updates/CommentStatusUpdate.php index 7071dc5a..b4315c30 100644 --- a/Classes/Updates/CommentStatusUpdate.php +++ b/Classes/Updates/CommentStatusUpdate.php @@ -10,8 +10,10 @@ namespace T3G\AgencyPack\Blog\Updates; +use TYPO3\CMS\Install\Attribute\UpgradeWizard; use TYPO3\CMS\Install\Updates\UpgradeWizardInterface; +#[UpgradeWizard(CommentStatusUpdate::class)] final class CommentStatusUpdate extends AbstractUpdate implements UpgradeWizardInterface { protected string $title = 'EXT:blog: Migrate Comment Status'; diff --git a/Classes/Updates/DatabaseMonthYearUpdate.php b/Classes/Updates/DatabaseMonthYearUpdate.php index 0e8519a1..e0647213 100644 --- a/Classes/Updates/DatabaseMonthYearUpdate.php +++ b/Classes/Updates/DatabaseMonthYearUpdate.php @@ -11,8 +11,10 @@ namespace T3G\AgencyPack\Blog\Updates; use T3G\AgencyPack\Blog\Constants; +use TYPO3\CMS\Install\Attribute\UpgradeWizard; use TYPO3\CMS\Install\Updates\UpgradeWizardInterface; +#[UpgradeWizard(DatabaseMonthYearUpdate::class)] final class DatabaseMonthYearUpdate extends AbstractUpdate implements UpgradeWizardInterface { protected string $title = 'EXT:blog: Set new month and year fields for existing blog posts'; diff --git a/Classes/Updates/DatabasePublishDateUpdate.php b/Classes/Updates/DatabasePublishDateUpdate.php index 10c72806..8c39dace 100644 --- a/Classes/Updates/DatabasePublishDateUpdate.php +++ b/Classes/Updates/DatabasePublishDateUpdate.php @@ -11,8 +11,10 @@ namespace T3G\AgencyPack\Blog\Updates; use T3G\AgencyPack\Blog\Constants; +use TYPO3\CMS\Install\Attribute\UpgradeWizard; use TYPO3\CMS\Install\Updates\UpgradeWizardInterface; +#[UpgradeWizard(DatabasePublishDateUpdate::class)] final class DatabasePublishDateUpdate extends AbstractUpdate implements UpgradeWizardInterface { protected string $title = 'EXT:blog: Set publish date fields to crdate for existing blog posts'; diff --git a/Classes/Updates/FeaturedImageUpdate.php b/Classes/Updates/FeaturedImageUpdate.php index b2b25196..068a79a8 100644 --- a/Classes/Updates/FeaturedImageUpdate.php +++ b/Classes/Updates/FeaturedImageUpdate.php @@ -10,9 +10,11 @@ namespace T3G\AgencyPack\Blog\Updates; use T3G\AgencyPack\Blog\Constants; +use TYPO3\CMS\Install\Attribute\UpgradeWizard; use TYPO3\CMS\Install\Updates\RepeatableInterface; use TYPO3\CMS\Install\Updates\UpgradeWizardInterface; +#[UpgradeWizard(FeaturedImageUpdate::class)] final class FeaturedImageUpdate extends AbstractUpdate implements UpgradeWizardInterface, RepeatableInterface { protected string $title = 'EXT:blog: Featured Image Update'; diff --git a/Classes/Updates/TagSlugUpdate.php b/Classes/Updates/TagSlugUpdate.php index b241eafd..b2f0c7ed 100644 --- a/Classes/Updates/TagSlugUpdate.php +++ b/Classes/Updates/TagSlugUpdate.php @@ -13,8 +13,10 @@ use TYPO3\CMS\Core\DataHandling\Model\RecordStateFactory; use TYPO3\CMS\Core\DataHandling\SlugHelper; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Install\Attribute\UpgradeWizard; use TYPO3\CMS\Install\Updates\UpgradeWizardInterface; +#[UpgradeWizard(TagSlugUpdate::class)] final class TagSlugUpdate extends AbstractUpdate implements UpgradeWizardInterface { protected string $title = 'EXT:blog: Generate Path-Segments for Tags'; diff --git a/ext_localconf.php b/ext_localconf.php index af1000e8..c039c46e 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -17,15 +17,6 @@ use T3G\AgencyPack\Blog\Notification\Processor\AdminNotificationProcessor; use T3G\AgencyPack\Blog\Notification\Processor\AuthorNotificationProcessor; use T3G\AgencyPack\Blog\Routing\Aspect\StaticDatabaseMapper; -use T3G\AgencyPack\Blog\Updates\AuthorSlugUpdate; -use T3G\AgencyPack\Blog\Updates\AvatarProviderUpdate; -use T3G\AgencyPack\Blog\Updates\CategorySlugUpdate; -use T3G\AgencyPack\Blog\Updates\CategoryTypeUpdate; -use T3G\AgencyPack\Blog\Updates\CommentStatusUpdate; -use T3G\AgencyPack\Blog\Updates\DatabaseMonthYearUpdate; -use T3G\AgencyPack\Blog\Updates\DatabasePublishDateUpdate; -use T3G\AgencyPack\Blog\Updates\FeaturedImageUpdate; -use T3G\AgencyPack\Blog\Updates\TagSlugUpdate; use TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowInitializeNew; use TYPO3\CMS\Core\Hooks\CreateSiteConfiguration; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; @@ -219,26 +210,6 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass']['Blog'] = DataHandlerHook::class; -// Upgrades -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][AuthorSlugUpdate::class] - = AuthorSlugUpdate::class; -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][AvatarProviderUpdate::class] - = AvatarProviderUpdate::class; -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][CategorySlugUpdate::class] - = CategorySlugUpdate::class; -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][CategoryTypeUpdate::class] - = CategoryTypeUpdate::class; -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][CommentStatusUpdate::class] - = CommentStatusUpdate::class; -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][DatabaseMonthYearUpdate::class] - = DatabaseMonthYearUpdate::class; -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][DatabasePublishDateUpdate::class] - = DatabasePublishDateUpdate::class; -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][FeaturedImageUpdate::class] - = FeaturedImageUpdate::class; -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][TagSlugUpdate::class] - = TagSlugUpdate::class; - // Register Static Database Mapper $GLOBALS['TYPO3_CONF_VARS']['SYS']['routing']['aspects']['BlogStaticDatabaseMapper'] = StaticDatabaseMapper::class; From 845aae165533dd6369a807e61410f0f9932ef742 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 09:56:59 +0200 Subject: [PATCH 15/49] [TASK] Replace EMU::addPageTSConfig by Configuration/page.tsconfig --- Configuration/page.tsconfig | 1 + ext_localconf.php | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) create mode 100644 Configuration/page.tsconfig diff --git a/Configuration/page.tsconfig b/Configuration/page.tsconfig new file mode 100644 index 00000000..af31cfab --- /dev/null +++ b/Configuration/page.tsconfig @@ -0,0 +1 @@ +@import "EXT:blog/Configuration/TsConfig/Page/All.tsconfig" diff --git a/ext_localconf.php b/ext_localconf.php index c039c46e..c45acc8b 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -19,16 +19,12 @@ use T3G\AgencyPack\Blog\Routing\Aspect\StaticDatabaseMapper; use TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowInitializeNew; use TYPO3\CMS\Core\Hooks\CreateSiteConfiguration; -use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Extbase\Utility\ExtensionUtility; if (!defined('TYPO3')) { die('Access denied.'); } -// PageTS -ExtensionManagementUtility::addPageTSConfig(''); - // Register "blogvh" as global fluid namespace $GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['namespaces']['blogvh'][] = 'T3G\\AgencyPack\\Blog\\ViewHelpers'; From 6ff3fa7b2bc0888737b1c5c2da2a5e352fd23770 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 11:27:43 +0200 Subject: [PATCH 16/49] [TASK] Make AbstractUpdate v13 compatible --- Classes/Updates/AbstractUpdate.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Classes/Updates/AbstractUpdate.php b/Classes/Updates/AbstractUpdate.php index 3ee3fc93..8281d512 100644 --- a/Classes/Updates/AbstractUpdate.php +++ b/Classes/Updates/AbstractUpdate.php @@ -10,6 +10,7 @@ namespace T3G\AgencyPack\Blog\Updates; +use T3G\AgencyPack\Blog\Updates\Criteria\CriteriaInterface; use T3G\AgencyPack\Blog\Updates\Criteria\EqualIntCriteria; use T3G\AgencyPack\Blog\Updates\Criteria\EqualStringCriteria; use T3G\AgencyPack\Blog\Updates\Criteria\InCriteria; @@ -119,9 +120,9 @@ protected function getRecordsByCriteria(QueryBuilder $queryBuilder, string $tabl $queryBuilder->select('*'); $queryBuilder->from($table); if ($condition === self::CONDITION_AND) { - $queryBuilder->where(...$criteria); + $queryBuilder->where(...array_map(static fn (CriteriaInterface $criterion): string => (string)$criterion, $criteria)); } else { - $queryBuilder->orWhere(...$criteria); + $queryBuilder->orWhere(...array_map(static fn (CriteriaInterface $criterion): string => (string)$criterion, $criteria)); } $result = $queryBuilder->executeQuery(); From 0c1760f85605c34a32117ef4bf62e9b661b69ca1 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 09:10:40 +0200 Subject: [PATCH 17/49] [TASK] Replace Bootstrap::initializeLanguageObject() in tests for v13 The core internal method Bootstrap::initializeLanguageObject() has been removed and LanguageServiceFactory is to be used directly in tests. Also see https://review.typo3.org/c/Packages/TYPO3.CMS/+/82266 for the respective core change. --- Tests/Functional/Hooks/DataHandlerHookTest.php | 6 +++--- Tests/Functional/Service/SetupServiceTest.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Tests/Functional/Hooks/DataHandlerHookTest.php b/Tests/Functional/Hooks/DataHandlerHookTest.php index 3cd7018d..17fb7918 100644 --- a/Tests/Functional/Hooks/DataHandlerHookTest.php +++ b/Tests/Functional/Hooks/DataHandlerHookTest.php @@ -13,8 +13,8 @@ use T3G\AgencyPack\Blog\Constants; use TYPO3\CMS\Backend\Utility\BackendUtility; -use TYPO3\CMS\Core\Core\Bootstrap; use TYPO3\CMS\Core\DataHandling\DataHandler; +use TYPO3\CMS\Core\Localization\LanguageServiceFactory; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -33,8 +33,8 @@ protected function setUp(): void parent::setUp(); $this->importCSVDataSet(__DIR__ . '/../Fixtures/DataHandler/be_users.csv'); - $this->setUpBackendUser(1); - Bootstrap::initializeLanguageObject(); + $backendUser = $this->setUpBackendUser(1); + $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->createFromUserPreferences($backendUser); } /** diff --git a/Tests/Functional/Service/SetupServiceTest.php b/Tests/Functional/Service/SetupServiceTest.php index 033b10ca..9d9cdda8 100644 --- a/Tests/Functional/Service/SetupServiceTest.php +++ b/Tests/Functional/Service/SetupServiceTest.php @@ -14,7 +14,7 @@ use T3G\AgencyPack\Blog\Constants; use T3G\AgencyPack\Blog\Service\SetupService; use TYPO3\CMS\Backend\Utility\BackendUtility; -use TYPO3\CMS\Core\Core\Bootstrap; +use TYPO3\CMS\Core\Localization\LanguageServiceFactory; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -33,8 +33,8 @@ protected function setUp(): void parent::setUp(); $this->importCSVDataSet(__DIR__ . '/../Fixtures/DataHandler/be_users.csv'); - $this->setUpBackendUser(1); - Bootstrap::initializeLanguageObject(); + $backendUser = $this->setUpBackendUser(1); + $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->createFromUserPreferences($backendUser); } /** From 0d0f0cf9f4dfd41e62f9eba912018cf51751d020 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 09:28:37 +0200 Subject: [PATCH 18/49] [TASK] Adapt GravatarProviderTest for v13 --- .../AvatarProvider/GravatarProviderTest.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Tests/Functional/AvatarProvider/GravatarProviderTest.php b/Tests/Functional/AvatarProvider/GravatarProviderTest.php index 56588e3a..5963dffc 100644 --- a/Tests/Functional/AvatarProvider/GravatarProviderTest.php +++ b/Tests/Functional/AvatarProvider/GravatarProviderTest.php @@ -12,6 +12,11 @@ use T3G\AgencyPack\Blog\AvatarProvider\GravatarProvider; use T3G\AgencyPack\Blog\Domain\Model\Author; +use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; +use TYPO3\CMS\Core\Http\ServerRequest; +use TYPO3\CMS\Core\TypoScript\AST\Node\RootNode; +use TYPO3\CMS\Core\TypoScript\FrontendTypoScript; +use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; class GravatarProviderTest extends FunctionalTestCase @@ -26,6 +31,13 @@ class GravatarProviderTest extends FunctionalTestCase public function testGetAvatarUrlReturnsOriginalGravatarComUrl(): void { + $frontendTypoScript = new FrontendTypoScript(new RootNode(), [], [], []); + $frontendTypoScript->setSetupArray([]); + $request = (new ServerRequest()) + ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_FE) + ->withAttribute('frontend.typoscript', $frontendTypoScript); + $this->get(ConfigurationManagerInterface::class)->setRequest($request); + $author = (new Author())->setEmail('name@host.tld'); $gravatarProvider = new GravatarProvider(); self::assertSame( @@ -37,6 +49,12 @@ public function testGetAvatarUrlReturnsOriginalGravatarComUrl(): void public function testGetAvatarUrlReturnsTypo3TempUrl(): void { $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['blog']['enableGravatarProxy'] = '1'; + $frontendTypoScript = new FrontendTypoScript(new RootNode(), [], [], []); + $frontendTypoScript->setSetupArray([]); + $request = (new ServerRequest()) + ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_FE) + ->withAttribute('frontend.typoscript', $frontendTypoScript); + $this->get(ConfigurationManagerInterface::class)->setRequest($request); $author = (new Author())->setEmail('name@host.tld'); $gravatarProvider = new GravatarProvider(); From 73e50f515f859328d515429c8889b2fdf3a4cd7d Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 12:00:40 +0200 Subject: [PATCH 19/49] [TASK] Adapt GravatarViewHelperTest for v13 --- .../ViewHelpers/GravatarViewHelperTest.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Tests/Functional/ViewHelpers/GravatarViewHelperTest.php b/Tests/Functional/ViewHelpers/GravatarViewHelperTest.php index c7624161..73d8e038 100644 --- a/Tests/Functional/ViewHelpers/GravatarViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/GravatarViewHelperTest.php @@ -11,6 +11,11 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers; +use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; +use TYPO3\CMS\Core\Http\ServerRequest; +use TYPO3\CMS\Core\TypoScript\AST\Node\RootNode; +use TYPO3\CMS\Core\TypoScript\FrontendTypoScript; +use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory; use TYPO3\CMS\Fluid\View\TemplateView; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -31,6 +36,13 @@ final class GravatarViewHelperTest extends FunctionalTestCase */ public function render(string $template, string $expected): void { + $frontendTypoScript = new FrontendTypoScript(new RootNode(), [], [], []); + $frontendTypoScript->setSetupArray([]); + $request = (new ServerRequest()) + ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_FE) + ->withAttribute('frontend.typoscript', $frontendTypoScript); + $this->get(ConfigurationManagerInterface::class)->setRequest($request); + $context = $this->get(RenderingContextFactory::class)->create(); $context->getTemplatePaths()->setTemplateSource($template); $view = (new TemplateView($context)); From 0191ec4b372e8ef4ef286258f80a51bf55a20f30 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 10:54:30 +0200 Subject: [PATCH 20/49] [TASK] Adapt SiteBasedTestCase for v13 Use SiteConfiguration/Writer (in v13) from DI instead of building the instance manually. --- Tests/Functional/SiteBasedTestCase.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/Tests/Functional/SiteBasedTestCase.php b/Tests/Functional/SiteBasedTestCase.php index 1d24d050..8ef30d9c 100644 --- a/Tests/Functional/SiteBasedTestCase.php +++ b/Tests/Functional/SiteBasedTestCase.php @@ -9,8 +9,8 @@ namespace T3G\AgencyPack\Blog\Tests\Functional; -use Psr\EventDispatcher\EventDispatcherInterface; use TYPO3\CMS\Core\Configuration\SiteConfiguration; +use TYPO3\CMS\Core\Configuration\SiteWriter; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Information\Typo3Version; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -38,14 +38,6 @@ protected function createTestSite(): void $this->importCSVDataSet(__DIR__ . '/Fixtures/Site/tt_content.csv'); $identifier = 'test'; - $arguments = []; - $arguments[] = $this->instancePath . '/typo3conf/sites/'; - if ((GeneralUtility::makeInstance(Typo3Version::class))->getMajorVersion() >= 12) { - $arguments[] = $this->get(EventDispatcherInterface::class); - } - $arguments[] = $this->get('cache.core'); - $siteConfiguration = new SiteConfiguration(...$arguments); - $configuration = [ 'websiteTitle' => 'Simple Test Site', 'rootPageId' => '1', @@ -73,7 +65,11 @@ protected function createTestSite(): void ]; GeneralUtility::rmdir($this->instancePath . '/typo3conf/sites/' . $identifier, true); - $siteConfiguration->write($identifier, $configuration); + if ((new Typo3Version())->getMajorVersion() >= 13) { + $this->get(SiteWriter::class)->write($identifier, $configuration); + } else { + $this->get(SiteConfiguration::class)->write($identifier, $configuration); + } } protected function renderFluidTemplateInTestSite(string $template, array $instructions = []): string From 3365532f8ff4cf6516baf4fbbcb5654246c20dea Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 14:41:55 +0200 Subject: [PATCH 21/49] [TASK] Adapt AvatarViewHelperTest for v13 --- .../ViewHelpers/Uri/AvatarViewHelperTest.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Tests/Functional/ViewHelpers/Uri/AvatarViewHelperTest.php b/Tests/Functional/ViewHelpers/Uri/AvatarViewHelperTest.php index b57dd44b..16b8e4e5 100644 --- a/Tests/Functional/ViewHelpers/Uri/AvatarViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Uri/AvatarViewHelperTest.php @@ -12,6 +12,11 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers\Uri; use T3G\AgencyPack\Blog\Domain\Model\Author; +use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; +use TYPO3\CMS\Core\Http\ServerRequest; +use TYPO3\CMS\Core\TypoScript\AST\Node\RootNode; +use TYPO3\CMS\Core\TypoScript\FrontendTypoScript; +use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory; use TYPO3\CMS\Fluid\View\TemplateView; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -32,6 +37,13 @@ final class AvatarViewHelperTest extends FunctionalTestCase */ public function render(string $template, string $expected): void { + $frontendTypoScript = new FrontendTypoScript(new RootNode(), [], [], []); + $frontendTypoScript->setSetupArray([]); + $request = (new ServerRequest()) + ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_FE) + ->withAttribute('frontend.typoscript', $frontendTypoScript); + $this->get(ConfigurationManagerInterface::class)->setRequest($request); + $author = new Author(); $author->setEmail('info+gravatar@typo3.com'); $author->setName('Info Gravatar'); From 4a8c0a24010fd918593032b0faf7e34d85510ea4 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 12:38:24 +0200 Subject: [PATCH 22/49] [TASK] Use phpunit attributes in tests --- .../Functional/Hooks/DataHandlerHookTest.php | 9 +++----- Tests/Functional/Service/SetupServiceTest.php | 13 ++++-------- .../Updates/AuthorSlugUpdateTest.php | 9 +++----- .../Updates/AvatarProviderUpdateTest.php | 9 +++----- .../Updates/CategorySlugUpdateTest.php | 9 +++----- .../Updates/CategoryTypeUpdateTest.php | 9 +++----- .../Updates/CommentStatusUpdateTest.php | 9 +++----- .../Updates/DatabaseMonthYearUpdateTest.php | 9 +++----- .../Updates/DatabasePublishDateUpdateTest.php | 9 +++----- .../Updates/FeaturedImageUpdateTest.php | 9 +++----- .../Functional/Updates/TagSlugUpdateTest.php | 9 +++----- .../Data/ContentListOptionsViewHelperTest.php | 9 +++----- .../ViewHelpers/GravatarViewHelperTest.php | 8 +++---- .../Link/ArchiveViewHelperTest.php | 8 +++---- .../ViewHelpers/Link/AuthorViewHelperTest.php | 8 +++---- .../Link/Be/AuthorViewHelperTest.php | 8 +++---- .../Link/Be/CategoryViewHelperTest.php | 8 +++---- .../Link/Be/CommentViewHelperTest.php | 8 +++---- .../Link/Be/PostViewHelperTest.php | 8 +++---- .../ViewHelpers/Link/Be/TagViewHelperTest.php | 8 +++---- .../Link/CategoryViewHelperTest.php | 8 +++---- .../ViewHelpers/Link/PostViewHelperTest.php | 8 +++---- .../ViewHelpers/Link/TagViewHelperTest.php | 8 +++---- .../ViewHelpers/Uri/AvatarViewHelperTest.php | 8 +++---- Tests/Unit/ConstantsTest.php | 5 ++--- Tests/Unit/Domain/Model/PostTest.php | 5 ++--- Tests/Unit/Service/CommentServiceTest.php | 21 ++++++------------- 27 files changed, 95 insertions(+), 144 deletions(-) diff --git a/Tests/Functional/Hooks/DataHandlerHookTest.php b/Tests/Functional/Hooks/DataHandlerHookTest.php index 17fb7918..0eb2c59a 100644 --- a/Tests/Functional/Hooks/DataHandlerHookTest.php +++ b/Tests/Functional/Hooks/DataHandlerHookTest.php @@ -11,6 +11,7 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\Service; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Constants; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\DataHandling\DataHandler; @@ -37,9 +38,7 @@ protected function setUp(): void $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->createFromUserPreferences($backendUser); } - /** - * @test - */ + #[Test] public function create(): void { $this->importCSVDataSet(__DIR__ . '/Fixtures/BlogBasePages.csv'); @@ -86,9 +85,7 @@ public function create(): void self::assertEquals($page['crdate_year'], 2023); } - /** - * @test - */ + #[Test] public function update(): void { $this->importCSVDataSet(__DIR__ . '/Fixtures/BlogBasePages.csv'); diff --git a/Tests/Functional/Service/SetupServiceTest.php b/Tests/Functional/Service/SetupServiceTest.php index 9d9cdda8..3cfbb80b 100644 --- a/Tests/Functional/Service/SetupServiceTest.php +++ b/Tests/Functional/Service/SetupServiceTest.php @@ -11,6 +11,7 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\Service; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Constants; use T3G\AgencyPack\Blog\Service\SetupService; use TYPO3\CMS\Backend\Utility\BackendUtility; @@ -37,9 +38,7 @@ protected function setUp(): void $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->createFromUserPreferences($backendUser); } - /** - * @test - */ + #[Test] public function create(): void { $setupService = GeneralUtility::makeInstance(SetupService::class); @@ -52,9 +51,7 @@ public function create(): void self::assertEquals($rootPage['is_siteroot'], 1); } - /** - * @test - */ + #[Test] public function createWithName(): void { $setupService = GeneralUtility::makeInstance(SetupService::class); @@ -67,9 +64,7 @@ public function createWithName(): void self::assertEquals($rootPage['is_siteroot'], 1); } - /** - * @test - */ + #[Test] public function determineBlogSetups(): void { $setupService = GeneralUtility::makeInstance(SetupService::class); diff --git a/Tests/Functional/Updates/AuthorSlugUpdateTest.php b/Tests/Functional/Updates/AuthorSlugUpdateTest.php index 2f49e64c..89f8bf83 100644 --- a/Tests/Functional/Updates/AuthorSlugUpdateTest.php +++ b/Tests/Functional/Updates/AuthorSlugUpdateTest.php @@ -11,6 +11,7 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\Updates; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Updates\AuthorSlugUpdate; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -27,18 +28,14 @@ final class AuthorSlugUpdateTest extends FunctionalTestCase 'typo3conf/ext/blog' ]; - /** - * @test - */ + #[Test] public function noUpdateNecessaryTest(): void { $subject = new AuthorSlugUpdate(); self::assertFalse($subject->updateNecessary()); } - /** - * @test - */ + #[Test] public function updateTest(): void { $subject = new AuthorSlugUpdate(); diff --git a/Tests/Functional/Updates/AvatarProviderUpdateTest.php b/Tests/Functional/Updates/AvatarProviderUpdateTest.php index 92d74d2d..6ffe87e5 100644 --- a/Tests/Functional/Updates/AvatarProviderUpdateTest.php +++ b/Tests/Functional/Updates/AvatarProviderUpdateTest.php @@ -11,6 +11,7 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\Updates; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Updates\AvatarProviderUpdate; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -27,18 +28,14 @@ final class AvatarProviderUpdateTest extends FunctionalTestCase 'typo3conf/ext/blog' ]; - /** - * @test - */ + #[Test] public function noUpdateNecessaryTest(): void { $subject = new AvatarProviderUpdate(); self::assertFalse($subject->updateNecessary()); } - /** - * @test - */ + #[Test] public function updateTest(): void { $subject = new AvatarProviderUpdate(); diff --git a/Tests/Functional/Updates/CategorySlugUpdateTest.php b/Tests/Functional/Updates/CategorySlugUpdateTest.php index 179fa34f..0ad3b61d 100644 --- a/Tests/Functional/Updates/CategorySlugUpdateTest.php +++ b/Tests/Functional/Updates/CategorySlugUpdateTest.php @@ -11,6 +11,7 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\Updates; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Updates\CategorySlugUpdate; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -27,18 +28,14 @@ final class CategorySlugUpdateTest extends FunctionalTestCase 'typo3conf/ext/blog' ]; - /** - * @test - */ + #[Test] public function noUpdateNecessaryTest(): void { $subject = new CategorySlugUpdate(); self::assertFalse($subject->updateNecessary()); } - /** - * @test - */ + #[Test] public function updateTest(): void { $subject = new CategorySlugUpdate(); diff --git a/Tests/Functional/Updates/CategoryTypeUpdateTest.php b/Tests/Functional/Updates/CategoryTypeUpdateTest.php index ad79f8c1..c5e64bd0 100644 --- a/Tests/Functional/Updates/CategoryTypeUpdateTest.php +++ b/Tests/Functional/Updates/CategoryTypeUpdateTest.php @@ -11,6 +11,7 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\Updates; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Updates\CategoryTypeUpdate; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -27,18 +28,14 @@ final class CategoryTypeUpdateTest extends FunctionalTestCase 'typo3conf/ext/blog' ]; - /** - * @test - */ + #[Test] public function noUpdateNecessaryTest(): void { $subject = new CategoryTypeUpdate(); self::assertFalse($subject->updateNecessary()); } - /** - * @test - */ + #[Test] public function updateTest(): void { $subject = new CategoryTypeUpdate(); diff --git a/Tests/Functional/Updates/CommentStatusUpdateTest.php b/Tests/Functional/Updates/CommentStatusUpdateTest.php index 6220881a..8a5ba128 100644 --- a/Tests/Functional/Updates/CommentStatusUpdateTest.php +++ b/Tests/Functional/Updates/CommentStatusUpdateTest.php @@ -11,6 +11,7 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\Updates; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Updates\CommentStatusUpdate; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -27,18 +28,14 @@ final class CommentStatusUpdateTest extends FunctionalTestCase 'typo3conf/ext/blog' ]; - /** - * @test - */ + #[Test] public function noUpdateNecessaryTest(): void { $subject = new CommentStatusUpdate(); self::assertFalse($subject->updateNecessary()); } - /** - * @test - */ + #[Test] public function updateTest(): void { $subject = new CommentStatusUpdate(); diff --git a/Tests/Functional/Updates/DatabaseMonthYearUpdateTest.php b/Tests/Functional/Updates/DatabaseMonthYearUpdateTest.php index 1bcd16dc..abae2e91 100644 --- a/Tests/Functional/Updates/DatabaseMonthYearUpdateTest.php +++ b/Tests/Functional/Updates/DatabaseMonthYearUpdateTest.php @@ -11,6 +11,7 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\Updates; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Updates\DatabaseMonthYearUpdate; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -27,18 +28,14 @@ final class DatabaseMonthYearUpdateTest extends FunctionalTestCase 'typo3conf/ext/blog' ]; - /** - * @test - */ + #[Test] public function noUpdateNecessaryTest(): void { $subject = new DatabaseMonthYearUpdate(); self::assertFalse($subject->updateNecessary()); } - /** - * @test - */ + #[Test] public function updateTest(): void { $subject = new DatabaseMonthYearUpdate(); diff --git a/Tests/Functional/Updates/DatabasePublishDateUpdateTest.php b/Tests/Functional/Updates/DatabasePublishDateUpdateTest.php index 89339fc3..47c34add 100644 --- a/Tests/Functional/Updates/DatabasePublishDateUpdateTest.php +++ b/Tests/Functional/Updates/DatabasePublishDateUpdateTest.php @@ -11,6 +11,7 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\Updates; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Updates\DatabasePublishDateUpdate; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -27,18 +28,14 @@ final class DatabasePublishDateUpdateTest extends FunctionalTestCase 'typo3conf/ext/blog' ]; - /** - * @test - */ + #[Test] public function noUpdateNecessaryTest(): void { $subject = new DatabasePublishDateUpdate(); self::assertFalse($subject->updateNecessary()); } - /** - * @test - */ + #[Test] public function updateTest(): void { $subject = new DatabasePublishDateUpdate(); diff --git a/Tests/Functional/Updates/FeaturedImageUpdateTest.php b/Tests/Functional/Updates/FeaturedImageUpdateTest.php index 618335d8..2742bd23 100644 --- a/Tests/Functional/Updates/FeaturedImageUpdateTest.php +++ b/Tests/Functional/Updates/FeaturedImageUpdateTest.php @@ -11,6 +11,7 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\Updates; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Updates\FeaturedImageUpdate; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -27,18 +28,14 @@ final class FeaturedImageUpdateTest extends FunctionalTestCase 'typo3conf/ext/blog' ]; - /** - * @test - */ + #[Test] public function noUpdateNecessaryTest(): void { $subject = new FeaturedImageUpdate(); self::assertFalse($subject->updateNecessary()); } - /** - * @test - */ + #[Test] public function updateTest(): void { $subject = new FeaturedImageUpdate(); diff --git a/Tests/Functional/Updates/TagSlugUpdateTest.php b/Tests/Functional/Updates/TagSlugUpdateTest.php index 88abf940..8aa67a7c 100644 --- a/Tests/Functional/Updates/TagSlugUpdateTest.php +++ b/Tests/Functional/Updates/TagSlugUpdateTest.php @@ -11,6 +11,7 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\Updates; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Updates\TagSlugUpdate; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -27,18 +28,14 @@ final class TagSlugUpdateTest extends FunctionalTestCase 'typo3conf/ext/blog' ]; - /** - * @test - */ + #[Test] public function noUpdateNecessaryTest(): void { $subject = new TagSlugUpdate(); self::assertFalse($subject->updateNecessary()); } - /** - * @test - */ + #[Test] public function updateTest(): void { $subject = new TagSlugUpdate(); diff --git a/Tests/Functional/ViewHelpers/Data/ContentListOptionsViewHelperTest.php b/Tests/Functional/ViewHelpers/Data/ContentListOptionsViewHelperTest.php index f35ef3af..a2885858 100644 --- a/Tests/Functional/ViewHelpers/Data/ContentListOptionsViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Data/ContentListOptionsViewHelperTest.php @@ -11,6 +11,7 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers\Data; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Constants; use T3G\AgencyPack\Blog\Tests\Functional\SiteBasedTestCase; @@ -20,9 +21,7 @@ final class ContentListOptionsViewHelperTest extends SiteBasedTestCase 'form' ]; - /** - * @test - */ + #[Test] public function render(): void { $this->createTestSite(); @@ -45,9 +44,7 @@ public function render(): void ); } - /** - * @test - */ + #[Test] public function renderWithOverwrite(): void { $this->createTestSite(); diff --git a/Tests/Functional/ViewHelpers/GravatarViewHelperTest.php b/Tests/Functional/ViewHelpers/GravatarViewHelperTest.php index 73d8e038..a46b3b26 100644 --- a/Tests/Functional/ViewHelpers/GravatarViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/GravatarViewHelperTest.php @@ -11,6 +11,8 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Core\TypoScript\AST\Node\RootNode; @@ -30,10 +32,8 @@ final class GravatarViewHelperTest extends FunctionalTestCase 'typo3conf/ext/blog' ]; - /** - * @test - * @dataProvider renderDataProvider - */ + #[Test] + #[DataProvider('renderDataProvider')] public function render(string $template, string $expected): void { $frontendTypoScript = new FrontendTypoScript(new RootNode(), [], [], []); diff --git a/Tests/Functional/ViewHelpers/Link/ArchiveViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/ArchiveViewHelperTest.php index ff5d2662..7a09cbd0 100644 --- a/Tests/Functional/ViewHelpers/Link/ArchiveViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/ArchiveViewHelperTest.php @@ -11,6 +11,8 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers\Link; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Constants; use T3G\AgencyPack\Blog\Tests\Functional\SiteBasedTestCase; use TYPO3\CMS\Core\Database\ConnectionPool; @@ -21,10 +23,8 @@ final class ArchiveViewHelperTest extends SiteBasedTestCase 'form' ]; - /** - * @test - * @dataProvider renderDataProvider - */ + #[Test] + #[DataProvider('renderDataProvider')] public function render(string $template, string $expected): void { $this->createTestSite(); diff --git a/Tests/Functional/ViewHelpers/Link/AuthorViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/AuthorViewHelperTest.php index e8ca8f36..6a8a39c5 100644 --- a/Tests/Functional/ViewHelpers/Link/AuthorViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/AuthorViewHelperTest.php @@ -11,6 +11,8 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers\Link; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Tests\Functional\SiteBasedTestCase; use TYPO3\CMS\Core\Database\ConnectionPool; @@ -20,10 +22,8 @@ final class AuthorViewHelperTest extends SiteBasedTestCase 'form' ]; - /** - * @test - * @dataProvider renderDataProvider - */ + #[Test] + #[DataProvider('renderDataProvider')] public function render(string $template, string $expected): void { $this->createTestSite(); diff --git a/Tests/Functional/ViewHelpers/Link/Be/AuthorViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/Be/AuthorViewHelperTest.php index c1d90b43..9b329664 100644 --- a/Tests/Functional/ViewHelpers/Link/Be/AuthorViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/Be/AuthorViewHelperTest.php @@ -11,6 +11,8 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers\Link\Be; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Domain\Model\Author; use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; use TYPO3\CMS\Core\Http\NormalizedParams; @@ -39,10 +41,8 @@ public function setUp(): void ->withAttribute('normalizedParams', new NormalizedParams([], [], '', '')); } - /** - * @test - * @dataProvider renderDataProvider - */ + #[Test] + #[DataProvider('renderDataProvider')] public function render(string $template, string $expected): void { $author = new Author(); diff --git a/Tests/Functional/ViewHelpers/Link/Be/CategoryViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/Be/CategoryViewHelperTest.php index 4be80620..223ef0ab 100644 --- a/Tests/Functional/ViewHelpers/Link/Be/CategoryViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/Be/CategoryViewHelperTest.php @@ -11,6 +11,8 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers\Link\Be; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Domain\Model\Category; use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; use TYPO3\CMS\Core\Http\NormalizedParams; @@ -39,10 +41,8 @@ public function setUp(): void ->withAttribute('normalizedParams', new NormalizedParams([], [], '', '')); } - /** - * @test - * @dataProvider renderDataProvider - */ + #[Test] + #[DataProvider('renderDataProvider')] public function render(string $template, string $expected): void { $category = new Category(); diff --git a/Tests/Functional/ViewHelpers/Link/Be/CommentViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/Be/CommentViewHelperTest.php index 0bf5a969..2951b840 100644 --- a/Tests/Functional/ViewHelpers/Link/Be/CommentViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/Be/CommentViewHelperTest.php @@ -11,6 +11,8 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers\Link\Be; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Domain\Model\Comment; use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; use TYPO3\CMS\Core\Http\NormalizedParams; @@ -39,10 +41,8 @@ public function setUp(): void ->withAttribute('normalizedParams', new NormalizedParams([], [], '', '')); } - /** - * @test - * @dataProvider renderDataProvider - */ + #[Test] + #[DataProvider('renderDataProvider')] public function render(string $template, string $expected): void { $comment = new Comment(); diff --git a/Tests/Functional/ViewHelpers/Link/Be/PostViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/Be/PostViewHelperTest.php index 45e880f9..1987e937 100644 --- a/Tests/Functional/ViewHelpers/Link/Be/PostViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/Be/PostViewHelperTest.php @@ -11,6 +11,8 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers\Link\Be; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Domain\Model\Post; use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; use TYPO3\CMS\Core\Http\NormalizedParams; @@ -39,10 +41,8 @@ public function setUp(): void ->withAttribute('normalizedParams', new NormalizedParams([], [], '', '')); } - /** - * @test - * @dataProvider renderDataProvider - */ + #[Test] + #[DataProvider('renderDataProvider')] public function render(string $template, string $expected): void { $post = new Post(); diff --git a/Tests/Functional/ViewHelpers/Link/Be/TagViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/Be/TagViewHelperTest.php index 77c51218..e16dbe95 100644 --- a/Tests/Functional/ViewHelpers/Link/Be/TagViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/Be/TagViewHelperTest.php @@ -11,6 +11,8 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers\Link\Be; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Domain\Model\Tag; use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; use TYPO3\CMS\Core\Http\NormalizedParams; @@ -39,10 +41,8 @@ public function setUp(): void ->withAttribute('normalizedParams', new NormalizedParams([], [], '', '')); } - /** - * @test - * @dataProvider renderDataProvider - */ + #[Test] + #[DataProvider('renderDataProvider')] public function render(string $template, string $expected): void { $tag = new Tag(); diff --git a/Tests/Functional/ViewHelpers/Link/CategoryViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/CategoryViewHelperTest.php index 673e4ad5..4a84b31e 100644 --- a/Tests/Functional/ViewHelpers/Link/CategoryViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/CategoryViewHelperTest.php @@ -11,6 +11,8 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers\Link; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Constants; use T3G\AgencyPack\Blog\Tests\Functional\SiteBasedTestCase; use TYPO3\CMS\Core\Database\ConnectionPool; @@ -21,10 +23,8 @@ final class CategoryViewHelperTest extends SiteBasedTestCase 'form' ]; - /** - * @test - * @dataProvider renderDataProvider - */ + #[Test] + #[DataProvider('renderDataProvider')] public function render(string $template, string $expected): void { $this->createTestSite(); diff --git a/Tests/Functional/ViewHelpers/Link/PostViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/PostViewHelperTest.php index 3134aa7e..84dd5079 100644 --- a/Tests/Functional/ViewHelpers/Link/PostViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/PostViewHelperTest.php @@ -11,6 +11,8 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers\Link; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Constants; use T3G\AgencyPack\Blog\Tests\Functional\SiteBasedTestCase; use TYPO3\CMS\Core\Database\ConnectionPool; @@ -21,10 +23,8 @@ final class PostViewHelperTest extends SiteBasedTestCase 'form' ]; - /** - * @test - * @dataProvider renderDataProvider - */ + #[Test] + #[DataProvider('renderDataProvider')] public function render(string $template, string $expected): void { $this->createTestSite(); diff --git a/Tests/Functional/ViewHelpers/Link/TagViewHelperTest.php b/Tests/Functional/ViewHelpers/Link/TagViewHelperTest.php index c5188129..28095549 100644 --- a/Tests/Functional/ViewHelpers/Link/TagViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Link/TagViewHelperTest.php @@ -11,6 +11,8 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers\Link; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Tests\Functional\SiteBasedTestCase; use TYPO3\CMS\Core\Database\ConnectionPool; @@ -20,10 +22,8 @@ final class TagViewHelperTest extends SiteBasedTestCase 'form' ]; - /** - * @test - * @dataProvider renderDataProvider - */ + #[Test] + #[DataProvider('renderDataProvider')] public function render(string $template, string $expected): void { $this->createTestSite(); diff --git a/Tests/Functional/ViewHelpers/Uri/AvatarViewHelperTest.php b/Tests/Functional/ViewHelpers/Uri/AvatarViewHelperTest.php index 16b8e4e5..1c00926d 100644 --- a/Tests/Functional/ViewHelpers/Uri/AvatarViewHelperTest.php +++ b/Tests/Functional/ViewHelpers/Uri/AvatarViewHelperTest.php @@ -11,6 +11,8 @@ namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers\Uri; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Domain\Model\Author; use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; use TYPO3\CMS\Core\Http\ServerRequest; @@ -31,10 +33,8 @@ final class AvatarViewHelperTest extends FunctionalTestCase 'typo3conf/ext/blog' ]; - /** - * @test - * @dataProvider renderDataProvider - */ + #[Test] + #[DataProvider('renderDataProvider')] public function render(string $template, string $expected): void { $frontendTypoScript = new FrontendTypoScript(new RootNode(), [], [], []); diff --git a/Tests/Unit/ConstantsTest.php b/Tests/Unit/ConstantsTest.php index e60cfa6f..fd236ed4 100644 --- a/Tests/Unit/ConstantsTest.php +++ b/Tests/Unit/ConstantsTest.php @@ -10,14 +10,13 @@ namespace T3G\AgencyPack\Blog\Tests\Unit; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Constants; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; class ConstantsTest extends UnitTestCase { - /** - * @test - */ + #[Test] public function constantForDoktypeOfBlogPostsIsSetCorrectly(): void { self::assertEquals(137, Constants::DOKTYPE_BLOG_POST); diff --git a/Tests/Unit/Domain/Model/PostTest.php b/Tests/Unit/Domain/Model/PostTest.php index 248bc51c..d6e7b9cd 100644 --- a/Tests/Unit/Domain/Model/PostTest.php +++ b/Tests/Unit/Domain/Model/PostTest.php @@ -9,6 +9,7 @@ namespace T3G\AgencyPack\Blog\Tests\Unit\Domain\Model; +use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Constants; use T3G\AgencyPack\Blog\Domain\Model\Post; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; @@ -19,9 +20,7 @@ */ class PostTest extends UnitTestCase { - /** - * @test - */ + #[Test] public function doktypeEqualsConstant(): void { $post = new Post(); diff --git a/Tests/Unit/Service/CommentServiceTest.php b/Tests/Unit/Service/CommentServiceTest.php index 536f3c22..983c253f 100644 --- a/Tests/Unit/Service/CommentServiceTest.php +++ b/Tests/Unit/Service/CommentServiceTest.php @@ -10,6 +10,7 @@ namespace T3G\AgencyPack\Blog\Tests\Unit\Service; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use T3G\AgencyPack\Blog\Domain\Model\Comment; use T3G\AgencyPack\Blog\Domain\Model\Post; @@ -42,9 +43,7 @@ public function initialize(): void ); } - /** - * @test - */ + #[Test] public function inactiveCommentsReturnErrorOnAdd(): void { $this->initialize(); @@ -57,9 +56,7 @@ public function inactiveCommentsReturnErrorOnAdd(): void self::assertSame(CommentService::STATE_ERROR, $result); } - /** - * @test - */ + #[Test] public function activeCommentsWithoutModerationReturnSuccessOnAdd(): void { $this->initialize(); @@ -75,9 +72,7 @@ public function activeCommentsWithoutModerationReturnSuccessOnAdd(): void self::assertSame(CommentService::STATE_SUCCESS, $result); } - /** - * @test - */ + #[Test] public function activeCommentsWithModerationReturnModerationOnAdd(): void { $this->initialize(); @@ -93,9 +88,7 @@ public function activeCommentsWithModerationReturnModerationOnAdd(): void self::assertSame(CommentService::STATE_MODERATION, $result); } - /** - * @test - */ + #[Test] public function commentGetsAddedToPost(): void { $this->initialize(); @@ -110,9 +103,7 @@ public function commentGetsAddedToPost(): void self::assertSame($comment, $post->getComments()->current()); } - /** - * @test - */ + #[Test] public function postGetsUpdatedInDatabase(): void { $this->initialize(); From 52881e0efb18227c4ba540500c9d7594b0203175 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 14:05:22 +0200 Subject: [PATCH 23/49] [TASK] Correct DataHandlerHookTest namespace to match psr-4 --- Tests/Functional/Hooks/DataHandlerHookTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Functional/Hooks/DataHandlerHookTest.php b/Tests/Functional/Hooks/DataHandlerHookTest.php index 0eb2c59a..e68af884 100644 --- a/Tests/Functional/Hooks/DataHandlerHookTest.php +++ b/Tests/Functional/Hooks/DataHandlerHookTest.php @@ -9,7 +9,7 @@ * LICENSE file that was distributed with this source code. */ -namespace T3G\AgencyPack\Blog\Tests\Functional\Service; +namespace T3G\AgencyPack\Blog\Tests\Functional\Hooks; use PHPUnit\Framework\Attributes\Test; use T3G\AgencyPack\Blog\Constants; From 60eede4a9eb6b4480afed66b7ff5061129796175 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 15:28:32 +0200 Subject: [PATCH 24/49] [TASK] Replace getTwoLetterIsoCode Has been deprecated in v12 and removed in v13. --- Classes/Controller/PostController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Controller/PostController.php b/Classes/Controller/PostController.php index 24b568cf..0f3d41d3 100644 --- a/Classes/Controller/PostController.php +++ b/Classes/Controller/PostController.php @@ -94,7 +94,7 @@ protected function initializeView($view): void $feedData = [ 'title' => LocalizationUtility::translate('feed.title' . $action, 'blog', $arguments), 'description' => LocalizationUtility::translate('feed.description' . $action, 'blog', $arguments), - 'language' => $this->getSiteLanguage()->getTwoLetterIsoCode(), + 'language' => $this->getSiteLanguage()->getLocale()->getLanguageCode(), 'link' => $this->getRequestUrl(), 'date' => date('r'), ]; From 0f98fac56120f7db5acd1221acde2a6965d7f84a Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 15:35:31 +0200 Subject: [PATCH 25/49] [TASK] Register icons via Configuration/Icons.php IconRegistry usage in ext_*.php has been deprecated --- Configuration/Icons.php | 41 +++++++++++++++++++++++++++++++++++++++++ ext_tables.php | 39 --------------------------------------- 2 files changed, 41 insertions(+), 39 deletions(-) create mode 100644 Configuration/Icons.php diff --git a/Configuration/Icons.php b/Configuration/Icons.php new file mode 100644 index 00000000..9fb95e94 --- /dev/null +++ b/Configuration/Icons.php @@ -0,0 +1,41 @@ + ['provider' => SvgIconProvider::class, 'source' => $source], [ + 'actions-approve' => 'EXT:blog/Resources/Public/Icons/actions-approve.svg', + 'actions-decline' => 'EXT:blog/Resources/Public/Icons/actions-decline.svg', + 'module-blog' => 'EXT:blog/Resources/Public/Icons/module-blog.svg', + 'module-blog-posts' => 'EXT:blog/Resources/Public/Icons/module-blog-posts.svg', + 'module-blog-comments' => 'EXT:blog/Resources/Public/Icons/module-blog-comments.svg', + 'module-blog-setup' => 'EXT:blog/Resources/Public/Icons/module-blog-setup.svg', + 'plugin-blog-archive' => 'EXT:blog/Resources/Public/Icons/plugin-blog-archive.svg', + 'plugin-blog-authorposts' => 'EXT:blog/Resources/Public/Icons/plugin-blog-authorposts.svg', + 'plugin-blog-authors' => 'EXT:blog/Resources/Public/Icons/plugin-blog-authors.svg', + 'plugin-blog-category' => 'EXT:blog/Resources/Public/Icons/plugin-blog-category.svg', + 'plugin-blog-commentform' => 'EXT:blog/Resources/Public/Icons/plugin-blog-commentform.svg', + 'plugin-blog-comments' => 'EXT:blog/Resources/Public/Icons/plugin-blog-comments.svg', + 'plugin-blog-demandedposts' => 'EXT:blog/Resources/Public/Icons/plugin-blog-demandedposts.svg', + 'plugin-blog-header' => 'EXT:blog/Resources/Public/Icons/plugin-blog-header.svg', + 'plugin-blog-footer' => 'EXT:blog/Resources/Public/Icons/plugin-blog-footer.svg', + 'plugin-blog-posts' => 'EXT:blog/Resources/Public/Icons/plugin-blog-posts.svg', + 'plugin-blog-relatedposts' => 'EXT:blog/Resources/Public/Icons/plugin-blog-relatedposts.svg', + 'plugin-blog-sidebar' => 'EXT:blog/Resources/Public/Icons/plugin-blog-sidebar.svg', + 'plugin-blog-tag' => 'EXT:blog/Resources/Public/Icons/plugin-blog-tag.svg', + 'record-blog-author' => 'EXT:blog/Resources/Public/Icons/record-blog-author.svg', + 'record-blog-comment' => 'EXT:blog/Resources/Public/Icons/record-blog-comment.svg', + 'record-blog-page' => 'EXT:blog/Resources/Public/Icons/record-blog-page.svg', + 'record-blog-page-root' => 'EXT:blog/Resources/Public/Icons/record-blog-page-root.svg', + 'record-blog-post' => 'EXT:blog/Resources/Public/Icons/record-blog-post.svg', + 'record-blog-tag' => 'EXT:blog/Resources/Public/Icons/record-blog-tag.svg', + 'record-blog-category' => 'EXT:blog/Resources/Public/Icons/record-blog-category.svg', + 'record-folder-contains-blog' => 'EXT:blog/Resources/Public/Icons/record-folder-contains-blog.svg', +]); diff --git a/ext_tables.php b/ext_tables.php index a7016853..30b307f0 100644 --- a/ext_tables.php +++ b/ext_tables.php @@ -8,11 +8,8 @@ */ use T3G\AgencyPack\Blog\Constants; -use TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider; -use TYPO3\CMS\Core\Imaging\IconRegistry; use TYPO3\CMS\Core\Information\Typo3Version; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; -use TYPO3\CMS\Core\Utility\GeneralUtility; if (!defined('TYPO3')) { die('Access denied.'); @@ -28,42 +25,6 @@ 'allowedTables' => '*', ]; -// Provide icon for page tree, list view, ... : -$icons = [ - 'actions-approve' => 'EXT:blog/Resources/Public/Icons/actions-approve.svg', - 'actions-decline' => 'EXT:blog/Resources/Public/Icons/actions-decline.svg', - 'module-blog' => 'EXT:blog/Resources/Public/Icons/module-blog.svg', - 'module-blog-posts' => 'EXT:blog/Resources/Public/Icons/module-blog-posts.svg', - 'module-blog-comments' => 'EXT:blog/Resources/Public/Icons/module-blog-comments.svg', - 'module-blog-setup' => 'EXT:blog/Resources/Public/Icons/module-blog-setup.svg', - 'plugin-blog-archive' => 'EXT:blog/Resources/Public/Icons/plugin-blog-archive.svg', - 'plugin-blog-authorposts' => 'EXT:blog/Resources/Public/Icons/plugin-blog-authorposts.svg', - 'plugin-blog-authors' => 'EXT:blog/Resources/Public/Icons/plugin-blog-authors.svg', - 'plugin-blog-category' => 'EXT:blog/Resources/Public/Icons/plugin-blog-category.svg', - 'plugin-blog-commentform' => 'EXT:blog/Resources/Public/Icons/plugin-blog-commentform.svg', - 'plugin-blog-comments' => 'EXT:blog/Resources/Public/Icons/plugin-blog-comments.svg', - 'plugin-blog-demandedposts' => 'EXT:blog/Resources/Public/Icons/plugin-blog-demandedposts.svg', - 'plugin-blog-header' => 'EXT:blog/Resources/Public/Icons/plugin-blog-header.svg', - 'plugin-blog-footer' => 'EXT:blog/Resources/Public/Icons/plugin-blog-footer.svg', - 'plugin-blog-posts' => 'EXT:blog/Resources/Public/Icons/plugin-blog-posts.svg', - 'plugin-blog-relatedposts' => 'EXT:blog/Resources/Public/Icons/plugin-blog-relatedposts.svg', - 'plugin-blog-sidebar' => 'EXT:blog/Resources/Public/Icons/plugin-blog-sidebar.svg', - 'plugin-blog-tag' => 'EXT:blog/Resources/Public/Icons/plugin-blog-tag.svg', - 'record-blog-author' => 'EXT:blog/Resources/Public/Icons/record-blog-author.svg', - 'record-blog-comment' => 'EXT:blog/Resources/Public/Icons/record-blog-comment.svg', - 'record-blog-page' => 'EXT:blog/Resources/Public/Icons/record-blog-page.svg', - 'record-blog-page-root' => 'EXT:blog/Resources/Public/Icons/record-blog-page-root.svg', - 'record-blog-post' => 'EXT:blog/Resources/Public/Icons/record-blog-post.svg', - 'record-blog-tag' => 'EXT:blog/Resources/Public/Icons/record-blog-tag.svg', - 'record-blog-category' => 'EXT:blog/Resources/Public/Icons/record-blog-category.svg', - 'record-folder-contains-blog' => 'EXT:blog/Resources/Public/Icons/record-folder-contains-blog.svg', -]; - -$iconRegistry = GeneralUtility::makeInstance(IconRegistry::class); -foreach ($icons as $identifier => $path) { - $iconRegistry->registerIcon($identifier, SvgIconProvider::class, ['source' => $path]); -} - // Replaced with Configuration/user.tsconfig in v13 if ((new Typo3Version())->getMajorVersion() < 13) { ExtensionManagementUtility::addUserTSConfig(' From 85c4716b43a14b96a5653e221f0895728efb1e72 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Wed, 16 Oct 2024 16:09:49 +0200 Subject: [PATCH 26/49] [TASK] Migrate to ES6 JavaScript modules RequireJS has been deprecated in v12 and removed in v13 --- Classes/Controller/BackendController.php | 9 ++- Configuration/JavaScriptModules.php | 17 +++++ .../backend/{Datatables.js => datatables.js} | 0 .../backend/{MassUpdate.js => mass-update.js} | 0 .../{SetupWizard.js => setup-wizard.js} | 4 +- Resources/Public/Css/datatables.min.css | 6 ++ Resources/Public/JavaScript/Datatables.js | 2 - Resources/Public/JavaScript/MassUpdate.js | 1 - Resources/Public/JavaScript/SetupWizard.js | 1 - Resources/Public/JavaScript/datatables.js | 2 + ....LICENSE.txt => datatables.js.LICENSE.txt} | 0 Resources/Public/JavaScript/mass-update.js | 1 + Resources/Public/JavaScript/setup-wizard.js | 1 + webpack.config.js | 60 ---------------- webpack.config.mjs | 69 +++++++++++++++++++ 15 files changed, 102 insertions(+), 71 deletions(-) create mode 100644 Configuration/JavaScriptModules.php rename Resources/Private/JavaScript/backend/{Datatables.js => datatables.js} (100%) rename Resources/Private/JavaScript/backend/{MassUpdate.js => mass-update.js} (100%) rename Resources/Private/JavaScript/backend/{SetupWizard.js => setup-wizard.js} (96%) create mode 100644 Resources/Public/Css/datatables.min.css delete mode 100644 Resources/Public/JavaScript/Datatables.js delete mode 100644 Resources/Public/JavaScript/MassUpdate.js delete mode 100644 Resources/Public/JavaScript/SetupWizard.js create mode 100644 Resources/Public/JavaScript/datatables.js rename Resources/Public/JavaScript/{Datatables.js.LICENSE.txt => datatables.js.LICENSE.txt} (100%) create mode 100644 Resources/Public/JavaScript/mass-update.js create mode 100644 Resources/Public/JavaScript/setup-wizard.js delete mode 100644 webpack.config.js create mode 100644 webpack.config.mjs diff --git a/Classes/Controller/BackendController.php b/Classes/Controller/BackendController.php index abfb6411..380dd42a 100644 --- a/Classes/Controller/BackendController.php +++ b/Classes/Controller/BackendController.php @@ -49,14 +49,13 @@ public function __construct( public function initializeAction(): void { - $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Tooltip'); $this->pageRenderer->addCssFile('EXT:blog/Resources/Public/Css/backend.min.css', 'stylesheet', 'all', '', false); } public function initializeSetupWizardAction(): void { $this->initializeDataTables(); - $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Blog/SetupWizard'); + $this->pageRenderer->loadJavaScriptModule('@t3g/blog/setup-wizard.js'); } public function initializePostsAction(): void @@ -67,13 +66,13 @@ public function initializePostsAction(): void public function initializeCommentsAction(): void { $this->initializeDataTables(); - $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Blog/MassUpdate'); + $this->pageRenderer->loadJavaScriptModule('@t3g/blog/mass-update.js'); } protected function initializeDataTables(): void { - $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Blog/Datatables'); - $this->pageRenderer->addCssFile('EXT:blog/Resources/Public/Css/Datatables.min.css', 'stylesheet', 'all', '', false); + $this->pageRenderer->loadJavaScriptModule('@t3g/blog/datatables.js'); + $this->pageRenderer->addCssFile('EXT:blog/Resources/Public/Css/datatables.min.css', 'stylesheet', 'all', '', false); } public function setupWizardAction(): ResponseInterface diff --git a/Configuration/JavaScriptModules.php b/Configuration/JavaScriptModules.php new file mode 100644 index 00000000..66944d8b --- /dev/null +++ b/Configuration/JavaScriptModules.php @@ -0,0 +1,17 @@ + [ + 'backend', + ], + 'imports' => [ + '@t3g/blog/' => 'EXT:blog/Resources/Public/JavaScript/', + ], +]; diff --git a/Resources/Private/JavaScript/backend/Datatables.js b/Resources/Private/JavaScript/backend/datatables.js similarity index 100% rename from Resources/Private/JavaScript/backend/Datatables.js rename to Resources/Private/JavaScript/backend/datatables.js diff --git a/Resources/Private/JavaScript/backend/MassUpdate.js b/Resources/Private/JavaScript/backend/mass-update.js similarity index 100% rename from Resources/Private/JavaScript/backend/MassUpdate.js rename to Resources/Private/JavaScript/backend/mass-update.js diff --git a/Resources/Private/JavaScript/backend/SetupWizard.js b/Resources/Private/JavaScript/backend/setup-wizard.js similarity index 96% rename from Resources/Private/JavaScript/backend/SetupWizard.js rename to Resources/Private/JavaScript/backend/setup-wizard.js index cbcb5f71..51654b6c 100644 --- a/Resources/Private/JavaScript/backend/SetupWizard.js +++ b/Resources/Private/JavaScript/backend/setup-wizard.js @@ -1,8 +1,8 @@ /** * Module: TYPO3/CMS/Blog/SetupWizard */ -import Modal from "TYPO3/CMS/Backend/Modal"; -import Severity from "TYPO3/CMS/Backend/Severity"; +import Modal from "@typo3/backend/modal"; +import Severity from "@typo3/backend/severity"; const SetupWizard = { triggerSelector: '.t3js-setup-wizard-trigger', diff --git a/Resources/Public/Css/datatables.min.css b/Resources/Public/Css/datatables.min.css new file mode 100644 index 00000000..ec6e2e27 --- /dev/null +++ b/Resources/Public/Css/datatables.min.css @@ -0,0 +1,6 @@ +:root{--dt-row-selected: 13, 110, 253;--dt-row-selected-text: 255, 255, 255;--dt-row-selected-link: 9, 10, 11}table.dataTable td.dt-control{text-align:center;cursor:pointer}table.dataTable td.dt-control:before{height:1em;width:1em;margin-top:-9px;display:inline-block;color:#fff;border:.15em solid #fff;border-radius:1em;-webkit-box-shadow:0 0 .2em #444;box-shadow:0 0 .2em #444;-webkit-box-sizing:content-box;box-sizing:content-box;text-align:center;text-indent:0 !important;font-family:"Courier New",Courier,monospace;line-height:1em;content:"+";background-color:#31b131}table.dataTable tr.dt-hasChild td.dt-control:before{content:"-";background-color:#d33333}table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting_asc_disabled,table.dataTable thead>tr>th.sorting_desc_disabled,table.dataTable thead>tr>td.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting_asc_disabled,table.dataTable thead>tr>td.sorting_desc_disabled{cursor:pointer;position:relative;padding-right:26px}table.dataTable thead>tr>th.sorting:before,table.dataTable thead>tr>th.sorting:after,table.dataTable thead>tr>th.sorting_asc:before,table.dataTable thead>tr>th.sorting_asc:after,table.dataTable thead>tr>th.sorting_desc:before,table.dataTable thead>tr>th.sorting_desc:after,table.dataTable thead>tr>th.sorting_asc_disabled:before,table.dataTable thead>tr>th.sorting_asc_disabled:after,table.dataTable thead>tr>th.sorting_desc_disabled:before,table.dataTable thead>tr>th.sorting_desc_disabled:after,table.dataTable thead>tr>td.sorting:before,table.dataTable thead>tr>td.sorting:after,table.dataTable thead>tr>td.sorting_asc:before,table.dataTable thead>tr>td.sorting_asc:after,table.dataTable thead>tr>td.sorting_desc:before,table.dataTable thead>tr>td.sorting_desc:after,table.dataTable thead>tr>td.sorting_asc_disabled:before,table.dataTable thead>tr>td.sorting_asc_disabled:after,table.dataTable thead>tr>td.sorting_desc_disabled:before,table.dataTable thead>tr>td.sorting_desc_disabled:after{position:absolute;display:block;opacity:.125;right:10px;line-height:9px;font-size:.8em}table.dataTable thead>tr>th.sorting:before,table.dataTable thead>tr>th.sorting_asc:before,table.dataTable thead>tr>th.sorting_desc:before,table.dataTable thead>tr>th.sorting_asc_disabled:before,table.dataTable thead>tr>th.sorting_desc_disabled:before,table.dataTable thead>tr>td.sorting:before,table.dataTable thead>tr>td.sorting_asc:before,table.dataTable thead>tr>td.sorting_desc:before,table.dataTable thead>tr>td.sorting_asc_disabled:before,table.dataTable thead>tr>td.sorting_desc_disabled:before{bottom:50%;content:"▲";content:"▲"/""}table.dataTable thead>tr>th.sorting:after,table.dataTable thead>tr>th.sorting_asc:after,table.dataTable thead>tr>th.sorting_desc:after,table.dataTable thead>tr>th.sorting_asc_disabled:after,table.dataTable thead>tr>th.sorting_desc_disabled:after,table.dataTable thead>tr>td.sorting:after,table.dataTable thead>tr>td.sorting_asc:after,table.dataTable thead>tr>td.sorting_desc:after,table.dataTable thead>tr>td.sorting_asc_disabled:after,table.dataTable thead>tr>td.sorting_desc_disabled:after{top:50%;content:"▼";content:"▼"/""}table.dataTable thead>tr>th.sorting_asc:before,table.dataTable thead>tr>th.sorting_desc:after,table.dataTable thead>tr>td.sorting_asc:before,table.dataTable thead>tr>td.sorting_desc:after{opacity:.6}table.dataTable thead>tr>th.sorting_desc_disabled:after,table.dataTable thead>tr>th.sorting_asc_disabled:before,table.dataTable thead>tr>td.sorting_desc_disabled:after,table.dataTable thead>tr>td.sorting_asc_disabled:before{display:none}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}div.dataTables_scrollBody>table.dataTable>thead>tr>th:before,div.dataTables_scrollBody>table.dataTable>thead>tr>th:after,div.dataTables_scrollBody>table.dataTable>thead>tr>td:before,div.dataTables_scrollBody>table.dataTable>thead>tr>td:after{display:none}div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:2px}div.dataTables_processing>div:last-child{position:relative;width:80px;height:15px;margin:1em auto}div.dataTables_processing>div:last-child>div{position:absolute;top:0;width:13px;height:13px;border-radius:50%;background:#0d6efd;background:rgb(var(--dt-row-selected));-webkit-animation-timing-function:cubic-bezier(0, 1, 1, 0);animation-timing-function:cubic-bezier(0, 1, 1, 0)}div.dataTables_processing>div:last-child>div:nth-child(1){left:8px;-webkit-animation:datatables-loader-1 .6s infinite;animation:datatables-loader-1 .6s infinite}div.dataTables_processing>div:last-child>div:nth-child(2){left:8px;-webkit-animation:datatables-loader-2 .6s infinite;animation:datatables-loader-2 .6s infinite}div.dataTables_processing>div:last-child>div:nth-child(3){left:32px;-webkit-animation:datatables-loader-2 .6s infinite;animation:datatables-loader-2 .6s infinite}div.dataTables_processing>div:last-child>div:nth-child(4){left:56px;-webkit-animation:datatables-loader-3 .6s infinite;animation:datatables-loader-3 .6s infinite}@-webkit-keyframes datatables-loader-1{0%{-webkit-transform:scale(0);transform:scale(0)}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes datatables-loader-1{0%{-webkit-transform:scale(0);transform:scale(0)}100%{-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes datatables-loader-3{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0);transform:scale(0)}}@keyframes datatables-loader-3{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0);transform:scale(0)}}@-webkit-keyframes datatables-loader-2{0%{-webkit-transform:translate(0, 0);transform:translate(0, 0)}100%{-webkit-transform:translate(24px, 0);transform:translate(24px, 0)}}@keyframes datatables-loader-2{0%{-webkit-transform:translate(0, 0);transform:translate(0, 0)}100%{-webkit-transform:translate(24px, 0);transform:translate(24px, 0)}}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th,table.dataTable thead td,table.dataTable tfoot th,table.dataTable tfoot td{text-align:left}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}/*! Bootstrap 5 integration for DataTables +* +* ©2020 SpryMedia Ltd, all rights reserved. +* License: MIT datatables.net/license/mit +*/table.dataTable{clear:both;margin-top:6px !important;margin-bottom:6px !important;max-width:none !important;border-collapse:separate !important;border-spacing:0}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.table-striped>tbody>tr:nth-of-type(2n+1)>*{-webkit-box-shadow:none;box-shadow:none}table.dataTable>tbody>tr{background-color:rgba(0,0,0,0)}table.dataTable>tbody>tr.selected>*{-webkit-box-shadow:inset 0 0 0 9999px #0d6efd;box-shadow:inset 0 0 0 9999px #0d6efd;-webkit-box-shadow:inset 0 0 0 9999px rgb(var(--dt-row-selected));box-shadow:inset 0 0 0 9999px rgb(var(--dt-row-selected));color:#fff;color:rgb(var(--dt-row-selected-text))}table.dataTable>tbody>tr.selected a{color:#090a0b;color:rgb(var(--dt-row-selected-link))}table.dataTable.table-striped>tbody>tr.odd>*{-webkit-box-shadow:inset 0 0 0 9999px rgba(0,0,0,.05);box-shadow:inset 0 0 0 9999px rgba(0,0,0,.05)}table.dataTable.table-striped>tbody>tr.odd.selected>*{-webkit-box-shadow:inset 0 0 0 9999px rgba(13,110,253,.95);box-shadow:inset 0 0 0 9999px rgba(13,110,253,.95);-webkit-box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.95);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.95)}table.dataTable.table-hover>tbody>tr:hover>*{-webkit-box-shadow:inset 0 0 0 9999px rgba(0,0,0,.075);box-shadow:inset 0 0 0 9999px rgba(0,0,0,.075)}table.dataTable.table-hover>tbody>tr.selected:hover>*{-webkit-box-shadow:inset 0 0 0 9999px rgba(13,110,253,.975);box-shadow:inset 0 0 0 9999px rgba(13,110,253,.975);-webkit-box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.975);box-shadow:inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.975)}div.dataTables_wrapper div.dataTables_length label{font-weight:normal;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:auto;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:normal;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:.85em}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}div.dataTables_wrapper div.dt-row{position:relative}div.dataTables_scrollHead table.dataTable{margin-bottom:0 !important}div.dataTables_scrollBody>table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody>table>thead .sorting:before,div.dataTables_scrollBody>table>thead .sorting_asc:before,div.dataTables_scrollBody>table>thead .sorting_desc:before,div.dataTables_scrollBody>table>thead .sorting:after,div.dataTables_scrollBody>table>thead .sorting_asc:after,div.dataTables_scrollBody>table>thead .sorting_desc:after{display:none}div.dataTables_scrollBody>table>tbody tr:first-child th,div.dataTables_scrollBody>table>tbody tr:first-child td{border-top:none}div.dataTables_scrollFoot>.dataTables_scrollFootInner{-webkit-box-sizing:content-box;box-sizing:content-box}div.dataTables_scrollFoot>.dataTables_scrollFootInner>table{margin-top:0 !important;border-top:none}@media screen and (max-width: 767px){div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_paginate{text-align:center}div.dataTables_wrapper div.dataTables_paginate ul.pagination{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}}table.dataTable.table-sm>thead>tr>th:not(.sorting_disabled){padding-right:20px}table.table-bordered.dataTable{border-right-width:0}table.table-bordered.dataTable thead tr:first-child th,table.table-bordered.dataTable thead tr:first-child td{border-top-width:1px}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-left-width:0}table.table-bordered.dataTable th:first-child,table.table-bordered.dataTable th:first-child,table.table-bordered.dataTable td:first-child,table.table-bordered.dataTable td:first-child{border-left-width:1px}table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable td:last-child{border-right-width:1px}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-bottom-width:1px}div.dataTables_scrollHead table.table-bordered{border-bottom-width:0}div.table-responsive>div.dataTables_wrapper>div.row{margin:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^=col-]:first-child{padding-left:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^=col-]:last-child{padding-right:0} +.table.dataTable{margin-top:0 !important;margin-bottom:0 !important}.table.dataTable .sorting .form-select{min-width:120px}.table.dataTable tfoot th{border-bottom:none}.col-datatable-checkbox{width:16px;min-width:16px;-webkit-box-sizing:content-box;box-sizing:content-box;padding-right:0 !important}.col-datatable-checkbox:after,.col-datatable-checkbox:before{display:none !important}.col-datatable-actions{white-space:nowrap;width:0}.col-datatable-text{white-space:normal !important} diff --git a/Resources/Public/JavaScript/Datatables.js b/Resources/Public/JavaScript/Datatables.js deleted file mode 100644 index 2eea3af6..00000000 --- a/Resources/Public/JavaScript/Datatables.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see Datatables.js.LICENSE.txt */ -define(["jquery"],(function(t){return function(){"use strict";var e={404:function(e){e.exports=t}},n={};function a(t){var r=n[t];if(void 0!==r)return r.exports;var o=n[t]={exports:{}};return e[t](o,o.exports,a),o.exports}a.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};return function(){a.r(r);var t=a(404);let e=t;var n,o,i,l,s=function(t,a){if(s.factory(t,a))return s;if(this instanceof s)return e(t).DataTable(a);a=t,this.$=function(t,e){return this.api(!0).$(t,e)},this._=function(t,e){return this.api(!0).rows(t,e).data()},this.api=function(t){return new o(t?se(this[n.iApiIndex]):this)},this.fnAddData=function(t,n){var a=this.api(!0),r=Array.isArray(t)&&(Array.isArray(t[0])||e.isPlainObject(t[0]))?a.rows.add(t):a.row.add(t);return(void 0===n||n)&&a.draw(),r.flatten().toArray()},this.fnAdjustColumnSizing=function(t){var e=this.api(!0).columns.adjust(),n=e.settings()[0],a=n.oScroll;void 0===t||t?e.draw(!1):""===a.sX&&""===a.sY||Vt(n)},this.fnClearTable=function(t){var e=this.api(!0).clear();(void 0===t||t)&&e.draw()},this.fnClose=function(t){this.api(!0).row(t).child.hide()},this.fnDeleteRow=function(t,e,n){var a=this.api(!0),r=a.rows(t),o=r.settings()[0],i=o.aoData[r[0][0]];return r.remove(),e&&e.call(this,o,i),(void 0===n||n)&&a.draw(),i},this.fnDestroy=function(t){this.api(!0).destroy(t)},this.fnDraw=function(t){this.api(!0).draw(t)},this.fnFilter=function(t,e,n,a,r,o){var i=this.api(!0);null==e?i.search(t,n,a,o):i.column(e).search(t,n,a,o),i.draw()},this.fnGetData=function(t,e){var n=this.api(!0);if(void 0!==t){var a=t.nodeName?t.nodeName.toLowerCase():"";return void 0!==e||"td"==a||"th"==a?n.cell(t,e).data():n.row(t).data()||null}return n.data().toArray()},this.fnGetNodes=function(t){var e=this.api(!0);return void 0!==t?e.row(t).node():e.rows().nodes().flatten().toArray()},this.fnGetPosition=function(t){var e=this.api(!0),n=t.nodeName.toUpperCase();if("TR"==n)return e.row(t).index();if("TD"==n||"TH"==n){var a=e.cell(t).index();return[a.row,a.columnVisible,a.column]}return null},this.fnIsOpen=function(t){return this.api(!0).row(t).child.isShown()},this.fnOpen=function(t,e,n){return this.api(!0).row(t).child(e,n).show().child()[0]},this.fnPageChange=function(t,e){var n=this.api(!0).page(t);(void 0===e||e)&&n.draw(!1)},this.fnSetColumnVis=function(t,e,n){var a=this.api(!0).column(t).visible(e);(void 0===n||n)&&a.columns.adjust().draw()},this.fnSettings=function(){return se(this[n.iApiIndex])},this.fnSort=function(t){this.api(!0).order(t).draw()},this.fnSortListener=function(t,e,n){this.api(!0).order.listener(t,e,n)},this.fnUpdate=function(t,e,n,a,r){var o=this.api(!0);return null==n?o.row(e).data(t):o.cell(e,n).data(t),(void 0===r||r)&&o.columns.adjust(),(void 0===a||a)&&o.draw(),0},this.fnVersionCheck=n.fnVersionCheck;var r=this,i=void 0===a,l=this.length;for(var u in i&&(a={}),this.oApi=this.internal=n.internal,s.ext.internal)u&&(this[u]=Ge(u));return this.each((function(){var t,n=l>1?de({},a,!0):a,o=0,u=this.getAttribute("id"),c=!1,d=s.defaults,f=e(this);if("table"==this.nodeName.toLowerCase()){R(d),j(d.column),F(d,d,!0),F(d.column,d.column,!0),F(d,e.extend(n,f.data()),!0);var h=s.settings;for(o=0,t=h.length;o").appendTo(f)),b.nTHead=i[0];var l=f.children("tbody");0===l.length&&(l=e("").insertAfter(i)),b.nTBody=l[0];var s=f.children("tfoot");if(0===s.length&&r.length>0&&(""!==b.oScroll.sX||""!==b.oScroll.sY)&&(s=e("").appendTo(f)),0===s.length||0===s.children().length?f.addClass(m.sNoFooter):s.length>0&&(b.nTFoot=s[0],ft(b.aoFooter,b.nTFoot)),n.aaData)for(o=0;o/g,f=/^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/,h=new RegExp("(\\"+["/",".","*","+","?","|","(",")","[","]","{","}","\\","$","^","-"].join("|\\")+")","g"),p=/['\u00A0,$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi,g=function(t){return!t||!0===t||"-"===t},v=function(t){var e=parseInt(t,10);return!isNaN(e)&&isFinite(t)?e:null},b=function(t,e){return u[e]||(u[e]=new RegExp(Ct(e),"g")),"string"==typeof t&&"."!==e?t.replace(/\./g,"").replace(u[e],"."):t},m=function(t,e,n){let a=typeof t;var r="string"===a;return"number"===a||"bigint"===a||(!!g(t)||(e&&r&&(t=b(t,e)),n&&r&&(t=t.replace(p,"")),!isNaN(parseFloat(t))&&isFinite(t)))},S=function(t,e,n){if(g(t))return!0;var a=function(t){return g(t)||"string"==typeof t}(t);return a&&!!m(T(t),e,n)||null},y=function(t,e,n){var a=[],r=0,o=t.length;if(void 0!==n)for(;r").css({position:"fixed",top:0,left:-1*e(window).scrollLeft(),height:1,width:1,overflow:"hidden"}).append(e("
").css({position:"absolute",top:1,left:1,width:100,overflow:"scroll"}).append(e("
").css({width:"100%",height:10}))).appendTo("body"),r=a.children(),o=r.children();n.barWidth=r[0].offsetWidth-r[0].clientWidth,n.bScrollOversize=100===o[0].offsetWidth&&100!==r[0].clientWidth,n.bScrollbarLeft=1!==Math.round(o.offset().left),n.bBounding=!!a[0].getBoundingClientRect().width,a.remove()}e.extend(t.oBrowser,s.__browser),t.oScroll.iBarWidth=s.__browser.barWidth}function H(t,e,n,a,r,o){var i,l=a,s=!1;for(void 0!==n&&(i=n,s=!0);l!==r;)t.hasOwnProperty(l)&&(i=s?e(i,t[l],l,t):t[l],s=!0,l+=o);return i}function O(t,n){var a=s.defaults.column,r=t.aoColumns.length,o=e.extend({},s.models.oColumn,a,{nTh:n||document.createElement("th"),sTitle:a.sTitle?a.sTitle:n?n.innerHTML:"",aDataSort:a.aDataSort?a.aDataSort:[r],mData:a.mData?a.mData:r,idx:r});t.aoColumns.push(o);var i=t.aoPreSearchCols;i[r]=e.extend({},s.models.oSearch,i[r]),k(t,r,e(n).data())}function k(t,n,a){var r=t.aoColumns[n],o=t.oClasses,i=e(r.nTh);if(!r.sWidthOrig){r.sWidthOrig=i.attr("width")||null;var l=(i.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/);l&&(r.sWidthOrig=l[1])}if(null!=a){j(a),F(s.defaults.column,a,!0),void 0===a.mDataProp||a.mData||(a.mData=a.mDataProp),a.sType&&(r._sManualType=a.sType),a.className&&!a.sClass&&(a.sClass=a.className),a.sClass&&i.addClass(a.sClass);var u=r.sClass;e.extend(r,a),ce(r,a,"sWidth","sWidthOrig"),u!==r.sClass&&(r.sClass=u+" "+r.sClass),void 0!==a.iDataSort&&(r.aDataSort=[a.iDataSort]),ce(r,a,"aDataSort")}var c=r.mData,d=K(c),f=r.mRender?K(r.mRender):null,h=function(t){return"string"==typeof t&&-1!==t.indexOf("@")};r._bAttrSrc=e.isPlainObject(c)&&(h(c.sort)||h(c.type)||h(c.filter)),r._setter=null,r.fnGetData=function(t,e,n){var a=d(t,e,void 0,n);return f&&e?f(a,e,t,n):a},r.fnSetData=function(t,e,n){return Q(c)(t,e,n)},"number"==typeof c||r._isArrayHost||(t._rowReadObject=!0),t.oFeatures.bSort||(r.bSortable=!1,i.addClass(o.sSortableNone));var p=-1!==e.inArray("asc",r.asSorting),g=-1!==e.inArray("desc",r.asSorting);r.bSortable&&(p||g)?p&&!g?(r.sSortingClass=o.sSortableAsc,r.sSortingClassJUI=o.sSortJUIAscAllowed):!p&&g?(r.sSortingClass=o.sSortableDesc,r.sSortingClassJUI=o.sSortJUIDescAllowed):(r.sSortingClass=o.sSortable,r.sSortingClassJUI=o.sSortJUI):(r.sSortingClass=o.sSortableNone,r.sSortingClassJUI="")}function M(t){if(!1!==t.oFeatures.bAutoWidth){var e=t.aoColumns;qt(t);for(var n=0,a=e.length;n=0;o--){var h=void 0!==(d=n[o]).target?d.target:void 0!==d.targets?d.targets:d.aTargets;for(Array.isArray(h)||(h=[h]),l=0,s=h.length;l=0){for(;f.length<=h[l];)O(t);r(h[l],d)}else if("number"==typeof h[l]&&h[l]<0)r(f.length+h[l],d);else if("string"==typeof h[l])for(u=0,c=f.length;ue&&t[r]--;-1!=a&&void 0===n&&t.splice(a,1)}function at(t,e,n,a){var r,o,i=t.aoData[e],l=function(n,a){for(;n.childNodes.length;)n.removeChild(n.firstChild);n.innerHTML=G(t,e,a,"display")};if("dom"!==n&&(n&&"auto"!==n||"dom"!==i.src)){var s=i.anCells;if(s)if(void 0!==a)l(s[a],a);else for(r=0,o=s.length;r").appendTo(l)),n=0,a=d.length;n=0;i--)t.aoColumns[i].bVisible||a||h[r].splice(i,1);p.push([])}for(r=0,o=h.length;r=t.fnRecordsDisplay()?0:n,t.iInitDisplayStart=-1)}(t);var a=pe(t,"aoPreDrawCallback","preDraw",[t]);if(-1===e.inArray(!1,a)){var r=[],o=0,i=t.asStripeClasses,l=i.length,s=t.oLanguage,u="ssp"==be(t),c=t.aiDisplay,d=t._iDisplayStart,f=t.fnDisplayEnd();if(t.bDrawing=!0,t.bDeferLoading)t.bDeferLoading=!1,t.iDraw++,Bt(t,!1);else if(u){if(!t.bDestroying&&!n)return void gt(t)}else t.iDraw++;if(0!==c.length)for(var h=u?0:d,p=u?t.aoData.length:f,g=h;g",{class:l?i[0]:""}).append(e("",{valign:"top",colSpan:B(t),class:t.oClasses.sRowEmpty}).html(y))[0]}pe(t,"aoHeaderCallback","header",[e(t.nTHead).children("tr")[0],tt(t),d,f,c]),pe(t,"aoFooterCallback","footer",[e(t.nTFoot).children("tr")[0],tt(t),d,f,c]);var D=e(t.nTBody);D.children().detach(),D.append(e(r)),pe(t,"aoDrawCallback","draw",[t]),t.bSorted=!1,t.bFiltered=!1,t.bDrawing=!1}else Bt(t,!1)}function ct(t,e){var n=t.oFeatures,a=n.bSort,r=n.bFilter;a&&Qt(t),r?yt(t,t.oPreviousSearch):t.aiDisplay=t.aiDisplayMaster.slice(),!0!==e&&(t._iDisplayStart=0),t._drawHold=e,ut(t),t._drawHold=!1}function dt(t){var n=t.oClasses,a=e(t.nTable),r=e("
").insertBefore(a),o=t.oFeatures,i=e("
",{id:t.sTableId+"_wrapper",class:n.sWrapper+(t.nTFoot?"":" "+n.sNoFooter)});t.nHolding=r[0],t.nTableWrapper=i[0],t.nTableReinsertBefore=t.nTable.nextSibling;for(var l,u,c,d,f,h,p=t.sDom.split(""),g=0;g")[0],"'"==(d=p[g+1])||'"'==d){for(f="",h=2;p[g+h]!=d;)f+=p[g+h],h++;if("H"==f?f=n.sJUIHeader:"F"==f&&(f=n.sJUIFooter),-1!=f.indexOf(".")){var v=f.split(".");c.id=v[0].substr(1,v[0].length-1),c.className=v[1]}else"#"==f.charAt(0)?c.id=f.substr(1,f.length-1):c.className=f;g+=h}i.append(c),i=e(c)}else if(">"==u)i=i.parent();else if("l"==u&&o.bPaginate&&o.bLengthChange)l=kt(t);else if("f"==u&&o.bFilter)l=St(t);else if("r"==u&&o.bProcessing)l=Wt(t);else if("t"==u)l=Ut(t);else if("i"==u&&o.bInfo)l=Pt(t);else if("p"==u&&o.bPaginate)l=Mt(t);else if(0!==s.ext.feature.length)for(var b=s.ext.feature,m=0,S=b.length;m',s=r.sSearch;s=s.match(/_INPUT_/)?s.replace("_INPUT_",l):s+l;var u=e("
",{id:i.f?null:a+"_filter",class:n.sFilter}).append(e("
").addClass(n.sLength);return t.aanFeatures.l||(d[0].id=a+"_length"),d.children().append(t.oLanguage.sLengthMenu.replace("_MENU_",s[0].outerHTML)),e("select",d).val(t._iDisplayLength).on("change.DT",(function(n){Ot(t,e(this).val()),ut(t)})),e(t.nTable).on("length.dt.DT",(function(n,a,r){t===a&&e("select",d).val(r)})),d[0]}function Mt(t){var n=t.sPaginationType,a=s.ext.pager[n],r="function"==typeof a,o=function(t){ut(t)},i=e("
").addClass(t.oClasses.sPaging+n)[0],l=t.aanFeatures;return r||a.fnInit(t,i,o),l.p||(i.id=t.sTableId+"_paginate",t.aoDrawCallback.push({fn:function(t){if(r){var e,n,i=t._iDisplayStart,s=t._iDisplayLength,u=t.fnRecordsDisplay(),c=-1===s,d=c?0:Math.ceil(i/s),f=c?1:Math.ceil(u/s),h=a(d,f);for(e=0,n=l.p.length;eo&&(a=0):"first"==e?a=0:"previous"==e?(a=r>=0?a-r:0)<0&&(a=0):"next"==e?a+r",{id:t.aanFeatures.r?null:t.sTableId+"_processing",class:t.oClasses.sProcessing,role:"status"}).html(t.oLanguage.sProcessing).append("
").insertBefore(t.nTable)[0]}function Bt(t,n){t.oFeatures.bProcessing&&e(t.aanFeatures.r).css("display",n?"block":"none"),pe(t,null,"processing",[t,n])}function Ut(t){var n=e(t.nTable),a=t.oScroll;if(""===a.sX&&""===a.sY)return t.nTable;var r=a.sX,o=a.sY,i=t.oClasses,l=n.children("caption"),s=l.length?l[0]._captionSide:null,u=e(n[0].cloneNode(!1)),c=e(n[0].cloneNode(!1)),d=n.children("tfoot"),f="
",h=function(t){return t?Zt(t):null};d.length||(d=null);var p=e(f,{class:i.sScrollWrapper}).append(e(f,{class:i.sScrollHead}).css({overflow:"hidden",position:"relative",border:0,width:r?h(r):"100%"}).append(e(f,{class:i.sScrollHeadInner}).css({"box-sizing":"content-box",width:a.sXInner||"100%"}).append(u.removeAttr("id").css("margin-left",0).append("top"===s?l:null).append(n.children("thead"))))).append(e(f,{class:i.sScrollBody}).css({position:"relative",overflow:"auto",width:h(r)}).append(n));d&&p.append(e(f,{class:i.sScrollFoot}).css({overflow:"hidden",border:0,width:r?h(r):"100%"}).append(e(f,{class:i.sScrollFootInner}).append(c.removeAttr("id").css("margin-left",0).append("bottom"===s?l:null).append(n.children("tfoot")))));var g=p.children(),v=g[0],b=g[1],m=d?g[2]:null;return r&&e(b).on("scroll.DT",(function(t){var e=this.scrollLeft;v.scrollLeft=e,d&&(m.scrollLeft=e)})),e(b).css("max-height",o),a.bCollapse||e(b).css("height",o),t.nScrollHead=v,t.nScrollBody=b,t.nScrollFoot=m,t.aoDrawCallback.push({fn:Vt,sName:"scrolling"}),p[0]}function Vt(t){var n,a,r,o,i,l,s,u,c,d=t.oScroll,f=d.sX,h=d.sXInner,p=d.sY,g=d.iBarWidth,v=e(t.nScrollHead),b=v[0].style,m=v.children("div"),S=m[0].style,D=m.children("table"),_=t.nScrollBody,w=e(_),T=_.style,C=e(t.nScrollFoot).children("div"),x=C.children("table"),A=e(t.nTHead),I=e(t.nTable),F=I[0],L=F.style,P=t.nTFoot?e(t.nTFoot):null,R=t.oBrowser,j=R.bScrollOversize,N=(y(t.aoColumns,"nTh"),[]),H=[],O=[],k=[],W=function(t){var e=t.style;e.paddingTop="0",e.paddingBottom="0",e.borderTopWidth="0",e.borderBottomWidth="0",e.height=0},B=_.scrollHeight>_.clientHeight;if(t.scrollBarVis!==B&&void 0!==t.scrollBarVis)return t.scrollBarVis=B,void M(t);t.scrollBarVis=B,I.children("thead, tfoot").remove(),P&&(l=P.clone().prependTo(I),a=P.find("tr"),o=l.find("tr"),l.find("[id]").removeAttr("id")),i=A.clone().prependTo(I),n=A.find("tr"),r=i.find("tr"),i.find("th, td").removeAttr("tabindex"),i.find("[id]").removeAttr("id"),f||(T.width="100%",v[0].style.width="100%"),e.each(ht(t,i),(function(e,n){s=E(t,e),n.style.width=t.aoColumns[s].sWidth})),P&&Xt((function(t){t.style.width=""}),o),c=I.outerWidth(),""===f?(L.width="100%",j&&(I.find("tbody").height()>_.offsetHeight||"scroll"==w.css("overflow-y"))&&(L.width=Zt(I.outerWidth()-g)),c=I.outerWidth()):""!==h&&(L.width=Zt(h),c=I.outerWidth()),Xt(W,r),Xt((function(t){var n=window.getComputedStyle?window.getComputedStyle(t).width:Zt(e(t).width());O.push(t.innerHTML),N.push(n)}),r),Xt((function(t,e){t.style.width=N[e]}),n),e(r).css("height",0),P&&(Xt(W,o),Xt((function(t){k.push(t.innerHTML),H.push(Zt(e(t).css("width")))}),o),Xt((function(t,e){t.style.width=H[e]}),a),e(o).height(0)),Xt((function(t,e){t.innerHTML='
'+O[e]+"
",t.childNodes[0].style.height="0",t.childNodes[0].style.overflow="hidden",t.style.width=N[e]}),r),P&&Xt((function(t,e){t.innerHTML='
'+k[e]+"
",t.childNodes[0].style.height="0",t.childNodes[0].style.overflow="hidden",t.style.width=H[e]}),o),Math.round(I.outerWidth())_.offsetHeight||"scroll"==w.css("overflow-y")?c+g:c,j&&(_.scrollHeight>_.offsetHeight||"scroll"==w.css("overflow-y"))&&(L.width=Zt(u-g)),""!==f&&""===h||ue(t,1,"Possible column misalignment",6)):u="100%",T.width=Zt(u),b.width=Zt(u),P&&(t.nScrollFoot.style.width=Zt(u)),p||j&&(T.height=Zt(F.offsetHeight+g));var U=I.outerWidth();D[0].style.width=Zt(U),S.width=Zt(U);var V=I.height()>_.clientHeight||"scroll"==w.css("overflow-y"),X="padding"+(R.bScrollbarLeft?"Left":"Right");S[X]=V?g+"px":"0px",P&&(x[0].style.width=Zt(U),C[0].style.width=Zt(U),C[0].style[X]=V?g+"px":"0px"),I.children("colgroup").insertBefore(I.children("thead")),w.trigger("scroll"),!t.bSorted&&!t.bFiltered||t._drawHold||(_.scrollTop=0)}function Xt(t,e,n){for(var a,r,o=0,i=0,l=e.length;i/g;function qt(t){var n,a,r,o=t.nTable,i=t.aoColumns,l=t.oScroll,s=l.sY,u=l.sX,c=l.sXInner,d=i.length,f=U(t,"bVisible"),h=e("th",t.nTHead),p=o.getAttribute("width"),g=o.parentNode,v=!1,b=t.oBrowser,m=b.bScrollOversize,S=o.style.width;for(S&&-1!==S.indexOf("%")&&(p=S),n=0;n").appendTo(D.find("tbody"));for(D.find("thead, tfoot").remove(),D.append(e(t.nTHead).clone()).append(e(t.nTFoot).clone()),D.find("tfoot th, tfoot td").css("width",""),h=ht(t,D.find("thead")[0]),n=0;n").css({width:a.sWidthOrig,margin:0,padding:0,border:0,height:1}));if(t.aoData.length)for(n=0;n").css(u||s?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(D).appendTo(g);u&&c?D.width(c):u?(D.css("width","auto"),D.removeAttr("width"),D.width()").css("width",Zt(t)).appendTo(n||document.body),r=a[0].offsetWidth;return a.remove(),r}function zt(t,n){var a=Yt(t,n);if(a<0)return null;var r=t.aoData[a];return r.nTr?r.anCells[n]:e("").html(G(t,a,n,"display"))[0]}function Yt(t,e){for(var n,a=-1,r=-1,o=0,i=t.aoData.length;oa&&(a=n.length,r=o);return r}function Zt(t){return null===t?"0px":"number"==typeof t?t<0?"0px":t+"px":t.match(/\d$/)?t+"px":t}function Kt(t){var n,a,r,o,i,l,u,c=[],d=t.aoColumns,f=t.aaSortingFixed,h=e.isPlainObject(f),p=[],g=function(t){t.length&&!Array.isArray(t[0])?p.push(t):e.merge(p,t)};for(Array.isArray(f)&&g(f),h&&f.pre&&g(f.pre),g(t.aaSorting),h&&f.post&&g(f.post),n=0;na?1:0))return"asc"===s.dir?l:-l;return(n=i[t])<(a=i[e])?-1:n>a?1:0})):d.sort((function(t,e){var n,a,r,s,c,d=o.length,f=u[t]._aSortData,h=u[e]._aSortData;for(r=0;ra?1:0}))}t.bSorted=!0}function te(t){for(var e,n,a=t.aoColumns,r=Kt(t),o=t.oLanguage.oAria,i=0,l=a.length;i/g,""),d=s.nTh;d.removeAttribute("aria-sort"),s.bSortable?(r.length>0&&r[0].col==i?(d.setAttribute("aria-sort","asc"==r[0].dir?"ascending":"descending"),n=u[r[0].index+1]||u[0]):n=u[0],e=c+("asc"===n?o.sSortAscending:o.sSortDescending)):e=c,d.setAttribute("aria-label",e)}}function ee(t,n,a,r){var o,i=t.aoColumns[n],l=t.aaSorting,s=i.asSorting,u=function(t,n){var a=t._idx;return void 0===a&&(a=e.inArray(t[1],s)),a+10&&n.time<+new Date-1e3*c)return t._bLoadingState=!1,void a();if(n.columns&&i.length!==n.columns.length)return t._bLoadingState=!1,void a();if(t.oLoadedState=e.extend(!0,{},n),void 0!==n.length&&(l?l.page.len(n.length):t._iDisplayLength=n.length),void 0!==n.start&&(null===l?(t._iDisplayStart=n.start,t.iInitDisplayStart=n.start):Et(t,n.start/t._iDisplayLength)),void 0!==n.order&&(t.aaSorting=[],e.each(n.order,(function(e,n){t.aaSorting.push(n[0]>=i.length?[0,n[1]]:n)}))),void 0!==n.search&&e.extend(t.oPreviousSearch,Lt(n.search)),n.columns){for(r=0,o=n.columns.length;r=n&&(e=n-a),e-=e%a,(-1===a||e<0)&&(e=0),t._iDisplayStart=e}function ve(t,n){var a=t.renderer,r=s.ext.renderer[n];return e.isPlainObject(a)&&a[n]?r[a[n]]||r._:"string"==typeof a&&r[a]||r._}function be(t){return t.oFeatures.bServerSide?"ssp":t.ajax||t.sAjaxSource?"ajax":"dom"}var me=[],Se=Array.prototype;o=function(t,n){if(!(this instanceof o))return new o(t,n);var a=[],r=function(t){var n=function(t){var n,a,r=s.settings,o=e.map(r,(function(t,e){return t.nTable}));return t?t.nTable&&t.oApi?[t]:t.nodeName&&"table"===t.nodeName.toLowerCase()?-1!==(n=e.inArray(t,o))?[r[n]]:null:t&&"function"==typeof t.settings?t.settings().toArray():("string"==typeof t?a=e(t):t instanceof e&&(a=t),a?a.map((function(t){return-1!==(n=e.inArray(this,o))?r[n]:null})).toArray():void 0):[]}(t);n&&a.push.apply(a,n)};if(Array.isArray(t))for(var i=0,l=t.length;it?new o(e[t],this[t]):null},filter:function(t){var e=[];if(Se.filter)e=Se.filter.call(this,t,this);else for(var n=0,a=this.length;n0)return t[0].json})),i("ajax.params()",(function(){var t=this.context;if(t.length>0)return t[0].oAjaxData})),i("ajax.reload()",(function(t,e){return this.iterator("table",(function(n){De(n,!1===e,t)}))})),i("ajax.url()",(function(t){var n=this.context;if(void 0===t){if(0===n.length)return;return(n=n[0]).ajax?e.isPlainObject(n.ajax)?n.ajax.url:n.ajax:n.sAjaxSource}return this.iterator("table",(function(n){e.isPlainObject(n.ajax)?n.ajax.url=t:n.ajax=t}))})),i("ajax.url().load()",(function(t,e){return this.iterator("table",(function(n){De(n,!1===e,t)}))}));var _e=function(t,e,a,r,o){var i,l,s,u,c,d,f=[],h=typeof e;for(e&&"string"!==h&&"function"!==h&&void 0!==e.length||(e=[e]),s=0,u=e.length;s0)return t[0]=t[e],t[0].length=1,t.length=1,t.context=[t.context[e]],t;return t.length=0,t},Ce=function(t,n){var a,r=[],o=t.aiDisplay,i=t.aiDisplayMaster,l=n.search,s=n.order,u=n.page;if("ssp"==be(t))return"removed"===l?[]:_(0,i.length);if("current"==u)for(d=t._iDisplayStart,f=t.fnDisplayEnd();d=0&&"applied"==l)&&r.push(d);return r};i("rows()",(function(t,n){void 0===t?t="":e.isPlainObject(t)&&(n=t,t=""),n=we(n);var a=this.iterator("table",(function(a){return function(t,n,a){var r;return _e("row",n,(function(n){var o=v(n),i=t.aoData;if(null!==o&&!a)return[o];if(r||(r=Ce(t,a)),null!==o&&-1!==e.inArray(o,r))return[o];if(null==n||""===n)return r;if("function"==typeof n)return e.map(r,(function(t){var e=i[t];return n(t,e._aData,e.nTr)?t:null}));if(n.nodeName){var l=n._DT_RowIndex,s=n._DT_CellIndex;if(void 0!==l)return i[l]&&i[l].nTr===n?[l]:[];if(s)return i[s.row]&&i[s.row].nTr===n.parentNode?[s.row]:[];var u=e(n).closest("*[data-dt-row]");return u.length?[u.data("dt-row")]:[]}if("string"==typeof n&&"#"===n.charAt(0)){var c=t.aIds[n.replace(/^#/,"")];if(void 0!==c)return[c.idx]}var d=w(D(t.aoData,r,"nTr"));return e(d).filter(n).map((function(){return this._DT_RowIndex})).toArray()}),t,a)}(a,t,n)}),1);return a.selector.rows=t,a.selector.opts=n,a})),i("rows().nodes()",(function(){return this.iterator("row",(function(t,e){return t.aoData[e].nTr||void 0}),1)})),i("rows().data()",(function(){return this.iterator(!0,"rows",(function(t,e){return D(t.aoData,e,"_aData")}),1)})),l("rows().cache()","row().cache()",(function(t){return this.iterator("row",(function(e,n){var a=e.aoData[n];return"search"===t?a._aFilterData:a._aSortData}),1)})),l("rows().invalidate()","row().invalidate()",(function(t){return this.iterator("row",(function(e,n){at(e,n,t)}))})),l("rows().indexes()","row().index()",(function(){return this.iterator("row",(function(t,e){return e}),1)})),l("rows().ids()","row().id()",(function(t){for(var e=[],n=this.context,a=0,r=n.length;a0&&e._iRecordsDisplay--,ge(e);var f=e.rowIdFn(d._aData);void 0!==f&&delete e.aIds[f]})),this.iterator("table",(function(t){for(var e=0,n=t.aoData.length;e0&&(e.on(a,(function(n,a){t===a&&e.rows({page:"current"}).eq(0).each((function(t){var e=l[t];e._detailsShow&&e._details.insertAfter(e.nTr)}))})),e.on(r,(function(e,n,a,r){if(t===n)for(var o,i=B(n),s=0,u=l.length;s").addClass(a);e("td",s).addClass(a).html(n)[0].colSpan=B(t),o.push(s[0])}};i(a,r),n._details&&n._details.detach(),n._details=e(o),n._detailsShow&&n._details.insertAfter(n.nTr)}(a[0],a[0].aoData[this[0]],t,n),this)})),i([Le+".show()",Pe+".show()"],(function(t){return Ie(this,!0),this})),i([Le+".hide()",Pe+".hide()"],(function(){return Ie(this,!1),this})),i([Le+".remove()",Pe+".remove()"],(function(){return Ae(this),this})),i(Le+".isShown()",(function(){var t=this.context;return t.length&&this.length&&t[0].aoData[this[0]]._detailsShow||!1}));var Re=/^([^:]+):(name|visIdx|visible)$/,je=function(t,e,n,a,r){for(var o=[],i=0,l=r.length;i=0?l:r.length+l];if("function"==typeof n){var s=Ce(t,a);return e.map(r,(function(e,a){return n(a,je(t,a,0,0,s),i[a])?a:null}))}var u="string"==typeof n?n.match(Re):"";if(u)switch(u[2]){case"visIdx":case"visible":var c=parseInt(u[1],10);if(c<0){var d=e.map(r,(function(t,e){return t.bVisible?e:null}));return[d[d.length+c]]}return[E(t,c)];case"name":return e.map(o,(function(t,e){return t===u[1]?e:null}));default:return[]}if(n.nodeName&&n._DT_CellIndex)return[n._DT_CellIndex.column];var f=e(i).filter(n).map((function(){return e.inArray(this,i)})).toArray();if(f.length||!n.nodeName)return f;var h=e(n).closest("*[data-dt-column]");return h.length?[h.data("dt-column")]:[]}),t,a)}(a,t,n)}),1);return a.selector.cols=t,a.selector.opts=n,a})),l("columns().header()","column().header()",(function(t,e){return this.iterator("column",(function(t,e){return t.aoColumns[e].nTh}),1)})),l("columns().footer()","column().footer()",(function(t,e){return this.iterator("column",(function(t,e){return t.aoColumns[e].nTf}),1)})),l("columns().data()","column().data()",(function(){return this.iterator("column-rows",je,1)})),l("columns().dataSrc()","column().dataSrc()",(function(){return this.iterator("column",(function(t,e){return t.aoColumns[e].mData}),1)})),l("columns().cache()","column().cache()",(function(t){return this.iterator("column-rows",(function(e,n,a,r,o){return D(e.aoData,o,"search"===t?"_aFilterData":"_aSortData",n)}),1)})),l("columns().nodes()","column().nodes()",(function(){return this.iterator("column-rows",(function(t,e,n,a,r){return D(t.aoData,r,"anCells",e)}),1)})),l("columns().visible()","column().visible()",(function(t,n){var a=this,r=this.iterator("column",(function(n,a){if(void 0===t)return n.aoColumns[a].bVisible;!function(t,n,a){var r,o,i,l,s=t.aoColumns,u=s[n],c=t.aoData;if(void 0===a)return u.bVisible;if(u.bVisible!==a){if(a){var d=e.inArray(!0,y(s,"bVisible"),n+1);for(o=0,i=c.length;on;return!0},s.isDataTable=s.fnIsDataTable=function(t){var n=e(t).get(0),a=!1;return t instanceof s.Api||(e.each(s.settings,(function(t,r){var o=r.nScrollHead?e("table",r.nScrollHead)[0]:null,i=r.nScrollFoot?e("table",r.nScrollFoot)[0]:null;r.nTable!==n&&o!==n&&i!==n||(a=!0)})),a)},s.tables=s.fnTables=function(t){var n=!1;e.isPlainObject(t)&&(n=t.api,t=t.visible);var a=e.map(s.settings,(function(n){if(!t||t&&e(n.nTable).is(":visible"))return n.nTable}));return n?new o(a):a},s.camelToHungarian=F,i("$()",(function(t,n){var a=this.rows(n).nodes(),r=e(a);return e([].concat(r.filter(t).toArray(),r.find(t).toArray()))})),e.each(["on","one","off"],(function(t,n){i(n+"()",(function(){var t=Array.prototype.slice.call(arguments);t[0]=e.map(t[0].split(/\s/),(function(t){return t.match(/\.dt\b/)?t:t+".dt"})).join(" ");var a=e(this.tables().nodes());return a[n].apply(a,t),this}))})),i("clear()",(function(){return this.iterator("table",(function(t){et(t)}))})),i("settings()",(function(){return new o(this.context,this.context)})),i("init()",(function(){var t=this.context;return t.length?t[0].oInit:null})),i("data()",(function(){return this.iterator("table",(function(t){return y(t.aoData,"_aData")})).flatten()})),i("destroy()",(function(t){return t=t||!1,this.iterator("table",(function(n){var a,r=n.oClasses,i=n.nTable,l=n.nTBody,u=n.nTHead,c=n.nTFoot,d=e(i),f=e(l),h=e(n.nTableWrapper),p=e.map(n.aoData,(function(t){return t.nTr}));n.bDestroying=!0,pe(n,"aoDestroyCallback","destroy",[n]),t||new o(n).columns().visible(!0),h.off(".DT").find(":not(tbody *)").off(".DT"),e(window).off(".DT-"+n.sInstance),i!=u.parentNode&&(d.children("thead").detach(),d.append(u)),c&&i!=c.parentNode&&(d.children("tfoot").detach(),d.append(c)),n.aaSorting=[],n.aaSortingFixed=[],ae(n),e(p).removeClass(n.asStripeClasses.join(" ")),e("th, td",u).removeClass(r.sSortable+" "+r.sSortableAsc+" "+r.sSortableDesc+" "+r.sSortableNone),f.children().detach(),f.append(p);var g=n.nTableWrapper.parentNode,v=t?"remove":"detach";d[v](),h[v](),!t&&g&&(g.insertBefore(i,n.nTableReinsertBefore),d.css("width",n.sDestroyWidth).removeClass(r.sTable),(a=n.asDestroyStripes.length)&&f.children().each((function(t){e(this).addClass(n.asDestroyStripes[t%a])})));var b=e.inArray(n,s.settings);-1!==b&&s.settings.splice(b,1)}))})),e.each(["column","row","cell"],(function(t,e){i(e+"s().every()",(function(t){var n=this.selector.opts,a=this;return this.iterator(e,(function(r,o,i,l,s){t.call(a[e](o,"cell"===e?i:n,"cell"===e?n:void 0),o,i,l,s)}))}))})),i("i18n()",(function(t,n,a){var r=this.context[0],o=K(t)(r.oLanguage);return void 0===o&&(o=n),void 0!==a&&e.isPlainObject(o)&&(o=void 0!==o[a]?o[a]:o._),o.replace("%d",a)})),s.version="1.13.4",s.settings=[],s.models={},s.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0,return:!1},s.models.oRow={nTr:null,anCells:null,_aData:[],_aSortData:null,_aFilterData:null,_sFilterRow:null,_sRowStripe:"",src:null,idx:-1},s.models.oColumn={idx:null,aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bVisible:null,_sManualType:null,_bAttrSrc:!1,fnCreatedCell:null,fnGetData:null,fnSetData:null,mData:null,mRender:null,nTh:null,nTf:null,sClass:null,sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null},s.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:[],ajax:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollCollapse:!1,bServerSide:!1,bSort:!0,bSortMulti:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(t){return t.toString().replace(/\B(?=(\d{3})+(?!\d))/g,this.oLanguage.sThousands)},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:null,fnServerParams:null,fnStateLoadCallback:function(t){try{return JSON.parse((-1===t.iStateDuration?sessionStorage:localStorage).getItem("DataTables_"+t.sInstance+"_"+location.pathname))}catch(t){return{}}},fnStateLoadParams:null,fnStateLoaded:null,fnStateSaveCallback:function(t,e){try{(-1===t.iStateDuration?sessionStorage:localStorage).setItem("DataTables_"+t.sInstance+"_"+location.pathname,JSON.stringify(e))}catch(t){}},fnStateSaveParams:null,iStateDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iTabIndex:0,oClasses:{},oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",sSortDescending:": activate to sort column descending"},oPaginate:{sFirst:"First",sLast:"Last",sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sDecimal:"",sThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"",sSearch:"Search:",sSearchPlaceholder:"",sUrl:"",sZeroRecords:"No matching records found"},oSearch:e.extend({},s.models.oSearch),sAjaxDataProp:"data",sAjaxSource:null,sDom:"lfrtip",searchDelay:null,sPaginationType:"simple_numbers",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET",renderer:null,rowId:"DT_RowId"},I(s.defaults),s.defaults.column={aDataSort:null,iDataSort:-1,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bVisible:!0,fnCreatedCell:null,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,sType:null,sWidth:null},I(s.defaults.column),s.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortMulti:null,bSortClasses:null,bStateSave:null},oScroll:{bCollapse:null,iBarWidth:0,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1,bScrollbarLeft:!1,bBounding:!1,barWidth:0},ajax:null,aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aIds:{},aoColumns:[],aoHeader:[],aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button",iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,jqXHR:null,json:void 0,oAjaxData:void 0,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return"ssp"==be(this)?1*this._iRecordsTotal:this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==be(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var t=this._iDisplayLength,e=this._iDisplayStart,n=e+t,a=this.aiDisplay.length,r=this.oFeatures,o=r.bPaginate;return r.bServerSide?!1===o||-1===t?e+a:Math.min(e+t,this._iRecordsDisplay):!o||n>a||-1===t?a:n},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null},s.ext=n={buttons:{},classes:{},builder:"-source-",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:s.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:s.version},e.extend(n,{afnFiltering:n.search,aTypes:n.type.detect,ofnSearch:n.type.search,oSort:n.type.order,afnSortData:n.order,aoFeatures:n.feature,oApi:n.internal,oStdClasses:n.classes,oPagination:n.pager}),e.extend(s.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_desc_disabled",sSortableDesc:"sorting_asc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",sJUIHeader:"",sJUIFooter:""});var Ne=s.ext.pager;function He(t,e){var n=[],a=Ne.numbers_length,r=Math.floor(a/2);return e<=a?n=_(0,e):t<=r?((n=_(0,a-2)).push("ellipsis"),n.push(e-1)):t>=e-1-r?((n=_(e-(a-2),e)).splice(0,0,"ellipsis"),n.splice(0,0,0)):((n=_(t-r+2,t+r-1)).push("ellipsis"),n.push(e-1),n.splice(0,0,"ellipsis"),n.splice(0,0,0)),n.DT_el="span",n}e.extend(Ne,{simple:function(t,e){return["previous","next"]},full:function(t,e){return["first","previous","next","last"]},numbers:function(t,e){return[He(t,e)]},simple_numbers:function(t,e){return["previous",He(t,e),"next"]},full_numbers:function(t,e){return["first","previous",He(t,e),"next","last"]},first_last_numbers:function(t,e){return["first",He(t,e),"last"]},_numbers:He,numbers_length:7}),e.extend(!0,s.ext.renderer,{pageButton:{_:function(t,n,a,r,o,i){var l,s,u,c=t.oClasses,d=t.oLanguage.oPaginate,f=t.oLanguage.oAria.paginate||{},h=function(n,r){var u,p,g,v,b=c.sPageButtonDisabled,m=function(e){Et(t,e.data.action,!0)};for(u=0,p=r.length;u").appendTo(n);h(S,g)}else{switch(l=null,s=g,v=t.iTabIndex,g){case"ellipsis":n.append('');break;case"first":l=d.sFirst,0===o&&(v=-1,s+=" "+b);break;case"previous":l=d.sPrevious,0===o&&(v=-1,s+=" "+b);break;case"next":l=d.sNext,0!==i&&o!==i-1||(v=-1,s+=" "+b);break;case"last":l=d.sLast,0!==i&&o!==i-1||(v=-1,s+=" "+b);break;default:l=t.fnFormatNumber(g+1),s=o===g?c.sPageButtonActive:""}if(null!==l){var y=t.oInit.pagingTag||"a",D=-1!==s.indexOf(b);fe(e("<"+y+">",{class:c.sPageButton+" "+s,"aria-controls":t.sTableId,"aria-disabled":D?"true":null,"aria-label":f[g],"aria-role":"link","aria-current":s===c.sPageButtonActive?"page":null,"data-dt-idx":g,tabindex:v,id:0===a&&"string"==typeof g?t.sTableId+"_"+g:null}).html(l).appendTo(n),{action:g},m)}}};try{u=e(n).find(document.activeElement).data("dt-idx")}catch(t){}h(e(n).empty(),r),void 0!==u&&e(n).find("[data-dt-idx="+u+"]").trigger("focus")}}}),e.extend(s.ext.type.detect,[function(t,e){var n=e.oLanguage.sDecimal;return m(t,n)?"num"+n:null},function(t,e){if(t&&!(t instanceof Date)&&!f.test(t))return null;var n=Date.parse(t);return null!==n&&!isNaN(n)||g(t)?"date":null},function(t,e){var n=e.oLanguage.sDecimal;return m(t,n,!0)?"num-fmt"+n:null},function(t,e){var n=e.oLanguage.sDecimal;return S(t,n)?"html-num"+n:null},function(t,e){var n=e.oLanguage.sDecimal;return S(t,n,!0)?"html-num-fmt"+n:null},function(t,e){return g(t)||"string"==typeof t&&-1!==t.indexOf("<")?"html":null}]),e.extend(s.ext.type.search,{html:function(t){return g(t)?t:"string"==typeof t?t.replace(c," ").replace(d,""):""},string:function(t){return g(t)?t:"string"==typeof t?t.replace(c," "):t}});var Oe=function(t,e,n,a){if(0!==t&&(!t||"-"===t))return-1/0;let r=typeof t;return"number"===r||"bigint"===r?t:(e&&(t=b(t,e)),t.replace&&(n&&(t=t.replace(n,"")),a&&(t=t.replace(a,""))),1*t)};function ke(t){e.each({num:function(e){return Oe(e,t)},"num-fmt":function(e){return Oe(e,t,p)},"html-num":function(e){return Oe(e,t,d)},"html-num-fmt":function(e){return Oe(e,t,d,p)}},(function(e,a){n.type.order[e+t+"-pre"]=a,e.match(/^html\-/)&&(n.type.search[e+t]=n.type.search.html)}))}e.extend(n.type.order,{"date-pre":function(t){var e=Date.parse(t);return isNaN(e)?-1/0:e},"html-pre":function(t){return g(t)?"":t.replace?t.replace(/<.*?>/g,"").toLowerCase():t+""},"string-pre":function(t){return g(t)?"":"string"==typeof t?t.toLowerCase():t.toString?t.toString():""},"string-asc":function(t,e){return te?1:0},"string-desc":function(t,e){return te?-1:0}}),ke(""),e.extend(!0,s.ext.renderer,{header:{_:function(t,n,a,r){e(t.nTable).on("order.dt.DT",(function(e,o,i,l){if(t===o){var s=a.idx;n.removeClass(r.sSortAsc+" "+r.sSortDesc).addClass("asc"==l[s]?r.sSortAsc:"desc"==l[s]?r.sSortDesc:a.sSortingClass)}}))},jqueryui:function(t,n,a,r){e("
").addClass(r.sSortJUIWrapper).append(n.contents()).append(e("").addClass(r.sSortIcon+" "+a.sSortingClassJUI)).appendTo(n),e(t.nTable).on("order.dt.DT",(function(e,o,i,l){if(t===o){var s=a.idx;n.removeClass(r.sSortAsc+" "+r.sSortDesc).addClass("asc"==l[s]?r.sSortAsc:"desc"==l[s]?r.sSortDesc:a.sSortingClass),n.find("span."+r.sSortIcon).removeClass(r.sSortJUIAsc+" "+r.sSortJUIDesc+" "+r.sSortJUI+" "+r.sSortJUIAscAllowed+" "+r.sSortJUIDescAllowed).addClass("asc"==l[s]?r.sSortJUIAsc:"desc"==l[s]?r.sSortJUIDesc:a.sSortingClassJUI)}}))}}});var Me=function(t){return Array.isArray(t)&&(t=t.join(",")),"string"==typeof t?t.replace(/&/g,"&").replace(//g,">").replace(/"/g,"""):t};function Ee(t,e,n,a,r){return window.moment?t[e](r):window.luxon?t[n](r):a?t[a](r):t}var We=!1;function Be(t,e,n){var a;if(window.moment){if(!(a=window.moment.utc(t,e,n,!0)).isValid())return null}else if(window.luxon){if(!(a=e&&"string"==typeof t?window.luxon.DateTime.fromFormat(t,e):window.luxon.DateTime.fromISO(t)).isValid)return null;a.setLocale(n)}else e?(We||alert("DataTables warning: Formatted date without Moment.js or Luxon - https://datatables.net/tn/17"),We=!0):a=new Date(t);return a}function Ue(t){return function(e,n,a,r){0===arguments.length?(a="en",n=null,e=null):1===arguments.length?(a="en",n=e,e=null):2===arguments.length&&(a=n,n=e,e=null);var o="datetime-"+n;return s.ext.type.order[o]||(s.ext.type.detect.unshift((function(t){return t===o&&o})),s.ext.type.order[o+"-asc"]=function(t,e){var n=t.valueOf(),a=e.valueOf();return n===a?0:na?-1:1}),function(i,l){if(null==i)if("--now"===r){var s=new Date;i=new Date(Date.UTC(s.getFullYear(),s.getMonth(),s.getDate(),s.getHours(),s.getMinutes(),s.getSeconds()))}else i="";if("type"===l)return o;if(""===i)return"sort"!==l?"":Be("0000-01-01 00:00:00",null,a);if(null!==n&&e===n&&"sort"!==l&&"type"!==l&&!(i instanceof Date))return i;var u=Be(i,e,a);if(null===u)return i;if("sort"===l)return u;var c=null===n?Ee(u,"toDate","toJSDate","")[t]():Ee(u,"format","toFormat","toISOString",n);return"display"===l?Me(c):c}}}var Ve=",",Xe=".";if(Intl)try{for(var Je=(new Intl.NumberFormat).formatToParts(100000.1),qe=0;qe<'col-sm-12 col-md-6'f>><'row dt-row'<'col-sm-12'tr>><'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",renderer:"bootstrap"}),t.extend($e.ext.classes,{sWrapper:"dataTables_wrapper dt-bootstrap5",sFilterInput:"form-control form-control-sm",sLengthSelect:"form-select form-select-sm",sProcessing:"dataTables_processing card",sPageButton:"paginate_button page-item"}),$e.ext.renderer.pageButton.bootstrap=function(e,n,a,r,o,i){var l,s,u,c=new $e.Api(e),d=e.oClasses,f=e.oLanguage.oPaginate,h=e.oLanguage.oAria.paginate||{},p=function(n,r){var u,g,v,b,m=function(e){e.preventDefault(),t(e.currentTarget).hasClass("disabled")||c.page()==e.data.action||c.page(e.data.action).draw("page")};for(u=0,g=r.length;u0?"":" disabled");break;case"previous":l=f.sPrevious,s=b+(o>0?"":" disabled");break;case"next":l=f.sNext,s=b+(o",{class:d.sPageButton+" "+s,id:0===a&&"string"==typeof b?e.sTableId+"_"+b:null}).append(t("",{href:S?null:"#","aria-controls":e.sTableId,"aria-disabled":S?"true":null,"aria-label":h[b],"aria-role":"link","aria-current":"active"===s?"page":null,"data-dt-idx":b,tabindex:e.iTabIndex,class:"page-link"}).html(l)).appendTo(n),e.oApi._fnBindAction(v,{action:b},m)}}},g=t(n);try{u=g.find(document.activeElement).data("dt-idx")}catch(t){}var v=g.children("ul.pagination");v.length?v.empty():v=g.html("