Completed
Push — issues/1038 ( a20520...503146 )
by Ravinder
20:53
created

Give_Fields_API::is_button()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
rs 10
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'                => '',
33
		'required'             => false,
34
		'options'              => array(),
35
36
		// Set default value to field.
37
		'default'              => '',
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
50
		// Add description to field as tooltip.
51
		'tooltip'              => '',
52
53
		// Show multiple fields in same row with in sub section.
54
		'sub_section_start'    => false,
55
		'sub_section_end'      => false,
56
57
		// Add custom attributes.
58
		'field_attributes'     => array(),
59
		'wrapper_attributes'   => array(),
60
61
		// Show/Hide field in before/after modal view.
62
		'show_without_modal'   => false,
63
		'show_within_modal'    => true,
64
65
		// Params to edit field html.
66
		'before_field'         => '',
67
		'after_field'          => '',
68
		'before_field_wrapper' => '',
69
		'after_field_wrapper'  => '',
70
		'before_label'         => '',
71
		'after_label'          => '',
72
73
		// Manually render field.
74
		'callback'             => '',
75
76
	);
77
78
	/**
79
	 * The defaults for all sections.
80
	 *
81
	 * @since  1.9
82
	 * @access static
83
	 */
84
	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...
85
		'type'               => 'section',
86
		'label'              => '',
87
		'id'               => '',
88
		'section_attributes' => array(),
89
90
		// Manually render section.
91
		'callback'           => '',
92
	);
93
94
	/**
95
	 * The defaults for all blocks.
96
	 *
97
	 * @since  1.9
98
	 * @access static
99
	 */
100
	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...
101
		'type'             => 'block',
102
		'label'            => '',
103
		'id'             => '',
104
		'block_attributes' => array(),
105
106
		// Manually render section.
107
		'callback'         => '',
108
	);
109
110
111
	private function __construct() {
112
	}
113
114
115
	/**
116
	 * Get instance.
117
	 *
118
	 * @return static
119
	 */
120
	public static function get_instance() {
121
		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...
122
			self::$instance = new static();
123
		}
124
125
		return self::$instance;
126
	}
127
128
	/**
129
	 * Initialize this module
130
	 *
131
	 * @since  1.9
132
	 * @access static
133
	 */
134
	public function init() {
135
		add_filter( 'give_form_api_render_form_tags', array( $this, 'render_tags' ), 10, 2 );
136
	}
137
138
139
	/**
140
	 * Render custom field.
141
	 *
142
	 * @since  1.0
143
	 * @access private
144
	 *
145
	 * @param array $field
146
	 * @param array $form
147
	 *
148
	 * @return bool
149
	 */
150
	private function render_custom_field( $field, $form = null ) {
151
		$field = self::$instance->set_default_values( $field, $form );
152
153
		$field_html = '';
154
155
		if ( empty( $field['callback'] ) ) {
156
			$callback = $field['callback'];
157
158
			// Process callback to get field html.
159
			if ( is_string( $callback ) && function_exists( "$callback" ) ) {
160
				$field_html = $callback( $field );
161
			} elseif ( is_array( $callback ) && method_exists( $callback[0], "$callback[1]" ) ) {
162
				$field_html = $callback[0]->$callback[1]( $field );
163
			}
164
		}
165
166
		return $field_html;
167
	}
168
169
170
	/**
171
	 * Render `{{form_fields}}` tag.
172
	 *
173
	 * @since  1.9
174
	 * @access private
175
	 *
176
	 * @param  string $form_html
177
	 * @param  array  $form
178
	 *
179
	 * @return string
180
	 */
181
	public function render_tags( $form_html, $form ) {
182
		// Bailout: If form does not contain any field.
183
		if ( empty( $form['fields'] ) ) {
184
			str_replace( '{{form_fields}}', '', $form_html );
185
186
			return $form_html;
187
		}
188
189
		$fields_html = '';
190
191
		// Set responsive fields.
192
		self::$instance->set_responsive_field( $form );
193
194
		// Render fields.
195
		foreach ( $form['fields'] as $key => $field ) {
196
			// Set default value.
197
			$field['id'] = empty( $field['id'] ) ? $key : $field['id'];
198
199
			// Render custom form with callback.
200
			if ( $field_html = self::$instance->render_custom_field( $field, $form ) ) {
201
				$fields_html .= $field_html;
202
			}
203
204
			switch ( true ) {
205
				// Block.
206
				case ( 'block' === self::get_field_type( $field ) ):
207
					$fields_html .= self::$instance->render_block( $field, $form );
208
					break;
209
210
				// Section.
211
				case ( 'section' === self::get_field_type( $field ) ):
212
					$fields_html .= self::$instance->render_section( $field, $form );
213
					break;
214
215
				// Field
216
				default:
217
					$fields_html .= self::render_tag( $field, $form );
218
			}
219
		}
220
221
		$form_html = str_replace( '{{form_fields}}', $fields_html, $form_html );
222
223
		return $form_html;
224
	}
