Completed
Branch master (16c0f9)
by
unknown
02:07
created

Auto_Load_Next_Post_Admin_Settings   D

Complexity

Total Complexity 97

Size/Duplication

Total Lines 625
Duplicated Lines 5.12 %

Coupling/Cohesion

Components 2
Dependencies 0

Importance

Changes 0
Metric Value
dl 32
loc 625
rs 4.7712
c 0
b 0
f 0
wmc 97
lcom 2
cbo 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A get_settings_pages() 0 13 2
A save() 0 14 1
A add_message() 0 3 1
A add_error() 0 3 1
B show_messages() 0 11 5
A output() 0 16 1
B get_option() 0 31 6
F output_fields() 16 294 58
F save_fields() 16 115 22

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Auto_Load_Next_Post_Admin_Settings 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 Auto_Load_Next_Post_Admin_Settings, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Auto Load Next Post - Admin Settings Class.
4
 *
5
 * @class    Auto_Load_Next_Post_Admin_Settings
6
 * @since    1.0.0
7
 * @version  1.4.8
8
 * @author   Sébastien Dumont
9
 * @category Admin
10
 * @package  Auto Load Next Post
11
 * @license  GPL-2.0+
12
 */
13
14
// Exit if accessed directly.
15
if ( ! defined( 'ABSPATH' ) ) {
16
	exit;
17
}
18
19
if ( ! class_exists('Auto_Load_Next_Post_Admin_Settings' ) ) {
20
21
	class Auto_Load_Next_Post_Admin_Settings {
22
23
		/**
24
		 * Setting pages.
25
		 *
26
		 * @access private
27
		 * @static
28
		 * @var array
29
		 */
30
		private static $settings = array();
31
32
		/**
33
		 * Error messages.
34
		 *
35
		 * @access private
36
		 * @static
37
		 * @var array
38
		 */
39
		private static $errors = array();
40
41
		/**
42
		 * Update messages.
43
		 *
44
		 * @access private
45
		 * @static
46
		 * @var array
47
		 */
48
		private static $messages = array();
49
50
		/**
51
		 * Include the settings page classes.
52
		 *
53
		 * @access  public
54
		 * @static
55
		 * @since   1.0.0
56
		 * @version 1.4.10
57
		 * @return  $settings
58
		 */
59
		public static function get_settings_pages() {
60
			if ( empty( self::$settings ) ) {
61
				$settings = array();
62
63
				include_once( dirname( __FILE__ ) . '/settings/class-alnp-settings-page.php' );
64
65
				$settings[] = include( dirname( __FILE__ ) . '/settings/class-alnp-settings-general.php');
66
67
				self::$settings = apply_filters( 'auto_load_next_post_get_settings_pages', $settings );
68
			}
69
70
			return self::$settings;
71
		} // END get_settings_page()
72
73
		/**
74
		 * Save the settings.
75
		 *
76
		 * @access  public
77
		 * @static
78
		 * @since   1.0.0
79
		 * @version 1.4.10
80
		 * @global  $current_tab
81
		 */
82
		public static function save() {
83
			global $current_tab;
84
85
			check_admin_referer( 'auto-load-next-post-settings' );
86
87
			// Trigger actions
88
			do_action( 'auto_load_next_post_settings_save_' . $current_tab );
89
			do_action( 'auto_load_next_post_update_options_' . $current_tab );
90
			do_action( 'auto_load_next_post_update_options' );
91
92
			self::add_message( __( 'Your settings have been saved.', 'auto-load-next-post' ) );
93
94
			do_action( 'auto_load_next_post_settings_saved' );
95
		} // END save()
96
97
		/**
98
		 * Add a message
99
		 *
100
		 * @access public
101
		 * @static
102
		 * @since  1.0.0
103
		 * @param  string $text Message
104
		 */
105
		public static function add_message( $text ) {
106
			self::$messages[] = $text;
107
		} // END add_message()
108
109
		/**
110
		 * Add an error
111
		 *
112
		 * @access public
113
		 * @static
114
		 * @since  1.0.0
115
		 * @param  string $text Error
116
		 */
117
		public static function add_error( $text ) {
118
			self::$errors[] = $text;
119
		} // END add_error()
120
121
		/**
122
		 * Output messages and errors.
123
		 *
124
		 * @access public
125
		 * @static
126
		 * @since  1.0.0
127
		 * @return string
128
		 */
129
		public static function show_messages() {
130
			if ( count( self::$errors ) > 0 ) {
131
				foreach ( self::$errors as $error ) {
132
					echo '<div id="message" class="error inline"><p><strong>' . esc_html( $error ) . '</strong></p></div>';
133
				}
134
			} elseif ( count( self::$messages ) > 0 ) {
135
				foreach ( self::$messages as $message ) {
136
					echo '<div id="message" class="updated inline"><p><strong>' . esc_html( $message ) . '</strong></p></div>';
137
				}
138
			}
139
		} // END show_messages()
140
141
		/**
142
		 * Settings Page.
143
		 *
144
		 * Handles the display of the main settings page in admin.
145
		 *
146
		 * @access  public
147
		 * @static
148
		 * @since   1.0.0
149
		 * @version 1.4.10
150
		 * @filter  auto_load_next_post_settings_tabs_array
151
		 * @global  string $current_section
152
		 * @global  string $current_tab
153
		 * @return  void
154
		 */
155
		public static function output() {
156
			global $current_section, $current_tab;
157
158
			do_action( 'auto_load_next_post_settings_start' );
159
160
			wp_enqueue_script( 'auto_load_next_post_settings', AUTO_LOAD_NEXT_POST_URL_PATH . '/assets/js/admin/settings' . AUTO_LOAD_NEXT_POST_SCRIPT_MODE . '.js', array('jquery'), AUTO_LOAD_NEXT_POST_VERSION, true );
161
162
			wp_localize_script( 'auto_load_next_post_settings', 'auto_load_next_post_settings_params', array(
163
				'i18n_nav_warning' => __( 'The changes you made will be lost if you navigate away from this page.', 'auto-load-next-post' ),
164
			) );
165
166
			// Get tabs for the settings page
167
			$tabs = apply_filters( 'auto_load_next_post_settings_tabs_array', array() );
168
169
			include( dirname( __FILE__ ) . '/views/html-admin-settings.php' );
170
		} // END output()
171
172
		/**
173
		 * Get a setting from the settings API.
174
		 *
175
		 * @access public
176
		 * @static
177
		 * @since  1.0.0
178
		 * @param  mixed $option_name
179
		 * @return string
180
		 */
181
		public static function get_option( $option_name, $default = '' ) {
182
			// Array value
183
			if ( strstr( $option_name, '[' ) ) {
184
				parse_str( $option_name, $option_array );
185
186
				// Option name is first key
187
				$option_name = current( array_keys( $option_array ) );
188
189
				// Get value
190
				$option_values = get_option( $option_name, '' );
191
192
				$key = key( $option_array[$option_name] );
193
194
				if ( isset( $option_values[$key] ) ) {
195
					$option_value = $option_values[$key];
196
				} else {
197
					$option_value = null;
198
				}
199
			// Single value
200
			} else {
201
				$option_value = get_option($option_name, null);
202
			}
203
204
			if ( is_array( $option_value ) ) {
205
				$option_value = array_map( 'stripslashes', $option_value );
206
			} elseif ( ! is_null( $option_value ) ) {
207
				$option_value = stripslashes( $option_value );
208
			}
209
210
			return $option_value === null ? $default : $option_value;
211
		} // END get_option()
212
213
	/**
214
	 * Output admin fields.
215
	 *
216
	 * Loops though the plugin name options array and outputs each field.
217
	 *
218
	 * @since  1.0.0
219
	 * @access public
220
	 * @static
221
	 * @param  array $options Opens array to output
222
	 */
223
	public static function output_fields($options) {
224
		foreach ($options as $value) {
225
			if ( ! isset($value['type'])) {
226
				continue;
227
			}
228
			if ( ! isset($value['id'])) {
229
				$value['id'] = '';
230
			}
231
			if ( ! isset($value['title'])) {
232
				$value['title'] = isset($value['name']) ? $value['name'] : '';
233
			}
234
			if ( ! isset($value['class'])) {
235
				$value['class'] = '';
236
			}
237
			if ( ! isset($value['css'])) {
238
				$value['css'] = '';
239
			}
240
			if ( ! isset($value['default'])) {
241
				$value['default'] = '';
242
			}
243
			if ( ! isset($value['desc'])) {
244
				$value['desc'] = '';
245
			}
246
			if ( ! isset($value['desc_tip'])) {
247
				$value['desc_tip'] = false;
248
			}
249
250
			// Custom attribute handling
251
			$custom_attributes = array();
252
253
			if ( ! empty($value['custom_attributes']) && is_array($value['custom_attributes'])) {
254
				foreach ($value['custom_attributes'] as $attribute => $attribute_value) {
255
					$custom_attributes[] = esc_attr($attribute).'="'.esc_attr($attribute_value).'"';
256
				}
257
			}
258
259
			// Description handling
260
			if ($value['desc_tip'] === true) {
261
				$description = '';
262
				$tip = $value['desc'];
263
			} else if ( ! empty($value['desc_tip'])) {
264
				$description = $value['desc'];
265
				$tip = $value['desc_tip'];
266
			} else if ( ! empty($value['desc'])) {
267
				$description = $value['desc'];
268
				$tip = '';
269
			} else {
270
				$description = $tip = '';
271
			}
272
273 View Code Duplication
			if ($description && in_array($value['type'], array('textarea', 'radio'))) {
274
				$description = '<p style="margin-top:0">'.wp_kses_post($description).'</p>';
275
			} else if ($description) {
276
				$description = '<span class="description">'.wp_kses_post($description).'</span>';
277
			}
278
279 View Code Duplication
			if ($tip && in_array($value['type'], array('checkbox'))) {
280
				$tip = '<p class="description">'.$tip.'</p>';
281
			} else if ($tip) {
282
				$tip = '<img class="help_tip" data-tip="'.esc_attr($tip).'" src="' . AUTO_LOAD_NEXT_POST_URL_PATH . '/assets/images/help.png" height="16" width="16" />';
283
			}
284
285
			// Switch based on type
286
			switch ($value['type']) {
287
				// Section Titles
288
				case 'title':
289
					if ( ! empty($value['title'])) {
290
						echo '<h3>'.esc_html($value['title']).'</h3>';
291
					}
292
293
					if ( ! empty($value['desc'])) {
294
						echo wpautop(wptexturize(wp_kses_post($value['desc'])));
295
					}
296
297
					echo '<table class="form-table">'."\n\n";
298
299
					if ( ! empty($value['id'])) {
300
						do_action('auto_load_next_post_settings_'.sanitize_title($value['id']));
301
					}
302
303
					break;
304
305
				// Section Ends
306
				case 'sectionend':
307
308 View Code Duplication
					if ( ! empty($value['id'])) {
309
						do_action('auto_load_next_post_settings_'.sanitize_title($value['id']).'_end');
310
					}
311
312
					echo '</table>';
313
314 View Code Duplication
					if ( ! empty($value['id'])) {
315
						do_action('auto_load_next_post_settings_'.sanitize_title($value['id']).'_after');
316
					}
317
318
					break;
319
320
				// Standard text inputs and subtypes like 'number'
321
				case 'text':
322
				case 'number':
323
					$type         = $value['type'];
324
					$class        = '';
325
					$option_value = self::get_option($value['id'], $value['default']);
326
					?><tr valign="top">
327
						<th scope="row" class="titledesc">
328
							<label for="<?php echo esc_attr($value['id']); ?>"><?php echo esc_html($value['title']); ?></label>
329
							<?php echo $tip; ?>
330
						</th>
331
						<td class="forminp forminp-<?php echo sanitize_title($value['type']); ?>">
332
							<input
333
								name="<?php echo esc_attr($value['id']); ?>"
334
								id="<?php echo esc_attr($value['id']); ?>"
335
								type="<?php echo esc_attr($type); ?>"
336
								style="<?php echo esc_attr($value['css']); ?>"
337
								value="<?php echo esc_attr($option_value); ?>"
338
								class="<?php echo esc_attr($value['class']); ?>"
339
								<?php echo implode(' ', $custom_attributes); ?>
340
							/> <?php echo $description; ?>
341
						</td>
342
					</tr><?php
343
344
					break;
345
346
				// Textarea
347
				case 'textarea':
348
					$option_value = self::get_option($value['id'], $value['default']);
349
					?><tr valign="top">
350
						<th scope="row" class="titledesc">
351
							<label for="<?php echo esc_attr($value['id']); ?>"><?php echo esc_html($value['title']); ?></label>
352
							<?php echo $tip; ?>
353
						</th>
354
						<td class="forminp forminp-<?php echo sanitize_title($value['type']); ?>">
355
						<?php echo $description; ?>
356
						<textarea
357
								name="<?php echo esc_attr($value['id']); ?>"
358
								id="<?php echo esc_attr($value['id']); ?>"
359
								style="<?php echo esc_attr($value['css']); ?>"
360
								class="<?php echo esc_attr($value['class']); ?>"
361
								<?php echo implode(' ', $custom_attributes); ?>
362
								><?php echo esc_textarea($option_value); ?></textarea>
363
						</td>
364
					</tr><?php
365
366
					break;
367
368
				// Select boxes
369
				case 'select':
370
				case 'multiselect':
371
					$option_value = self::get_option($value['id'], $value['default']);
372
					?><tr valign="top">
373
						<th scope="row" class="titledesc">
374
							<label for="<?php echo esc_attr($value['id']); ?>"><?php echo esc_html($value['title']); ?></label>
375
							<?php echo $tip; ?>
376
						</th>
377
						<td class="forminp forminp-<?php echo sanitize_title($value['type']); ?>">
378
						<select
379
								name="<?php echo esc_attr($value['id']); ?><?php if ($value['type'] == 'multiselect') {
380
	echo '[]';
381
}
382
?>"
383
								id="<?php echo esc_attr($value['id']); ?>"
384
								style="<?php echo esc_attr($value['css']); ?>"
385
								class="<?php echo esc_attr($value['class']); ?>"
386
								<?php echo implode(' ', $custom_attributes); ?>
387
								<?php if ($value['type'] == 'multiselect') {
388
	echo 'multiple="multiple"';
389
}
390
?>>
391
								<?php foreach ($value['options'] as $key => $val) { ?>
392
										<option value="<?php echo esc_attr($key); ?>" <?php
393
											if (is_array($option_value)) {
394
												selected(in_array($key, $option_value), true);
395
											} else {
396
												selected($option_value, $key);
397
											}
398
										?>><?php echo $val ?></option>
399
										<?php
400
									}
401
								?>
402
							</select> <?php echo $description; ?>
403
						</td>
404
						</tr><?php
405
406
						break;
407
408
				// Radio inputs
409
				case 'radio':
410
					$option_value = self::get_option($value['id'], $value['default']);
411
					?><tr valign="top">
412
						<th scope="row" class="titledesc">
413
							<label for="<?php echo esc_attr($value['id']); ?>"><?php echo esc_html($value['title']); ?></label>
414
							<?php echo $tip; ?>
415
						</th>
416
						<td class="forminp forminp-<?php echo sanitize_title($value['type']); ?>">
417
							<fieldset>
418
								<?php echo $description; ?>
419
							<ul>
420
							<?php foreach ($value['options'] as $key => $val) { ?>
421
								<li>
422
									<label><input
423
												name="<?php echo esc_attr($value['id']); ?>"
424
												value="<?php echo $key; ?>"
425
												type="radio"
426
												style="<?php echo esc_attr($value['css']); ?>"
427
												class="<?php echo esc_attr($value['class']); ?>"
428
												<?php echo implode(' ', $custom_attributes); ?>
429
												<?php checked($key, $option_value); ?>
430
												/> <?php echo $val ?></label>
431
								</li>
432
							<?php } ?>
433
							</ul>
434
							</fieldset>
435
						</td>
436
					</tr><?php
437
438
					break;
439
440
				// Checkbox input
441
				case 'checkbox':
442
					$option_value = self::get_option($value['id'], $value['default']);
443
					if ( ! isset($value['hide_if_checked'])) {
444
						$value['hide_if_checked'] = false;
445
					}
446
					if ( ! isset($value['show_if_checked'])) {
447
						$value['show_if_checked'] = false;
448
					}
449
					if ( ! isset($value['checkboxgroup']) || (isset($value['checkboxgroup']) && $value['checkboxgroup'] == 'start')) {
450
					?>
451
						<tr valign="top" class="<?php
452
							if ($value['hide_if_checked'] == 'yes' || $value['show_if_checked'] == 'yes') {
453
								echo 'hidden_option';
454
							}
455
							if ($value['hide_if_checked'] == 'option') {
456
								echo 'hide_options_if_checked';
457
							}
458
							if ($value['show_if_checked'] == 'option') {
459
								echo 'show_options_if_checked';
460
							}
461
						?>">
462
						<th scope="row" class="titledesc"><?php echo esc_html($value['title']); ?></th>
463
						<td class="forminp forminp-checkbox">
464
							<fieldset>
465
						<?php
466
					} else {
467
						?>
468
						<fieldset class="<?php
469
							if ($value['hide_if_checked'] == 'yes' || $value['show_if_checked'] == 'yes') {
470
								echo 'hidden_option';
471
							}
472
							if ($value['hide_if_checked'] == 'option') {
473
								echo 'hide_options_if_checked';
474
							}
475
							if ($value['show_if_checked'] == 'option') {
476
								echo 'show_options_if_checked';
477
							}
478
						?>">
479
					<?php
480
					}
481
					?>
482
						<legend class="screen-reader-text"><span><?php echo esc_html($value['title']); ?></span></legend>
483
						<label for="<?php echo $value['id'] ?>">
484
						<input
485
							name="<?php echo esc_attr($value['id']); ?>"
486
							id="<?php echo esc_attr($value['id']); ?>"
487
							type="checkbox"
488
							value="1"
489
							<?php checked($option_value, 'yes'); ?>
490
							<?php echo implode(' ', $custom_attributes); ?>
491
						/> <?php echo wp_kses_post($value['desc']) ?></label> <?php echo $tip; ?>
492
					<?php
493
					if ( ! isset($value['checkboxgroup']) || (isset($value['checkboxgroup']) && $value['checkboxgroup'] == 'end')) {
494
						?>
495
							</fieldset>
496
						</td>
497
						</tr>
498
						<?php
499
					} else {
500
						?>
501
						</fieldset>
502
						<?php
503
					}
504
505
					break;
506
507
				// Default: run an action
508
				default:
509
					do_action('auto_load_next_post_admin_field_'.$value['type'], $value);
510
511
					break;
512
			} // end switch
513
514
		}
515
516
	} // END output_fields()
517
518
		/**
519
		 * Save admin fields.
520
		 *
521
		 * Loops though the plugin name options array and outputs each field.
522
		 *
523
		 * @access public
524
		 * @static
525
		 * @since  1.0.0
526
		 * @param  array $options Opens array to output
527
		 * @return bool
528
		 */
529
		public static function save_fields( $options, $current_tab ) {
530
			if ( empty( $_POST ) ) {
531
				return false;
532
			}
533
534
			// Options to update will be stored here
535
			$update_options = array();
536
537
			// Loop options and get values to save
538
			foreach ( $options as $value ) {
539
540
				if ( ! isset( $value['id'] ) ) {
541
					continue;
542
				}
543
544
				$type = isset( $value['type'] ) ? sanitize_title( $value['type'] ) : '';
545
546
				// Get the option name
547
				$option_value = null;
548
549
				switch ( $type ) {
550
					// Standard types
551
					case "checkbox" :
552
						if ( isset( $_POST[$value['id']] ) ) {
553
							$option_value = 'yes';
554
						} else {
555
							$option_value = 'no';
556
						}
557
558
					break;
559
560 View Code Duplication
					case "textarea" :
561
						if ( isset( $_POST[$value['id']] ) ) {
562
							$option_value = wp_kses_post( trim( stripslashes( $_POST[$value['id']] ) ) );
563
						} else {
564
							$option_value = '';
565
						}
566
567
					break;
568
569
					case "text" :
570
					case "number":
571
					case "select" :
572
					case "single_select_page" :
573 View Code Duplication
					case "radio" :
574
						if ( isset( $_POST[$value['id']] ) ) {
575
							$option_value = auto_load_next_post_clean( stripslashes( $_POST[$value['id']] ) );
576
						} else {
577
							$option_value = '';
578
						}
579
580
					break;
581
582
					// Special types
583
					case "multiselect" :
584
						// Get array
585
						if ( isset( $_POST[$value['id']] ) ) {
586
							$selected_values = array_map( 'auto_load_next_post_clean', array_map( 'stripslashes', (array) $_POST[$value['id']] ) );
587
						} else {
588
							$selected_values = array();
589
						}
590
						$option_value = $selected_values;
591
592
					break;
593
594
					// Custom handling
595
					default :
596
						do_action( 'auto_load_next_post_update_option_' . $type, $value );
597
598
					break;
599
				} // END switch()
600
601
				if ( ! is_null( $option_value ) ) {
602
603
					// Check if option is an array
604
					if ( strstr( $value['id'], '[') ) {
605
						parse_str( $value['id'], $option_array );
606
607
						// Option name is first key
608
						$option_name = current( array_keys( $option_array ) );
609
610
						// Get old option value
611
						if ( ! isset($update_options[$option_name])) {
612
							$update_options[$option_name] = get_option($option_name, array());
613
						}
614
615
						if ( ! is_array($update_options[$option_name])) {
616
							$update_options[$option_name] = array();
617
						}
618
619
						// Set keys and value
620
						$key = key($option_array[$option_name]);
621
						$update_options[$option_name][$key] = $option_value;
622
623
					// Single value
624
					} else {
625
						$update_options[$value['id']] = $option_value;
626
					}
627
628
				}
629
630
				// Custom handling
631
				do_action( 'auto_load_next_post_update_option', $value );
632
			}
633
634
			// Now save the options
635
			foreach ( $update_options as $name => $value ) {
636
				update_option( $name, $value );
637
			}
638
639
			// Save all options as an array. Ready for export.
640
			update_option( 'auto_load_next_post_options_' . $current_tab, $update_options );
641
642
			return true;
643
		} // END save_fields()
644
645
	} // END class.
646
647
} // END if class exists.
648