Completed
Push — issues/1038 ( 5fb60b...8f0d36 )
by Ravinder
17:16
created

Give_Fields_API::render_callback()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 9
nc 4
nop 3
dl 0
loc 16
rs 8.2222
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
		'id'                   => '',
31
		'data_type'            => '',
32
		'value'                => null,
33
		'required'             => false,
34
		'options'              => array(),
35
36
		// Set default value to field.
37
		'default'              => null,
38
39
		// Set checkbox value.
40
		'cbvalue'              => 'on',
41
42
		// Field with wrapper.
43
		'wrapper'              => true,
44
		'wrapper_type'         => 'p',
45
46
		// Add label, before and after field.
47
		'label'                => '',
48
		'label_position'       => 'before',
49
		'label_tooltip'        => '',
50
51
		// Show multiple fields in same row with in sub section.
52
		'sub_section_start'    => false,
53
		'sub_section_end'      => false,
54
55
		// Sortable.
56
		'sortable'             => false,
57
		'sortable-icon'        => false,
58
59
		// Add custom attributes.
60
		'label_attributes'     => array(),
61
		'field_attributes'     => array(),
62
		'wrapper_attributes'   => array(),
63
64
		// Show/Hide field in before/after modal view.
65
		'show_without_modal'   => false,
66
		'show_within_modal'    => true,
67
68
		// Params to edit field html.
69
		// They accept callback or string input.
70
		'before_field'         => '',
71
		'after_field'          => '',
72
		'before_field_wrapper' => '',
73
		'after_field_wrapper'  => '',
74
		'before_field_label'   => '',
75
		'after_field_label'    => '',
76
77
		// Manually render field.
78
		'callback'             => '',
79
80
	);
81
82
	/**
83
	 * The defaults for all sections.
84
	 *
85
	 * @since  1.9
86
	 * @access static
87
	 */
88
	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...
89
		'type'               => 'section',
90
		'label'              => '',
91
		'id'               => '',
92
		'section_attributes' => array(),
93
94
		// Manually render section.
95
		'callback'           => '',
96
	);
97
98
	/**
99
	 * The defaults for all blocks.
100
	 *
101
	 * @since  1.9
102
	 * @access static
103
	 */
104
	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...
105
		'type'             => 'block',
106
		'label'            => '',
107
		'id'             => '',
108
		'block_attributes' => array(),
109
110
		// Manually render section.
111
		'callback'         => '',
112
	);
113
114
115
	private function __construct() {
116
	}
117
118
119
	/**
120
	 * Get instance.
121
	 *
122
	 * @return static
123
	 */
124
	public static function get_instance() {
125
		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...
126
			self::$instance = new static();
127
		}
128
129
		return self::$instance;
130
	}
131
132
	/**
133
	 * Initialize this module
134
	 *
135
	 * @since  1.9
136
	 * @access static
137
	 */
138
	public function init() {
139
		add_filter( 'give_form_api_render_form_tags', array( $this, 'render_tags' ), 10, 2 );
140
	}
141
142
143
	/**
144
	 * Render callback.
145
	 *
146
	 * @since 1.9
147
	 * @access public
148
	 * @param       $callback
149
	 * @param array $field
150
	 * @param null  $form
151
	 *
152
	 * @return string
153
	 */
154
	public static function render_callback( $callback, $field = array(), $form = null  ){
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
155
		$field_html = '';
156
157
		if( empty( $callback ) || ! self::is_callback( $callback ) ) {
158
			return $field_html;
159
		}
160
161
		// Process callback to get field html.
162
		if ( is_string( $callback ) && function_exists( "$callback" ) ) {
163
			$field_html = $callback( $field );
164
		} elseif ( is_array( $callback ) && method_exists( $callback[0], "$callback[1]" ) ) {
165
			$field_html = $callback[0]->$callback[1]( $field );
166
		}
167
168
		return $field_html;
169
	}
170
171
172
	/**
173
	 * Render custom field.
174
	 *
175
	 * @since  1.0
176
	 * @access private
177
	 *
178
	 * @param array $field
179
	 * @param array $form
180
	 *
181
	 * @return string
182
	 */
183
	private function render_custom_field( $field, $form = null ) {
184
		$field_html = '';
185
186
		if ( ! empty( $field['callback'] ) ) {
187
			$field = self::$instance->set_default_values( $field, $form );
188
			
189
			$callback = $field['callback'];
190
			$field_html = self::render_callback( $callback, $field, $form );
191
		}
192
193
		return $field_html;
194
	}
195
196
197
	/**
198
	 * Render `{{form_fields}}` tag.
199
	 *
200
	 * @since  1.9
201
	 * @access private
202
	 *
203
	 * @param  string $form_html
204
	 * @param  array  $form
205
	 *
206
	 * @return string
207
	 */
208
	public function render_tags( $form_html, $form ) {
209
		// Bailout: If form does not contain any field.
210
		if ( empty( $form['fields'] ) ) {
211
			str_replace( '{{form_fields}}', '', $form_html );
212
213
			return $form_html;
214
		}
215
216
		$fields_html = '';
217
218
		// Set responsive fields.
219
		self::$instance->set_responsive_field( $form );
220
221
		// Render fields.
222
		foreach ( $form['fields'] as $key => $field ) {
223
			// Set default value.
224
			$field['id'] = empty( $field['id'] ) ? $key : $field['id'];
225
226
			// Render custom form with callback.
227
			if ( $field_html = self::$instance->render_custom_field( $field, $form ) ) {
228
				$fields_html .= $field_html;
229
			}
230
231
			switch ( true ) {
232
				// Block.
233
				case ( 'block' === self::get_field_type( $field ) ):
234
					$fields_html .= self::$instance->render_block( $field, $form );
235
					break;
236
237
				// Section.
238
				case ( 'section' === self::get_field_type( $field ) ):
239
					$fields_html .= self::$instance->render_section( $field, $form );
240
					break;
241
242
				// Field
243
				default:
244
					$fields_html .= self::render_tag( $field, $form );
245
			}
246
		}
247
248
		$form_html = str_replace( '{{form_fields}}', $fields_html, $form_html );
249
250
		return $form_html;
251
	}
