Laravel Create and Download Zipped File - php

I'm having trouble on Creating and downloading Zip file
I see on this code on
http://laravelcode.com/post/how-to-create-zip-file-in-laravel-using-ziparchive
This is my controller
public function download(){
$FOLDERID = $_GET['id'];
$FILEPATH = *My Database Query*
$PATHTOFILE = public_path().'/images/';
$ZIPNAME = 'ZIPFILENAME.zip';
$ZIP = new ZipArchive;
if ($ZIP->open($PATHTOFILE.'/'.$ZIPNAME, ZipArchive::CREATE) === TRUE) {
$FILES = *My Database Query to get file*
foreach ($FILES as $FILE) {
$ZIP->addFile($FILE->File_Path , $FILE->File_Name);
}
$ZIP->close();
}
else{
return "NO FILES CREATED";
}
and I dont know what this one do
$HEADERS = array(
'Content-Type' => 'application/octet-stream',
);
And this one is for download the zip
if(file_exists($PATHTOFILE)){
return Response()->download($PATHTOFILE, $ZIPNAME, $HEADERS);
}else{
return "asd";
}
still didnt know what #HEADERS do
Im having trouble on Creating Zip File, The error always on the $ZIP->close();
It says
ZipArchive::close(): Read error: Bad file descriptor
can you guys help me which one i did wrong?
Thankyou in advance!

create route
Route::get('download-zip', 'ZipController#downloadZip');
step:2 Create Controller
add one new method for route. downloadZip() will generate new zip file and download as response, so let's add below:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use File;
use ZipArchive;
class ZipController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function downloadZip()
{
$zip = new ZipArchive;
$fileName = 'myNewFile.zip';
if ($zip->open(public_path($fileName), ZipArchive::CREATE) === TRUE)
{
$files = File::files(public_path('myFiles'));
foreach ($files as $key => $value) {
$relativeNameInZipFile = basename($value);
$zip->addFile($value, $relativeNameInZipFile);
}
$zip->close();
}
return response()->download(public_path($fileName));
}
}

Related

I am trying to download multiple image as a zip file but getting error using laravel 7

I am trying to download multiple images as a zip file but getting errors
Invalid argument supplied for foreach() please help me how i resolve that thanks.
Check the error: https://flareapp.io/share/47qG2A3m
Controller
public function dowloads($id)
{
$url = config('yourstitchart.file_url');
$zip = new ZipArchive;
$inboxFiles = Inbox::where('id', $id)->first()->file;
// $inboxFiles = "["phpCM0Yia.png","phptLC57a.png"]"
foreach ($inboxFiles as $file) {
$zip->add($url . $file); // update it by your path
}
$zip->close();
return response()
->download(
public_path('/temporary_files/' . "deals.zip"),
"deals.zip",
["Content-Type" => "application/zip"]
);
}
You are returning a string, you can't handle it like an array.
It's JSON, you can just use :
$inboxFiles = json_decode(Inbox::where('id', $id)->first()->file);
(the above code is not really robust, but you have the way)
I know this has already been answered, but do not use json_decode any more in Laravel...
Cast the field file as a JSON/array, so it will automatically be an array and when you save it in the database, it will be transformed to JSON, and when you want to read it back, it will be automatically transformed to array...
To do so, you have to edit Inbox model and add this property:
protected $casts = ['file' => 'array'];
And that's it, then you have to use the field as if it is already an array, so leaving your code as it is in your question, without any edit, it will work right away:
public function dowloads($id)
{
$url = config('yourstitchart.file_url');
$zip = new ZipArchive;
$inboxFiles = Inbox::where('id', $id)->first()->file;
// $inboxFiles = "["phpCM0Yia.png","phptLC57a.png"]"
foreach ($inboxFiles as $file) {
$zip->add($url . $file); // update it by your path
}
$zip->close();
return response()
->download(
public_path('/temporary_files/' . "deals.zip"),
"deals.zip",
["Content-Type" => "application/zip"]
);
}

Undefind Property Error while creating Zip file in Laravel using ZipArchive

