In one of our projects, we have 2 use cases that could be mapped with an extension, except for one small detail. This detail is an e-mail address, which is a mandatory field in one use case and does not have to be entered in the other.
Extbase is very consistent thanks to the MVC principle. So if it is determined in a model that the e-mail address is not a mandatory field, then you cannot simply say at runtime that the e-mail address suddenly becomes a mandatory field.
Let's take a look at the source code to see why this is not possible:
It fails because of the createAction(). This is because it specifies that all form entries are to be transferred to the model Tx_ExtName_Domain_Model_Topic. However, we are here within the parameter list of a method call and therefore have no option at all, e.g. to select a different model with a different validation, as PHP methods such as if and switch are not permitted here.
The option of subsequently checking the e-mail address within the createAction also fails, as Fluid can no longer find out whether this property has caused an error or not. This means that the CSS error class "f3-form-error" can no longer be added to the e-mail field in the event of an error. The website visitor therefore no longer receives any visual feedback.
With the help of an additional initializeCreateAction method, however, it is possible to intervene BEFORE the actual call of the createAction method. But there are problems here too. Although the ConjunctionValidator is basically intended to include several validators, even after several hours it has not been possible to add a validator with addValidator that also works. Extbase and Fluid apparently expect a predefined structure/nesting of the validators.
/**
* add new validator to topic
*
* @return void
*/
public function initializeCreateAction() {
if ($this->arguments->hasArgument('newTopic')) {
if ($this->settings['emailIsMandatory']) {
/** @var Tx_Extbase_Validation_ValidatorResolver $validatorResolver */
$validatorResolver = $this->objectManager->get('Tx_Extbase_Validation_ValidatorResolver');
$topicValidator = $validatorResolver->getBaseValidatorConjunction('Tx_ExtName_Domain_Model_Wme_Topic');
/** @var Tx_Extbase_Validation_Validator_ConjunctionValidator $conjunctionValidator */
$conjunctionValidator = $this->arguments->getArgument('newTopic')->getValidator();
/* remove default validator */
foreach ($conjunctionValidator->getValidators() as $validator) {
$conjunctionValidator->removeValidator($validator);
}
/* add our own validator with mandatory email to topic */
$conjunctionValidator->addValidator($topicValidator);
}
}
}
The initializeCreateAction method now checks whether the subsequent method (createAction) contains the $newTopic argument and whether the email address has been set as a mandatory field via TypoScript.
If this is the case, we get the ValidatorResolver object. Using the contained getBaseValidatorConjunction method, we can now create a new validator for the domain model in which the email address is now a mandatory field (WME = With Mandatory Email).
We now retrieve the validators created by Extbase, delete all of them and add our self-created validator to the argument for the createAction again.
Author: Stefan Frömken