252
253
254
	/**
255
	 * Render section.
256
	 *
257
	 * @since  1.9
258
	 * @access public
259
	 *
260
	 * @param array $section
261
	 * @param array $form
262
	 * @param array $args Helper argument to render section.
263
	 *
264
	 * @return string
265
	 */
266
	public static function render_section( $section, $form = null, $args = array() ) {
267
		// Set default values if necessary.
268
		if ( ! isset( $args['set_default'] ) || (bool) $args['set_default'] ) {
269
			$section = self::$instance->set_default_values( $section, $form );
270
		}
271
272
		ob_start();
273
		?>
274
		<fieldset <?php echo self::$instance->get_attributes( $section['section_attributes'] ); ?>>
275
			<?php
276
			// Legend.
277
			if ( ! empty( $section['label'] ) ) {
278
				echo "<legend>{$section['label']}</legend>";
279
			};
280
281
			// Fields.
282
			foreach ( $section['fields'] as $key => $field ) {
283
				echo self::render_tag( $field, $form, array( 'set_default' => false ) );
284
			}
285
			?>
286
		</fieldset>
287
		<?php
288
		return ob_get_clean();
289
	}
290
291
292
	/**
293
	 * Render block.
294
	 *
295
	 * @since  1.9
296
	 * @access public
297
	 *
298
	 * @param array $block
299
	 * @param array $form
300
	 * @param array $args Helper argument to render section.
301
	 *
302
	 * @return string
303
	 */
304
	public static function render_block( $block, $form = null, $args = array() ) {
305
		// Set default values if necessary.
306
		if ( ! isset( $args['set_default'] ) || (bool) $args['set_default'] ) {
307
			$block = self::$instance->set_default_values( $block, $form );
308
		}
309
310
		ob_start();
311
		?>
312
		<div <?php echo self::$instance->get_attributes( $block['block_attributes'] ); ?>>
313
			<?php
314
			// Fields.
315
			foreach ( $block['fields'] as $key => $field ) {
316
				echo array_key_exists( 'fields', $field )
317
					? self::render_section( $field, $form, array( 'set_default' => false ) )
318
					: self::render_tag( $field, $form, array( 'set_default' => false ) );
319
			}
320
			?>
321
		</div>
322
		<?php
323
		return ob_get_clean();
324
	}
325
326
	/**
327
	 * Render tag
328
	 *
329
	 * @since   1.9
330
	 * @access  public
331
	 *
332
	 * @param array $field
333
	 * @param array $form
334
	 * @param array $args Helper argument to render section.
335
	 *
336
	 * @return string
337
	 */
338
	public static function render_tag( $field, $form = null, $args = array() ) {
339
		// Enqueue scripts.
340
		Give_Form_API::enqueue_scripts();
341
342
		if( ! empty( $field['sortable'] ) ) {
343
			wp_enqueue_script('jquery-ui-sortable');
344
		}
345
346
		// Set default values if necessary.
347
		if ( ! isset( $args['set_default'] ) || (bool) $args['set_default'] ) {
348
			$field = self::$instance->set_default_values( $field, $form );
349
		}
350
351
		$field_html     = '';
352
		$functions_name = "render_{$field['type']}_field";
353
354
		if ( 'section' === self::$instance->get_field_type( $field ) ) {
355
			$field_html = self::$instance->render_section( $field, $form, array( 'set_default' => false ) );
356
357
		} elseif ( method_exists( self::$instance, $functions_name ) ) {
358
			$field_html = self::$instance->{$functions_name}( $field, $form, $args );
359
360
		}
361
362
		/**
363
		 * Filter the custom field type html.
364
		 * Developer can use this hook to render custom field type.
365
		 *
366
		 * @since 1.9
367
		 *
368
		 * @param string $field_html
369
		 * @param array  $field
370
		 * @param array  $form
371
		 */
372
		$field_html = apply_filters(
373
			"give_field_api_render_{$field['type']}_field",
374
			$field_html,
375
			$field,
376
			$form,
377
			$args
378
		);
379
380
		/**
381
		 * Filter the all field type html.
382
		 *
383
		 * @since 1.9
384
		 *
385
		 * @param string $field_html
386
		 * @param array  $field
387
		 * @param array  $form
388
		 */
389
		$field_html = apply_filters(
390
			"give_field_api_render_field",
391
			$field_html,
392
			$field,
393
			$form,
394
			$args
395
		);
396
397
		return $field_html;
398
	}
399
400
401
	/**
402
	 * Render text field.
403
	 *
404
	 * @since  1.9
405
	 * @access public
406
	 *
407
	 * @param  array $field
408
	 * @param  array $form
409
	 * @param  array $args
410
	 *
411
	 * @return string
412
	 */
413
	public static function render_text_field( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
414
		$field_wrapper = self::$instance->render_field_wrapper( $field );
415
		$field['field_attributes']['name'] = self::get_field_name( $field );
416
		$field['field_attributes']['type'] = $field['type'];
417
418
		if( ! empty( $field['required'] ) ) {
419
			$field['field_attributes']['required'] = 'required';
420
			$field['field_attributes']['aria-required'] = 'true';
421
		}
422
423
		ob_start();
424
425
		echo '<input ' . self::$instance->get_attributes( $field['field_attributes'] ) . '>';
426
427
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
428
	}
429
430
	/**
431
	 * Render submit field.
432
	 *
433
	 * @since  1.9
434
	 * @access public
435
	 *
436
	 * @param  array $field
437
	 * @param  array $form
438
	 * @param  array $args
439
	 *
440
	 * @return string
441
	 */
