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

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