Skip to content

Commit f5e06c8

Browse files
authored
!!![TASK] TYPO3 v14 only (#37)
* use own cache for asssets instead saving assets in INTincScript_ext of TSFE (which is gone) * additional: CSS Resource Compression is dropped
1 parent 8dba13f commit f5e06c8

22 files changed

+175
-296
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
runs-on: ubuntu-latest
99
strategy:
1010
matrix:
11-
TYPO3: ['12', '13']
11+
TYPO3: ['14']
1212

1313
steps:
1414
- name: Checkout
@@ -32,25 +32,13 @@ jobs:
3232
path: ~/.composer/cache
3333
key: dependencies-composer-${{ hashFiles('composer.json') }}
3434

35-
- name: Install composer dependencies TYPO3 13
36-
if: matrix.TYPO3 == '13'
35+
- name: Install composer dependencies TYPO3 14
36+
if: matrix.TYPO3 == '14'
3737
run: |
3838
composer install --no-progress --no-interaction
39-
40-
- name: Install composer dependencies TYPO3 12
41-
if: matrix.TYPO3 == '12'
42-
run: |
43-
composer require typo3/cms-core:^12.4 --no-progress --no-interaction --dev -W
44-
- name: Install composer dependencies TYPO3 11
45-
if: matrix.TYPO3 == '11'
46-
run: |
47-
composer require typo3/cms-core:^11.5 --no-progress --no-interaction --dev -W
48-
- name: Phpstan 12/13
49-
if: matrix.TYPO3 != '11'
39+
- name: Phpstan
40+
if: matrix.TYPO3 == '14'
5041
run: .Build/bin/phpstan analyze -c Build/phpstan.neon
51-
- name: Phpstan 11
52-
if: matrix.TYPO3 == '11'
53-
run: .Build/bin/phpstan analyze -c Build/phpstan11.neon
5442
- name: Phpcsfix
5543
run: .Build/bin/php-cs-fixer fix --config=Build/php-cs-fixer.php --dry-run --stop-on-violation --using-cache=no
5644
- name: Unit Tests

Build/php-cs-fixer.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,10 @@
22

33
$config = \TYPO3\CodingStandards\CsFixerConfig::create();
44
$config->getFinder()->exclude(['var'])->in(__DIR__ . '/..');
5+
$config->addRules([
6+
'nullable_type_declaration' => [
7+
'syntax' => 'question_mark',
8+
],
9+
'nullable_type_declaration_for_default_null_value' => true,
10+
]);
511
return $config;

Build/phpstan.neon

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
includes:
2-
- ../.Build/vendor/saschaegerer/phpstan-typo3/extension.neon
31
parameters:
42
level: 5
53
paths:

Build/phpstan11.neon

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

Classes/AssetCollector.php

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,15 @@
1212
* of the License, or any later version.
1313
*/
1414

15-
use B13\Assetcollector\Resource\ResourceCompressor;
1615
use Psr\Http\Message\ServerRequestInterface;
17-
use TYPO3\CMS\Core\Information\Typo3Version;
18-
use TYPO3\CMS\Core\SingletonInterface;
1916
use TYPO3\CMS\Core\TypoScript\FrontendTypoScript;
2017
use TYPO3\CMS\Core\Utility\GeneralUtility;
2118
use TYPO3\CMS\Core\Utility\PathUtility;
22-
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
2319

2420
/**
2521
* Main collector class to be used everywhere
2622
*/
27-
class AssetCollector implements SingletonInterface
23+
class AssetCollector
2824
{
2925
protected array $inlineCss = [];
3026
protected array $cssFiles = [];
@@ -132,8 +128,7 @@ public function buildInlineCssTag(): string
132128
}
133129
}
134130
if (trim($inlineCss) !== '') {
135-
$compressor = GeneralUtility::makeInstance(ResourceCompressor::class);
136-
return '<style class="tx_assetcollector">' . $compressor->publicCompressCssString($inlineCss) . '</style>';
131+
return '<style class="tx_assetcollector">' . trim($inlineCss) . '</style>';
137132
}
138133
return '';
139134
}
@@ -144,9 +139,6 @@ protected function cssContentWithResolvedPaths(string $cssFile): string
144139
$absoluteFile = GeneralUtility::getFileAbsFileName($cssFile);
145140
if (file_exists($absoluteFile)) {
146141
$content = $this->removeUtf8Bom(file_get_contents($absoluteFile));
147-
if ((GeneralUtility::makeInstance(Typo3Version::class))->getMajorVersion() < 11) {
148-
return $content;
149-
}
150142
preg_match_all('/url\("([a-zA-Z0-9_.\-\/]+)"\)/', $content, $matches);
151143
if (!empty($matches[1])) {
152144
$content = $this->replacePaths($matches[1], $cssFile, $content);
@@ -259,33 +251,18 @@ public function getTypoScriptValue(string $name): string
259251
protected function loadTypoScript(): void
260252
{
261253
$this->typoScriptConfiguration = [];
262-
if (GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion() < 12) {
263-
$frontendController = $this->getTypoScriptFrontendController();
264-
if ($frontendController !== null) {
265-
$this->typoScriptConfiguration = $frontendController->tmpl->setup['plugin.']['tx_assetcollector.']['icons.'] ?? [];
266-
}
267-
} else {
268-
$request = $this->getServerRequest();
269-
if ($request === null) {
270-
return;
271-
}
272-
/** @var FrontendTypoScript $typoScript */
273-
$typoScript = $request->getAttribute('frontend.typoscript');
274-
$setup = $typoScript->getSetupArray();
275-
$this->typoScriptConfiguration = $setup['plugin.']['tx_assetcollector.']['icons.'] ?? [];
254+
$request = $this->getServerRequest();
255+
if ($request === null) {
256+
return;
276257
}
258+
/** @var FrontendTypoScript $typoScript */
259+
$typoScript = $request->getAttribute('frontend.typoscript');
260+
$setup = $typoScript->getSetupArray();
261+
$this->typoScriptConfiguration = $setup['plugin.']['tx_assetcollector.']['icons.'] ?? [];
277262
}
278263

279264
protected function getServerRequest(): ?ServerRequestInterface
280265
{
281266
return $GLOBALS['TYPO3_REQUEST'] ?? null;
282267
}
283-
284-
protected function getTypoScriptFrontendController(): ?TypoScriptFrontendController
285-
{
286-
if (($GLOBALS['TSFE'] ?? null) instanceof TypoScriptFrontendController) {
287-
return $GLOBALS['TSFE'];
288-
}
289-
return null;
290-
}
291268
}

Classes/Hooks/AssetRenderer.php

Lines changed: 54 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@
1313
*/
1414

1515
use B13\Assetcollector\AssetCollector;
16-
use TYPO3\CMS\Core\Information\Typo3Version;
16+
use Psr\Http\Message\ServerRequestInterface;
17+
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
18+
use TYPO3\CMS\Core\Cache\CacheDataCollector;
19+
use TYPO3\CMS\Core\Cache\CacheTag;
20+
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
21+
use TYPO3\CMS\Core\Http\ApplicationType;
1722
use TYPO3\CMS\Core\Page\PageRenderer;
18-
use TYPO3\CMS\Core\SingletonInterface;
19-
use TYPO3\CMS\Core\Utility\GeneralUtility;
20-
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
23+
use TYPO3\CMS\Frontend\Page\PageInformation;
2124

2225
/**
2326
* Hooks into PageRenderer to add CSS / JS / SVG files
@@ -36,8 +39,13 @@
3639
* With COA_INT 2nd hit
3740
* 1. insertAssets() - taking data from the cache PLUS all the the assets added via USER_INTs
3841
*/
39-
class AssetRenderer implements SingletonInterface
42+
#[Autoconfigure(public: true)]
43+
class AssetRenderer
4044
{
45+
public function __construct(private readonly FrontendInterface $cache, private readonly AssetCollector $assetCollector)
46+
{
47+
}
48+
4149
/**
4250
* Called via PageRenderer->render-postProcess(). Get this:
4351
*
@@ -55,37 +63,35 @@ class AssetRenderer implements SingletonInterface
5563
*/
5664
public function insertAssets($params, PageRenderer $pageRenderer): void
5765
{
58-
$frontendController = $this->getTypoScriptFrontendController();
59-
if ($frontendController instanceof TypoScriptFrontendController) {
60-
$assetCollector = GeneralUtility::makeInstance(AssetCollector::class);
61-
$cached = $this->getFromCached($frontendController);
66+
$request = $this->getServerRequest();
67+
if (ApplicationType::fromRequest($this->getServerRequest())->isFrontend() === false) {
68+
return;
69+
}
70+
if ($request !== null) {
71+
$cached = $this->getFromCached($request);
6272
if (!empty($cached['cssFiles']) && is_array($cached['cssFiles'])) {
63-
$assetCollector->mergeCssFiles($cached['cssFiles']);
73+
$this->assetCollector->mergeCssFiles($cached['cssFiles']);
6474
}
6575
if (!empty($cached['inlineCss']) && is_array($cached['inlineCss'])) {
66-
$assetCollector->mergeInlineCss($cached['inlineCss']);
76+
$this->assetCollector->mergeInlineCss($cached['inlineCss']);
6777
}
6878
if (!empty($cached['jsFiles']) && is_array($cached['jsFiles'])) {
6979
foreach ($cached['jsFiles'] as $data) {
70-
$assetCollector->addJavaScriptFile($data['fileName'], $data['additionalAttributes']);
71-
}
72-
}
73-
// Add individual registered JS files. Only relevant on first hit, fully cacheable
74-
// when the cache is not accessed yet.
75-
foreach ($frontendController->pSetup['jsFiles.'] ?? [] as $key => $jsFile) {
76-
if (is_array($jsFile)) {
77-
continue;
80+
$this->assetCollector->addJavaScriptFile($data['fileName'], $data['additionalAttributes']);
7881
}
79-
$additionalAttributes = $frontendController->pSetup['jsFiles.'][$key . '.'] ?? [];
80-
$assetCollector->addJavaScriptFile($jsFile, $additionalAttributes);
8182
}
8283
$params['headerData'] = array_merge(
8384
$params['headerData'],
84-
[$assetCollector->buildInlineCssTag(), $assetCollector->buildJavaScriptIncludes()]
85+
[$this->assetCollector->buildInlineCssTag(), $this->assetCollector->buildJavaScriptIncludes()]
8586
);
8687
}
8788
}
8889

90+
protected function getServerRequest(): ?ServerRequestInterface
91+
{
92+
return $GLOBALS['TYPO3_REQUEST'] ?? null;
93+
}
94+
8995
/**
9096
* Called via contentPostProc-all hook.
9197
*
@@ -101,61 +107,52 @@ public function insertAssets($params, PageRenderer $pageRenderer): void
101107
* If the page is fully cacheable the hook is not called on a "cached hit".
102108
*
103109
* Then, the full information is again stored in the "b13/assetcollector" bucket.
104-
*
105-
* @param array $params
106-
* @param TypoScriptFrontendController $frontendController
107110
*/
108-
public function collectInlineAssets($params, TypoScriptFrontendController $frontendController): void
111+
public function collectInlineAssets(ServerRequestInterface $serverRequest): void
109112
{
110-
$assetCollector = GeneralUtility::makeInstance(AssetCollector::class);
111-
$cached = $this->getFromCached($frontendController);
112-
113-
// Add individual registered JS files
114-
foreach ($frontendController->pSetup['jsFiles.'] ?? [] as $key => $jsFile) {
115-
if (is_array($jsFile)) {
116-
continue;
117-
}
118-
$additionalAttributes = $frontendController->pSetup['jsFiles.'][$key . '.'] ?? [];
119-
$assetCollector->addJavaScriptFile($jsFile, $additionalAttributes);
120-
}
113+
$cached = $this->getFromCached($serverRequest);
121114
if (!empty($cached['jsFiles']) && is_array($cached['jsFiles'])) {
122115
foreach ($cached['jsFiles'] as $data) {
123-
$assetCollector->addJavaScriptFile($data['fileName'], $data['additionalAttributes']);
116+
$this->assetCollector->addJavaScriptFile($data['fileName'], $data['additionalAttributes']);
124117
}
125118
}
126119
if (!empty($cached['cssFiles']) && is_array($cached['cssFiles'])) {
127-
$assetCollector->mergeCssFiles($cached['cssFiles']);
120+
$this->assetCollector->mergeCssFiles($cached['cssFiles']);
128121
}
129122
if (!empty($cached['inlineCss']) && is_array($cached['inlineCss'])) {
130-
$assetCollector->mergeInlineCss($cached['inlineCss']);
123+
$this->assetCollector->mergeInlineCss($cached['inlineCss']);
131124
}
132125
if (!empty($cached['xmlFiles']) && is_array($cached['xmlFiles'])) {
133-
$assetCollector->mergeXmlFiles($cached['xmlFiles']);
126+
$this->assetCollector->mergeXmlFiles($cached['xmlFiles']);
134127
}
135128
$cached = [
136-
'jsFiles' => $assetCollector->getJavaScriptFiles(),
137-
'cssFiles' => $assetCollector->getUniqueCssFiles(),
138-
'inlineCss' => $assetCollector->getUniqueInlineCss(),
139-
'xmlFiles' => $assetCollector->getUniqueXmlFiles(),
129+
'jsFiles' => $this->assetCollector->getJavaScriptFiles(),
130+
'cssFiles' => $this->assetCollector->getUniqueCssFiles(),
131+
'inlineCss' => $this->assetCollector->getUniqueInlineCss(),
132+
'xmlFiles' => $this->assetCollector->getUniqueXmlFiles(),
140133
];
141-
$this->addToCached($frontendController, $cached);
134+
$this->addToCached($serverRequest, $cached);
142135
}
143136

144-
protected function getFromCached(TypoScriptFrontendController $frontendController): array
137+
protected function getFromCached(ServerRequestInterface $request): array
145138
{
146-
if ((GeneralUtility::makeInstance(Typo3Version::class))->getMajorVersion() < 13) {
147-
return $frontendController->config['b13/assetcollector'] ?? [];
139+
/** @var CacheDataCollector $cacheDataCollector */
140+
$cacheDataCollector = $request->getAttribute('frontend.cache.collector');
141+
$identifier = $cacheDataCollector->getPageCacheIdentifier();
142+
if ($this->cache->has($identifier)) {
143+
return $this->cache->get($identifier);
148144
}
149-
return $frontendController->config['INTincScript_ext']['b13/assetcollector'] ?? [];
145+
return [];
150146
}
151147

152-
protected function addToCached(TypoScriptFrontendController $frontendController, array $data): void
148+
protected function addToCached(ServerRequestInterface $request, array $data): void
153149
{
154-
if ((GeneralUtility::makeInstance(Typo3Version::class))->getMajorVersion() < 13) {
155-
$frontendController->config['b13/assetcollector'] = $data;
156-
} else {
157-
$frontendController->config['INTincScript_ext']['b13/assetcollector'] = $data;
158-
}
150+
/** @var CacheDataCollector $cacheDataCollector */
151+
$cacheDataCollector = $request->getAttribute('frontend.cache.collector');
152+
$identifier = $cacheDataCollector->getPageCacheIdentifier();
153+
$cacheTags = array_map(fn (CacheTag $cacheTag) => $cacheTag->name, $cacheDataCollector->getCacheTags());
154+
$cacheTimeout = $cacheDataCollector->resolveLifetime();
155+
$this->cache->set($identifier, $data, $cacheTags, $cacheTimeout);
159156
}
160157

161158
/**
@@ -167,17 +164,8 @@ protected function addToCached(TypoScriptFrontendController $frontendController,
167164
*/
168165
public function collectCssFiles($params, PageRenderer $pageRenderer): void
169166
{
170-
$assetCollector = GeneralUtility::makeInstance(AssetCollector::class);
171-
foreach ($assetCollector->getExternalCssFiles() as $cssFile) {
167+
foreach ($this->assetCollector->getExternalCssFiles() as $cssFile) {
172168
$pageRenderer->addCssFile($cssFile['fileName'], 'stylesheet', $cssFile['mediaType'], '', false, false, '', true);
173169
}
174170
}
175-
176-
protected function getTypoScriptFrontendController(): ?TypoScriptFrontendController
177-
{
178-
if (($GLOBALS['TSFE'] ?? null) instanceof TypoScriptFrontendController) {
179-
return $GLOBALS['TSFE'];
180-
}
181-
return null;
182-
}
183171
}

Classes/Listener/AfterCacheableContentIsGenerated.php

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

0 commit comments

Comments
 (0)