PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.9
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.9
6.2.14 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 All 196 releases
fluentform / app / Services / Parser / Form.php

Form.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.9, at app/Services/Parser/Form.php

486 lines 12.4 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\Services\Parser;
4
5 use FluentForm\App\Helpers\Str;
6 use FluentForm\Framework\Helpers\ArrayHelper as Arr;
7
8 class Form
9 {
10 /**
11 * @var \stdClass $form
12 */
13 protected $form;
14
15 /**
16 * @var array $inputTypes
17 */
18 protected $inputTypes;
19
20 /**
21 * The parsed form fields.
22 *
23 * @var array
24 */
25 protected $parsed;
26
27 /**
28 * The parsed essential form fields.
29 *
30 * @var array
31 */
32 protected $essentials;
33
34 /**
35 * The parsed validations
36 *
37 * @var array
38 */
39 protected $validations;
40
41 /**
42 * Form Parser constructor.
43 *
44 * @param \stdClass $form
45 */
46 public function __construct($form)
47 {
48 $this->form = $form;
49
50 $this->setInputTypes();
51 }
52
53 /**
54 * Set input types of the form.
55 *
56 * @param array $types
57 * @return \FluentForm\App\Services\Parser\Form $this
58 */
59 public function setInputTypes($types = [])
60 {
61 // If the $types is empty we'll use the default input types.
62 $types = $types ?: [
63 'input_text',
64 'input_name',
65 'textarea',
66 'select',
67 'input_radio',
68 'input_checkbox',
69 'input_email',
70 'input_url',
71 'input_password',
72 'input_file',
73 'input_image',
74 'input_date',
75 'select_country',
76 'input_number',
77 'input_repeat',
78 'address',
79 'terms_and_condition',
80 'input_hidden',
81 'ratings',
82 'net_promoter',
83 'tabular_grid',
84 'gdpr_agreement',
85 'taxonomy'
86 ];
87
88 $types = apply_filters_deprecated(
89 'fluentform_form_input_types',
90 [
91 $types
92 ],
93 FLUENTFORM_FRAMEWORK_UPGRADE,
94 'fluentform/form_input_types',
95 'Use fluentform/form_input_types instead of fluentform_form_input_types'
96 );
97 // Firing an event so that others can hook into it and add other input types.
98 $this->inputTypes = apply_filters('fluentform/form_input_types', $types);
99
100 return $this;
101 }
102
103 /**
104 * Get form fields.
105 *
106 * @param boolean $asArray
107 * @return array
108 */
109 public function getFields($asArray = false)
110 {
111 $default = $asArray ? [] : null;
112
113 // Return default if form_fields is null or empty
114 if (!$this->form || !isset($this->form->form_fields) || $this->form->form_fields === null) {
115 return $default;
116 }
117
118 $fields = json_decode($this->form->form_fields, $asArray);
119
120 return Arr::get((array)$fields, 'fields', $default);
121 }
122
123 /**
124 * Get flatten form inputs. Flatten implies that all
125 * of the form fields will be in a simple array.
126 *
127 * @param array $with
128 * @return array
129 */
130 public function getInputs($with = [])
131 {
132 // If the form is already parsed we'll return it. Otherwise,
133 // we'll parse the form and return the data after saving it.
134 if (!$this->parsed) {
135 $fields = $this->getFields(true);
136
137 $with = $with ?: ['admin_label', 'element', 'options', 'attributes', 'raw'];
138 $this->parsed = (new Extractor($fields, $with, $this->inputTypes))->extract();
139 }
140
141 return $this->parsed;
142 }
143
144 /**
145 * Get the inputs just as they setup in the form editor.
146 * e.g. `names` as `names` not with the child fields.
147 *
148 * @param array $with
149 * @return array
150 */
151 public function getEntryInputs($with = ['admin_label'])
152 {
153 $inputs = $this->getInputs($with);
154
155 // The inputs that has `[]` in their keys are custom fields
156 // & for the purpose of this scenario we'll remove those.
157 foreach ($inputs as $key => $value) {
158 if (Str::contains($key, '[')) {
159 unset($inputs[$key]);
160 }
161 }
162
163 return $inputs;
164 }
165
166 /**
167 * Get the flatten inputs as the result of the `getInputs`
168 * method but replace the keys those have `[]` with `.`
169 * And also remove the repeat fields' child fields.
170 *
171 * @param array $with
172 * @param array
173 */
174 public function getShortCodeInputs($with = ['admin_label'])
175 {
176 $inputs = $this->getInputs($with);
177
178 $result = [];
179
180 // For the purpose of this scenario we'll rename
181 // the keys that have `[]` in 'em to `.` and
182 // remove the keys that have `*` in 'em.
183 foreach ($inputs as $key => $value) {
184 if (Str::contains($key, '*')) {
185 unset($inputs[$key]);
186 } else {
187 $key = str_replace(['[', ']'], ['.'], $key);
188
189 $result[$key] = $value;
190 }
191 }
192
193 return $result;
194 }
195
196 /**
197 * Get admin labels of the form fields.
198 *
199 * @param array $fields
200 * @return array
201 */
202 public function getAdminLabels($fields = [])
203 {
204 $fields = $fields ?: $this->getInputs(['admin_label']);
205
206 $labels = [];
207
208 foreach ($fields as $key => $field) {
209 $labels[$key] = Arr::get($field, 'admin_label');
210 }
211
212 return $labels;
213 }
214
215 /**
216 * Get admin labels of the form fields.
217 *
218 * @param array $inputs
219 * @param array $fields
220 * @return array
221 */
222 public function getValidations($inputs, $fields = [])
223 {
224 // If the form validations are already parsed we'll return it.
225 // Otherwise, we'll parse the form validation and return
226 // the data after saving it to the validations array.
227 if (!$this->validations) {
228 $fields = $fields ?: $this->getInputs(['rules']);
229 $this->validations = (new Validations($fields, $inputs))->get();
230 }
231
232 return $this->validations;
233 }
234
235 /**
236 * Get an element by it's name.
237 *
238 * @param string|array $name
239 * @param array $with
240 * @return array
241 */
242 public function getElement($name, $with = [])
243 {
244 $this->inputTypes = (array) $name;
245
246 return $this->getInputs($with);
247 }
248
249 /**
250 * Determine whether the form has an element.
251 *
252 * @param string $name
253 * @return bool
254 */
255 public function hasElement($name)
256 {
257 $elements = $this->getElement($name, ['element']);
258
259 foreach ($elements as $item) {
260 if ($item['element'] === $name) {
261 return true;
262 }
263 }
264
265 return false;
266 }
267
268 /**
269 * Determine whether the form has any required fields.
270 *
271 * @param array $fields
272 * @return bool
273 */
274 public function hasRequiredFields($fields = [])
275 {
276 // $fields can be user provided when called this method or,
277 // the current object could have already parsed fields or,
278 // we should parse the form and use the processed result.
279 $fields = $fields ?: $this->parsed ?: $this->getInputs(['rules']);
280
281 $exist = false;
282
283 foreach ($fields as $field) {
284 $exist = Arr::get($field, 'rules.required.value');
285
286 if ($exist) {
287 break;
288 }
289 }
290
291 return (boolean)$exist;
292 }
293
294
295 /**
296 * Get Payment Related Fields
297 *
298 * @param array $with array
299 * @return array
300 */
301 public function getPaymentFields($with = ['element', 'settings'])
302 {
303 $fields = $this->getInputs($with);
304
305 $data = [
306 'custom_payment_component',
307 'multi_payment_component',
308 'payment_method',
309 'item_quantity_component',
310 'rangeslider',
311 'payment_coupon',
312 'subscription_payment_component',
313 ];
314
315 $data = apply_filters_deprecated('fluentform_form_payment_fields', [
316 $data
317 ],
318 FLUENTFORM_FRAMEWORK_UPGRADE,
319 'fluentform/form_payment_fields',
320 'Use fluentform/form_payment_fields instead of fluentform_form_payment_fields'
321 );
322
323 $paymentElements = apply_filters('fluentform/form_payment_fields', $data);
324
325 return array_filter($fields, function ($field) use ($paymentElements) {
326 if ($field['element'] === 'rangeslider') {
327 return Arr::get($field, 'settings.enable_target_product', 'no') === 'yes';
328 }
329 return in_array($field['element'], $paymentElements);
330 });
331 }
332
333 /**
334 * Get Payment Input Fields
335 *
336 * @return array
337 */
338 public function getPaymentInputFields($with = ['element'])
339 {
340 $fields = $this->getInputs($with);
341
342 $data = [
343 'custom_payment_component',
344 'multi_payment_component'
345 ];
346
347 $data = apply_filters_deprecated(
348 'fluentform_form_payment_inputs',
349 [
350 $data
351 ],
352 FLUENTFORM_FRAMEWORK_UPGRADE,
353 'fluentform/form_payment_inputs',
354 'Use fluentform/form_payment_inputs instead of fluentform_form_payment_inputs'
355 );
356
357 $paymentElements = apply_filters('fluentform/form_payment_inputs', $data);
358
359 return array_filter($fields, function ($field) use ($paymentElements) {
360 return in_array($field['element'], $paymentElements);
361 });
362 }
363
364 /**
365 * Determine whether the form has payment elements
366 *
367 * @return bool
368 */
369 public function hasPaymentFields()
370 {
371 $fields = $this->getInputs(['element']);
372
373 $data = [
374 'custom_payment_component',
375 'multi_payment_component',
376 'payment_method',
377 'item_quantity_component',
378 'payment_coupon',
379 'subscription_payment_component'
380 ];
381
382 $data = apply_filters_deprecated(
383 'fluentform_form_payment_fields',
384 [
385 $data
386 ],
387 FLUENTFORM_FRAMEWORK_UPGRADE,
388 'fluentform/form_payment_fields',
389 'Use fluentform/form_payment_fields instead of fluentform_form_payment_fields'
390 );
391
392 $paymentElements = apply_filters('fluentform/form_payment_fields', $data);
393
394 foreach ($fields as $field) {
395 if (in_array($field['element'], $paymentElements)) {
396 return true;
397 }
398 }
399
400 return false;
401 }
402
403
404 /**
405 * Get an specific field for an element type.
406 *
407 * @param $element
408 * @param $attribute
409 * @param array $with
410 * @return array|null
411 */
412 public function getField($element, $attribute, $with = [])
413 {
414 $element = $this->getElement($element, $with);
415
416 return array_intersect_key($element, array_flip((array)$attribute));
417 }
418
419
420 /**
421 * Get Payment Input Fields
422 *
423 * @return array
424 */
425 public function getAttachmentInputFields($with = ['element'])
426 {
427 $fields = $this->getInputs($with);
428 $paymentElements = [
429 'input_file',
430 'input_image',
431 'featured_image',
432 'signature'
433 ];
434
435 return array_filter($fields, function ($field) use ($paymentElements) {
436 return in_array($field['element'], $paymentElements);
437 });
438 }
439
440 /**
441 * Get Any Field Type
442 * @return array
443 */
444
445 public function getInputsByElementTypes($types, $with = ['element'])
446 {
447 $fields = $this->getInputs($with);
448
449 return array_filter($fields, function ($field) use ($types) {
450 return in_array($field['element'], $types);
451 });
452 }
453
454 /**
455 * Get Address Fields
456 *
457 * @return array
458 */
459 public function getAddressFields($with = ['admin_label', 'attributes'])
460 {
461 $fields = $this->getInputs($with);
462 $addressElements = [
463 'address'
464 ];
465
466 return array_filter($fields, function ($field) use ($addressElements) {
467 return in_array($field['element'], $addressElements);
468 });
469 }
470
471 public function getEssentialInputs($formData, $with = [])
472 {
473 // If the form is already parsed we'll return it. Otherwise,
474 // we'll parse the form and return the data after saving it.
475 if (!$this->essentials) {
476 $fields = $this->getFields(true);
477
478 $with = $with ?: ['rules', 'raw'];
479
480 $this->essentials = (new Extractor($fields, $with, $this->inputTypes))->extractEssentials($formData);
481 }
482
483 return $this->essentials;
484 }
485 }
486