diff --git a/Classes/Bootstrap.php b/Classes/Bootstrap.php index 2b72afaf..e86c4465 100755 --- a/Classes/Bootstrap.php +++ b/Classes/Bootstrap.php @@ -3,327 +3,66 @@ namespace Cundd\Rest; -use Locale; -use Psr\Http\Message\ServerRequestInterface; -use stdClass; -use TYPO3\CMS\Core\Routing\SiteMatcher; -use TYPO3\CMS\Core\Routing\SiteRouteResult; -use TYPO3\CMS\Core\TimeTracker\TimeTracker; +use Cundd\Rest\Bootstrap\Core; +use Cundd\Rest\Bootstrap\LanguageBootstrap; +use TYPO3\CMS\Core\Error\Http\ServiceUnavailableException; +use TYPO3\CMS\Core\Http\ServerRequest; +use TYPO3\CMS\Core\Http\ServerRequestFactory; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Extbase\Object\ObjectManager; use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; -use TYPO3\CMS\Frontend\Utility\EidUtility; -use TYPO3\CMS\Lang\LanguageService; -use function class_exists; -use function intval; -use function is_int; -use function is_string; - /** - * Class to bootstrap TYPO3 frontend controller + * @deprecated will be removed in 5.0. Use \Cundd\Rest\Bootstrap\Core instead */ class Bootstrap { /** - * Initializes the TYPO3 environment - * - * @param TypoScriptFrontendController|null $frontendController - * @return TypoScriptFrontendController - * @throws \TYPO3\CMS\Core\Error\Http\ServiceUnavailableException - * @throws \TYPO3\CMS\Core\Http\ImmediateResponseException + * @var Core */ - public function init(TypoScriptFrontendController $frontendController = null) - { - $this->initializeTimeTracker(); - $this->initializeLanguageObject(); - - $frontendController = $frontendController ?: $this->buildFrontendController($this->getPageUid()); - - if ($this->getFrontendControllerIsInitialized()) { - return $GLOBALS['TSFE']; - } - - // Register the frontend controller as the global TSFE - $GLOBALS['TSFE'] = $frontendController; - $this->configureFrontendController($frontendController); - - return $frontendController; - } + private $coreBootstrap; /** - * Initialize language object + * @var ServerRequest */ - public function initializeLanguageObject() - { - if (!isset($GLOBALS['LANG']) || !is_object($GLOBALS['LANG'])) { - /** @var LanguageService $GLOBALS ['LANG'] */ - $GLOBALS['LANG'] = GeneralUtility::makeInstance(LanguageService::class); - $GLOBALS['LANG']->init($this->getRequestedLanguageCode()); - } - } - - private function initializeTimeTracker() - { - if (!isset($GLOBALS['TT']) || !is_object($GLOBALS['TT'])) { - $GLOBALS['TT'] = new TimeTracker(); - $GLOBALS['TT']->start(); - } - } - - /** - * Build the TSFE object - * - * @param int $pageUid - * @return TypoScriptFrontendController - */ - private function buildFrontendController(int $pageUid): TypoScriptFrontendController - { - $cHash = GeneralUtility::_GP('cHash') ?: 'cunddRestFakeHash'; - - $objectManager = GeneralUtility::makeInstance(ObjectManager::class); - - return $objectManager->get( - TypoScriptFrontendController::class, - null, // previously TYPO3_CONF_VARS - $pageUid, - 0, // Type - 0, // no_cache - $cHash, // cHash - null, // previously jumpurl - '', // MP, - '' // RDCT - ); - } - - /** - * @return int - */ - private function getPageUid(): int - { - return GeneralUtility::_GP('pid') !== null - ? intval(GeneralUtility::_GP('pid')) - : 0; - } - - /** - * @return bool - */ - private function getFrontendControllerIsInitialized(): bool - { - return isset($GLOBALS['TSFE']) - && is_object($GLOBALS['TSFE']) - && !($GLOBALS['TSFE'] instanceof stdClass); - } - - /** - * Configure the given frontend controller - * - * @param TypoScriptFrontendController $frontendController - * @throws \TYPO3\CMS\Core\Error\Http\ServiceUnavailableException - * @throws \TYPO3\CMS\Core\Http\ImmediateResponseException - */ - private function configureFrontendController(TypoScriptFrontendController $frontendController) - { - $frontendController->initTemplate(); - - if (!is_array($frontendController->page)) { - $frontendController->page = []; - } - - // Build an instance of ContentObjectRenderer - $frontendController->newCObj(); - - // Add the FE user - $frontendController->fe_user = EidUtility::initFeUser(); - - $frontendController->determineId(); - $frontendController->getConfigArray(); - - $this->detectAndSetRequestedLanguage($frontendController); - //try { - // $frontendController->settingLanguage(); - //} catch (\RuntimeException $exception) { - //} - $frontendController->settingLocale(); - } + private $request; /** - * Configure the system to use the requested language UID - * - * @param TypoScriptFrontendController $frontendController + * @var LanguageBootstrap */ - private function detectAndSetRequestedLanguage(TypoScriptFrontendController $frontendController) - { - if (!isset($GLOBALS['TYPO3_REQUEST']) || !class_exists(SiteMatcher::class)) { - $this->setRequestedLanguage($frontendController, $this->getRequestedLanguageUid($frontendController)); - - return; - } - - // support new TYPO3 v9.2 Site Handling until middleware concept is implemented - // see https://github.com/cundd/rest/issues/59 - /** @var ServerRequestInterface $request */ - $request = $GLOBALS['TYPO3_REQUEST']; - - /** - * Try to detect the language ID from request parameters or headers. If the SiteMatcher detects a language this - * fallback will **not** be used - * - * @var int|null $fallbackLanguageId - */ - $fallbackLanguageId = (int)($request->getQueryParams()['L'] - ?? $request->getParsedBody()['L'] - ?? $this->getRequestedLanguageUid($frontendController)); - - - /** @var SiteRouteResult $routeResult */ - $routeResult = GeneralUtility::makeInstance(SiteMatcher::class)->matchRequest($request); - - - $site = $routeResult->getSite(); - $language = $routeResult->getLanguage(); - - // If TYPO3 could not determine the language for the request use the detected fallback - if (!$language && $fallbackLanguageId !== null) { - $language = $site->getLanguageById($fallbackLanguageId); - } - - $request = $request->withAttribute('site', $site); - $request = $request->withAttribute('language', $language); - $request = $request->withAttribute('routing', $routeResult); - - // Patch the original Request so that at least `site` and `routing` are defined - $GLOBALS['TYPO3_REQUEST'] = $request - ->withAttribute('site', $site) - ->withAttribute('language', $language) - ->withAttribute('routing', $routeResult); - - // Set language if defined - if ($language && $language->getLanguageId() !== null) { - $this->setRequestedLanguage($frontendController, $language->getLanguageId()); - } else { - $this->setRequestedLanguage($frontendController, $fallbackLanguageId); - } - } + private $languageBootstrap; /** - * Detect the language UID for the requested language - * - * @param TypoScriptFrontendController $frontendController - * @return int|null + * Bootstrap constructor */ - private function getRequestedLanguageUid(TypoScriptFrontendController $frontendController): ?int + public function __construct() { - if (GeneralUtility::_GP('L') !== null) { - return (int)GeneralUtility::_GP('L'); - } - if (GeneralUtility::_GP('locale') !== null) { - $languageId = $this->getLanguageIdForCode($frontendController, GeneralUtility::_GP('locale')); - if ($languageId !== null) { - return $languageId; - } - } - - // Test the full HTTP_ACCEPT_LANGUAGE header - if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { - $languageId = $this->getLanguageIdForCode( - $frontendController, - (string)$_SERVER['HTTP_ACCEPT_LANGUAGE'] - ); - - if ($languageId !== null) { - return $languageId; - } - } - - // Retrieve and test the parsed header - $languageCode = $this->getRequestedLanguageCode(); - if ($languageCode !== null) { - $languageId = $this->getLanguageIdForCode($frontendController, $languageCode); - if ($languageId !== null) { - return $languageId; - } - } - - return null; + $objectManager = GeneralUtility::makeInstance(ObjectManager::class); + $this->coreBootstrap = $objectManager->get(Core::class); + $this->languageBootstrap = $objectManager->get(LanguageBootstrap::class); + $this->request = ServerRequestFactory::fromGlobals(); } /** - * Retrieve the TypoScript configuration for the given key path + * Initializes the TYPO3 environment * - * @param string $keyPath - * @param TypoScriptFrontendController $typoScriptFrontendController - * @return mixed + * @param TypoScriptFrontendController|null $frontendController + * @return TypoScriptFrontendController + * @throws ServiceUnavailableException + * @deprecated will be removed in 5.0. Use \Cundd\Rest\Bootstrap\Core::initialize() instead */ - private function readConfigurationFromTyposcript( - string $keyPath, - TypoScriptFrontendController $typoScriptFrontendController + public function init( + /** @noinspection PhpUnusedParameterInspection */ TypoScriptFrontendController $frontendController = null ) { - $keyPathParts = explode('.', (string)$keyPath); - $currentValue = $typoScriptFrontendController->tmpl->setup; - - foreach ($keyPathParts as $currentKey) { - if (isset($currentValue[$currentKey . '.'])) { - $currentValue = $currentValue[$currentKey . '.']; - } elseif (isset($currentValue[$currentKey])) { - $currentValue = $currentValue[$currentKey]; - } else { - return null; - } - } - - return $currentValue; + return $this->coreBootstrap->initialize($this->request); } /** - * Detect the requested language + * Initialize language object * - * @return null|string + * @deprecated will be removed in 5.0. Use \Cundd\Rest\Bootstrap\LanguageBootstrap::initializeLanguageObject() instead */ - private function getRequestedLanguageCode(): ?string - { - if (class_exists('Locale') && isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { - /** @noinspection PhpComposerExtensionStubsInspection */ - return Locale::getPrimaryLanguage(Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE'])); - } - - return null; - } - - /** - * @param TypoScriptFrontendController $frontendController - * @param string $languageCode - * @return int - */ - private function getLanguageIdForCode(TypoScriptFrontendController $frontendController, string $languageCode): ?int + public function initializeLanguageObject() { - $value = $this->readConfigurationFromTyposcript( - 'plugin.tx_rest.settings.languages.' . $languageCode, - $frontendController - ); - if (is_int($value)) { - return $value; - } elseif (is_string($value)) { - return trim($value) === '' ? null : (int)$value; - } else { - return null; - } - } - - /** - * @param TypoScriptFrontendController $frontendController - * @param int|null $requestedLanguageUid - */ - private function setRequestedLanguage( - TypoScriptFrontendController $frontendController, - ?int $requestedLanguageUid - ): void { - if (null !== $requestedLanguageUid) { - $frontendController->config['config']['sys_language_uid'] = $requestedLanguageUid; - // Add LinkVars and language to work with correct localized labels - $frontendController->config['config']['linkVars'] = 'L(int)'; - $frontendController->config['config']['language'] = $this->getRequestedLanguageCode(); - } + $this->languageBootstrap->initializeLanguageObject($this->request); } } diff --git a/Classes/Bootstrap/Core.php b/Classes/Bootstrap/Core.php new file mode 100755 index 00000000..e5655fea --- /dev/null +++ b/Classes/Bootstrap/Core.php @@ -0,0 +1,149 @@ +languageBootstrap = $languageBootstrap; + $this->objectManager = $objectManager; + } + + /** + * Initializes the TYPO3 environment + * + * @param ServerRequestInterface $request + * @return TypoScriptFrontendController + * @throws ServiceUnavailableException + */ + public function initialize(ServerRequestInterface $request): TypoScriptFrontendController + { + $this->initializeTimeTracker(); + $this->languageBootstrap->initializeLanguageObject($request); + + if ($this->getFrontendControllerIsInitialized()) { + return $GLOBALS['TSFE']; + } + $frontendController = $this->buildFrontendController($this->getPageUid($request)); + + // Register the frontend controller as the global TSFE + $GLOBALS['TSFE'] = $frontendController; + $this->configureFrontendController($frontendController); + $this->languageBootstrap->initializeFrontendController($frontendController, $request); + + return $frontendController; + } + + private function initializeTimeTracker() + { + if (!isset($GLOBALS['TT']) || !is_object($GLOBALS['TT'])) { + $GLOBALS['TT'] = new TimeTracker(); + $GLOBALS['TT']->start(); + } + } + + /** + * @return bool + */ + private function getFrontendControllerIsInitialized(): bool + { + return isset($GLOBALS['TSFE']) + && is_object($GLOBALS['TSFE']) + && !($GLOBALS['TSFE'] instanceof stdClass); + } + + /** + * Build the TSFE object + * + * @param int $pageUid + * @return TypoScriptFrontendController + */ + private function buildFrontendController(int $pageUid): TypoScriptFrontendController + { + $cHash = GeneralUtility::_GP('cHash') ?: 'cunddRestFakeHash'; + + /** @var TypoScriptFrontendController $frontendController */ + $frontendController = $this->objectManager->get( + TypoScriptFrontendController::class, + null, // previously TYPO3_CONF_VARS + $pageUid, + 0, // Type + 0, // no_cache + $cHash, // cHash + null, // previously jumpurl + '', // MP, + '' // RDCT + ); + + return $frontendController; + } + + /** + * @param ServerRequestInterface $request + * @return int + */ + private function getPageUid(ServerRequestInterface $request): int + { + return (int)($request->getQueryParams()['pid'] ?? 0); + } + + /** + * Configure the given frontend controller + * + * @param TypoScriptFrontendController $frontendController + * @throws ServiceUnavailableException + */ + private function configureFrontendController(TypoScriptFrontendController $frontendController) + { + if (is_callable([$frontendController, 'initTemplate'])) { + $frontendController->initTemplate(); + } + + if (!is_array($frontendController->page)) { + $frontendController->page = []; + } + + // Build an instance of ContentObjectRenderer + $frontendController->newCObj(); + + // Add the FE user + if (class_exists(EidUtility::class)) { + $frontendController->fe_user = EidUtility::initFeUser(); + } + + $frontendController->determineId(); + $frontendController->getConfigArray(); + } +} diff --git a/Classes/Bootstrap/LanguageBootstrap.php b/Classes/Bootstrap/LanguageBootstrap.php new file mode 100644 index 00000000..7822cfe4 --- /dev/null +++ b/Classes/Bootstrap/LanguageBootstrap.php @@ -0,0 +1,281 @@ +objectManager = $objectManager; + } + + /** + * Initialize the language settings + * + * @param TypoScriptFrontendController $frontendController + * @param ServerRequestInterface $request + * @return TypoScriptFrontendController + */ + public function initializeFrontendController( + TypoScriptFrontendController $frontendController, + ServerRequestInterface $request + ) { + $this->detectAndSetRequestedLanguage($frontendController, $request); + + return $frontendController; + } + + /** + * Configure the system to use the requested language + * + * @param TypoScriptFrontendController $frontendController + * @param ServerRequestInterface $request + */ + private function detectAndSetRequestedLanguage( + TypoScriptFrontendController $frontendController, + ServerRequestInterface $request + ) { + $requestedLanguageUid = $this->getRequestedLanguageUid($frontendController, $request); + if (!class_exists(SiteMatcher::class)) { + $this->setRequestedLanguage( + $frontendController, + $requestedLanguageUid, + null + ); + + return; + } + + // support new TYPO3 v9.2 Site Handling until middleware concept is implemented + // see https://github.com/cundd/rest/issues/59 + + /** @var SiteRouteResult $routeResult */ + $routeResult = $this->objectManager->get(SiteMatcher::class)->matchRequest($request); + $site = $routeResult->getSite(); + + // If a language is requested explicitly look if it is available in the Site + if ($requestedLanguageUid) { + $language = $site->getLanguageById($requestedLanguageUid); + } else { + $language = $routeResult->getLanguage(); + } + + // Patch the original Request so that at least `site` and `routing` are defined + $patchedRequest = $request + ->withAttribute('site', $site) + ->withAttribute('language', $language) + ->withAttribute('routing', $routeResult); + $GLOBALS['TYPO3_REQUEST'] = $patchedRequest; + + // Set language if defined + if ($language && $language->getLanguageId() !== null) { + $this->setRequestedLanguage( + $frontendController, + $language->getLanguageId(), + $language->getTwoLetterIsoCode() + ); + } else { + $this->setRequestedLanguage( + $frontendController, + $requestedLanguageUid, + $this->getRequestedPrimaryLanguageCode($patchedRequest) + ); + } + } + + /** + * Detect the language UID for the requested language + * + * - If `$_GET['L']` or `$_POST['L']` are defined, the value will be returned. + * - If `$_GET['locale']` is defined the TypoScript value `plugin.tx_rest.settings.languages.{locale from GET}` will + * be returned if set, otherwise a `InvalidLanguageException` will be thrown. + * - If an `Accept-Language` header is sent, the preferred language will be extracted and looked up in + * `plugin.tx_rest.settings.languages.{preferred language header}`. If the language is registered in + * TypoScript the value will be returned. + * - If none of the above is true `NULL` will be returned + * + * @param TypoScriptFrontendController $frontendController + * @param ServerRequestInterface $request + * @return int|null + */ + private function getRequestedLanguageUid( + TypoScriptFrontendController $frontendController, + ServerRequestInterface $request + ): ?int { + // Check $_GET['L'] + $queryParams = $request->getQueryParams(); + if (isset($queryParams['L'])) { + return (int)$queryParams['L']; + } + + // Check $_POST['L'] + $parsedBody = $request->getParsedBody(); + if (isset($parsedBody['L'])) { + return (int)$parsedBody['L']; + } + + // Check $_GET['locale'] + if (isset($queryParams['locale'])) { + $languageId = $this->getLanguageIdForCode( + $frontendController, + $queryParams['locale'] + ); + + if ($languageId === null) { + throw new InvalidLanguageException( + sprintf('Requested locale "%s" could not be found', $queryParams['locale']) + ); + } + + return $languageId; + } + + // Check the full Accept-Language header + $languageId = $this->getLanguageIdForCode($frontendController, $request->getHeaderLine('Accept-Language')); + if ($languageId !== null) { + return $languageId; + } + + // Check the primary language + $languageCode = $this->getRequestedPrimaryLanguageCode($request); + if ($languageCode === null) { + return null; + } + + $languageId = $this->getLanguageIdForCode($frontendController, $languageCode); + if ($languageId !== null) { + return $languageId; + } + + return null; + } + + /** + * @param TypoScriptFrontendController $frontendController + * @param string $languageCode + * @return int + */ + private function getLanguageIdForCode(TypoScriptFrontendController $frontendController, string $languageCode): ?int + { + if ('' === trim($languageCode)) { + return null; + } + $value = $this->readConfigurationFromTyposcript( + 'plugin.tx_rest.settings.languages.' . $languageCode, + $frontendController + ); + if (is_int($value)) { + return $value; + } elseif (is_string($value)) { + return trim($value) === '' ? null : (int)$value; + } else { + return null; + } + } + + /** + * Retrieve the TypoScript configuration for the given key path + * + * @param string $keyPath + * @param TypoScriptFrontendController $frontendController + * @return mixed + */ + private function readConfigurationFromTyposcript( + string $keyPath, + TypoScriptFrontendController $frontendController + ) { + $keyPathParts = explode('.', (string)$keyPath); + $currentValue = $frontendController->tmpl->setup; + + foreach ($keyPathParts as $currentKey) { + if (isset($currentValue[$currentKey . '.'])) { + $currentValue = $currentValue[$currentKey . '.']; + } elseif (isset($currentValue[$currentKey])) { + $currentValue = $currentValue[$currentKey]; + } else { + return null; + } + } + + return $currentValue; + } + + /** + * Detect the preferred language from the request headers + * + * @param ServerRequestInterface $request + * @return null|string + */ + private function getRequestedPrimaryLanguageCode(ServerRequestInterface $request): ?string + { + $headerValue = $request->getHeaderLine('Accept-Language'); + if (!$headerValue) { + return null; + } + + if (class_exists('Locale')) { + /** @noinspection PhpComposerExtensionStubsInspection PhpFullyQualifiedNameUsageInspection */ + return \Locale::getPrimaryLanguage(\Locale::acceptFromHttp($headerValue)); + } + + if (preg_match('/^[a-z]{2}/', $headerValue, $matches)) { + return $matches[0]; + } + + return null; + } + + /** + * @param TypoScriptFrontendController $frontendController + * @param int|null $requestedLanguageUid + * @param string|null $requestedLanguageCode + */ + private function setRequestedLanguage( + TypoScriptFrontendController $frontendController, + ?int $requestedLanguageUid, + ?string $requestedLanguageCode + ): void { + if (null !== $requestedLanguageUid) { + $frontendController->config['config']['sys_language_uid'] = $requestedLanguageUid; + // Add LinkVars and language to work with correct localized labels + $frontendController->config['config']['linkVars'] = 'L(int)'; + $frontendController->config['config']['language'] = $requestedLanguageCode; + } + + $frontendController->settingLocale(); + } + + /** + * Initialize language object + * + * @param ServerRequestInterface $request + */ + public function initializeLanguageObject(ServerRequestInterface $request) + { + if (!isset($GLOBALS['LANG']) || !is_object($GLOBALS['LANG'])) { + /** @var LanguageService $GLOBALS ['LANG'] */ + $GLOBALS['LANG'] = GeneralUtility::makeInstance(LanguageService::class); + $GLOBALS['LANG']->init($this->getRequestedPrimaryLanguageCode($request)); + } + } +} diff --git a/Classes/BootstrapDispatcher.php b/Classes/BootstrapDispatcher.php index f7a98352..6074fa10 100644 --- a/Classes/BootstrapDispatcher.php +++ b/Classes/BootstrapDispatcher.php @@ -3,15 +3,20 @@ namespace Cundd\Rest; +use Cundd\Rest\Bootstrap\Core; use Cundd\Rest\DataProvider\Utility; use Cundd\Rest\Dispatcher\DispatcherInterface; use Cundd\Rest\Log\LoggerInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; +use TYPO3\CMS\Core\Error\Http\ServiceUnavailableException; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; use TYPO3\CMS\Extbase\Object\Container\Container; +/** + * Main entry point into the REST application + */ class BootstrapDispatcher { /** @@ -30,28 +35,64 @@ class BootstrapDispatcher private $dispatcher; /** - * Initialize - * + * @var array + */ + private $configuration; + + /** + * @var bool + */ + private $isInitialized = false; + + /** * @param ObjectManagerInterface $objectManager * @param array $configuration */ public function __construct(ObjectManagerInterface $objectManager = null, array $configuration = []) { - (new Bootstrap())->init(); + $this->objectManager = $objectManager; + $this->configuration = $configuration; + } - if ($objectManager === null) { - $objectManager = GeneralUtility::makeInstance(ObjectManager::class); - } + /** + * Process the raw request + * + * Entry point for the PSR 7 middleware + * + * @param ServerRequestInterface $request + * @return ResponseInterface + */ + public function processRequest(ServerRequestInterface $request) + { + $this->bootstrap($request); - $this->objectManager = $objectManager; - $this->initializeConfiguration($configuration); - $this->configureObjectManager(); - $this->registerSingularToPlural($objectManager); - $this->configureDispatcher($objectManager); + return $this->dispatcher->processRequest($request); } /** - * Initializes the Configuration Manager + * Bootstrap the TYPO3 environment + * + * @param ServerRequestInterface $request + * @throws ServiceUnavailableException + */ + private function bootstrap(ServerRequestInterface $request) + { + if (!$this->isInitialized) { + $this->initializeObjectManager(); + $coreBootstrap = $this->objectManager->get(Core::class); + $coreBootstrap->initialize($request); + + $this->initializeConfiguration($this->configuration); + $this->configureObjectManager(); + $this->registerSingularToPlural($this->objectManager); + $this->configureDispatcher($this->objectManager); + + $this->isInitialized = true; + } + } + + /** + * Initialize the Configuration Manager instance * * @param array $configuration */ @@ -61,6 +102,16 @@ private function initializeConfiguration(array $configuration) $this->configurationManager->setConfiguration($configuration); } + /** + * Initialize the Object Manager instance + */ + private function initializeObjectManager() + { + if (!$this->objectManager) { + $this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);; + } + } + /** * Configures the object manager object configuration from * config.tx_extbase.objects and plugin.tx_foo.objects @@ -109,17 +160,4 @@ private function configureDispatcher(ObjectManagerInterface $objectManager) $this->dispatcher = new Dispatcher($objectManager, $requestFactory, $responseFactory, $logger); } - - /** - * Process the raw request - * - * Entry point for the PSR 7 middleware - * - * @param ServerRequestInterface $request - * @return ResponseInterface - */ - public function processRequest(ServerRequestInterface $request) - { - return $this->dispatcher->processRequest($request); - } } diff --git a/Classes/Exception/InvalidLanguageException.php b/Classes/Exception/InvalidLanguageException.php new file mode 100644 index 00000000..b6678a21 --- /dev/null +++ b/Classes/Exception/InvalidLanguageException.php @@ -0,0 +1,8 @@ +requestJson( @@ -382,6 +382,16 @@ public function getCorrectTranslationTest($language, $expected) $this->assertArrayHasKey('original', $parsedBody, $errorDescription); $this->assertSame('tx_customrest_domain_model_person.first_name', $parsedBody['original'], $errorDescription); $this->assertSame($expected, $parsedBody['translated'], $errorDescription); + $this->assertArrayHasKey('locale', $parsedBody, $errorDescription); + if ($parsedBody['locale'] === '') { + // TYPO3 8 + } else { + $this->assertSame( + $language, + str_replace('_', '-', substr($parsedBody['locale'], 0, strlen($language))), + $errorDescription + ); + } } public function getCorrectTranslationDataProvider(): array @@ -391,5 +401,4 @@ public function getCorrectTranslationDataProvider(): array ['de-DE', 'Vorname'], ]; } - }