Overview

Namespaces

  • None
  • Quform
    • Traduttore_Registry

Classes

  • Quform
  • Quform_Admin_InsertForm
  • Quform_Admin_Page
  • Quform_Admin_Page_Controller
  • Quform_Admin_Page_Dashboard
  • Quform_Admin_Page_Entries
  • Quform_Admin_Page_Entries_Edit
  • Quform_Admin_Page_Entries_List
  • Quform_Admin_Page_Entries_View
  • Quform_Admin_Page_Factory
  • Quform_Admin_Page_Forms_Add
  • Quform_Admin_Page_Forms_Edit
  • Quform_Admin_Page_Forms_List
  • Quform_Admin_Page_Help
  • Quform_Admin_Page_Preview
  • Quform_Admin_Page_Settings
  • Quform_Admin_Page_Tools
  • Quform_Admin_Page_Tools_ExportEntries
  • Quform_Admin_Page_Tools_ExportForm
  • Quform_Admin_Page_Tools_Home
  • Quform_Admin_Page_Tools_ImportForm
  • Quform_Admin_Page_Tools_Migrate
  • Quform_Admin_Page_Tools_Uninstall
  • Quform_Api
  • Quform_Block
  • Quform_Builder
  • Quform_Captcha
  • Quform_ClassLoader
  • Quform_Confirmation
  • Quform_Container
  • Quform_Dashboard_Widget
  • Quform_Dispatcher
  • Quform_Element
  • Quform_Element_Captcha
  • Quform_Element_Checkbox
  • Quform_Element_Column
  • Quform_Element_Container
  • Quform_Element_Container_Iterator
  • Quform_Element_Date
  • Quform_Element_Email
  • Quform_Element_Factory
  • Quform_Element_Field
  • Quform_Element_File
  • Quform_Element_Group
  • Quform_Element_Hidden
  • Quform_Element_Honeypot
  • Quform_Element_Html
  • Quform_Element_Multi
  • Quform_Element_Multiselect
  • Quform_Element_Name
  • Quform_Element_Page
  • Quform_Element_Password
  • Quform_Element_Radio
  • Quform_Element_Recaptcha
  • Quform_Element_Row
  • Quform_Element_Select
  • Quform_Element_Submit
  • Quform_Element_Text
  • Quform_Element_Textarea
  • Quform_Element_Time
  • Quform_Entry_Controller
  • Quform_Entry_Exporter
  • Quform_Entry_List_Settings
  • Quform_Entry_List_Table
  • Quform_Entry_Processor
  • Quform_Entry_UserSearcher
  • Quform_Filter_Abstract
  • Quform_Filter_Alpha
  • Quform_Filter_AlphaNumeric
  • Quform_Filter_Digits
  • Quform_Filter_Regex
  • Quform_Filter_Static
  • Quform_Filter_StripTags
  • Quform_Filter_Trim
  • Quform_Form
  • Quform_Form_Controller
  • Quform_Form_Exporter
  • Quform_Form_Factory
  • Quform_Form_Importer
  • Quform_Form_Iterator
  • Quform_Form_List_Settings
  • Quform_Form_List_Table
  • Quform_Form_Processor
  • Quform_License
  • Quform_Migrator
  • Quform_NonceRefresher
  • Quform_Notification
  • Quform_Notification_Resender
  • Quform_Options
  • Quform_Permissions
  • Quform_Repository
  • Quform_ScriptLoader
  • Quform_Session
  • Quform_Settings
  • Quform_Shortcode
  • Quform_Themes
  • Quform_TokenReplacer
  • Quform_Toolbar
  • Quform_Translations
  • Quform_Updater
  • Quform_Upgrader
  • Quform_Uploader
  • Quform_Validator_Abstract
  • Quform_Validator_Alpha
  • Quform_Validator_AlphaNumeric
  • Quform_Validator_Array
  • Quform_Validator_Captcha
  • Quform_Validator_Date
  • Quform_Validator_Digits
  • Quform_Validator_Duplicate
  • Quform_Validator_Email
  • Quform_Validator_FileUpload
  • Quform_Validator_GreaterThan
  • Quform_Validator_Honeypot
  • Quform_Validator_Identical
  • Quform_Validator_InArray
  • Quform_Validator_Length
  • Quform_Validator_LessThan
  • Quform_Validator_Recaptcha
  • Quform_Validator_Regex
  • Quform_Validator_Required
  • Quform_Validator_Static
  • Quform_Validator_Time
  • Quform_View
  • Quform_ViewFactory
  • Quform_Widget_Form
  • Quform_Widget_Popup

