Skip to content

Commit

Permalink
Move changing language request set in header X-Locale to earlier stag…
Browse files Browse the repository at this point in the history
…e, before "typo3/cms-frontend/tsfe". Add support for setting language of api request by standard language prefix instead of header X-Locale.
  • Loading branch information
kszymukowicz committed Apr 28, 2024
1 parent 1bf367c commit c36be25
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 14 deletions.
11 changes: 2 additions & 9 deletions Classes/Hook/EnrichHashBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

namespace SourceBroker\T3api\Hook;

use SourceBroker\T3api\Routing\Enhancer\ResourceEnhancer;
use TYPO3\CMS\Core\Http\ServerRequest;
use SourceBroker\T3api\Service\RouteService;

class EnrichHashBase
{
Expand All @@ -17,13 +16,7 @@ class EnrichHashBase
*/
public function init(array &$params): void
{
/** @var ServerRequest $request */
$request = $GLOBALS['TYPO3_REQUEST'] ?? null;
if (
$request instanceof ServerRequest
&& is_array($request->getQueryParams())
&& array_key_exists(ResourceEnhancer::PARAMETER_NAME, $request->getQueryParams())
) {
if (RouteService::routeHasT3ApiResourceEnhancerQueryParam()) {
$params['hashParameters']['t3api_hash_base_random'] = microtime();
}
}
Expand Down
48 changes: 48 additions & 0 deletions Classes/Middleware/T3apiRequestLanguageResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace SourceBroker\T3api\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use SourceBroker\T3api\Service\RouteService;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;

class T3apiRequestLanguageResolver implements MiddlewareInterface
{
/**
* Prepare Language switch for t3api
*
* @param ServerRequestInterface $request
* @param RequestHandlerInterface $handler
* @return ResponseInterface
*/
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface {

/** @var SiteLanguage $language */
$language = $request->getAttribute('language');
$t3apiHeaderLanguageUid = $this->getT3apiLanguageUid($request);

if ($t3apiHeaderLanguageUid !== null
&& RouteService::routeHasT3ApiResourceEnhancerQueryParam($request)
&& ($language && $language->getLanguageId() !== $t3apiHeaderLanguageUid)
) {
$request->withAttribute('t3apiHeaderLanguageRequest', true);
$request = $request->withAttribute(
'language',
$request->getAttribute('site')->getLanguageById($t3apiHeaderLanguageUid)
);
}
return $handler->handle($request);
}

protected function getT3apiLanguageUid(ServerRequestInterface $request): ?int
{
$languageHeader = $request->getHeader($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['t3api']['languageHeader']);
return (!empty($languageHeader) ? (int)array_shift($languageHeader) : null);
}
}
4 changes: 2 additions & 2 deletions Classes/Middleware/T3apiRequestResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Psr\Http\Server\RequestHandlerInterface;
use SourceBroker\T3api\Dispatcher\Bootstrap;
use SourceBroker\T3api\Routing\Enhancer\ResourceEnhancer;
use SourceBroker\T3api\Service\RouteService;
use Throwable;

/**
Expand All @@ -29,8 +30,7 @@ public function __construct(Bootstrap $bootstrap)
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
if (is_array($request->getQueryParams())
&& array_key_exists(ResourceEnhancer::PARAMETER_NAME, $request->getQueryParams())) {
if (RouteService::routeHasT3ApiResourceEnhancerQueryParam($request)) {
return $this->bootstrap->process($this->cleanupRequest($request));
}

Expand Down
37 changes: 34 additions & 3 deletions Classes/Service/RouteService.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

namespace SourceBroker\T3api\Service;

use Psr\Http\Message\ServerRequestInterface;
use RuntimeException;
use SourceBroker\T3api\Routing\Enhancer\ResourceEnhancer;
use TYPO3\CMS\Core\Http\ServerRequest;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;

class RouteService implements SingletonInterface
{
Expand All @@ -24,7 +27,7 @@ public static function getApiBasePath(): string
*/
public static function getFullApiBasePath(): string
{
return trim(self::getDefaultLanguageBasePath() . self::getApiBasePath(), '/');
return trim(self::getLanguageBasePath() . self::getApiBasePath(), '/');
}

public static function getFullApiBaseUrl(): string
Expand All @@ -33,6 +36,13 @@ public static function getFullApiBaseUrl(): string
. '/' . ltrim(self::getFullApiBasePath(), '/');
}

public static function routeHasT3ApiResourceEnhancerQueryParam(ServerRequestInterface $request = null): bool
{
$request = $request ?? self::getRequest();
return $request instanceof ServerRequest && is_array($request->getQueryParams())
&& array_key_exists(ResourceEnhancer::PARAMETER_NAME, $request->getQueryParams());
}

protected static function getApiRouteEnhancer(): array
{
static $apiRouteEnhancer;
Expand All @@ -57,8 +67,29 @@ protected static function getApiRouteEnhancer(): array
);
}

protected static function getDefaultLanguageBasePath(): string
/**
* We support for two cases:language set in X-Locale header
* 1) when request has X-Locale header with language (t3apiHeaderLanguageRequest))
* 2) when request has no X-Locale header and url itself stores language information
*/
protected static function getLanguageBasePath(): string
{
$request = self::getRequest();
/** @var SiteLanguage $requestLanguage */
$requestLanguage = $request->getAttribute('language');
$languagePrefix = $requestLanguage && $request->getAttribute('t3apiHeaderLanguageRequest') !== true ?
$requestLanguage->getBase()->getPath() :
SiteService::getCurrent()->getDefaultLanguage()->getBase()->getPath();

if (str_starts_with((string)$request?->getUri()->getPath(), $languagePrefix)) {
return $languagePrefix;
}

return '';
}

protected static function getRequest(): ServerRequestInterface
{
return SiteService::getCurrent()->getDefaultLanguage()->getBase()->getPath();
return $GLOBALS['TYPO3_REQUEST'];
}
}
9 changes: 9 additions & 0 deletions Configuration/RequestMiddlewares.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

return [
'frontend' => [
'sourcebroker/t3api/prepare-api-request' => [
'target' => \SourceBroker\T3api\Middleware\T3apiRequestLanguageResolver::class,
'after' => [
'typo3/cms-frontend/site'
],
'before' => [
'typo3/cms-frontend/tsfe'
]
],
'sourcebroker/t3api/process-api-request' => [
'target' => \SourceBroker\T3api\Middleware\T3apiRequestResolver::class,
'after' => [
Expand Down
1 change: 1 addition & 0 deletions Documentation/Miscellaneous/Changelog/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Changelog
- Protect against "&cHash empty" error when ``cacheHash.enforceValidation`` is set to ``true`` [`issue <https://github.com/sourcebroker/t3api/issues/81>`__]
- Add testing instance for TYPO3 12, remove testing instance for TYPO3 10. Change PHP to 8.1 for testing instances.
- [!!!] Drop TYPO3 10, TYPO3 11 on dependencies. Update dependencies to TYPO3 12.
- Move changing language request set in header X-Locale to earlier stage, before "typo3/cms-frontend/tsfe". Add support for setting language of api request by standard language prefix instead of header X-Locale.

2.0.3
=====
Expand Down

0 comments on commit c36be25

Please sign in to comment.