parent_page = 'options-general.php'; $this->prefix = $key; $this->capability = 'administrator'; $this->option_key = "{$key}-settings"; $this->init_action = "{$key}_settings"; $this->sanitize_action = "{$key}_on_sanitize"; // {sanitize_on_action}_{field_key} $this->sanitize_filter = "{$key}_sanitize"; // {sanitize_filter}_{field_key} $this->pages = []; $this->sections = []; $this->settings = []; add_action( 'init', [ $this, 'settings_init_hook' ] ); add_action( 'admin_menu', [ $this, 'register_pages' ] ); add_action( 'admin_init', [ $this, 'register_settings' ] ); } public function settings_init_hook() { do_action( $this->init_action ); } public function register_pages() { foreach ( $this->pages as $key => $name ) { add_submenu_page( $this->parent_page, $name, $name, $this->capability, $key, function () use ( $name, $key ) { ?>

debug ) { echo '
';
							echo esc_html( print_r( $this->get_settings(), true ) );
							echo '
'; } ?>
prefix}-errors" ); settings_fields( "{$this->prefix}-group" ); $this->do_settings_sections( $key ); submit_button(); ?>
prefix}-group", $this->option_key, [ $this, 'sanitize' ] ); foreach ( $this->sections as $key => $values ) { add_settings_section( $key, $values['title'], function () use ( $values ) { echo apply_filters( 'the_content', $values['description'] ); }, $values['page'] ); } foreach ( $this->settings as $key => $values ) { $args = [ 'label_for' => $key, ]; add_settings_field( $key, $values['name'], function () use ( $key, $values ) { $choices = []; if ( 'select' == $values['type'] ) { $choices = $values['choices']; } $args = shortcode_atts( [ 'pre_field' => '', 'after_field' => '', ], $values['args'] ); echo $args['pre_field']; echo $this->do_field( $key, $values['type'], $choices ); echo $args['after_field']; }, $values['page'], $values['section'], $args ); } } public function sanitize( $input ) { do_action( "{$this->sanitize_action}", $input ); foreach ( $input as $key => $val ) { do_action( "{$this->sanitize_action}_{$key}", $val, $input ); } $defaults = $this->get_settings(); foreach ( $defaults as $key => $old_val ) { if ( isset( $this->settings[ $key ] ) && 'message' == $this->settings[ $key ]['type'] ) { continue; } if ( isset( $input[ $key ] ) ) { $input[ $key ] = esc_html( apply_filters( "{$this->sanitize_filter}_{$key}", $input[ $key ] ) ); } else { $input[ $key ] = $old_val; } } return $input; } /** * Helpers */ private function do_field( $key, $type, $choices = [] ) { $val = $this->get_setting( $key ); $return = ''; switch ( $type ) { case 'checkbox': $return .= sprintf( '', $this->option_key, $key, ( true == $val ? 'checked' : '' ) ); break; case 'select': $return .= sprintf( ''; break; case 'textarea': $return .= sprintf( '', $this->option_key, $key, $val ); break; case 'message': $return .= $val; break; default: $return .= sprintf( '', $this->option_key, $key, $val ); } return $return; } private function do_settings_sections( $page ) { global $wp_settings_sections, $wp_settings_fields; if ( ! isset( $wp_settings_sections[ $page ] ) ) { return; } foreach ( (array) $wp_settings_sections[ $page ] as $section ) { echo '
'; if ( $section['title'] ) { echo "

{$section['title']}

\n"; } if ( $section['callback'] ) { call_user_func( $section['callback'], $section ); } if ( ! isset( $wp_settings_fields ) || ! isset( $wp_settings_fields[ $page ] ) || ! isset( $wp_settings_fields[ $page ][ $section['id'] ] ) ) { echo '
'; continue; } echo ''; do_settings_fields( $page, $section['id'] ); echo '
'; echo ''; } } /** * Public setters */ public function set_parent_page( $parent_slug ) { $this->parent_page = $parent_slug; } public function set_capability( $cap ) { $this->capability = $cap; } public function set_debug( $debug ) { if ( ! is_bool( $debug ) ) { $this->debug = false; } $this->debug = $debug; } /** * Public Methods */ public function get_settings() { $defaults = []; foreach ( $this->settings as $key => $vals ) { $defaults[ $key ] = $vals['default']; } return wp_parse_args( get_option( $this->option_key ), $defaults ); } public function get_setting( $key ) { $options = $this->get_settings(); if ( isset( $options[ $key ] ) ) { return $options[ $key ]; } if ( ! isset( $this->settings[ $key ] ) ) { return false; } return $this->settings[ $key ]['default']; } public function add_page( $key, $title ) { $key = "{$this->prefix}-{$key}"; $this->pages[ $key ] = $title; return $key; } public function add_section( $page, $key, $title, $description = '' ) { if ( ! isset( $this->pages[ $page ] ) ) { return false; } $key = "{$this->prefix}-section-{$key}"; $this->sections[ $key ] = [ 'title' => $title, 'page' => $page, 'description' => $description, ]; return $key; } /** * Input fields */ public function add_input( $section, $key, $name, $default = '', $args = [] ) { if ( ! isset( $this->sections[ $section ] ) ) { return false; } $this->settings[ $key ] = [ 'page' => $this->sections[ $section ]['page'], 'section' => $section, 'name' => $name, 'type' => 'input', 'default' => $default, 'args' => $args, ]; return $key; } public function add_textarea( $section, $key, $name, $default = '', $args = [] ) { if ( ! isset( $this->sections[ $section ] ) ) { return false; } $this->settings[ $key ] = [ 'page' => $this->sections[ $section ]['page'], 'section' => $section, 'name' => $name, 'type' => 'textarea', 'default' => $default, 'args' => $args, ]; return $key; } public function add_checkbox( $section, $key, $name, $default = false, $args = [] ) { if ( ! isset( $this->sections[ $section ] ) ) { return false; } $this->settings[ $key ] = [ 'page' => $this->sections[ $section ]['page'], 'section' => $section, 'name' => $name, 'type' => 'checkbox', 'default' => $default, 'args' => $args, ]; return $key; } public function add_select( $section, $key, $name, $choices, $default = '', $args = [] ) { if ( ! isset( $this->sections[ $section ] ) ) { return false; } if ( '' == $default || ! isset( $choices[ $default ] ) ) { $default = current( array_keys( $choices ) ); } $this->settings[ $key ] = [ 'page' => $this->sections[ $section ]['page'], 'section' => $section, 'name' => $name, 'type' => 'select', 'choices' => $choices, 'default' => $default, 'args' => $args, ]; return $key; } public function add_message( $section, $key, $name, $message = '', $args = [] ) { if ( ! isset( $this->sections[ $section ] ) ) { return false; } $this->settings[ $key ] = [ 'page' => $this->sections[ $section ]['page'], 'section' => $section, 'name' => $name, 'type' => 'message', 'default' => $message, 'args' => $args, ]; return $key; } }