Skip to content

Commit e7fb6b7

Browse files
authored
Merge pull request #15 from pluswerk/bugfix-add-resource-loader
bugfix-add-resource-loader
2 parents 028103c + 81cfa2e commit e7fb6b7

11 files changed

Lines changed: 248 additions & 41 deletions

File tree

.gitattributes

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Exclude from release archives
2+
/.github export-ignore
3+
/Tests export-ignore
4+
.gitattributes export-ignore
5+
.gitignore export-ignore
6+
grumphp.yml export-ignore
7+
Makefile export-ignore
8+
phpstan.neon export-ignore
9+
phpstan-baseline.neon export-ignore
10+
phpunit.xml export-ignore
11+
rector.php export-ignore

.github/workflows/tasks.yml

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,21 @@ jobs:
99
strategy:
1010
fail-fast: false
1111
matrix:
12-
php: [ '8.1', '8.2', '8.3', '8.4' ]
13-
typo3: [ '11', '12', '13' ]
14-
exclude:
15-
- php: '8.1'
16-
typo3: '13'
17-
- php: '8.4'
18-
typo3: '11'
12+
php: [ '82', '83', '84' ]
13+
typo3: [ '12', '13' ]
14+
container:
15+
image: ghcr.io/typo3/core-testing-php${{ matrix.php }}:latest
1916
steps:
20-
- name: Setup PHP with PECL extension
21-
uses: shivammathur/setup-php@v2
22-
with:
23-
php-version: ${{ matrix.php }}
17+
- name: Install dependencies
18+
run: apk add --no-cache nodejs
2419
- uses: actions/checkout@v5
25-
- uses: actions/cache@v3
20+
- uses: actions/cache@v4
2621
with:
2722
path: ~/.composer/cache/files
2823
key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
2924
restore-keys: |
3025
${{ runner.os }}-${{ matrix.php }}-composer-
31-
- run: composer require typo3/minimal="^${{ matrix.typo3 }}" --dev
32-
- run: composer install --no-interaction --no-progress
33-
- run: ./vendor/bin/grumphp run --ansi
26+
- run: git config --global --add safe.directory $GITHUB_WORKSPACE
27+
- run: composer switchto${{ matrix.typo3 }}
28+
- run: ./vendor/bin/grumphp run --ansi --no-interaction
29+
- run: composer test

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ vendor
33
public
44
composer.lock
55
var/
6+
.phpunit.result.cache

Classes/EventListener/RenderedEventListener.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace Pluswerk\PlusMinify\EventListener;
46

57
use AUS\SsiInclude\Event\RenderedEvent;

Configuration/RequestMiddlewares.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
use Pluswerk\PlusMinify\Middleware\MinifyMiddleware;
46

