aboutsummaryrefslogtreecommitdiff
path: root/src/Service/FormValidation.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/Service/FormValidation.php')
-rw-r--r--src/Service/FormValidation.php216
1 files changed, 216 insertions, 0 deletions
diff --git a/src/Service/FormValidation.php b/src/Service/FormValidation.php
new file mode 100644
index 0000000..d91aa12
--- /dev/null
+++ b/src/Service/FormValidation.php
@@ -0,0 +1,216 @@
1<?php
2// src/Service/FormValidation.php
3//
4// pattern strategy simplifié, permet évolution future vers le vrai pattern
5
6declare(strict_types=1);
7
8namespace App\Service;
9
10// classe spéciale permettant de bénéficier du typage de classe au lieu de passer une chaîne à FormValidation
11enum ValidationStrategy {
12 // bloc formulaire de contact
13 case EmailSend;
14 case EmailParam;
15 // formulaires pages spéciales
16 case CreateUser;
17 case Connection;
18 case UsernameUpdate;
19 case PasswordUpdate;
20
21 public function method(): string
22 {
23 return match($this){
24 self::EmailSend => 'emailSendStrategy',
25 self::EmailParam => 'emailParamStrategy',
26 self::CreateUser => 'createUserStrategy',
27 self::Connection => 'connectionStrategy',
28 self::UsernameUpdate => 'usernameUpdateStrategy',
29 self::PasswordUpdate => 'passwordUpdateStrategy'
30 };
31 }
32}
33
34class FormValidation
35{
36 private array $data; // tableau associatif (probablement $_POST)
37 private \Closure $callStrategy;
38 private ?string $error;
39
40 public function __construct(array $data, ValidationStrategy $strategy){
41 $this->data = $data;
42 $method = $strategy->method();
43 $this->callStrategy = fn() => $this->$method();
44 }
45
46 public function validate(): bool
47 {
48 $this->error = ($this->callStrategy)(); // appel de la callback
49 return empty($this->errors);
50 }
51
52 public function getError(): string
53 {
54 return $this->error;
55 }
56
57 public function getField(string $field): string
58 {
59 return $this->data[$field] ?? '';
60 }
61
62 // méthodes de validation
63 private function captchaValidate(bool $clean_session = true): ?string
64 {
65 $captcha_solution = (isset($_SESSION['captcha']) && is_int($_SESSION['captcha'])) ? $_SESSION['captcha'] : 0;
66 $captcha_try = isset($this->data['captcha']) ? Captcha::controlInput($this->data['captcha']) : 0;
67 if($clean_session){
68 unset($_SESSION['captcha']);
69 }
70
71 if($captcha_try == 0){
72 return 'error_non_valid_captcha';
73 }
74 elseif($captcha_solution == 0){ // ne peut pas arriver, si?
75 return 'captcha_server_error';
76 }
77 elseif($captcha_try !== $captcha_solution){
78 return 'bad_solution_captcha';
79 }
80 return null;
81 }
82
83 // erreurs à la création des mots de passe
84 static private function removeSpacesTabsCRLF(string $chaine): string
85 {
86 $cibles = [' ', "\t", "\n", "\r"]; // doubles quotes !!
87 return(str_replace($cibles, '', $chaine));
88 }
89
90
91 // stratégies
92 private function emailSendStrategy(): ?string
93 {
94 if($error = $this->captchaValidate(false)){
95 return $error;
96 }
97
98 if(empty($this->data['name']) || empty($this->data['email']) || empty($this->data['message'])
99 || !isset($this->data['hidden']) || !empty($this->data['hidden'])){
100 return 'missing_fields';
101 }
102
103 elseif(!filter_var(trim($this->data['email']), FILTER_VALIDATE_EMAIL)){
104 return 'bad_email_address';
105 }
106
107 $this->data['name'] = htmlspecialchars(trim($this->data['name']));
108 $this->data['email'] = htmlspecialchars(trim($this->data['email']));
109 $this->data['message'] = htmlspecialchars($this->data['message']);
110
111 return null;
112 }
113 private function emailParamStrategy(): ?string
114 {
115 if(empty($this->data['id']) || empty($this->data['what_param']) || empty($this->data['value'])
116 || !isset($this->data['hidden']) || !empty($this->data['hidden'])){
117 return 'missing_fields';
118 }
119
120 if(!in_array($this->data['what_param'], ['smtp_host', 'smtp_secure', 'smtp_username', 'smtp_password', 'email_dest'])){
121 return 'unknown_parameter';
122 }
123 elseif($this->data['what_param'] === 'smtp_username' || $this->data['what_param'] === 'email_dest'){
124 if(!filter_var($this->data['value'], FILTER_VALIDATE_EMAIL)){
125 return 'invalide_email_address';
126 }
127 }
128 return null;
129 }
130 private function createUserStrategy(): ?string
131 {
132 if($error = $this->captchaValidate()){
133 return $error;
134 }
135
136 // test mauvais paramètres
137 if(empty($this->data['login']) || empty($this->data['password']) || empty($this->data['password_confirmation'])
138 || !isset($this->data['create_user_hidden']) || !empty($this->data['create_user_hidden']))
139 {
140 return 'bad_login_or_password';
141 }
142
143 if($this->data['password'] !== $this->data['password_confirmation']){
144 return 'different_passwords';
145 }
146
147 if($this->data['login'] !== self::removeSpacesTabsCRLF(htmlspecialchars($this->data['login']))
148 || $this->data['password'] !== self::removeSpacesTabsCRLF(htmlspecialchars($this->data['password']))){
149 return 'forbidden_characters';
150 }
151 return null;
152 }
153 private function connectionStrategy(): ?string
154 {
155 if($error = $this->captchaValidate()){
156 return $error;
157 }
158
159 if(empty($this->data['login']) || empty($this->data['password'])
160 || !isset($this->data['connection_hidden']) || !empty($this->data['connection_hidden']))
161 {
162 return 'bad_login_or_password';
163 }
164 return null;
165 }
166 private function usernameUpdateStrategy(): ?string
167 {
168 if($error = $this->captchaValidate()){
169 return $error;
170 }
171
172 if(empty($this->data['login']) || empty($this->data['password']) || empty($this->data['new_login'])
173 || !isset($this->data['modify_username_hidden']) || !empty($this->data['modify_username_hidden']))
174 {
175 return 'bad_login_or_password';
176 }
177
178 $new_login = self::removeSpacesTabsCRLF(htmlspecialchars($this->data['new_login']));
179 if($new_login !== $this->data['new_login']){
180 return 'forbidden_characters';
181 }
182
183 if($this->data['login'] !== $_SESSION['user']['username']){
184 return 'bad_login_or_password';
185 }
186 if($this->data['login'] === $new_login){
187 return 'same_username_as_before';
188 }
189 return null;
190 }
191 private function passwordUpdateStrategy(): ?string
192 {
193 if($error = $this->captchaValidate()){
194 return $error;
195 }
196
197 if(empty($this->data['login']) || empty($this->data['password']) || empty($this->data['new_password'])
198 || !isset($this->data['modify_password_hidden']) || !empty($this->data['modify_password_hidden']))
199 {
200 return 'bad_login_or_password';
201 }
202
203 $new_password = self::removeSpacesTabsCRLF(htmlspecialchars($this->data['new_password']));
204 if($new_password !== $this->data['new_password']){
205 return 'forbidden_characters';
206 }
207
208 if($this->data['login'] !== $_SESSION['user']['username']){
209 return 'bad_login_or_password';
210 }
211 if($this->data['password'] === $new_password){
212 return 'same_password_as_before';
213 }
214 return null;
215 }
216} \ No newline at end of file