Passed
Push — master ( 53d0e8...738d0e )
by Chris
10:21
created

uix   F

Complexity

Total Complexity 79

Size/Duplication

Total Lines 596
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 299
c 2
b 0
f 0
dl 0
loc 596
rs 2.08
wmc 79

How to fix   Complexity   

Complex Class

Complex classes like uix 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.

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 uix, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * UIX Setting Class.
4
 *
5
 * @package   uix
6
 * @author    David Cramer
7
 * @license   GPL-2.0+
8
 * @link
9
 * @copyright 2016 David Cramer
10
 */
11
namespace lsx\ui;
12
13
/**
14
 * Settings class
15
 *
16
 * @package uix
17
 * @author  David Cramer
18
 */
19
class uix {
20
21
	/**
22
	 * The slug for this plugin
23
	 *
24
	 * @since 1.0.0
25
	 * @var      string
26
	 */
27
	protected $plugin_slug = null;
28
29
	/**
30
	 * List of registered pages
31
	 *
32
	 * @since 1.0.0
33
	 * @var      array
34
	 */
35
	protected $pages = array();
36
37
	/**
38
	 * List of registered metaboxes
39
	 *
40
	 * @since 1.0.0
41
	 * @var      array
42
	 */
43
	protected $metaboxes = array();
44
45
	/**
46
	 * Holds class instance
47
	 *
48
	 * @since 1.0.0
49
	 * @var      object|\uix
50
	 */
51
	protected static $instance = null;
52
53
	/**
54
	 * Holds the option screen prefix
55
	 *
56
	 * @since 1.0.0
57
	 * @var      string
58
	 */
59
	protected $plugin_screen_hook_suffix = null;
60
61
	/**
62
	 * Holds the current_tab being rendered
63
	 *
64
	 * @since 1.0.0
65
	 * @var      string
66
	 */
67
	public $current_tab = null;
68
69
	/**
70
	 * Initialize the plugin by setting localization, filters, and
71
	 * administration functions.
72
	 *
73
	 * @since  1.0.0
74
	 * @access private
75
	 */
76
	private function __construct( $slug ) {
77
78
79
		// set slug
80
		$this->plugin_slug = $slug;
81
82
		// add admin page
83
		add_action( 'admin_menu', array( $this, 'add_settings_pages' ), 25 );
84
85
		// add metaboxes
86
		add_action( 'add_meta_boxes', array( $this, 'add_metaboxes' ), 25 );
87
88
		// save config
89
		add_action( 'wp_ajax_' . $this->plugin_slug . '_save_config', array(
90
			$this,
91
			'save_config',
92
		) );
93
94
	}
95
96
97
	public function add_metaboxes() {
98
		//add_meta_box( 'meta-box-id', __( 'My Meta Box', 'textdomain' ), array( $this, 'render_metabox' ), 'post' );
99
	}
100
101
	public function render_metabox( $a ) {
102
		var_dump( $a );
103
		die;
104
	}
105
106
	/**
107
	 * Return an instance of this class.
108
	 *
109
	 * @since 1.0.0
110
	 * @return    object|\uix\uix    A single instance of this class.
111
	 */
112
	public static function get_instance( $slug ) {
113
114
		// If the single instance hasn't been set, set it now.
115
		if ( null == self::$instance ) {
116
			self::$instance = new self( $slug );
117
		}
118
119
		return self::$instance;
120
121
	}
122
123
	/**
124
	 * Return a setting
125
	 *
126
	 * @since 1.0.0
127
	 * @return    string/array    the requested setting
128
	 */
129
	public static function get_setting( $path, $manual = false ) {
130
131
		$path      = explode( '.', $path );
132
		$temp      = null;
133
		$page_slug = array_shift( $path );
134
135
		if ( null == self::$instance || true === $manual ) {
136
			if ( false === $manual ) {
137
				trigger_error( 'Cannot request a value without a UIX instance. Set second argument to TRUE for manual lookup.' );
138
139
				return;
140
			}
141
			// attempt a manual lookup - requires the full option name
142
			$option_tag = $page_slug;
143
		} else {
144
			if ( ! empty( self::$instance->pages[ $page_slug ]['option_name'] ) ) {
145
				$option_tag = self::$instance->pages[ $page_slug ]['option_name'];
146
			} else {
147
				$option_tag = '_' . self::$instance->plugin_slug . '_' . $page_slug;
148
			}
149
		}
150
		$temp = get_option( $option_tag );
151
		foreach ( $path as $index => $value ) {
152
			if ( ! isset( $temp[ $value ] ) ) {
153
				return null;
154
			}
155
			$temp = $temp[ $value ];
156
		}
157
158
		return $temp;
159
160
	}
161
162
	/**
163
	 * Register the admin pages
164
	 *
165
	 * @since 1.0.0
166
	 */
167
	public function register_pages( $pages ) {
168
169
		/**
170
		 * Filter settings pages to be created
171
		 *
172
		 * @param array $pages Page structures to be created
173
		 */
174
175
		$this->pages = apply_filters( $this->plugin_slug . '_set_admin_pages', $pages );
176
	}
177
178
	/**
179
	 * Register metaboxes
180
	 *
181
	 * @since 1.0.0
182
	 */
183
	public function register_metaboxes( $metaboxes ) {
184
		// register pages
185
		$this->metaboxes = $metaboxes;
186
	}
187
188
189
	/**
190
	 * Add defined contextual help to admin page
191
	 *
192
	 * @since 1.0.0
193
	 */
194
	public function add_help() {
195
196
197
		$page = $this->get_page();
198
199
		if ( ! empty( $page['help'] ) ) {
200
201
			$screen = get_current_screen();
202
203
			foreach ( (array) $page['help'] as $help_slug => $help ) {
204
205
				if ( is_file( $help['content'] ) && file_exists( $help['content'] ) ) {
206
					ob_start();
207
					include $help['content'];
208
					$content = ob_get_clean();
209
				} else {
210
					$content = $help['content'];
211
				}
212
213
				$screen->add_help_tab( array(
214
					'id'      => $help_slug,
215
					'title'   => $help['title'],
216
					'content' => $content,
217
				) );
218
			}
219
220
			// Help sidebars are optional
221
			if ( ! empty( $page['help_sidebar'] ) ) {
222
				$screen->set_help_sidebar( $page['help_sidebar'] );
223
			}
224
		}
225
226
	}
227
228
229
	/**
230
	 * Saves a config
231
	 *
232
	 * @uses  "wp_ajax_uix_save_config" hook
233
	 * @since 0.0.1
234
	 */
235
	public function save_config() {
236
237
		if ( ! empty( $_POST['config'] ) ) {
238
239
			$config = json_decode( stripslashes_deep( $_POST['config'] ), true );
240
241
			if ( wp_verify_nonce( $_POST['uix_setup'], $this->plugin_slug ) ) {
242
243
				$page_slug = sanitize_text_field( $_POST['page_slug'] );
244
245
				if ( ! empty( $this->pages[ $page_slug ] ) ) {
246
					$params = null;
247
					if ( ! empty( $_POST['params'] ) ) {
248
						$params = $_POST['params'];
249
					}
250
					/**
251
					 * Filter page settings pre save
252
					 *
253
					 * @param array $page_config the page config array
254
					 * @param array $params      any defined save_params.
255
					 */
256
					$page = apply_filters( $this->plugin_slug . '_get_page_save', $this->pages[ $page_slug ], $params );
257
258
					/**
259
					 * Filter config object
260
					 *
261
					 * @param array $config the config array to save
262
					 * @param array $page   the page config to be saved for
263
					 */
264
					$config = apply_filters( $this->plugin_slug . '_pre_save_config', $config, $page );
265
266
267
					$success = __( 'Settings saved.', $this->plugin_slug );
268
					if ( ! empty( $page['saved_message'] ) ) {
269
						$success = $page['saved_message'];
270
					}
271
					$option_tag = '_' . $this->plugin_slug . '_' . $page_slug;
272
					if ( ! empty( $page['option_name'] ) ) {
273
						$option_tag = $page['option_name'];
274
					}
275
					// push backup if not autosave
276
					if ( empty( $_POST['autosave'] ) ) {
277
						$previous = get_option( $option_tag );
278
						if ( ! empty( $previous ) ) {
279
							update_option( $option_tag . '-' . current_time( 'timestamp' ), $previous );
280
						}
281
					}
282
					// save object
283
					update_option( $option_tag, $config );
284
					wp_send_json_success( $success );
285
				}
286
287
			} else {
288
				wp_send_json_error( esc_html__( 'Could not verify nonce', $this->plugin_slug ) );
289
			}
290
291
		}
292
293
		// nope
294
		wp_send_json_error( esc_html__( 'Could not save, sorry.', $this->plugin_slug ) );
295
	}
296
297
298
	/**
299
	 * Register and enqueue admin-specific style sheet.
300
	 *
301
	 * @since 1.0.0
302
	 * @return    null
303
	 */
304
	public function enqueue_admin_stylescripts() {
305
306
		$uix = $this->get_page();
307
		if ( false === $uix ) {
308
			return;
309
		}
310
311
		$uix['slug'] = $this->plugin_slug;
312
313
		// allow for minimized scripts
314
		$prefix  = '.min';
315
		$uix_url = plugin_dir_url( __FILE__ );
316
		if ( defined( 'DEBUG_SCRIPTS' ) ) {
317
			//$prefix = null;
318
		}
319
		// base styles
320
		wp_enqueue_style( $this->plugin_slug . '-base-icons', $uix_url . 'assets/css/icons' . $prefix . '.css' );
321
		wp_enqueue_style( $this->plugin_slug . '-base-styles', $uix_url . 'assets/css/admin' . $prefix . '.css' );
322
		// enqueue scripts
323
		wp_enqueue_script( 'handlebars', $uix_url . 'assets/js/handlebars.min-latest.js', array(), null, true );
324
		// if has modals
325
		if ( ! empty( $uix['modals'] ) ) {
326
			wp_enqueue_script( $this->plugin_slug . '-core-modals', $uix_url . 'assets/js/uix-modals' . $prefix . '.js', array(
327
				'jquery',
328
				'handlebars',
329
			), null, true );
330
		}
331
		wp_enqueue_script( $this->plugin_slug . '-helpers', $uix_url . 'assets/js/uix-helpers' . $prefix . '.js', array( 'handlebars' ), null, true );
332
		wp_enqueue_script( $this->plugin_slug . '-core-admin', $uix_url . 'assets/js/uix-core' . $prefix . '.js', array(
333
			'jquery',
334
			'handlebars',
335
		), null, true );
336
337
		// enqueue admin runtime styles
338
		$this->enqueue_set( $uix, $this->plugin_slug . '-' . $uix['page_slug'] );
339
340
		// enqueue tab specific runtime styles
341
		if ( ! empty( $uix['tabs'] ) ) {
342
			foreach ( $uix['tabs'] as $tab_slug => $tab ) {
343
				//$this->enqueue_set( $tab, $this->plugin_slug . '-' . $uix['page_slug'] . '-' . $tab_slug );
344
			}
345
		}
346
347
		wp_localize_script( $this->plugin_slug . '-core-admin', 'uix', $uix );
348
	}
349
350
	/**
351
	 * enqueue a set of styles and scripts
352
	 *
353
	 * @since 0.0.1
354
	 */
355
	private function enqueue_set( $set, $prefix ) {
356
		// go over the set to see if it has styles or scripts
357
358
		// setup default args for array type includes
359
		$arguments_array = array(
360
			"src"       => false,
361
			"deps"      => array(),
362
			"ver"       => false,
363
			"in_footer" => false,
364
			"media"     => false,
365
		);
366
367
		// enqueue set specific runtime styles
368
		if ( ! empty( $set['styles'] ) ) {
369
			foreach ( $set['styles'] as $style_key => $style ) {
370
				if ( is_int( $style_key ) ) {
371
					wp_enqueue_style( $style );
372
				} else {
373
					if ( is_array( $style ) ) {
374
						$args = array_merge( $arguments_array, $style );
375
						wp_enqueue_style( $prefix . '-' . $script_key, $args['src'], $args['deps'], $args['ver'], $args['in_footer'] );
376
					} else {
377
						wp_enqueue_style( $prefix . '-' . $style_key, $style );
378
					}
379
				}
380
			}
381
		}
382
		// enqueue set specific runtime scripts
383
		if ( ! empty( $set['scripts'] ) ) {
384
			foreach ( $set['scripts'] as $script_key => $script ) {
385
				if ( is_int( $script_key ) ) {
386
					wp_enqueue_script( $script );
387
				} else {
388
					if ( is_array( $script ) ) {
389
						$args = array_merge( $arguments_array, $script );
390
						wp_enqueue_script( $prefix . '-' . $script_key, $args['src'], $args['deps'], $args['ver'], $args['in_footer'] );
391
					} else {
392
						wp_enqueue_script( $prefix . '-' . $script_key, $script );
393
					}
394
				}
395
			}
396
		}
397
398
	}
399
400
	/**
401
	 * get the config for the current page
402
	 *
403
	 * @since 0.0.1
404
	 * @return array $page array structure of current uix page
405
	 */
406
	private function get_page() {
407
408
		// check that the scrren object is valid to be safe.
409
		$screen = get_current_screen();
410
411
		if ( empty( $screen ) || ! is_object( $screen ) ) {
412
			return false;
413
		}
414
415
		// get the page slug from base ID
416
		$page_slug = array_search( $screen->base, $this->plugin_screen_hook_suffix );
417
		if ( empty( $page_slug ) || empty( $this->pages[ $page_slug ] ) ) {
418
			return false; // in case its not found or the array item is no longer valid, just leave.
419
		}
420
		/**
421
		 * Filter page object
422
		 *
423
		 * @param array $page The page object array.
424
		 */
425
		$uix = apply_filters( $this->plugin_slug . '_get_page', $this->pages[ $page_slug ] );
426
427
		if ( empty( $uix['option_name'] ) ) {
428
			$uix['option_name'] = '_' . $this->plugin_slug . '_' . sanitize_text_field( $page_slug );
429
		}
430
		// get config object
431
		$config_object = get_option( $uix['option_name'], array() );
432
433
		$uix['page_slug'] = $page_slug;
434
		/**
435
		 * Filter config object
436
		 *
437
		 * @param array $config_object The object as retrieved from DB
438
		 * @param array $page_slug     The page slug this object belongs to.
439
		 */
440
		$uix['config'] = apply_filters( $this->plugin_slug . '_get_config', $config_object, $uix );
441
442
443
		return $uix;
444
	}
445
446
	/**
447
	 * Add options page
448
	 *
449
	 * @since 0.0.1
450
	 * @uses  "admin_menu" hook
451
	 */
452
	public function add_settings_pages() {
453
454
		foreach ( (array) $this->pages as $page_slug => $page ) {
455
456
			if ( empty( $page['page_title'] ) || empty( $page['menu_title'] ) ) {
457
				continue;
458
			}
459
460
			$args = array(
461
				'capability' => 'manage_options',
462
				'icon'       => null,
463
				'position'   => null,
464
			);
465
			$args = array_merge( $args, $page );
466
467
			if ( ! empty( $page['parent'] ) ) {
468
469
				$this->plugin_screen_hook_suffix[ $page_slug ] = add_submenu_page(
470
					$args['parent'],
471
					$args['page_title'],
472
					$args['menu_title'],
473
					$args['capability'],
474
					$this->plugin_slug . '-' . $page_slug,
475
					array( $this, 'create_admin_page' )
476
				);
477
478
			} else {
479
480
				$this->plugin_screen_hook_suffix[ $page_slug ] = add_menu_page(
481
					$args['page_title'],
482
					$args['menu_title'],
483
					$args['capability'],
484
					$this->plugin_slug . '-' . $page_slug,
485
					array( $this, 'create_admin_page' ),
486
					$args['icon'],
487
					$args['position']
488
				);
489
			}
490
			add_action( 'admin_print_styles-' . $this->plugin_screen_hook_suffix[ $page_slug ], array(
491
				$this,
492
				'enqueue_admin_stylescripts',
493
			) );
494
			add_action( 'load-' . $this->plugin_screen_hook_suffix[ $page_slug ], array(
495
				$this,
496
				'add_help',
497
			) );
498
		}
499
	}
500
501
	/**
502
	 * Options page callback
503
	 *
504
	 * @since 0.0.1
505
	 */
506
	public function create_admin_page() {
507
508
		$uix           = $this->get_page();
509
		$template_path = plugin_dir_path( dirname( __FILE__ ) );
510
		?>
511
        <div class="wrap">
512
513
            <h1><?php esc_html_e( $uix['page_title'], $this->plugin_slug ); ?>
514
				<?php if ( ! empty( $uix['version'] ) ) { ?>
515
                    <small><?php esc_html_e( $uix['version'], $this->plugin_slug ); ?></small><?php } ?>
516
            </h1>
517
			<?php if ( ! empty( $uix['tabs'] ) ) { ?>
518
                <div class="wp-filter hide-if-no-js">
519
                    <ul class="filter-links">
520
						<?php foreach ( (array) $uix['tabs'] as $tab_slug => $tab ) {
521
							$display = "";
522
							if ( isset( $tab['disabled'] ) && true === $tab['disabled'] ) {
523
								$display = 'style="display:none;"';
524
							}
525
							?>
526
                            <li><a <?php echo $display; ?>
527
                                        data-tab="<?php echo esc_attr( $tab_slug ); ?>"
528
                                        href="#<?php echo esc_attr( $tab_slug ) ?>"><?php echo esc_html( $tab['menu_title'] ); ?></a>
529
                            </li>
530
						<?php } ?>
531
                    </ul>
532
                </div>
533
			<?php } ?>
534
			<?php wp_nonce_field( $this->plugin_slug, 'uix_setup' ); ?>
535
			<?php
536
			if ( ! empty( $uix['tabs'] ) ) {
537
				$this->current_tab = false;
538
				foreach ( (array) $uix['tabs'] as $tab_slug => $tab ) {
539
					$this->current_tab = $tab_slug; ?>
540
                    <div class="uix-tab-canvas"
541
                         data-app="<?php echo esc_attr( $tab_slug ); ?>"></div>
542
                    <script type="text/html"
543
                            data-template="<?php echo esc_attr( $tab_slug ); ?>">
544
						<?php
545
						if ( ! empty( $tab['page_title'] ) ) {
546
							echo '<h2>' . $tab['page_title'];
547
						}
548
						if ( ! empty( $tab['page_description'] ) ) { ?>
549
                            <small><?php echo $tab['page_description']; ?></small> <?php }
550
						if ( ! empty( $tab['page_title'] ) ) {
551
							echo '</h2>';
552
						}
553
						// include this tabs template
554
						if ( ! empty( $tab['template'] ) && file_exists( $tab['template'] ) ) {
555
							include $tab['template'];
556
						} else {
557
							echo esc_html__( 'Template not found: ', $this->plugin_slug ) . $tab['page_title'];
558
						}
559
						?>
560
                    </script>
561
				<?php if ( ! empty( $tab['partials'] ) ){
562
				foreach ( $tab['partials'] as $partial_id => $partial ){
563
				?>
564
                    <script type="text/html"
565
                            id="__partial_<?php echo esc_attr( $partial_id ); ?>"
566
                            data-handlebars-partial="<?php echo esc_attr( $partial_id ); ?>">
567
						<?php
568
						// include this tabs template
569
						if ( ! empty( $partial ) && file_exists( $template_path . $partial ) ) {
570
							include $template_path . $partial;
571
						} else {
572
							echo esc_html__( 'Partial Template not found: ', $this->plugin_slug ) . $partial_id;
573
						}
574
						?>
575
                    </script>
576
					<?php
577
				}
578
				}
579
				}
580
				$this->current_tab = false;
581
			} else {
582
				if ( ! empty( $uix['template'] ) && file_exists( $uix['template'] ) ) {
583
					include $uix['template'];
584
				}
585
			}
586
			if ( ! empty( $uix['modals'] ) ) {
587
				foreach ( $uix['modals'] as $modal_id => $modal ) {
588
					?>
589
                    <script type="text/html"
590
                            id="__modal_<?php echo esc_attr( $modal_id ); ?>"
591
                            data-handlebars-partial="<?php echo esc_attr( $modal_id ); ?>">
592
						<?php
593
						// include this tabs template
594
						if ( ! empty( $modal ) && file_exists( $template_path . $modal ) ) {
595
							include $template_path . $modal;
596
						} else {
597
							echo esc_html__( 'Modal Template not found: ', $this->plugin_slug ) . $modal_id;
598
						}
599
						?>
600
                    </script>
601
					<?php
602
				}
603
			}
604
			?>
605
            <hr>
606
			<?php if ( ! empty( $uix['save_button'] ) ) { ?>
607
                <p class="uix-footer-bar"><button type="button" class="button button-primary" data-save-object="true">
608
					<?php esc_html_e( $uix['save_button'], $this->plugin_slug ); ?>
609
                </button>
610
                <span class="spinner uix-save-spinner"></span>
611
                <span class="save-confirm" style="display: none;"><span class="dashicons dashicons-yes"></span></span>
612
                </p>
613
			<?php } ?>
614
        </div>
615
616
        <script type="text/html" data-template="__notice">
617
            <div class="{{#if success}}updated{{else}}error{{/if}} notice uix-notice is-dismissible">
618
                <p>{{{data}}}</p>
619
                <button class="notice-dismiss" type="button">
620
                    <span class="screen-reader-text">Dismiss this notice.</span>
621
                </button>
622
            </div>
623
        </script>
624
        <script type="text/html" id="__partial_save">
625
            <button class="button" type="button"
626
                    data-modal-node="{{__node_path}}" data-app="{{__app}}"
627
                    data-type="save" {{#if
628
                    __callback}}data-callback="{{__callback}}" {{/if}}>
629
            Save Changes
630
            </button>
631
        </script>
632
        <script type="text/html" id="__partial_create">
633
            <button class="button" type="button"
634
                    data-modal-node="{{__node_path}}" data-app="{{__app}}"
635
                    data-type="add" {{#if
636
                    __callback}}data-callback="{{__callback}}" {{/if}}>
637
            Create
638
            </button>
639
        </script>
640
        <script type="text/html" id="__partial_delete">
641
            <button style="float:left;" class="button" type="button"
642
                    data-modal-node="{{__node_path}}" data-app="{{__app}}"
643
                    data-type="delete" {{#if
644
                    __callback}}data-callback="{{__callback}}" {{/if}}>
645
            Remove
646
            </button>
647
        </script>
648
		<?php
649
	}
650
651
}