wp_redirect “headers already sent” after front-end submission form

I’m trying to practice with setting up a front-end post submission form. And I’m getting this error:

Warning: Cannot modify header information - headers already sent by (output started at /home/sadlight/public_html/members/wp-content/themes/default-child/announcement-submit.php:1) in /home/sadlight/public_html/members/wp-includes/pluggable.php on line 876

announcement-submit.php is my template below.

Read More

I’ve tried this solution, but no go.

Also, when I use wp_redirect in my code below, it inserts TWO posts instead of one. When I remove it, it only enters one. Any help would be great!

Just for extra info: I’m using buddypress with the default buddypress theme.

<?php

/*
 * Template Name: Announcement Submit
  */

$postTitleError = '';
if ( isset( $_POST['submitted'] ) ) {
    if ( trim( $_POST['postTitle'] ) === '' ) {
        $postTitleError = 'Please enter a title.';
        $hasError = true;
    }
}


get_header(); ?>

    <div id="content">
        <div class="padder">

            <form action="" id="primaryPostForm" method="POST">
                <fieldset>
                    <label for="postTitle"><?php _e('Post Title:', 'framework') ?></label>
                    <input type="text" name="postTitle" id="postTitle" class="required" value="<?php if ( isset( $_POST['postTitle'] ) ) echo esc_attr( stripslashes( $_POST['postTitle'] ) ); ?>" />
                </fieldset>
                <fieldset>
                    <?php wp_editor( 'Testing some content', 'postcontent'); ?>
                </fieldset>
                <fieldset>
                    <?php wp_nonce_field( 'post_nonce', 'post_nonce_field' ); ?>
                    <input type="hidden" name="submitted" id="submitted" value="true" />
                    <button type="submit"><?php _e('Add Post', 'framework') ?></button>
                </fieldset>
            </form>

            <?php if ( $postTitleError != '' ) { ?>
                <span class="error"><?php echo $postTitleError; ?></span>
                <div class="clearfix"></div>
            <?php } ?>

            <?php
                if ( isset( $_POST['submitted'] ) && isset( $_POST['post_nonce_field'] ) && wp_verify_nonce( $_POST['post_nonce_field'], 'post_nonce' ) ) {
                    if ( trim( $_POST['postTitle'] ) === '' ) {
                        $postTitleError = 'Please enter a title.';
                        $hasError = true;
                    }
                    $post_information = array(
                        'post_title' => wp_strip_all_tags( $_POST['postTitle'] ),
                        'post_content' => wp_kses_post( $_POST['postcontent'] ),
                        'post_type' => 'post',
                        'post_status' => 'pending'                                      
                    );
                    wp_insert_post( $post_information );                    
                }

                $post_id = wp_insert_post( $post_information );

                if ( $post_id ) {
                    wp_redirect( home_url() );
                    exit;                   
                }
            ?>

        </div><!-- .padder -->
    </div><!-- #content -->

    <?php get_sidebar(); ?>

<?php get_footer(); ?>

Related posts

Leave a Reply

3 comments

  1. As Otto pointed out, you’re sending data to the browser before calling wp_redirect().

    • get_header() will output the page’s HTML <head>
    • You’re printing the entire form to the page before processing it.

    To fix the “headers already sent” issue, you need to move all of your form processing from the bottom of the page to the top of the page. If you need to call wp_redirect() you must make that call before you print anything – HTML or anything else – to the page.

    As for the duplicate post entry, you have wp_insert_post() twice in your code:

    if ( isset( $_POST['submitted'] ) && isset( $_POST['post_nonce_field'] ) && wp_verify_nonce( $_POST['post_nonce_field'], 'post_nonce' ) ) {
        if ( trim( $_POST['postTitle'] ) === '' ) {
            $postTitleError = 'Please enter a title.';
            $hasError = true;
        }
        $post_information = array(
            'post_title' => wp_strip_all_tags( $_POST['postTitle'] ),
            'post_content' => wp_kses_post( $_POST['postcontent'] ),
            'post_type' => 'post',
            'post_status' => 'pending'                                      
        );
        wp_insert_post( $post_information );                    
    }
    
    $post_id = wp_insert_post( $post_information );
    

    So you’re attempting to insert a post on every page load but if nothing has been submitted the $post_information variable won’t be set and nothing gets inserted. However, when you submit the form you’re creating a new post both inside the bool check and outside the bool check.

  2. headers already sent by (output started at
    /home/sadlight/public_html/members/wp-content/themes/default-child/announcement-submit.php:1)

    The error message tells you exactly what you need to know.

    The “announcement-submit.php” is where the problem is.

    The “1” is the line number of the problem.

    So, you actually have something before your initial <?php line that is causing output. A blank line, perhaps. Or the UTF-8 BOM, perhaps.

    Load the file in a plain text editor. Nothing fancy. Notepad, perhaps. Or VIM. Make sure nothing exists before that starting PHP tag. Save the file. Or, in your editor of choice, check the save options and make sure it’s not set to save a BOM (Byte-Order-Marker) at the beginning of the file.

  3. This can have multiple causes. The headers can only be send when there is no output before it. And with output I mean any output. So no whitespaces before the PHP opening tags, no echos no BOM characters.

    Basically that error message tells you exactly where the output is started so that is where one of above things is happening.

    For a complete list of things you should check and also how to prevent this error please see this fine Stack Overflow post.