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_Controller
  7: {
  8:     /**
  9:      * @var Quform_Repository
 10:      */
 11:     protected $repository;
 12: 
 13:     /**
 14:      * @var Quform_Form_Factory
 15:      */
 16:     protected $formFactory;
 17: 
 18:     /**
 19:      * @var Quform_Form_Processor
 20:      */
 21:     protected $processor;
 22: 
 23:     /**
 24:      * @var Quform_Session
 25:      */
 26:     protected $session;
 27: 
 28:     /**
 29:      * @var Quform_Uploader
 30:      */
 31:     protected $uploader;
 32: 
 33:     /*
 34:      * Form counter to differentiate multiple instances of the same form
 35:      *
 36:      * @var int
 37:      */
 38:     protected $count = 0;
 39: 
 40:     /**
 41:      * Store used unique IDs to avoid conflicts
 42:      *
 43:      * @var array
 44:      */
 45:     protected $uniqueIds = array();
 46: 
 47:     /**
 48:      * @param  Quform_Form_Factory   $formFactory
 49:      * @param  Quform_Repository     $repository
 50:      * @param  Quform_Form_Processor $processor
 51:      * @param  Quform_Session        $session
 52:      * @param  Quform_Uploader       $uploader
 53:      */
 54:     public function __construct(Quform_Form_Factory $formFactory, Quform_Repository $repository,
 55:                                 Quform_Form_Processor $processor, Quform_Session $session, Quform_Uploader $uploader)
 56:     {
 57:         $this->formFactory = $formFactory;
 58:         $this->repository = $repository;
 59:         $this->processor = $processor;
 60:         $this->session = $session;
 61:         $this->uploader = $uploader;
 62:     }
 63: 
 64:     /**
 65:      * Display the form, also handle non-Ajax form processing
 66:      *
 67:      * @param   array        $options
 68:      * @return  string|void
 69:      */
 70:     public function form(array $options = array())
 71:     {
 72:         $options = wp_parse_args($options, array(
 73:             'id' => '',
 74:             'values' => '',
 75:             'content' => '',
 76:             'popup' => false,
 77:             'options' => '',
 78:             'width' => '',
 79:             'show_title' => true,
 80:             'show_description' => true
 81:         ));
 82: 
 83:         $config = $this->repository->getConfig((int) $options['id']);
 84: 
 85:         if ( ! is_array($config)) {
 86:             return;
 87:         }
 88: 
 89:         $this->count++;
 90:         $config['count'] = $this->count;
 91: 
 92:         $processingThisForm = Quform::isPostRequest() && Quform::get($_POST, 'quform_form_id') == $config['id'] && Quform::get($_POST, 'quform_count') == $this->count;
 93: 
 94:         if ($processingThisForm && Quform_Form::isValidUniqueId(Quform::get($_POST, 'quform_form_uid'))) {
 95:             $uniqueId = Quform::get($_POST, 'quform_form_uid');
 96:         } else {
 97:             $uniqueId = $this->generateUniqueId();
 98:         }
 99: 
100:         $config['uniqueId'] = $uniqueId;
101:         $this->uniqueIds[] = $uniqueId;
102: 
103:         if (is_string($options['values'])) {
104:             $options['values'] = join('&', explode('&amp;', $options['values']));
105:         }
106: 
107:         $config['dynamicValues'] = $options['values'];
108: 
109:         $form = $this->formFactory->create($config);
110: 
111:         if ( ! ($form instanceof Quform_Form) || $form->config('trashed')) {
112:             return;
113:         }
114: 
115:         if ( ! $form->isActive()) {
116:             return do_shortcode($form->config('inactiveMessage'));
117:         }
118: 
119:         $output = '';
120: 
121:         if ($processingThisForm) {
122:             $result = $this->processor->process($form);
123: 
124:             if ($result['type'] == 'page') {
125:                 $this->uploader->saveUploadedFilesIntoSession($form);
126:                 $form->setCurrentPageById($result['page']);
127:             } else if ($result['type'] == 'success') {
128:                 $confirmation = $result['confirmation'];
129: 
130:                 switch ($confirmation['type']) {
131:                     case 'message':
132:                         // Show the success message and reset the form values
133:                         $form->setSubmitted(true);
134:                         $form->reset();
135:                         break;
136:                     case 'message-redirect-page':
137:                     case 'message-redirect-url':
138:                         // Show the success message
139:                         $form->setSubmitted(true);
140:                         $output .= sprintf('<meta http-equiv="refresh" content="%d;URL=\'%s\'">', esc_attr($confirmation['redirectDelay']), esc_url($confirmation['redirectUrl']));
141:                         break;
142:                     case 'redirect-page':
143:                     case 'redirect-url':
144:                         $output .= sprintf('<meta http-equiv="refresh" content="0;URL=\'%s\'">', esc_url($confirmation['redirectUrl']));
145:                         break;
146:                     case 'reload':
147:                         $output .= '<meta http-equiv="refresh" content="0">';
148:                         break;
149:                 }
150:             } else if ($result['type'] == 'error') {
151:                 // If the first error is on a previous page, go there
152:                 if (isset($result['page']) && $form->getCurrentPage()->getId() != $result['page']) {
153:                     $form->setCurrentPageById($result['page']);
154:                 }
155: 
156:                 // Set up the non-JS error global form error message
157:                 if (isset($result['error']) && is_array($result['error'])) {
158:                     if (isset($result['error']['enabled']) && is_bool($result['error']['enabled'])) {
159:                         $form->setConfig('errorEnabled', $result['error']['enabled']);
160:                     }
161: 
162:                     if (isset($result['error']['title']) && is_string($result['error']['title'])) {
163:                         $form->setConfig('errorTitle', $result['error']['title']);
164:                     }
165: 
166:                     if (isset($result['error']['content']) && is_string($result['error']['content'])) {
167:                         $form->setConfig('errorContent', $result['error']['content']);
168:                     }
169:                 }
170: 
171:                 // Show the global form error message if enabled
172:                 if ($form->config('errorEnabled')) {
173:                     $form->setShowGlobalError(true);
174:                 }
175:             }
176:         }
177: 
178:         $outputOverride = '';
179: 
180:         if (
181:             !apply_filters('quform_bypass_entry_limits', current_user_can('quform_edit_forms'), $form) &&
182:             $form->config('limitEntries') &&
183:             is_numeric($form->config('entryLimit')) &&
184:             $form->config('entryLimit') > 0
185:         ) {
186:             $entryCount = $this->repository->getEntryCount($form->getId());
187: 
188:             $entryCount = apply_filters('quform_entry_count', $entryCount, $form);
189:             $entryCount = apply_filters('quform_entry_count_' . $form->getId(), $entryCount, $form);
190: 
191:             if ($entryCount >= $form->config('entryLimit')) {
192:                 $outputOverride = do_shortcode(shortcode_unautop(wpautop($form->config('entryLimitReachedMessage'))));
193:             }
194:         }
195: 
196:         if (
197:             !apply_filters('quform_bypass_form_schedule', current_user_can('quform_edit_forms'), $form) &&
198:             $form->config('enableSchedule')
199:         ) {
200:             try {
201:                 $now = new DateTime('now', new DateTimeZone('UTC'));
202: 
203:                 if (Quform::isNonEmptyString($form->config('scheduleStart'))) {
204:                     $start = DateTime::createFromFormat('Y-m-d H:i:s', $form->config('scheduleStart'));
205: 
206:                     if ($start instanceof DateTime && $now < $start) {
207:                         $outputOverride = do_shortcode(shortcode_unautop(wpautop($form->config('scheduleStartMessage'))));
208:                     }
209:                 }
210: 
211:                 if (Quform::isNonEmptyString($form->config('scheduleEnd'))) {
212:                     $end = DateTime::createFromFormat('Y-m-d H:i:s', $form->config('scheduleEnd'));
213: 
214:                     if ($end instanceof DateTime && $now > $end) {
215:                         $outputOverride = do_shortcode(shortcode_unautop(wpautop($form->config('scheduleEndMessage'))));
216:                     }
217:                 }
218:             } catch (Exception $e) {
219:                 // Ignore exception, show the form as normal
220:             }
221:         }
222: 
223:         $output .= $options['popup'] ? $form->renderPopup($options, $outputOverride) : $form->render($options, $outputOverride);
224: 
225:         return $output;
226:     }
227: 
228:     /**
229:      * Get the entry limit for the given form ID
230:      *
231:      * @param   int     $formId  The ID of the form
232:      * @return  string           The maximum entry limit number, an empty string or infinity sign
233:      */
234:     public function getEntryLimit($formId) {
235:         $config = $this->repository->getConfig($formId);
236: 
237:         if ( ! is_array($config)) {
238:             return '';
239:         }
240: 
241:         $form = $this->formFactory->create($config);
242: 
243:         if ( ! ($form instanceof Quform_Form) || $form->config('trashed')) {
244:             return '';
245:         }
246: 
247:         if ($form->config('limitEntries') && is_numeric($form->config('entryLimit')) && $form->config('entryLimit') > 0) {
248:             return $form->config('entryLimit');
249:         }
250: 
251:         return '∞';
252:     }
253: 
254:     /**
255:      * Get the entry count for the given form ID
256:      *
257:      * @param   int  $formId  The ID of the form
258:      * @return  int           The number of entries
259:      */
260:     public function getEntryCount($formId) {
261:         $config = $this->repository->getConfig($formId);
262: 
263:         if ( ! is_array($config)) {
264:             return '';
265:         }
266: 
267:         $form = $this->formFactory->create($config);
268: 
269:         if ( ! ($form instanceof Quform_Form) || $form->config('trashed')) {
270:             return '';
271:         }
272: 
273:         $entryCount = $this->repository->getEntryCount($formId);
274: 
275:         $entryCount = apply_filters('quform_entry_count', $entryCount, $form);
276:         $entryCount = apply_filters('quform_entry_count_' . $form->getId(), $entryCount, $form);
277: 
278:         return $entryCount;
279:     }
280: 
281:     /**
282:      * Get the number of entries remaining for the given form ID
283:      *
284:      * @param   int         $formId  The ID of the form
285:      * @return  int|string           The number of entries remaining, an empty string or infinity sign
286:      */
287:     public function getEntriesRemaining($formId) {
288:         $config = $this->repository->getConfig($formId);
289: 
290:         if ( ! is_array($config)) {
291:             return '';
292:         }
293: 
294:         $form = $this->formFactory->create($config);
295: 
296:         if ( ! ($form instanceof Quform_Form) || $form->config('trashed')) {
297:             return '';
298:         }
299: 
300:         if ($form->config('limitEntries') && is_numeric($form->config('entryLimit')) && $form->config('entryLimit') > 0) {
301:             $entryCount = $this->repository->getEntryCount($formId);
302: 
303:             $entryCount = apply_filters('quform_entry_count', $entryCount, $form);
304:             $entryCount = apply_filters('quform_entry_count_' . $form->getId(), $entryCount, $form);
305: 
306:             $entryLimit = (int) $form->config('entryLimit');
307: 
308:             return $entryCount < $entryLimit ? $entryLimit - $entryCount : 0;
309:         }
310: 
311:         return '∞';
312:     }
313: 
314:     /**
315:      * Hook entry point for submitting the form via Ajax
316:      */
317:     public function process()
318:     {
319:         if ( ! Quform::isPostRequest() || ! isset($_POST['quform_ajax'])) {
320:             return;
321:         }
322: 
323:         $this->validateProcessRequest();
324:         $this->handleProcessRequest();
325:     }
326: 
327:     /**
328:      * Validate the request for submitting the form via Ajax
329:      */
330:     protected function validateProcessRequest()
331:     {
332:         if ( ! isset($_POST['quform_form_id'], $_POST['quform_form_uid']) ||
333:              ! is_numeric($_POST['quform_form_id']) ||
334:              ! Quform_Form::isValidUniqueId($_POST['quform_form_uid'])
335:         ) {
336:             $this->sendEncodedResponse(array(
337:                 'type' => 'error',
338:                 'error' => array(
339:                     'enabled' => true,
340:                     'title' => __('An error occurred', 'quform'),
341:                     'content' => __('Bad request', 'quform')
342:                 )
343:             ));
344:         }
345:     }
346: 
347:     /**
348:      * Handle the request for submitting the form via Ajax
349:      */
350:     protected function handleProcessRequest()
351:     {
352:         $config = $this->repository->getConfig((int) $_POST['quform_form_id']);
353: 
354:         if ( ! is_array($config)) {
355:             $this->sendEncodedResponse(array(
356:                 'type' => 'error',
357:                 'error' => array(
358:                     'enabled' => true,
359:                     'title' => __('An error occurred', 'quform'),
360:                     'content' => __('Form not found', 'quform')
361:                 )
362:             ));
363:         }
364: 
365:         $config['uniqueId'] = $_POST['quform_form_uid'];
366: 
367:         $form = $this->formFactory->create($config);
368: 
369:         if ( ! ($form instanceof Quform_Form) || $form->config('trashed')) {
370:             $this->sendEncodedResponse(array(
371:                 'type' => 'error',
372:                 'error' => array(
373:                     'enabled' => true,
374:                     'title' => __('An error occurred', 'quform'),
375:                     'content' => __('Form does not exist', 'quform')
376:                 )
377:             ));
378:         }
379: 
380:         if ( ! $form->isActive()) {
381:             $this->sendEncodedResponse(array(
382:                 'type' => 'error',
383:                 'error' => array(
384:                     'enabled' => true,
385:                     'title' => __('An error occurred', 'quform'),
386:                     'content' => __('Form is not active', 'quform')
387:                 )
388:             ));
389:         }
390: 
391:         $this->sendEncodedResponse($this->processor->process($form));
392:     }
393: 
394:     /**
395:      * Generate a unique ID that is not currently being used
396:      *
397:      * @return string
398:      */
399:     protected function generateUniqueId()
400:     {
401:         $uniqueId = Quform_Form::generateUniqueId();
402: 
403:         while (in_array($uniqueId, $this->uniqueIds) || $this->session->has(sprintf('quform-%s', $uniqueId))) {
404:             $uniqueId = Quform_Form::generateUniqueId();
405:         }
406: 
407:         return $uniqueId;
408:     }
409: 
410:     /**
411:      * Hook entry point for the support page caching request
412:      */
413:     public function supportPageCaching()
414:     {
415:         $this->validateSupportPageCachingRequest();
416:         $this->handleSupportPageCachingRequest();
417:     }
418: 
419:     /**
420:      * Validate the request to support page caching
421:      */
422:     protected function validateSupportPageCachingRequest()
423:     {
424:         if ( ! isset($_GET['forms']) || ! is_array($_GET['forms'])) {
425:             wp_send_json(array('type' => 'error'));
426:         }
427:     }
428: 
429:     /**
430:      * Handle the request to support page caching
431:      */
432:     protected function handleSupportPageCachingRequest()
433:     {
434:         $forms = array();
435: 
436:         foreach ($_GET['forms'] as $oldUniqueId) {
437:             $forms[$oldUniqueId] = $this->generateUniqueId();
438:         }
439: 
440:         wp_send_json(array(
441:             'type' => 'success',
442:             'token' => $this->session->getToken(),
443:             'forms' => $forms
444:         ));
445:     }
446: 
447:     /**
448:      * JSON encodes the given data and wraps it in a &lt;textarea&gt; tag
449:      *
450:      * Escaping is necessary to counteract the fact that wrapping the JSON response in a textarea decodes HTML entities
451:      *
452:      * @see http://malsup.com/jquery/form/#file-upload
453:      *
454:      * @param array $response
455:      */
456:     protected function sendEncodedResponse($response)
457:     {
458:         if ( ! headers_sent()) {
459:             header('Content-Type: text/html; charset=' . get_option('blog_charset'));
460:         }
461: 
462:         echo '<textarea>' . Quform::escape(wp_json_encode($response)) . '</textarea>';
463: 
464:         // Call the die handler instead of exit to facilitate unit tests
465:         call_user_func(apply_filters('wp_die_ajax_handler', '_ajax_wp_die_handler'), '');
466:     }
467: }
468: 
API documentation generated by ApiGen