225
226
227
	/**
228
	 * Render section.
229
	 *
230
	 * @since  1.9
231
	 * @access public
232
	 *
233
	 * @param array $section
234
	 * @param array $form
235
	 * @param array $args Helper argument to render section.
236
	 *
237
	 * @return string
238
	 */
239
	public static function render_section( $section, $form = null, $args = array() ) {
240
		// Set default values if necessary.
241
		if ( ! isset( $args['set_default'] ) || (bool) $args['set_default'] ) {
242
			$section = self::$instance->set_default_values( $section, $form );
243
		}
244
245
		ob_start();
246
		?>
247
		<fieldset <?php echo self::$instance->get_attributes( $section['section_attributes'] ); ?>>
248
			<?php
249
			// Legend.
250
			if ( ! empty( $section['label'] ) ) {
251
				echo "<legend>{$section['label']}</legend>";
252
			};
253
254
			// Fields.
255
			foreach ( $section['fields'] as $key => $field ) {
256
				echo self::render_tag( $field, $form, array( 'set_default' => false ) );
257
			}
258
			?>
259
		</fieldset>
260
		<?php
261
		return ob_get_clean();
262
	}
263
264
265
	/**
266
	 * Render block.
267
	 *
268
	 * @since  1.9
269
	 * @access public
270
	 *
271
	 * @param array $block
272
	 * @param array $form
273
	 * @param array $args Helper argument to render section.
274
	 *
275
	 * @return string
276
	 */
277
	public static function render_block( $block, $form = null, $args = array() ) {
278
		// Set default values if necessary.
279
		if ( ! isset( $args['set_default'] ) || (bool) $args['set_default'] ) {
280
			$block = self::$instance->set_default_values( $block, $form );
281
		}
282
283
		ob_start();
284
		?>
285
		<div <?php echo self::$instance->get_attributes( $block['block_attributes'] ); ?>>
286
			<?php
287
			// Fields.
288
			foreach ( $block['fields'] as $key => $field ) {
289
				echo array_key_exists( 'fields', $field )
290
					? self::render_section( $field, $form, array( 'set_default' => false ) )
291
					: self::render_tag( $field, $form, array( 'set_default' => false ) );
292
			}
293
			?>
294
		</div>
295
		<?php
296
		return ob_get_clean();
297
	}
298
299
	/**
300
	 * Render tag
301
	 *
302
	 * @since   1.9
303
	 * @access  public
304
	 *
305
	 * @param array $field
306
	 * @param array $form
307
	 * @param array $args Helper argument to render section.
308
	 *
309
	 * @return string
310
	 */
311
	public static function render_tag( $field, $form = null, $args = array() ) {
312
		// Enqueue scripts.
313
		Give_Form_API::enqueue_scripts();
314
315
		// Set default values if necessary.
316
		if ( ! isset( $args['set_default'] ) || (bool) $args['set_default'] ) {
317
			$field = self::$instance->set_default_values( $field, $form );
318
		}
319
320
		$field_html     = '';
321
		$functions_name = "render_{$field['type']}_field";
322
323
		if ( 'section' === self::$instance->get_field_type( $field ) ) {
324
			$field_html = self::$instance->render_section( $field, $form, array( 'set_default' => false ) );
325
326
		} elseif ( method_exists( self::$instance, $functions_name ) ) {
327
			$field_html = self::$instance->{$functions_name}( $field );
328
329
		}
330
331
		/**
332
		 * Filter the custom field type html.
333
		 * Developer can use this hook to render custom field type.
334
		 *
335
		 * @since 1.9
336
		 *
337
		 * @param string $field_html
338
		 * @param array  $field
339
		 * @param array  $form
340
		 */
341
		$field_html = apply_filters(
342
			"give_field_api_render_{$field['type']}_field",
343
			$field_html,
344
			$field,
345
			$form
346
		);
347
348
		return $field_html;
349
	}
350
351
352
	/**
353
	 * Render text field.
354
	 *
355
	 * @since  1.9
356
	 * @access public
357
	 *
358
	 * @param  array $field
359
	 *
360
	 * @return string
361
	 */
362
	public static function render_text_field( $field ) {
363
		$field_wrapper = self::$instance->render_field_wrapper( $field );
364
		ob_start();
365
		?>
366
		<input
367
				type="<?php echo $field['type']; ?>"
368
				name="<?php echo self::get_field_name( $field ); ?>"
369
			<?php echo( $field['required'] ? 'required=""' : '' ); ?>
370
			<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
371
		>
372
		<?php
373
374
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
375
	}