442
	public static function render_submit_field( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
443
		return self::$instance->render_text_field( $field );
444
	}
445
446
	/**
447
	 * Render checkbox field.
448
	 *
449
	 * @since  1.9
450
	 * @access public
451
	 *
452
	 * @param  array $field
453
	 * @param  array $form
454
	 * @param  array $args
455
	 *
456
	 * @return string
457
	 */
458
	public static function render_checkbox_field( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
459
		return self::$instance->render_text_field( $field );
460
	}
461
462
	/**
463
	 * Render email field.
464
	 *
465
	 * @since  1.9
466
	 * @access public
467
	 *
468
	 * @param  array $field
469
	 * @param  array $form
470
	 * @param  array $args
471
	 *
472
	 * @return string
473
	 */
474
	public static function render_email_field( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
475
		return self::$instance->render_text_field( $field );
476
	}
477
478
	/**
479
	 * Render number field.
480
	 *
481
	 * @since  1.9
482
	 * @access public
483
	 *
484
	 * @param  array $field
485
	 * @param  array $form
486
	 * @param  array $args
487
	 *
488
	 * @return string
489
	 */
490
	public static function render_number_field( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
491
		return self::$instance->render_text_field( $field );
492
	}
493
494
	/**
495
	 * Render password field.
496
	 *
497
	 * @since  1.9
498
	 * @access public
499
	 *
500
	 * @param  array $field
501
	 * @param  array $form
502
	 * @param  array $args
503
	 *
504
	 * @return string
505
	 */
506
	public static function render_password_field( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
507
		return self::$instance->render_text_field( $field );
508
	}
509
510
	/**
511
	 * Render button field.
512
	 *
513
	 * @since  1.9
514
	 * @access public
515
	 *
516
	 * @param  array $field
517
	 * @param  array $form
518
	 * @param  array $args
519
	 *
520
	 * @return string
521
	 */
522
	public static function render_button_field( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
523
		return self::$instance->render_text_field( $field );
524
	}
525
526
	/**
527
	 * Render hidden field.
528
	 *
529
	 * @since  1.9
530
	 * @access public
531
	 *
532
	 * @param  array $field
533
	 * @param  array $form
534
	 * @param  array $args
535
	 *
536
	 * @return string
537
	 */
538
	public static function render_hidden_field( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
539
		$field['wrapper'] = false;
540
541
		return self::$instance->render_text_field( $field );
542
	}
543
544
	/**
545
	 * Render textarea field.
546
	 *
547
	 * @since  1.9
548
	 * @access public
549
	 *
550
	 * @param  array $field
551
	 * @param  array $form
552
	 * @param  array $args
553
	 *
554
	 * @return string
555
	 */
556
	public static function render_textarea_field( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
557
		$field_wrapper = self::$instance->render_field_wrapper( $field );
558
		ob_start();
559
		?>
560
		<textarea
561
				name="<?php echo self::get_field_name( $field ); ?>"
562
			<?php echo( $field['required'] ? 'required=""' : '' ); ?>
563
			<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
564
		><?php echo $field ['value']; ?></textarea>
565
566
567
		<?php
568
569
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
570
	}
571
572
	/**
573
	 * Render select field.
574
	 *
575
	 * @since  1.9
576
	 * @access public
577
	 *
578
	 * @param  array $field
579
	 * @param  array $form
580
	 * @param  array $args
581
	 *
582
	 * @return string
583
	 */
584
	public static function render_select_field( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
585
		$field_wrapper = self::$instance->render_field_wrapper( $field );
586
		ob_start();
587
588
		$options_html = '';
589
		foreach ( $field['options'] as $key => $option ) {
590
			$options_html .= '<option '. self::get_attributes( $option['field_attributes'] ). '>' . $option['label'] . '</option>';
591
		}
592
		?>
593
594
		<select
595
				name="<?php echo self::get_field_name( $field ); ?>"
596
			<?php echo( $field['required'] ? 'required=""' : '' ); ?>
597
			<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
598
		><?php echo $options_html; ?></select>
599
		<?php
600
601
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
602
	}
603
604
	/**
605
	 * Render multi select field.
606
	 *
607
	 * @since  1.9
608
	 * @access public
609
	 *
610
	 * @param  array $field
611
	 * @param  array $form
612
	 * @param  array $args
613
	 *
614
	 * @return string
615
	 */
616
	public static function render_multi_select_field( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
617
		$field['field_attributes'] = array_merge( $field['field_attributes'], array( 'multiple' => 'multiple' ) );
618
		$field['id']             = "{$field['id']}[]";
619
620
		return self::$instance->render_select_field( $field );
621
	}
622
623
	/**
624
	 * Render radio field.
625
	 *
626
	 * @since  1.9
627
	 * @access public
628
	 *
629
	 * @param  array $field
630
	 * @param  array $form
631
	 * @param  array $args
632
	 *
633
	 * @return string
634
	 */
635
	public static function render_radio_field( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
636
		$field['wrapper_type'] = 'p' === $field['wrapper_type']
637
			? 'fieldset'
638
			: $field['wrapper_type'];
639
640
641
		$field_wrapper = self::$instance->render_field_wrapper( $field );
642
		ob_start();
643
644
		$id_base = $field['field_attributes']['id'];
645
		unset( $field['field_attributes']['id'] );
646
647
		echo '<ul>';
648
		foreach ( $field['options'] as $key => $option ) :
649
			$option['field_attributes']['type'] = $field['type'];
650
			$option['field_attributes']['name'] = self::get_field_name( $field );
651
			$option['field_attributes']['id'] = "{$id_base}-{$key}";
652
			?>
653
			<li>
654
				<label class="give-label" for="<?php echo $option['field_attributes']['id']; ?>">
655
					<input <?php echo self::$instance->get_attributes( $option['field_attributes'] ); ?>
656
					><?php echo $option['label']; ?>
657
				</label>
658
			</li>
659
			<?php
660
		endforeach;
661
		echo '</ul>';
662
663
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
664
	}
