yaxe
yaxe

Reputation: 365

delete a file after download in codeigniter

I want to remove my file from downloads directory after a user has downloaded it. But it is not deleted. I am using Codeigniter download_helper for downloading the file. Below is my code:

Controller

public function download($key,$id)
{
    $link=$this->article->download($key,$id);//get record from database via article model
    if(empty($link))
    {
        show_404(); 
    }
    force_download(DOWNLOADS_PATH.$link->file_name, NULL);//download file
    $this->article_lib->remove_downloaded($link->file_name);//user has downloaded so now delete this
}

Library

public function remove_downloaded($file_name)
{
   if(file_exists(DOWNLOADS_PATH.$file_name))
     {
      unlink(DOWNLOADS_PATH.$file_name);
     }
}

Upvotes: 4

Views: 2795

Answers (6)

CAllen
CAllen

Reputation: 836

Sorry I was not reading, but the problem with your code is that it is missing the closing )

    public function remove_downloaded($file_name)
    {
       if(file_exists($file_name)) // here is the problem
         {
          unlink($file_name);
         }
    }

Also the way the force download works is that anything after will not run. I would suggest using an ajax call after the controller.

UPDATE:

But as you have mentioned in your comment, you can delete the file before creating it as mentioned in this post Unlink after force download not working Codeigniter

Upvotes: 1

Kerkouch
Kerkouch

Reputation: 1456

You can find out why it wont be deleted in system/helpers/download_helper.php, there is an exit, so all code you have after force_download() will never be executed.

//File:  system/helpers/download_helper.php
// From line 135
// Generate the server headers
header('Content-Type: '.$mime);
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.$filesize);
header('Cache-Control: private, no-transform, no-store, must-revalidate');

// If we have raw data - just dump it
if ($data !== NULL)
{
    exit($data);
}

// Flush 1MB chunks of data
while ( ! feof($fp) && ($data = fread($fp, 1048576)) !== FALSE)
{
    echo $data;
}

fclose($fp);
exit;
}

Upvotes: 2

Adnan Rasheed
Adnan Rasheed

Reputation: 876

Make sure that you are deleting a file not the directory. if not sure then try this. it will delete the file and directory also

function rrmdir($dir) {
if (is_dir($dir)) {
    $files=scandir($dir);
    foreach ($files as $file)
     if ($file != "." && $file != "..") rrmdir("$dir/$file");
    rmdir($dir);
}
else if (file_exists($dir)) unlink($dir);
}

Upvotes: 0

Anubhav Gupta
Anubhav Gupta

Reputation: 102

just replace in controller function

this:

$this->article_lib->remove_downloaded($link->file_name);

with:

$this->article_lib->remove_downloaded(DOWNLOADS_PATH.$link->file_name);

or maybe with:

$this->article->remove_downloaded(DOWNLOADS_PATH.$link->file_name);

Upvotes: 0

Shashikumar Misal
Shashikumar Misal

Reputation: 509

While downloading you are passing the full path of the file you want to download but while deleting it, i mean while unlinking it you are passing only filename.

So please do try:

public function download($key,$id)
{
    $link=$this->article->download($key,$id);//get record from database via article model
    if(empty($link))
    {
        show_404(); 
    }
    force_download(DOWNLOADS_PATH.$link->file_name, NULL);//download file
    $this->article_lib->remove_downloaded(DOWNLOADS_PATH.$link->file_name); //Included full path
}

Hope this helps.

Upvotes: 0

Praneeth Nidarshan
Praneeth Nidarshan

Reputation: 1704

I used ignore_user_abort(true) function (docs) to solve this issue, and it worked for me.

Try below code,

public function download($key, $id)
{
    $link = $this->article->download($key, $id);//get record from database via article model
    if (empty($link)) {
        show_404();
    }

    force_download(DOWNLOADS_PATH . $link->file_name, NULL);//download file

    ignore_user_abort(true); // Set whether a client disconnect should abort script execution
    if (connection_aborted()) {
        $this->article_lib->remove_downloaded($link->file_name);//user has downloaded so now delete this
    }
}

Upvotes: 1

Related Questions