376
377
	/**
378
	 * Render submit field.
379
	 *
380
	 * @since  1.9
381
	 * @access public
382
	 *
383
	 * @param  array $field
384
	 *
385
	 * @return string
386
	 */
387
	public static function render_submit_field( $field ) {
388
		return self::$instance->render_text_field( $field );
389
	}
390
391
	/**
392
	 * Render checkbox field.
393
	 *
394
	 * @since  1.9
395
	 * @access public
396
	 *
397
	 * @param  array $field
398
	 *
399
	 * @return string
400
	 */
401
	public static function render_checkbox_field( $field ) {
402
		$field_wrapper = self::$instance->render_field_wrapper( $field );
403
		ob_start();
404
		?>
405
		<input
406
				type="checkbox"
407
				name="<?php echo self::get_field_name( $field ); ?>"
408
			<?php echo( $field['required'] ? 'required=""' : '' ); ?>
409
			<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
410
		>
411
		<?php
412
413
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
414
	}
415
416
	/**
417
	 * Render email field.
418
	 *
419
	 * @since  1.9
420
	 * @access public
421
	 *
422
	 * @param  array $field
423
	 *
424
	 * @return string
425
	 */
426
	public static function render_email_field( $field ) {
427
		return self::$instance->render_text_field( $field );
428
	}
429
430
	/**
431
	 * Render number field.
432
	 *
433
	 * @since  1.9
434
	 * @access public
435
	 *
436
	 * @param  array $field
437
	 *
438
	 * @return string
439
	 */
440
	public static function render_number_field( $field ) {
441
		return self::$instance->render_text_field( $field );
442
	}
443
444
	/**
445
	 * Render password field.
446
	 *
447
	 * @since  1.9
448
	 * @access public
449
	 *
450
	 * @param  array $field
451
	 *
452
	 * @return string
453
	 */
454
	public static function render_password_field( $field ) {
455
		return self::$instance->render_text_field( $field );
456
	}
457
458
	/**
459
	 * Render button field.
460
	 *
461
	 * @since  1.9
462
	 * @access public
463
	 *
464
	 * @param  array $field
465
	 *
466
	 * @return string
467
	 */
468
	public static function render_button_field( $field ) {
469
		return self::$instance->render_text_field( $field );
470
	}
471
472
	/**
473
	 * Render hidden field.
474
	 *
475
	 * @since  1.9
476
	 * @access public
477
	 *
478
	 * @param  array $field
479
	 *
480
	 * @return string
481
	 */
482
	public static function render_hidden_field( $field ) {
483
		$field['wrapper'] = false;
484
485
		return self::$instance->render_text_field( $field );
486
	}
487
488
	/**
489
	 * Render textarea field.
490
	 *
491
	 * @since  1.9
492
	 * @access public
493
	 *
494
	 * @param  array $field
495
	 *
496
	 * @return string
497
	 */
498
	public static function render_textarea_field( $field ) {
499
		$field_wrapper = self::$instance->render_field_wrapper( $field );
500
		ob_start();
501
		?>
502
		<textarea
503
				name="<?php echo self::get_field_name( $field ); ?>"
504
			<?php echo( $field['required'] ? 'required=""' : '' ); ?>
505
			<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
506
		><?php echo $field ['value']; ?></textarea>
507
508
509
		<?php
510
511
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
512
	}
513
514
	/**
515
	 * Render select field.
516
	 *
517
	 * @since  1.9
518
	 * @access public
519
	 *
520
	 * @param  array $field
521
	 *
522
	 * @return string
523
	 */
524
	public static function render_select_field( $field ) {
525
		$field_wrapper = self::$instance->render_field_wrapper( $field );
526
		ob_start();
527
528
		$options_html = '';
529
		foreach ( $field['options'] as $key => $option ) {
530
			$selected = '';
531
532
			if ( is_array( $field['value'] ) ) {
533
				$selected = in_array( $key, $field['value'] )
534
					? 'selected="selected"'
535
					: '';
536
537
			} else {
538
				$selected = selected( $key, $field['value'], false );
539
			}
540
541
			$options_html .= '<option value="' . $key . '" ' . $selected . '>' . $option . '</option>';
542
		}
543
		?>
544
545
		<select
546
				name="<?php echo self::get_field_name( $field ); ?>"
547
			<?php echo( $field['required'] ? 'required=""' : '' ); ?>
548
			<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
549
		><?php echo $options_html; ?></select>
550
		<?php
551
552
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
553
	}
554
555
	/**
556
	 * Render multi select field.
557
	 *
558
	 * @since  1.9
559
	 * @access public
560
	 *
561
	 * @param  array $field
562
	 *
563
	 * @return string
564
	 */