665
666
	/**
667
	 * Render multi checkbox field.
668
	 *
669
	 * Note:
670
	 * You can reorder checklist if sortable with help of give_reorder_array function.
671
	 *
672
	 * @since  1.9
673
	 * @access public
674
	 *
675
	 * @param  array $field
676
	 * @param  array $form
677
	 * @param  array $args
678
	 *
679
	 * @return string
680
	 */
681
	public static function render_multi_checkbox_field( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
682
		// Field wrapper.
683
		$field['wrapper_type'] = 'p' === $field['wrapper_type']
684
			? 'fieldset'
685
			: $field['wrapper_type'];
686
687
		// Field value.
688
		$field['value'] = is_array( $field['value'] )
689
			? $field['value']
690
			: array();
691
692
		// Field type.
693
		$field['field_attributes']['type'] = 'checkbox';
694
695
		// Field name.
696
		$field['field_attributes']['name'] = self::get_field_name( $field ) . '[]';
697
698
		$field_wrapper = self::$instance->render_field_wrapper( $field );
699
		ob_start();
700
701
		$id_base = $field['field_attributes']['id'];
702
		unset( $field['field_attributes']['id'] );
703
		
704
		echo '<ul class="give-checklist-fields" data-give-sortable-list="' . absint( $field['sortable'] ) . '" data-give-sortable-icon="' . absint( $field['sortable-icon'] ) . '">';
705
706
		foreach ( $field['options'] as $key => $option ) :
707
			// Set basic values for field.
708
			$option = is_array( $option ) ? $option : array( 'label' => $option );
709
			$option['field_attributes']['id'] = "give-{$id_base}-{$key}";
710
			$option['field_attributes']['data-give-required'] = ( $field['required'] ? 1 : 0 );
711
			$option['field_attributes']['value']         = empty( $option['field_attributes']['value'] )
712
				? $key
713
				: $option['field_attributes']['value'];
714
715
			// Check if field checked or not.
716
			if (
717
				! empty( $field['value'] ) && in_array( $key, $field['value'] )
718
				|| (
719
					( ! empty( $field['repeater_default_template'] ) || ! empty( $field['repeater_template'] ) )
720
					&& is_array( $option )
721
					&& ! empty( $option['checked'] )
722
				)
723
			) {
724
				$option['field_attributes']['checked'] = 'checked';
725
			}
726
727
			// Add extra attribute per checkbox.
728
			$option['field_attributes'] = is_array( $option ) && ! empty( $option['field_attributes'] )
729
				? array_merge( $field['field_attributes'], $option['field_attributes'] )
730
				: $field['field_attributes'];
731
732
			// Add field specific class.
733
			$option['field_attributes']['class'] = trim( "{$option['field_attributes']['class']} give-{$key}" );
734
			?>
735
			<li>
736
				<label class="give-label" for="<?php echo $option['field_attributes']['id']; ?>">
737
					<input <?php echo self::$instance->get_attributes( $option['field_attributes'] ); ?>><?php echo( ! is_array( $option ) ? $option : ( isset( $option['label'] ) ? $option['label'] : '' ) ); ?>
738
				</label>
739
			</li>
740
			<?php
741
		endforeach;
742
743
		echo '</ul>';
744
745
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
746
	}
747
748
749
	/**
750
	 * Render group field
751
	 *
752
	 * @since 1.9
753
	 * @access public
754
	 *
755
	 * @param  array $fields
756
	 * @param  array $form
757
	 * @param  array $args
758
	 *
759
	 * @return string
760
	 */
