'How to POST to admin-post.php from Avada formbuilder form

Using the Avada theme's form builder functionality, I’m attempting to use the “Send to URL” option to POST the form and then run an api call in a plugin I’ve written.

I was thinking I could set the “Send to URL” value to /wp-admin/admin-post.php and add a hidden field to the form named “action” with a value of “make_api_call” to get it to run the code in my plugin set up like so:

add_action('admin_post_make_api_call', 'make_api_call');
function make_api_call()
{
    //todo: make the api call

    wp_redirect(‘another-page’);
}

However, this does not work and returns this from the server: {"status":"error","info":"url_failed"}

What I want to do is to POST the form to admin-post.php, have my plugin run code when it POSTs, and then redirect to another page.

I've checked the documentation for the AVADA theme and it only says that you can specify a url to post to but doesn't give any additional details.



Solution 1:[1]

So I eventually got something to work, and I'm not knowledgeable or experienced enough with WordPress development to know if it is the "right" way, but it works well.

I realized that using the "Send to Url" option on the Avada form, it was POSTing the form to the admin-ajax.php file. There's plenty of documentation on that and I was able to partially make that work but I was not able to make it fit my use case b/c even though there is a way to configure the Avada form to redirect to a different URL on success I couldn't append parameters to that URL based on the return value from admin-ajax.php.

For future reference, here's what I was able to make work but not fit my use case by having the Avada form submission set to Send to Url. (I'm recreating this and some of it's from memory since I went with a different solution, so it may not be 100% runnable.)

Form set to Send to Url

The way admin-ajax works is all requests to admin-ajax.php are eventually handled by a WordPress action (filter?) like so: add_action( 'wp_ajax_my_action', 'my_function' );

In the above, my_action is what you've set as the form's action by creating a hidden input element on your html form named action and setting it's value to "my_action". The my_function argument is the name of the function you want to run when the action happens.

add_action( 'wp_ajax_my_action', 'my_function' );
function my_function(){
//do stuff
}

Watching the request in Chrome's dev tools, I could see the action the form was setting was fusion_form_submit_form_to_url.

Dev tools

So ended up with this:

add_action( 'wp_ajax_fusion_form_submit_form_to_url', 'my_function' );
function my_function(){
//do stuff
}

You can see that the url you enter in the Form Submission URL field gets passed to admin-ajax as fusionAction. Whether the Avada theme does something additional with that - I don't know but you could use it to control the logic that gets executed in my_function. I suspect there's an action in the Avada form that works similar to the wp_ajax_ WordPress action but by the time I got this far I realized this wasn't going to work so I pivoted to the actual solution, below.

All of that worked okay but you can't redirect out of a call to admin-ajax.php unless you do it on the client side and I didn't want to dive into that.

What I was able to make work was configuring the Avada form to do a traditional HTTP POST. I added a hidden input element on the Avada form with a name of formName and the value set to the name of the form I wanted to handle.

Avada Form

In my plugin code, I hooked into the WordPress init action as in the code sample below, and then customized the logic to be executed based on which formName was sent in.

add_action('init', 'callback_function');
function callback_function()
{   
    if (isset($_POST['formName'])) {
        $form = $_POST['formName']; //from the hidden input element "formName"      
            
            //there is a call to wp_redirect in each case
            switch ($form) {
                case 'form1':                    
                    process_form_1();

                    break;
                case 'form2':
                    process_form_1();

                    break;

                default:
                    # code...
                    break;
            }
      
        //without this "exit" you will get errors similar to "headers already sent"
        exit;
    }
}

This allowed me to run the code I needed to run based on what form was submitted, and redirect to the correct place afterward.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 agileMike