Completed
Push — issues/1038 ( f74a66...b6104c )
by Ravinder
20:08
created

Give_Fields_API::render_hidden_field()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Fields API
5
 *
6
 * @package     Give
7
 * @subpackage  Classes/Give_Fields_API
8
 * @copyright   Copyright (c) 2016, WordImpress
9
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
10
 * @since       1.9
11
 */
12
class Give_Fields_API {
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
13
	/**
14
	 * Instance.
15
	 *
16
	 * @since  1.9
17
	 * @access private
18
	 * @var Give_Fields_API
19
	 */
20
	static private $instance;
21
22
	/**
23
	 * The defaults for all elements
24
	 *
25
	 * @since  1.9
26
	 * @access static
27
	 */
28
	static $field_defaults = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $field_defaults.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
29
		'type'                 => '',
30
		'name'                 => '',
31
		'data_type'            => '',
32
		'value'                => '',
33
		'required'             => false,
34
		'options'              => array(),
35
36
		// Set default value to field.
37
		'default'              => '',
38
39
		// Field with wrapper.
40
		'wrapper'              => true,
41
		'wrapper_type'         => 'p',
42
43
		// Add label, before and after field.
44
		'label'                => '',
45
		'label_position'       => 'before',
46
47
		// Add description to field as tooltip.
48
		'tooltip'              => '',
49
50
		// Show multiple fields in same row with in sub section.
51
		'sub_section_start'    => false,
52
		'sub_section_end'      => false,
53
54
		// Add custom attributes.
55
		'field_attributes'     => array(),
56
		'wrapper_attributes'   => array(),
57
58
		// Show/Hide field in before/after modal view.
59
		'show_without_modal'   => false,
60
		'show_within_modal'    => true,
61
62
		// Params to edit field html.
63
		'before_field'         => '',
64
		'after_field'          => '',
65
		'before_field_wrapper' => '',
66
		'after_field_wrapper'  => '',
67
		'before_label'         => '',
68
		'after_label'          => '',
69
70
		// Manually render field.
71
		'callback'             => '',
72
73
	);
74
75
	/**
76
	 * The defaults for all sections.
77
	 *
78
	 * @since  1.9
79
	 * @access static
80
	 */
81
	static $section_defaults = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $section_defaults.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
82
		'type'               => 'section',
83
		'label'              => '',
84
		'name'               => '',
85
		'section_attributes' => array(),
86
87
		// Manually render section.
88
		'callback'           => '',
89
	);
90
91
	/**
92
	 * The defaults for all blocks.
93
	 *
94
	 * @since  1.9
95
	 * @access static
96
	 */
97
	static $block_defaults = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $block_defaults.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
98
		'type'             => 'block',
99
		'label'            => '',
100
		'name'             => '',
101
		'block_attributes' => array(),
102
103
		// Manually render section.
104
		'callback'         => '',
105
	);
106
107
108
	private function __construct() {
109
	}
110
111
112
	/**
113
	 * Get instance.
114
	 *
115
	 * @return static
116
	 */
117
	public static function get_instance() {
118
		if ( is_null( static::$instance ) ) {
0 ignored issues
show
Bug introduced by
Since $instance is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $instance to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
119
			self::$instance = new static();
120
		}
121
122
		return self::$instance;
123
	}
124
125
	/**
126
	 * Initialize this module
127
	 *
128
	 * @since  1.9
129
	 * @access static
130
	 */
131
	public function init() {
132
		add_filter( 'give_form_api_render_form_tags', array( $this, 'render_tags' ), 10, 2 );
133
	}
134
135
136
	/**
137
	 * Render custom field.
138
	 *
139
	 * @since  1.0
140
	 * @access private
141
	 *
142
	 * @param array $field
143
	 * @param array $form
144
	 *
145
	 * @return bool
146
	 */
147
	private function render_custom_field( $field, $form = null ) {
148
		$field = self::$instance->set_default_values( $field, $form );
149
150
		$field_html = '';
151
152
		if ( empty( $field['callback'] ) ) {
153
			$callback = $field['callback'];
154
155
			// Process callback to get field html.
156
			if ( is_string( $callback ) && function_exists( "$callback" ) ) {
157
				$field_html = $callback( $field );
158
			} elseif ( is_array( $callback ) && method_exists( $callback[0], "$callback[1]" ) ) {
159
				$field_html = $callback[0]->$callback[1]( $field );
160
			}
161
		}
162
163
		return $field_html;
164
	}
