Unable to get wp_redirect() working after adding a CPT via the front end

I am attempting to learn PHP by creating a relatively simple application built on wordpress, it is a basic CRM and I’ve made decent progress but have been stuck on some of the finer points.

I’ve been having some serious ‘headers already sent’ problems with getting wp_redirect() working after a user creates a new customer.

Read More

Here is an example of what I want to do:

  • /new-customer.php : Create a new Custom Post Type via the front end and then redirect to that particular customer’s single post page. Here is the code:

        <?php
            $address_line_1      = $_POST['address_line_1'];
            $address_line_2      = $_POST['address_line_2'];
            $suburb              = $_POST['suburb'];
            $state               = $_POST['state'];
            $post_code           = $_POST['post_code'];
            $country             = $_POST['country'];
            $email               = $_POST['email'];
            $first_name          = $_POST['first_name'];
            $last_name           = $_POST['last_name'];
            $phone_number        = $_POST['phone_number'];
            $progress_identifier = '1';
    
                // PROCESS THE FORM
                if ('POST' == $_SERVER['REQUEST_METHOD'] && !empty($_POST['action']) && $_POST['action'] == "new_customer")
                {
    
                    $new_customer = array(
                        'post_title'  => wp_rand(100,999).'-'.wp_rand(),
                        'post_author' => $user_ID,
                        'post_status' => 'publish',
                        'post_type'   => 'customer'
                    );
    
                    $pid = wp_insert_post($new_customer);
    
                    add_post_meta($pid, 'address_line_1',      $address_line_1,      true);
                    add_post_meta($pid, 'address_line_2',      $address_line_2,      true);
                    add_post_meta($pid, 'suburb',              $suburb,              true);
                    add_post_meta($pid, 'state',               $state,               true);
                    add_post_meta($pid, 'post_code',           $post_code,           true);
                    add_post_meta($pid, 'country',             $country,             true);
                    add_post_meta($pid, 'email',               $email,               true);
                    add_post_meta($pid, 'first_name',          $first_name,          true);
                    add_post_meta($pid, 'last_name',           $last_name,           true);
                    add_post_meta($pid, 'phone_number',        $phone_number,        true);
                    add_post_meta($pid, 'address',             $address,             true);
                    add_post_meta($pid, 'progress_identifier', $progress_identifier, true);
    
                    $survey_post = array(
                        'post_title' => $pid . '-' . wp_rand(),
                        'post_author' => $user_ID,
                        'post_status' => 'publish',
                        'post_type' => 'survey'
                    );
    
                    $survey_id = wp_insert_post($survey_post);
    
                    global $wpdb;
                    $wpdb->insert(
                        $wpdb->p2p,
                        array(
                            'p2p_from' => $survey_id,
                            'p2p_to' => $pid,
                            'p2p_type' => 'survey_to_customer'
                        )
                    );
                    wp_redirect(home_url());
                    exit();
                }
        ?>
    

This code is placed after the HTML form.

I know wp_redirect() has to be called before the page starts outputting anything but I am unsure how to make that happen because I have tried putting it further up in the page but it doesn’t get me anywhere.

Feel free to abuse me for the terrible code and ambiguous question but if you could possibly point me in the right direction to accomplish what I am trying to achieve that would be great! I have tried to break things up into functions to get called via the ‘save_post’ hook but no luck with that either.

Thanks for reading!

Related posts

Leave a Reply

3 comments

  1. You should keep the form on new-customer.php and set the form action to POST to another script (something like new-customer-process.php) and then paste your PHP code into that script. Essentially the user won’t know any different as they will be redirected back to the home page.

    To give you a little more information, the form is what is sending the headers which is why you need to separate out the form and the processing script. The redirect needs to be BEFORE any HTML is sent.

  2. I would suggest you to have a look on wordpress ajax calls.

    you could add your ajax like that:

    add_action( 'wp_ajax_{nopriv_}new_customer', 'my_function_to_hendle_ajax' );

    where {nopriv_} is for not logged in users

    and your function would be like:

    function my_function_to_hendle_ajax() {
    $address_line_1      = $_POST['address_line_1'];
    $address_line_2      = $_POST['address_line_2'];
    $suburb              = $_POST['suburb'];
    $state               = $_POST['state'];
    //....
    // no need in if( 'post' .... )
    $new_customer = array(
      'post_title'  => wp_rand(100,999).'-'.wp_rand(),
      'post_author' => $user_ID,
      'post_status' => 'publish',
      'post_type'   => 'customer'
    );
    
    $pid = wp_insert_post($new_customer);
    
    add_post_meta($pid, 'address_line_1',      $address_line_1,      true);
    add_post_meta($pid, 'address_line_2',      $address_line_2,      true);
    // ....
    wp_redirect(home_url());
    exit();
    }
    

    and your html form should be:

    <form action="<?php echo admin_url( 'admin-ajax.php' ); ?>" method="POST">
    <input type="hidden" name="action" value="new_customer" />
    ...
    </form>
    

    morover you could return with wp_send_json_error function an error to hendle it in jquery ( but it thet case u need to do $.ajax or $.post ) on form submit.

    Check the docuumentation about WordPress Ajax
    Hope these hellps you.