Error "headers already sent" en wp_redirect después de formulario de envío front-end

14 ene 2013, 23:24:25
Vistas: 16.6K
Votos: 2

Estoy practicando con la creación de un formulario de envío de publicaciones desde el front-end. Y me aparece este 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 es mi plantilla que muestro abajo.

He intentado esta solución, pero no funciona.

Además, cuando uso wp_redirect en mi código, inserta DOS publicaciones en lugar de una. Cuando lo quito, solo inserta una. ¡Cualquier ayuda sería genial!

Para más información: Estoy usando Buddypress con el tema predeterminado de Buddypress.

<?php

/*
 * Plantilla Nombre: Envío de Anuncio
 */

$postTitleError = '';
if ( isset( $_POST['submitted'] ) ) {
    if ( trim( $_POST['postTitle'] ) === '' ) {
        $postTitleError = 'Por favor ingresa un título.';
        $hasError = true;
    }
}


get_header(); ?>

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

            <form action="" id="primaryPostForm" method="POST">
                <fieldset>
                    <label for="postTitle"><?php _e('Título de la publicación:', '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( 'Probando algo de contenido', '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('Añadir publicación', '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 = 'Por favor ingresa un título.';
                        $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'                                      
                    );
                    $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
Comentarios

Revisa esta respuesta http://wordpress.stackexchange.com/a/76993/10413

Anagio Anagio
14 ene 2013 23:33:11

Gracias por tu respuesta. Eso solucionó el error, pero no añadió la publicación. :(

Josh Josh
15 ene 2013 00:11:21
Todas las respuestas a la pregunta 3
3

Como señaló Otto, estás enviando datos al navegador antes de llamar a wp_redirect().

  • get_header() generará el HTML <head> de la página
  • Estás imprimiendo todo el formulario en la página antes de procesarlo.

Para solucionar el problema de "headers already sent", necesitas mover todo el procesamiento de tu formulario desde la parte inferior de la página a la parte superior. Si necesitas llamar a wp_redirect(), debes hacer esa llamada antes de imprimir cualquier cosa - HTML o cualquier otro contenido - en la página.

En cuanto a la entrada duplicada del post, tienes wp_insert_post() dos veces en tu código:

if ( isset( $_POST['submitted'] ) && isset( $_POST['post_nonce_field'] ) && wp_verify_nonce( $_POST['post_nonce_field'], 'post_nonce' ) ) {
    if ( trim( $_POST['postTitle'] ) === '' ) {
        $postTitleError = 'Por favor ingresa un título.';
        $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 );

Así que estás intentando insertar un post en cada carga de página, pero si no se ha enviado nada, la variable $post_information no estará definida y no se insertará nada. Sin embargo, cuando envías el formulario, estás creando un nuevo post tanto dentro de la verificación booleana como fuera de la verificación booleana.

15 ene 2013 00:33:29
Comentarios

Además, sería mejor mover todo el procesamiento del formulario a tu archivo de funciones y engancharlo a alguna acción como template_redirect, donde puedes estar seguro de que aún no se ha enviado nada al navegador.

Mateusz Hajdziony Mateusz Hajdziony
15 ene 2013 00:40:20

¡Gracias! Esto es algo que prefiero hacer para mantener las cosas separadas. Sin embargo, he estado buscando durante la última hora tratando de entender mejor cómo usar template_redirect o qué hace realmente. Estoy desconcertado.

Josh Josh
15 ene 2013 01:59:37

Bueno, lo separé. ¡Y funcionó! Haré que los nombres $_POST sean únicos para que no entren en conflicto con nada más.

Josh Josh
15 ene 2013 02:10:53
4

encabezados ya enviados por (salida iniciada en /home/sadlight/public_html/members/wp-content/themes/default-child/announcement-submit.php:1)

El mensaje de error te indica exactamente lo que necesitas saber.

El archivo "announcement-submit.php" es donde está el problema.

El "1" es el número de línea del problema.

Por lo tanto, realmente tienes algo antes de tu línea inicial <?php que está causando la salida. Tal vez una línea en blanco. O quizás el BOM UTF-8.

Carga el archivo en un editor de texto plano. Nada sofisticado. Bloc de Notas, tal vez. O VIM. Asegúrate de que no exista nada antes de esa etiqueta PHP inicial. Guarda el archivo. O, en tu editor preferido, revisa las opciones de guardado y asegúrate de que no esté configurado para guardar un BOM (Byte-Order-Marker) al principio del archivo.

14 ene 2013 23:29:34
Comentarios

es más que solo espacio antes de la apertura <?php, está todo el get_header y todo el marcado de salida antes de la línea wp_redirect a mitad de la plantilla.

Milo Milo
14 ene 2013 23:32:15

Gracias por tu respuesta. Intenté lo que sugeriste usando solo el bloc de notas. Incluso me aseguré de que Notepad++ (mi editor de código) guardara en UTF-8 sin BOM. Volví a subir el archivo... y ahora tengo este 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 .... La línea 2 de header.php es <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>

Josh Josh
14 ene 2013 23:59:00

@Milo Eliminé todo el espacio en blanco que pude y que tenía sentido... entre líneas y después de las líneas. El mismo error.

Josh Josh
15 ene 2013 00:00:34

No debe haber absolutamente nada antes de esa línea inicial de php. Ni espacio, ni texto, ni código.

Otto Otto
15 ene 2013 06:36:12
0

Esto puede tener múltiples causas. Las cabeceras solo pueden enviarse cuando no hay ninguna salida antes. Y con salida me refiero a cualquier salida. Así que no debe haber espacios en blanco antes de las etiquetas de apertura de PHP, ni echo, ni caracteres BOM.

Básicamente, ese mensaje de error te indica exactamente dónde comenzó la salida, por lo que ahí es donde está ocurriendo una de las cosas mencionadas anteriormente.

Para obtener una lista completa de aspectos que deberías verificar y también cómo prevenir este error, por favor revisa esta excelente publicación en Stack Overflow.

15 ene 2013 00:15:27