Completed
Pull Request — master (#1412)
by Ravinder
17:25
created

Give_CMB2_Settings_Loader   D

Complexity

Total Complexity 90

Size/Duplication

Total Lines 617
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 617
rs 4.8038
c 0
b 0
f 0
wmc 90
lcom 1
cbo 2

14 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 32 3
A set_default_setting_tab() 0 10 2
B add_addon_settings_page() 0 27 2
B setup_addon_save_hook() 0 27 3
A get_section_name() 0 11 2
D get_filtered_addon_sections() 0 37 10
F get_filtered_addon_settings() 0 177 36
D get_section_settings() 0 36 10
B addon_setting_field() 0 38 5
B get_sections() 0 13 5
A get_settings() 0 20 4
B output_sections() 0 25 6
A output() 0 5 1
A save() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like Give_CMB2_Settings_Loader often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Give_CMB2_Settings_Loader, and based on these observations, apply Extract Interface, too.

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 19 and the first side effect is on line 636.

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 CMB2 settings backward compatibility.
4
 *
5
 * @package     Give
6
 * @subpackage  Classes/Give_CMB2_Settings_Loader
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 ( ! class_exists( 'Give_CMB2_Settings_Loader' ) ) :
13
14
	/**
15
	 * This class loads the cmb2 settings.
16
	 *
17
	 * @since 1.8
18
	 */
19
	class Give_CMB2_Settings_Loader {
20
21
		/**
22
		 * @since 1.8
23
		 * @var   Give_Plugin_Settings $prev_settings Previous setting class object.
24
		 */
25
		private $id;
26
27
		/**
28
		 * @since 1.8
29
		 * @var   Give_Plugin_Settings $prev_settings Previous setting class object.
30
		 */
31
		private $prev_settings;
32
33
		/**
34
		 * @since 1.8
35
		 * @var   string $current_tab Current setting section.
36
		 */
37
		protected $current_tab;
38
39
		/**
40
		 * @since 1.8
41
		 * @var   string $current_tab Current setting section.
42
		 */
43
		private $current_section;
44
45
46
		/**
47
		 * Give_CMB2_Settings_Loader constructor.
48
		 */
49
		function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
50
			// Get previous setting class object.
51
			$this->prev_settings = new Give_Plugin_Settings();
52
53
			// Get current tab.
54
			$this->current_tab     = give_get_current_setting_tab();
55
			$this->current_section = empty( $_REQUEST['section'] ) ? ( current( array_keys( $this->get_sections() ) ) ) : sanitize_title( $_REQUEST['section'] );
56
57
			// Tab ID.
58
			$this->id = $this->current_tab;
59
60
			// Add addon tabs.
61
			add_filter( 'give-settings_tabs_array', array( $this, 'add_addon_settings_page' ), 999999 );
62
63
			// Add save hook to addons.
64
			add_action( 'give-settings_get_settings_pages', array( $this, 'setup_addon_save_hook' ), 999999 );
65
66
			// Add backward compatibility filters plugin settings.
67
			$setting_tabs = array( 'general', 'gateways', 'display', 'emails', 'addons', 'licenses' );
68
69
			// Filter Payment Gateways settings.
70
			if ( in_array( $this->current_tab, $setting_tabs ) ) {
71
				add_filter( "give_get_settings_{$this->current_tab}", array(
72
					$this,
73
					'get_filtered_addon_settings',
74
				), 999999, 1 );
75
				add_filter( "give_get_sections_{$this->current_tab}", array(
76
					$this,
77
					'get_filtered_addon_sections',
78
				), 999999, 1 );
79
			}
80
		}
81
82
		/**
83
		 * Default setting tab.
84
		 *
85
		 * @since  1.8
86
		 *
87
		 * @param  $setting_tab
88
		 *
89
		 * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|string|false?

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...
90
		 */
91
		function set_default_setting_tab( $setting_tab ) {
0 ignored issues
show
Unused Code introduced by
The parameter $setting_tab 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...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
92
			$default_tab = '';
93
94
			// Set default tab to first setting tab.
95
			if ( $sections = array_keys( $this->get_sections() ) ) {
96
				$default_tab = current( $sections );
97
			}
98
99
			return $default_tab;
100
		}
101
102
		/**
103
		 * Add addon setting pages.
104
		 *
105
		 * @since  1.8
106
		 *
107
		 * @param  $pages
108
		 *
109
		 * @return mixed
110
		 */
111
		function add_addon_settings_page( $pages ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
112
			// Previous setting page.
113
			$previous_pages = $this->prev_settings->give_get_settings_tabs();
114
115
			// API and System Info setting tab merge to Tools setting tab, so remove them from tabs.
116
			unset( $previous_pages['api'] );
117
			unset( $previous_pages['system_info'] );
118
119
			// Tab is not register.
120
			$pages_diff = array_keys( array_diff( $previous_pages, $pages ) );
121
122
			// Merge old settings with new settings.
123
			$pages = array_merge( $pages, $previous_pages );
124
125
			if ( in_array( $this->current_tab, $pages_diff ) ) {
126
				// Filter & actions.
127
				add_filter( "give_default_setting_tab_section_{$this->current_tab}", array(
128
					$this,
129
					'set_default_setting_tab',
130
				), 10 );
131
				add_action( "give-settings_sections_{$this->current_tab}_page", array( $this, 'output_sections' ) );
132
				add_action( "give-settings_settings_{$this->current_tab}_page", array( $this, 'output' ), 10 );
133
				add_action( "give-settings_save_{$this->current_tab}", array( $this, 'save' ) );
134
			}
135
136
			return $pages;
137
		}
138
139
140
		/**
141
		 * Setup save addon data hook.
142
		 *
143
		 * @since  1.8
144
		 *
145
		 * @param  $pages
146
		 *
147
		 * @return mixed
148
		 */
149
		function setup_addon_save_hook( $pages ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
150
			$page_ids = array();
151
152
			foreach ( $pages as $page ) {
153
				$page_ids = $page->add_settings_page( $page_ids );
154
			}
155
156
			// Previous setting page.
157
			$previous_pages = $this->prev_settings->give_get_settings_tabs();
158
159
			// API and System Info setting tab merge to Tools setting tab, so remove them from tabs.
160
			unset( $previous_pages['api'] );
161
			unset( $previous_pages['system_info'] );
162
163
			// Tab is not register.
164
			$pages_diff = array_keys( array_diff( $previous_pages, $page_ids ) );
165
166
			// Merge old settings with new settings.
167
			$pages = array_merge( $page_ids, $previous_pages );
168
169
			if ( in_array( $this->current_tab, $pages_diff ) ) {
170
				// Filter & actions.
171
				add_action( "give-settings_save_{$this->current_tab}", array( $this, 'save' ) );
172
			}
173
174
			return $pages;
175
		}
176
177
		/**
178
		 * Get section name from section title
179
		 *
180
		 * @since  1.8
181
		 *
182
		 * @param  $field_name
183
		 *
184
		 * @return string
185
		 */
186
		function get_section_name( $field_name ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
187
			// Bailout.
188
			if ( empty( $field_name ) ) {
189
				return $field_name;
190
			}
191
192
			$section_name = explode( ' ', $field_name );
193
194
			// Output.
195
			return strip_tags( implode( ' ', $section_name ) );
196
		}
197
198
199
		/**
200
		 * Get addon sections.
201
		 *
202
		 * @since  1.8
203
		 *
204
		 * @param  array $sections Array of setting fields (Optional).
205
		 *
206
		 * @return mixed
207
		 */
208
		function get_filtered_addon_sections( $sections = array() ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
209
			// New sections.
210
			$new_sections = array();
211
			$sections_ID  = array_keys( $sections );
212
213
			if ( ( $setting_fields = $this->prev_settings->give_settings( $this->current_tab ) ) && ! empty( $setting_fields['fields'] ) ) {
214
215
				foreach ( $setting_fields['fields'] as $field ) {
216
					// Section name.
217
					$field['name'] = isset( $field['name'] ) ? $field['name'] : '';
218
					$section_name  = $this->get_section_name( $field['name'] );
219
220
					// Check if section name exit and section title array is not empty.
221
					if ( ! empty( $sections ) && ! empty( $field['name'] ) ) {
222
223
						// Bailout: Do not load section if it is already exist.
224
						if (
225
							in_array( sanitize_title( $field['name'] ), $sections_ID ) // Check section id.
226
							|| in_array( $section_name, $sections )                    // Check section name.
227
						) {
228
							continue;
229
						}
230
					}
231
232
					// Collect new sections from addons.
233
					if ( 'give_title' == $field['type'] ) {
234
						$new_sections[ sanitize_title( $field['name'] ) ] = $section_name;
235
					}
236
				}
237
			}
238
239
			// Add new section.
240
			$sections = array_merge( $sections, $new_sections );
241
242
			// Output.
243
			return $sections;
244
		}
245
246
247
		/**
248
		 * Get setting fields.
249
		 *
250
		 * @since  1.8
251
		 *
252
		 * @param  array $settings       List of settings.
253
		 * @param  array $setting_fields Main tab settings data.
254
		 *
255
		 * @return array
256
		 */
257
		function get_filtered_addon_settings( $settings, $setting_fields = array() ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
258
			global $wp_filter;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
259
260
			$new_setting_fields = array();
261
262
			if ( ! empty( $settings ) ) {
263
				// Bailout: If setting array contain first element of type title then it means it is already created with new setting api (skip this section ).
264
				if ( isset( $settings[0]['type'] ) && 'title' == $settings[0]['type'] ) {
265
					foreach ( $settings as $setting ) {
266
						$new_setting_fields[] = $setting;
267
268
						// We need setting only till first section end.
269
						if ( 'sectionend' === $setting['type'] ) {
270
							break;
271
						}
272
					}
273
274
					return $new_setting_fields;
275
				}
276
277
				// Store title field id.
278
				$prev_title_field_id = '';
279
280
				// Create new setting fields.
281
				foreach ( $settings as $index => $field ) {
282
283
					// Bailout: Must need field type to process.
284
					if ( ! isset( $field['type'] ) ) {
285
						continue;
286
					}
287
288
					// Set wrapper class if any.
289
					if ( ! empty( $field['row_classes'] ) ) {
290
						$field['wrapper_class'] = $field['row_classes'];
291
						unset( $field['row_classes'] );
292
					}
293
294
					$field['name'] = ! isset( $field['name'] ) ? '' : $field['name'];
295
					$field['desc'] = ! isset( $field['desc'] ) ? '' : $field['desc'];
296
297
					// Modify cmb2 setting fields.
298
					switch ( $field['type'] ) {
299
						case 'text' :
300
						case 'file' :
301
							$field['css'] = 'width:25em;';
302
							break;
303
304
						case 'text_small' :
305
							$field['type'] = 'text';
306
							break;
307
308
						case 'text_email' :
309
							$field['type'] = 'email';
310
							$field['css']  = 'width:25em;';
311
							break;
312
313
						case 'radio_inline' :
314
							$field['type']  = 'radio';
315
							$field['class'] = 'give-radio-inline';
316
							break;
317
318
						case 'give_title' :
319
							$field['type'] = 'title';
320
321
							// Since we are showing sections, so there now ned to show horizontal rules.
322
							if ( '<hr>' === $field['desc'] ) {
323
								$field['desc'] = '';
324
							}
325
326
							break;
327
					}
328
329
					if ( 'title' === $field['type'] ) {
330
331
						// If we do not have first element as title then these field will be skip from frontend
332
						// because there are not belong to any section, so put all abandon fields under first section.
333
						if ( $index && empty( $prev_title_field_id ) ) {
334
							array_unshift(
335
								$new_setting_fields,
336
								array(
337
									'title' => $field['name'],
338
									'type'  => $field['type'],
339
									'desc'  => $field['desc'],
340
									'id'    => $field['id'],
341
								)
342
							);
343
344
							$prev_title_field_id = $field['id'];
345
346
							continue;
347
						} elseif ( $index ) {
348
							// Section end.
349
							$new_setting_fields[] = array(
350
								'type' => 'sectionend',
351
								'id'   => $prev_title_field_id,
352
							);
353
						}
354
355
						// Section start.
356
						$new_setting_fields[] = array(
357
							'title' => $field['name'],
358
							'type'  => $field['type'],
359
							'desc'  => $field['desc'],
360
							'id'    => $field['id'],
361
						);
362
363
						$prev_title_field_id = $field['id'];
364
					} else {
365
366
						// setting fields
367
						$new_setting_fields[] = $field;
368
					}// End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% 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...
369
				}// End foreach().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% 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...
370
371
				// Section end.
372
				$new_setting_fields[] = array(
373
					'type' => 'sectionend',
374
					'id'   => $prev_title_field_id,
375
				);
376
377
				// Check if setting page has title section or not.
378
				// If setting page does not have title section  then add title section to it and fix section end array id.
379
				if ( 'title' !== $new_setting_fields[0]['type'] ) {
380
					array_unshift(
381
						$new_setting_fields,
382
						array(
383
							'title' => ( isset( $settings['give_title'] ) ? $settings['give_title'] : '' ),
384
							'type'  => 'title',
385
							'desc'  => ! empty( $setting_fields['desc'] ) ? $setting_fields['desc'] : '',
386
							'id'    => ( isset( $settings['id'] ) ? $settings['id'] : '' ),
387
						)
388
					);
389
390
					// Update id in section end array if does not contain.
391
					if ( empty( $new_setting_fields[ count( $new_setting_fields ) - 1 ]['id'] ) ) {
392
						$new_setting_fields[ count( $new_setting_fields ) - 1 ]['id'] = ( isset( $settings['id'] ) ? $settings['id'] : '' );
393
					}
394
				}
395
396
				// Return only section related settings.
397
				if ( $sections = $this->get_filtered_addon_sections() ) {
398
					$new_setting_fields = $this->get_section_settings( $new_setting_fields );
399
				}
400
401
				// Third party plugin backward compatibility.
402
				$wp_filter_keys = array_keys( $wp_filter );
403
				foreach ( $new_setting_fields as $index => $field ) {
404
					if ( ! isset( $field['type'] ) || in_array( $field['type'], array( 'title', 'sectionend' ) ) ) {
405
						continue;
406
					}
407
408
					$cmb2_filter_name = "cmb2_render_{$field['type']}";
409
410
					if ( in_array( $cmb2_filter_name, $wp_filter_keys ) ) {
411
412
						if ( 0 >= version_compare( 4.7, get_bloginfo( 'version' ) ) && ! empty( $wp_filter[ $cmb2_filter_name ]->callbacks ) ) {
413
							$cmb2_filter_arr = current( $wp_filter[ $cmb2_filter_name ]->callbacks );
414
						} else {
415
							$cmb2_filter_arr = current( $wp_filter[ $cmb2_filter_name ] );
416
						}
417
418
						if ( ! empty( $cmb2_filter_arr ) ) {
419
							// Note: function can be called either globally or with class object, it depends on how developer invoke it.
420
							$new_setting_fields[ $index ]['func'] = current( $cmb2_filter_arr );
421
							add_action( "give_admin_field_{$field['type']}", array(
422
								$this,
423
								'addon_setting_field',
424
							), 10, 2 );
425
						}
426
					}
427
				}
428
429
				return $new_setting_fields;
430
			}// End if().
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% 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...
431
432
			return $settings;
433
		}
434
435
436
		/**
437
		 * Get section related setting.
438
		 *
439
		 * @since 1.8
440
		 *
441
		 * @param $tab_settings
442
		 *
443
		 * @return array
444
		 */
445
		function get_section_settings( $tab_settings ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
446
			$current_section = give_get_current_setting_section();
447
448
			// Note: If we are opening default tabe for addon setting then it is possible that we will get empty string as current section
449
			// because default section filter added after save hook fire, so we will always get problem to save first section [default] or if there are only on section
450
			// This is hack to fix this.
451
			if ( empty( $current_section ) ) {
452
				$current_section = $this->set_default_setting_tab( $current_section );
453
			}
454
455
			$section_start               = false;
456
			$section_end                 = false;
457
			$section_only_setting_fields = array();
458
459
			foreach ( $tab_settings as $field ) {
460
				if ( 'title' == $field['type'] && $current_section == sanitize_title( $field['title'] ) ) {
461
					$section_start = true;
462
				}
463
464
				if ( ! $section_start || $section_end ) {
465
					continue;
466
				}
467
468
				if ( $section_start && ! $section_end ) {
469
					if ( 'sectionend' == $field['type'] ) {
470
						$section_end = true;
471
					}
472
					$section_only_setting_fields[] = $field;
473
				}
474
			}
475
476
			// Remove title from setting, pevent it from render in setting tab.
477
			$section_only_setting_fields[0]['title'] = '';
478
479
			return apply_filters( "give_get_settings_{$this->current_tab}_{$current_section}", $section_only_setting_fields, $tab_settings );
480
		}
481
482
483
		/**
484
		 * CMB2 addon setting fields backward compatibility.
485
		 *
486
		 * @since  1.8
487
		 *
488
		 * @param  array $field
489
		 * @param  mixed $saved_value
490
		 *
491
		 * @return void
492
		 */
493
		function addon_setting_field( $field, $saved_value ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
494
			// Create object for cmb2  function callback backward compatibility.
495
			// Note: Do not call any cmb2 function on these objects
496
			$field_obj      = (object) array( 'args' => $field );
497
			$field_type_obj = (object) array( 'field' => $field_obj );
498
499
			switch ( $this->current_tab ) :
500
				case 'licenses':
501
					?>
502
					<div class="give-settings-wrap give-settings-wrap-<?php echo $this->current_tab; ?>">
503
						<?php $field['func']['function']( $field_obj, $saved_value, '', '', $field_type_obj ); ?>
504
					</div>
505
					<?php break;
506
507
				default :
508
					$colspan = 'colspan="2"';
509
					?>
510
					<tr valign="top">
511
						<?php if ( ! empty( $field['name'] ) && ! in_array( $field['name'], array( '&nbsp;' ) ) ) : ?>
512
							<th scope="row" class="titledesc">
513
								<label
514
										for="<?php echo esc_attr( $field['name'] ); ?>"><?php echo $field['title']; ?></label>
515
							</th>
516
							<?php $colspan = ''; ?>
517
						<?php endif; ?>
518
						<td class="give-forminp" <?php echo $colspan; ?>>
519
							<?php
520
							if ( is_array( $field['func']['function'] ) ) {
521
								$field['func']['function'][0]->$field['func']['function'][1]( $field_obj, $saved_value, '', '', $field_type_obj );
522
							} else {
523
								$field['func']['function']( $field_obj, $saved_value, '', '', $field_type_obj );
524
							}
525
							?>
526
						</td>
527
					</tr>
528
					<?php
529
			endswitch;
530
		}
531
532
		/**
533
		 * Get sections.
534
		 *
535
		 * @since  1.8
536
		 * @return array
537
		 */
538
		public function get_sections() {
539
			$sections = array();
540
541
			if ( ( $setting_fields = $this->prev_settings->give_settings( $this->current_tab ) ) && ! empty( $setting_fields['fields'] ) ) {
542
				foreach ( $setting_fields['fields'] as $field ) {
543
					if ( 'give_title' == $field['type'] ) {
544
						$sections[ sanitize_title( $field['name'] ) ] = $this->get_section_name( $field['name'] );
545
					}
546
				}
547
			}
548
549
			return $sections;
550
		}
551
552
553
		/**
554
		 * Get setting fields.
555
		 *
556
		 * @since  1.8
557
		 * @return array
558
		 */
559
		function get_settings() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
560
			global $wp_filter;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
561
562
			$new_setting_fields = array();
563
564
			if ( $setting_fields = $this->prev_settings->give_settings( $this->current_tab ) ) {
565
				if ( isset( $setting_fields['fields'] ) ) {
566
567
					$tab_data = array(
568
						'id'         => $setting_fields['id'],
569
						'give_title' => $setting_fields['give_title'],
570
						'desc'       => ( isset( $setting_fields['desc'] ) ? $setting_fields['desc'] : '' ),
571
					);
572
573
					$new_setting_fields = $this->get_filtered_addon_settings( $setting_fields['fields'], $tab_data );
574
				}
575
			}
576
577
			return $new_setting_fields;
578
		}
