Laravel Zipper delete files after zipping - php

I am using a Zipper package for making zip files out of API fetched PDF's. Zipping works fine but I would like to delete PDF files that were zipped.
$pdf_summary_filename = public_path() . $path . uniqid() . '_summary.pdf';
PDF::loadView('pdf.summary', $pdf_data)->save($pdf_summary_filename);
$zipper->make($zip_filename)->add($pdf_summary_filename);
File::cleanDirectory(public_path() . '/user_downloads');
I am using this code, however, I think that cleanDirectory() gets called before the zipping finishes, and I see no zip generated. If I comment out the last line, I get both the zip file as well as PDF's in /user_downloads.
How can I wait for the zipper to finish zipping?

UPDATE: You can try below code:
$flgFile = $zipper->make($zip_filename)->add($pdf_summary_filename);
if($flgFile){
File::cleanDirectory(public_path() . '/user_downloads');
}
This may help you better!

Related

How to delete laravel delete file after extract?

I am using Zipper to extract uploaded zip file and delete the file after extract.
So I upload and extract like this:
$f = $request['file']->move(public_path($directory), $fullFileName);
\Zipper::make($f)->extractTo(public_path($directory) . $fileName);
and it works great. I've tried to delete the file using these ways.
1 - Storage::disk('products')->delete($fullFileName);
2 - File::delete(public_path($directory) . $fullFileName);
3 - $del = unlink(public_path($directory) . $fullFileName);
but in all actions get resource temporarily unavailable error.
I found this error is because of the zipper (simple files and directories works).
so my question is, How can I delete upload zip file after extract, using a zipper?
Any idea would be great.
thanks in advance.
You need to call $zipper->close(); after you extract it, so if you do something like this it should work:
$zipper = new \Chumper\Zipper\Zipper;
$zipper->make($f)->extractTo(public_path($directory) . $fileName);
$zipper->close();
unlink(public_path($directory) . $fullFileName);
If you do not close the zipper it will not write the result to the disk and keep the original file locked. See the documentation.
$zip = new Zipper;
$zip->make($pathZipFile)->extractTo($destinationPath);
$zip->close(); // important
unlink($pathZipFile); // delete Zip file after

DS_Store file is created on ZipArchive::extractTo

I'm creating a PHP script, which supposed to extract a zip archive stored on the php file directory to a folder.
Everything works well, but when I check te result, I find 2 folders under the directory: a folder with the name of the zip archive, and another folder named __MACOSX. I don't know how this folder came there, especially as I'm using Windows 7. Second, in each folder there is a file called .DS_Store.
Now, I don't know how these things got there. This is my code:
$zip = new ZipArchive;
if ($zip->open('File.zip')) {
$path = getcwd() . "/details/" . trim($id) . "/";
$path = str_replace("\\","/",$path);
echo $path;
echo $zip->extractTo($path);
$zip->close();
echo 'ok';
} else {
echo 'failed';
}
This is the only code that extracts the zip file, or touching it, and as you can see, there is nothing like __MACOSX or .DS_Store.
Can you please help me?
File.zip originated on a OSX system. __MACOSX and .DS_Store have 0 usage or bearing on any other OS. Delete / Ignore them and keep trucking.
As an aside, you may want to add the stated file system objects to your project .gitignore.
https://superuser.com/questions/104500/what-is-macosx-folder
https://en.wikipedia.org/wiki/.DS_Store

PHP can't access newly created zip file

Im using Laravel 5.2 and Zipper to create ZIP archive in a fly and download it by user. I think this problem is generall not strictly related to Laravel or Zipper. Steps:
User click link download_all.
First php script create archive.
Next the same script push created file to force user download.
Everything sounds normal but I have strange behaviour that after zip archive is created (point 2) php/server cant see this newly created file.
Both filesize and file_exists on $filePath return false but file exist. I cant read file why?
When I redirect user to $filePath (instead of reading it and pushing to download) everything is okay and user get file. But why I cant access newly creatd file during "script lifetime"? $paths are correct.
Tested on Windows 7 and Unix.
Any idea?
code:
public function downloadAll($id)
{
$sourceFilesDir = 'upload/source/' . $id;
$zipPath = 'upload/source-zip/' . date('Y-m-d-H-i-s') . '.zip';
Zipper::make($zipPath)->add($sourceFilesDir);
$fullPath = public_path($zipPath);
// works
// return response()->redirectTo($zipPath);
$headers = [
'Content-Type: application/zip',
'Content-Transfer-Encoding: Binary',
'Content-Length: ' . filesize($fullPath),
];
// dont works, cant see file
return response()->download($fullPath, basename($zipPath), $headers);
}
Soved by #Holger.
Zipper should be closed to save file.
Proper code:
Zipper::make($zipPath)->add($sourceFilesDir)->close();
->close()
Unfortunately in Zipper docs this is not clearly mentioned.