565
	public static function render_multi_select_field( $field ) {
566
		$field['field_attributes'] = array_merge( $field['field_attributes'], array( 'multiple' => 'multiple' ) );
567
		$field['id']             = "{$field['id']}[]";
568
569
		return self::$instance->render_select_field( $field );
570
	}
571
572
	/**
573
	 * Render radio field.
574
	 *
575
	 * @since  1.9
576
	 * @access public
577
	 *
578
	 * @param  array $field
579
	 *
580
	 * @return string
581
	 */
582
	public static function render_radio_field( $field ) {
583
		$field['wrapper_type'] = 'p' === $field['wrapper_type']
584
			? 'fieldset'
585
			: $field['wrapper_type'];
586
587
588
		$field_wrapper = self::$instance->render_field_wrapper( $field );
589
		ob_start();
590
591
		$id_base = $field['field_attributes']['id'];
592
		unset( $field['field_attributes']['id'] );
593
594
		echo '<ul>';
595
		foreach ( $field['options'] as $key => $option ) :
596
			?>
597
			<li>
598
				<label class="give-label" for="<?php echo "{$id_base}-{$key}" ?>">
599
					<input
600
							type="<?php echo $field['type']; ?>"
601
							name="<?php echo self::get_field_name( $field ); ?>"
602
							value="<?php echo $key; ?>"
603
							id="<?php echo "{$id_base}-{$key}"; ?>"
604
						<?php checked( $key, $field['value'] ) ?>
605
						<?php echo( $field['required'] ? 'required=""' : '' ); ?>
606
						<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
607
					><?php echo $option; ?>
608
				</label>
609
			</li>
610
			<?php
611
		endforeach;
612
		echo '</ul>';
613
614
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
615
	}
616
617
	/**
618
	 * Render multi checkbox field.
619
	 *
620
	 * @since  1.9
621
	 * @access public
622
	 *
623
	 * @param  array $field
624
	 *
625
	 * @return string
626
	 */
627
	public static function render_multi_checkbox_field( $field ) {
628
		$field['wrapper_type'] = 'p' === $field['wrapper_type']
629
			? 'fieldset'
630
			: $field['wrapper_type'];
631
632
		$field_wrapper = self::$instance->render_field_wrapper( $field );
633
		ob_start();
634
635
		$id_base = $field['field_attributes']['id'];
636
		unset( $field['field_attributes']['id'] );
637
638
		echo '<ul>';
639
		foreach ( $field['options'] as $key => $option ) :
640
			$checked = ! empty( $field['value'] ) && in_array( $key, $field['value'] )
641
				? 'checked="checked"'
642
				: '';
643
			?>
644
			<li>
645
				<label class="give-label" for="<?php echo "{$id_base}-{$key}" ?>">
646
					<input
647
							type="checkbox"
648
							name="<?php echo self::get_field_name( $field ); ?>[]"
649
							value="<?php echo $key; ?>"
650
							id="<?php echo "{$id_base}-{$key}"; ?>"
651
						<?php echo $checked ?>
652
						<?php echo( $field['required'] ? 'required=""' : '' ); ?>
653
						<?php echo self::$instance->get_attributes( $field['field_attributes'] ); ?>
654
					><?php echo $option; ?>
655
				</label>
656
			</li>
657
			<?php
658
		endforeach;
659
		echo '</ul>';
660
661
662
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
663
	}
664
665
666
	/**
667
	 * Render group field
668
	 *
669
	 * @since 1.9
670
	 * @access public
671
	 *
672
	 * @param array $fields
673
	 * @param array $form
674
	 *
675
	 * @return string
676
	 */
