PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 4.3.6
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v4.3.6
6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 3.6.66 All 195 releases
fluentform / app / Modules / Form / Form.php

Form.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 4.3.6, at app/Modules/Form/Form.php

636 lines 19.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\App\Modules\Form;
4
5 use FluentForm\App\Helpers\Helper;
6 use FluentForm\App\Modules\Acl\Acl;
7 use FluentForm\Framework\Foundation\Application;
8 use FluentForm\Framework\Helpers\ArrayHelper;
9
10 class Form
11 {
12 /**
13 * @var \FluentForm\Framework\Request\Request $request
14 */
15 protected $request;
16
17 /**
18 * Set this value when we need predefined default settings.
19 *
20 * @var array $defaultSettings
21 */
22 protected $defaultSettings;
23
24
25 /**
26 * Set this value when we need predefined default notifications.
27 *
28 * @var array $defaultNotifications
29 */
30 protected $defaultNotifications;
31
32 /**
33 * Set this value when we need predefined form fields.
34 *
35 * @var array $formFields
36 */
37 protected $formFields;
38
39 protected $metas = [];
40
41 protected $formType = 'form';
42
43 protected $hasPayment = 0;
44
45 /**
46 * Form constructor.
47 *
48 * @param \FluentForm\Framework\Foundation\Application $application
49 *
50 * @throws \Exception
51 */
52 public function __construct(Application $application)
53 {
54 $this->request = $application->request;
55 $this->model = wpFluent()->table('fluentform_forms');
56 }
57
58 /**
59 * Get all forms from database
60 *
61 * @return void
62 * @throws \Exception
63 */
64 public function index()
65 {
66 $forms = fluentFormApi('forms')->forms([
67 'search' => $this->request->get('search'),
68 'status' => $this->request->get('status'),
69 'sort_column' => $this->request->get('sort_column', 'id'),
70 'sort_by' => $this->request->get('sort_by', 'DESC'),
71 'per_page' => $this->request->get('per_page', 10),
72 'page' => $this->request->get('page', 1),
73 ]);
74
75 wp_send_json($forms, 200);
76 }
77
78
79 /**
80 * Create a form from backend/editor
81 * @return void|array
82 */
83 public function store($returnJSON = true)
84 {
85 $type = $this->request->get('type', $this->formType);
86 $title = $this->request->get('title', 'My New Form');
87 $status = $this->request->get('status', 'published');
88 $createdBy = get_current_user_id();
89
90 $now = current_time('mysql');
91
92 $insertData = [
93 'title' => $title,
94 'type' => $type,
95 'status' => $status,
96 'created_by' => $createdBy,
97 'created_at' => $now,
98 'updated_at' => $now
99 ];
100
101 if ($this->formFields) {
102 $insertData['form_fields'] = $this->formFields;
103 }
104
105 if($this->hasPayment) {
106 $insertData['has_payment'] = $this->hasPayment;
107 }
108
109 $formId = $this->model->insert($insertData);
110
111 // Rename the form name here
112 wpFluent()->table('fluentform_forms')->where('id', $formId)->update(array(
113 'title' => $title . ' (#' . $formId . ')'
114 ));
115
116 if($this->metas && is_array($this->metas)) {
117 foreach ($this->metas as $meta) {
118 $meta['value'] = trim(preg_replace('/\s+/', ' ', $meta['value']));
119
120 wpFluent()->table('fluentform_form_meta')
121 ->insert(array(
122 'form_id' => $formId,
123 'meta_key' => $meta['meta_key'],
124 'value' => $meta['value']
125 ));
126 }
127 } else {
128 // add default form settings now
129 $defaultSettings = $this->defaultSettings ?: $this->getFormsDefaultSettings($formId);
130
131 $defaultSettings = apply_filters('fluentform_create_default_settings', $defaultSettings);
132
133 wpFluent()->table('fluentform_form_meta')
134 ->insert(array(
135 'form_id' => $formId,
136 'meta_key' => 'formSettings',
137 'value' => json_encode($defaultSettings)
138 ));
139
140 if ($this->defaultNotifications) {
141 wpFluent()->table('fluentform_form_meta')
142 ->insert(array(
143 'form_id' => $formId,
144 'meta_key' => 'notifications',
145 'value' => json_encode($this->defaultNotifications)
146 ));
147 }
148 }
149
150 do_action('fluentform_inserted_new_form', $formId, $insertData);
151
152 $data = array(
153 'formId' => $formId,
154 'redirect_url' => admin_url('admin.php?page=fluent_forms&form_id=' . $formId . '&route=editor'),
155 'message' => __('Successfully created a form.', 'fluentform')
156 );
157
158 if($returnJSON) {
159 wp_send_json_success($data, 200);
160 }
161
162 return $data;
163 }
164
165 public function getFormsDefaultSettings($formId = false)
166 {
167 $defaultSettings = array(
168 'confirmation' => array(
169 'redirectTo' => 'samePage',
170 'messageToShow' => __('Thank you for your message. We will get in touch with you shortly', 'fluentform'),
171 'customPage' => null,
172 'samePageFormBehavior' => 'hide_form',
173 'customUrl' => null
174 ),
175 'restrictions' => array(
176 'limitNumberOfEntries' => array(
177 'enabled' => false,
178 'numberOfEntries' => null,
179 'period' => 'total',
180 'limitReachedMsg' => 'Maximum number of entries exceeded.'
181 ),
182 'scheduleForm' => array(
183 'enabled' => false,
184 'start' => null,
185 'end' => null,
186 'selectedDays' => null,
187 'pendingMsg' => __("Form submission is not started yet.", 'fluentform'),
188 'expiredMsg' => __("Form submission is now closed.", 'fluentform')
189 ),
190 'requireLogin' => array(
191 'enabled' => false,
192 'requireLoginMsg' => 'You must be logged in to submit the form.',
193 ),
194 'denyEmptySubmission' => [
195 'enabled' => false,
196 'message' => __('Sorry, you cannot submit an empty form. Let\'s hear what you wanna say.', 'fluentform'),
197 ]
198 ),
199 'layout' => array(
200 'labelPlacement' => 'top',
201 'helpMessagePlacement' => 'with_label',
202 'errorMessagePlacement' => 'inline',
203 'cssClassName' => '',
204 'asteriskPlacement' => 'asterisk-right'
205 ),
206 'delete_entry_on_submission' => 'no'
207 );
208
209 if ($formId) {
210 $value = $this->getMeta($formId, 'formSettings', true);
211 if ($value) {
212 $defaultSettings = wp_parse_args($value, $defaultSettings);
213 }
214 } else {
215 $globalSettings = get_option('_fluentform_global_form_settings');
216 if (isset($globalSettings['layout'])) {
217 $defaultSettings['layout'] = $globalSettings['layout'];
218 }
219 }
220
221 return $defaultSettings;
222 }
223
224 public function getAdvancedValidationSettings($formId)
225 {
226 $settings = [
227 'status' => false,
228 'type' => 'all',
229 'conditions' => [
230 [
231 'field' => '',
232 'operator' => '=',
233 'value' => ''
234 ]
235 ],
236 'error_message' => '',
237 'validation_type' => 'fail_on_condition_met'
238 ];
239
240 $metaSettings = $this->getMeta($formId, 'advancedValidationSettings', true);
241
242 if($metaSettings && is_array($metaSettings)) {
243 $settings = wp_parse_args($metaSettings, $settings);
244 }
245
246 return $settings;
247 }
248
249 public function getMeta($formId, $metaKey, $isJson = true)
250 {
251 $settingsMeta = wpFluent()->table('fluentform_form_meta')
252 ->where('form_id', $formId)
253 ->where('meta_key', $metaKey)
254 ->first();
255 if ($settingsMeta) {
256 if($isJson) {
257 return \json_decode($settingsMeta->value, true);
258 } else {
259 return $settingsMeta->value;
260 }
261 }
262 return false;
263 }
264
265 public function updateMeta($formId, $metaKey, $metaValue)
266 {
267 $exist = wpFluent()->table('fluentform_form_meta')
268 ->where('form_id', $formId)
269 ->where('meta_key', $metaKey)
270 ->first();
271
272 if(is_array($metaValue) || is_object($metaValue)) {
273 $metaValue = \json_encode($metaValue);
274 }
275
276 if($exist) {
277 return wpFluent()->table('fluentform_form_meta')
278 ->where('id', $exist->id)
279 ->update([
280 'value' => $metaValue
281 ]);
282 }
283
284 return wpFluent()->table('fluentform_form_meta')->insert([
285 'form_id' => $formId,
286 'meta_key' => $metaKey,
287 'value' => $metaValue
288 ]);
289 }
290
291 public function deleteMeta($formId, $metaKey)
292 {
293 return wpFluent()->table('fluentform_form_meta')
294 ->where('form_id', $formId)
295 ->where('meta_key', $metaKey)
296 ->delete();
297 }
298
299 /**
300 * Find/Read a from from the database
301 * @return void
302 */
303 public function find()
304 {
305 $form = $this->fetchForm($this->request->get('formId'));
306 wp_send_json(['form' => $form, 'metas' => []], 200);
307 }
308
309 /**
310 * Fetch a from from the database
311 * Note: required for ninja-tables
312 * @return mixed
313 */
314 public function fetchForm($formId)
315 {
316 return $this->model->find($formId);
317 }
318
319 /**
320 * Save/update a form from backend/editor
321 * @return void
322 * @throws \WpFluent\Exception
323 */
324 public function update()
325 {
326 $formId = $this->request->get('formId');
327 $title = sanitize_text_field($this->request->get('title'));
328 $status = $this->request->get('status', 'published');
329
330 $this->validate();
331
332 $data = [
333 'title' => $title,
334 'status' => $status,
335 'updated_at' => current_time('mysql')
336 ];
337
338
339 if ($formFields = $this->request->get('formFields')) {
340 $formFields = apply_filters('fluentform_form_fields_update', $formFields, $formId);
341 $data['form_fields'] = $formFields;
342 }
343
344 $this->model->where('id', $formId)->update($data);
345
346 $form = $this->fetchForm($formId);
347
348 if (FormFieldsParser::hasPaymentFields($form)) {
349 $this->model->where('id', $formId)->update([
350 'has_payment' => 1
351 ]);
352 } else if ($form->has_payment) {
353 $this->model->where('id', $formId)->update([
354 'has_payment' => 0
355 ]);
356 }
357
358 $emailInputs = FormFieldsParser::getElement($form, ['input_email'], ['element', 'attributes']);
359 if($emailInputs) {
360 $emailInput = array_shift($emailInputs);
361 $emailInputName = ArrayHelper::get($emailInput, 'attributes.name');
362 $this->updateMeta($formId, '_primary_email_field', $emailInputName);
363 } else {
364 $this->updateMeta($formId, '_primary_email_field', '');
365 }
366
367 wp_send_json([
368 'message' => __('The form is successfully updated.', 'fluentform')
369 ], 200);
370 }
371
372 /**
373 * Delete a from from database
374 * @return void
375 * @throws \WpFluent\Exception
376 */
377 public function delete()
378 {
379 $formId = $this->request->get('formId');
380
381 $this->model->where('id', $formId)->delete();
382
383 $maybeErrors = $this->deleteFormAssests($formId);
384
385 wp_send_json([
386 'message' => __('Successfully deleted the form.', 'fluentform'),
387 'errors' => $maybeErrors
388 ], 200);
389 }
390
391
392 protected function deleteFormAssests($formId)
393 {
394 // Now Let's delete associate items
395 wpFluent()->table('fluentform_submissions')
396 ->where('form_id', $formId)
397 ->delete();
398
399 wpFluent()->table('fluentform_submission_meta')
400 ->where('form_id', $formId)
401 ->delete();
402
403 wpFluent()->table('fluentform_entry_details')
404 ->where('form_id', $formId)
405 ->delete();
406
407 wpFluent()->table('fluentform_form_meta')
408 ->where('form_id', $formId)
409 ->delete();
410
411 wpFluent()->table('fluentform_form_analytics')
412 ->where('form_id', $formId)
413 ->delete();
414
415 wpFluent()->table('fluentform_logs')
416 ->where('parent_source_id', $formId)
417 ->whereIn('source_type', ['submission_item', 'form_item', 'draft_submission_meta'])
418 ->delete();
419
420 ob_start();
421 if (defined('FLUENTFORMPRO')) {
422 try {
423 wpFluent()->table('fluentform_order_items')
424 ->where('form_id', $formId)
425 ->delete();
426
427 wpFluent()->table('fluentform_transactions')
428 ->where('form_id', $formId)
429 ->delete();
430 } catch (\Exception $exception) {
431
432 }
433 }
434 $errors = ob_get_clean();
435 return $errors;
436 }
437
438 /**
439 * Duplicate a from
440 * @return void
441 * @throws \WpFluent\Exception
442 */
443 public function duplicate()
444 {
445 $formId = absint($this->request->get('formId'));
446 $form = $this->model->where('id', $formId)->first();
447
448 $data = array(
449 'title' => $form->title,
450 'status' => $form->status,
451 'appearance_settings' => $form->appearance_settings,
452 'form_fields' => $form->form_fields,
453 'type' => $form->type,
454 'has_payment' => $form->has_payment,
455 'conditions' => $form->conditions,
456 'created_by' => get_current_user_id(),
457 'created_at' => current_time('mysql'),
458 'updated_at' => current_time('mysql')
459 );
460
461 $newFormId = $this->model->insert($data);
462
463 // Rename the form name here
464 wpFluent()->table('fluentform_forms')
465 ->where('id', $newFormId)
466 ->update(array(
467 'title' => $form->title . ' (#' . $newFormId . ')'
468 ));
469
470 $formMetas = wpFluent()->table('fluentform_form_meta')
471 ->where('form_id', $formId)
472 ->whereNot('meta_key', ['_total_views'])
473 ->get();
474
475 // Required for duplicating PDF feeds
476 $extras = [];
477
478 foreach ($formMetas as $meta) {
479
480 if ($meta->meta_key == 'notifications' || $meta->meta_key == '_pdf_feeds'){
481 $extras[$meta->meta_key][] = $meta;
482 continue;
483 }
484 $metaData = [
485 'meta_key' => $meta->meta_key,
486 'value' => $meta->value,
487 'form_id' => $newFormId
488 ];
489
490 wpFluent()->table('fluentform_form_meta')->insert($metaData);
491 }
492
493 $pdfFeedMap = $this->getPdfFeedMap($extras, $newFormId);
494 if (array_key_exists('notifications', $extras)) {
495 $extras = $this->notificationWithPdfMap($extras, $pdfFeedMap);
496 foreach ($extras['notifications'] as $notify) {
497 $notifyData = [
498 'meta_key' => $notify->meta_key,
499 'value' => $notify->value,
500 'form_id' => $newFormId
501 ];
502 wpFluent()->table('fluentform_form_meta')->insert($notifyData);
503 }
504 }
505
506 do_action('flentform_form_duplicated', $newFormId);
507
508 wp_send_json([
509 'message' => __('Form has been successfully duplicated.', 'fluentform'),
510 'form_id' => $newFormId,
511 'redirect' => admin_url('admin.php?page=fluent_forms&route=editor&form_id=' . $newFormId)
512 ], 200);
513 }
514
515 /**
516 * Validate a form by form title & for duplicate name attributes
517 * @return void
518 */
519 private function validate()
520 {
521 $fields = $this->request->get('formFields');
522 if($fields) {
523 $duplicates = Helper::getDuplicateFieldNames($fields);
524 if($duplicates){
525 $duplicateString = implode(', ', $duplicates);
526 wp_send_json([
527 'title' => sprintf( __( 'Name attribute %s has duplicate value.', 'fluentform' ), $duplicateString )
528 ], 422);
529 }
530 }
531
532 if (!sanitize_text_field($this->request->get('title'))) {
533 wp_send_json([
534 'title' => 'The title field is required.'
535 ], 422);
536 }
537 }
538
539 public function convertToConversational()
540 {
541 $formId = $this->request->get('form_id');
542 $form = $this->fetchForm($formId);
543
544
545 if (!$form) {
546 wp_send_json([
547 'message' => __('Form Not Found! Try Again.', 'fluentform')
548 ], 422);
549 }
550 $formConverted['form_fields'] = \FluentForm\App\Services\FluentConversational\Classes\Converter\Converter::convertExistingForm($form);
551
552 $this->model->where('id', $formId)->update($formConverted);
553
554
555 $this->updateMeta($formId, 'is_conversion_form', 'yes');
556 wp_send_json_success([
557 'message' => __('Form has been successfully converted to conversational form.', 'fluentform'),
558 ], 200);
559 }
560
561 private function getAdminPermalink($route, $form)
562 {
563 $baseUrl = admin_url('admin.php?page=fluent_forms');
564 return $baseUrl . '&route=' . $route . '&form_id=' . $form->id;
565 }
566
567 private function getSettingsUrl($form)
568 {
569 $baseUrl = admin_url('admin.php?page=fluent_forms');
570 return $baseUrl . '&form_id=' . $form->id . '&route=settings&sub_route=form_settings#basic_settings';
571 }
572
573 public function getAllForms()
574 {
575 $fields = $this->request->get('fields');
576
577 if ($fields) {
578 $forms = $this->model
579 ->select($fields)
580 ->orderBy('created_at', 'DESC')->get();
581 } else {
582 $forms = $this->model->orderBy('created_at', 'DESC')->get();
583 }
584
585 wp_send_json($forms, 200);
586 }
587
588 /**
589 * Map pdf feed ID to replace with duplicated PDF feed ID when duplicating form
590 * @param array $extras
591 * @param array $newFormId
592 * @return array
593 */
594 private function getPdfFeedMap($extras, $newFormId)
595 {
596 $pdfFeedMap = [];
597 if (array_key_exists('_pdf_feeds', $extras)) {
598 foreach ($extras['_pdf_feeds'] as $pdf_feed) {
599 $pdfData = [
600 'meta_key' => $pdf_feed->meta_key,
601 'value' => $pdf_feed->value,
602 'form_id' => $newFormId
603 ];
604 $pdfFeedMap[$pdf_feed->id] = wpFluent()->table('fluentform_form_meta')->insert($pdfData);
605 }
606 }
607 return $pdfFeedMap;
608 }
609
610 /**
611 * Map notification data with PDF feed map
612 * @param array $extras
613 * @param array $pdfFeedMap
614 * @return array
615 */
616 private function notificationWithPdfMap($extras, $pdfFeedMap)
617 {
618 foreach ($extras['notifications'] as $key => $notification) {
619 $notificationValue = json_decode($notification->value);
620 $pdf_attachments = [];
621
622 if ($notificationValue->pdf_attachments && count($notificationValue->pdf_attachments)) {
623 foreach ($notificationValue->pdf_attachments as $attachment) {
624 $pdf_attachments[] = json_encode($pdfFeedMap[$attachment]);
625 }
626 }
627 $notificationValue->pdf_attachments = $pdf_attachments;
628 $notification->value = json_encode($notificationValue);
629
630 $extras['notifications'][$key] = $notification;
631 }
632 return $extras;
633 }
634
635 }
636