I had a need on a recent project to add a few settings for multisite administrators. Rather than running to Google or the Codex, I decided to just dig into core. It actually took me less time than I thought it would and was surprisingly simple. Here’s a basic example of how I added, sanitized and saved network-wide settings. There’s a lot of boilerplate, scroll down to Lines 41-96 for the important bits.
<?php class Plugin { private static $instance; /** * Get active object instance * * @since 1.0 * * @access public * @static * @return object */ public static function get_instance() { if ( ! self::$instance ) self::$instance = new Plugin(); return self::$instance; } /** * Class constructor. Includes constants, includes and init method. * * @since 1.0 * * @access public * @return void */ public function __construct() { $this->init(); } /** * Run action and filter hooks. * * @since 1.0 * * @access private * @return void */ private function init() { //Adds settings to Network Settings add_filter( 'wpmu_options' , array( $this, 'show_network_settings' ) ); add_action( 'update_wpmu_options', array( $this, 'save_network_settings' ) ); } public static function save_network_settings() { $posted_settings = array_map( 'sanitize_text_field', $_POST['plugin'] ); foreach ( $posted_settings as $name => $value ) { update_site_option( $name, $value ); } } public static function show_network_settings() { $settings = self::get_network_settings(); ?> <h3><?php _e( 'Plugin Settings' ); ?></h3> <table id="menu" class="form-table"> <?php foreach ( $settings as $setting ) : ?> <tr valign="top"> <th scope="row"><?php echo $setting['name']; ?></th> <td> <input type="<?php echo $setting['type'];?>" name="plugin[<?php echo $setting['id']; ?>]" value="<?php echo esc_attr( get_site_option( $setting['id'] ) ); ?>" /> <br /><?php echo $setting['desc']; ?> </td> </tr> <?php endforeach; echo '</table>'; } public static function get_network_settings() { $settings[] = array( 'id' => 'data-one', 'name' => __( 'Data Name' ), 'desc' => __( 'Here is some description' ), 'type' => 'text', 'size' => 'regular' ); $settings[] = array( 'id' => 'data-two', 'name' => __( 'More Data' ), 'desc' => __( 'More description!' ), 'std' => '5', 'type' => 'text' ); return apply_filters( 'plugin_settings', $settings ); } } Plugin::get_instance();