Skip to content

Commit c19fee2

Browse files
committed
[FEATURE] Add TYPO3 v11 support
1 parent 035a829 commit c19fee2

File tree

7 files changed

+92
-12
lines changed

7 files changed

+92
-12
lines changed

Classes/Http/ResourcePusher.php

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
declare(strict_types = 1);
3+
namespace B13\Http2\Http;
4+
5+
/*
6+
* This file is part of TYPO3 CMS-based extension "http2" by b13.
7+
*
8+
* It is free software; you can redistribute it and/or modify it under
9+
* the terms of the GNU General Public License, either version 2
10+
* of the License, or any later version.
11+
*/
12+
13+
use Psr\Http\Message\ResponseInterface;
14+
use Psr\Http\Message\ServerRequestInterface;
15+
use Psr\Http\Server\MiddlewareInterface;
16+
use Psr\Http\Server\RequestHandlerInterface;
17+
use TYPO3\CMS\Core\Http\NormalizedParams;
18+
use TYPO3\CMS\Core\Utility\PathUtility;
19+
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
20+
21+
/**
22+
* Takes existing accumulated resources and pushes them as HTTP2 <link> headers as middleware.
23+
*
24+
* This considers that everything is required, thus is marked as "preload", not via "prefetch".
25+
*
26+
* Also, it only tackles "script", "style", but we should incorporate font as well.
27+
* See https://w3c.github.io/preload/#as-attribute
28+
*/
29+
class ResourcePusher implements MiddlewareInterface
30+
{
31+
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
32+
{
33+
$response = $handler->handle($request);
34+
if (($GLOBALS['TSFE'] ?? null) instanceof TypoScriptFrontendController) {
35+
$resources = $GLOBALS['TSFE']->config['b13/http2'] ?? null;
36+
/** @var NormalizedParams $normalizedParams */
37+
$normalizedParams = $request->getAttribute('normalizedParams');
38+
if (is_array($resources) && $normalizedParams->isHttps()) {
39+
foreach ($resources['scripts'] ?? [] as $resource) {
40+
$response = $this->addPreloadHeaderToResponse($response, $resource, 'script');
41+
}
42+
foreach ($resources['styles'] ?? [] as $resource) {
43+
$response = $this->addPreloadHeaderToResponse($response, $resource, 'style');
44+
}
45+
}
46+
}
47+
return $response;
48+
}
49+
50+
protected function addPreloadHeaderToResponse(ResponseInterface $response, string $uri, string $type): ResponseInterface
51+
{
52+
return $response->withAddedHeader('Link', '<' . htmlspecialchars(PathUtility::getAbsoluteWebPath($uri)) . '>; rel=preload; as=' . $type);
53+
}
54+
}

Classes/ResourcePusher.php

+14-5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* of the License, or any later version.
1111
*/
1212