57
return [

Configuration/Services.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ services:
44
autoconfigure: true
55
public: false
66

7+
Pluswerk\PlusMinify\:
8+
resource: '../Classes/*'
9+
710
Pluswerk\PlusMinify\EventListener\RenderedEventListener:
811
tags:
912
- name: event.listener

Makefile

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
ACT_IMAGE ?= efrecon/act:v0.2.80
2+
WORKDIR ?= /work
3+
UID_GID := $(shell id -u):$(shell id -g)
4+
DOCKER_GID := $(shell stat -c '%g' /var/run/docker.sock)
5+
6+
PLATFORM ?= -P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-24.04
7+
8+
# Secrets-File in ENV format
9+
SECRETS ?= --secret-file .secrets
10+
11+
ACT_ARGS ?= \
12+
--artifact-server-path /home/act/.cache/artifacts
13+
14+
define DOCKER_RUN
15+
docker run --rm -it \
16+
-u $(UID_GID) \
17+
--group-add $(DOCKER_GID) \
18+
-e HOME=/home/act \
19+
-e XDG_CACHE_HOME=/home/act/.cache \
20+
-e ACT_CACHE_DIR=/home/act/.cache/actcache \
21+
-v /var/run/docker.sock:/var/run/docker.sock \
22+
-v $(PWD):$(WORKDIR) -w $(WORKDIR) \
23+
-v $$HOME/.cache:/home/act/.cache \
24+
$(ACT_IMAGE)
25+
endef
26+
27+
# ---- Targets ----
28+
.PHONY: all ci clean
29+
30+
all: ci clean
31+
32+
ci: ## Standard-Event "push"
33+
$(DOCKER_RUN) $(PLATFORM) $(SECRETS) $(ACT_ARGS) 2>&1 | tee /tmp/act-output.log; \
34+
echo ""; \
35+
echo "=== 🏁 Summary ==="; \
36+
grep "🏁" /tmp/act-output.log || true
37+
38+
39+
clean:
40+
docker rm -f $$(docker ps -aq --filter "name=act-") 2>/dev/null || true
41+
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Pluswerk\PlusMinify\Tests\Unit\Service;
6+
7+
use PHPUnit\Framework\Attributes\Test;
8+
use PHPUnit\Framework\TestCase;
9+
use Pluswerk\PlusMinify\Service\MinifyService;
10+
11+
class MinifyServiceTest extends TestCase
12+
{
13+
private MinifyService $subject;
14+
15+
protected function setUp(): void
16+
{
17+
parent::setUp();
18+
19+
// Reset all minify feature flags — everything disabled by default
20+
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify'] = [];
21+
22+
$this->subject = new MinifyService();
23+
}
24+
25+
// -------------------------------------------------------------------------
26+
// All features off (default)
27+
// -------------------------------------------------------------------------
28+
29+
#[Test]
30+
public function minifyKeepsHtmlCommentsWhenNoFeaturesAreEnabled(): void
31+
{
32+
$html = '<html><head><meta charset="utf-8"><!-- a comment --></head><body><p>Hello</p></body></html>';
33+
34+
$result = $this->subject->minify($html);
35+
36+
self::assertStringContainsString('<!-- a comment -->', $result);
37+
}
38+
39+
#[Test]
40+
public function minifyKeepsTypo3CommentWhenNoFeaturesAreEnabled(): void
41+
{
42+
$html = '<html><head><meta charset="utf-8"><!-- TYPO3 page info --></head><body><p>Hello</p></body></html>';
43+
44+
$result = $this->subject->minify($html);
45+
46+
self::assertStringContainsString('<!-- TYPO3 page info -->', $result);
47+
}
48+
49+
// -------------------------------------------------------------------------
50+
// remove_comments alone — comment removal needs the DOM parser too,
51+
// so the output stays unchanged when only remove_comments is set.
52+
// -------------------------------------------------------------------------
53+
54+
#[Test]
55+
public function minifyDoesNotRemoveCommentsWithOnlyRemoveCommentsFlagEnabled(): void
56+
{
57+
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['remove_comments'] = '1';
58+
59+
$html = '<html><head><meta charset="utf-8"></head><body><!-- just a comment --><p>Hello</p></body></html>';
60+
61+
$result = $this->subject->minify($html);
62+
63+
// Without the DOM parser the minifier cannot parse the tree,
64+
// so the comment is left in the output.
65+
self::assertStringContainsString('<!-- just a comment -->', $result);
66+
}
67+
68+
// -------------------------------------------------------------------------
69+
// remove_comments + optimize_via_html_dom_parser (the realistic combination)
70+
// -------------------------------------------------------------------------
71+
72+
#[Test]
73+
public function minifyRemovesRegularCommentsWhenRemoveCommentsAndDomParserAreEnabled(): void
74+
{
75+
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['remove_comments'] = '1';
76+
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['optimize_via_html_dom_parser'] = '1';
77+
78+
$html = '<html><head><meta charset="utf-8"></head><body><!-- just a comment --><p>Hello</p></body></html>';
79+
80+
$result = $this->subject->minify($html);
81+
82+
self::assertStringNotContainsString('<!-- just a comment -->', $result);
83+
self::assertStringContainsString('<p>Hello</p>', $result);
84+
}
85+
86+
#[Test]
87+
public function minifyPreservesTypo3CommentWhenRemoveCommentsAndDomParserAreEnabled(): void
88+
{
89+
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['remove_comments'] = '1';
90+
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['optimize_via_html_dom_parser'] = '1';
91+
92+
$html = '<html><head><meta charset="utf-8"><!-- TYPO3CMS id=1 --></head><body><p>Hello</p></body></html>';
93+
94+
$result = $this->subject->minify($html);
95+
96+
self::assertStringContainsString('<!-- TYPO3CMS id=1 -->', $result);
97+
}
98+
99+
#[Test]
100+
public function minifyRemovesRegularCommentButKeepsTypo3CommentWhenBothFlagsAreEnabled(): void
101+
{
102+
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['remove_comments'] = '1';
103+
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['optimize_via_html_dom_parser'] = '1';
104+
105+
$html = '<html><head><meta charset="utf-8"><!-- TYPO3 page --></head><body><!-- drop me --><p>Hello</p></body></html>';
106+
107+
$result = $this->subject->minify($html);
108+
109+
self::assertStringContainsString('<!-- TYPO3 page -->', $result);
110+
self::assertStringNotContainsString('<!-- drop me -->', $result);
111+
}
112+
113+
// -------------------------------------------------------------------------
114+
// Output integrity
115+
// -------------------------------------------------------------------------
116+
117+
#[Test]
118+
public function minifyReturnsFallbackHtmlWhenMinifierProducesEmptyString(): void
119+
{
120+
// An empty string causes the minifier to return '' which triggers
121+
// the $originalHtml fallback — the method must not crash.
122+
$result = $this->subject->minify('');
123+
124+
self::assertSame('', $result);
125+
}
126+
127+
#[Test]
128+
public function minifyAppendsClosingBodyTagWhenAbsentFromMinifiedOutput(): void
129+
{
130+
// Enable features that actually cause HtmlMin to strip closing tags.
131+
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['remove_comments'] = '1';
132+
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['optimize_via_html_dom_parser'] = '1';
133+
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['minify']['remove_omitted_html_tags'] = '1';
134+
135+
$html = '<html><head><meta charset="utf-8"></head><body><p>Hello</p></body></html>';
136+
137+
$result = $this->subject->minify($html);
138+
139+
self::assertStringEndsWith('</body>', $result);
140+
}
141+
}

composer.json

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,28 @@
88
"source": "https://github.com/pluswerk/minify"
99
},
1010
"require": {
11-
"php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0",
11+
"php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0",
1212
"composer-runtime-api": "^2",
13-
"typo3/cms-core": "^11.5 || ^12.4 || ^13.4",
14-
"voku/html-min": "^4.5.1"
13+
"typo3/cms-core": "^12.4 || ^13.4",
14+
"voku/html-min": "^5.0.0"
1515
},
1616
"require-dev": {
1717
"andersundsehr/ssi-include": "^1.1.0 || ^2.2.0",
1818
"pluswerk/grumphp-config": "^7 || ^10",
19-
"saschaegerer/phpstan-typo3": "^1.10.0 || ^2.1.1",
20-
"ssch/typo3-rector": "^2.5.0 || ^3.6.2"
19+
"saschaegerer/phpstan-typo3": "^1.10.2 || ^2.1.1",
20+
"ssch/typo3-rector": "^2.15.2 || ^3.14.1",
21+
"typo3/testing-framework": "^8.2 || ^9.4"
2122
},
2223
"autoload": {
2324
"psr-4": {
2425
"Pluswerk\\PlusMinify\\": "Classes/"
2526
}
2627
},
28+
"autoload-dev": {
29+
"psr-4": {
30+
"Pluswerk\\PlusMinify\\Tests\\": "Tests/"
31+
}
32+
},
2733
"config": {
2834
"allow-plugins": {
2935
"ergebnis/composer-normalize": true,
@@ -39,5 +45,16 @@
3945
"typo3/cms": {
4046
"extension-key": "minify"
4147
}
48+
},
49+
"scripts": {
50+
"switchto12": [
51+
"rm -rf composer.lock vendor/composer/installed.json",
52+
"@composer req typo3/minimal:^12 --dev --no-interaction --no-progress"
53+
],
54+
"switchto13": [
55+
"rm -rf composer.lock vendor/composer/installed.json",
56+
"@composer req typo3/minimal:^13 --dev --no-interaction --no-progress"
57+
],
58+
"test": "@php ./vendor/bin/phpunit --testdox --stderr"
4259
}
4360
}

ext_emconf.php

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)