#31274 closed enhancement (duplicate)
Use Settings API for site options
| Reported by: |
|
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.phpcan't be used).- Settings errors:
wp-admin/options-head.phpis 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