761
	public static function render_group_field( $fields, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
762
		// Bailout.
763
		if ( ! isset( $fields['fields'] ) || empty( $fields['fields'] ) ) {
764
			return '';
765
		}
766
767
		$group_numbering       = isset( $fields['options']['group_numbering'] ) ? (int) $fields['options']['group_numbering'] : 0;
768
		$close_tabs            = isset( $fields['options']['close_tabs'] ) ? (int) $fields['options']['close_tabs'] : 0;
769
		$repeater_field_values = $fields['value'];
770
		$header_title          = isset( $fields['options']['header_title'] )
771
			? $fields['options']['header_title']
772
			: esc_attr__( 'Group', 'give' );
773
774
		$add_default_donation_field = false;
775
776
		// Check if level is not created or we have to add default level.
777
		if ( is_array( $repeater_field_values ) && ( $fields_count = count( $repeater_field_values ) ) ) {
778
			$repeater_field_values = array_values( $repeater_field_values );
779
		} else {
780
			$fields_count               = 1;
781
			$add_default_donation_field = true;
782
		}
783
784
		$field_wrapper = self::$instance->render_field_wrapper( $fields );
785
786
		ob_start();
787
		?>
788
		<div class="give-repeatable-field-section" id="<?php echo "{$fields['id']}_field"; ?>"
789
			 data-group-numbering="<?php echo $group_numbering; ?>" data-close-tabs="<?php echo $close_tabs; ?>">
790
			<?php if ( ! empty( $fields['label'] ) ) : ?>
791
				<p class="give-repeater-field-name"><?php echo $fields['label']; ?></p>
792
			<?php endif; ?>
793
794
			<?php if ( ! empty( $fields['description'] ) ) : ?>
795
				<p class="give-repeater-field-description"><?php echo $fields['description']; ?></p>
796
			<?php endif; ?>
797
798
			<table class="give-repeatable-fields-section-wrapper" cellspacing="0">
799
				<tbody class="container"<?php echo " data-rf-row-count=\"{$fields_count}\""; ?>>
800
					<!--Repeater field group template-->
801
					<tr class="give-template give-row">
802
						<td class="give-repeater-field-wrap give-column" colspan="2">
803
							<div class="give-row-head give-move">
804
								<button type="button" class="give-toggle-btn">
805
									<span class="give-toggle-indicator"></span>
806
								</button>
807
								<span class="give-remove" title="<?php esc_html_e( 'Remove Group', 'give' ); ?>">-</span>
808
								<h2>
809
									<span data-header-title="<?php echo $header_title; ?>"><?php echo $header_title; ?></span>
810
								</h2>
811
							</div>
812
							<div class="give-row-body">
813
								<?php
814
								foreach ( $fields['fields'] as $field_id => $field ) :
815
									$field['id']     = ! empty( $field['id'] ) ? $field['id'] : $field_id;
816
									$field['repeat'] = true;
817
									$field['repeater_template'] = true;
818
819
									$field['repeater_field_name'] = self::get_repeater_field_name( $field, $fields );
820
									$field['field_attributes']['id'] = str_replace( array( '[', ']' ), array( '_', '', ), $field['repeater_field_name'] );
821
822
									echo self::render_tag( $field, $form );
823
								endforeach;
824
								?>
825
							</div>
826
						</td>
827
					</tr>
828
829
					<?php if ( ! empty( $repeater_field_values ) ) : ?>
830
						<!--Stored repeater field group-->
831
						<?php foreach ( $repeater_field_values as $index => $field_group ) : ?>
832
							<tr class="give-row">
833
								<td class="give-repeater-field-wrap give-column" colspan="2">
834
									<div class="give-row-head give-move">
835
										<button type="button" class="give-toggle-btn">
836
											<span class="give-toggle-indicator"></span>
837
										</button>
838
										<sapn class="give-remove" title="<?php esc_html_e( 'Remove Group', 'give' ); ?>">-
839
										</sapn>
840
										<h2>
841
											<span data-header-title="<?php echo $header_title; ?>"><?php echo $header_title; ?></span>
842
										</h2>
843
									</div>
844
									<div class="give-row-body">
845
										<?php
846
										foreach ( $fields['fields'] as $field_id => $field ) :
847
											$field['id']     = ! empty( $field['id'] ) ? $field['id'] : $field_id;
848
											$field['repeat'] = true;
849
850
											$field['repeater_field_name'] = self::get_repeater_field_name( $field, $fields, $index );
851
											$field['value'] = self::get_repeater_field_value( $field, $field_group, $fields );
852
											$field['field_attributes']['id']  = str_replace( array( '[', ']' ), array( '_', '', ), $field['repeater_field_name'] );
853
854
											echo self::render_tag( $field, $form );
855
										endforeach;
856
										?>
857
									</div>
858
								</td>
859
							</tr>
860
						<?php endforeach; ?>
861
862
					<?php elseif ( $add_default_donation_field ) : ?>
863
						<!--Default repeater field group-->
864
						<tr class="give-row">
865
							<td class="give-repeater-field-wrap give-column" colspan="2">
866
								<div class="give-row-head give-move">
867
									<button type="button" class="give-toggle-btn">
868
										<span class="give-toggle-indicator"></span>
869
									</button>
870
									<sapn class="give-remove" title="<?php esc_html_e( 'Remove Group', 'give' ); ?>">-
871
									</sapn>
872
									<h2>
873
										<span data-header-title="<?php echo $header_title; ?>"><?php echo $header_title; ?></span>
874
									</h2>
875
								</div>
876
								<div class="give-row-body">
877
									<?php
878
									foreach ( $fields['fields'] as $field_id => $field ) :
879
										$field['id']     = ! empty( $field['id'] ) ? $field['id'] : $field_id;
880
										$field['repeat'] = true;
881
										$field['repeater_default_template'] = true;
882
883
										$field['repeater_field_name'] = self::get_repeater_field_name( $field, $fields, 0 );
884
										$field['field_attributes']['id']  = str_replace( array( '[', ']' ), array( '_', '', ), $field['repeater_field_name'] );
885
886
										echo self::render_tag( $field, $form );
887
									endforeach;
888
									?>
889
								</div>
890
							</td>
891
						</tr>
892
					<?php endif; ?>
893
				</tbody>
894
				<tfoot>
895
					<tr>
896
						<?php
897
						$add_row_btn_title = isset( $fields['options']['add_button'] )
898
							? $add_row_btn_title = $fields['options']['add_button']
899
							: esc_html__( 'Add Row', 'give' );
900
						?>
901
						<td colspan="2" class="give-add-repeater-field-section-row-wrap">
902
							<button class="button button-primary give-add-repeater-field-section-row"><?php echo $add_row_btn_title; ?></button>
903
						</td>
904
					</tr>
905
				</tfoot>
906
			</table>
907
		</div>
908
		<?php
909
910
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
911
	}
912
913
914
	/**
915
	 * Render wrapper
916
	 *
917
	 * @since  1.9
918
	 * @access private
919
	 *
920
	 * @param  array $field
921
	 * @param  array $form
922
	 * @param  array $args
923
	 *
924
	 * @return string
925
	 */
