Download CSV file with PHP using Wordpress

Viewed 2723

I have developed a little plugin (for training) for Wordpress. The plugin allows to get the data from a form, save it into a csv file, and then the admin can download the file.

My problem is that I can't download this file. When I click on the download button, it opens a download.php page but nothing more happens.

I tried different solutions but nothing is working. Here is the code of the main file:

<?php
/*
    Plugin Name: Form to CSV
    Version: 1.0
    Author: Grégory Huyghe
*/


// 1. Shortcode
function ftc_shortcode() {
    readfile("form-to-csv.html", 1);
}

add_shortcode( 'form_csv', 'ftc_shortcode' );

// 1.1 CSS
function ftc_style() {
    wp_register_style('stylesheet', plugins_url('form-to-csv.css', __FILE__));
    wp_enqueue_style('stylesheet');
}

add_action('admin_init', 'ftc_style');


// 2. Onglet plugin dans panneau admin pour voir et télécharger les données collectées
function ftc_menu_item() {
    add_menu_page(
        __( 'Form to CSV', 'textdomain' ),
        'Form to CSV',
        'manage_options',
        'form-to-csv',
        'ftc_menu_plugin',
        'dashicons-portfolio',
        21
    );
}
add_action('admin_menu', 'ftc_menu_item');


// 3. Ecrire les données dans un fichier

// 3.1 Variables
$error = '';
$fname = sanitize_text_field($_POST['prenom']);
$lname = sanitize_text_field($_POST['nom']);
$email = sanitize_email($_POST['email']);
$checkbox = implode(" / ", (array)$_POST['films']);

// 3.2 Clean_text
function clean_text($clean) {
    $trimmed = trim($clean);
    $stripped = stripslashes($clean);
    $special = htmlspecialchars($clean);
    return $clean;
}

// 3.3 Submission form
if(isset($_POST['submit'])) {
    $success = true;

    if(empty($_POST['prenom']) OR empty($_POST['nom']) OR empty($_POST['email'])) {
        $error = '<p>Veuillez réessayer</p>';
    } else {
        $fname = clean_text($_POST['prenom']);
        $lname = clean_text($_POST['nom']);
        $email = clean_text($_POST['email']);
        }

    if($error == '' && $success = true) {

        // Ecriture dans fichier csv
        $file_open = fopen('C:\Users\huygh\Desktop\form-to-csv.csv', 'a');
        $index = count(file('C:\Users\huygh\Desktop\form-to-csv.csv')); 
        if ($index == 0) {
            $index = $index +1;
        } else if ($index > 0) {
            $index = $index +1;
        }

        $form_data = array(
        'id' => $index,
        'prenom' => $fname,
        'nom' => $lname,
        'email' => $email,
        'films' => $checkbox
    );
        fputcsv($file_open, $form_data);
        header( 'Location: index.php' );
        exit();
    }           
}


// 4. Récupérer ses infos dans un custom post accessible depuis le panneau admin. Pas d'envoi de mail.

// 4.1 Récupérer et  Afficher les données dans l'onglet du plugin

function ftc_menu_plugin() {

//    if (isset($_GET['action']) && $_GET['action'] == 'download') {
//        header('Location: C:\Users\huygh\Desktop\form-to-csv.csv');
//        header('Content-Disposition: attachment; filename="form-to-csv.csv"');
//        header("Content-Type: application/force-download");
//        header("Content-Transfer-Encoding: Binary");
//        header("Pragma: no-cache");
//        header("Expires: 0");
//
//        readfile('form-to-csv.csv');
//        
//        echo "toto";
//    }

    $counter = 0;

    echo "<html><body><table>\n\n";

    // Titres du tableau
    echo "<thead>";
    echo "<tr class=\"titles\">";
    echo "<th>ID</th>";
    echo "<th>Prénom</th>";
    echo "<th>Nom</th>";
    echo "<th>Email</th>";
    echo "<th>Sélection</th>";
    echo "</tr>\n";
    echo "</thead>";

    if (($file_read = fopen('C:\Users\huygh\Desktop\form-to-csv.csv', 'r')) !== FALSE) {
        while (($data = fgetcsv($file_read)) !== FALSE && $counter < 20) {
            echo "<tr>";
            $counter++;
            foreach ($data as $cell) {
                    echo "<td>" . $cell . "</td>";
            }
            echo "</tr>\n";
        }
    }
    fclose($file_read);
    echo "\n</table></body></html>";

    // 4.2 Télécharger ce fichier .csv depuis l'onglet du plugin

    ?>
        <a href="download.php" target="_blank">
            <button class="button__csv">Télécharger fichier CSV</button>
        </a>

        <a href="delete.php" target="blank">
            <button class="button__csv button__csv--delete">Supprimer données</button> 
        </a>
<?php

And the code of the download.php:

<?php
header('Content-Disposition: attachment; filename="form-to-csv.csv"');
header('Content-Type: text/csv');
readfile('C:\\Users\\huygh\\Desktop\\form-to-csv.csv');

As you can see in the main file code, I also tried a solution without using a download.php page, writing the a tag as follow:

<a href="?action=download" target="blank">

But nothing is working. Does the problem come from the headers? Or from Wordpress, something specific to write?

Here is the screenshot of the response header in the developer tool: enter image description here

3 Answers

As mentioned by Jamie_D, using Location will forward the user to the specified address (like in your 3.3 Submission form code block).

Remove the line from your code block and you should get the desired download page:

<?php
header('Content-Disposition: attachment; filename="form-to-csv.csv"');
header('Content-Type: text/csv');
// take care to escape the backslashes properly:
readfile('C:\\Users\huygh\\Desktop\\form-to-csv.csv'); 

Additional comments regarding your code:

  1. Missing underscore in anchor; it should be: <a href="download.php" target="_blank">Link</a>

  2. Get rid of the closing ?php> tag: I have seen cases where control / invisible characters after the closing tag caused download troubles as they are then transmitted as part of the file's content.

Solution

In the question asker's case the problem was not due to incorrect headers sent to the client but the path pointing to the download.php was incorrect.

Here is the solution, a simple mistake about the location of download.php which has to be in the wp-admin folder.

To keep the download.php file into the plugin folder, I wrote a relative URL for the a tag:

<a href="/Plugin/wp-content/plugins/form-to-csv/download.php"

Answer of SaschaM78: As you can see the "download.php" can not be found, a 404 means "Page not found". Make sure that the file really is in "plugins/wp-admin". – SaschaM78 54 mins ago

You can use the download property of HTML5 to down load file directly,

<a href="C:\\Users\\huygh\\Desktop\\form-to-csv.csv" download="form-to-csv.csv">download form-to-csv.csv</a>
Related