From c0d56735e4ed87c8d231550058e8981f80189464 Mon Sep 17 00:00:00 2001 From: Lamm Date: Mon, 27 Apr 2026 17:05:39 +0200 Subject: [PATCH 1/4] bugfix-add-resource-loader --- Configuration/Services.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index d1adcd0..f2a63a0 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -4,6 +4,9 @@ services: autoconfigure: true public: false + Pluswerk\PlusMinify\: + resource: '../Classes/*' + Pluswerk\PlusMinify\EventListener\RenderedEventListener: tags: - name: event.listener From 47ef099a8ca781c749ead4a70ea72cff013b7f04 Mon Sep 17 00:00:00 2001 From: Lamm Date: Tue, 28 Apr 2026 09:45:35 +0200 Subject: [PATCH 2/4] Breaking: Remove TYPO3 v11 support. Add tests. --- .gitattributes | 11 ++ .github/workflows/tasks.yml | 25 ++-- .gitignore | 1 + .../EventListener/RenderedEventListener.php | 2 + Configuration/RequestMiddlewares.php | 2 + Makefile | 41 +++++ Tests/Unit/Service/MinifyServiceTest.php | 141 ++++++++++++++++++ composer.json | 27 +++- ext_emconf.php | 2 + phpunit.xml | 14 ++ 10 files changed, 246 insertions(+), 20 deletions(-) create mode 100644 .gitattributes create mode 100644 Makefile create mode 100644 Tests/Unit/Service/MinifyServiceTest.php create mode 100644 phpunit.xml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a6f1eac --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +# Exclude from release archives +/.github export-ignore +/Tests export-ignore +.gitattributes export-ignore +.gitignore export-ignore +grumphp.yml export-ignore +Makefile export-ignore +phpstan.neon export-ignore +phpstan-baseline.neon export-ignore +phpunit.xml export-ignore +rector.php export-ignore diff --git a/.github/workflows/tasks.yml b/.github/workflows/tasks.yml index ac43d24..8a57e07 100644 --- a/.github/workflows/tasks.yml +++ b/.github/workflows/tasks.yml @@ -9,25 +9,20 @@ jobs: strategy: fail-fast: false matrix: - php: [ '8.1', '8.2', '8.3', '8.4' ] - typo3: [ '11', '12', '13' ] - exclude: - - php: '8.1' - typo3: '13' - - php: '8.4' - typo3: '11' + php: [ '82', '83', '84' ] + typo3: [ '12', '13' ] + container: + image: ghcr.io/typo3/core-testing-php${{ matrix.php }}:latest steps: - - name: Setup PHP with PECL extension - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} + - name: Install dependencies + run: apk add --no-cache nodejs - uses: actions/checkout@v5 - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ~/.composer/cache/files key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: | ${{ runner.os }}-${{ matrix.php }}-composer- - - run: composer require typo3/minimal="^${{ matrix.typo3 }}" --dev - - run: composer install --no-interaction --no-progress - - run: ./vendor/bin/grumphp run --ansi + - run: composer switchto${{ matrix.typo3 }} + - run: ./vendor/bin/grumphp run --ansi --no-interaction + - run: composer test diff --git a/.gitignore b/.gitignore index 0c7c416..b1220e8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ vendor public composer.lock var/ +.phpunit.result.cache diff --git a/Classes/EventListener/RenderedEventListener.php b/Classes/EventListener/RenderedEventListener.php index a8a368b..7478d5e 100644 --- a/Classes/EventListener/RenderedEventListener.php +++ b/Classes/EventListener/RenderedEventListener.php @@ -1,5 +1,7 @@ &1 | tee /tmp/act-output.log; \ + echo ""; \ + echo "=== 🏁 Summary ==="; \ + grep "🏁" /tmp/act-output.log || true + + +clean: + docker rm -f $$(docker ps -aq --filter "name=act-") 2>/dev/null || true + diff --git a/Tests/Unit/Service/MinifyServiceTest.php b/Tests/Unit/Service/MinifyServiceTest.php new file mode 100644 index 0000000..dc74aff --- /dev/null +++ b/Tests/Unit/Service/MinifyServiceTest.php @@ -0,0 +1,141 @@ +subject = new MinifyService(); + } + + // ------------------------------------------------------------------------- + // All features off (default) + // ------------------------------------------------------------------------- + + #[Test] + public function minifyKeepsHtmlCommentsWhenNoFeaturesAreEnabled(): void + { + $html = '

Hello

'; + + $result = $this->subject->minify($html); + + self::assertStringContainsString('', $result); + } + + #[Test] + public function minifyKeepsTypo3CommentWhenNoFeaturesAreEnabled(): void + { + $html = '

Hello

'; + + $result = $this->subject->minify($html); + + self::assertStringContainsString('', $result); + } + + // ------------------------------------------------------------------------- + // remove_comments alone — comment removal needs the DOM parser too, + // so the output stays unchanged when only remove_comments is set. + // ------------------------------------------------------------------------- + + #[Test] + public function minifyDoesNotRemoveCommentsWithOnlyRemoveCommentsFlagEnabled(): void + { + $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['remove_comments'] = '1'; + + $html = '

Hello

'; + + $result = $this->subject->minify($html); + + // Without the DOM parser the minifier cannot parse the tree, + // so the comment is left in the output. + self::assertStringContainsString('', $result); + } + + // ------------------------------------------------------------------------- + // remove_comments + optimize_via_html_dom_parser (the realistic combination) + // ------------------------------------------------------------------------- + + #[Test] + public function minifyRemovesRegularCommentsWhenRemoveCommentsAndDomParserAreEnabled(): void + { + $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['remove_comments'] = '1'; + $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['optimize_via_html_dom_parser'] = '1'; + + $html = '