926
	public static function render_field_wrapper( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
927
		ob_start();
928
929
		// Label: before field.
930
		if ( 'before' === $field['label_position'] ) {
931
			echo self::$instance->render_label( $field );
932
		}
933
934
		// Set before field html.
935
		$field['before_field'] = self::is_callback( $field['before_field'] )
936
			? self::render_callback( $field['before_field'] )
937
			: $field['before_field'];
938
939
		// Set after field html.
940
		$field['after_field'] = self::is_callback( $field['after_field'] )
941
			? self::render_callback( $field['after_field'] )
942
			: $field['after_field'];
943
944
		echo "{$field['before_field']}{{form_field}}{$field['after_field']}";
945
946
		// Label: before field.
947
		if ( 'after' === $field['label_position'] ) {
948
			echo self::$instance->render_label( $field );
949
		}
950
951
		$field_with_label = ob_get_clean();
952
953
		ob_start();
954
955
		if ( $field['wrapper'] ) :
956
957
			// Set before wrapper html.
958
			$field['before_field_wrapper'] = self::is_callback( $field['before_field_wrapper'] )
959
				? self::render_callback( $field['before_field_wrapper'] )
960
				: $field['before_field_wrapper'];
961
962
			echo $field['before_field_wrapper'];
963
964
			echo '<' . $field['wrapper_type'] . ' ' . self::$instance->get_attributes( $field['wrapper_attributes'] ) . '>';
965
				echo $field_with_label;
966
			echo "</{$field['wrapper_type']}>";
967
968
			// Set after wrapper html.
969
			$field['after_field_wrapper'] = self::is_callback( $field['after_field_wrapper'] )
970
				? self::render_callback( $field['after_field_wrapper'] )
971
				: $field['after_field_wrapper'];
972
973
			echo $field['after_field_wrapper'];
974
		else :
975
			echo $field_with_label;
976
		endif;
977
978
		return ob_get_clean();
979
	}
980
981
982
	/**
983
	 * Render label
984
	 *
985
	 * @since  1.9
986
	 * @access private
987
	 *
988
	 * @param  array $field
989
	 * @param  array $form
990
	 * @param  array $args
991
	 *
992
	 * @return string
993
	 */
994
	private function render_label( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
995
		ob_start();
996
		$label_type = ( 'fieldset' === $field['wrapper_type'] ? 'legend' : 'label' );
997
		?>
998
		<?php if ( ! empty( $field['label'] ) ) : ?>
999
			<?php
1000
			// Set before label html.
1001
			$field['before_field_label'] = self::is_callback( $field['before_field_label'] )
1002
				? self::render_callback( $field['before_field_label'] )
1003
				: $field['before_field_label'];
1004
			echo $field['before_field_label'];
1005
			?>
1006
			<<?php echo $label_type; ?> for="<?php echo $field['field_attributes']['id']; ?>" <?php echo self::get_attributes( $field['label_attributes'] ); ?>>
1007
1008
				<?php echo $field['label']; ?>
1009
1010
				<?php if ( $field['required'] ) : ?>
1011
					<span class="give-required-indicator">*</span>
1012
				<?php endif; ?>
1013
1014
				<?php if ( $field['label_tooltip'] ) : ?>
1015
					<span class="give-tooltip give-icon give-icon-question" data-tooltip="<?php echo $field['label_tooltip'] ?>"></span>
1016
				<?php endif; ?>
1017
			</<?php echo $label_type; ?>>
1018
			<?php
1019
			// Set after label html.
1020
			$field['after_field_label'] = self::is_callback( $field['after_field_label'] )
1021
				? self::render_callback( $field['after_field_label'] )
1022
				: $field['after_field_label'];
1023
			echo $field['after_field_label'];
1024
			?>
1025
		<?php endif; ?>
1026
		<?php
1027
		return ob_get_clean();
1028
	}
1029
1030
	/**
1031
	 * Get field attribute string from field arguments.
1032
	 *
1033
	 * @since  1.9
1034
	 * @access private
1035
	 *
1036
	 * @param array $attributes
1037
	 *
1038
	 * @return array|string
1039
	 */
1040
	private function get_attributes( $attributes ) {
1041
		$field_attributes_val = '';
1042
1043
		if ( ! empty( $attributes ) ) {
1044
			foreach ( $attributes as $attribute_name => $attribute_val ) {
1045
				$field_attributes_val[] = "{$attribute_name}=\"{$attribute_val}\"";
1046
			}
1047
		}
1048
1049
		if ( ! empty( $field_attributes_val ) ) {
1050
			$field_attributes_val = implode( ' ', $field_attributes_val );
1051
		}
1052
1053
		return $field_attributes_val;
1054
	}
1055
1056
	/**
1057
	 * Set default values for fields
1058
	 *
1059
	 * @since  1.0
1060
	 * @access private
1061
	 *
1062
	 * @param array $field
1063
	 * @param array $form
1064
	 * @param array $args
1065
	 *
1066
	 * @return array
1067
	 */