579
580
		/**
581
		 * Output sections.
582
		 *
583
		 * @since  1.8
584
		 * @return void
585
		 */
586
		public function output_sections() {
587
			$sections = $this->get_sections();
588
589
			// Show section settings only if setting section exist.
590
			if ( ! in_array( $this->current_section, array_keys( $sections ) ) ) {
591
				echo '<div class="error"><p>' . __( 'Oops, this settings page does not exist.', 'give' ) . '</p></div>';
592
593
				return;
594
			}
595
596
			// Bailout.
597
			if ( empty( $sections ) ) {
598
				return;
599
			}
600
601
			echo '<ul class="subsubsub">';
602
603
			$array_keys = array_keys( $sections );
604
605
			foreach ( $sections as $id => $label ) {
606
				echo '<li><a href="' . admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=' . $this->current_tab . '&section=' . sanitize_title( $id ) ) . '" class="' . ( $this->current_section == $id ? 'current' : '' ) . '">' . strip_tags( $label ) . '</a> ' . ( end( $array_keys ) == $id ? '' : '|' ) . ' </li>';
607
			}
608
609
			echo '</ul><br class="clear" /><hr>';
610
		}
611
612
		/**
613
		 * Output the settings.
614
		 *
615
		 * @since  1.8
616
		 * @return void
617
		 */
618
		public function output() {
619
			$settings = $this->get_settings();
620
621
			Give_Admin_Settings::output_fields( $settings, 'give_settings' );
622
		}
623
624
		/**
625
		 * Save settings.
626
		 *
627
		 * @since  1.8
628
		 * @return void
629
		 */
630
		public function save() {
631
			$settings = $this->get_settings();
632
633
			Give_Admin_Settings::save_fields( $settings, 'give_settings' );
634
		}
635
	}
636
endif;
637
638
new Give_CMB2_Settings_Loader();
639