PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 5.4
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v5.4
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 5.4, at classes/models/fields/FrmFieldCombo.php

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