165
166
167
	/**
168
	 * Render `{{form_fields}}` tag.
169
	 *
170
	 * @since  1.9
171
	 * @access private
172
	 *
173
	 * @param  string $form_html
174
	 * @param  array  $form
175
	 *
176
	 * @return string
177
	 */
178
	public function render_tags( $form_html, $form ) {
179
		// Bailout: If form does not contain any field.
180
		if ( empty( $form['fields'] ) ) {
181
			str_replace( '{{form_fields}}', '', $form_html );
182
183
			return $form_html;
184
		}
185
186
		$fields_html = '';
187
188
		// Set responsive fields.
189
		self::$instance->set_responsive_field( $form );
190
191
		// Render fields.
192
		foreach ( $form['fields'] as $key => $field ) {
193
			// Set default value.
194
			$field['name'] = empty( $field['name'] ) ? $key : $field['name'];
195
196
			// Render custom form with callback.
197
			if ( $field_html = self::$instance->render_custom_field( $field, $form ) ) {
198
				$fields_html .= $field_html;
199
			}
200
201
			switch ( true ) {
202
				// Block.
203
				case ( array_key_exists( 'type', $field ) && 'block' === $field['type'] ):
204
					$fields_html .= self::$instance->render_block( $field, $form );
205
					break;
206
207
				// Section.
208
				case array_key_exists( 'fields', $field ):
209
					$fields_html .= self::$instance->render_section( $field, $form );
210
					break;
211
212
				// Field
213
				default:
214
					$fields_html .= self::render_tag( $field, $form );
215
			}
216
		}
217
218
		$form_html = str_replace( '{{form_fields}}', $fields_html, $form_html );
219
220
		return $form_html;
221
	}
222
223
224
	/**
225
	 * Render section.
226
	 *
227
	 * @since  1.9
228
	 * @access public
229
	 *
230
	 * @param array $section
231
	 * @param array $form
232
	 * @param array $args Helper argument to render section.
233
	 *
234
	 * @return string
235
	 */
236
	public static function render_section( $section, $form = null, $args = array() ) {
237
		// Set default values if necessary.
238
		if ( ! isset( $args['set_default'] ) || (bool) $args['set_default'] ) {
239
			$section = self::$instance->set_default_values( $section, $form );
240
		}
241
242
		ob_start();
243
		?>
244
		<fieldset <?php echo self::$instance->get_attributes( $section['section_attributes'] ); ?>>
245
			<?php
246
			// Legend.
247
			if ( ! empty( $section['label'] ) ) {
248
				echo "<legend>{$section['label']}</legend>";
249
			};
250
251
			// Fields.
252
			foreach ( $section['fields'] as $key => $field ) {
253
				echo self::render_tag( $field, $form, array( 'set_default' => false ) );
254
			}
255
			?>
256
		</fieldset>
257
		<?php
258
		return ob_get_clean();
259
	}
260
261
262
	/**
263
	 * Render block.
264
	 *
265
	 * @since  1.9
266
	 * @access public
267
	 *
268
	 * @param array $block
269
	 * @param array $form
270
	 * @param array $args Helper argument to render section.
271
	 *
272
	 * @return string
273
	 */
274
	public static function render_block( $block, $form = null, $args = array() ) {
275
		// Set default values if necessary.
276
		if ( ! isset( $args['set_default'] ) || (bool) $args['set_default'] ) {
277
			$block = self::$instance->set_default_values( $block, $form );
278
		}
279
280
		ob_start();
281
		?>
282
		<div <?php echo self::$instance->get_attributes( $block['block_attributes'] ); ?>>
283
			<?php
284
			// Fields.
285
			foreach ( $block['fields'] as $key => $field ) {
286
				echo array_key_exists( 'fields', $field )
287
					? self::render_section( $field, $form, array( 'set_default' => false ) )
288
					: self::render_tag( $field, $form, array( 'set_default' => false ) );
289
			}
290
			?>
291
		</div>
292
		<?php
293
		return ob_get_clean();
294
	}
