| @@ -1,37 +1,48 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace FluentForm\App\Modules\Form; |
| 4 | 4 | |
| 5 | -use FluentForm\App\Databases\Migrations\FormSubmissionDetails; | |
| 5 | +use FluentForm\Database\Migrations\SubmissionDetails; | |
| 6 | +use FluentForm\App\Helpers\Helper; | |
| 6 | 7 | use FluentForm\App\Modules\Activator; |
| 7 | -use FluentForm\App\Modules\Entries\Entries; | |
| 8 | 8 | use FluentForm\App\Modules\ReCaptcha\ReCaptcha; |
| 9 | +use FluentForm\App\Modules\HCaptcha\HCaptcha; | |
| 10 | +use FluentForm\App\Modules\Turnstile\Turnstile; | |
| 9 | 11 | use FluentForm\App\Services\Browser\Browser; |
| 10 | 12 | use FluentForm\App\Services\FormBuilder\ShortCodeParser; |
| 13 | +use FluentForm\App\Services\Submission\SubmissionService; | |
| 11 | 14 | use FluentForm\Framework\Foundation\Application; |
| 12 | 15 | use FluentForm\Framework\Helpers\ArrayHelper as Arr; |
| 13 | 16 | use FluentForm\Framework\Helpers\ArrayHelper; |
| 14 | 17 | |
| 18 | +/* @deprecated Use class \FluentForm\App\Http\Controllers\SubmissionHandlerController */ | |
| 19 | + | |
| 15 | 20 | class FormHandler |
| 16 | 21 | { |
| 17 | 22 | /** |
| 23 | + * App instance | |
| 24 | + * | |
| 18 | 25 | * @var \FluentForm\Framework\Foundation\Application |
| 19 | 26 | */ |
| 20 | 27 | protected $app; |
| 21 | 28 | |
| 22 | 29 | /** |
| 30 | + * Request object | |
| 31 | + * | |
| 23 | 32 | * @var \FluentForm\Framework\Request\Request |
| 24 | 33 | */ |
| 25 | 34 | protected $request; |
| 26 | 35 | |
| 27 | 36 | /** |
| 37 | + * Form Data | |
| 38 | + * | |
| 28 | 39 | * @var array $formData |
| 29 | 40 | */ |
| 30 | 41 | protected $formData; |
| 31 | 42 | |
| 32 | 43 | /** |
| 33 | - * The fluent form object. | |
| 44 | + * The Fluent Forms object. | |
| 34 | 45 | * |
| 35 | 46 | * @var \stdClass |
| 36 | 47 | */ |
| 37 | 48 | protected $form; |
| @@ -50,8 +61,9 @@ | ||
| 50 | 61 | /** |
| 51 | 62 | * Set the form using it's ID. |
| 52 | 63 | * |
| 53 | 64 | * @param $formId |
| 65 | + * | |
| 54 | 66 | * @return $this |
| 55 | 67 | */ |
| 56 | 68 | public function setForm($formId) |
| 57 | 69 | { |
| @@ -66,8 +78,10 @@ | ||
| 66 | 78 | { |
| 67 | 79 | // Parse the url encoded data from the request object. |
| 68 | 80 | parse_str($this->app->request->get('data'), $data); |
| 69 | 81 | |
| 82 | + $data['_wp_http_referer'] = urldecode($data['_wp_http_referer']); | |
| 83 | + | |
| 70 | 84 | // Merge it back again to the request object. |
| 71 | 85 | $this->app->request->merge(['data' => $data]); |
| 72 | 86 | |
| 73 | 87 | $formId = intval($this->app->request->get('form_id')); |
| @@ -73,8 +87,14 @@ | ||
| 73 | 87 | $formId = intval($this->app->request->get('form_id')); |
| 74 | 88 | |
| 75 | 89 | $this->setForm($formId); |
| 76 | 90 | |
| 91 | + if (!$this->form) { | |
| 92 | + wp_send_json([ | |
| 93 | + 'errors' => [], | |
| 94 | + 'message' => 'Sorry, No corresponding form found', | |
| 95 | + ], 423); | |
| 96 | + } | |
| 77 | 97 | |
| 78 | 98 | // Parse the form and get the flat inputs with validations. |
| 79 | 99 | $fields = FormFieldsParser::getInputs($this->form, ['rules', 'raw']); |
| 80 | 100 | |
| @@ -86,21 +106,64 @@ | ||
| 86 | 106 | |
| 87 | 107 | // Prepare the data to be inserted to the DB. |
| 88 | 108 | $insertData = $this->prepareInsertData(); |
| 89 | 109 | |
| 90 | - if ($this->isSpam($this->formData, $this->form)) { | |
| 110 | + if ($this->isAkismetSpam($this->formData, $this->form)) { | |
| 91 | 111 | $insertData['status'] = 'spam'; |
| 92 | 112 | $this->handleSpamError(); |
| 93 | 113 | } |
| 94 | 114 | |
| 95 | - do_action('fluentform_before_insert_submission', $insertData, $data, $this->form); | |
| 115 | + do_action_deprecated( | |
| 116 | + 'fluentform_before_insert_submission', | |
| 117 | + [ | |
| 118 | + $insertData, | |
| 119 | + $data, | |
| 120 | + $this->form | |
| 121 | + ], | |
| 122 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 123 | + 'fluentform/before_insert_submission', | |
| 124 | + 'Use fluentform/before_insert_submission instead of fluentform_before_insert_submission.' | |
| 125 | + ); | |
| 96 | 126 | |
| 127 | + do_action('fluentform/before_insert_submission', $insertData, $data, $this->form); | |
| 128 | + | |
| 97 | 129 | if ($this->form->has_payment) { |
| 98 | - do_action('fluentform_before_insert_payment_form', $insertData, $data, $this->form); | |
| 130 | + do_action_deprecated( | |
| 131 | + 'fluentform_before_insert_payment_form', | |
| 132 | + [ | |
| 133 | + $insertData, | |
| 134 | + $data, | |
| 135 | + $this->form | |
| 136 | + ], | |
| 137 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 138 | + 'fluentform/before_insert_payment_form', | |
| 139 | + 'Use fluentform/before_insert_payment_form instead of fluentform_before_insert_payment_form.' | |
| 140 | + ); | |
| 141 | + | |
| 142 | + do_action('fluentform/before_insert_payment_form', $insertData, $data, $this->form); | |
| 99 | 143 | } |
| 100 | 144 | |
| 101 | - $insertId = wpFluent()->table('fluentform_submissions')->insert($insertData); | |
| 145 | + $insertId = wpFluent()->table('fluentform_submissions')->insertGetId($insertData); | |
| 102 | 146 | |
| 147 | + do_action('fluentform/notify_on_form_submit', $insertId, $this->formData, $this->form); | |
| 148 | + | |
| 149 | + $uidHash = md5(wp_generate_uuid4() . $insertId); | |
| 150 | + Helper::setSubmissionMeta($insertId, '_entry_uid_hash', $uidHash, $formId); | |
| 151 | + | |
| 152 | + do_action_deprecated( | |
| 153 | + 'fluentform_before_form_actions_processing', | |
| 154 | + [ | |
| 155 | + $insertId, | |
| 156 | + $this->formData, | |
| 157 | + $this->form | |
| 158 | + ], | |
| 159 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 160 | + 'fluentform/before_form_actions_processing', | |
| 161 | + 'Use fluentform/before_form_actions_processing instead of fluentform_before_form_actions_processing.' | |
| 162 | + ); | |
| 163 | + | |
| 164 | + do_action('fluentform/before_form_actions_processing', $insertId, $this->formData, $this->form); | |
| 165 | + | |
| 103 | 166 | $result = $this->processFormSubmissionData($insertId, $this->formData, $this->form); |
| 104 | 167 | |
| 105 | 168 | wp_send_json_success($result, 200); |
| 106 | 169 | } |
| @@ -108,13 +171,13 @@ | ||
| 108 | 171 | public function processFormSubmissionData($insertId, $formData, $form) |
| 109 | 172 | { |
| 110 | 173 | if ($insertId) { |
| 111 | 174 | ob_start(); |
| 112 | - $entries = new Entries(); | |
| 113 | - $entries->recordEntryDetails($insertId, $form->id, $formData); | |
| 175 | + $submissionService = new SubmissionService(); | |
| 176 | + $submissionService->recordEntryDetails($insertId, $form->id, $formData); | |
| 114 | 177 | $isError = ob_get_clean(); |
| 115 | 178 | if ($isError) { |
| 116 | - FormSubmissionDetails::migrate(); | |
| 179 | + SubmissionDetails::migrate(); | |
| 117 | 180 | } |
| 118 | 181 | } |
| 119 | 182 | |
| 120 | 183 | $returnData = $this->getReturnData($insertId, $form, $formData); |
| @@ -120,21 +183,42 @@ | ||
| 120 | 183 | $returnData = $this->getReturnData($insertId, $form, $formData); |
| 121 | 184 | |
| 122 | 185 | $error = ''; |
| 123 | 186 | try { |
| 124 | - $this->app->doAction( | |
| 125 | - 'fluentform_submission_inserted', | |
| 187 | + | |
| 188 | + /* | |
| 189 | + * We will keep this old hook for backward compatability. | |
| 190 | + */ | |
| 191 | + do_action('fluentform_submission_inserted', $insertId, $formData, $form); | |
| 192 | + | |
| 193 | + do_action( | |
| 194 | + 'fluentform/submission_inserted', | |
| 126 | 195 | $insertId, |
| 127 | 196 | $formData, |
| 128 | 197 | $form |
| 129 | 198 | ); |
| 130 | 199 | |
| 131 | - $this->app->doAction( | |
| 200 | + Helper::setSubmissionMeta($insertId, 'is_form_action_fired', 'yes'); | |
| 201 | + | |
| 202 | + do_action_deprecated( | |
| 132 | 203 | 'fluentform_submission_inserted_' . $form->type . '_form', |
| 204 | + [ | |
| 205 | + $insertId, | |
| 206 | + $formData, | |
| 207 | + $form | |
| 208 | + ], | |
| 209 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 210 | + 'fluentform/submission_inserted', | |
| 211 | + 'Use fluentform/submission_inserted_' . $form->type . '_form' . ' instead of fluentform_submission_inserted_' . $form->type . '_form' | |
| 212 | + ); | |
| 213 | + | |
| 214 | + do_action( | |
| 215 | + 'fluentform/submission_inserted_' . $form->type . '_form', | |
| 133 | 216 | $insertId, |
| 134 | 217 | $formData, |
| 135 | 218 | $form |
| 136 | 219 | ); |
| 220 | + | |
| 137 | 221 | } catch (\Exception $e) { |
| 138 | 222 | if (defined('WP_DEBUG') && WP_DEBUG) { |
| 139 | 223 | $error = $e->getMessage(); |
| 140 | 224 | } |
| @@ -139,14 +223,26 @@ | ||
| 139 | 223 | $error = $e->getMessage(); |
| 140 | 224 | } |
| 141 | 225 | } |
| 142 | 226 | |
| 143 | - do_action('fluenform_before_submission_confirmation', $insertId, $formData, $form); | |
| 227 | + do_action_deprecated( | |
| 228 | + 'fluentform_before_submission_confirmation', | |
| 229 | + [ | |
| 230 | + $insertId, | |
| 231 | + $formData, | |
| 232 | + $form | |
| 233 | + ], | |
| 234 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 235 | + 'fluentform/before_submission_confirmation', | |
| 236 | + 'Use fluentform/before_submission_confirmation instead of fluentform_before_submission_confirmation.' | |
| 237 | + ); | |
| 144 | 238 | |
| 239 | + do_action('fluentform/before_submission_confirmation', $insertId, $formData, $form); | |
| 240 | + | |
| 145 | 241 | return [ |
| 146 | 242 | 'insert_id' => $insertId, |
| 147 | - 'result' => $returnData, | |
| 148 | - 'error' => $error | |
| 243 | + 'result' => $returnData, | |
| 244 | + 'error' => $error, | |
| 149 | 245 | ]; |
| 150 | 246 | } |
| 151 | 247 | |
| 152 | 248 | public function getReturnData($insertId, $form, $formData) |
| @@ -158,45 +254,61 @@ | ||
| 158 | 254 | ->first(); |
| 159 | 255 | |
| 160 | 256 | $form->settings = $formSettings ? json_decode($formSettings->value, true) : []; |
| 161 | 257 | } |
| 162 | - | |
| 163 | - $confirmation = apply_filters( | |
| 258 | + $confirmation = $form->settings['confirmation']; | |
| 259 | + $confirmation = apply_filters_deprecated( | |
| 164 | 260 | 'fluentform_form_submission_confirmation', |
| 165 | - $form->settings['confirmation'], | |
| 261 | + [ | |
| 262 | + $confirmation, | |
| 263 | + $formData, | |
| 264 | + $form | |
| 265 | + ], | |
| 266 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 267 | + 'fluentform/form_submission_confirmation', | |
| 268 | + 'Use fluentform/form_submission_confirmation instead of fluentform_form_submission_confirmation.' | |
| 269 | + ); | |
| 270 | + | |
| 271 | + $confirmation = $this->app->applyFilters( | |
| 272 | + 'fluentform/form_submission_confirmation', | |
| 273 | + $confirmation, | |
| 166 | 274 | $formData, |
| 167 | 275 | $form |
| 168 | 276 | ); |
| 169 | 277 | |
| 170 | - if ($confirmation['redirectTo'] == 'samePage') { | |
| 278 | + if ('samePage' == $confirmation['redirectTo']) { | |
| 279 | + | |
| 280 | + $confirmation['messageToShow'] = fluentform_sanitize_html($confirmation['messageToShow']); | |
| 281 | + | |
| 282 | + $confirmation['messageToShow'] = do_shortcode($confirmation['messageToShow']); | |
| 283 | + | |
| 284 | + $confirmation['messageToShow'] = apply_filters('fluentform/submission_message_parse', | |
| 285 | + $confirmation['messageToShow'], $insertId, $formData, $form); | |
| 171 | 286 | |
| 172 | - $confirmation['messageToShow'] = apply_filters('fluentform_submission_message_parse', $confirmation['messageToShow'], $insertId, $formData, $form); | |
| 173 | - | |
| 174 | - | |
| 175 | 287 | $message = ShortCodeParser::parse( |
| 176 | 288 | $confirmation['messageToShow'], |
| 177 | 289 | $insertId, |
| 178 | 290 | $formData, |
| 179 | - $form | |
| 291 | + $form, | |
| 292 | + false, | |
| 293 | + true | |
| 180 | 294 | ); |
| 181 | 295 | |
| 182 | - | |
| 183 | 296 | $message = $message ? $message : 'The form has been successfully submitted.'; |
| 184 | 297 | |
| 185 | 298 | $returnData = [ |
| 186 | - 'message' => do_shortcode($message), | |
| 187 | - 'action' => $confirmation['samePageFormBehavior'], | |
| 299 | + 'message' => $message, | |
| 300 | + 'action' => $confirmation['samePageFormBehavior'], | |
| 188 | 301 | ]; |
| 189 | - | |
| 190 | 302 | } else { |
| 191 | 303 | $redirectUrl = Arr::get($confirmation, 'customUrl'); |
| 192 | 304 | |
| 193 | - if ($confirmation['redirectTo'] == 'customPage') { | |
| 305 | + if ('customPage' == $confirmation['redirectTo']) { | |
| 194 | 306 | $redirectUrl = get_permalink($confirmation['customPage']); |
| 195 | 307 | } |
| 196 | 308 | |
| 197 | 309 | if ( |
| 198 | - (Arr::get($confirmation, 'enable_query_string') == 'yes') && | |
| 310 | + ('yes' == Arr::get($confirmation, 'enable_query_string')) && | |
| 199 | 311 | Arr::get($confirmation, 'query_strings') |
| 200 | 312 | ) { |
| 201 | 313 | if (strpos($redirectUrl, '?')) { |
| 202 | 314 | $redirectUrl .= '&' . Arr::get($confirmation, 'query_strings'); |
| @@ -203,10 +315,21 @@ | ||
| 203 | 315 | } else { |
| 204 | 316 | $redirectUrl .= '?' . Arr::get($confirmation, 'query_strings'); |
| 205 | 317 | } |
| 206 | 318 | } |
| 319 | + $parseUrl = true; | |
| 320 | + $parseUrl = apply_filters_deprecated( | |
| 321 | + 'fluentform_will_parse_url_value', | |
| 322 | + [ | |
| 323 | + $parseUrl, | |
| 324 | + $form | |
| 325 | + ], | |
| 326 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 327 | + 'fluentform/will_parse_url_value', | |
| 328 | + 'Use fluentform/will_parse_url_value instead of fluentform_will_parse_url_value.' | |
| 329 | + ); | |
| 207 | 330 | |
| 208 | - $isUrlParser = apply_filters('fluentform_will_parse_url_value', true, $form); | |
| 331 | + $isUrlParser = apply_filters('fluentform/will_parse_url_value', $parseUrl, $form); | |
| 209 | 332 | |
| 210 | 333 | $redirectUrl = ShortCodeParser::parse( |
| 211 | 334 | $redirectUrl, |
| 212 | 335 | $insertId, |
| @@ -213,16 +336,14 @@ | ||
| 213 | 336 | $formData, |
| 214 | 337 | $form, |
| 215 | 338 | $isUrlParser |
| 216 | 339 | ); |
| 217 | - | |
| 218 | - if($isUrlParser) { | |
| 219 | - $redirectUrl = esc_url_raw($redirectUrl); | |
| 220 | - | |
| 340 | + | |
| 341 | + if ($isUrlParser) { | |
| 221 | 342 | /* |
| 222 | 343 | * For Empty Redirect Value |
| 223 | 344 | */ |
| 224 | - if(strpos($redirectUrl, '=&') || substr($redirectUrl, -1) == '=') { | |
| 345 | + if (strpos($redirectUrl, '=&') || '=' == substr($redirectUrl, -1)) { | |
| 225 | 346 | $urlArray = explode('?', $redirectUrl); |
| 226 | 347 | $baseUrl = array_shift($urlArray); |
| 227 | 348 | |
| 228 | 349 | $query = wp_parse_url($redirectUrl)['query']; |
| @@ -231,9 +352,9 @@ | ||
| 231 | 352 | |
| 232 | 353 | $params = []; |
| 233 | 354 | foreach ($queryParams as $queryParam) { |
| 234 | 355 | $paramArray = explode('=', $queryParam); |
| 235 | - if(!empty($paramArray[1])) { | |
| 356 | + if (!empty($paramArray[1])) { | |
| 236 | 357 | $params[$paramArray[0]] = $paramArray[1]; |
| 237 | 358 | } |
| 238 | 359 | } |
| 239 | 360 | |
| @@ -244,19 +365,34 @@ | ||
| 244 | 365 | $message = ShortCodeParser::parse( |
| 245 | 366 | ArrayHelper::get($confirmation, 'redirectMessage', ''), |
| 246 | 367 | $insertId, |
| 247 | 368 | $formData, |
| 248 | - $form | |
| 369 | + $form, | |
| 370 | + false, | |
| 371 | + true | |
| 249 | 372 | ); |
| 250 | - | |
| 373 | + | |
| 374 | + $redirectUrl = wp_sanitize_redirect(urldecode($redirectUrl)); | |
| 251 | 375 | $returnData = [ |
| 252 | - 'redirectUrl' => $redirectUrl, | |
| 253 | - 'message' => $message | |
| 376 | + 'redirectUrl' => esc_url_raw($redirectUrl), | |
| 377 | + 'message' => $message, | |
| 254 | 378 | ]; |
| 255 | 379 | } |
| 380 | + | |
| 381 | + $returnData = apply_filters_deprecated( | |
| 382 | + 'fluentform_submission_confirmation', | |
| 383 | + [ | |
| 384 | + $returnData, | |
| 385 | + $form, | |
| 386 | + $confirmation | |
| 387 | + ], | |
| 388 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 389 | + 'fluentform/submission_confirmation', | |
| 390 | + 'Use fluentform/submission_confirmation instead of fluentform_submission_confirmation.' | |
| 391 | + ); | |
| 256 | 392 | |
| 257 | 393 | return $this->app->applyFilters( |
| 258 | - 'fluentform_submission_confirmation', | |
| 394 | + 'fluentform/submission_confirmation', | |
| 259 | 395 | $returnData, |
| 260 | 396 | $form, |
| 261 | 397 | $confirmation |
| 262 | 398 | ); |
| @@ -265,22 +401,60 @@ | ||
| 265 | 401 | /** |
| 266 | 402 | * Validate form data. |
| 267 | 403 | * |
| 268 | 404 | * @param $fields |
| 405 | + * | |
| 269 | 406 | * @return bool |
| 270 | 407 | */ |
| 271 | 408 | private function validate(&$fields) |
| 272 | 409 | { |
| 410 | + $this->preventMaliciousAttacks(); | |
| 411 | + | |
| 273 | 412 | $this->validateRestrictions($fields); |
| 274 | 413 | |
| 275 | 414 | $this->validateNonce(); |
| 276 | 415 | |
| 277 | 416 | $this->validateReCaptcha(); |
| 417 | + $this->validateHCaptcha(); | |
| 418 | + $this->validateTurnstile(); | |
| 278 | 419 | |
| 420 | + foreach ($fields as $fieldName => $field) { | |
| 421 | + if (isset($this->formData[$fieldName])) { | |
| 422 | + $element = $field['element']; | |
| 423 | + | |
| 424 | + $this->formData[$fieldName] = apply_filters_deprecated( | |
| 425 | + 'fluentform_input_data_' . $element, | |
| 426 | + [ | |
| 427 | + $this->formData[$fieldName], | |
| 428 | + $field, | |
| 429 | + $this->formData, | |
| 430 | + $this->form | |
| 431 | + ], | |
| 432 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 433 | + 'fluentform/input_data_' . $element, | |
| 434 | + 'Use fluentform/input_data_' . $element . ' instead of fluentform_input_data_' . $element | |
| 435 | + ); | |
| 436 | + | |
| 437 | + $this->formData[$fieldName] = $this->app->applyFilters('fluentform/input_data_' . $element, | |
| 438 | + $this->formData[$fieldName], $field, $this->formData, $this->form); | |
| 439 | + } | |
| 440 | + } | |
| 441 | + | |
| 279 | 442 | $originalValidations = FormFieldsParser::getValidations($this->form, $this->formData, $fields); |
| 280 | - | |
| 443 | + | |
| 444 | + $originalValidations = apply_filters_deprecated( | |
| 445 | + 'fluentform_validations', | |
| 446 | + [ | |
| 447 | + $originalValidations, | |
| 448 | + $this->form, | |
| 449 | + $this->formData | |
| 450 | + ], | |
| 451 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 452 | + 'fluentform/validations', | |
| 453 | + 'Use fluentform/validations instead of fluentform_validations.' | |
| 454 | + ); | |
| 281 | 455 | // Fire an event so that one can hook into it to work with the rules & messages. |
| 282 | - $validations = apply_filters('fluentform_validations', $originalValidations, $this->form, $this->formData); | |
| 456 | + $validations = apply_filters('fluentform/validations', $originalValidations, $this->form, $this->formData); | |
| 283 | 457 | |
| 284 | 458 | /* |
| 285 | 459 | * Clean talk fix for now |
| 286 | 460 | * They should not hook fluentform_validations and return nothing! |
| @@ -289,9 +463,9 @@ | ||
| 289 | 463 | if ($originalValidations && (!$validations || !array_filter($validations))) { |
| 290 | 464 | $validations = $originalValidations; |
| 291 | 465 | } |
| 292 | 466 | |
| 293 | - $validator = \FluentValidator\Validator::make($this->formData, $validations[0], $validations[1]); | |
| 467 | + $validator = wpFluentForm('validator')->make($this->formData, $validations[0], $validations[1]); | |
| 294 | 468 | |
| 295 | 469 | $errors = []; |
| 296 | 470 | if ($validator->validate()->fails()) { |
| 297 | 471 | foreach ($validator->errors() as $attribute => $rules) { |
| @@ -302,10 +476,24 @@ | ||
| 302 | 476 | } |
| 303 | 477 | |
| 304 | 478 | $errors[$attribute] = $rules; |
| 305 | 479 | } |
| 480 | + | |
| 481 | + $errors = apply_filters_deprecated( | |
| 482 | + 'fluentform_validation_error', | |
| 483 | + [ | |
| 484 | + $errors, | |
| 485 | + $this->form, | |
| 486 | + $fields, | |
| 487 | + $this->formData | |
| 488 | + ], | |
| 489 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 490 | + 'fluentform/validation_error', | |
| 491 | + 'Use fluentform/validation_error instead of fluentform_validation_error.' | |
| 492 | + ); | |
| 306 | 493 | // Fire an event so that one can hook into it to work with the errors. |
| 307 | - $errors = $this->app->applyFilters('fluentform_validation_error', $errors, $this->form, $fields, $this->formData); | |
| 494 | + $errors = $this->app->applyFilters('fluentform/validation_error', $errors, $this->form, $fields, | |
| 495 | + $this->formData); | |
| 308 | 496 | } |
| 309 | 497 | |
| 310 | 498 | foreach ($fields as $fieldKey => $field) { |
| 311 | 499 | $field['data_key'] = $fieldKey; |
| @@ -310,15 +498,31 @@ | ||
| 310 | 498 | foreach ($fields as $fieldKey => $field) { |
| 311 | 499 | $field['data_key'] = $fieldKey; |
| 312 | 500 | $inputName = \FluentForm\Framework\Helpers\ArrayHelper::get($field, 'raw.attributes.name'); |
| 313 | 501 | $field['name'] = $inputName; |
| 314 | - $error = apply_filters('fluentform_validate_input_item_' . $field['element'], '', $field, $this->formData, $fields, $this->form, $errors); | |
| 502 | + | |
| 503 | + $error = apply_filters_deprecated( | |
| 504 | + 'fluentform_validate_input_item_' . $field['element'], | |
| 505 | + [ | |
| 506 | + '', | |
| 507 | + $field, | |
| 508 | + $this->formData, | |
| 509 | + $fields, | |
| 510 | + $this->form, | |
| 511 | + $errors | |
| 512 | + ], | |
| 513 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 514 | + 'fluentform_validate_input_item_' . $field['element'], | |
| 515 | + 'Use fluentform/validate_input_item_' . $field['element'] . ' instead of fluentform_validate_input_item_' . $field['element'] | |
| 516 | + ); | |
| 517 | + | |
| 518 | + $error = apply_filters('fluentform/validate_input_item_' . $field['element'], $error, $field, $this->formData, $fields, $this->form, $errors); | |
| 315 | 519 | if ($error) { |
| 316 | 520 | if (empty($errors[$inputName])) { |
| 317 | 521 | $errors[$inputName] = []; |
| 318 | 522 | } |
| 319 | 523 | |
| 320 | - if(is_string($error)) { | |
| 524 | + if (is_string($error)) { | |
| 321 | 525 | $error = [$error]; |
| 322 | 526 | } |
| 323 | 527 | |
| 324 | 528 | $errors[$inputName] = array_merge($error, $errors[$inputName]); |
| @@ -323,13 +527,61 @@ | ||
| 323 | 527 | |
| 324 | 528 | $errors[$inputName] = array_merge($error, $errors[$inputName]); |
| 325 | 529 | } |
| 326 | 530 | } |
| 531 | + | |
| 532 | + $errors = apply_filters_deprecated( | |
| 533 | + 'fluentform_validation_errors', | |
| 534 | + [ | |
| 535 | + $errors, | |
| 536 | + $this->formData, | |
| 537 | + $this->form, | |
| 538 | + $fields | |
| 539 | + ], | |
| 540 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 541 | + 'fluentform/validation_errors', | |
| 542 | + 'Use fluentform/validation_errors instead of fluentform_validation_errors.' | |
| 543 | + ); | |
| 327 | 544 | |
| 328 | - $errors = apply_filters('fluentform_validation_errors', $errors, $this->formData, $this->form, $fields); | |
| 545 | + $errors = apply_filters('fluentform/validation_errors', $errors, $this->formData, $this->form, $fields); | |
| 329 | 546 | |
| 547 | + if ('yes' == Helper::getFormMeta($this->form->id, '_has_user_registration') && !get_current_user_id()) { | |
| 548 | + $errors = apply_filters_deprecated( | |
| 549 | + 'fluentform_validation_user_registration_errors', | |
| 550 | + [ | |
| 551 | + $errors, | |
| 552 | + $this->formData, | |
| 553 | + $this->form, | |
| 554 | + $fields | |
| 555 | + ], | |
| 556 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 557 | + 'fluentform/validation_user_registration_errors', | |
| 558 | + 'Use fluentform/validation_user_registration_errors instead of fluentform_validation_user_registration_errors.' | |
| 559 | + ); | |
| 560 | + | |
| 561 | + $errors = apply_filters('fluentform/validation_user_registration_errors', $errors, $this->formData, | |
| 562 | + $this->form, $fields); | |
| 563 | + } | |
| 564 | + | |
| 565 | + if ('yes' == Helper::getFormMeta($this->form->id, '_has_user_update') && get_current_user_id()) { | |
| 566 | + $errors = apply_filters_deprecated( | |
| 567 | + 'fluentform_validation_user_update_errors', | |
| 568 | + [ | |
| 569 | + $errors, | |
| 570 | + $this->formData, | |
| 571 | + $this->form, | |
| 572 | + $fields | |
| 573 | + ], | |
| 574 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 575 | + 'fluentform/validation_user_update_errors', | |
| 576 | + 'Use fluentform/validation_user_update_errors instead of fluentform_validation_user_update_errors.' | |
| 577 | + ); | |
| 578 | + | |
| 579 | + $errors = apply_filters('fluentform/validation_user_update_errors', $errors, $this->formData, $this->form, $fields); | |
| 580 | + } | |
| 581 | + | |
| 330 | 582 | if ($errors) { |
| 331 | - wp_send_json(['errors' => $errors], 422); | |
| 583 | + wp_send_json(['errors' => $errors], 423); | |
| 332 | 584 | } |
| 333 | 585 | |
| 334 | 586 | return true; |
| 335 | 587 | } |
| @@ -339,19 +591,30 @@ | ||
| 339 | 591 | */ |
| 340 | 592 | protected function validateNonce() |
| 341 | 593 | { |
| 342 | 594 | $formId = $this->form->id; |
| 595 | + $nonceVerify = false; | |
| 596 | + /* This filter is deprecated and will be removed soon. */ | |
| 597 | + $nonceVerify = $this->app->applyFilters('fluentform_nonce_verify', $nonceVerify, $formId); | |
| 343 | 598 | |
| 344 | - $shouldVerifyNonce = $this->app->applyFilters('fluentform_nonce_verify', false, $formId); | |
| 599 | + $shouldVerifyNonce = $this->app->applyFilters('fluentform/nonce_verify', $nonceVerify, $formId); | |
| 345 | 600 | |
| 346 | 601 | if ($shouldVerifyNonce) { |
| 347 | 602 | $nonce = Arr::get($this->formData, '_fluentform_' . $formId . '_fluentformnonce'); |
| 348 | 603 | if (!wp_verify_nonce($nonce, 'fluentform-submit-form')) { |
| 349 | - $errors = $this->app->applyFilters('fluentForm_nonce_error', [ | |
| 350 | - '_fluentformnonce' => [ | |
| 351 | - __('Nonce verification failed, please try again.', 'fluentform') | |
| 352 | - ] | |
| 353 | - ]); | |
| 604 | + $nonceMessage = apply_filters_deprecated( | |
| 605 | + 'fluentForm_nonce_error', | |
| 606 | + [ | |
| 607 | + '_fluentformnonce' => [ | |
| 608 | + __('Nonce verification failed, please try again.', 'fluentform'), | |
| 609 | + ], | |
| 610 | + ], | |
| 611 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 612 | + 'fluentform/nonce_error', | |
| 613 | + 'Use fluentform/nonce_error instead of fluentForm_nonce_error.' | |
| 614 | + ); | |
| 615 | + | |
| 616 | + $errors = $this->app->applyFilters('fluentform/nonce_error', $nonceMessage); | |
| 354 | 617 | wp_send_json(['errors' => $errors], 422); |
| 355 | 618 | } |
| 356 | 619 | } |
| 357 | 620 | } |
| @@ -358,33 +621,61 @@ | ||
| 358 | 621 | |
| 359 | 622 | protected function handleSpamError() |
| 360 | 623 | { |
| 361 | 624 | $settings = get_option('_fluentform_global_form_settings'); |
| 362 | - if (!$settings || ArrayHelper::get($settings, 'misc.akismet_validation') != 'validation_failed') { | |
| 625 | + if (!$settings || 'validation_failed' != ArrayHelper::get($settings, 'misc.akismet_validation')) { | |
| 363 | 626 | return; |
| 364 | 627 | } |
| 365 | 628 | |
| 366 | - $errors = [ | |
| 367 | - '_fluentformakismet' => __('Submission marked as spammed. Please try again', 'fluentform') | |
| 629 | + $errors = [ | |
| 630 | + '_fluentformakismet' => apply_filters( | |
| 631 | + 'fluentform/akismet_spam_message', | |
| 632 | + __('Submission marked as spammed. Please try again', 'fluentform'), | |
| 633 | + $this->form->id | |
| 634 | + ), | |
| 368 | 635 | ]; |
| 369 | 636 | |
| 370 | 637 | wp_send_json(['errors' => $errors], 422); |
| 371 | 638 | } |
| 372 | 639 | |
| 373 | - protected function isSpam($formData, $form) | |
| 640 | + protected function isAkismetSpam($formData, $form) | |
| 374 | 641 | { |
| 375 | 642 | if (!AkismetHandler::isEnabled()) { |
| 376 | 643 | return false; |
| 377 | 644 | } |
| 645 | + $isSpamCheck = true; | |
| 646 | + $isSpamCheck = apply_filters_deprecated( | |
| 647 | + 'fluentform_akismet_check_spam', | |
| 648 | + [ | |
| 649 | + true, | |
| 650 | + $form->id, | |
| 651 | + $formData | |
| 652 | + ], | |
| 653 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 654 | + 'fluentform/akismet_check_spam', | |
| 655 | + 'Use fluentform/akismet_check_spam instead of fluentform_akismet_check_spam.' | |
| 656 | + ); | |
| 378 | 657 | |
| 379 | - $isSpamCheck = apply_filters('fluentform_akismet_check_spam', true, $form->id, $formData); | |
| 658 | + $isSpamCheck = apply_filters('fluentform/akismet_check_spam', $isSpamCheck, $form->id, $formData); | |
| 380 | 659 | if (!$isSpamCheck) { |
| 381 | 660 | return false; |
| 382 | 661 | } |
| 383 | 662 | // Let's validate now |
| 384 | 663 | $isSpam = AkismetHandler::isSpamSubmission($formData, $form); |
| 664 | + | |
| 665 | + $isSpam = apply_filters_deprecated( | |
| 666 | + 'fluentform_akismet_spam_result', | |
| 667 | + [ | |
| 668 | + $isSpam, | |
| 669 | + $form->id, | |
| 670 | + $formData | |
| 671 | + ], | |
| 672 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 673 | + 'fluentform/akismet_spam_result', | |
| 674 | + 'Use fluentform/akismet_spam_result instead of fluentform_akismet_spam_result.' | |
| 675 | + ); | |
| 385 | 676 | |
| 386 | - return apply_filters('fluentform_akismet_spam_result', $isSpam, $form->id, $formData); | |
| 677 | + return $this->app->applyFilters('fluentform/akismet_spam_result', $isSpam, $form->id, $formData); | |
| 387 | 678 | } |
| 388 | 679 | |
| 389 | 680 | /** |
| 390 | 681 | * Validate reCaptcha. |
| @@ -390,24 +681,107 @@ | ||
| 390 | 681 | * Validate reCaptcha. |
| 391 | 682 | */ |
| 392 | 683 | private function validateReCaptcha() |
| 393 | 684 | { |
| 394 | - if (FormFieldsParser::hasElement($this->form, 'recaptcha')) { | |
| 395 | - $isValid = ReCaptcha::validate(Arr::get($this->formData, 'g-recaptcha-response')); | |
| 685 | + $hasAutoRecaptcha = false; | |
| 686 | + $hasAutoRecaptcha = apply_filters_deprecated( | |
| 687 | + 'ff_has_auto_recaptcha', | |
| 688 | + [ | |
| 689 | + $hasAutoRecaptcha | |
| 690 | + ], | |
| 691 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 692 | + 'fluentform/has_recaptcha', | |
| 693 | + 'Use fluentform/has_recaptcha instead of ff_has_auto_recaptcha.' | |
| 694 | + ); | |
| 695 | + $autoInclude = apply_filters('fluentform/has_recaptcha', $hasAutoRecaptcha); | |
| 696 | + if (FormFieldsParser::hasElement($this->form, 'recaptcha') || $autoInclude) { | |
| 697 | + $keys = get_option('_fluentform_reCaptcha_details'); | |
| 698 | + $token = Arr::get($this->formData, 'g-recaptcha-response'); | |
| 699 | + $version = 'v2_visible'; | |
| 700 | + if (!empty($keys['api_version'])) { | |
| 701 | + $version = $keys['api_version']; | |
| 702 | + } | |
| 703 | + $isValid = ReCaptcha::validate($token, $keys['secretKey'], $version); | |
| 396 | 704 | |
| 397 | 705 | if (!$isValid) { |
| 398 | - wp_send_json([ | |
| 399 | - 'errors' => [ | |
| 400 | - 'g-recaptcha-response' => [ | |
| 401 | - __('reCaptcha verification failed, please try again.', 'fluentform') | |
| 402 | - ] | |
| 403 | - ] | |
| 404 | - ], 422); | |
| 706 | + $message = apply_filters( | |
| 707 | + 'fluentform/recaptcha_failed_message', | |
| 708 | + __('reCaptcha verification failed, please try again.', 'fluentform'), | |
| 709 | + $this->form | |
| 710 | + ); | |
| 711 | + wp_send_json(['errors' => ['g-recaptcha-response' => [$message]]], 422); | |
| 405 | 712 | } |
| 406 | 713 | } |
| 407 | 714 | } |
| 408 | 715 | |
| 409 | 716 | /** |
| 717 | + * Validate hCaptcha. | |
| 718 | + */ | |
| 719 | + private function validateHCaptcha() | |
| 720 | + { | |
| 721 | + $hasAutoHcaptcha = false; | |
| 722 | + | |
| 723 | + $hasAutoHcaptcha = apply_filters_deprecated( | |
| 724 | + 'ff_has_auto_hcaptcha', | |
| 725 | + [ | |
| 726 | + $hasAutoHcaptcha | |
| 727 | + ], | |
| 728 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 729 | + 'fluentform/has_hcaptcha', | |
| 730 | + 'Use fluentform/has_hcaptcha instead of ff_has_auto_hcaptcha.' | |
| 731 | + ); | |
| 732 | + $autoInclude = apply_filters('fluentform/has_hcaptcha', $hasAutoHcaptcha); | |
| 733 | + FormFieldsParser::resetData(); | |
| 734 | + if (FormFieldsParser::hasElement($this->form, 'hcaptcha') || $autoInclude) { | |
| 735 | + $keys = get_option('_fluentform_hCaptcha_details'); | |
| 736 | + $token = Arr::get($this->formData, 'h-captcha-response'); | |
| 737 | + $isValid = HCaptcha::validate($token, $keys['secretKey']); | |
| 738 | + | |
| 739 | + if (!$isValid) { | |
| 740 | + $message = apply_filters( | |
| 741 | + 'fluentform/hcaptcha_failed_message', | |
| 742 | + __('hCaptcha verification failed, please try again.', 'fluentform'), | |
| 743 | + $this->form | |
| 744 | + ); | |
| 745 | + wp_send_json(['errors' => ['h-captcha-response' => [$message]]], 422); | |
| 746 | + } | |
| 747 | + } | |
| 748 | + } | |
| 749 | + | |
| 750 | + /** | |
| 751 | + * Validate turnstile. | |
| 752 | + */ | |
| 753 | + private function validateTurnstile() | |
| 754 | + { | |
| 755 | + $hasAutoTurnsTile = false; | |
| 756 | + $hasAutoTurnsTile = apply_filters_deprecated( | |
| 757 | + 'ff_has_auto_turnstile', | |
| 758 | + [ | |
| 759 | + $hasAutoTurnsTile | |
| 760 | + ], | |
| 761 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 762 | + 'fluentform/has_turnstile', | |
| 763 | + 'Use fluentform/has_turnstile instead of ff_has_auto_turnstile.' | |
| 764 | + ); | |
| 765 | + $autoInclude = apply_filters('fluentform/has_turnstile', $hasAutoTurnsTile); | |
| 766 | + if (FormFieldsParser::hasElement($this->form, 'turnstile') || $autoInclude) { | |
| 767 | + $keys = get_option('_fluentform_turnstile_details'); | |
| 768 | + $token = Arr::get($this->formData, 'cf-turnstile-response'); | |
| 769 | + | |
| 770 | + $isValid = Turnstile::validate($token, $keys['secretKey']); | |
| 771 | + | |
| 772 | + if (!$isValid) { | |
| 773 | + $message = apply_filters( | |
| 774 | + 'fluentform/turnstile_failed_message', | |
| 775 | + __('Turnstile verification failed, please try again.', 'fluentform'), | |
| 776 | + $this->form | |
| 777 | + ); | |
| 778 | + wp_send_json(['errors' => ['cf-turnstile-response' => [$message]]], 422); | |
| 779 | + } | |
| 780 | + } | |
| 781 | + } | |
| 782 | + | |
| 783 | + /** | |
| 410 | 784 | * Validate form data based on the form restrictions settings. |
| 411 | 785 | * |
| 412 | 786 | * @param $fields |
| 413 | 787 | */ |
| @@ -420,10 +794,10 @@ | ||
| 420 | 794 | |
| 421 | 795 | $this->form->settings = $formSettings ? json_decode($formSettings->value, true) : []; |
| 422 | 796 | |
| 423 | 797 | $isAllowed = [ |
| 424 | - 'status' => true, | |
| 425 | - 'message' => '' | |
| 798 | + 'status' => true, | |
| 799 | + 'message' => '', | |
| 426 | 800 | ]; |
| 427 | 801 | |
| 428 | 802 | // This will check the following restriction settings. |
| 429 | 803 | // 1. limitNumberOfEntries |
| @@ -428,17 +802,21 @@ | ||
| 428 | 802 | // This will check the following restriction settings. |
| 429 | 803 | // 1. limitNumberOfEntries |
| 430 | 804 | // 2. scheduleForm |
| 431 | 805 | // 3. requireLogin |
| 806 | + | |
| 807 | + /* This filter is deprecated and will be removed soon */ | |
| 432 | 808 | $isAllowed = apply_filters('fluentform_is_form_renderable', $isAllowed, $this->form); |
| 809 | + | |
| 810 | + $isAllowed = apply_filters('fluentform/is_form_renderable', $isAllowed, $this->form); | |
| 433 | 811 | |
| 434 | 812 | if (!$isAllowed['status']) { |
| 435 | 813 | wp_send_json([ |
| 436 | 814 | 'errors' => [ |
| 437 | 815 | 'restricted' => [ |
| 438 | - __($isAllowed['message'], 'fluentform') | |
| 439 | - ] | |
| 440 | - ] | |
| 816 | + $isAllowed['message'], | |
| 817 | + ], | |
| 818 | + ], | |
| 441 | 819 | ], 422); |
| 442 | 820 | } |
| 443 | 821 | |
| 444 | 822 | // Since we are here, we should now handle if the form should be allowed to submit empty. |
| @@ -452,9 +830,9 @@ | ||
| 452 | 830 | * |
| 453 | 831 | * @param array $settings |
| 454 | 832 | * @param $fields |
| 455 | 833 | */ |
| 456 | - private function handleDenyEmptySubmission($settings = [], &$fields) | |
| 834 | + private function handleDenyEmptySubmission($settings, &$fields) | |
| 457 | 835 | { |
| 458 | 836 | // Determine whether empty form submission is allowed or not. |
| 459 | 837 | if (Arr::get($settings, 'enabled')) { |
| 460 | 838 | // confirm this form has no required fields. |
| @@ -460,9 +838,9 @@ | ||
| 460 | 838 | // confirm this form has no required fields. |
| 461 | 839 | if (!FormFieldsParser::hasRequiredFields($this->form, $fields)) { |
| 462 | 840 | // Filter out the form data which doesn't have values. |
| 463 | 841 | $filteredFormData = array_filter( |
| 464 | - // Filter out the other meta fields that aren't actual inputs. | |
| 842 | + // Filter out the other meta fields that aren't actual inputs. | |
| 465 | 843 | array_intersect_key($this->formData, $fields) |
| 466 | 844 | ); |
| 467 | 845 | |
| 468 | 846 | // TODO: Extract this function into global functions file... |
| @@ -476,19 +854,18 @@ | ||
| 476 | 854 | return $array; |
| 477 | 855 | }; |
| 478 | 856 | |
| 479 | 857 | if (!count($arrayFilterRecursive($filteredFormData))) { |
| 858 | + $message = Arr::get($settings, 'message'); | |
| 859 | + if (!$message) { | |
| 860 | + $message = __('Sorry! You can\'t submit an empty form.', 'fluentform'); | |
| 861 | + } | |
| 480 | 862 | wp_send_json([ |
| 481 | 863 | 'errors' => [ |
| 482 | 864 | 'restricted' => [ |
| 483 | - __( | |
| 484 | - !($m = Arr::get($settings, 'message')) | |
| 485 | - ? 'Sorry! You can\'t submit an empty form.' | |
| 486 | - : $m, | |
| 487 | - 'fluentform' | |
| 488 | - ) | |
| 489 | - ] | |
| 490 | - ] | |
| 865 | + $message, | |
| 866 | + ], | |
| 867 | + ], | |
| 491 | 868 | ], 422); |
| 492 | 869 | } |
| 493 | 870 | } |
| 494 | 871 | } |
| @@ -497,13 +874,13 @@ | ||
| 497 | 874 | /** |
| 498 | 875 | * Prepare the data to be inserted to the database. |
| 499 | 876 | * |
| 500 | 877 | * @param boolean $formData |
| 878 | + * | |
| 501 | 879 | * @return array |
| 502 | 880 | */ |
| 503 | 881 | public function prepareInsertData($formData = false) |
| 504 | 882 | { |
| 505 | - | |
| 506 | 883 | $formId = $this->form->id; |
| 507 | 884 | |
| 508 | 885 | if (!$formData) { |
| 509 | 886 | $formData = $this->formData; |
| @@ -519,34 +896,67 @@ | ||
| 519 | 896 | if ($previousItem) { |
| 520 | 897 | $serialNumber = $previousItem->serial_number + 1; |
| 521 | 898 | } |
| 522 | 899 | |
| 523 | - $browser = new Browser; | |
| 900 | + $browser = new Browser(); | |
| 524 | 901 | |
| 525 | - $inputConfigs = FormFieldsParser::getEntryInputs($this->form, array('admin_label', 'raw')); | |
| 902 | + $inputConfigs = FormFieldsParser::getEntryInputs($this->form, ['admin_label', 'raw']); | |
| 903 | + | |
| 904 | + $formData = apply_filters_deprecated( | |
| 905 | + 'fluentform_insert_response_data', | |
| 906 | + [ | |
| 907 | + $formData, | |
| 908 | + $formId, | |
| 909 | + $inputConfigs | |
| 910 | + ], | |
| 911 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 912 | + 'fluentform/insert_response_data', | |
| 913 | + 'Use fluentform/insert_response_data instead of fluentform_insert_response_data.' | |
| 914 | + ); | |
| 915 | + $this->formData = apply_filters('fluentform/insert_response_data', $formData, $formId, $inputConfigs); | |
| 526 | 916 | |
| 527 | - $this->formData = apply_filters('fluentform_insert_response_data', $formData, $formId, $inputConfigs); | |
| 917 | + $ipAddress = sanitize_text_field($this->app->request->getIp()); | |
| 918 | + $disableIpLogging = false; | |
| 919 | + $disableIpLogging = apply_filters_deprecated( | |
| 920 | + 'fluentform_disable_ip_logging', | |
| 921 | + [ | |
| 922 | + $disableIpLogging, | |
| 923 | + $formId | |
| 924 | + ], | |
| 925 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 926 | + 'fluentform/disable_ip_logging', | |
| 927 | + 'Use fluentform/disable_ip_logging instead of fluentform_disable_ip_logging.' | |
| 928 | + ); | |
| 528 | 929 | |
| 529 | - $ipAddress = $this->app->request->getIp(); | |
| 530 | - | |
| 531 | - if ((defined('FLUENTFROM_DISABLE_IP_LOGGING') && FLUENTFROM_DISABLE_IP_LOGGING) || apply_filters('fluentform_disable_ip_logging', false, $formId)) { | |
| 930 | + if ((defined('FLUENTFROM_DISABLE_IP_LOGGING') && FLUENTFROM_DISABLE_IP_LOGGING) || apply_filters('fluentform/disable_ip_logging', | |
| 931 | + $disableIpLogging, $formId)) { | |
| 532 | 932 | $ipAddress = false; |
| 533 | 933 | } |
| 534 | 934 | |
| 535 | 935 | $response = [ |
| 536 | - 'form_id' => $formId, | |
| 936 | + 'form_id' => $formId, | |
| 537 | 937 | 'serial_number' => $serialNumber, |
| 538 | - 'response' => json_encode($this->formData), | |
| 539 | - 'source_url' => site_url(Arr::get($this->formData, '_wp_http_referer')), | |
| 540 | - 'user_id' => get_current_user_id(), | |
| 541 | - 'browser' => $browser->getBrowser(), | |
| 542 | - 'device' => $browser->getPlatform(), | |
| 543 | - 'ip' => $ipAddress, | |
| 544 | - 'created_at' => current_time('mysql'), | |
| 545 | - 'updated_at' => current_time('mysql') | |
| 938 | + 'response' => json_encode($this->formData, JSON_UNESCAPED_UNICODE), | |
| 939 | + 'source_url' => site_url(Arr::get($formData, '_wp_http_referer')), | |
| 940 | + 'user_id' => get_current_user_id(), | |
| 941 | + 'browser' => $browser->getBrowser(), | |
| 942 | + 'device' => $browser->getPlatform(), | |
| 943 | + 'ip' => $ipAddress, | |
| 944 | + 'created_at' => current_time('mysql'), | |
| 945 | + 'updated_at' => current_time('mysql'), | |
| 546 | 946 | ]; |
| 947 | + | |
| 948 | + $response = apply_filters_deprecated( | |
| 949 | + 'fluentform_filter_insert_data', | |
| 950 | + [ | |
| 951 | + $response | |
| 952 | + ], | |
| 953 | + FLUENTFORM_FRAMEWORK_UPGRADE, | |
| 954 | + 'fluentform/filter_insert_data', | |
| 955 | + 'Use fluentform/filter_insert_data instead of fluentform_filter_insert_data.' | |
| 956 | + ); | |
| 547 | 957 | |
| 548 | - return apply_filters('fluentform_filter_insert_data', $response); | |
| 958 | + return apply_filters('fluentform/filter_insert_data', $response); | |
| 549 | 959 | } |
| 550 | 960 | |
| 551 | 961 | /** |
| 552 | 962 | * Delegate the validation rules & messages to the |
| @@ -551,10 +961,11 @@ | ||
| 551 | 961 | /** |
| 552 | 962 | * Delegate the validation rules & messages to the |
| 553 | 963 | * ones that the validation library recognizes. |
| 554 | 964 | * |
| 555 | - * @param $rules | |
| 556 | - * @param $messages | |
| 965 | + * @param $rules | |
| 966 | + * @param $messages | |
| 967 | + * | |
| 557 | 968 | * @return array |
| 558 | 969 | */ |
| 559 | 970 | protected function delegateValidations($rules, $messages, $search = [], $replace = []) |
| 560 | 971 | { |
| @@ -573,5 +984,41 @@ | ||
| 573 | 984 | |
| 574 | 985 | return [$rules, $messages]; |
| 575 | 986 | } |
| 576 | 987 | |
| 988 | + /** | |
| 989 | + * Prevents malicious attacks when the submission | |
| 990 | + * count exceeds in an allowed interval. | |
| 991 | + */ | |
| 992 | + public function preventMaliciousAttacks() | |
| 993 | + { | |
| 994 | + $prevent = apply_filters('fluentform/prevent_malicious_attacks', true, $this->form->id); | |
| 995 | + | |
| 996 | + if ($prevent) { | |
| 997 | + $maxSubmissionCount = apply_filters('fluentform/max_submission_count', 5, $this->form->id); | |
| 998 | + $minSubmissionInterval = apply_filters('fluentform/min_submission_interval', 30, $this->form->id); | |
| 999 | + | |
| 1000 | + $interval = date('Y-m-d H:i:s', strtotime(current_time('mysql')) - $minSubmissionInterval); | |
| 1001 | + | |
| 1002 | + $clientIp = sanitize_text_field($this->app->request->getIp()); | |
| 1003 | + $submissionCount = wpFluent()->table('fluentform_submissions') | |
| 1004 | + ->where('status', '!=', 'trashed') | |
| 1005 | + ->where('ip', $clientIp ?: '0.0.0.0') | |
| 1006 | + ->where('created_at', '>=', $interval) | |
| 1007 | + ->count(); | |
| 1008 | + | |
| 1009 | + if ($submissionCount >= $maxSubmissionCount) { | |
| 1010 | + wp_send_json([ | |
| 1011 | + 'errors' => [ | |
| 1012 | + 'restricted' => [ | |
| 1013 | + apply_filters( | |
| 1014 | + 'fluentform/too_many_requests', | |
| 1015 | + __('Too Many Requests.', 'fluentform'), | |
| 1016 | + $this->form->id | |
| 1017 | + ), | |
| 1018 | + ], | |
| 1019 | + ], | |
| 1020 | + ], 429); | |
| 1021 | + } | |
| 1022 | + } | |
| 1023 | + } | |
| 577 | 1024 | } |