2

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.

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(); ?>
2

3 Answers 3

8

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.

3
  • In addition, it would be better to move the entire form processing into your functions file and hook into some action like template_redirect, where you are sure nothing has been sent to the browser yet. Commented Jan 14, 2013 at 22:40
  • Thanks! This is something that I'd rather do to keep things separate. However, I've been searching for the past hour trying to get a better understanding of how to use template_redirect or what it actually does. I'm dumbfounded.
    – Josh
    Commented Jan 14, 2013 at 23:59
  • Well, I separated it. And it worked! I'll make the $_POST names unique so they won't clash with anything else.
    – Josh
    Commented Jan 15, 2013 at 0:10
3

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.

4
  • 2
    it's more than just space before the opening <?php, there's the whole get_header and all the markup output before the wp_redirect line half-way down the template.
    – Milo
    Commented Jan 14, 2013 at 21:32
  • Thanks for your response. I tried what you suggested with just using notepad. I even ensured Notepad++ (my code editor) was saving UTF-8 without BOM. Re-uploaded the file... and now I have this error: Warning: Cannot modify header information - headers already sent by (output started at /home/sadlight/public_html/members/wp-content/plugins/buddypress/bp-themes/bp-default/header.php:2) in /home/sadlight/public_html/members/wp-includes/pluggable.php on line 876 .... Line 2 of header.php is <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
    – Josh
    Commented Jan 14, 2013 at 21:59
  • @Milo I removed all white space that I could that made sense... inbetween lines and after lines. Same error.
    – Josh
    Commented Jan 14, 2013 at 22:00
  • There should be absolutely nothing at all before that initial php line. No space, no text, no code.
    – Otto
    Commented Jan 15, 2013 at 4:36
0

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.

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.