295
296
	/**
297
	 * Render tag
298
	 *
299
	 * @since   1.9
300
	 * @access  public
301
	 *
302
	 * @param array $field
303
	 * @param array $form
304
	 * @param array $args Helper argument to render section.
305
	 *
306
	 * @return string
307
	 */
308
	public static function render_tag( $field, $form = null, $args = array() ) {
309
		// Set default values if necessary.
310
		if ( ! isset( $args['set_default'] ) || (bool) $args['set_default'] ) {
311
			$field = self::$instance->set_default_values( $field, $form );
312
		}
313
314
		$field_html     = '';
315
		$functions_name = "render_{$field['type']}_field";
316
317
		if ( 'section' === self::$instance->get_field_type( $field ) ) {
318
			echo self::$instance->render_section( $field, $form, array( 'set_default' => false ) );
319
320
		} elseif ( method_exists( self::$instance, $functions_name ) ) {
321
			$field_html .= self::$instance->{$functions_name}( $field );
322
323
		} else {
324
			/**
325
			 * Filter the custom field type html.
326
			 * Developer can use this hook to render custom field type.
327
			 *
328
			 * @since 1.9
329
			 *
330
			 * @param string $field_html
331
			 * @param array  $field
332
			 * @param array  $form
333
			 */
334
			$field_html .= apply_filters(
335
				"give_field_api_render_{$field['type']}_field",
336
				$field_html,
337
				$field,
338
				$form
339
			);
340
		}
341
342
		return $field_html;
343
	}
344
345
346
	/**
347
	 * Render text field.
348
	 *
349
	 * @since  1.9
350
	 * @access private
351
	 *
352
	 * @param  array $field
353
	 *
354
	 * @return string
355
	 */
356
	public static function render_text_field( $field ) {
357
		$field_wrapper = self::$instance->render_field_wrapper( $field );
358
		ob_start();
359
		?>
360
		<input
361
				type="<?php echo $field['type']; ?>"
362
				name="<?php echo $field['name']; ?>"
363
			<?php echo( $field['required'] ? 'required=""' : '' ); ?>
364
			<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
365
		>
366
		<?php
367
368
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
369
	}
370
371
	/**
372
	 * Render submit field.
373
	 *
374
	 * @since  1.9
375
	 * @access private
376
	 *
377
	 * @param  array $field
378
	 *
379
	 * @return string
380
	 */
381
	public static function render_submit_field( $field ) {
382
		return self::$instance->render_text_field( $field );
383
	}
384
385
	/**
386
	 * Render checkbox field.
387
	 *
388
	 * @since  1.9
389
	 * @access private
390
	 *
391
	 * @param  array $field
392
	 *
393
	 * @return string
394
	 */
395
	public static function render_checkbox_field( $field ) {
396
		$field_wrapper = self::$instance->render_field_wrapper( $field );
397
		ob_start();
398
		?>
399
		<input
400
				type="checkbox"
401
				name="<?php echo $field['name']; ?>"
402
			<?php echo( $field['required'] ? 'required=""' : '' ); ?>
403
			<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
404
		>
405
		<?php
406
407
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
408
	}
409
410
	/**
411
	 * Render email field.
412
	 *
413
	 * @since  1.9
414
	 * @access private
415
	 *
416
	 * @param  array $field
417
	 *
418
	 * @return string
419
	 */
420
	public static function render_email_field( $field ) {
421
		return self::$instance->render_text_field( $field );
422
	}
423
424
	/**
425
	 * Render number field.
426
	 *
427
	 * @since  1.9
428
	 * @access private
429
	 *
430
	 * @param  array $field
431
	 *
432
	 * @return string
433
	 */
434
	public static function render_number_field( $field ) {
435
		return self::$instance->render_text_field( $field );
436
	}
437
438
	/**
439
	 * Render password field.
440
	 *
441
	 * @since  1.9
442
	 * @access private
443
	 *
444
	 * @param  array $field
445
	 *
446
	 * @return string
447
	 */
448
	public static function render_password_field( $field ) {
449
		return self::$instance->render_text_field( $field );
450
	}