Multiple process read same file php

I have a little problem inside my application.
I have many process launched automatically, from the server with crontab, written in php to read file inside a folder.
Sometimes different process read the same file and create a problem inside the application.
Is there a way to manage this problem?
Actually I read all files inside a folder, read each of them and delete immediately, but sometimes another process read the same file before I delete It.
This is my script written with cakephp3 (so some classes like File is only for cakephp3 but isn't the point of the question) to read and delete:
$xml_files = glob(TMP . 'xml/*.xml');
foreach($xml_files as $fileXml)
{
//read the file and put into a string or array or object
$explStr = explode('/', $fileXml);
$filename = $explStr[count($explStr) - 1];
$path = TMP . '/xml/' . $filename;
$file = new File($path, false);
if($file->exists()){
$string = $file->read();
$file->close();
$file->delete();
}
}
Use flock() to obtain (or attempt to obtain) a file lock and act accordingly.
It's called a race condition, and when working with files you could lock the file when process A uses it, it locks it, then other processes would check if it's locked and if it is then do nothing. Then unlock the file when process A has finished with it.

Zip PDF-Files download not working

I'm building an interface that allows collecting PDF-Files from a server-path to download them zipped at once which works fine most of the time. Now, some PDF-Files are not working, means if the zip contains one of the non-working files the whole download will not performed.
Now i tried many files with different sizes. I can tell most of the files larger than 10MB are not working, but one file (15mb) is working, so it can't be the file-size causing this error - right?
What happens is there's just no download at all. Additionally tried reading the results of "$zip->addFile" and "$zip->close" but it's all true, even if the download will not be performed. ANY ideas which may cause this bug or at least some hints on how to find this out?
The (x)debug inspection of the variables during process does not differ between the time it worked and the time its not working. Only differences are filesizes and -paths.
Here's the Code i'm using to build the ZIP:
public function downloadFiles() {
$myFiles = $this->Session->read('Files.MyFiles');
if(count($myFiles)) {
// build zip
$zipname = 'amaz_photos_' . time() . '.zip';
$zip = new ZipArchive();
$zip->open($zipname, ZipArchive::CREATE);
foreach($myFiles as $file) {
if($file['type'] == 'directory') {
$dirName = str_replace('/', '', substr($file['path'], strrpos($file['path'], '/'), (strlen($file['path']) - strrpos($file['path'], '/'))));
$zip->addEmptyDir($dirName);
$this->addFolderToZip($file['path'] . '/', $zip, $dirName . '/');
} else {
$zip->addFile($file['path'], str_replace('/', '', substr($file['path'], strrpos($file['path'], '/'), (strlen($file['path']) - strrpos($file['path'], '/')))));
}
}
$zip->close();
// get(send) zip
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename=' . $zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
ignore_user_abort(true);
unlink($zipname);
}
// clear "myFiles"
//$this->Session->write('Files.MyFiles', array());
$this->redirect(array(
'controller' => 'pages',
'action' => 'display'
));
}
After all i tried opening the affected files with several PDF-Readers including Adobe's original to determine if its broken, but ̶i̶̶t̶̶s̶ it seems not.
This will occur in openable zip-files but the download does not start anyways. I found out that in that special cases where the download does not start, there is no response-header ("application/zip") being set on the network-frame compared to the times it worked.
What I found out else:
Lets say I have a folder with 20 files in it, that's not downloading. I tried selecting file 1-10: downloading, then I tried downloading file 11-20: downloading, then I tried to download file 1-20: not downloading, then I tried two times mixing the patterns, first the even files 2,4,6,8.. (1-20), after that the odd files 1,3,5,7,.. (1-20): each not downloading.
This states out the error does not belong to a specific file.
Any suggestions how to determine the trigger for this error?
Update:
I was able to download the generated zip-file doing these steps:
Trigger 'create & download zip-file'
It creates a zip-file but not download it
Type the generated zip-files filename in the code to download it on the next procedure (e. g. "$zipname = "generatedOnStep1.zip").
Trigger 'create & download zip-file' again
It does not download the (recently) generated file, but the file i generated in step 1. So it seems that: Generating Zip-Files is working AND downloading that same zip-File is working, but not at once and only in some unknown combinations.
...
Update 2:
Since I was not able to determine the issue nor fix it, I ended up redesigning the whole process, to redirect to the generated zip-file instead of "readfile" it. Some features had to be sourced out but anyways it works this way.
Try this... Remove readfile($zipname); and replace it with these:
/* make sure no other functions
holding this file */
$filehandle = fopen($zipname, "r");
while (!feof($filehandle)) {
/* lets read the file by pieces and
send it to user's browser */
echo fread($filehandle, 8192);
}
fclose($filehandle);
Hope this helps.

Categories