Force download from amazon s3 private file in laravel - php

Hello i have some problem with doing a force download.
Here is my code :
public function download(Request $request, $id) {
$document = Document::find($id);
$s3 = Storage::disk('s3');
$name = substr($document->link, strrpos($document->link, '/') + 1);
$file = $s3->get($name);
$headers = [
'Content-Type' => 'application/pdf',
'Content-Description' => 'File Transfer',
'Content-Disposition' => "attachment; filename={$name}",
'filename'=> $name
];
return response()->download($file);
}
i don't get it how to access the good file
response :
is_file() expects parameter 1 to be a valid path, string given
Any ideas ?

Your headers are not actually attached to the response. If you refer to: https://laravel.com/docs/5.5/responses#attaching-headers-to-responses you will see that the proper way to send headers in Laravel is:
return response($file)
->header('Content-Type', 'application/pdf')
->header('Content-Description', 'File Transfer')
->header('Content-Disposition', "attachment; filename={$name}")
->header('Filename', $name)
The $file is alse sent as a paramenter in reponse() instead of as download().

Related

Zend Framework CSV download

I am currently working on a CSV generator in Zend Framwork. At this point I am able to create a valid CSV file on the server side and now I want to download that file. I am currently using the following code:
$reader = new \PHPExcel_Reader_CSV();
$reader->setReadDataOnly(true);
$excel = $reader->load($file); //$file = Path of the csv file in the local storage
$writer = \PHPExcel_IOFactory::createWriter($excel, 'CSV');
$path = 'public/download';
$fileName = 'test.csv';
$writer->save($path . '/' . $fileName);
$response = new ResponseStream();
$response->setStream(fopen($path . '/' . $fileName, 'r'));
$headers = new Headers();
$headers->addHeaders([
'Content-Type' => [
'application/force-download',
'application/octet-stream',
'application/download'
],
'Content-Length' => filesize($path . '/' . $fileName),
'Content-Disposition' => 'attachment;filename=' . $fileName,
'Cache-Control' => 'must-revalidate',
'Pragma' => 'no-cache',
'Expires' => 'Thu, 1 Jan 1970 00:00:00 GMT'
]);
$response->setHeaders($headers);
$cookie = new SetCookie('downloadComplete', 'true', time() + 60 * 60, '/');
$response->getHeaders()->addHeader($cookie);
$response->setContent($writer);
return $response;
The problem is now that I only get a Zend error popup:
statusCode 200 thrownError SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data at line 1 column 21 of the JSON data
And the content of my CSV as response text.
Do you have an idea?
Thanks in advance.
After a lot of investigation I found out that the download only fails if we send a Post request to the download action via zend (I assume it overrides the self-setted headers). So I sendt the request via a java script redirect ($viewModel->addScriptBlock('window.location = "Your URL";');) and it worked.

Response::download() doesn't work in Laravel 4

I'm trying to use this: Response::download() to make a download of a file, I'm using Laravel 4, here my code:
public function download_file($file)
{
$file = 'myfile.pdf';
//-- public/docs/myfile.pdf
$path = public_path(). '/docs/' . $file;
$headers = array(
'Content-Type' => 'application/pdf',
);
return Response::download($path, $file, $headers);
}
The error I got:
The file "C:\Users\myuser\Workbench\Web\sites\mysite\public/docs/myfile.pdf" does not exist
What did I went wrong?
Thanks!

How can I download file from s3 in php?

How can I download file from s3 in php. The following code not working for me...
Here is my code
upload file should work correct
try {
$s3->putObject([
'Bucket' => $config['s3']['bucket'],//'eliuserfiles',
'Key' => "uploads/{$name}",
'Body' => fopen($tmp_name, 'r+'),
//'SourceFile' => $pathToFile,
'ACL' => 'public-read',
]);
download gives me error
$objInfo = $s3->get_object_headers($config['s3']['bucket'], "uploads/{$name}");
$obj = $s3->get_object($config['s3']['bucket'], "uploads/{$name}");
header('Content-type: ' . $objInfo->header['_info']['content_type']);
echo $obj->body;
error
PHP Catchable fatal error: Argument 2 passed to Aws\\AwsClient::getCommand() must be of the type array, string given, called in /php_workspace/s3_php/vendor/aws/aws-sdk-php/src/AwsClient.php on line 167 and defined in /php_workspace/s3_php/vendor/aws/aws-sdk-php/src/AwsClient.php on line 211, referer: http://localhost/upload.php
Simple way to do this:
include Amazon S3 PHP Class in you're project.
instantiate the class:
1. OO method (e,g; $s3->getObject(...)):
$s3 = new S3($awsAccessKey, $awsSecretKey);
2. Statically (e,g; S3::getObject(...)):
S3::setAuth($awsAccessKey, $awsSecretKey);
Then get Objects:
// Return an entire object buffer:
$object = S3::getObject($bucket, $uri));
var_dump($object);
Usually, the most efficient way to do this is to save the object to a file or resource
<?php
// To save it to a file (unbuffered write stream):
if (($object = S3::getObject($bucket, $uri, "/tmp/savefile.txt")) !== false) {
print_r($object);
}
// To write it to a resource (unbuffered write stream):
$fp = fopen("/tmp/savefile.txt", "wb");
if (($object = S3::getObject($bucket, $uri, $fp)) !== false) {
print_r($object);
}
?>
S3 Class -With Examples
S3 Class -Documentation
You can try this :
$bucket= "bucket-name";
$filetodownload = "name-of-the-file";
$resultbool = $s3->doesObjectExist ($bucket, $filetodownload );
if ($resultbool) {
$result = $client->getObject ( [
'Bucket' => $bucket,
'Key' => $filetodownload
] );
}
else
{
echo "file not found";die;
}
header ( "Content-Type: {$result['ContentType']}" );
header ( "Content-Disposition: attachment; filename=" . $filetodownload );
header ('Pragma: public');
echo $result ['Body'];
die ();

String concatenation - preg_match() expects string, array given

public function getDownload($name){
$file = storage_path().'/cv/'.$name; //error here
$headers = array(
'Content-Description' => 'File Transfer',
'Content-Type' => 'application/pdf',
);
return Response::download($file, $headers);
}
I just want to concatenate all in one variable. All parameters are string.
Below is one var_dump () of the two variavaies storage_path() and $name.
If you were to take a look at the download method of the Request factory you will find that you are missing a parameter.
public function download($file, $name = null, array $headers = array(), $disposition = 'attachment');

Server send a image as response and rename it before serving - Symfony 2

I want to serve a image as Response in Symfony 2.3.16
So I'm doing this in my action:
$image = $this->getDoctrine()->getRepository('MakoBackendBundle:Image')->find($id);
if($image !== null) {
/** #var $image Image */
$info = getimagesize($image->getAbsolutePath());
$content = file_get_contents($image->getAbsolutePath());
return new Response($content, 200, array(
'Content-Type' => $info['mime'],
'Content-Length' => strlen($content),
'Content-Disposition' => 'attachment;'
));
}
return new Response();
My question is how can I serve this image with a different name, like a time based hash or something? I want to serve it with a different name than it is stored on the server-side.
Symfony2 has a helper for this. This is from the documentation.
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
$d = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT, // disposition
'foo.pdf' // filename
);
$response->headers->set('Content-Disposition', $d);

Categories