451
452
	/**
453
	 * Render button field.
454
	 *
455
	 * @since  1.9
456
	 * @access private
457
	 *
458
	 * @param  array $field
459
	 *
460
	 * @return string
461
	 */
462
	public static function render_button_field( $field ) {
463
		return self::$instance->render_text_field( $field );
464
	}
465
466
	/**
467
	 * Render hidden field.
468
	 *
469
	 * @since  1.9
470
	 * @access public
471
	 *
472
	 * @param  array $field
473
	 *
474
	 * @return string
475
	 */
476
	public static function render_hidden_field( $field ) {
477
		$field['wrapper'] = false;
478
479
		return self::$instance->render_text_field( $field );
480
	}
481
482
	/**
483
	 * Render textarea field.
484
	 *
485
	 * @since  1.9
486
	 * @access private
487
	 *
488
	 * @param  array $field
489
	 *
490
	 * @return string
491
	 */
492
	public static function render_textarea_field( $field ) {
493
		$field_wrapper = self::$instance->render_field_wrapper( $field );
494
		ob_start();
495
		?>
496
		<textarea
497
				name="<?php echo $field['name']; ?>"
498
			<?php echo( $field['required'] ? 'required=""' : '' ); ?>
499
			<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
500
		><?php echo $field ['value']; ?></textarea>
501
502
503
		<?php
504
505
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
506
	}
507
508
	/**
509
	 * Render select field.
510
	 *
511
	 * @since  1.9
512
	 * @access private
513
	 *
514
	 * @param  array $field
515
	 *
516
	 * @return string
517
	 */
518
	public static function render_select_field( $field ) {
519
		$field_wrapper = self::$instance->render_field_wrapper( $field );
520
		ob_start();
521
522
		$options_html = '';
523
		foreach ( $field['options'] as $key => $option ) {
524
			$selected = '';
525
526
			if ( is_array( $field['value'] ) ) {
527
				$selected = in_array( $key, $field['value'] )
528
					? 'selected="selected"'
529
					: '';
530
531
			} else {
532
				$selected = selected( $key, $field['value'], false );
533
			}
534
535
			$options_html .= '<option value="' . $key . '" ' . $selected . '>' . $option . '</option>';
536
		}
537
		?>
538
539
		<select
540
				name="<?php echo $field['name']; ?>"
541
			<?php echo( $field['required'] ? 'required=""' : '' ); ?>
542
			<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
543
		><?php echo $options_html; ?></select>
544
		<?php
545
546
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
547
	}
548
549
	/**
550
	 * Render multi select field.
551
	 *
552
	 * @since  1.9
553
	 * @access private
554
	 *
555
	 * @param  array $field
556
	 *
557
	 * @return string
558
	 */
559
	public static function render_multi_select_field( $field ) {
560
		$field['field_attributes'] = array_merge( $field['field_attributes'], array( 'multiple' => 'multiple' ) );
561
		$field['name']             = "{$field['name']}[]";
562
563
		return self::$instance->render_select_field( $field );
564
	}
565
566
	/**
567
	 * Render text field.
568
	 *
569
	 * @since  1.9
570
	 * @access private
571
	 *
572
	 * @param  array $field
573
	 *
574
	 * @return string
575
	 */
576
	public static function render_radio_field( $field ) {
577
		$field_wrapper = self::$instance->render_field_wrapper( $field );
578
		ob_start();
579
580
		$id_base = $field['field_attributes']['id'];
581
		unset( $field['field_attributes']['id'] );
582
583
		foreach ( $field['options'] as $key => $option ) :
584
			?>
585
			<label class="give-label" for="<?php echo "{$id_base}-{$key}" ?>">
586
				<input
587
						type="<?php echo $field['type']; ?>"
588
						name="<?php echo $field['name']; ?>"
589
						value="<?php echo $key; ?>"
590
						id="<?php echo "{$id_base}-{$key}"; ?>"
591
					<?php checked( $key, $field['value'] ) ?>
592
					<?php echo( $field['required'] ? 'required=""' : '' ); ?>
593
					<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
594
				><?php echo $option; ?>
595
			</label>
596
			<?php
597
		endforeach;
598
599
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
600
	}