677
	public static function render_group_field( $fields, $form = null ) {
678
		// Bailout.
679
		if ( ! isset( $fields['fields'] ) || empty( $fields['fields'] ) ) {
680
			return '';
681
		}
682
683
		$group_numbering       = isset( $fields['options']['group_numbering'] ) ? (int) $fields['options']['group_numbering'] : 0;
684
		$close_tabs            = isset( $fields['options']['close_tabs'] ) ? (int) $fields['options']['close_tabs'] : 0;
685
		$repeater_field_values = $fields['value'];
686
		$header_title          = isset( $fields['options']['header_title'] )
687
			? $fields['options']['header_title']
688
			: esc_attr__( 'Group', 'give' );
689
690
		$add_default_donation_field = false;
691
692
		// Check if level is not created or we have to add default level.
693
		if ( is_array( $repeater_field_values ) && ( $fields_count = count( $repeater_field_values ) ) ) {
694
			$repeater_field_values = array_values( $repeater_field_values );
695
		} else {
696
			$fields_count               = 1;
697
			$add_default_donation_field = true;
698
		}
699
700
		$field_wrapper = self::$instance->render_field_wrapper( $fields );
701
702
		ob_start();
703
		?>
704
		<div class="give-repeatable-field-section" id="<?php echo "{$fields['id']}_field"; ?>"
705
			 data-group-numbering="<?php echo $group_numbering; ?>" data-close-tabs="<?php echo $close_tabs; ?>">
706
			<?php if ( ! empty( $fields['label'] ) ) : ?>
707
				<p class="give-repeater-field-name"><?php echo $fields['label']; ?></p>
708
			<?php endif; ?>
709
710
			<?php if ( ! empty( $fields['description'] ) ) : ?>
711
				<p class="give-repeater-field-description"><?php echo $fields['description']; ?></p>
712
			<?php endif; ?>
713
714
			<table class="give-repeatable-fields-section-wrapper" cellspacing="0">
715
				<?php
716
717
				?>
718
				<tbody class="container"<?php echo " data-rf-row-count=\"{$fields_count}\""; ?>>
719
					<!--Repeater field group template-->
720
					<tr class="give-template give-row">
721
						<td class="give-repeater-field-wrap give-column" colspan="2">
722
							<div class="give-row-head give-move">
723
								<button type="button" class="give-toggle-btn">
724
									<span class="give-toggle-indicator"></span>
725
								</button>
726
								<span class="give-remove" title="<?php esc_html_e( 'Remove Group', 'give' ); ?>">-</span>
727
								<h2>
728
									<span data-header-title="<?php echo $header_title; ?>"><?php echo $header_title; ?></span>
729
								</h2>
730
							</div>
731
							<div class="give-row-body">
732
								<?php
733
								foreach ( $fields['fields'] as $field ) :
734
									$field['repeater_field_name'] = give_get_repeater_field_id( $field, $fields );
735
									$field['value'] = $field['field_attributes']['value'] = $field['default'];
736
737
738
									//$single_field['attributes']['value'] = apply_filters( "give_default_field_group_field_{$field['id']}_value", ( ! empty( $field['default'] ) ? $field['default'] : '' ), $field );
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% 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...
739
									$field['field_attributes']['id'] = str_replace( array( '[', ']' ), array( '_', '', ), $field['repeater_field_name'] );
740
									echo self::render_tag( $field, $form, array( 'set_default' => false ) );
741
								endforeach;
742
								?>
743
							</div>
744
						</td>
745
					</tr>
746
747
					<?php if ( ! empty( $repeater_field_values ) ) : ?>
748
						<!--Stored repeater field group-->
749
						<?php foreach ( $repeater_field_values as $index => $field_group ) : ?>
750
							<tr class="give-row">
751
								<td class="give-repeater-field-wrap give-column" colspan="2">
752
									<div class="give-row-head give-move">
753
										<button type="button" class="give-toggle-btn">
754
											<span class="give-toggle-indicator"></span>
755
										</button>
756
										<sapn class="give-remove" title="<?php esc_html_e( 'Remove Group', 'give' ); ?>">-
757
										</sapn>
758
										<h2>
759
											<span data-header-title="<?php echo $header_title; ?>"><?php echo $header_title; ?></span>
760
										</h2>
761
									</div>
762
									<div class="give-row-body">
763
										<?php
764
										foreach ( $fields['fields'] as $field ) :
765
											$field['repeater_field_name'] = give_get_repeater_field_id( $field, $fields, $index );
766
											$field['value'] = $field['field_attributes']['value'] = ! empty( $repeater_field_values[ $index ][ $field['id'] ] )
767
												? $repeater_field_values[ $index ][ $field['id'] ]
768
												: $field['default'];
769
770
											//$single_field['attributes']['value'] = apply_filters( "give_default_field_group_field_{$field['id']}_value", ( ! empty( $field['default'] ) ? $field['default'] : '' ), $field );
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% 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...
771
											$field['field_attributes']['id']  = str_replace( array( '[', ']' ), array( '_', '', ), $field['repeater_field_name'] );
772
773
											echo self::render_tag( $field, $form, array( 'set_default' => false ) );
774
										endforeach;
775
										?>
776
									</div>
777
								</td>
778
							</tr>
779
						<?php endforeach; ?>
780
781
					<?php elseif ( $add_default_donation_field ) : ?>
782
						<!--Default repeater field group-->
783
						<tr class="give-row">
784
							<td class="give-repeater-field-wrap give-column" colspan="2">
785
								<div class="give-row-head give-move">
786
									<button type="button" class="give-toggle-btn">
787
										<span class="give-toggle-indicator"></span>
788
									</button>
789
									<sapn class="give-remove" title="<?php esc_html_e( 'Remove Group', 'give' ); ?>">-
790
									</sapn>
791
									<h2>
792
										<span data-header-title="<?php echo $header_title; ?>"><?php echo $header_title; ?></span>
793
									</h2>
794
								</div>
795
								<div class="give-row-body">
796
									<?php
797
									foreach ( $fields['fields'] as $field ) :
798
										$field['repeater_field_name'] = give_get_repeater_field_id( $field, $fields, 0 );
799
										$field['value'] = $field['field_attributes']['value'] = $field['default'];
800
801
										//$single_field['attributes']['value'] = apply_filters( "give_default_field_group_field_{$field['id']}_value", ( ! empty( $field['default'] ) ? $field['default'] : '' ), $field );
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% 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...
802
										$field['field_attributes']['id']  = str_replace( array( '[', ']' ), array( '_', '', ), $field['repeater_field_name'] );
803
804
										echo self::render_tag( $field, $form, array( 'set_default' => false ) );
805
									endforeach;
806
									?>
807
								</div>
808
							</td>
809
						</tr>
810
					<?php endif; ?>
811
				</tbody>
812
				<tfoot>
813
					<tr>
814
						<?php
815
						$add_row_btn_title = isset( $fields['options']['add_button'] )
816
							? $add_row_btn_title = $fields['options']['add_button']
817
							: esc_html__( 'Add Row', 'give' );
818
						?>
819
						<td colspan="2" class="give-add-repeater-field-section-row-wrap">
820
							<button class="button button-primary give-add-repeater-field-section-row"><?php echo $add_row_btn_title; ?></button>
821
						</td>
822
					</tr>
823
				</tfoot>
824
			</table>
825
		</div>
826
		<?php
827
828
		return str_replace( '{{form_field}}', ob_get_clean(), $field_wrapper );
829
	}
