Project

General

Profile

Actions

Feature #104763

open

Allow Models used in Request Validation to be XClass overridden

Added by Jannis Bell 3 months ago. Updated 3 months ago.

Status:
Needs Feedback
Priority:
Should have
Assignee:
-
Category:
Extbase
Target version:
-
Start date:
2024-08-28
Due date:
% Done:

0%

Estimated time:
PHP Version:
Tags:
Complexity:
medium
Sprint Focus:

Description

My Company uses a self-developed extension for some forms.
We use the Request Argument Objects extensively.
And we have to overwrite and adapt the forms constantly for our customers.
Specifically the Validators are impossible to change:

class BaseInquiry {
    /** @TYPO3\CMS\Extbase\Annotation\Validate("NotEmpty") */
    protected string $inquiry = '';
    protected string $message = '';
}

class OverriderInquiry extends BaseInquiry {
    protected string $inquiry = '';
    /** @TYPO3\CMS\Extbase\Annotation\Validate("NotEmpty") */
    protected string $message = '';
}

class InquiryController extends ActionController {
    public function processAction(BaseInquiry $inquiry = NULL): ResponseInterface
    // a OverriderInquiry arrives here
    // but is validated for a BaseInquiry

//localconf
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][BaseInquiry::class] = ['className' => OverriderInquiry::class];

Expected: Validates $message for NotEmpty and does not validate $inquiry
Reality: Validates $inquiry for NotEmpty and does not validate $message

This would be my patch to fix this:
https://github.com/TYPO3/typo3/blob/main/typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php#L238

    protected function initializeActionMethodArguments(): void
    {
        $methodParameters = $this->reflectionService
            ->getClassSchema(static::class)
            ->getMethod($this->actionMethodName)->getParameters();

        foreach ($methodParameters as $parameterName => $parameter) {
            $dataType = null;
            if ($parameter->getType() !== null) {
                $dataType = $parameter->getType();
                /** This is the new part:*/
                // this can overwrite the Datatype aka Classname to match the given XClass counterpart
                if (array_key_exists($dataType, $GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'])) {
                    $dataType = $GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][$dataType]['className'];
                }
                /** end of the new part */
            } elseif ($parameter->isArray()) {
                $dataType = 'array';
            }
            if ($dataType === null) {
                throw new InvalidArgumentTypeException('The argument type for parameter $' . $parameterName . ' of method ' . static::class . '->' . $this->actionMethodName . '() could not be detected.', 1253175643);
            }
            $defaultValue = $parameter->hasDefaultValue() ? $parameter->getDefaultValue() : null;
            $this->arguments->addNewArgument($parameterName, $dataType, !$parameter->isOptional(), $defaultValue);
        }
    }

I am not sure about the code standards in the core:
Im not sure if you rather use isset() than array_key_exists()
Or if the XClass has no 'classname', if the core should crash or warn or cover this

Also im sry if this is very gibberish and poorly explained

Actions

Also available in: Atom PDF