My system creates temporary files and send them to download. That part works very well. The problem is that I want to delete those files from file system after user download the file or just after in some point in the time, but seems to afterFilter() function which is the last controller method to run, executes even before the file is downloaded, so is not a posibility or I'm missing something.
I have these functions in a DowloaderController
public function download() {
$fileName = $this->Session->read('nameFile');
if (!is_file(STORAGEPATH . $fileName)) {
return;
}
$this->response->file( STORAGEPATH . $fileName );
$this->response->download($fileName);
return $this->response;
}
and
public function afterFilter() {
if ($this->Session->check('nameFile')) {
if (is_file(STORAGEPATH . $this->Session->read('nameFile'))) {
@unlink(STORAGEPATH . $this->Session->read('nameFile'));
}
$this->Session->delete('nameFile');
}
}
In a previous version of cake, i used to use something like:
$this->viewClass = 'Media';
$params = array(
'id' => $fileName,
'name' => $fileAlias,
'download' => true,
'extension' => $extension,
'path' => $path
);
$this->set($params);
and worked well, but now it doesnt
Is there any way to unlink the temporary file just after this was dowloaded?
or
what you have done to solve this problem?
Using cakephp 2.8
Because there is no way to know when the file download was finished and I do not have free access to the server following your comments, I ended up creating this function to delete all files except the last 5 sorted by date modified (just in case of multiple downloads by different users) when another download is called.
Using in the controller:
App::uses('Folder', 'Utility');
App::uses('File', 'Utility');
protected function _clearTemporaryFiles() {
$dir = new Folder(STORAGEPATH);
$files = $dir->find('.*', true);
if (count($files) > 5 ) {
foreach ($files as $key => $file) {
$file = new File($dir->pwd() . DS . $file);
$files[$key] = array();
$files[$key]['name'] = $file->name() . '.' . $file->ext();
$files[$key]['lastUpdate'] = $file->lastChange();
$file->close();
}
$orderedFiles = Set::sort($files, '{n}.lastUpdate', 'asc');
$orderedFiles = array_splice($orderedFiles, 0, count($orderedFiles) - 5);
foreach ($orderedFiles as $archivo) {
$archivo = new File($dir->pwd() . DS . $archivo['name']);
$archivo->delete();
$file->close();
}
}
}
It is not the most efficient solution, or would have wanted to use, but somehow solve my problem. The only concern is the possibility of downloads at the same time , but it would be a rare case that were more than 5 at a time.