1: <?php
2:
3: 4: 5:
6: class Quform_Form_Controller
7: {
8: 9: 10:
11: protected $repository;
12:
13: 14: 15:
16: protected $formFactory;
17:
18: 19: 20:
21: protected $processor;
22:
23: 24: 25:
26: protected $session;
27:
28: 29: 30:
31: protected $uploader;
32:
33: 34: 35: 36: 37:
38: protected $count = 0;
39:
40: 41: 42: 43: 44:
45: protected $uniqueIds = array();
46:
47: 48: 49: 50: 51: 52: 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: 66: 67: 68: 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('&', $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:
133: $form->setSubmitted(true);
134: $form->reset();
135: break;
136: case 'message-redirect-page':
137: case 'message-redirect-url':
138:
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:
152: if (isset($result['page']) && $form->getCurrentPage()->getId() != $result['page']) {
153: $form->setCurrentPageById($result['page']);
154: }
155:
156:
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:
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:
220: }
221: }
222:
223: $output .= $options['popup'] ? $form->renderPopup($options, $outputOverride) : $form->render($options, $outputOverride);
224:
225: return $output;
226: }
227:
228: 229: 230: 231: 232: 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: 256: 257: 258: 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: 283: 284: 285: 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: 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: 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: 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: 396: 397: 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: 412:
413: public function supportPageCaching()
414: {
415: $this->validateSupportPageCachingRequest();
416: $this->handleSupportPageCachingRequest();
417: }
418:
419: 420: 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: 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: 449: 450: 451: 452: 453: 454: 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:
465: call_user_func(apply_filters('wp_die_ajax_handler', '_ajax_wp_die_handler'), '');
466: }
467: }
468: