TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Extbase\Mvc;
|
||||
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessage;
|
||||
use TYPO3\CMS\Core\Utility\ClassNamingUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Error\Result;
|
||||
use TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentNameException;
|
||||
use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException;
|
||||
|
||||
/**
|
||||
* Extbase request related state.
|
||||
* Attached as 'extbase' attribute to PSR-7 ServerRequestInterface.
|
||||
*
|
||||
* @internal Sets up extbase internally, use TYPO3\CMS\Extbase\Mvc\Request instead.
|
||||
*/
|
||||
class ExtbaseRequestParameters
|
||||
{
|
||||
/**
|
||||
* Key of the plugin which identifies the plugin.
|
||||
* In frontend, it is the second argument of ExtensionUtility::configurePlugin(), example: "FormFramework" in ext:form.
|
||||
* In backend, it is the module identifier from the corresponding module configuration, for example
|
||||
* "web_FormFormbuilder" for the ext:form backend module.
|
||||
*/
|
||||
protected string $pluginName = '';
|
||||
|
||||
/**
|
||||
* Name of the extension which is supposed to handle this request. This is the extension key in UpperCamelCase.
|
||||
* This is typically defined by ExtensionUtility::configurePlugin() and friends as first argument.
|
||||
* Example: "IndexedSearch", when the extension key "directory name of extension" is indexed_search.
|
||||
*/
|
||||
protected string $controllerExtensionName = '';
|
||||
|
||||
/**
|
||||
* This is the FQDN of a controller, example: "TYPO3\CMS\Form\Controller\FormManagerController"
|
||||
* for ext:form backend module.
|
||||
*/
|
||||
protected string $controllerObjectName = '';
|
||||
|
||||
/**
|
||||
* Object name of the controller which is supposed to handle this request. This is the non-FQDN
|
||||
* version of $controllerObjectName, without the word "Controller", example: "FormManager".
|
||||
*/
|
||||
protected string $controllerName = 'Standard';
|
||||
|
||||
/**
|
||||
* A map $controllerName => $controllerObjectName
|
||||
*/
|
||||
protected array $controllerAliasToClassNameMapping = [];
|
||||
|
||||
/**
|
||||
* Name of the action the controller is supposed to execute. For example "create" with the
|
||||
* controller method name being "createAction()".
|
||||
* Action name must start with a lower case letter and is case-sensitive.
|
||||
*/
|
||||
protected string $controllerActionName = 'index';
|
||||
|
||||
/**
|
||||
* The arguments for this request. This receives only those arguments relevant and
|
||||
* prefixed for this extension/controller/plugin combination.
|
||||
*/
|
||||
protected array $arguments = [];
|
||||
|
||||
/**
|
||||
* Framework-internal arguments for this request, such as __referrer.
|
||||
* All framework-internal arguments start with double underscore (__),
|
||||
* and are only used from within the framework. Not for user consumption.
|
||||
* Internal Arguments can be objects, in contrast to public arguments
|
||||
*/
|
||||
protected array $internalArguments = [];
|
||||
|
||||
/**
|
||||
* The requested representation format, "html", "xml", "png", "json" or the like.
|
||||
* Can even be something like "rss.xml".
|
||||
*/
|
||||
protected string $format = 'html';
|
||||
|
||||
/**
|
||||
* If this request is a forward because of an error, the original request gets filled.
|
||||
*/
|
||||
protected ?RequestInterface $originalRequest = null;
|
||||
|
||||
/**
|
||||
* If the request is a forward because of an error, these mapping results get filled here.
|
||||
*/
|
||||
protected ?Result $originalRequestMappingResults = null;
|
||||
|
||||
/**
|
||||
* @var list<FlashMessage>
|
||||
*/
|
||||
protected array $originalFlashMessages = [];
|
||||
|
||||
/**
|
||||
* If files were uploaded, this array holds the files
|
||||
* prefixed for this extension/controller/plugin combination.
|
||||
*/
|
||||
protected array $uploadedFiles = [];
|
||||
|
||||
public function __construct(string $controllerClassName = '')
|
||||
{
|
||||
$this->controllerObjectName = $controllerClassName;
|
||||
}
|
||||
|
||||
public function getControllerObjectName(): string
|
||||
{
|
||||
return $this->controllerObjectName;
|
||||
}
|
||||
|
||||
public function setControllerObjectName(string $controllerObjectName): self
|
||||
{
|
||||
$nameParts = ClassNamingUtility::explodeObjectControllerName($controllerObjectName);
|
||||
$this->controllerExtensionName = $nameParts['extensionName'];
|
||||
$this->controllerName = $nameParts['controllerName'];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPluginName(string $pluginName): self
|
||||
{
|
||||
$this->pluginName = $pluginName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPluginName(): string
|
||||
{
|
||||
return $this->pluginName;
|
||||
}
|
||||
|
||||
public function setControllerExtensionName(string $controllerExtensionName): self
|
||||
{
|
||||
$this->controllerExtensionName = $controllerExtensionName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getControllerExtensionName(): string
|
||||
{
|
||||
return $this->controllerExtensionName;
|
||||
}
|
||||
|
||||
public function getControllerExtensionKey(): string
|
||||
{
|
||||
return GeneralUtility::camelCaseToLowerCaseUnderscored($this->controllerExtensionName);
|
||||
}
|
||||
|
||||
public function setControllerAliasToClassNameMapping(array $controllerAliasToClassNameMapping): self
|
||||
{
|
||||
// this is only needed as long as forwarded requests are altered and unless there
|
||||
// is no new request object created by the request builder.
|
||||
$this->controllerAliasToClassNameMapping = $controllerAliasToClassNameMapping;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setControllerName(string $controllerName): self
|
||||
{
|
||||
$this->controllerName = $controllerName;
|
||||
// There might be no Controller Class, for example for Fluid Templates.
|
||||
$this->controllerObjectName = $this->controllerAliasToClassNameMapping[$controllerName] ?? '';
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getControllerName(): string
|
||||
{
|
||||
return $this->controllerName;
|
||||
}
|
||||
|
||||
public function setControllerActionName(string $actionName): self
|
||||
{
|
||||
$this->controllerActionName = $actionName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getControllerActionName(): string
|
||||
{
|
||||
return $this->controllerActionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value The new value
|
||||
* @throws InvalidArgumentNameException
|
||||
*/
|
||||
public function setArgument(string $argumentName, mixed $value): self
|
||||
{
|
||||
if ($argumentName === '') {
|
||||
throw new InvalidArgumentNameException('Invalid argument name.', 1210858767);
|
||||
}
|
||||
if (str_starts_with($argumentName, '__')) {
|
||||
$this->internalArguments[$argumentName] = $value;
|
||||
return $this;
|
||||
}
|
||||
if (!in_array($argumentName, ['@extension', '@subpackage', '@controller', '@action', '@format'], true)) {
|
||||
$this->arguments[$argumentName] = $value;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the whole arguments array and therefore replaces any arguments which existed before.
|
||||
*
|
||||
* @param array<string, mixed> $arguments
|
||||
* @throws InvalidArgumentNameException
|
||||
*/
|
||||
public function setArguments(array $arguments): self
|
||||
{
|
||||
$this->arguments = [];
|
||||
foreach ($arguments as $argumentName => $argumentValue) {
|
||||
$this->setArgument($argumentName, $argumentValue);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getArguments(): array
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified argument.
|
||||
*
|
||||
* @return mixed Value of the argument
|
||||
* @throws NoSuchArgumentException if such an argument does not exist
|
||||
*/
|
||||
public function getArgument(string $argumentName): mixed
|
||||
{
|
||||
if (!isset($this->arguments[$argumentName])) {
|
||||
throw new NoSuchArgumentException('An argument "' . $argumentName . '" does not exist for this request.', 1176558158);
|
||||
}
|
||||
return $this->arguments[$argumentName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an argument of the given name exists (is set)
|
||||
*/
|
||||
public function hasArgument(string $argumentName = ''): bool
|
||||
{
|
||||
return isset($this->arguments[$argumentName]);
|
||||
}
|
||||
|
||||
public function setFormat(string $format): self
|
||||
{
|
||||
$this->format = $format;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFormat(): string
|
||||
{
|
||||
return $this->format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the original request. Filled only if a property mapping error occurred.
|
||||
*/
|
||||
public function getOriginalRequest(): ?RequestInterface
|
||||
{
|
||||
return $this->originalRequest;
|
||||
}
|
||||
|
||||
public function setOriginalRequest(RequestInterface $originalRequest): self
|
||||
{
|
||||
$this->originalRequest = $originalRequest;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOriginalRequestMappingResults(): Result
|
||||
{
|
||||
if ($this->originalRequestMappingResults === null) {
|
||||
return new Result();
|
||||
}
|
||||
return $this->originalRequestMappingResults;
|
||||
}
|
||||
|
||||
public function setOriginalRequestMappingResults(Result $originalRequestMappingResults): self
|
||||
{
|
||||
$this->originalRequestMappingResults = $originalRequestMappingResults;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<FlashMessage>
|
||||
*/
|
||||
public function getOriginalFlashMessages(): array
|
||||
{
|
||||
return $this->originalFlashMessages;
|
||||
}
|
||||
|
||||
public function setOriginalFlashMessages(FlashMessage ...$originalFlashMessages): self
|
||||
{
|
||||
$this->originalFlashMessages = $originalFlashMessages;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified argument
|
||||
*
|
||||
* @return mixed Value of the argument, or NULL if not set.
|
||||
*/
|
||||
public function getInternalArgument($argumentName): mixed
|
||||
{
|
||||
if (!isset($this->internalArguments[$argumentName])) {
|
||||
return null;
|
||||
}
|
||||
return $this->internalArguments[$argumentName];
|
||||
}
|
||||
|
||||
public function getUploadedFiles(): array
|
||||
{
|
||||
return $this->uploadedFiles;
|
||||
}
|
||||
|
||||
public function setUploadedFiles(array $files): self
|
||||
{
|
||||
$this->validateUploadedFiles($files);
|
||||
$this->uploadedFiles = $files;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively validate the structure in an uploaded files array.
|
||||
*
|
||||
* @throws \InvalidArgumentException if any leaf is not an UploadedFileInterface instance.
|
||||
*/
|
||||
protected function validateUploadedFiles(array $uploadedFiles): void
|
||||
{
|
||||
foreach ($uploadedFiles as $file) {
|
||||
if (is_array($file)) {
|
||||
$this->validateUploadedFiles($file);
|
||||
continue;
|
||||
}
|
||||
if (!$file instanceof UploadedFileInterface) {
|
||||
throw new \InvalidArgumentException('Invalid file in uploaded files structure.', 1647338470);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user