601
602
	/**
603
	 * Render multi checkbox field.
604
	 *
605
	 * @since  1.9
606
	 * @access private
607
	 *
608
	 * @param  array $field
609
	 *
610
	 * @return string
611
	 */
612
	public static function render_multi_checkbox_field( $field ) {
613
		$field_wrapper = self::$instance->render_field_wrapper( $field );
614
		ob_start();
615
616
		$id_base = $field['field_attributes']['id'];
617
		unset( $field['field_attributes']['id'] );
618
619
		foreach ( $field['options'] as $key => $option ) :
620
			$checked = ! empty( $field['value'] ) && in_array( $key, $field['value'] )
621
				? 'checked="checked"'
622
				: '';
623
			?>
624
			<label class="give-label" for="<?php echo "{$id_base}-{$key}" ?>">
625
				<input
626
						type="checkbox"
627
						name="<?php echo $field['name']; ?>[]"
628
						value="<?php echo $key; ?>"
629
						id="<?php echo "{$id_base}-{$key}"; ?>"
630
					<?php echo $checked ?>
631
					<?php echo( $field['required'] ? 'required=""' : '' ); ?>
632
					<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
633
				><?php echo $option; ?>
634
			</label>
635
			<?php
636
		endforeach;
637
638
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
639
	}
640
641
642
	/**
643
	 * Render wrapper
644
	 *
645
	 * @since  1.9
646
	 * @access private
647
	 *
648
	 * @param $field
649
	 *
650
	 * @return string
651
	 */
652
	private function render_field_wrapper( $field ) {
653
		ob_start();
654
655
		if ( $field['wrapper'] ) :
656
657
			echo $field['before_field_wrapper'];
658
			?>
659
			<<?php echo $field['wrapper_type']; ?> <?php echo self::$instance->get_attributes( $field['wrapper_attributes'] ); ?>>
660
			<?php
661
			// Label: before field.
662
			if ( 'before' === $field['label_position'] ) {
663
				echo self::$instance->render_label( $field );
664
			}
665
666
			echo "{$field['before_field']}{{form_field}}{$field['after_field']}";
667
668
			// Label: before field.
669
			if ( 'after' === $field['label_position'] ) {
670
				echo self::$instance->render_label( $field );
671
			}
672
			?>
673
			</<?php echo $field['wrapper_type']; ?>>
674
			<?php
675
			echo $field['after_field_wrapper'];
676
		else :
677
			echo "{$field['before_field']}{{form_field}}{$field['after_field']}";
678
		endif;
679
680
		return ob_get_clean();
681
	}
682
683
684
	/**
685
	 * Render label
686
	 *
687
	 * @since  1.9
688
	 * @access private
689
	 *
690
	 * @param $field
691
	 *
692
	 * @return string
693
	 */
694
	private function render_label( $field ) {
695
		ob_start();
696
		?>
697
		<?php if ( ! empty( $field['label'] ) ) : ?>
698
			<?php echo $field['before_label']; ?>
699
			<label class="give-label" for="<?php echo $field['field_attributes']['id']; ?>">
700
701
				<?php echo $field['label']; ?>
702
703
				<?php if ( $field['required'] ) : ?>
704
					<span class="give-required-indicator">*</span>
705
				<?php endif; ?>
706
707
				<?php if ( $field['tooltip'] ) : ?>
708
					<span class="give-tooltip give-icon give-icon-question" data-tooltip="<?php echo $field['tooltip'] ?>"></span>
709
				<?php endif; ?>
710
			</label>
711
			<?php echo $field['after_label']; ?>
712
		<?php endif; ?>
713
		<?php
714
		return ob_get_clean();
715
	}
716
717
	/**
718
	 * Get field attribute string from field arguments.
719
	 *
720
	 * @since  1.9
721
	 * @access private
722
	 *
723
	 * @param array $attributes
724
	 *
725
	 * @return array|string
726
	 */
727
	private function get_attributes( $attributes ) {
728
		$field_attributes_val = '';
729
730
		if ( ! empty( $attributes ) ) {
731
			foreach ( $attributes as $attribute_name => $attribute_val ) {
732
				$field_attributes_val[] = "{$attribute_name}=\"{$attribute_val}\"";
733
			}
734
		}
735
736
		if ( ! empty( $field_attributes_val ) ) {
737
			$field_attributes_val = implode( ' ', $field_attributes_val );
738
		}
739
740
		return $field_attributes_val;
741
	}
