PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.10
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.10
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / models / fields / FrmFieldCombo.php

FrmFieldCombo.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.10, at classes/models/fields/FrmFieldCombo.php

489 lines 11.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Combo field - Field contains sub fields
4 *
5 * @package Formidable
6 * @since 4.11
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 die( 'You are not allowed to call this page directly.' );
11 }
12
13 class FrmFieldCombo extends FrmFieldType {
14
15 /**
16 * Does the html for this field label need to include "for"?
17 *
18 * @var bool
19 * @since 3.0
20 */
21 protected $has_for_label = false;
22
23 /**
24 * Sub fields.
25 *
26 * @var array
27 */
28 protected $sub_fields = array();
29
30 /**
31 * This is used to check if field is combo field.
32 *
33 * @var bool
34 */
35 public $is_combo_field = true;
36
37 /**
38 * Gets ALL subfields.
39 *
40 * @return array
41 */
42 public function get_sub_fields() {
43 return $this->sub_fields;
44 }
45
46 /**
47 * Registers sub fields.
48 *
49 * @param array $sub_fields Sub fields. Accepts array or array or array of string.
50 *
51 * @return void
52 */
53 protected function register_sub_fields( array $sub_fields ) {
54 $defaults = $this->get_default_sub_field();
55
56 foreach ( $sub_fields as $name => $sub_field ) {
57 if ( empty( $sub_field ) ) {
58 continue;
59 }
60
61 if ( is_array( $sub_field ) ) {
62 $sub_field = wp_parse_args( $sub_field, $defaults );
63 $sub_field['name'] = $name;
64 $this->sub_fields[ $name ] = $sub_field;
65 continue;
66 }
67
68 if ( is_string( $sub_field ) ) {
69 $this->sub_fields[ $name ] = wp_parse_args(
70 array(
71 'name' => $name,
72 'label' => $sub_field,
73 ),
74 $defaults
75 );
76 }
77 }//end foreach
78 }
79
80 /**
81 * Gets default sub field.
82 *
83 * @return array
84 */
85 protected function get_default_sub_field() {
86 return array(
87 'type' => 'text',
88 'label' => '',
89 'classes' => '',
90 'wrapper_classes' => '',
91 'options' => array(
92 'default_value',
93 'placeholder',
94 'desc',
95 ),
96 'optional' => false,
97 'atts' => array(),
98 );
99 }
100
101 /**
102 * Registers extra options for saving.
103 *
104 * @return array
105 */
106 protected function extra_field_opts() {
107 $extra_options = parent::extra_field_opts();
108
109 // Register for sub field options.
110 foreach ( $this->sub_fields as $key => $sub_field ) {
111 if ( empty( $sub_field['options'] ) || ! is_array( $sub_field['options'] ) ) {
112 continue;
113 }
114
115 foreach ( $sub_field['options'] as $option ) {
116 if ( 'default_value' === $option ) {
117 // We parse default value from field column.
118 continue;
119 }
120
121 if ( is_string( $option ) ) {
122 $extra_options[ $key . '_' . $option ] = '';
123 } elseif ( ! empty( $option['name'] ) ) {
124 $extra_options[ $key . '_' . $option['name'] ] = '';
125 }
126 }
127 }
128
129 return $extra_options;
130 }
131
132 /**
133 * Include the settings for placeholder, default value, and sub labels for each
134 * of the individual field labels.
135 *
136 * @since 4.0
137 *
138 * @param array $args Includes 'field', 'display'.
139 *
140 * @return void
141 */
142 public function show_after_default( $args ) {
143 $field = (array) $args['field'];
144 $default_value = $this->get_default_value();
145 $processed_sub_fields = $this->get_processed_sub_fields();
146
147 foreach ( $this->sub_fields as $name => $sub_field ) {
148 $sub_field['name'] = $name;
149 $wrapper_classes = 'frm_grid_container frm_sub_field_options frm_sub_field_options-' . $sub_field['name'];
150 if ( ! isset( $processed_sub_fields[ $name ] ) ) {
151 // Options for this subfield should be hidden.
152 $wrapper_classes .= ' frm_hidden';
153 }
154
155 include FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/combo-field/sub-field-options.php';
156 }
157 }
158
159 /**
160 * Gets default value of field.
161 * This should return an array of default value of sub fields.
162 *
163 * @return array
164 */
165 protected function get_default_value() {
166 $default_value = $this->get_field_column( 'default_value' );
167
168 if ( is_array( $default_value ) ) {
169 return $default_value;
170 }
171
172 if ( is_object( $default_value ) ) {
173 return (array) $default_value;
174 }
175
176 if ( ! $default_value ) {
177 $default_value = array();
178
179 foreach ( $this->sub_fields as $name => $sub_field ) {
180 $default_value[ $name ] = '';
181 }
182
183 return $default_value;
184 }
185
186 // We store default value as JSON string in db.
187 return json_decode( $default_value, true );
188 }
189
190 /**
191 * Gets labels for built-in options of fields or sub fields.
192 *
193 * @return array
194 */
195 protected function get_built_in_option_labels() {
196 return array(
197 'default_value' => __( 'Default Value', 'formidable' ),
198 'placeholder' => __( 'Placeholder Text', 'formidable' ),
199 'desc' => __( 'Description', 'formidable' ),
200 );
201 }
202
203 /**
204 * Which built-in settings this field supports?
205 *
206 * @return array
207 */
208 protected function field_settings_for_type() {
209 $settings = array(
210 'description' => false,
211 'default' => false,
212 // Don't use the regular placeholder option.
213 'clear_on_focus' => false,
214 'logic' => true,
215 'visibility' => true,
216 );
217
218 return $settings;
219 }
220
221 /**
222 * Shows field on the form builder.
223 *
224 * @param string $name Field name.
225 *
226 * @return void
227 */
228 public function show_on_form_builder( $name = '' ) {
229 $field = FrmFieldsHelper::setup_edit_vars( $this->field );
230
231 $field['default_value'] = $this->get_default_value();
232 $field['value'] = $field['default_value'];
233
234 $field_name = $this->html_name( $name );
235
236 $this->load_field_output( compact( 'field', 'field_name' ) );
237 }
238
239 /**
240 * Gets processed sub fields.
241 * This should return the list of sub fields after sorting or show/hide based of some options.
242 *
243 * @return array
244 */
245 protected function get_processed_sub_fields() {
246 return $this->sub_fields;
247 }
248
249 /**
250 * Shows field in the frontend.
251 *
252 * @param array $args Arguments.
253 * @param array $shortcode_atts Shortcode attributes.
254 * @return string
255 */
256 public function front_field_input( $args, $shortcode_atts ) {
257 $field = (array) $this->field;
258
259 $field['default_value'] = $this->get_default_value();
260 if ( empty( $field['value'] ) ) {
261 $field['value'] = $field['default_value'];
262 }
263
264 $args['field'] = $field;
265 $args['shortcode_atts'] = $shortcode_atts;
266
267 ob_start();
268 $this->load_field_output( $args );
269 $input_html = ob_get_clean();
270
271 return $input_html;
272 }
273
274 /**
275 * Loads field output.
276 *
277 * @param array $args {
278 * Arguments.
279 *
280 * @type array $field Field array.
281 * @type string $html_id HTML ID.
282 * @type string $field_name Field name attribute.
283 * @type array $shortcode_atts Shortcode attributes.
284 * @type array $errors Field errors.
285 * @type bool $remove_names Remove name attribute or not.
286 * }
287 *
288 * @return void
289 */
290 protected function load_field_output( $args ) {
291 if ( empty( $args['field'] ) ) {
292 return;
293 }
294
295 $this->process_args_for_field_output( $args );
296
297 $include_paths = array(
298 FrmAppHelper::plugin_path() . "/classes/views/frm-fields/front-end/{$args['field']['type']}-field/{$args['field']['type']}-field.php",
299 FrmAppHelper::plugin_path() . '/classes/views/frm-fields/front-end/combo-field/combo-field.php',
300 );
301
302 foreach ( $include_paths as $include_path ) {
303 if ( file_exists( $include_path ) ) {
304 include $include_path;
305 return;
306 }
307 }
308 }
309
310 /**
311 * Loads processed args for field output.
312 *
313 * @param array $args {
314 * Arguments.
315 *
316 * @type array $field Field array.
317 * @type string $html_id HTML ID.
318 * @type string $field_name Field name attribute.
319 * @type array $shortcode_atts Shortcode attributes.
320 * @type array $errors Field errors.
321 * @type bool $remove_names Remove name attribute or not.
322 * }
323 *
324 * @return void
325 */
326 protected function process_args_for_field_output( &$args ) {
327 $args['field'] = (array) $args['field'];
328
329 if ( ! isset( $args['html_id'] ) ) {
330 $args['html_id'] = $this->html_id();
331 }
332
333 if ( ! isset( $args['field_name'] ) ) {
334 $args['field_name'] = $this->html_name( $args['field']['name'] );
335 }
336
337 $args['sub_fields'] = $this->get_processed_sub_fields();
338
339 if ( ! isset( $args['shortcode_atts'] ) ) {
340 $args['shortcode_atts'] = array();
341 }
342
343 if ( ! isset( $args['errors'] ) ) {
344 $args['errors'] = array();
345 }
346 }
347
348 /**
349 * Prints sub field input atts.
350 *
351 * @param array $args Arguments. Includes `field`, `sub_field`.
352 *
353 * @return void
354 */
355 protected function print_input_atts( $args ) {
356 $field = $args['field'];
357 $sub_field = $args['sub_field'];
358
359 // Placeholder.
360 if ( in_array( 'placeholder', $sub_field['options'], true ) ) {
361 $placeholders = FrmField::get_option( $field, 'placeholder' );
362 if ( ! empty( $placeholders[ $sub_field['name'] ] ) ) {
363 $field['placeholder'] = $placeholders[ $sub_field['name'] ];
364 }
365 }
366
367 // Add optional class.
368 $classes = isset( $sub_field['classes'] ) ? $sub_field['classes'] : '';
369 if ( is_array( $classes ) ) {
370 $classes = implode( ' ', $classes );
371 }
372
373 if ( ! empty( $sub_field['optional'] ) ) {
374 $classes .= ' frm_optional';
375 }
376
377 if ( $classes ) {
378 $field['input_class'] = esc_attr( $classes );
379 }
380
381 // Fake it to avoid printing frm-val attribute.
382 $field['default_value'] = '';
383
384 do_action( 'frm_field_input_html', $field );
385
386 // Print custom attributes.
387 if ( ! empty( $sub_field['atts'] ) && is_array( $sub_field['atts'] ) ) {
388 foreach ( $sub_field['atts'] as $att_name => $att_value ) {
389 echo esc_attr( trim( $att_name ) ) . '="' . esc_attr( trim( $att_value ) ) . '" ';
390 }
391 }
392 }
393
394 /**
395 * Validate field.
396 *
397 * @param array $args Arguments. Includes `errors`, `value`.
398 * @return array Errors array.
399 */
400 public function validate( $args ) {
401 $errors = isset( $args['errors'] ) ? $args['errors'] : array();
402
403 if ( ! $this->field->required ) {
404 return $errors;
405 }
406
407 if ( class_exists( 'FrmProEntryMeta' ) && FrmProEntryMeta::skip_required_validation( $this->field ) ) {
408 return $errors;
409 }
410
411 if ( class_exists( 'FrmProFieldsHelper' ) && ! FrmProFieldsHelper::is_field_visible_to_user( $this->field ) ) {
412 return $errors;
413 }
414
415 $blank_msg = FrmFieldsHelper::get_error_msg( $this->field, 'blank' );
416
417 $sub_fields = $this->get_processed_sub_fields();
418
419 // Validate not empty.
420 foreach ( $sub_fields as $name => $sub_field ) {
421 if ( empty( $sub_field['optional'] ) && empty( $args['value'][ $name ] ) ) {
422 $errors[ 'field' . $args['id'] . '-' . $name ] = '';
423 $errors[ 'field' . $args['id'] ] = $blank_msg;
424 }
425 }
426
427 return $errors;
428 }
429
430 /**
431 * Gets export headings.
432 *
433 * @return array
434 */
435 public function get_export_headings() {
436 $headings = array();
437 $field_id = isset( $this->field->id ) ? $this->field->id : $this->field['id'];
438 $field_name = isset( $this->field->name ) ? $this->field->name : $this->field['name'];
439 $field_key = isset( $this->field->field_key ) ? $this->field->field_key : $this->field['field_key'];
440 $sub_fields = $this->get_processed_sub_fields();
441 foreach ( $sub_fields as $name => $sub_field ) {
442 $headings[ $field_id . '_' . $name ] = $field_name . ' (' . $field_key . ') - ' . $sub_field['label'];
443 }
444
445 return $headings;
446 }
447
448 /**
449 * Get a list of all field settings that should be translated
450 * on a multilingual site.
451 *
452 * @since 3.06.01
453 *
454 * @return array
455 */
456 public function translatable_strings() {
457 $strings = parent::translatable_strings();
458
459 foreach ( $this->sub_fields as $name => $sub_field ) {
460 if ( in_array( 'desc', $sub_field['options'], true ) ) {
461 $strings[] = $name . '_desc';
462 }
463 }
464
465 return $strings;
466 }
467
468 /**
469 * Checks if should print hidden subfields and hide them. This is useful to use js to show or hide sub fields.
470 *
471 * @return bool
472 */
473 protected function should_print_hidden_sub_fields() {
474 return false;
475 }
476
477 /**
478 * Gets inputs container attributes.
479 *
480 * @return array
481 */
482 protected function get_inputs_container_attrs() {
483 return array(
484 'class' => 'frm_combo_inputs_container',
485 'id' => 'frm_combo_inputs_container_' . $this->field_id,
486 );
487 }
488 }
489