最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Update a core option from plugin settings page

programmeradmin0浏览0评论

I'm trying to update a core WordPress option, image_default_link_type, from my plugin's settings page, but WordPress is refusing to update it. The options registered by the plugin itself are updated. Here is a minimal example:

add_action( 'init', 'wpse_register_plugin_settings' );    
add_action( 'admin_menu', 'wpse_add_plugin_admin_menu_entry' );

/**
 * Register a plugin setting.
 */
function wpse_register_plugin_settings() {
    add_settings_field(
        'my_plugin_settings',
        __( 'Settings', 'my-plugin' ),
        'wpse_display_settings_field',
        'my-plugin-admin-options',
    );

    register_setting(
        'my-plugin-admin-options',
        'my_plugin_setting',
    );
}

/**
 * Callback function for the plugin settings section.
 */
function wpse_display_settings_field() {
    require_once plugin_dir_path( 'my-plugin' ) . 'partials/admin/settings/section-display.php';
}

/**
 * Add the settings page as an entry in the admin menu.
 */
function wpse_add_plugin_admin_menu_entry() {
    add_options_page(
        __( 'My Plugin Settings', 'my-plugin' ),
        __( 'My Plugin', 'my-plugin' ),
        'manage_options',
        'my-plugin-setting-page-slug',
        'wpse_output_plugin_settings_page'
    );
}

/**
 * Callback function for the plugin settings page.
 */
function wpse_output_plugin_settings_page() {
    // Check user has permissions.
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_die(
            '<h1>' . esc_html__( 'You need a higher level of permission.', 'my-plugin' ) . '</h1>' .
            '<p>' . esc_html__( 'Sorry, you are not allowed to use the plugin admin settings.', 'my-plugin' ) . '</p>',
            403
        );
    }

    require_once plugin_dir_path( 'my-plugin' ) . 'partials/admin/settings/display.php';
}

Contents of section-display.php:

<label for="my_plugin_setting">
    <input type="checkbox" name="my_plugin_setting" id="my_plugin_setting" value="1" <?php checked( get_option( 'my_plugin_setting' ) ); ?> />
    <?php esc_html_e( 'Some setting', 'my-plugin' ); ?>
</label>
<br/>
<select name="image_default_link_type">
    <!-- some options -->
</select>

Contents of display.php:

<?php

/**
 * Plugin settings.
 */
?>
<div class="wrap">
    <h2><?php esc_html_e( 'My Plugin Settings', 'my-plugin' ); ?></h2>
    <div>
        <form method="post" action="options.php">
            <?php settings_fields( 'my-plugin-admin-options' ); ?>
            <?php do_settings_sections( 'my-plugin-admin-options' ); ?>
            <?php submit_button( esc_html__( 'Save Changes' ) ); ?>
        </form>
    </div>
</div>

WordPress seems to be blocking the setting from being updated. How can I enable updates to core options via my plugin's settings page?

I'm trying to update a core WordPress option, image_default_link_type, from my plugin's settings page, but WordPress is refusing to update it. The options registered by the plugin itself are updated. Here is a minimal example:

add_action( 'init', 'wpse_register_plugin_settings' );    
add_action( 'admin_menu', 'wpse_add_plugin_admin_menu_entry' );

/**
 * Register a plugin setting.
 */
function wpse_register_plugin_settings() {
    add_settings_field(
        'my_plugin_settings',
        __( 'Settings', 'my-plugin' ),
        'wpse_display_settings_field',
        'my-plugin-admin-options',
    );

    register_setting(
        'my-plugin-admin-options',
        'my_plugin_setting',
    );
}

/**
 * Callback function for the plugin settings section.
 */
function wpse_display_settings_field() {
    require_once plugin_dir_path( 'my-plugin' ) . 'partials/admin/settings/section-display.php';
}

/**
 * Add the settings page as an entry in the admin menu.
 */
function wpse_add_plugin_admin_menu_entry() {
    add_options_page(
        __( 'My Plugin Settings', 'my-plugin' ),
        __( 'My Plugin', 'my-plugin' ),
        'manage_options',
        'my-plugin-setting-page-slug',
        'wpse_output_plugin_settings_page'
    );
}

/**
 * Callback function for the plugin settings page.
 */
function wpse_output_plugin_settings_page() {
    // Check user has permissions.
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_die(
            '<h1>' . esc_html__( 'You need a higher level of permission.', 'my-plugin' ) . '</h1>' .
            '<p>' . esc_html__( 'Sorry, you are not allowed to use the plugin admin settings.', 'my-plugin' ) . '</p>',
            403
        );
    }

    require_once plugin_dir_path( 'my-plugin' ) . 'partials/admin/settings/display.php';
}

Contents of section-display.php:

<label for="my_plugin_setting">
    <input type="checkbox" name="my_plugin_setting" id="my_plugin_setting" value="1" <?php checked( get_option( 'my_plugin_setting' ) ); ?> />
    <?php esc_html_e( 'Some setting', 'my-plugin' ); ?>
</label>
<br/>
<select name="image_default_link_type">
    <!-- some options -->
</select>

Contents of display.php:

<?php

/**
 * Plugin settings.
 */
?>
<div class="wrap">
    <h2><?php esc_html_e( 'My Plugin Settings', 'my-plugin' ); ?></h2>
    <div>
        <form method="post" action="options.php">
            <?php settings_fields( 'my-plugin-admin-options' ); ?>
            <?php do_settings_sections( 'my-plugin-admin-options' ); ?>
            <?php submit_button( esc_html__( 'Save Changes' ) ); ?>
        </form>
    </div>
</div>

WordPress seems to be blocking the setting from being updated. How can I enable updates to core options via my plugin's settings page?

Share Improve this question asked Jan 4, 2021 at 12:23 SeanSean 6677 silver badges17 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

The file wp-admin/options.php handles updates to options submitted via the admin area and filters the submitted option values against a list of allowed options for the option page that submitted the request.

The allowed list (called a "whitelist" before WordPress 5.5) uses the value of the variable $option_page to determine the settings that are allowed to be updated. The $option_page value will be set to whatever was specified as the argument to settings_fields() when the options page was output, which in your case is my-plugin-admin-options.

The core option image_default_link_type is only allowed to be updated when $option_page is media. That's why it doesn't get updated by your plugin's settings page. You noticed that your own plugin's settings were updated without any issue - this is because register_setting adds the option name to the allowed list for the specified $option_page automatically.

The solution is to add a filter on allowed_options (WordPress 5.5+) or whitelist_options (WordPress < 5.5) that adds the core option to the list of allowed options for the current $option_page:

add_filter( 'allowed_options', 'wpse_allow_image_default_link_type_update' );

/**
 * Allow core `image_default_link_type` setting to be updated from the
 * plugin settings page.
 *
 * @global $option_page
 */
function wpse_allow_image_default_link_type_update( $allowed_options ) {
    global $option_page;

    if ( 'my-plugin-admin-options' === $option_page ) {
        $allowed_options['my-plugin-admin-options'][] = 'image_default_link_type';
    }

    return $allowed_options;
}
发布评论

评论列表(0)

  1. 暂无评论