3

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
  • you need to pass the nonce itself and not the nonce field name, try with wp_verify_nonce($_POST['_wp_nonce'], 'wpshout_option_page_example_action' )
    – mmm
    Commented Dec 8, 2017 at 9:14
  • thank you but also it's not work
    – Alex
    Commented Dec 8, 2017 at 9:33

2 Answers 2

1

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.

-1

I think for your wp_nonce_field you have to use a second parameter (the field name of your custom nonce).

<?php echo wp_nonce_field( 'wpshout_option_page_example_action', 'wpshout_option_page_nonce_field' ); ?>

Then when you're using your if statement for nonce use it :

if (! wp_verify_nonce( $_POST['wpshout_option_page_nonce_field'], 'wpshout_option_page_example_action' )) {
    wp_die('Nonce verification failed');
}

Try it, I think it's ok :)

2
  • Hum, try to dump and die your $_POST before the if statement of your nonce and show us. Possibly the hook :/
    – Elex
    Commented Dec 8, 2017 at 17:48
  • I have downvoted your answer because you did not test your solution! Commented Apr 25, 2021 at 7:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.