742
743
	/**
744
	 * Set default values for fields
745
	 *
746
	 * @since  1.0
747
	 * @access private
748
	 *
749
	 * @param array $field
750
	 * @param array $form
751
	 * @param bool  $fire_filter
752
	 *
753
	 * @return array
754
	 */
755
	private function set_default_values( $field, $form = null, $fire_filter = true ) {
756
		/**
757
		 * Filter the field before set default values.
758
		 *
759
		 * @since 1.9
760
		 *
761
		 * @param array $field
762
		 * @param array $form
763
		 */
764
		$field = $fire_filter
765
			? apply_filters( 'give_field_api_pre_set_default_values', $field, $form )
766
			: $field;
767
768
		switch ( self::$instance->get_field_type( $field ) ) {
769
			case 'block':
770
				// Set default values for block.
771
				$field = wp_parse_args( $field, self::$block_defaults );
772
773
				// Set wrapper class.
774
				$field['block_attributes']['class'] = empty( $field['block_attributes']['class'] )
775
					? "give-block-wrapper js-give-block-wrapper give-block-{$field['name']}"
776
					: "give-block-wrapper js-give-block-wrapper give-block-{$field['name']} {$field['block_attributes']['class']}";
777
778
				foreach ( $field['fields'] as $key => $single_field ) {
779
					$single_field['name']    = ! empty( $single_field['name'] )
780
						? $single_field['name']
781
						: $key;
782
					$field['fields'][ $key ] = self::$instance->set_default_values( $single_field, $form, false );
783
				}
784
785
				break;
786
787
			case 'section':
788
				// Set default values for block.
789
				$field = wp_parse_args( $field, self::$section_defaults );
790
791
				// Set wrapper class.
792
				$field['section_attributes']['class'] = empty( $field['section_attributes']['class'] )
793
					? 'give-section-wrapper'
794
					: "give-section-wrapper {$field['section_attributes']['class']}";
795
796
				foreach ( $field['fields'] as $key => $single_field ) {
797
					$single_field['name']    = ! empty( $single_field['name'] )
798
						? $single_field['name']
799
						: $key;
800
					$field['fields'][ $key ] = self::$instance->set_default_values( $single_field, $form, false );
801
				}
802
803
				break;
804
805
			default:
806
				// Set default values for field or section.
807
				$field = wp_parse_args( $field, self::$field_defaults );
808
809
				// Set ID.
810
				$field['field_attributes']['id'] = empty( $field['field_attributes']['id'] )
811
					? "give-{$field['name']}-field"
812
					: $field['field_attributes']['id'];
813
814
				// Set class.
815
				$field['field_attributes']['class'] = empty( $field['field_attributes']['class'] )
816
					? "give-field js-give-field give-field-type-{$field['type']}"
817
					: "give-field js-give-field give-field-type-{$field['type']} {$field['field_attributes']['class']}";
818
819
				// Set wrapper class.
820
				$field['wrapper_attributes']['class'] = empty( $field['wrapper_attributes']['class'] )
821
					? 'give-field-wrapper'
822
					: "give-field-wrapper {$field['wrapper_attributes']['class']}";
823
824
				/**
825
				 * Filter the field values.
826
				 *
827
				 * @since 1.9
828
				 *
829
				 * @param array $field
830
				 * @param array $form
831
				 */
832
				$field = apply_filters( 'give_field_api_set_values', $field, $form );
833
		}
834
835
		/**
836
		 * Filter the field after set default values.
837
		 *
838
		 * @since 1.9
839
		 *
840
		 * @param array $field
841
		 * @param array $form
842
		 */
843
		$field = $fire_filter
844
			? apply_filters( 'give_field_api_post_set_default_values', $field, $form )
845
			: $field;
846
847
		return $field;
848
	}
849
850
851
	/**
852
	 * Set responsive fields.
853
	 *
854
	 * @since  1.9
855
	 * @access private
856
	 *
857
	 * @param $form
858
	 *
859
	 * @return mixed
860
	 */