I'm getting following Error while to creating Zip file in laravel using ZipArchive which will have all the PDF files
"Undefined property: ZipArchive::$close"
CONTROLLER:
public function downloadZip(Request $request)
{
#$job_id = $request->job_id;
#$filenames = DB::table('analytics_report')->where('job_id',$job_id)->get()->pluck('filename')->toArray();
#$zipname = $request->job_id;
$zip = new \ZipArchive;
$zip->open($zipname, \ZipArchive::CREATE);
foreach ($filenames as $filename){
$zip->addFile($filename);
}
$zip->close;
#$path = '../storage/app/public/bks/case_1/'.$zipname;
}
$zip->close();
You're missing the parantheses to make it a function call - currently you're trying to access a property $close on $zip, which doesn't exist.

Symfony2 API - Best way to import and save a CSV file

I need to create an API that receives via POST a .csv file that in a second moment has to be saved to the DB.
This is how I wrote the function:
/**
* #Route("/importCSV", name = "import_csv")
* #Method("POST")
**/
public function importCSVAction(Request $request) {
if ($this->getRequest()->files) {
$type = "csv";
$filename = date('Ymd').'-'.$type.'-filename';
$directory = $this->container->getParameter('kernel.root_dir') . '/../Documents';
$request = $this->get('request');
$data = $request->getContent();
try {
$fs = new Filesystem();
$fs->dumpFile($filename, $data);
move_uploaded_file($filename, $directory);
}
catch(IOException $e) {
return new Response ("File not saved!", 500, array('Content-Type' => 'application/json'));
}
return new Response($data);
}
else return new Response("Error!", 500, array('Content-Type' => 'application/json'));
}
1 One problem is that the file is saved under the web folder and not under Documents as I wanted.
Also, how can I check if the file I'm importing is a .csv file?
2 I searched on the web but I did not found many resources on this subject.
I just want to know if this is generally a correct way to save the .csv file.
Thanks!

Manipulate Symfony 2 UploadFile object in a unit test

I'm working on a Symfony2 project.
I created a simple TempFile class to manipulate an UploadFile. Here is my constructor :
public function __construct(UploadedFile $file, $destination, $suffix)
{
$this->file = $file;
$this->destination = $destination;
$this->fileId = sprintf('%s_%s', uniqid(), (string) $suffix);
}
And my move method
public function move()
{
$extension = $this->file->guessExtension();
if (!$extension) {
throw new \Exception(__METHOD__ . ' -> Unable to detect extension');
}
$this->tmpFileName = sprintf('%s.%s', $this->fileId, $extension);
$this->file->move($this->destination, $this->tmpFileName);
}
I try to create an UploadFile object in my test and here is what I did :
protected function setUp()
{
$this->file = tempnam(sys_get_temp_dir(), 'upload');
imagepng(imagecreatetruecolor(10, 10), $this->file);
$this->uploadedFile = new UploadedFile($this->file, "test.png");
}
public function testMoveWithAValidUploadedFile()
{
$tempFile = new TempFile($this->uploadedFile, '/tmp', 'tmp');
$tempFile->move();
// Future assertion
}
I have the following error :
Symfony\Component\HttpFoundation\File\Exception\FileException: The file "test.png" was not uploaded due to an unknown error
Any ideas ?
Thx,
Regards
From memory, Symfony2 checks if a file was uploaded as part of the request using is_uploaded_file(). This can be overridden using the test mode of the UploadedFile class. You can also define which PHP upload error code constitutes success.
copy(__DIR__ . '/Fixtures/test.pdf', '/tmp/test.pdf');
new UploadedFile(
'/tmp/test.pdf',
'original.pdf',
null,
null,
UPLOAD_ERR_OK,
true /* test */
)

Create .CRX (chrome extension / webapp ) file on demand using PHP