1068
	public static function set_default_values( $field, $form = null, $args = array() ) {
1069
		/**
1070
		 * Filter the field before set default values.
1071
		 *
1072
		 * @since 1.9
1073
		 *
1074
		 * @param array $field
1075
		 * @param array $form
1076
		 */
1077
		$field = ! empty( $args['fire_filter'] )
1078
			? apply_filters( 'give_field_api_pre_set_default_values', $field, $form )
1079
			: $field;
1080
1081
		switch ( self::$instance->get_field_type( $field ) ) {
1082
			case 'block':
1083
				// Set default values for block.
1084
				$field = wp_parse_args( $field, self::$block_defaults );
1085
1086
				// Set wrapper class.
1087
				$field['block_attributes']['class'] = empty( $field['block_attributes']['class'] )
1088
					? "give-block-wrap js-give-block-wrap give-block-{$field['id']}"
1089
					: trim( "give-block-wrap js-give-block-wrap give-block-{$field['id']} {$field['block_attributes']['class']}" );
1090
1091
				foreach ( $field['fields'] as $key => $single_field ) {
1092
					$single_field['id']    = ! empty( $single_field['id'] )
1093
						? $single_field['id']
1094
						: $key;
1095
					$field['fields'][ $key ] = self::$instance->set_default_values( $single_field, $form, array( 'fire_filter' => false ) );
1096
				}
1097
1098
				break;
1099
1100
			case 'section':
1101
				// Set default values for block.
1102
				$field = wp_parse_args( $field, self::$section_defaults );
1103
1104
				// Set wrapper class.
1105
				$field['section_attributes']['class'] = empty( $field['section_attributes']['class'] )
1106
					? 'give-section-wrap'
1107
					: trim( "give-section-wrap {$field['section_attributes']['class']}" );
1108
1109
				foreach ( $field['fields'] as $key => $single_field ) {
1110
					$single_field['id']    = ! empty( $single_field['id'] )
1111
						? $single_field['id']
1112
						: $key;
1113
					$field['fields'][ $key ] = self::$instance->set_default_values( $single_field, $form, array( 'fire_filter' => false ) );
1114
				}
1115
1116
				break;
1117
1118
			default:
1119
				// Set default values for field or section.
1120
				$field = wp_parse_args( $field, self::$field_defaults );
1121
1122
				// Set default class for label.
1123
				$field['label_attributes']['class'] = empty( $field['label_attributes']['class'] )
1124
					? 'give-label'
1125
					: trim( "give-label {$field['label_attributes']['class']}" );
1126
1127
				// Set field id.
1128
				$field['field_attributes']['id'] = ! isset( $field['field_attributes']['id'] )
1129
					? "give-{$field['id']}-field"
1130
					: $field['field_attributes']['id'];
1131
1132
				// Set field class.
1133
				$field['field_attributes']['class'] = empty( $field['field_attributes']['class'] )
1134
					? "give-field js-give-field"
1135
					: trim( "give-field js-give-field {$field['field_attributes']['class']}" );
1136
1137
				// Set wrapper class.
1138
				$field['wrapper_attributes']['class'] = empty( $field['wrapper_attributes']['class'] )
1139
					? "give-field-wrap {$field['id']}_field"
1140
					: trim( "give-field-wrap {$field['id']}_field {$field['wrapper_attributes']['class']}"  );
1141
1142
				// if( 'group' === $field['type'] && ! empty( $field['fields'] ) ) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1143
				// 	foreach ( $field['fields'] as $key => $single_field ) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1144
				// 		$single_field['id']    = ! empty( $single_field['id'] )
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1145
				// 			? $single_field['id']
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1146
				// 			: $key;
1147
				// 		$single_field['repeat'] = true;
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1148
				// 		$field['fields'][ $key ] = self::$instance->set_default_values( $single_field, $form, false );
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1149
				// 	}
1150
				// }
1151
1152
				/**
1153
				 * Filter the field values.
1154
				 *
1155
				 * @since 1.9
1156
				 *
1157
				 * @param array $field
1158
				 * @param array $form
1159
				 */
1160
				$field = apply_filters( 'give_field_api_set_values', $field, $form );
1161
		}
1162
1163
		/**
1164
		 * Filter the field after set default values.
1165
		 *
1166
		 * @since 1.9
1167
		 *
1168
		 * @param array $field
1169
		 * @param array $form
1170
		 */
1171
		$field = ! empty( $args['fire_filter'] )
1172
			? apply_filters( 'give_field_api_post_set_default_values', $field, $form )
1173
			: $field;
1174
1175
		return $field;
1176
	}
1177
1178
1179
	/**
1180
	 * Set responsive fields.
1181
	 *
1182
	 * @since  1.9
1183
	 * @access private
1184
	 *
1185
	 * @param $form
1186
	 *
1187
	 * @return mixed
1188
	 */
1189
	private function set_responsive_field( &$form ) {
1190
1191
		foreach ( $form['fields'] as $key => $field ) {
1192
			switch ( true ) {
1193
				case array_key_exists( 'fields', $field ):
1194
					foreach ( $field['fields'] as $section_field_index => $section_field ) {
1195
						if ( ! self::$instance->is_sub_section( $section_field ) ) {
1196
							continue;
1197
						}
1198
1199
						$form['fields'][ $key ]['fields'][ $section_field_index ]['wrapper_attributes']['class'] = 'give-form-col';
1200
1201
						if ( array_key_exists( 'sub_section_end', $section_field ) ) {
1202
							$form['fields'][ $key ]['fields'][ $section_field_index ]['wrapper_attributes']['class'] = 'give-form-col give-form-col-end';
1203
1204
							// Clear float left for next field.
1205
							$fields_keys = array_keys( $form['fields'][ $key ]['fields'] );
1206
1207
							if ( $next_field_key = array_search( $section_field_index, $fields_keys ) ) {
1208
								if (
1209
									! isset( $fields_keys[ $next_field_key + 1 ] )
1210
									|| ! isset( $form['fields'][ $key ]['fields'][ $fields_keys[ $next_field_key + 1 ] ] )
1211
								) {
1212
									continue;
1213
								}
1214
1215
								$next_field = $form['fields'][ $key ]['fields'][ $fields_keys[ $next_field_key + 1 ] ];
1216
1217
								$next_field['wrapper_attributes']['class'] = isset( $next_field['wrapper_attributes']['class'] )
1218
									? $next_field['wrapper_attributes']['class'] . ' give-clearfix'
1219
									: 'give-clearfix';
1220
1221
								$form['fields'][ $key ]['fields'][ $fields_keys[ $next_field_key + 1 ] ] = $next_field;
1222
							}
1223
						}
1224
					}
1225
1226
					break;
1227
1228
				default:
1229
					if ( ! self::$instance->is_sub_section( $field ) ) {
1230
						continue;
1231
					}
1232
1233
					$form['fields'][ $key ]['wrapper_attributes']['class'] = 'give-form-col';
1234
1235
					if ( array_key_exists( 'sub_section_end', $field ) ) {
1236
						$form['fields'][ $key ]['wrapper_attributes']['class'] = 'give-form-col give-form-col-end';
1237
1238
						// Clear float left for next field.
1239
						$fields_keys = array_keys( $form['fields'] );
1240
1241
						if ( $next_field_key = array_search( $key, $fields_keys ) ) {
1242
							$form['fields'][ $fields_keys[ $next_field_key + 1 ] ]['wrapper_attributes']['class'] = 'give-clearfix';
1243
						}
1244
					}
1245
			}
1246
		}
1247
	}
