Support » Developing with WordPress » Sequence of admin_post and admin_menu

  • Resolved ace0930

    (@ace0930)


    I use the hook admin_menu to create a custom menu page that has a form. And it looks like the below:

    
    function wpdocs_register_my_custom_menu_page(){
       add_menu_page( 
          'custom menu',
          'custom menu',
          'manage_options',
          'custompage',
          'my_custom_menu_page',
          plugins_url( 'myplugin/images/icon.png' ),
          6
       ); 
    }
    
    function my_custom_menu_page () {
       require_once form.php;
    }
    
    add_action( 'admin_menu', 'wpdocs_register_my_custom_menu_page' );
    

    I have a function to process the submitted data attach to the admin_post_{$action} hook which looks like the below:

    
    function process_form () {
       wp_redirect ( 'https://example.com' );
    }
    
    add_action( 'admin_post_process_form', 'process_form' );
    

    The problem is that wp_redirect is actually header ( "Location: https://example.com" ), so if the sequence is admin_menu -> admin_post_process_form, it should cause an error because the output is sent ( the form require_once form.php; ).

    Or actually the admin_post_process_form will not be “require” on the custom menu page?

    Because I have test to put the header ( "Location: https://example.com" ) on the custom menu page after the form, there is no error which is very weird ( already turn on all error ).

Viewing 8 replies - 1 through 8 (of 8 total)
  • You should check within process_form() if the request is a POST request and only then do the forwarding. If the form is simply called, it is a GET request and you do not want to forward it.

    Thread Starter ace0930

    (@ace0930)

    @threadi Hi, sorry but I don’t think you understand the question…

    Then describe the problem differently. I understand that you are always redirected? Perhaps the complete source code you use would also be interesting, so that I could test it myself.

    Thread Starter ace0930

    (@ace0930)

    @threadi From the doc

    Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP.

    Normally, we will have another file/script to handle the form like, right?
    Assume index.php has a form and it looks like this:

    
    <form action="process.php" method="post"></form>
    

    Then in the process.php file, we use $_POST to get the data like this ( call this “example-1” for later reference ):

    
    $name = $_POST['name'];
    
    header ( "Location: https://example.com" ); // Redirect user to https://example.com after processing the data.
    

    But if we put the processing code above on the same file ( index.php ) and it looks like this ( call this “example-2” for later reference ):

    
    <form action="process.php" method="post"></form>
    
    <?php
    $name = $_POST['name'];
    
    header ( "Location: https://example.com" );
    ?>
    

    It would cause an error because there is already an output ( the form ) before the header ().

    Now let’s get back to the “WordPress” way of handling form, we will use the hook admin_post_{$action} with a function like:

    
    add_action( admin_post_handle_data, handle_data );
    

    Then we write the processing code inside handle_data like the below:

    
    function handle_data () {
       $name = $_POST['name'];
    
       header ( "Location: https://example.com" );
    }
    

    The form page is created by add_menu_page with the admin_menu hook.

    My question is:
    1) Will this function handle_data () be include/require on the form page? If it does, it will look like the “example-2”.

    2) If the question “1)” is a yes, then the sequence matter, whether it’s admin_post first or admin_menu first. If it’s admin_post first, then the function handle_data () is before the form; If it’s the admin_menu first, then the function handle_data () is after the form.

    Or am I complicating it, WordPress will just do the traditional way like “example-1” where the processing code is in another script/file?

    • This reply was modified 2 weeks, 6 days ago by ace0930.

    No, if the function is executed only when the hook ‘admin_post_handle_data’ is executed. This is basically unrelated to your form. So you could theoretically execute the hook in other contexts.

    You can have a look at the hook here:
    https://github.com/WordPress/WordPress/blob/master/wp-admin/admin-post.php

    While your form is executed via admin_menu, here: https://github.com/WordPress/WordPress/blob/master/wp-admin/includes/menu.php#L155

    Thread Starter ace0930

    (@ace0930)

    @threadi To be honest, I still do not fully understand. But do you mean the function handle_data () will not be include/require on the form page? If it’s true, then my question is solved.

    That’s exactly what I meant. This processing is done long before the form is output.

    Thread Starter ace0930

    (@ace0930)

    @threadi You saved my day, thank you so much!

Viewing 8 replies - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.