I was to tried create theme options admin page (without settings API)

in this code I’d like to know why wp_verify_nonce return false:

main file

<?php

add_action('admin_menu', 'awesome_page_create');
function awesome_page_create() {
    $page_title="My Awesome Admin Page";
    $menu_title="Awesome Admin Page";
    $capability = 'edit_posts';
    $menu_slug = 'awesome_page';
    $function = 'my_awesome_page_display';
    $icon_url="";
    $position = 24;

    add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position );
}
function my_awesome_page_display() {
    if (!current_user_can('manage_options')) {
        wp_die('Unauthorized user');
    }

    if (! wp_verify_nonce( '_wp_nonce', 'wpshout_option_page_example_action' )) {
        wp_die('Nonce verification failed');
    }

    if (isset($_POST['awesome_text'])) {
        update_option('awesome_text', $_POST['awesome_text']);
        $value = $_POST['awesome_text'];
    }

    $value = get_option('awesome_text', 'hey-ho');

    include 'form-file.php';
}
$value = get_option('awesome_text');
if (FALSE === $value) {
    $value="hey-ho";
}

form-file


<h1>My Awesome Settings Page</h1>

<form method="POST">
    <label for="awesome_text">Awesome Text</label>
    <input type="text" name="awesome_text" id="awesome_text" value="<?php echo $value; ?>" />
    <?php echo wp_nonce_field( 'wpshout_option_page_example_action' ); ?>
    <input type="submit" value="Save" class="button button-primary button-large" />
</form>

2 Answers
2

Revised code

if(is_admin()) {
    add_action('admin_menu', 'awesome_page_create');
    function awesome_page_create() {
        $page_title="My Awesome Admin Page";
        $menu_title="Awesome Admin Page";
        $capability = 'edit_posts';
        $menu_slug = 'awesome_page';
        $function = 'my_awesome_page_display';
        $icon_url="";
        $position = 24;
        add_menu_page($page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position);
    }
    function my_awesome_page_display() {
        if (!current_user_can('manage_options')) {
            wp_die('Unauthorized user');
        }
        $value = get_option('awesome_text', '');
?>
        <h1>My Awesome Settings Page</h1>
        <form method="POST">
            <label for="awesome_text">Awesome Text</label>
            <input type="text" name="awesome_text" id="awesome_text" value="<?php echo $value; ?>" />
            <?php wp_nonce_field('wpshout_option_page_example_action', 'awesome_nonce', false); ?>
            <input type="submit" value="Save" class="button button-primary button-large" />
        </form>
<?php
    }
    add_action('init', 'process_my_awesome_form_data');
    function process_my_awesome_form_data() {
        if(isset($_REQUEST['awesome_nonce'])) {
            if(wp_verify_nonce($_REQUEST['awesome_nonce'], 'wpshout_option_page_example_action')) {
                if (isset($_POST['awesome_text'])) {
                    update_option('awesome_text', $_POST['awesome_text']);
                }
            } else {
                echo 'nonce verification failed';
            }
        }
    }
}

Explanation

if(is_admin()) { is to make sure, you’re creating admin menu in the right context.

Instead of include 'form-file.php';, the form is embedded in my_awesome_page_display function, which makes it easier to debug. The line <?php echo wp_nonce_field( 'wpshout_option_page_example_action' ); ?> in form’s definition was changed to <?php wp_nonce_field('wpshout_option_page_example_action', 'awsome_nonce', false); ?>. Your original line was outputting two identical hidden input fields for nonce, one, because of echo, and second, because the fourth parameter had default value of true (which means – print this line).

Don’t process your form’s submission in my_awesome_page_display function. Instead, use init hook to add the form’s submission processing function process_my_awsome_form_data. In that function, $_REQUEST['awsome_nonce'] is used to retrieve the value of nonce for verification, $_POST['awesome_text'] is used to retrive the value of the text input.

Leave a Reply

Your email address will not be published. Required fields are marked *