830
831
832
	/**
833
	 * Render wrapper
834
	 *
835
	 * @since  1.9
836
	 * @access private
837
	 *
838
	 * @param $field
839
	 *
840
	 * @return string
841
	 */
842
	public static function render_field_wrapper( $field ) {
843
		ob_start();
844
845
		if ( $field['wrapper'] ) :
846
847
			echo $field['before_field_wrapper'];
848
			?>
849
			<<?php echo $field['wrapper_type']; ?> <?php echo self::$instance->get_attributes( $field['wrapper_attributes'] ); ?>>
850
			<?php
851
			// Label: before field.
852
			if ( 'before' === $field['label_position'] ) {
853
				echo self::$instance->render_label( $field );
854
			}
855
856
			echo "{$field['before_field']}{{form_field}}{$field['after_field']}";
857
858
			// Label: before field.
859
			if ( 'after' === $field['label_position'] ) {
860
				echo self::$instance->render_label( $field );
861
			}
862
			?>
863
			</<?php echo $field['wrapper_type']; ?>>
864
			<?php
865
			echo $field['after_field_wrapper'];
866
		else :
867
			echo "{$field['before_field']}{{form_field}}{$field['after_field']}";
868
		endif;
869
870
		return ob_get_clean();
871
	}
872
873
874
	/**
875
	 * Render label
876
	 *
877
	 * @since  1.9
878
	 * @access private
879
	 *
880
	 * @param $field
881
	 *
882
	 * @return string
883
	 */
884
	private function render_label( $field ) {
885
		ob_start();
886
		?>
887
		<?php if ( ! empty( $field['label'] ) ) : ?>
888
			<?php echo $field['before_label']; ?>
889
			<label class="give-label" for="<?php echo $field['field_attributes']['id']; ?>">
890
891
				<?php echo $field['label']; ?>
892
893
				<?php if ( $field['required'] ) : ?>
894
					<span class="give-required-indicator">*</span>
895
				<?php endif; ?>
896
897
				<?php if ( $field['tooltip'] ) : ?>
898
					<span class="give-tooltip give-icon give-icon-question" data-tooltip="<?php echo $field['tooltip'] ?>"></span>
899
				<?php endif; ?>
900
			</label>
901
			<?php echo $field['after_label']; ?>
902
		<?php endif; ?>
903
		<?php
904
		return ob_get_clean();
905
	}
906
907
	/**
908
	 * Get field attribute string from field arguments.
909
	 *
910
	 * @since  1.9
911
	 * @access private
912
	 *
913
	 * @param array $attributes
914
	 *
915
	 * @return array|string
916
	 */
917
	private function get_attributes( $attributes ) {
918
		$field_attributes_val = '';
919
920
		if ( ! empty( $attributes ) ) {
921
			foreach ( $attributes as $attribute_name => $attribute_val ) {
922
				$field_attributes_val[] = "{$attribute_name}=\"{$attribute_val}\"";
923
			}
924
		}
925
926
		if ( ! empty( $field_attributes_val ) ) {
927
			$field_attributes_val = implode( ' ', $field_attributes_val );
928
		}
929
930
		return $field_attributes_val;
931
	}
