Completed
Push — issues/1038 ( ec6ff3...7b5150 )
by Ravinder
16:45
created

Give_Admin_Settings::get_field_wrapper()   B

Complexity

Conditions 6
Paths 32

Size

Total Lines 27
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 19
nc 32
nop 2
dl 0
loc 27
rs 8.439
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 23 and the first side effect is on line 13.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

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

Loading history...
2
/**
3
 * Give Admin Settings Class
4
 *
5
 * @package     Give
6
 * @subpackage  Classes/Give_Admin_Settings
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
 * @since       1.8
10
 */
11
12
if ( ! defined( 'ABSPATH' ) ) {
13
	exit;
14
}
15
16
if ( ! class_exists( 'Give_Admin_Settings' ) ) :
17
18
	/**
19
	 * Give_Admin_Settings Class.
20
	 *
21
	 * @since 1.8
22
	 */
23
	class Give_Admin_Settings {
24
25
		/**
26
		 * Setting pages.
27
		 *
28
		 * @since 1.8
29
		 * @var   array List of settings.
30
		 */
31
		private static $settings = array();
32
33
		/**
34
		 * Setting filter and action prefix.
35
		 *
36
		 * @since 1.8
37
		 * @var   string setting fileter and action anme prefix.
38
		 */
39
		private static $setting_filter_prefix = '';
40
41
		/**
42
		 * Error messages.
43
		 *
44
		 * @since 1.8
45
		 * @var   array List of errors.
46
		 */
47
		private static $errors = array();
48
49
		/**
50
		 * Update messages.
51
		 *
52
		 * @since 1.8
53
		 * @var   array List of messages.
54
		 */
55
		private static $messages = array();
56
57
		/**
58
		 * Include the settings page classes.
59
		 *
60
		 * @since  1.8
61
		 * @return array
62
		 */
63
		public static function get_settings_pages() {
64
			/**
65
			 * Filter the setting page.
66
			 *
67
			 * Note: filter dynamically fire on basis of setting page slug.
68
			 * For example: if you register a setting page with give-settings menu slug
69
			 *              then filter will be give-settings_get_settings_pages
70
			 *
71
			 * @since 1.8
72
			 *
73
			 * @param array $settings Array of settings class object.
74
			 */
75
			self::$settings = apply_filters( self::$setting_filter_prefix . '_get_settings_pages', array() );
76
77
			return self::$settings;
78
		}
79
80
		/**
81
		 * Save the settings.
82
		 *
83
		 * @since  1.8
84
		 * @return void
85
		 */
86
		public static function save() {
87
			$current_tab = give_get_current_setting_tab();
88
89
			if ( empty( $_REQUEST['_give-save-settings'] ) || ! wp_verify_nonce( $_REQUEST['_give-save-settings'], 'give-save-settings' ) ) {
90
				die( __( 'Action failed. Please refresh the page and retry.', 'give' ) );
0 ignored issues
show
Coding Style Compatibility introduced by
The method save() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
91
			}
92
93
			/**
94
			 * Trigger Action.
95
			 *
96
			 * Note: action dynamically fire on basis of setting page slug and current tab.
97
			 * For example: if you register a setting page with give-settings menu slug and general current tab name
98
			 *              then action will be give-settings_save_general
99
			 *
100
			 * @since 1.8
101
			 */
102
			do_action( self::$setting_filter_prefix . '_save_' . $current_tab );
103
104
			self::add_message( 'give-setting-updated', __( 'Your settings have been saved.', 'give' ) );
105
106
			/**
107
			 * Trigger Action.
108
			 *
109
			 * Note: action dynamically fire on basis of setting page slug.
110
			 * For example: if you register a setting page with give-settings menu slug
111
			 *              then action will be give-settings_saved
112
			 *
113
			 * @since 1.8
114
			 */
115
			do_action( self::$setting_filter_prefix . '_saved' );
116
		}
117
118
		/**
119
		 * Add a message.
120
		 *
121
		 * @since  1.8
122
		 *
123
		 * @param  string $code    Message code (Note: This should be unique).
124
		 * @param  string $message Message text.
125
		 *
126
		 * @return void
127
		 */
128
		public static function add_message( $code, $message ) {
129
			self::$messages[ $code ] = $message;
130
		}
131
132
		/**
133
		 * Add an error.
134
		 *
135
		 * @since  1.8
136
		 *
137
		 * @param  string $code    Message code (Note: This should be unique).
138
		 * @param  string $message Message text.
139
		 *
140
		 * @return void
141
		 */
142
		public static function add_error( $code, $message ) {
143
			self::$errors[ $code ] = $message;
144
		}
145
146
		/**
147
		 * Output messages + errors.
148
		 *
149
		 * @since  1.8
150
		 * @return void
151
		 */
152
		public static function show_messages() {
153
			$notice_html = '';
154
			$classes     = 'give-notice settings-error notice is-dismissible';
155
156
			self::$errors   = apply_filters( self::$setting_filter_prefix . '_error_notices', self::$errors );
157
			self::$messages = apply_filters( self::$setting_filter_prefix . '_update_notices', self::$messages );
158
159
			if ( 0 < count( self::$errors ) ) {
160
				foreach ( self::$errors as $code => $message ) {
161
					$notice_html .= '<div id="setting-error-' . $code . '" class="' . $classes . ' error"><p><strong>' . $message . '</strong></p></div>';
162
				}
163
			}
164
165
			if ( 0 < count( self::$messages ) ) {
166
				foreach ( self::$messages as $code => $message ) {
167
					$notice_html .= '<div id="setting-error-' . $code . '" class="' . $classes . ' updated"><p><strong>' . $message . '</strong></p></div>';
168
				}
169
			}
170
171
			echo $notice_html;
172
		}
173
174
		/**
175
		 * Settings page.
176
		 *
177
		 * Handles the display of the main give settings page in admin.
178
		 *
179
		 * @since  1.8
180
		 *
181
		 * @return bool
182
		 */
183
		public static function output() {
184
			// Get current setting page.
185
			self::$setting_filter_prefix = give_get_current_setting_page();
186
187
			// Bailout: Exit if setting page is not defined.
188
			if ( empty( self::$setting_filter_prefix ) ) {
189
				return false;
190
			}
191
192
			/**
193
			 * Trigger Action.
194
			 *
195
			 * Note: action dynamically fire on basis of setting page slug
196
			 * For example: if you register a setting page with give-settings menu slug
197
			 *              then action will be give-settings_start
198
			 *
199
			 * @since 1.8
200
			 */
201
			do_action( self::$setting_filter_prefix . '_start' );
202
203
			$current_tab = give_get_current_setting_tab();
204
205
			// Include settings pages.
206
			self::get_settings_pages();
207
208
			// Save settings if data has been posted.
209
			if ( ! empty( $_POST ) ) {
210
				self::save();
211
			}
212
213
			/**
214
			 * Filter the tabs for current setting page.
215
			 *
216
			 * Note: filter dynamically fire on basis of setting page slug.
217
			 * For example: if you register a setting page with give-settings menu slug and general current tab name
218
			 *              then action will be give-settings_tabs_array
219
			 *
220
			 * @since 1.8
221
			 */
222
			$tabs = apply_filters( self::$setting_filter_prefix . '_tabs_array', array() );
223
224
			include 'views/html-admin-settings.php';
225
226
			return true;
227
		}
228
229
		/**
230
		 * Get a setting from the settings API.
231
		 *
232
		 * @since  1.8
233
		 *
234
		 * @param  string $option_name
235
		 * @param  string $field_id
236
		 * @param  mixed  $default
237
		 *
238
		 * @return array|string|bool
239
		 */
240
		public static function get_option( $option_name = '', $field_id = '', $default = false ) {
241
			// Bailout.
242
			if ( empty( $option_name ) && empty( $field_id ) ) {
243
				return false;
244
			}
245
246
			if ( ! empty( $field_id ) && ! empty( $option_name ) ) {
247
				// Get field value if any.
248
				$option_value = get_option( $option_name );
249
250
				$option_value = ( is_array( $option_value ) && array_key_exists( $field_id, $option_value ) )
251
					? $option_value[ $field_id ]
252
					: $default;
253
			} else {
254
				// If option name is empty but not field name then this means, setting is direct store to option table under there field name.
255
				$option_name = ! $option_name ? $field_id : $option_name;
256
257
				// Get option value if any.
258
				$option_value = get_option( $option_name, $default );
259
			}
260
261
			return $option_value;
262
		}
263
264
		/**
265
		 * Output admin fields.
266
		 *
267
		 * Loops though the give options array and outputs each field.
268
		 *
269
		 * @since  1.8
270
		 *
271
		 * @param  array  $options     Opens array to output
272
		 * @param  string $option_name Opens array to output
273
		 *
274
		 * @return void
275
		 */
276
		public static function output_fields( $options, $option_name = '' ) {
277
			$current_tab = give_get_current_setting_tab();
278
279
			// Field Default values.
280
			$defaults = array(
281
				'id'         => '',
282
				'name'       => '',
283
				'class'      => '',
284
				'css'        => '',
285
				'default'    => '',
286
				'desc'       => '',
287
				'table_html' => true,
288
			);
289
290
			foreach ( $options as $value ) {
291
				if ( ! isset( $value['type'] ) ) {
292
					continue;
293
				}
294
295
				// Set default setting.
296
				$value = wp_parse_args( $value, $defaults );
297
298
299
				// Custom attribute handling.
300
				$custom_attributes = array();
301
302
				if ( ! empty( $value['attributes'] ) && is_array( $value['attributes'] ) ) {
303
					foreach ( $value['attributes'] as $attribute => $attribute_value ) {
304
						$custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
305
					}
306
				}
307
308
				// Description handling.
309
				$description          = self::get_field_description( $value );
310
311
				// Switch based on type.
312
				switch ( $value['type'] ) {
313
314
					// Section Titles
315
					case 'title':
316
						if ( self::get_field_title( $value ) ) {
317
							echo '<div class="give-setting-tab-header give-setting-tab-header-' . $current_tab . '"><h2>' . self::get_field_title( $value ) . '</h2><hr></div>';
318
						}
319
320
						if ( ! empty( $value['desc'] ) ) {
321
							echo wpautop( wptexturize( wp_kses_post( $value['desc'] ) ) );
322
						}
323
324
						if ( $value['table_html'] ) {
325
							echo '<table class="form-table give-setting-tab-body give-setting-tab-body-' . $current_tab . '">' . "\n\n";
326
						}
327
328
						if ( ! empty( $value['id'] ) ) {
329
330
							/**
331
							 * Trigger Action.
332
							 *
333
							 * Note: action dynamically fire on basis of field id.
334
							 *
335
							 * @since 1.8
336
							 */
337
							do_action( 'give_settings_' . sanitize_title( $value['id'] ) );
338
						}
339
340
						break;
341
342
					// Section Ends.
343
					case 'sectionend':
344
						if ( ! empty( $value['id'] ) ) {
345
346
							/**
347
							 * Trigger Action.
348
							 *
349
							 * Note: action dynamically fire on basis of field id.
350
							 *
351
							 * @since 1.8
352
							 */
353
							do_action( 'give_settings_' . sanitize_title( $value['id'] ) . '_end' );
354
						}
355
356
						if ( $value['table_html'] ) {
357
							echo '</table>';
358
						}
359
360
						if ( ! empty( $value['id'] ) ) {
361
362
							/**
363
							 * Trigger Action.
364
							 *
365
							 * Note: action dynamically fire on basis of field id.
366
							 *
367
							 * @since 1.8
368
							 */
369
							do_action( 'give_settings_' . sanitize_title( $value['id'] ) . '_after' );
370
						}
371
372
						break;
373
374
					// Standard text inputs and subtypes like 'number'.
375
					case 'colorpicker':
376
						$value['field_attributes']['class'] = trim( $value['class'] ) . ' give-colorpicker';
377
						$value['type'] = 'text';
378
379
					case 'api_key' :
380
						$value['value']  = self::get_option( $option_name, $value['id'], $value['default'] );
381
						$value['type'] = ! empty( $value['value'] ) ? 'password' : 'text';
382
383
					case 'text':
384
					case 'email':
385
					case 'number':
386
					case 'password' :
387
						$value = give_backward_compatibility_setting_api_1_8( $value );
388
389
						// Set layout.
390
						$value = array_merge( $value, self::get_field_wrapper( $value, $option_name ) );
391
392
						// Add input specific class.
393
						$value['field_attributes']['class'] = empty( $value['field_attributes']['class'] )
394
							? 'give-input-field'
395
							: trim( $value['field_attributes']['class'] ) . ' give-input-field';
396
397
						// Render function.
398
						echo Give_Fields_API::render_tag( $value );
399
400
						break;
401
402
					// Textarea.
403
					case 'textarea':
404
						$value = give_backward_compatibility_setting_api_1_8( $value );
405
406
						// Set field value.
407
						$value['value'] = esc_textarea( self::get_option( $option_name, $value['id'], $value['default'] ) );
408
409
						// Set layout.
410
						$value = array_merge( $value, self::get_field_wrapper( $value, $option_name ) );
411
412
						// Add rows and cols for textarea.
413
						$value['field_attributes']['rows'] = 10;
414
						$value['field_attributes']['cols'] = 60;
415
416
						echo Give_Fields_API::render_tag( $value );
417
						break;
418
419
					// Select boxes.
420
					case 'select' :
421
					case 'multiselect' :
422
						$value = give_backward_compatibility_setting_api_1_8( $value );
423
424
						// Set layout.
425
						$value = array_merge( $value, self::get_field_wrapper( $value, $option_name ) );
426
427
						// Update td wrapper.
428
						$value['before_field'] = '<td class="give-forminp give-forminp-' . sanitize_title( $value['type'] ) . '"><fieldset>';
429
						$value['after_field']  = "{$description}</fieldset></td>";
430
431
432
						// Update param for radio_inline field type.
433
						if( 'radio_inline' === $value['type'] ) {
434
							$value['type']  = 'radio';
435
							$value['wrapper_attributes']['class'] = empty( $value['wrapper_attributes']['class'] )
436
								? 'give-radio-inline'
437
								: trim( $value['wrapper_attributes']['class'] ) . ' give-radio-inline';
438
						}
439
440
						echo Give_Fields_API::render_tag( $value );
441
						break;
442
443
					// Radio inputs.
444
					case 'radio_inline' :
445
					case 'radio' :
446
						$value = give_backward_compatibility_setting_api_1_8( $value );
447
448
						// Set layout.
449
						$value = array_merge( $value, self::get_field_wrapper( $value, $option_name ) );
450
451
						// Update td wrapper.
452
						$value['before_field'] = '<td class="give-forminp give-forminp-' . sanitize_title( $value['type'] ) . '"><fieldset>';
453
						$value['after_field']  = "{$description}</fieldset></td>";
454
455
456
						// Update param for radio_inline field type.
457
						if( 'radio_inline' === $value['type'] ) {
458
							$value['type']  = 'radio';
459
							$value['wrapper_attributes']['class'] = empty( $value['wrapper_attributes']['class'] )
460
								? 'give-radio-inline'
461
								: trim( $value['wrapper_attributes']['class'] ) . ' give-radio-inline';
462
						}
463
464
						echo Give_Fields_API::render_tag( $value );
465
						break;
466
467
					// Checkbox input.
468
					case 'checkbox' :
469
						$value = give_backward_compatibility_setting_api_1_8( $value );
470
471
						// Set layout.
472
						$value = array_merge( $value, self::get_field_wrapper( $value, $option_name ) );
473
474
						echo Give_Fields_API::render_tag( $value );
475
						break;
476
477
					// Multi Checkbox input.
478
					case 'multicheck' :
479
						$value = give_backward_compatibility_setting_api_1_8( $value );
480
481
						// Set layout.
482
						$value = array_merge( $value, self::get_field_wrapper( $value, $option_name ) );
483
484
						echo Give_Fields_API::render_tag( $value );
485
						break;
486
487
					// File input field.
488
					case 'file' :
489
						$value = give_backward_compatibility_setting_api_1_8( $value );
490
491
						// Set layout.
492
						$value = array_merge( $value, self::get_field_wrapper( $value, $option_name ) );
493
494
						echo Give_Fields_API::render_tag( $value );
495
						break;
496
497
					// WordPress Editor.
498
					case 'wysiwyg' :
499
						$value = give_backward_compatibility_setting_api_1_8( $value );
500
501
						// Set field value.
502
						$value['value'] = wp_kses_post( self::get_option( $option_name, $value['id'], $value['default'] ) );
503
504
						// Set layout.
505
						$value = array_merge( $value, self::get_field_wrapper( $value, $option_name ) );
506
						
507
						echo Give_Fields_API::render_tag( $value );
508
						break;
509
510
					// Custom: Give Docs Link field type.
511
					case 'give_docs_link' :
512
						$value = give_backward_compatibility_setting_api_1_8( $value );
513
514
						// Set layout.
515
						$value = array_merge( $value, self::get_field_wrapper( $value, $option_name ) );
516
						$value['before_field'] = '<td class="give-forminp give-forminp-' . sanitize_title( $value['type'] ) . ' give-docs-link" colspan="2">';
517
518
						echo Give_Fields_API::render_tag( $value );
519
						break;
520
521
					case 'group':
522
						$value = give_backward_compatibility_setting_api_1_8( $value );
523
524
						// Set field value.
525
						$value['value'] = self::get_option( $option_name, $value['id'], $value['default'] );
526
527
						// Set layout.
528
						$value = array_merge( $value, self::get_field_wrapper( $value, $option_name ) );
529
						
530
						echo Give_Fields_API::render_tag( $value );
531
						break;
532
533
					// Default: run an action
534
					// You can add or handle your custom field action.
535
					default:
536
						$value = give_backward_compatibility_setting_api_1_8( $value );
537
538
						// Get option value.
539
						$option_value = self::get_option( $option_name, $value['id'], $value['default'] );
540
						do_action( 'give_admin_field_' . $value['type'], $value, $option_value );
541
						break;
542
				}
543
			}
544
		}
545
546
		/**
547
		 * Helper function to get the formatted description for a given form field.
548
		 * Plugins can call this when implementing their own custom settings types.
549
		 *
550
		 * @since  1.8
551
		 *
552
		 * @param  array $value The form field value array
553
		 *
554
		 * @return string The HTML description of the field.
555
		 */
556
		public static function get_field_description( $value ) {
557
			$description = '';
558
559
			// Support for both 'description' and 'desc' args.
560
			$description_key = isset( $value['description'] ) ? 'description' : 'desc';
561
			$value           = ( isset( $value[ $description_key ] ) && ! empty( $value[ $description_key ] ) ) ? $value[ $description_key ] : '';
562
563
			if ( ! empty( $value ) ) {
564
				$description = '<p class="give-field-description">' . wp_kses_post( $value ) . '</p>';
565
			}
566
567
			return $description;
568
		}
569
570
571
		/**
572
		 * Helper function to get the formated title.
573
		 * Plugins can call this when implementing their own custom settings types.
574
		 *
575
		 * @since  1.8
576
		 *
577
		 * @param  array $value The form field value array
578
		 *
579
		 * @return array The description and tip as a 2 element array
580
		 */
581
		public static function get_field_title( $value ) {
582
			// Backward compatibility: version 1.8
583
			$title = ! empty( $value['id'] )
584
				? ( ! empty( $value['title'] ) ? $value['title'] : $value['name'] )
585
				: ( ! empty( $value['label'] ) ? $value['label'] : '' );
586
587
			// If html tag detected then allow them to print.
588
			if ( ! strip_tags( $title ) ) {
589
				$title = esc_html( $title );
590
			}
591
592
			return $title;
593
		}
594
595
		/**
596
		 * Save admin fields.
597
		 *
598
		 * Loops though the give options array and outputs each field.
599
		 *
600
		 * @since  1.8
601
		 *
602
		 * @param  array  $options     Options array to output
603
		 * @param  string $option_name Option name to save output. If empty then option will be store in there own option name i.e option id.
604
		 *
605
		 * @return bool
606
		 */
607
		public static function save_fields( $options, $option_name = '' ) {
608
			if ( empty( $_POST ) ) {
609
				return false;
610
			}
611
612
			// Options to update will be stored here and saved later.
613
			$update_options = array();
614
615
			// Loop options and get values to save.
616
			foreach ( $options as $option ) {
617
				if ( ! isset( $option['id'] ) || ! isset( $option['type'] ) ) {
618
					continue;
619
				}
620
621
622
				// Get posted value.
623
				if ( strstr( $option['id'], '[' ) ) {
624
					parse_str( $option['id'], $option_name_array );
625
					$field_option_name = current( array_keys( $option_name_array ) );
626
					$setting_name      = key( $option_name_array[ $field_option_name ] );
627
					$raw_value         = isset( $_POST[ $field_option_name ][ $setting_name ] ) ? wp_unslash( $_POST[ $field_option_name ][ $setting_name ] ) : null;
628
				} else {
629
					$field_option_name = $option['id'];
630
					$setting_name      = '';
631
					$raw_value         = isset( $_POST[ $option['id'] ] ) ? wp_unslash( $_POST[ $option['id'] ] ) : null;
632
				}
633
634
				// Format the value based on option type.
635
				switch ( $option['type'] ) {
636
					case 'checkbox' :
637
						$value = is_null( $raw_value )
638
							? ''
639
							: ( ! empty( $option['cbvalue'] ) ? $option['cbvalue'] : 'on' );
640
						break;
641
					case 'wysiwyg'  :
642
					case 'textarea' :
643
						$value = wp_kses_post( trim( $raw_value ) );
644
						break;
645
					case 'group' :
646
						if( ! empty( $raw_value ) ) {
647
							foreach ( $raw_value as $index => $single_value ) {
648
								foreach ( $option['fields'] as $single_field ) {
649
									if(
650
										! isset( $single_field[ 'type' ] )
651
										|| ! isset( $single_field[ 'id' ] )
652
										|| ! isset( $single_value[$single_field['id']] )
653
									) {
654
										continue;
655
									}
656
657
									switch ( $single_field[ 'type' ] ) {
658
										case 'checkbox' :
659
											$value[$index][$single_field['id']] = is_null( $single_value[$single_field['id']] ) ? '' : 'on';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$value was never initialized. Although not strictly required by PHP, it is generally a good practice to add $value = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
660
											break;
661
										case 'wysiwyg'  :
662
										case 'textarea' :
663
											$value[$index][$single_field['id']] = wp_kses_post( trim( $single_value[$single_field['id']] ) );
0 ignored issues
show
Bug introduced by
The variable $value does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
664
											break;
665
										default :
666
											$value[$index][$single_field['id']] = give_clean( $single_value[$single_field['id']] );
667
											break;
668
									}
669
								}
670
							}
671
						}
672
						break;
673
					default :
674
						$value = give_clean( $raw_value );
675
						break;
676
				}
677
678
				/**
679
				 * Sanitize the value of an option.
680
				 *
681
				 * @since 1.8
682
				 */
683
				$value = apply_filters( 'give_admin_settings_sanitize_option', $value, $option, $raw_value );
684
685
				/**
686
				 * Sanitize the value of an option by option name.
687
				 *
688
				 * @since 1.8
689
				 */
690
				$value = apply_filters( "give_admin_settings_sanitize_option_{$field_option_name}", $value, $option, $raw_value );
691
692
				if ( is_null( $value ) ) {
693
					continue;
694
				}
695
696
				// Check if option is an array and handle that differently to single values.
697
				if ( $field_option_name && $setting_name ) {
698
					if ( ! isset( $update_options[ $field_option_name ] ) ) {
699
						$update_options[ $field_option_name ] = get_option( $field_option_name, array() );
700
					}
701
					if ( ! is_array( $update_options[ $field_option_name ] ) ) {
702
						$update_options[ $field_option_name ] = array();
703
					}
704
					$update_options[ $field_option_name ][ $setting_name ] = $value;
705
				} else {
706
					$update_options[ $field_option_name ] = $value;
707
				}
708
			}
709
710
			// Save all options in our array or there own option name i.e. option id.
711
			if ( empty( $option_name ) ) {
712
				foreach ( $update_options as $name => $value ) {
713
					update_option( $name, $value );
714
715
					/**
716
					 * Trigger action.
717
					 *
718
					 * Note: This is dynamically fire on basis of option name.
719
					 *
720
					 * @since 1.8
721
					 */
722
					do_action( "give_save_option_{$name}", $value, $name );
723
				}
724
			} else {
725
				$old_options    = ( $old_options = get_option( $option_name ) ) ? $old_options : array();
726
				$update_options = array_merge( $old_options, $update_options );
727
728
				update_option( $option_name, $update_options );
729
730
				/**
731
				 * Trigger action.
732
				 *
733
				 * Note: This is dynamically fire on basis of setting name.
734
				 *
735
				 * @since 1.8
736
				 */
737
				do_action( "give_save_settings_{$option_name}", $update_options, $option_name );
738
			}
739
740
			return true;
741
		}
742
743
744
		/**
745
		 * Get field wrapper.
746
		 *
747
		 * @since  1.9
748
		 * @access private
749
		 *
750
		 * @param array  $field
751
		 * @param string $option_name
752
		 *
753
		 * @return array
754
		 */
755
		public static function get_field_wrapper( $field, $option_name = '' ) {
756
			$field_args = array(
757
				'before_field_label' => ! empty( $field['before_field_label'] )
758
					? "<th scope=\"row\" class=\"titledesc\">{$field['before_field_label']}"
759
					: '<th scope="row" class="titledesc">',
760
761
				'after_field_label' => ! empty( $field['after_field_label'] )
762
					? "{$field['after_field_label']}</th>"
763
					: '</th>',
764
765
				'value' => ! empty( $field['value'] )
766
					? $field['value']
767
					: give_clean( self::get_option( $option_name, $field['id'], $field['default'] ) ),
768
769
				'wrapper_type' => 'tr',
770
771
				'before_field' => ! empty( $field['before_field'] )
772
					? '<td class="give-forminp give-forminp-' . sanitize_title( $field['type'] ) . '">' . $field['before_field']
773
					: '<td class="give-forminp give-forminp-' . sanitize_title( $field['type'] ) . '">',
774
775
				'after_field' => ! empty( $field['after_field'] )
776
					? self::get_field_description( $field ) . $field['after_field'] . '</td>'
777
					: self::get_field_description( $field ) . '</td>',
778
			);
779
780
			return $field_args;
781
		}
782
	}
783
784
endif;
785