Hello

'; + + $result = $this->subject->minify($html); + + self::assertStringNotContainsString('', $result); + self::assertStringContainsString('

Hello

', $result); + } + + #[Test] + public function minifyPreservesTypo3CommentWhenRemoveCommentsAndDomParserAreEnabled(): void + { + $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['remove_comments'] = '1'; + $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['optimize_via_html_dom_parser'] = '1'; + + $html = '

Hello

'; + + $result = $this->subject->minify($html); + + self::assertStringContainsString('', $result); + } + + #[Test] + public function minifyRemovesRegularCommentButKeepsTypo3CommentWhenBothFlagsAreEnabled(): void + { + $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['remove_comments'] = '1'; + $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['optimize_via_html_dom_parser'] = '1'; + + $html = '

Hello

'; + + $result = $this->subject->minify($html); + + self::assertStringContainsString('', $result); + self::assertStringNotContainsString('', $result); + } + + // ------------------------------------------------------------------------- + // Output integrity + // ------------------------------------------------------------------------- + + #[Test] + public function minifyReturnsFallbackHtmlWhenMinifierProducesEmptyString(): void + { + // An empty string causes the minifier to return '' which triggers + // the $originalHtml fallback — the method must not crash. + $result = $this->subject->minify(''); + + self::assertSame('', $result); + } + + #[Test] + public function minifyAppendsClosingBodyTagWhenAbsentFromMinifiedOutput(): void + { + // Enable features that actually cause HtmlMin to strip closing tags. + $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['remove_comments'] = '1'; + $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['optimize_via_html_dom_parser'] = '1'; + $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['remove_omitted_html_tags'] = '1'; + + $html = '

Hello

'; + + $result = $this->subject->minify($html); + + self::assertStringEndsWith('', $result); + } +} diff --git a/composer.json b/composer.json index 2072b57..ebaafdb 100644 --- a/composer.json +++ b/composer.json @@ -8,22 +8,28 @@ "source": "https://github.com/pluswerk/minify" }, "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", "composer-runtime-api": "^2", - "typo3/cms-core": "^11.5 || ^12.4 || ^13.4", - "voku/html-min": "^4.5.1" + "typo3/cms-core": "^12.4 || ^13.4", + "voku/html-min": "^5.0.0" }, "require-dev": { "andersundsehr/ssi-include": "^1.1.0 || ^2.2.0", "pluswerk/grumphp-config": "^7 || ^10", - "saschaegerer/phpstan-typo3": "^1.10.0 || ^2.1.1", - "ssch/typo3-rector": "^2.5.0 || ^3.6.2" + "saschaegerer/phpstan-typo3": "^1.10.2 || ^2.1.1", + "ssch/typo3-rector": "^2.15.2 || ^3.14.1", + "typo3/testing-framework": "^8.2 || ^9.4" }, "autoload": { "psr-4": { "Pluswerk\\PlusMinify\\": "Classes/" } }, + "autoload-dev": { + "psr-4": { + "Pluswerk\\PlusMinify\\Tests\\": "Tests/" + } + }, "config": { "allow-plugins": { "ergebnis/composer-normalize": true, @@ -39,5 +45,16 @@ "typo3/cms": { "extension-key": "minify" } + }, + "scripts": { + "switchto12": [ + "rm -rf composer.lock vendor/composer/installed.json", + "@composer req typo3/minimal:^12 --dev --no-interaction --no-progress" + ], + "switchto13": [ + "rm -rf composer.lock vendor/composer/installed.json", + "@composer req typo3/minimal:^13 --dev --no-interaction --no-progress" + ], + "test": "@php ./vendor/bin/phpunit --testdox --stderr" } } diff --git a/ext_emconf.php b/ext_emconf.php index 5ff53a8..47c5feb 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -1,5 +1,7 @@ + + + + Tests + + + + + Classes + + + From e834815f735bca2c02846e22004ca40653e6cb30 Mon Sep 17 00:00:00 2001 From: Lamm Date: Tue, 28 Apr 2026 09:51:06 +0200 Subject: [PATCH 3/4] Fix pipeline --- .github/workflows/tasks.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tasks.yml b/.github/workflows/tasks.yml index 8a57e07..a9c7b7e 100644 --- a/.github/workflows/tasks.yml +++ b/.github/workflows/tasks.yml @@ -23,6 +23,7 @@ jobs: key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: | ${{ runner.os }}-${{ matrix.php }}-composer- + - run: git config --global --add safe.directory $GITHUB_WORKSPACE - run: composer switchto${{ matrix.typo3 }} - run: ./vendor/bin/grumphp run --ansi --no-interaction - run: composer test From 81cfa2e3030e386bc75b81c212320d315fa78c85 Mon Sep 17 00:00:00 2001 From: Lamm Date: Tue, 28 Apr 2026 09:59:18 +0200 Subject: [PATCH 4/4] Remove obsolete ext_emconf.php --- ext_emconf.php | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 ext_emconf.php diff --git a/ext_emconf.php b/ext_emconf.php deleted file mode 100644 index 47c5feb..0000000 --- a/ext_emconf.php +++ /dev/null @@ -1,23 +0,0 @@ - '+Pluswerk: Minify', - 'description' => 'Minifies your html at a glace', - 'category' => 'service', - 'author' => 'Stefan Lamm', - 'author_email' => 'stefan.lamm@pluswerk.ag', - 'state' => 'stable', - 'version' => InstalledVersions::getPrettyVersion('pluswerk/minify'), - 'constraints' => [ - 'depends' => [ - 'typo3' => '11.5.0 - 13.99.99', - ], - 'conflicts' => [], - 'suggests' => [], - ], -];