2

I have built a Wordpress plugin that allows the user to export all pages, with their levels and urls, to a csv file.

The problem I have is that I keep getting error messages when trying to export the csv file:

Warning: Cannot modify header information - headers already sent

I have checked the config & functions files for spaces, as well as trying on different installations, but still can't get this to work!!!

Does anybody know how to fix this please?

Plugin code:

/*
Plugin Name: Your Site's Functionality Plugin
Description: All of the important functionality of your site belongs in this.
Version: 0.1
License: GPL
Author: Your Name
Author URI: yoururl
*/
add_action('admin_menu', 'my_page_export_menu');

function my_page_export_menu() {
   add_submenu_page('edit-pages.php', __("Wordpress Export Pages to CSV", "my-page-export"), __("Export Page List", "my_page_export_menu"), 'edit_pages', __FILE__,'my_page_export_menu_options');
}

function my_page_export_menu_options() {

echo '<div id="treecontrol" style="margin:20px 0;position:relative;">
    <form method="post" id="download_form" action=""><input type="submit" name="download_csv" class="button-primary" value="Export" /></form>
</div>';

if ( isset($_POST['download_csv']) ) {

    $text = wp_list_pages("echo=0&title_li=");
    $html = preg_replace('/class=".*?"/', '', $text);
    $html = strip_tags($html, '<ul>, <li>, <a>');
    $html = '<ul>'.$html.'</ul>';

    function get_depth(DOMElement $element)
    {
        $depth = -1;
        while (
            $element->parentNode->tagName === 'li' || 
            $element->parentNode->tagName === 'ul'
        ) {
            if ($element->parentNode->tagName === 'ul') {
                $depth++;
            }
            $element = $element->parentNode;
        }
        return $depth;
    }

    $dom = new DOMDocument;
    $dom->preserveWhiteSpace = false;
    $dom->loadHTML($html);
    echo '<pre>';
    $fp = fopen("php://output", "w");

    $file = 'test_export';
    $filename = $file."_".date("Y-m-d_H-i",time());
    header("Content-type: text/csv");
    header("Content-disposition: csv" . date("Y-m-d") . ".csv");
    header( "Content-disposition: filename=".$filename.".csv");
    header("Pragma: no-cache");
    header("Expires: 0");

    foreach ($dom->getElementsByTagName('a') as $li) {
     printf(
          '%s%s%s', 
          str_repeat(',', get_depth($li)),
          trim($li->childNodes->item(0)->nodeValue),
          ',,,,=HYPERLINK("'.$li->getAttribute( 'href' ).'")'.PHP_EOL
      );
    }           
    echo '</pre>';

} else {
    echo '<ul>';
    wp_list_pages("&title_li=");
    echo '</ul>';
}

}

4

Move your download/output code into admin_init hook. This hook is called before anything is output. It should work.

<?php 
/*
Plugin Name: Your Site's Functionality Plugin
Description: All of the important functionality of your site belongs in this.
Version: 0.1
License: GPL
Author: Your Name
Author URI: yoururl
*/
add_action('admin_menu', 'my_page_export_menu');

add_action('admin_init','wpse9876_download_csv');
function my_page_export_menu() {
   add_submenu_page('edit-pages.php', __("Wordpress Export Pages to CSV", "my-page-export"), __("Export Page List", "my_page_export_menu"), 'edit_pages', __FILE__,'my_page_export_menu_options');
}


function wpse9876_download_csv(){

    if ( isset($_POST['download_csv']) ) {

        $text = wp_list_pages("echo=0&title_li=");
        $html = preg_replace('/class=".*?"/', '', $text);
        $html = strip_tags($html, '<ul>, <li>, <a>');
        $html = '<ul>'.$html.'</ul>';

        function get_depth(DOMElement $element)
        {
            $depth = -1;
            while (
                    $element->parentNode->tagName === 'li' ||
                    $element->parentNode->tagName === 'ul'
            ) {
                if ($element->parentNode->tagName === 'ul') {
                    $depth++;
                }
                $element = $element->parentNode;
            }
            return $depth;
        }

        $dom = new DOMDocument;
        $dom->preserveWhiteSpace = false;
        $dom->loadHTML($html);
        echo '<pre>';
        $fp = fopen("php://output", "w");

        $file = 'test_export';
        $filename = $file."_".date("Y-m-d_H-i",time());
        header("Content-type: text/csv");
        header("Content-disposition: csv" . date("Y-m-d") . ".csv");
        header( "Content-disposition: filename=".$filename.".csv");
        header("Pragma: no-cache");
        header("Expires: 0");

        foreach ($dom->getElementsByTagName('a') as $li) {
            printf(
                    '%s%s%s',
                    str_repeat(',', get_depth($li)),
                    trim($li->childNodes->item(0)->nodeValue),
                    ',,,,=HYPERLINK("'.$li->getAttribute( 'href' ).'")'.PHP_EOL
            );
        }
        echo '</pre>';
        exit;
    }
}

function my_page_export_menu_options() {

echo '<div id="treecontrol" style="margin:20px 0;position:relative;">
    <form method="post" id="download_form" action=""><input type="submit" name="download_csv" class="button-primary" value="Export" /></form>
</div>';

echo '<ul>';
wp_list_pages("&title_li=");
echo '</ul>';

}
  • Brilliant thank you!!! I did have to follow @vancoder's advice and remove the pre tags to make it work :) – sta777 Apr 12 '13 at 8:33
2

You have

echo '<pre>';

right before you set your headers. That will break it.

Also, you didn't show the entire "Cannot modify..." error message. It should include directions to the exact line of code causing the issue.

  • Thank you muchly!!! I had to remove the pre tags from @Rajeev Vyas's answer in order for it to work :) – sta777 Apr 12 '13 at 8:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.