861
	private function set_responsive_field( &$form ) {
862
863
		foreach ( $form['fields'] as $key => $field ) {
864
			switch ( true ) {
865
				case array_key_exists( 'fields', $field ):
866
					foreach ( $field['fields'] as $section_field_index => $section_field ) {
867
						if ( ! self::$instance->is_sub_section( $section_field ) ) {
868
							continue;
869
						}
870
871
						$form['fields'][ $key ]['fields'][ $section_field_index ]['wrapper_attributes']['class'] = 'give-form-col';
872
873
						if ( array_key_exists( 'sub_section_end', $section_field ) ) {
874
							$form['fields'][ $key ]['fields'][ $section_field_index ]['wrapper_attributes']['class'] = 'give-form-col give-form-col-end';
875
876
							// Clear float left for next field.
877
							$fields_keys = array_keys( $form['fields'][ $key ]['fields'] );
878
879
							if ( $next_field_key = array_search( $section_field_index, $fields_keys ) ) {
880
								if (
881
									! isset( $fields_keys[ $next_field_key + 1 ] )
882
									|| ! isset( $form['fields'][ $key ]['fields'][ $fields_keys[ $next_field_key + 1 ] ] )
883
								) {
884
									continue;
885
								}
886
887
								$next_field = $form['fields'][ $key ]['fields'][ $fields_keys[ $next_field_key + 1 ] ];
888
889
								$next_field['wrapper_attributes']['class'] = isset( $next_field['wrapper_attributes']['class'] )
890
									? $next_field['wrapper_attributes']['class'] . ' give-clearfix'
891
									: 'give-clearfix';
892
893
								$form['fields'][ $key ]['fields'][ $fields_keys[ $next_field_key + 1 ] ] = $next_field;
894
							}
895
						}
896
					}
897
898
					break;
899
900
				default:
901
					if ( ! self::$instance->is_sub_section( $field ) ) {
902
						continue;
903
					}
904
905
					$form['fields'][ $key ]['wrapper_attributes']['class'] = 'give-form-col';
906
907
					if ( array_key_exists( 'sub_section_end', $field ) ) {
908
						$form['fields'][ $key ]['wrapper_attributes']['class'] = 'give-form-col give-form-col-end';
909
910
						// Clear float left for next field.
911
						$fields_keys = array_keys( $form['fields'] );
912
913
						if ( $next_field_key = array_search( $key, $fields_keys ) ) {
914
							$form['fields'][ $fields_keys[ $next_field_key + 1 ] ]['wrapper_attributes']['class'] = 'give-clearfix';
915
						}
916
					}
917
			}
918
		}
919
	}
920
921
922
	/**
923
	 * Check if current field is part of sub section or not.
924
	 *
925
	 * @since  1.9
926
	 * @access private
927
	 *
928
	 * @param $field
929
	 *
930
	 * @return bool
931
	 */
932
	private function is_sub_section( $field ) {
933
		$is_sub_section = false;
934
		if ( array_key_exists( 'sub_section_start', $field ) || array_key_exists( 'sub_section_end', $field ) ) {
935
			$is_sub_section = true;
936
		}
937
938
		return $is_sub_section;
939
	}
940
941
942
	/**
943
	 * Get field type.
944
	 *
945
	 * @since  1.9
946
	 * @access private
947
	 *
948
	 * @param $field
949
	 *
950
	 * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
951
	 */
952
	public static function get_field_type( $field ) {
953
		$field_type = 'field';
954
955
		if (
956
			isset( $field['type'] )
957
			&& 'block' === $field['type']
958
		) {
959
			$field_type = 'block';
960
961
		} elseif ( array_key_exists( 'fields', $field ) ) {
962
			$field_type = 'section';
963
964
		}
965
966
		return $field_type;
967
	}
968
969
	/**
970
	 * Is the element a button?
971
	 *
972
	 * @since  1.9
973
	 * @access static
974
	 *
975
	 * @param array $element
976
	 *
977
	 * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
978
	 */
979
	static function is_button( $element ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
980
		return preg_match( '/^button|submit$/', $element['#type'] );
981
	}
982
}