932
933
	/**
934
	 * Set default values for fields
935
	 *
936
	 * @since  1.0
937
	 * @access private
938
	 *
939
	 * @param array $field
940
	 * @param array $form
941
	 * @param bool  $fire_filter
942
	 *
943
	 * @return array
944
	 */
945
	public static function set_default_values( $field, $form = null, $fire_filter = true ) {
946
		/**
947
		 * Filter the field before set default values.
948
		 *
949
		 * @since 1.9
950
		 *
951
		 * @param array $field
952
		 * @param array $form
953
		 */
954
		$field = $fire_filter
955
			? apply_filters( 'give_field_api_pre_set_default_values', $field, $form )
956
			: $field;
957
958
		switch ( self::$instance->get_field_type( $field ) ) {
959
			case 'block':
960
				// Set default values for block.
961
				$field = wp_parse_args( $field, self::$block_defaults );
962
963
				// Set wrapper class.
964
				$field['block_attributes']['class'] = empty( $field['block_attributes']['class'] )
965
					? "give-block-wrap js-give-block-wrapper give-block-{$field['id']}"
966
					: trim( "give-block-wrap js-give-block-wrapper give-block-{$field['id']} {$field['block_attributes']['class']}" );
967
968
				foreach ( $field['fields'] as $key => $single_field ) {
969
					$single_field['id']    = ! empty( $single_field['id'] )
970
						? $single_field['id']
971
						: $key;
972
					$field['fields'][ $key ] = self::$instance->set_default_values( $single_field, $form, false );
973
				}
974
975
				break;
976
977
			case 'section':
978
				// Set default values for block.
979
				$field = wp_parse_args( $field, self::$section_defaults );
980
981
				// Set wrapper class.
982
				$field['section_attributes']['class'] = empty( $field['section_attributes']['class'] )
983
					? 'give-section-wrap'
984
					: trim( "give-section-wrap {$field['section_attributes']['class']}" );
985
986
				foreach ( $field['fields'] as $key => $single_field ) {
987
					$single_field['id']    = ! empty( $single_field['id'] )
988
						? $single_field['id']
989
						: $key;
990
					$field['fields'][ $key ] = self::$instance->set_default_values( $single_field, $form, false );
991
				}
992
993
				break;
994
995
			default:
996
				// Set default values for field or section.
997
				$field = wp_parse_args( $field, self::$field_defaults );
998
999
				// Set ID.
1000
				$field['field_attributes']['id'] = empty( $field['field_attributes']['id'] )
1001
					? "give-{$field['id']}-field"
1002
					: $field['field_attributes']['id'];
1003
1004
				// Set class.
1005
				$field['field_attributes']['class'] = empty( $field['field_attributes']['class'] )
1006
					? "give-field js-give-field give-field-type-{$field['type']}"
1007
					: trim( "give-field js-give-field give-field-type-{$field['type']} {$field['field_attributes']['class']}" );
1008
1009
				// Set wrapper class.
1010
				$field['wrapper_attributes']['class'] = empty( $field['wrapper_attributes']['class'] )
1011
					? 'give-field-wrap'
1012
					: 'give-field-wrap ' . trim( $field['wrapper_attributes']['class'] );
1013
1014
				if( 'group' === $field['type'] && ! empty( $field['fields'] ) ) {
1015
					foreach ( $field['fields'] as $key => $single_field ) {
1016
						$single_field['id']    = ! empty( $single_field['id'] )
1017
							? $single_field['id']
1018
							: $key;
1019
						$single_field['repeat'] = true;
1020
						$field['fields'][ $key ] = self::$instance->set_default_values( $single_field, $form, false );
1021
					}
1022
				}
1023
1024
				/**
1025
				 * Filter the field values.
1026
				 *
1027
				 * @since 1.9
1028
				 *
1029
				 * @param array $field
1030
				 * @param array $form
1031
				 */
1032
				$field = apply_filters( 'give_field_api_set_values', $field, $form );
1033
		}
1034
1035
		/**
1036
		 * Filter the field after set default values.
1037
		 *
1038
		 * @since 1.9
1039
		 *
1040
		 * @param array $field
1041
		 * @param array $form
1042
		 */
1043
		$field = $fire_filter
1044
			? apply_filters( 'give_field_api_post_set_default_values', $field, $form )
1045
			: $field;
1046
1047
		return $field;
1048
	}