Interfaces

  • Quform_Attachable
  • Quform_Element_Editable
  • Quform_Filter_Interface
  • Quform_Validator_Interface

Constants

  • Quform\Traduttore_Registry\TRANSIENT_KEY_PLUGIN
  • Quform\Traduttore_Registry\TRANSIENT_KEY_THEME

Functions

  • Quform\Traduttore_Registry\add_project
  • Quform\Traduttore_Registry\clean_translations_cache
  • Quform\Traduttore_Registry\get_available_locales
  • Quform\Traduttore_Registry\get_installed_translations
  • Quform\Traduttore_Registry\get_translations
  • Quform\Traduttore_Registry\register_clean_translations_cache
  • Quform\Traduttore_Registry\sanitize_date
  • Overview
  • Namespace
  • Class
  1: <?php
  2: 
  3: /**
  4:  * @copyright Copyright (c) 2009-2022 ThemeCatcher (https://www.themecatcher.net)
  5:  */
  6: class Quform_Form_Processor
  7: {
  8:     /**
  9:      * @var Quform_Repository
 10:      */
 11:     protected $repository;
 12: 
 13:     /**
 14:      * @var Quform_Session
 15:      */
 16:     protected $session;
 17: 
 18:     /**
 19:      * @var Quform_Uploader
 20:      */
 21:     protected $uploader;
 22: 
 23:     /**
 24:      * @var Quform_Options
 25:      */
 26:     protected $options;
 27: 
 28:     /**
 29:      * @param  Quform_Repository $repository
 30:      * @param  Quform_Session    $session
 31:      * @param  Quform_Uploader   $uploader
 32:      * @param  Quform_Options    $options
 33:      */
 34:     public function __construct(
 35:         Quform_Repository $repository,
 36:         Quform_Session $session,
 37:         Quform_Uploader $uploader,
 38:         Quform_Options $options
 39:     ) {
 40:         $this->repository = $repository;
 41:         $this->session = $session;
 42:         $this->uploader = $uploader;
 43:         $this->options = $options;
 44:     }
 45: 
 46:     /**
 47:      * Process the given form
 48:      *
 49:      * @param   Quform_Form  $form
 50:      * @return  array
 51:      */
 52:     public function process(Quform_Form $form)
 53:     {
 54:         // Strip slashes from the submitted data (WP adds them automatically)
 55:         $_POST = wp_unslash($_POST);
 56: 
 57:         // CSRF check
 58:         if ($this->options->get('csrfProtection') && ( ! isset($_POST['quform_csrf_token']) || $this->session->getToken() != $_POST['quform_csrf_token'])) {
 59:             return apply_filters(
 60:                 'quform_csrf_failure_response',
 61:                 array(
 62:                     'type' => 'error',
 63:                     'error' => array(
 64:                         'enabled' => true,
 65:                         'title' => __('An error occurred', 'quform'),
 66:                         'content' => __('Refresh the page and try again.', 'quform')
 67:                     )
 68:                 ),
 69:                 $form
 70:             );
 71:         }
 72: 
 73:         // Pre-process hooks
 74:         $result = apply_filters('quform_pre_process', array(), $form);
 75:         $result = apply_filters('quform_pre_process_' . $form->getId(), $result, $form);
 76: 
 77:         if (is_array($result) && ! empty($result)) {
 78:             return $result;
 79:         }
 80: 
 81:         $result = $this->checkEntryLimits( $form);
 82: 
 83:         if (is_array($result) && ! empty($result)) {
 84:             return $result;
 85:         }
 86: 
 87:         $result = $this->checkFormSchedule( $form);
 88: 
 89:         if (is_array($result) && ! empty($result)) {
 90:             return $result;
 91:         }
 92: 
 93:         $this->uploader->mergeSessionFiles($form);
 94: 
 95:         // Set the form element values
 96:         $form->setValues($_POST, true);
 97: 
 98:         $result = apply_filters('quform_post_set_form_values', array(), $form);
 99:         $result = apply_filters('quform_post_set_form_values_' . $form->getId(), $result, $form);
100: 
101:         if (is_array($result) && ! empty($result)) {
102:             return $result;
103:         }
104: 
105:         // Calculate which elements are hidden by conditional logic and which groups are empty
106:         $form->calculateElementVisibility();
107: 
108:         $form->setCurrentPageById((int) $_POST['quform_current_page_id']);
109: 
110:         // Pre-validate action hooks
111:         $result = apply_filters('quform_pre_validate', array(), $form);
112:         $result = apply_filters('quform_pre_validate_' . $form->getId(), $result, $form);
113: 
114:         if (is_array($result) && ! empty($result)) {
115:             return $result;
116:         }
117: 
118:         // Moving between pages
119:         if ($form->hasPages()) {
120:             if (isset($_POST['quform_submit']) && $_POST['quform_submit'] === 'back') {
121:                 // We want to go to a previous page, so don't validate just find the closest page that isn't hidden by CL
122:                 return array('type' => 'page', 'page' => $form->getNextPageId(true));
123:             } else {
124:                 // If the current page is valid and there is a next page not hidden by CL, return the next page ID
125:                 if (($nextPageId = $form->getNextPageId()) !== null) {
126:                     if ($form->getCurrentPage()->isValid()) {
127:                         return array('type' => 'page', 'page' => $nextPageId);
128:                     } else {
129:                         // Return current page errors
130:                         return array('type' => 'error', 'error' => $form->getGlobalError(), 'errors' => $form->getCurrentPage()->getErrors(), 'page' => $form->getCurrentPage()->getId());
131:                     }
132:                 }
133:             }
134:         }
135: 
136:         // This is the last page so validate the entire form
137:         list($valid, $firstErrorPage) = $form->isValid();
138: 
139:         if ($valid) {
140:             // Post-validate action hooks
141:             $result = apply_filters('quform_post_validate', array(), $form);
142:             $result = apply_filters('quform_post_validate_' . $form->getId(), $result, $form);
143: 
144:             if (is_array($result) && ! empty($result)) {
145:                 return $result;
146:             }
147: 
148:             // Save the entry
149:             $entryId = $this->saveEntry($form);
150:             $form->setEntryId($entryId);
151: 
152:             $result = apply_filters('quform_post_set_entry_id', array(), $form);
153:             $result = apply_filters('quform_post_set_entry_id_' . $form->getId(), $result, $form);
154: 
155:             if (is_array($result) && ! empty($result)) {
156:                 return $result;
157:             }
158: 
159:             // Process any uploads
160:             $this->uploader->process($form);
161: 
162:             // Save the entry data
163:             $this->saveEntryData($entryId, $form);
164: 
165:             $result = apply_filters('quform_post_save_entry_data', array(), $form);
166:             $result = apply_filters('quform_post_save_entry_data_' . $form->getId(), $result, $form);
167: 
168:             if (is_array($result) && ! empty($result)) {
169:                 return $result;
170:             }
171: 
172:             // Send notification emails
173:             $this->sendNotifications($form);
174: 
175:             // Set the confirmation to use for this submission
176:             $form->setConfirmation();
177: 
178:             // Save to custom database table
179:             $this->saveToCustomDatabase($form);
180: 
181:             // Clear session data for this form
182:             if ($this->session->has($form->getSessionKey())) {
183:                 $this->session->forget($form->getSessionKey());
184:             }
185: 
186:             // Post-process action hooks
187:             $result = apply_filters('quform_post_process', array(), $form);
188:             $result = apply_filters('quform_post_process_' . $form->getId(), $result, $form);
189: 
190:             if (is_array($result) && ! empty($result)) {
191:                 return $result;
192:             }
193: 
194:             $result = array(
195:                 'type' => 'success',
196:                 'confirmation' => $form->getConfirmation()->getData()
197:             );
198:         } else {
199:             $result = array(
200:                 'type' => 'error',
201:                 'error' => $form->getGlobalError(),
202:                 'errors' => $form->getErrors(),
203:                 'page' => $firstErrorPage->getId()
204:             );
205:         }
206: 
207:         return $result;
208:     }
209: 
210:     /**
211:      * Check if the current submission exceeds any entry limit
212:      *
213:      * @param   Quform_Form  $form  The current form instance
214:      * @return  true|array          Return true to proceed with form processing, or a response array to show an error
215:      */
216:     protected function checkEntryLimits(Quform_Form $form) {
217:         if ( ! $this->options->get('saveEntries') || ! $form->config('saveEntry')) {
218:             return true;
219:         }
220: 
221:         if (apply_filters('quform_bypass_entry_limits', current_user_can('quform_edit_forms'), $form)) {
222:             return true;
223:         }
224: 
225:         if ($form->config('oneEntryPerUser')) {
226:             $entryExists = false;
227: 
228:             if ($form->config('oneEntryPer') == 'logged-in-user') {
229:                 if (is_user_logged_in()) {
230:                     $entryExists = $this->repository->entryExistsByFormIdAndCreatedBy(
231:                         $form->getId(),
232:                         get_current_user_id()
233:                     );
234:                 }
235:             } elseif ($form->config('oneEntryPer') == 'ip-address') {
236:                 $entryExists = $this->repository->entryExistsByFormIdAndIpAddress(
237:                     $form->getId(),
238:                     Quform::getClientIp()
239:                 );
240:             }
241: 
242:             $entryExists = apply_filters('quform_one_entry_per_user_entry_exists', $entryExists, $form);
243: 
244:             if ($entryExists) {
245:                 return apply_filters('quform_one_entry_per_user_error', array(
246:                     'type' => 'error',
247:                     'error' => array(
248:                         'enabled' => true,
249:                         'title' => '',
250:                         'content' => $form->getTranslation(
251:                             'onlyOneSubmissionAllowed',
252:                             __('Only one submission is allowed.', 'quform')
253:                         )
254:                     )
255:                 ), $form);
256:             }
257:         }
258: 
259:         if ($form->config('limitEntries') && is_numeric($form->config('entryLimit')) && $form->config('entryLimit') > 0) {
260:             $entryCount = $this->repository->getEntryCount($form->getId());
261: 
262:             $entryCount = apply_filters('quform_entry_count', $entryCount, $form);
263:             $entryCount = apply_filters('quform_entry_count_' . $form->getId(), $entryCount, $form);
264: 
265:             if ($entryCount >= $form->config('entryLimit')) {
266:                 return apply_filters('quform_entry_limit_reached_error', array(
267:                     'type' => 'error',
268:                     'error' => array(
269:                         'enabled' => true,
270:                         'title' => '',
271:                         'content' => $form->getTranslation(
272:                             'thisFormIsCurrentlyClosed',
273:                             __('This form is currently closed for submissions.', 'quform')
274:                         )
275:                     )
276:                 ), $form);
277:             }
278:         }
279: 
280:         return true;
281:     }
282: 
283:     /**
284:      * Check if the current submission is within the schedule
285:      *
286:      * @param   Quform_Form  $form  The current form instance
287:      * @return  true|array          Return true to proceed with form processing, or a response array to show an error
288:      */
289:     public function checkFormSchedule(Quform_Form $form)
290:     {
291:         if (
292:             ! $form->config('enableSchedule') ||
293:             (
294:                 ! Quform::isNonEmptyString('scheduleStart') &&
295:                 ! Quform::isNonEmptyString('scheduleEnd')
296:             )
297:         ) {
298:             return true;
299:         }
300: 
301:         if (apply_filters('quform_bypass_form_schedule', current_user_can('quform_edit_forms'), $form)) {
302:             return true;
303:         }
304: 
305:         try {
306:             $now = new DateTime('now', new DateTimeZone('UTC'));
307: 
308:             if (Quform::isNonEmptyString($form->config('scheduleStart'))) {
309:                 $start = DateTime::createFromFormat('Y-m-d H:i:s', $form->config('scheduleStart'));
310: 
311:                 if ($start instanceof DateTime && $now < $start) {
312:                     return apply_filters('quform_schedule_start_error', array(
313:                         'type' => 'error',
314:                         'error' => array(
315:                             'enabled' => true,
316:                             'title' => '',
317:                             'content' => $form->getTranslation(
318:                                 'formIsNotYetOpenForSubmissions',
319:                                 __('This form is not yet open for submissions.', 'quform')
320:                             )
321:                         )
322:                     ), $form);
323:                 }
324:             }
325: 
326:             if (Quform::isNonEmptyString($form->config('scheduleEnd'))) {
327:                 $end = DateTime::createFromFormat('Y-m-d H:i:s', $form->config('scheduleEnd'));
328: 
329:                 if ($end instanceof DateTime && $now > $end) {
330:                     return apply_filters('quform_schedule_end_error', array(
331:                         'type' => 'error',
332:                         'error' => array(
333:                             'enabled' => true,
334:                             'title' => '',
335:                             'content' => $form->getTranslation(
336:                                 'formIsNoLongerOpenForSubmissions',
337:                                 __('This form is no longer open for submissions.', 'quform')
338:                             )
339:                         )
340:                     ), $form);
341:                 }
342:             }
343:         } catch (Exception $e) {
344:             // Ignore exception, continue processing
345:         }
346: 
347:         return true;
348:     }
349: 
350:     /**
351:      * @param   Quform_Form  $form
352:      * @return  $this
353:      */
354:     protected function sendNotifications(Quform_Form $form)
355:     {
356:         foreach ($form->getNotifications() as $notification) {
357:             if ( ! $notification->config('enabled')) {
358:                 continue;
359:             }
360: 
361:             if ($notification->config('logicEnabled') && count($notification->config('logicRules'))) {
362:                 if ($form->checkLogicAction($notification->config('logicAction'), $notification->config('logicMatch'), $notification->config('logicRules'))) {
363:                     $notification->send();
364:                 }
365:             } else {
366:                 $notification->send();
367:             }
368:         }
369: 
370:         return $this;
371:     }
372: 
373:     /**
374:      * Create a new entry and return the new entry ID
375:      *
376:      * @param   Quform_Form  $form
377:      * @return  int|null
378:      */
379:     protected function saveEntry(Quform_Form $form)
380:     {
381:         if ( ! $this->options->get('saveEntries') || ! $form->config('saveEntry')) {
382:             return null;
383:         }
384: 
385:         $currentTime = Quform::date('Y-m-d H:i:s', null, new DateTimeZone('UTC'));
386: 
387:         $entry = array(
388:             'form_id'           => $form->getId(),
389:             'ip'                => $this->options->get('saveIpAddresses') ? Quform::substr(Quform::getClientIp(), 0, 45) : '',
390:             'form_url'          => isset($_POST['form_url']) ? Quform::substr($_POST['form_url'], 0, 512) : '',
391:             'referring_url'     => isset($_POST['referring_url']) ? Quform::substr($_POST['referring_url'], 0, 512) : '',
392:             'post_id'           => is_numeric($postId = Quform::get($_POST, 'post_id')) && $postId > 0 ? (int) $postId : null,
393:             'created_by'        => is_user_logged_in() ? (int) Quform::getUserProperty('ID') : null,
394:             'created_at'        => $currentTime,
395:             'updated_at'        => $currentTime,
396:         );
397: 
398:         $entry = $this->repository->saveEntry($entry);
399: 
400:         return $entry['id'];
401:     }
402: 
403:     /**
404:      * Save the entry data
405:      *
406:      * @param  int          $entryId
407:      * @param  Quform_Form  $form
408:      */
409:     protected function saveEntryData($entryId, Quform_Form $form)
410:     {
411:         if ( ! ($entryId > 0) || ! $this->options->get('saveEntries') || ! $form->config('saveEntry')) {
412:             return;
413:         }
414: 
415:         $data = array();
416: 
417:         foreach ($form->getRecursiveIterator() as $element) {
418:             if ($element->config('saveToDatabase') && ! $element->isConditionallyHidden()) {
419:                 if ( ! $element->isEmpty()) {
420:                     $data[$element->getId()] = $element->getValueForStorage();
421:                 }
422:             }
423:         }
424: 
425:         if (count($data)) {
426:             $this->repository->saveEntryData($entryId, $data);
427:         }
428:     }
429: 
430:     /**
431:      * Save to the custom database table if configured
432:      *
433:      * @param Quform_Form $form
434:      */
435:     protected function saveToCustomDatabase(Quform_Form $form)
436:     {
437:         if ( ! $form->config('databaseEnabled') ||
438:              ! count($columns = $form->config('databaseColumns')) ||
439:              ! Quform::isNonEmptyString($table = $form->config('databaseTable'))
440:         ) {
441:             return;
442:         }
443: 
444:         $data = array();
445:         foreach ($columns as $column) {
446:             if ( ! Quform::isNonEmptyString($column['name'])) {
447:                 continue;
448:             }
449: 
450:             $data[$column['name']] = $form->replaceVariables($column['value']);
451:         }
452: 
453:         if ($form->config('databaseWordpress')) {
454:             global $wpdb;
455:             $wpdb->insert($table, $data);
456:         } else {
457:             $customWpdb = new wpdb(
458:                 $form->config('databaseUsername'),
459:                 $form->config('databasePassword'),
460:                 $form->config('databaseDatabase'),
461:                 $form->config('databaseHost')
462:             );
463: 
464:             $customWpdb->insert($table, $data);
465:         }
466:     }
467: }
468: 
API documentation generated by ApiGen