#31274 closed enhancement (duplicate)
Use Settings API for site options
Reported by: | GregLone | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | |
Component: | Options, Meta APIs | Keywords: | |
Focuses: | administration, multisite | Cc: |
Description
Hello.
For my little story:
One of my plugin can work for monosite and multisite. In a multisite configuration, my options need to be "network wide" though. So far, I used to store them in the main blog (let's say it's the number 1), and then I used to use:
switch_to_blog( 1 ); $my_options = get_option( 'sfml' ); restore_current_blog();
Today I think it's a bit overkill, just to get one option :/
So I naturally started to look at site options.
Now, for the "problem":
For "monosite" options it's very simple when you use the Settings API:
- You register your setting into the white list + sanitization callback (
register_setting()
), - You build your form (pointing to
options.php
) using settings sections, fields, nonce, etc. - And you're done: when your form is submitted, your option is updated.
For site-wide options, 2 pieces are missing:
options.php
: there is none forupdate_site_option()
(network/settings.php
can't be used).- Settings errors:
wp-admin/options-head.php
is not automatically included (it is used to display the errors).
A possible solution, at least for the update part, is to use admin-post.php
.
As an example, here is what I intend to use for my plugin, most of the code is picked from options.php
and should easily be adapted:
if ( is_multisite() ) : add_action( 'admin_post_update', 'sfml_update_site_option_on_submit' ); function sfml_update_site_option_on_submit() { $option_group = 'sfml_settings'; // Restrict to my option group, I don't want to die() if another plugin has the same idea. if ( ! isset( $_POST['option_page'] ) || $_POST['option_page'] !== $option_group ) { return; } $capability = apply_filters( "option_page_capability_{$option_group}", 'manage_network_options' ); if ( ! current_user_can( $capability ) ) { wp_die( __( 'Cheatin’ uh?' ), 403 ); } check_admin_referer( $option_group . '-options' ); $whitelist_options = apply_filters( 'whitelist_options', array() ); if ( ! isset( $whitelist_options[ $option_group ] ) ) { wp_die( __( '<strong>ERROR</strong>: options page not found.' ) ); } $options = $whitelist_options[ $option_group ]; if ( $options ) { foreach ( $options as $option ) { $option = trim( $option ); $value = null; if ( isset( $_POST[ $option ] ) ) { $value = $_POST[ $option ]; if ( ! is_array( $value ) ) { $value = trim( $value ); } $value = wp_unslash( $value ); } update_site_option( $option, $value ); } } /** * Handle settings errors and return to options page */ // If no settings errors were registered add a general 'updated' message. if ( ! count( get_settings_errors() ) ) { add_settings_error( 'general', 'settings_updated', __( 'Settings saved.' ), 'updated' ); } set_transient( 'settings_errors', get_settings_errors(), 30 ); /** * Redirect back to the settings page that was submitted */ $goback = add_query_arg( 'settings-updated', 'true', wp_get_referer() ); wp_redirect( $goback ); exit; } endif;
As an alternative, network/settings.php
or options.php
could be enhanced.
What do you think?
related to #15691