WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 3 years ago

Last modified 3 years ago

#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 for update_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?

Change History (5)

This ticket was mentioned in Slack in #core-multisite by johnbillion. View the logs.


4 years ago

This ticket was mentioned in Slack in #core-multisite by jeremyfelt. View the logs.


3 years ago

#3 @Bueltge
3 years ago

related to #15691

#4 @flixos90
3 years ago

  • Resolution set to duplicate
  • Status changed from new to closed

Let's continue discussion and development in #15691 where we already have patches to build on.

#5 @netweb
3 years ago

  • Milestone Awaiting Review deleted
Note: See TracTickets for help on using tickets.