1049
1050
1051
	/**
1052
	 * Set responsive fields.
1053
	 *
1054
	 * @since  1.9
1055
	 * @access private
1056
	 *
1057
	 * @param $form
1058
	 *
1059
	 * @return mixed
1060
	 */
1061
	private function set_responsive_field( &$form ) {
1062
1063
		foreach ( $form['fields'] as $key => $field ) {
1064
			switch ( true ) {
1065
				case array_key_exists( 'fields', $field ):
1066
					foreach ( $field['fields'] as $section_field_index => $section_field ) {
1067
						if ( ! self::$instance->is_sub_section( $section_field ) ) {
1068
							continue;
1069
						}
1070
1071
						$form['fields'][ $key ]['fields'][ $section_field_index ]['wrapper_attributes']['class'] = 'give-form-col';
1072
1073
						if ( array_key_exists( 'sub_section_end', $section_field ) ) {
1074
							$form['fields'][ $key ]['fields'][ $section_field_index ]['wrapper_attributes']['class'] = 'give-form-col give-form-col-end';
1075
1076
							// Clear float left for next field.
1077
							$fields_keys = array_keys( $form['fields'][ $key ]['fields'] );
1078
1079
							if ( $next_field_key = array_search( $section_field_index, $fields_keys ) ) {
1080
								if (
1081
									! isset( $fields_keys[ $next_field_key + 1 ] )
1082
									|| ! isset( $form['fields'][ $key ]['fields'][ $fields_keys[ $next_field_key + 1 ] ] )
1083
								) {
1084
									continue;
1085
								}
1086
1087
								$next_field = $form['fields'][ $key ]['fields'][ $fields_keys[ $next_field_key + 1 ] ];
1088
1089
								$next_field['wrapper_attributes']['class'] = isset( $next_field['wrapper_attributes']['class'] )
1090
									? $next_field['wrapper_attributes']['class'] . ' give-clearfix'
1091
									: 'give-clearfix';
1092
1093
								$form['fields'][ $key ]['fields'][ $fields_keys[ $next_field_key + 1 ] ] = $next_field;
1094
							}
1095
						}
1096
					}
1097
1098
					break;
1099
1100
				default:
1101
					if ( ! self::$instance->is_sub_section( $field ) ) {
1102
						continue;
1103
					}
1104
1105
					$form['fields'][ $key ]['wrapper_attributes']['class'] = 'give-form-col';
1106
1107
					if ( array_key_exists( 'sub_section_end', $field ) ) {
1108
						$form['fields'][ $key ]['wrapper_attributes']['class'] = 'give-form-col give-form-col-end';
1109
1110
						// Clear float left for next field.
1111
						$fields_keys = array_keys( $form['fields'] );
1112
1113
						if ( $next_field_key = array_search( $key, $fields_keys ) ) {
1114
							$form['fields'][ $fields_keys[ $next_field_key + 1 ] ]['wrapper_attributes']['class'] = 'give-clearfix';
1115
						}
1116
					}
1117
			}
1118
		}
1119
	}
1120
1121
1122
	/**
1123
	 * Check if current field is part of sub section or not.
1124
	 *
1125
	 * @since  1.9
1126
	 * @access private
1127
	 *
1128
	 * @param $field
1129
	 *
1130
	 * @return bool
1131
	 */
1132
	private function is_sub_section( $field ) {
1133
		$is_sub_section = false;
1134
		if ( array_key_exists( 'sub_section_start', $field ) || array_key_exists( 'sub_section_end', $field ) ) {
1135
			$is_sub_section = true;
1136
		}
1137
1138
		return $is_sub_section;
1139
	}
1140
1141
1142
	/**
1143
	 * Get field type.
1144
	 *
1145
	 * @since  1.9
1146
	 * @access private
1147
	 *
1148
	 * @param $field
1149
	 *
1150
	 * @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...
1151
	 */
1152
	public static function get_field_type( $field ) {
1153
		$field_type = 'field';
1154
1155
		if (
1156
			isset( $field['type'] )
1157
			&& 'block' === $field['type']
1158
		) {
1159
			$field_type = 'block';
1160
1161
		} elseif (
1162
			array_key_exists( 'fields', $field )
1163
			&& 'section' === $field['type']
1164
		) {
1165
			$field_type = 'section';
1166
1167
		}
1168
1169
		return $field_type;
1170
	}
1171
1172
	/**
1173
	 * Get field name.
1174
	 *
1175
	 * @since  1.9
1176
	 *
1177
	 * @param  array $field
1178
	 *
1179
	 * @return string
1180
	 */
1181
	public static function get_field_name( $field ) {
1182
		$field_name = esc_attr( empty( $field['repeat'] ) ? $field['id'] : $field['repeater_field_name'] );
1183
1184
		return $field_name;
1185
	}
1186
}
1187