# Add new Validators ## Introduction In powermail a combination of different validation types is possible: - Serverside Validation (PHP) - Clientside Validation (JavaScript) - Clientside Validation (Native with HTML5) You can enable or disable or combine some validation methods via TypoScript ``` plugin.tx_powermail.settings.setup { validation { native = 1 client = 1 server = 1 } } ``` Meanwhile, we added an own robust JavaScript validation which also supports native HTML5 validation ![developer_new_validation2](../Images/developer_new_validation2.png) Serverside Validation Example ![developer_new_validation1](../Images/developer_new_validation1.png) Clientside Validation Example ## 1. Add a new validation type A new validation type is a validation that can be selected for a single field by the editor. The following example includes clientside and serverside validation. ### Add new Option Per default, all standard validators are available for a field ![developer_new_validationtype1](../Images/developer_new_validationtype1.png) If you want to add a new validation, use Page TSConfig for this. In this case, we want to validate for a ZIP-Code which is greater than 79999 (for bavarian ZIP within Germany): `tx_powermail.flexForm.validation.addFieldOptions.100 = Bavarian ZIP Code` This leads to a new validation option for the editors: ![developer_new_validationtype2](../Images/developer_new_validationtype2.png) ### Add new JavaScript Validation You will see an HTML-Code like this for this field `` Add a new Extension or simply a JavaScript File with this content. Please pay attention to the ordering. This code must be included after all JavaScripts of powermail. ``` page.includeJSFooter.powermailextended = EXT:powermailextended/Resources/Public/JavaScripts/ZipValidation.js page.includeJSFooter.powermailextended.defer = 1 ``` ``` /** * Add a ZIP validation to all powermail forms on the current page and listen to those fields: * */ const forms = document.querySelectorAll('.powermail_form'); forms.forEach(function(form) { let formValidation = form.powermailFormValidation; formValidation.addValidator('custom100', function(field) { if (field.hasAttribute('data-powermail-custom100')) { // return true means validation has failed return field.value < parseInt(field.getAttribute('data-powermail-custom100')); } return false; }); }); ``` See Extension powermailextended https://github.com/einpraegsam/powermailextended for details ### Add new PHP Validation First of all, you have to register a PHP Class for your new validation via TypoScript (and an errormessage in case of a negative validation). ``` plugin.tx_powermail { settings.setup { validation { customValidation { 100 = In2code\Powermailextended\Domain\Validator\ZipValidator } } } _LOCAL_LANG.default.validationerror_validation.100 = Please add a ZIP with 8 begginning } ``` In this case we choose a further Extension "powermailextended" and add a new file and folders powermailextended/Classes/Domain/Validator/ZipValidator.php The content: ``` = $validationConfiguration) { return true; } return false; } } ``` ### Example Code Look at https://github.com/einpraegsam/powermailextended for an example extension. This extension allows you to: - Extend powermail with a complete new field type (Just a small "Show Text" example) - Extend powermail with an own Php and JavaScript validator (ZIP validator - number has to start with 8) - Extend powermail with new field properties (readonly and prepend text from Textarea) - Extend powermail with an example SignalSlot (see ext_localconf.php and EXT:powermailextended/Classes/Controller/FormController.php) ## 2. Add own global serverside validators A global validator is something that could normally not be selected by an editor. ### 2a. Use a validator class #### Introduction Let's say you want to easily add your own php function to validate user inputs, that should be called after a user submits a form, but of course before the createAction() is called. #### Small example Just define which classes should be used. Method validate() will be called: ``` plugin.tx_powermail.settings.setup { validators { 1 { class = Vendor\Ext\Domain\Model\DoSomethingValidator } } } ``` Add a php-file and extend your class with the AbstractValidator from powermail: ``` addError(new Error('Error', 123456789, ['marker'=> 'firstname'])); return $result; } } ``` #### Extended example See the advanced example with some configuration in TypoScript and with the possibility to load the file (useful if file could not be loaded from autoloader because it's stored in fileadmin or elsewhere) ``` plugin.tx_powermail.settings.setup { validators { 1 { # Classname that should be called with method *Validator() class = Vendor\Ext\Domain\Model\AlexValidator # optional: Add configuration for your PHP config { allowedValues = alex, alexander form = 210 } # optional: If file will not be loaded from autoloader, add path and it will be called with require_once require = fileadmin/powermail/validator/AlexValidator.php } } } ``` Add your php-file again and extend your class with the AbstractValidator from powermail: ``` configuration['form'] === $mail->getForm()->getUid()) { foreach ($mail->getAnswers() as $answer) { if ($answer->getField()->getMarker() === $this->fieldMarker && !$this->isAllowedValue($answer->getValue())) { $result->addError(new Error('Firstname must be "Alexander"', 123456789, ['marker' => $this->fieldMarker])); } } } return $result; } /** * Check if this value is allowed * * @return bool */ protected function isAllowedValue(string $value): bool { $allowedValues = GeneralUtility::trimExplode(',', $this->configuration['allowedValues'], true); return in_array(strtolower($value), $allowedValues); } } ``` ![developer_new_validation2](../Images/developer_new_validationtype1.png) ### 2b. Use an event with CustomValidator #### Introduction You can also use the CustomValidator (used twice in powermail FormsController: confirmationAction and createAction) to write your own field validation after a form submit. The customValidator is located at powermail/Classes/Domain/Validator/CustomValidator.php. An eventdispatcher within the class waits for your extension. #### Call the Custom Validator from your Extension Add a new extension (example key powermail_extend). Register a new listener in Configuration/Services.yaml: ``` services: Vendor\PowermailExtend\EventListeners\CustomValidator: tags: - name: event.listener identifier: 'customValidator' event: In2code\Powermail\Events\CustomValidatorEvent ``` Example file: ``` class Vendor\PowermailExtend\EventListeners\CustomValidator { public function __invoke(\In2code\Powermail\Events\CustomValidatorEvent $event): void { // $field failed - set error $event->getCustomValidator()->setErrorAndMessage($field, 'error message');; } } ``` ### Example Code Look at https://github.com/einpraegsam/powermailextended for an example extension. This extension allows you to: - Extend powermail with a complete new field type (Just a small "Show Text" example) - Extend powermail with an own Php and JavaScript validator (ZIP validator - number has to start with 8) - Extend powermail with new field properties (readonly and prepend text from Textarea) - Extend powermail with an example SignalSlot (see ext_localconf.php and EXT:powermailextended/Classes/Controller/FormController.php) ## 3. Add own global clientside validators A global validator is something that could normally not be selected by an editor. ### Javascript validation introduction Example form, validated with form validation framework, with a required and an email field. In addition to HTML5, this input fields are validated now: ```
``` ### Own JavaScript validator #### Quick example See how you can relate a JavaScript validator to a field with a data-attribute. In addition we recommend to set the message also via data-attribute: ``` [...] ``` #### Step by step Let's build an own field (look at the section how to easily extend powermail with own fieldtypes) with two fields where the user should add his/her email address twice. A validator should check if both strings are identical. The example fluid template (partial): ``` {namespace vh=In2code\Powermail\ViewHelpers}
``` The example JavaScript: ``` ``` ### Example Code Look at https://github.com/einpraegsam/powermailextended for an example extension. This extension allows you to: - Extend powermail with a complete new field type (Just a small "Show Text" example) - Extend powermail with an own Php and JavaScript validator (ZIP validator - number has to start with 8) - Extend powermail with new field properties (readonly and prepend text from Textarea) - Extend powermail with an example SignalSlot (see ext_localconf.php and EXT:powermailextended/Classes/Controller/FormController.php)