I need to create CRX file on the fly. It's for my CMS backend, so it will be just for authenticated users who can install CMS backend as webapp and offer some more privileges to the web app. The problem is, that the backend is used for many domains so creating CRX file for each of them is quite a work. So I figured that it would be easier to just create CRX file on demand which would be generated by PHP using its own domain and probably custom icon.
On the documentation page, they explain the CRX package format. There are many third party libraries that implemented that format. In the following page, you can learn the format and either download a Ruby / Bash script (you can find others too online), and if you want to implement your own packager, you can follow the format described there.
https://developer.chrome.com/extensions/crx
If you really don't want to follow the format, you can let your PHP script do one of the following:
Use Chrome binary chrome.exe --pack-extension=c:\myext --pack-extension-key=c:\myext.pem
Use the Ruby or Bash script from PHP (you can call system commands)
Hope that helps!
Also, for anyone still looking for a way to create a CTX in PHP, look at this question: Create Google Chrome Crx file with PHP
This works for me :D I just change from real path to null without that changes won't work on new chrome :D
/**
* Class CrxGenerator
*
* Create Chrome Extension CRX packages from
* folder & pem private key
*
* Based on CRX format documentation: http://developer.chrome.com/extensions/crx.html
*
* #author: Tomasz Banasiak
* #license: MIT
* #date: 2013-11-03
*/
class CrxGenerator {
const TEMP_ARCHIVE_EXT = '.zip';
private $sourceDir = null;
private $cacheDir = '';
private $privateKeyContents = null;
private $publicKeyContents = null;
private $privateKey = null;
private $publicKey = null;
/**
* #param $file Path to PEM key
* #throws Exception
*/
public function setPrivateKey($file) {
if (!file_exists($file)) {
throw new Exception('Private key file does not exist');
}
$this->privateKeyContents = file_get_contents($file);
$this->privateKey = $file;
}
/**
* #param $file Path to PUB key
* #throws Exception
*/
public function setPublicKey($file) {
if (!file_exists($file)) {
throw new Exception('Private key file does not exist');
}
$this->publicKeyContents = file_get_contents($file);
$this->publicKey = $file;
}
/**
* #param $cacheDir dir specified for caching temporary archives
* #throws Exception
*/
public function setCacheDir($cacheDir) {
if (!is_dir($cacheDir)) {
throw new Exception('Cache dir does not exist!');
}
$this->cacheDir = $cacheDir;
}
/**
* #param $sourceDir Extension source directory
*/
public function setSourceDir($sourceDir) {
$this->sourceDir = $sourceDir;
}
/**
* #param $outputFile path to output file
* #throws Exception
*/
public function generateCrx($outputFile) {
$basename = basename($outputFile);
// First step - create ZIP archive
$zipArchive = $this->cacheDir . DIRECTORY_SEPARATOR . $basename . self::TEMP_ARCHIVE_EXT;
$result = $this->createZipArchive(
$this->sourceDir,
$zipArchive
);
if (!$result) {
throw new Exception('ZIP creation failed');
}
$zipContents = file_get_contents($zipArchive);
// Second step - create file signature
$privateKey = openssl_pkey_get_private($this->privateKeyContents);
openssl_sign($zipContents, $signature, $privateKey, 'sha1');
openssl_free_key($privateKey);
// Create output file
$crx = fopen($outputFile, 'wb');
fwrite($crx, 'Cr24');
fwrite($crx, pack('V', 2));
fwrite($crx, pack('V', strlen($this->publicKeyContents)));
fwrite($crx, pack('V', strlen($signature)));
fwrite($crx, $this->publicKeyContents);
fwrite($crx, $signature);
fwrite($crx, $zipContents);
fclose($crx);
// Clear cache
unset($zipArchive);
}
/**
* #param $source - source dir
* #param $outputFile - output file
* #return bool - success?
*/
private function createZipArchive($source, $outputFile) {
if (!extension_loaded('zip') || !file_exists($source)) {
return false;
}
$zip = new ZipArchive();
if (!$zip->open($outputFile, ZIPARCHIVE::CREATE)) {
return false;
}
$source = str_replace('\\', '/', realpath($source));
if (is_dir($source) === true) {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file) {
$file = str_replace('\\', '/', $file);
// Exclude "." and ".." folders
if( in_array(substr($file, strrpos($file, '/') + 1), array('.', '..')) ) {
continue;
}
$file = $file;
if (is_dir($file) === true) {
$zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
}
else if (is_file($file) === true) {
$zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
}
}
}
else if (is_file($source) === true) {
$zip->file_get_contents($source);
echo $source;
}
return $zip->close();
}
}
Looks like I have found exactly what I was looking for. Chrome team has made this option to create CRX-less web apps, just by using simple manifest file.
Much easier to create own webapp and publish it on website for installation. And it also solves my problem when I have many websites with a lot of domains and I don't have to create custom CRX file for each domain. I just create small PHP script which creates manifest files on the fly for each domain.

Categories