/** * @test */ public function canGetCombinedExtensionKeyFromRequest() { $arguments = array('label' => 'Test field', 'pluginName' => 'API', 'controllerName' => 'Flux', 'actions' => array(), 'disableLocalLanguageLabels' => FALSE, 'excludeActions' => array(), 'localLanguageFileRelativePath' => '/Resources/Private/Language/locallang_db.xml', 'prefixOnRequiredArguments' => '*', 'subActions' => array(), 'separator' => ' :: '); $instance = $this->buildViewHelperInstance($arguments); $request = new Request(); $request->setControllerExtensionName('Flux'); $request->setControllerVendorName('FluidTYPO3'); $expected = 'FluidTYPO3.Flux'; $result = $this->callInaccessibleMethod($instance, 'getFullExtensionNameFromRequest', $request); $this->assertEquals($expected, $result); }
/** * Checks if cHash is required for the current request and calls * TypoScriptFrontendController::reqCHash() if so. * This call will trigger a PageNotFoundException if arguments are required and cHash is not present. * * @param Request $request * @param string $pluginNamespace */ public function enforceForRequest(Request $request, string $pluginNamespace) { $arguments = $request->getArguments(); if (is_array($arguments) && count($arguments) > 0) { $parameters = [$pluginNamespace => $arguments]; $parameters['id'] = $this->typoScriptFrontendController->id; $relevantParameters = $this->cacheHashCalculator->getRelevantParameters(http_build_query($parameters)); if (count($relevantParameters) > 0) { $this->typoScriptFrontendController->reqCHash(); } } }
/** * @test */ public function buildBackendUriCreatesAbsoluteUrisIfSpecified() { \TYPO3\CMS\Core\Utility\GeneralUtility::_GETset(array('M' => 'moduleKey')); $this->mockRequest->expects($this->any())->method('getBaseUri')->will($this->returnValue('http://baseuri/' . TYPO3_mainDir)); $this->uriBuilder->setCreateAbsoluteUri(TRUE); $expectedResult = 'http://baseuri/' . TYPO3_mainDir . 'mod.php?M=moduleKey&moduleToken=dummyToken'; $actualResult = $this->uriBuilder->buildBackendUri(); $this->assertSame($expectedResult, $actualResult); }
/** * @test */ public function getPartialSourceReturnsContentOfDefaultPartialFileIfNoPartialExistsForTheSpecifiedFormat() { $partialRootPath = __DIR__ . '/Fixtures'; $this->view->setPartialRootPath($partialRootPath); $this->mockRequest->expects($this->once())->method('getFormat')->will($this->returnValue('foo')); $expectedResult = file_get_contents($partialRootPath . '/LayoutFixture'); $actualResult = $this->view->_call('getPartialSource', 'LayoutFixture'); $this->assertEquals($expectedResult, $actualResult); }
/** * Helper function for a mapping result with errors */ protected function stubRequestWithMappingErrors() { $this->request->getOriginalRequest()->willReturn(null); $this->request->getArguments()->willReturn([]); $result = $this->prophesize(Result::class); $result->forProperty('objectName')->willReturn($result->reveal()); $result->forProperty('someProperty')->willReturn($result->reveal()); $result->hasErrors()->willReturn(true); $this->request->getOriginalRequestMappingResults()->willReturn($result->reveal()); }
/** * @test */ public function buildSetsDefaultActionNameIfSpecifiedActionIsNotAllowedAndCallDefaultActionIfActionCantBeResolvedIsSet() { $this->configuration['mvc']['callDefaultActionIfActionCantBeResolved'] = 1; $this->injectDependencies(); $this->requestBuilder->_set('extensionService', $this->mockExtensionService); $_GET = array('tx_myextension_pi1' => array('controller' => 'TheThirdController', 'action' => 'someInvalidAction')); $this->mockRequest->expects($this->once())->method('setControllerName')->with('TheThirdController'); $this->mockRequest->expects($this->once())->method('setControllerActionName')->with('delete'); $this->requestBuilder->build(); }
/** * @test */ public function getLayoutPathAndFilenameWalksStringKeysInReversedOrder() { $this->view->setLayoutRootPaths(array('default' => 'some/Default/Directory', 'specific' => 'specific/Layout', 'verySpecific' => 'evenMore/Specific/Layout')); $this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html')); $this->view->expects($this->at(0))->method('testFileExistence')->with('evenMore/Specific/Layout/Default.html')->will($this->returnValue(FALSE)); $this->view->expects($this->at(1))->method('testFileExistence')->with('evenMore/Specific/Layout/Default')->will($this->returnValue(FALSE)); $this->view->expects($this->at(2))->method('testFileExistence')->with('specific/Layout/Default.html')->will($this->returnValue(FALSE)); $this->view->expects($this->at(3))->method('testFileExistence')->with('specific/Layout/Default')->will($this->returnValue(FALSE)); $this->view->expects($this->at(4))->method('testFileExistence')->with('some/Default/Directory/Default.html')->will($this->returnValue(FALSE)); $this->view->expects($this->at(5))->method('testFileExistence')->with('some/Default/Directory/Default')->will($this->returnValue(TRUE)); $this->assertEquals('some/Default/Directory/Default', $this->view->_call('getLayoutPathAndFilename')); }
/** * @test */ public function setTemplateWalksStringKeysInReversedOrder() { $this->view->setTemplateRootPaths(array('default' => 'some/Default/Directory', 'specific' => 'specific/Templates', 'verySpecific' => 'evenMore/Specific/Templates')); $this->mockRequest->expects($this->any())->method('getFormat')->will($this->returnValue('html')); $this->view->expects($this->at(0))->method('testFileExistence')->with(PATH_site . 'evenMore/Specific/Templates/Template.html')->will($this->returnValue(false)); $this->view->expects($this->at(1))->method('testFileExistence')->with(PATH_site . 'evenMore/Specific/Templates/Template')->will($this->returnValue(false)); $this->view->expects($this->at(2))->method('testFileExistence')->with(PATH_site . 'specific/Templates/Template.html')->will($this->returnValue(false)); $this->view->expects($this->at(3))->method('testFileExistence')->with(PATH_site . 'specific/Templates/Template')->will($this->returnValue(false)); $this->view->expects($this->at(4))->method('testFileExistence')->with(PATH_site . 'some/Default/Directory/Template.html')->will($this->returnValue(false)); $this->view->expects($this->at(5))->method('testFileExistence')->with(PATH_site . 'some/Default/Directory/Template')->will($this->returnValue(true)); $this->view->setTemplate('Template'); $this->assertEquals(PATH_site . 'some/Default/Directory/Template', $this->view->getTemplatePathAndFilename()); }
/** * @test */ public function buildTypolinkConfigurationResolvesPageTypeFromFormat() { $this->uriBuilder->setTargetPageUid(123); $this->uriBuilder->setFormat('txt'); $this->mockRequest->expects($this->once())->method('getControllerExtensionName')->will($this->returnValue('SomeExtensionNameFromRequest')); $mockConfigurationManager = $this->getMock(ConfigurationManager::class); $mockConfigurationManager->expects($this->any())->method('getConfiguration')->will($this->returnValue(array('view' => array('formatToPageTypeMapping' => array('txt' => 2))))); $this->uriBuilder->_set('configurationManager', $mockConfigurationManager); $this->mockExtensionService->expects($this->any())->method('getTargetPageTypeByFormat')->with('SomeExtensionNameFromRequest', 'txt')->will($this->returnValue(2)); $expectedConfiguration = array('parameter' => '123,2', 'useCacheHash' => 1); $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration'); $this->assertEquals($expectedConfiguration, $actualConfiguration); }
/** * Adds an additional header data (something like * '<script src="myext/Resources/JavaScript/my.js" type="text/javascript"></script>' * ) * * @TODO The workround and the $request member should be removed again, once the PageRender does support non-cached USER_INTs * @param string $additionalHeaderData The value additonal header * @throws \InvalidArgumentException * @return void * @api */ public function addAdditionalHeaderData($additionalHeaderData) { if (!is_string($additionalHeaderData)) { throw new \InvalidArgumentException('The additiona header data must be of type String, ' . gettype($additionalHeaderData) . ' given.', 1237370877); } if ($this->request->isCached()) { /** @var PageRenderer $pageRenderer */ $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); $pageRenderer->addHeaderData($additionalHeaderData); } else { $this->additionalHeaderData[] = $additionalHeaderData; } }
/** * Adds an additional header data (something like * '<script src="myext/Resources/JavaScript/my.js" type="text/javascript"></script>' * ) * * @TODO The workround and the $request member should be removed again, once the PageRender does support non-cached USER_INTs * @param string $additionalHeaderData The value additonal header * @throws \InvalidArgumentException * @return void * @api */ public function addAdditionalHeaderData($additionalHeaderData) { if (!is_string($additionalHeaderData)) { throw new \InvalidArgumentException('The additiona header data must be of type String, ' . gettype($additionalHeaderData) . ' given.', 1237370877); } if ($this->request->isCached()) { if ($this->environmentService->isEnvironmentInFrontendMode()) { $pageRenderer = $GLOBALS['TSFE']->getPageRenderer(); } elseif ($this->environmentService->isEnvironmentInBackendMode()) { $pageRenderer = $GLOBALS['TBE_TEMPLATE']->getPageRenderer(); } $pageRenderer->addHeaderData($additionalHeaderData); } else { $this->additionalHeaderData[] = $additionalHeaderData; } }
/** * Adds an additional header data (something like * '<script src="myext/Resources/JavaScript/my.js" type="text/javascript"></script>' * ) * * @TODO The workround and the $request member should be removed again, once the PageRender does support non-cached USER_INTs * @param string $additionalHeaderData The value additonal header * @throws \InvalidArgumentException * @return void * @api */ public function addAdditionalHeaderData($additionalHeaderData) { if (!is_string($additionalHeaderData)) { throw new \InvalidArgumentException('The additiona header data must be of type String, ' . gettype($additionalHeaderData) . ' given.', 1237370877); } if ($this->request->isCached()) { /** @var PageRenderer $pageRenderer */ $pageRenderer = NULL; if ($this->environmentService->isEnvironmentInFrontendMode()) { $pageRenderer = $this->getTypoScriptFrontendController()->getPageRenderer(); } elseif ($this->environmentService->isEnvironmentInBackendMode()) { $pageRenderer = $this->getDocumentTemplate()->getPageRenderer(); } if ($pageRenderer !== NULL) { $pageRenderer->addHeaderData($additionalHeaderData); } } else { $this->additionalHeaderData[] = $additionalHeaderData; } }
/** * @dataProvider getIdentifierTestValues * @param string|NULL $identifierArgument * @param string $expectedIdentifier */ public function testGetIdentifier($identifierArgument, $expectedIdentifier) { $instance = $this->createInstance(); $instance->setArguments(array('identifier' => $identifierArgument)); $renderingContext = new RenderingContext(); $controllerContext = new ControllerContext(); $request = new Request(); $request->setControllerActionName('p1'); $request->setControllerName('p2'); $request->setPluginName('p3'); $request->setControllerExtensionName('p4'); $controllerContext->setRequest($request); $renderingContext->setControllerContext($controllerContext); $instance->setRenderingContext($renderingContext); $result = $this->callInaccessibleMethod($instance, 'getIdentifier'); $this->assertEquals($expectedIdentifier, $result); }
/** * Builds a TypoLink configuration array from the current settings * * @return array typolink configuration array * @see TSref/typolink */ protected function buildTypolinkConfiguration() { $typolinkConfiguration = array(); $typolinkConfiguration['parameter'] = $this->targetPageUid !== NULL ? $this->targetPageUid : $GLOBALS['TSFE']->id; if ($this->targetPageType !== 0) { $typolinkConfiguration['parameter'] .= ',' . $this->targetPageType; } elseif ($this->format !== '') { $targetPageType = $this->extensionService->getTargetPageTypeByFormat($this->request->getControllerExtensionName(), $this->format); $typolinkConfiguration['parameter'] .= ',' . $targetPageType; } if (count($this->arguments) > 0) { $arguments = $this->convertDomainObjectsToIdentityArrays($this->arguments); $this->lastArguments = $arguments; $typolinkConfiguration['additionalParams'] = \TYPO3\CMS\Core\Utility\GeneralUtility::implodeArrayForUrl(NULL, $arguments); } if ($this->addQueryString === TRUE) { $typolinkConfiguration['addQueryString'] = 1; if (count($this->argumentsToBeExcludedFromQueryString) > 0) { $typolinkConfiguration['addQueryString.'] = array('exclude' => implode(',', $this->argumentsToBeExcludedFromQueryString)); } if ($this->addQueryStringMethod) { $typolinkConfiguration['addQueryString.']['method'] = $this->addQueryStringMethod; } } if ($this->noCache === TRUE) { $typolinkConfiguration['no_cache'] = 1; } elseif ($this->useCacheHash) { $typolinkConfiguration['useCacheHash'] = 1; } if ($this->section !== '') { $typolinkConfiguration['section'] = $this->section; } if ($this->linkAccessRestrictedPages === TRUE) { $typolinkConfiguration['linkAccessRestrictedPages'] = 1; } return $typolinkConfiguration; }
/** * @test */ public function initiateSubRequestBuildsRequestProperly() { $controller = $this->getMock(\TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetController::class, array(), array(), '', FALSE); $this->viewHelper->_set('controller', $controller); // Initial Setup $widgetRequest = $this->getMock(\TYPO3\CMS\Fluid\Core\Widget\WidgetRequest::class); $response = $this->getMock(\TYPO3\CMS\Extbase\Mvc\Web\Response::class); $this->objectManager->expects($this->at(0))->method('get')->with(\TYPO3\CMS\Fluid\Core\Widget\WidgetRequest::class)->will($this->returnValue($widgetRequest)); $this->objectManager->expects($this->at(1))->method('get')->with(\TYPO3\CMS\Extbase\Mvc\Web\Response::class)->will($this->returnValue($response)); // Widget Context is set $widgetRequest->expects($this->once())->method('setWidgetContext')->with($this->widgetContext); // The namespaced arguments are passed to the sub-request // and the action name is exctracted from the namespace. $this->controllerContext->expects($this->once())->method('getRequest')->will($this->returnValue($this->request)); $this->widgetContext->expects($this->once())->method('getWidgetIdentifier')->will($this->returnValue('widget-1')); $this->request->expects($this->once())->method('getArguments')->will($this->returnValue(array('k1' => 'k2', 'widget-1' => array('arg1' => 'val1', 'arg2' => 'val2', 'action' => 'myAction')))); $widgetRequest->expects($this->once())->method('setArguments')->with(array('arg1' => 'val1', 'arg2' => 'val2')); $widgetRequest->expects($this->once())->method('setControllerActionName')->with('myAction'); // Controller is called $controller->expects($this->once())->method('processRequest')->with($widgetRequest, $response); $output = $this->viewHelper->_call('initiateSubRequest'); // SubResponse is returned $this->assertSame($response, $output); }
/** * Verify the request. Checks if there is an __hmac argument, and if yes, tries to validate and verify it. * * In the end, $request->setHmacVerified is set depending on the value. * * @param \TYPO3\CMS\Extbase\Mvc\Web\Request $request The request to verify * @throws \TYPO3\CMS\Extbase\Security\Exception\SyntacticallyWrongRequestHashException * @return void */ public function verifyRequest(\TYPO3\CMS\Extbase\Mvc\Web\Request $request) { if (!$request->getInternalArgument('__hmac')) { $request->setHmacVerified(FALSE); return; } $hmac = $request->getInternalArgument('__hmac'); if (strlen($hmac) < 40) { throw new \TYPO3\CMS\Extbase\Security\Exception\SyntacticallyWrongRequestHashException('Request hash too short. This is a probably manipulation attempt!', 1255089361); } $serializedFieldNames = substr($hmac, 0, -40); // TODO: Constant for hash length needs to be introduced $hash = substr($hmac, -40); if ($this->hashService->validateHmac($serializedFieldNames, $hash)) { $requestArguments = $request->getArguments(); // Unset framework arguments unset($requestArguments['__referrer']); unset($requestArguments['__hmac']); if ($this->checkFieldNameInclusion($requestArguments, unserialize($serializedFieldNames))) { $request->setHmacVerified(TRUE); } else { $request->setHmacVerified(FALSE); } } else { $request->setHmacVerified(FALSE); } }
/** * @param Page $page * @return Result * @throws PropertyMappingException */ protected function mapAndValidatePage(Page $page) : Result { $result = $this->objectManager->get(Result::class); $requestArguments = $this->request->getArguments(); $propertyPathsForWhichPropertyMappingShouldHappen = []; $registerPropertyPaths = function ($propertyPath) use(&$propertyPathsForWhichPropertyMappingShouldHappen) { $propertyPathParts = explode('.', $propertyPath); $accumulatedPropertyPathParts = []; foreach ($propertyPathParts as $propertyPathPart) { $accumulatedPropertyPathParts[] = $propertyPathPart; $temporaryPropertyPath = implode('.', $accumulatedPropertyPathParts); $propertyPathsForWhichPropertyMappingShouldHappen[$temporaryPropertyPath] = $temporaryPropertyPath; } }; foreach ($page->getElementsRecursively() as $element) { $value = ArrayUtility::getValueByPath($requestArguments, $element->getIdentifier()); $element->onSubmit($this, $value, $requestArguments); $this->formState->setFormValue($element->getIdentifier(), $value); $registerPropertyPaths($element->getIdentifier()); } // The more parts the path has, the more early it is processed usort($propertyPathsForWhichPropertyMappingShouldHappen, function ($a, $b) { return substr_count($b, '.') - substr_count($a, '.'); }); $processingRules = $this->formDefinition->getProcessingRules(); foreach ($propertyPathsForWhichPropertyMappingShouldHappen as $propertyPath) { if (isset($processingRules[$propertyPath])) { $processingRule = $processingRules[$propertyPath]; $value = $this->formState->getFormValue($propertyPath); try { $value = $processingRule->process($value); } catch (PropertyException $exception) { throw new PropertyMappingException('Failed to process FormValue at "' . $propertyPath . '" from "' . gettype($value) . '" to "' . $processingRule->getDataType() . '"', 1480024933, $exception); } $result->forProperty($propertyPath)->merge($processingRule->getProcessingMessages()); $this->formState->setFormValue($propertyPath, $value); } } return $result; }
/** * Resolve view and initialize the general view-variables extensionName, * controllerName and actionName based on the request object * * @return \TYPO3\CMS\Fluid\View\TemplateView */ protected function resolveView() { $view = parent::resolveView(); $view->assignMultiple(['extensionName' => $this->request->getControllerExtensionName(), 'controllerName' => $this->request->getControllerName(), 'actionName' => $this->request->getControllerActionName()]); return $view; }
/** * @test */ public function setFormatSetsRequestFormat() { $this->mockRequest->expects($this->once())->method('setFormat')->with('xml'); $this->view->setFormat('xml'); }