Moongazer
Moongazer

Reputation: 455

Sanitize user-input for Extbase model before custom validator validates the input

I'm struggling to figure out a way to sanitize user-input for an Extbase model. There seems to be no resources at all in the internet and I'm wondering about if I'm looking for a wrong thing here...

Lets look at an example: a user fills out a registration form with a required field for "phone number". Basically I could use the property annotation @Extbase\Validate("NotEmpty") for $telephone, but for other reasons I use a custom UserValidator (which should not matter here).

I was hoping that the User object passed to the validator is writable, but it seems to be a cloned object. That's why setting a "cleaned" phone-number inside the validator does not work (sure, this would be bad-practice anyway, but it was a try):

class UserValidator extends AbstractValidator
{
    /**
     * @param User $value
     */
    protected function isValid($value): void
    {
        $this->validateTelephone($value);
    }

    protected function validateTelephone(User $user): void
    {
        // sanitize the "telephone" value
        $validTelephone = filter_var($user->getTelephone(), FILTER_SANITIZE_NUMBER_INT);
        $user->setTelephone($validTelephone); // <== does not work, is $user a clone? (in Fluid the original value is still shown e.g. "+1-123-xx2 foo211", but "+1-123-2211" exected)

        if (empty($validTelephone)) {
            $this->result->forProperty('telephone')->addError(
                new Error('Invalid phone number', 1705061262334)
            );
        }
    }
}

Next try was to use Extbase initializeAction() to modify the value before mapping, but there seems to be no methods for it:

    public function initializeRegisterCompleteAction()
    {
        // sanitize the "telephone" value
        $this->arguments->getArgument('user')->getPropertyMappingConfiguration()
            ->forProperty('telephone')->...
        // how to get(), filter() and set() the value for the property?
    }

By the way: yes I could use RegExp inside the validator. BUT there is a requirement to make the registration as painless as possible. And many user will be annoyed by strict format requirements/errors, as they dont know e.g. about international format etc... So everything what passes filter_var($user->getTelephone(), FILTER_SANITIZE_NUMBER_INT); should be accepted as phone number.

Community question: how do you sanitize model field values in Extbase context? Thanks ahead for you ideas.

Upvotes: 0

Views: 135

Answers (2)

derhansen
derhansen

Reputation: 6133

If you want to change the user input on submission and before it is processed by the Extbase action, you should use the initialize<YourAction>Action method as shown below (TYPO3 v12):

public function initializeRegisterCompleteAction()
{
    $arguments = $this->request->getArguments();

    $telephone = $arguments['telephone'];
    $validTelephone = filter_var(telephone, FILTER_SANITIZE_NUMBER_INT);
    if (validTelephone) {
        $arguments['telephone'] = validTelephone;
    }

    $this->request = $this->request->withArguments($arguments);
}

You can then use action validators to validate the (then sanitized) telephone number.

Upvotes: 1

Milenov
Milenov

Reputation: 1

You could do it in your template, thus providing your model directly with "clean" values. https://docs.typo3.org/other/typo3/view-helper-reference/11.5/en-us/typo3/fluid/latest/Sanitize/Html.html

You could also add an validation via TCA Overrides: tx_your_extension_domain_model.php

'propertyname' => [
        'exclude' => true,
        'label' => 'LLL:EXT:your_extension/Resources/Private/Language/locallang_db.xlf:tx_your_extension_domain_model_field.propertyname',
        'config' => [
            'type' => 'input',
            'size' => 30,
            'eval' => 'trim,uniqueInSite',
            'default' => ''
        ],

'eval' are some validators you can use. See the documentation for exact specs.

Upvotes: -2

Related Questions