Completed
Push — unit-tests-validation ( c31383...82d287 )
by Romain
17:06
created

AbstractFormValidator::isValid()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.3142
c 0
b 0
f 0
cc 2
eloc 10
nc 2
nop 1
1
<?php
2
/*
3
 * 2017 Romain CANON <[email protected]>
4
 *
5
 * This file is part of the TYPO3 Formz project.
6
 * It is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License, either
8
 * version 3 of the License, or any later version.
9
 *
10
 * For the full copyright and license information, see:
11
 * http://www.gnu.org/licenses/gpl-3.0.html
12
 */
13
14
namespace Romm\Formz\Validation\Validator\Form;
15
16
use Romm\Formz\Core\Core;
17
use Romm\Formz\Error\FormResult;
18
use Romm\Formz\Form\FormInterface;
19
use Romm\Formz\Service\FormService;
20
use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator as ExtbaseAbstractValidator;
21
22
/**
23
 * @todo
24
 *
25
 * This is the abstract form validator, which must be inherited by any custom
26
 * form validator in order to work properly.
27
 *
28
 * Please note that a default form validator already exists if you need a form
29
 * which does not require any particular action: `DefaultFormValidator`.
30
 *
31
 * A form validator should be called to validate any form instance (which is a
32
 * child of `AbstractForm`). Usually, this is used in controller actions to
33
 * validate a form sent by the user. Example:
34
 *
35
 * /**
36
 *  * Action called when the Example form is submitted.
37
 *  *
38
 *  * @param $exForm
39
 *  * @validate $exForm Romm.Formz:Form\DefaultFormValidator
40
 *  * /
41
 *  public function submitFormAction(ExampleForm $exForm) { ... }
42
 *
43
 *******************************************************************************
44
 *
45
 * You may use you own custom form validator in order to be able to use the
46
 * following features:
47
 *
48
 * - Fields validation (de)activation:
49
 *   You are able to handle manually which validation rule for each field of the
50
 *   form may be activated or not. These functions can be used during the custom
51
 *   process functions described below.
52
 *   See the functions:
53
 *    - `activateField()`
54
 *    - `deactivateField()`
55
 *    - `activateFieldValidator()`
56
 *    - `deactivateFieldValidator()`
57
 *   And the properties:
58
 *    - `$deactivatedFields`
59
 *    - `$deactivatedFieldsValidators`
60
 *
61
 * - Pre-validation custom process:
62
 *   By extending the method `beforeValidationProcess()`, you are able to handle
63
 *   anything you want just before the form validation begins to loop on every
64
 *   field. This can be used for instance to (de)activate the validation of
65
 *   certain fields under very specific circumstances.
66
 *
67
 * - In real time custom process:
68
 *   After each field went trough a validation process, a magic method is called
69
 *   to allow very low level custom process. The magic method name looks like:
70
 *   "{lowerCamelCaseFieldName}Validated". For instance, when the "email" field
71
 *   just went trough the validation process, the method `emailValidated()` is
72
 *   called.
73
 *
74
 * - Post-validation custom process:
75
 *   After the validation was done on every field of the form, this method is
76
 *   called to allow you high level process. For instance, let's assume your
77
 *   form is used to calculate a price estimation depending on information
78
 *   submitted in the form; when the form went trough the validation process and
79
 *   got no error, you can run the price estimation, and if any error occurs you
80
 *   are still able to add an error to `$this->result` (in a controller you do
81
 *   not have access to it anymore).
82
 */
83
abstract class AbstractFormValidator extends ExtbaseAbstractValidator implements FormValidatorInterface
84
{
85
86
    /**
87
     * @inheritdoc
88
     */
89
    protected $supportedOptions = [
90
        'name' => ['', 'Name of the form.', 'string', true]
91
    ];
92
93
    /**
94
     * @var FormResult
95
     */
96
    protected $result;
97
98
    /**
99
     * Contains the validation results of all forms which were validated. The
100
     * key is the form name (the property `formName` in the form configuration)
101
     * and the value is an instance of `FormResult`.
102
     *
103
     * Note: we need to store the results here, because the TYPO3 request
104
     * handler builds an instance of Extbase's `Result` from scratch, so we are
105
     * not able to retrieve the `FormResult` instance afterward.
106
     *
107
     * @var FormResult[]
108
     */
109
    private static $formsValidationResults = [];
110
111
    /**
112
     * @todo
113
     *
114
     * @param mixed $form
115
     */
116
    public function isValid($form)
117
    {
118
        /** @var FormValidatorExecutor $formValidatorExecutor */
119
        $formValidatorExecutor = Core::instantiate(FormValidatorExecutor::class, $form, $this->options['name'], $this->result);
120
121
        $formValidatorExecutor->applyBehaviours();
122
        $formValidatorExecutor->checkFieldsActivation();
123
124
        $this->beforeValidationProcess();
125
126
        $formValidatorExecutor->validateFields();
127
128
        $this->afterValidationProcess();
129
130
        if ($this->result->hasErrors()) {
131
            // Storing the form for possible third party further usage.
132
            FormService::addFormWithErrors($form);
133
        }
134
135
        self::$formsValidationResults[get_class($form) . '::' . $this->options['name']] = $this->result;
136
    }
137
138
    /**
139
     * Validates the given Form instance. See class description for more
140
     * information.
141
     *
142
     * @param FormInterface $form The form instance to be validated.
143
     * @return FormResult
144
     */
145
    public function validate($form)
146
    {
147
        $this->result = new FormResult;
148
149
        $this->isValid($form);
150
151
        return $this->result;
152
    }
153
154
    /**
155
     * Returns the validation result of the asked form. The form name matches
156
     * the property `formName` of the form configuration.
157
     *
158
     * @param string $formClassName
159
     * @param string $formName
160
     * @return null|FormResult
161
     */
162
    public static function getFormValidationResult($formClassName, $formName)
163
    {
164
        $key = $formClassName . '::' . $formName;
165
166
        return (true === isset(self::$formsValidationResults[$key]))
167
            ? self::$formsValidationResults[$key]
168
            : null;
169
    }
170
171
    /**
172
     * Use this function to (de)activate the validation for some given fields.
173
     */
174
    protected function beforeValidationProcess()
175
    {
176
    }
177
178
    /**
179
     * Use this function to run your own processes after the validation ran.
180
     */
181
    protected function afterValidationProcess()
182
    {
183
    }
184
}
185