3

There is a download in CSV feature in my current CodeIgniter project. When a user click the link, it will download a file in CSV. The downloaded CSV file's filename is incorrect once the provided filename in the code has a question mark character. To make things clear, below is the code.

public function download($role = NULL, $id = 0, $eid = 0) {
        $this->load->helper('download');
        $list = $this->respondent->get_respondents($eid);
        $questions = $this->respondent->get_all_questions($eid);

        $fp = fopen('php://output', 'w');
        $fields = array(
            'Timestamp',
            'First Name',
            'Middle Name',
            'Last Name',
            );

        $fields = array_merge($fields, $questions);

        fputcsv($fp, $fields);

    foreach ($list as $respondent) {
            $respondent_data = array(
            $respondent->since,
            $respondent->first_name,
            $respondent->middle_name,
            $respondent->last_name,
            );

            $query = $this->respondent->get_responses($respondent->rid);

            foreach($query as $response) {
            array_push($respondent_data, $response->answer, $response->duration);
        }

        fputcsv($fp, $respondent_data);
    }

    $data = file_get_contents('php://output');
    $name = $this->respondent->get_experiment($respondent->eid)->title.'.csv';

    // Build the headers to push out the file properly.
    header('Pragma: public');     // required
    header('Expires: 0');         // no cache
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Cache-Control: private',false);
    header('Content-Disposition: attachment; filename="'.basename($name).'"');
    header('Content-Transfer-Encoding: binary');
    header('Connection: close');
    exit();

    force_download($name, $data);
    fclose($fp);
    }

In the line header('Content-Disposition: attachment; filename="'.basename($name).'"');, once the $name has a question mark character, downloading the file in Firefox or Chrome browser can't interpret it correctly. Rather than a question mark character, the generated character is an underscore or hyphen, respectively. However, when Safari is used to download, the filename is just fine. Is the problem in the code or the browsers?

Earl Bunao
  • 205
  • 1
  • 5
  • 13
  • 1
    why not just rename the file? (or simply get rid of question mark if present?) – Kyslik Jul 23 '14 at 11:06
  • The filename inputed is dynamic. It is not hardcoded so I can't control it. In the project, the users input their filenames, and I don't want to limit the characters. – Earl Bunao Jul 23 '14 at 12:32

1 Answers1

0

What I meant in my comment is this.

str_replace('?', '_', $name); //when saving file on the server

This way there is no limit for users simply every question mark is replaced with _, I guess no big deal.

The part about FF and GCH I can not answer.

Kyslik
  • 8,217
  • 5
  • 54
  • 87
  • I think retaining the '?' character is important. Thanks though! – Earl Bunao Jul 23 '14 at 12:40
  • Dont tell me you speak portugese or spanish, I dont understand why is question mark so important in filenames I just never use it. Have fun finding out tho! (the FF and GCH problem). – Kyslik Jul 23 '14 at 12:42
  • 1
    by default firefox/chrome already replace question marks to "_" or "-", been trying to urlencode it but no success, always replaces it – G.Mendes Jul 23 '14 at 12:43
  • By that, you mean there's no other way? – Earl Bunao Jul 23 '14 at 12:45
  • @Larssen maybe there is a way, this question has a lot of relevant info http://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter-of-content-disposition-header-in-http – G.Mendes Jul 23 '14 at 12:46
  • I read the question/answers you posted, in a nutshell I would replace every special character with `_` or `-`, it is too complicated to serve all browsers + versions and keep track of changes. – Kyslik Jul 23 '14 at 13:02
  • @Kyslik sometimes the complicated is something that is needed, as per RFC standard we can encode majority of special characters using `filename*=UTF-8''file%20name.csv` and still keep `filename="file name.txt"` – G.Mendes Jul 23 '14 at 13:09
  • 1
    That is true, the problem is that until the OP tests all the possible solutions for all browsers and versions... this kind of functionality should be built in frameworks. And yet I would stick with filename policy as my comment above simple as that. Or maybe do an overkill and zip file and serve it that way (file.zip or something). – Kyslik Jul 23 '14 at 13:25
  • could even generate a file in server and redirect to it instead of output and urlencode will do the job – G.Mendes Jul 23 '14 at 13:56