1248
1249
1250
	/**
1251
	 * Check if current field is part of sub section or not.
1252
	 *
1253
	 * @since  1.9
1254
	 * @access private
1255
	 *
1256
	 * @param $field
1257
	 *
1258
	 * @return bool
1259
	 */
1260
	private function is_sub_section( $field ) {
1261
		$is_sub_section = false;
1262
		if ( array_key_exists( 'sub_section_start', $field ) || array_key_exists( 'sub_section_end', $field ) ) {
1263
			$is_sub_section = true;
1264
		}
1265
1266
		return $is_sub_section;
1267
	}
1268
1269
1270
	/**
1271
	 * Get field type.
1272
	 *
1273
	 * @since  1.9
1274
	 * @access private
1275
	 *
1276
	 * @param  array $field
1277
	 * @param  array $form
1278
	 * @param  array $args
1279
	 *
1280
	 * @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...
1281
	 */
1282
	public static function get_field_type( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1283
		$field_type = 'field';
1284
1285
		if (
1286
			isset( $field['type'] )
1287
			&& 'block' === $field['type']
1288
		) {
1289
			$field_type = 'block';
1290
1291
		} elseif (
1292
			array_key_exists( 'fields', $field )
1293
			&& 'section' === $field['type']
1294
		) {
1295
			$field_type = 'section';
1296
1297
		}
1298
1299
		return $field_type;
1300
	}
1301
1302
	/**
1303
	 * Get field name.
1304
	 *
1305
	 * @since  1.9
1306
	 *
1307
	 * @param  array $field
1308
	 * @param  array $form
1309
	 * @param  array $args
1310
	 *
1311
	 * @return string
1312
	 */
1313
	public static function get_field_name( $field, $form = null, $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1314
		$field_name = esc_attr( empty( $field['repeat'] ) ? $field['id'] : $field['repeater_field_name'] );
1315
1316
		/**
1317
		 * Filter the field name.
1318
		 *
1319
		 * @since 1.8
1320
		 *
1321
		 * @param string $field_name
1322
		 */
1323
		$field_name = apply_filters( 'give_get_field_name', $field_name, $field );
1324
1325
		return $field_name;
1326
	}
1327
1328
	/**
1329
	 * Get repeater field id.
1330
	 *
1331
	 * @since  1.9
1332
	 *
1333
	 * @param array    $field
1334
	 * @param array    $fields
1335
	 * @param int|bool $default
1336
	 *
1337
	 * @return string
1338
	 */
1339
	public static function get_repeater_field_name( $field, $fields , $default = false ) {
1340
		$row_placeholder = false !== $default ? $default : '{{row-count-placeholder}}';
1341
1342
		// Get field id.
1343
		$field_id = "{$fields['id']}[{$row_placeholder}][{$field['id']}]";
1344
1345
		/**
1346
		 * Filter the specific repeater field id
1347
		 *
1348
		 * @since 1.8
1349
		 *
1350
		 * @param string $field_id
1351
		 */
1352
		$field_id = apply_filters( "give_get_repeater_field_{$field['id']}_name", $field_id, $field, $fields, $default );
1353
1354
		/**
1355
		 * Filter the repeater field id
1356
		 *
1357
		 * @since 1.8
1358
		 *
1359
		 * @param string $field_id
1360
		 */
1361
		$field_id = apply_filters( 'give_get_repeater_field_name', $field_id, $field, $fields, $default );
1362
1363
		return $field_id;
1364
	}
1365
1366
1367
	/**
1368
	 * Get repeater field value.
1369
	 *
1370
	 * @since 1.9
1371
	 * @access public
1372
	 *
1373
	 * @param array $field
1374
	 * @param array $field_value_group
1375
	 * @param array $fields
1376
	 *
1377
	 * @return mixed
1378
	 */
1379
	public static function get_repeater_field_value( $field, $field_value_group, $fields ) {
1380
		$field_value = ( isset( $field_value_group[ $field['id'] ] ) ? $field_value_group[ $field['id'] ] : '' );
1381
1382
		/**
1383
		 * Filter the specific repeater field value
1384
		 *
1385
		 * @since 1.8
1386
		 *
1387
		 * @param string $field_id
1388
		 */
1389
		$field_value = apply_filters( "give_get_repeater_field_{$field['id']}_value", $field_value, $field, $field_value_group, $fields );
1390
1391
		/**
1392
		 * Filter the repeater field value
1393
		 *
1394
		 * @since 1.8
1395
		 *
1396
		 * @param string $field_id
1397
		 */
1398
		$field_value = apply_filters( 'give_get_repeater_field_value', $field_value, $field, $field_value_group, $fields );
1399
1400
		return $field_value;
1401
	}
1402
1403
1404
	/**
1405
	 * Check if string or array is callback or not.
1406
	 *
1407
	 * @since  1.9
1408
	 * @access public
1409
	 *
1410
	 * @param $callback
1411
	 *
1412
	 * @return bool
1413
	 */
1414
	public static function is_callback( $callback ) {
1415
		$is_callback = false;
1416
1417
		// Process callback to get field html.
1418
		if ( is_string( $callback ) && function_exists( "$callback" ) ) {
1419
			$is_callback = true;
1420
		} elseif ( is_array( $callback ) && method_exists( $callback[0], "$callback[1]" ) ) {
1421
			$is_callback = true;
1422
		}
1423
1424
		return $is_callback;
1425
	}
1426
}
1427
1428
// @todo implement required and aria-required for all form fields. required should be custom tag because we want custom validation for form instead html5.
1429