13+
use TYPO3\CMS\Core\Information\Typo3Version;
1314
use TYPO3\CMS\Core\Utility\GeneralUtility;
1415
use TYPO3\CMS\Core\Utility\PathUtility;
1516
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
@@ -29,23 +30,23 @@ class ResourcePusher
2930
*/
3031
public function pushAll(array $resources)
3132
{
32-
foreach ($resources['scripts'] as $resource) {
33+
foreach ($resources['scripts'] ?? [] as $resource) {
3334
$this->addPreloadHeader($resource, 'script');
3435
}
35-
foreach ($resources['styles'] as $resource) {
36+
foreach ($resources['styles'] ?? [] as $resource) {
3637
$this->addPreloadHeader($resource, 'style');
3738
}
3839
}
3940

4041
/**
4142
* @param array $params
4243
* @param TypoScriptFrontendController $typoScriptFrontendController
43-
* @internal this is just a hook implementation.
44+
* @internal this is just a hook implementation. can be removed when TYPO3 v9 support is removed.
4445
*/
4546
public function pushForFrontend(array $params, TypoScriptFrontendController $typoScriptFrontendController)
4647
{
47-
$allResources = $typoScriptFrontendController->config['b13/http2'];
48-
if (GeneralUtility::getIndpEnv('TYPO3_SSL') && is_array($allResources)) {
48+
$allResources = $typoScriptFrontendController->config['b13/http2'] ?? null;
49+
if ($this->useHook() && GeneralUtility::getIndpEnv('TYPO3_SSL') && is_array($allResources)) {
4950
$this->pushAll($allResources);
5051
}
5152
}
@@ -60,4 +61,12 @@ protected function addPreloadHeader(string $uri, string $type)
6061
{
6162
header('Link: <' . htmlspecialchars(PathUtility::getAbsoluteWebPath($uri)) . '>; rel=preload; as=' . $type, false);
6263
}
64+
65+
protected function useHook(): bool
66+
{
67+
if (class_exists(Typo3Version::class) && (new Typo3Version())->getMajorVersion() >= 10) {
68+
return false;
69+
}
70+
return true;
71+
}
6372
}

Configuration/RequestMiddlewares.php

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
return [
3+
'frontend' => [
4+
'b13/http2/push-resources' => [
5+
'target' => \B13\Http2\Http\ResourcePusher::class,
6+
'before' => [
7+
'typo3/cms-frontend/prepare-tsfe-rendering',
8+
],
9+
'after' => [
10+
'typo3/cms-frontend/authentication',
11+
],
12+
],
13+
]
14+
];

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ This TYPO3 extension fetches all CSS and JS resources that are used
88
for a page-rendering and sends additional HTTP/2 Headers "Link" for each resource
99
resulting in a faster first contentful paint for TYPO3 CMS.
1010

11-
This extension currently runs on TYPO3 v7 LTS, TYPO3 v8 LTS and TYPO3 v9 LTS.
11+
This extension currently runs on TYPO3 v7, TYPO3 v8, TYPO3 v9, TYPO3 v10 and TYPO3 v11,
12+
and needs PHP 7.0 or higher.
1213

1314
## Installation
1415

@@ -33,11 +34,10 @@ Also, use PHP7 - if you care about performance or supported PHP versions, there
3334
1. Hook into the "PageRenderer" API class by fetching the concatenated CSS / JS files, and
3435
libraries.
3536
2. If in FE, this is stored within TSFE together with cached data (could be run twice here for non-cached info)
36-
3. Send to the client via `header()` - in BE directly or in FE at the end of the request.
37+
3. Send to the client via `header()` - in BE directly or in FE at the end of the request via a PSR-15 middleware (TYPO3 v10+ only).
3738

3839
## ToDo
3940

40-
* Use Middlewares and PSR-7 for TYPO3 v9
4141
* Implement options to also allow to define other resources (fonts/images), e.g. via TypoScript.
4242
* Use proper DTOs instead of arrays.
4343

composer.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
"description": "Speed up TYPO3 rendering via HTTP/2 Server Push",
55
"require": {
66
"php": "^7.0",
7-
"typo3/cms-core": "^7.6 || ^8.7 || ^9.5 || ^10.0",
8-
"typo3/cms-frontend": "^7.6 || ^8.7 || ^9.5 || ^10.0"
7+
"psr/http-server-middleware": "^1.0",
8+
"typo3/cms-core": "^7.6 || ^8.7 || ^9.5 || ^10.0 || ^11.0",
9+
"typo3/cms-frontend": "^7.6 || ^8.7 || ^9.5 || ^10.0 || ^11.0"
910
},
1011
"require-dev": {
1112
"phpunit/phpunit": "~7.0",

ext_emconf.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
'state' => 'stable',
99
'clearcacheonload' => 1,
1010
'author' => 'b13 GmbH',
11-
'author_email' => 'typo3@b13.de',
11+
'author_email' => 'typo3@b13.com',
1212
'author_company' => 'b13 GmbH',
1313
'constraints' => [
1414
'depends' => [
15-
'typo3' => '7.6.0-10.99.99',
15+
'typo3' => '7.6.0-11.99.99',
1616
],
1717
],
1818
];

ext_localconf.php

+2
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22
defined('TYPO3_MODE') or die();
33

44
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postProcess']['b13/http2'] = B13\Http2\PageRendererHook::class . '->accumulateResources';
5+
6+
// can be removed as soon as TYPO3 v9 support is dropped, as this is now taken care of by a middleware
57
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-output']['b13/http2'] = B13\Http2\ResourcePusher::class . '->pushForFrontend';

0 commit comments

Comments
 (0)