Download file from Slim Framework 2.4 - php

I am trying to let the user download a file in the Slim php framework.
The intended use is that the file will be:
http://api.test.com/item/123.json <- returns json string with data
http://api.test.com/item/123.pdf <- download pdf-file with human-readable presentation of data
I have the code producing the PDF, but what I need is to make Slim send the correct headers so the file will be downloaded.
This is the following code I have (working) for the existing system:
header("Pragma: public");
header('Content-disposition: attachment; filename='.$f->name);
header('Content-type: ' .$f->type);
header('Content-Transfer-Encoding: binary');
echo $f->data;
Following is my current (non-working) Slim-code where the headers I declare is not sent to the browser. Instead I get text/html. (Note that this example only contains one header, I have also tested to see if any other header manipulation would cause any effect, but it haven't). The switch-case of json/pdf/xml will be added later on.
R::setup();
$app = new \Slim\Slim();
$app->get('/item', function() use ($app) {
$f = R::load('file', 123);
$app->response->headers->set("Content-Type", "application/pdf"); //$f->type
$app->response->setBody($f->data);
});
$app->run();
The $app->response->setBody($f->data) however works fine.

Problem solved. Turned out to be a included php class with whitespace in it. This messed up the headers i guess.
Solved by creating a new, empty project and include step by step until the bad class showed.
Working solution for setting headers inside a Slim function;
<?php
require 'vendor/autoload.php';
$app = new \Slim\Slim();
$app->get('/foo', function () use ($app) {
$app->response->headers->set('Content-Type', "application/pdf");
$app->response->setBody("foo");
});
$app->run();
?>
Updated: This is the headers I use to let a user download a PDF:
$app->response->headers->set('Content-Type', $f->type);
$app->response->headers->set('Pragma', "public");
$app->response->headers->set('Content-disposition:', 'attachment; filename=' . $f->name);
$app->response->headers->set('Content-Transfer-Encoding', 'binary');
$app->response->headers->set('Content-Length', $f->size);
$app->response->setBody($f->data);

Related

PHPPresentation - How to customize filename of served (downloadable in browser) file to not be the filename of the invoking php script?

How do I modify the following script (Summary.php) so that the served PPTX file name is not "Summary.php" and my served file is not named Summary.php.pptx?
The technique I am using is to render contents of the PowerPoint file into into the browser but I intentionally want to change the filename to at least not contain .php, but at best be a custom name like Presentation.pptx as specified in my php header below.
Summary.php
require_once 'vendor/phpoffice/phppresentation/vendor/autoload.php';
use PhpOffice\PhpPresentation\PhpPresentation;
use PhpOffice\PhpPresentation\IOFactory;
use PhpOffice\PhpPresentation\Style\Alignment;
use PhpOffice\PhpPresentation\Style\Color;
use PhpOffice\PhpPresentation\Style\Fill;
use PhpOffice\PhpPresentation\Style\Border;
class Presentation
{
function generatePresentation()
{
header("Content-Type: application/vnd.openxmlformats-officedocument.presentationml.presentation; filename=Presentation.pptx");
$oWriterPPTX = IOFactory::createWriter($this->objPhpPresentation,'PowerPoint2007' );
$oWriterPPTX->save('php://output');
}
}
EDIT
Solution
header("Content-Type: application/vnd.openxmlformats-officedocument.presentationml.presentation");
header("Content-Disposition: attachment; filename=Presentation.pptx");
$oWriterPPTX = IOFactory::createWriter($this->objPhpPresentation,'PowerPoint2007' );
$oWriterPPTX->save('php://output');
You should use Content-Disposition response header. E.g.
Content-Disposition: attachment; filename="filename.jpg"
Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition

laravel print preview using laravel-dompdf

I am using Laravel 5.4 and using
"barryvdh/laravel-dompdf": "^0.8.0",
https://github.com/barryvdh/laravel-dompdf
i have follwoing code in controller
$pdf = PDF::loadView('print.print', $data);
return $pdf->download('invoice.pdf');
As it will download pdf properly but i am looking to preview the content in the view to print.
i have googled lot still not able to get it
You can use stream() function as stated in documentation here.
According to documentation of dompdf,
When you use stream like this:
$dompdf->stream('filename.pdf');
In default, you will see a download dialouge box.
But, you can add parameter Attachment value to false so that you can view pdf in browser.
Here is what you need to do:
$dompdf->stream("filename.pdf", array("Attachment" => false));
This might help you.
I've struggled with this and manage to make it work with the following snippet:
$html = view('desktop.bill', $data)->render();
return #\PDF::loadHTML($html, 'utf-8')->stream(); // to debug + add the follosing headers in controller ( TOP LEVEL )
Besides the upper command, you will need to add on a TOP LEVEL, like first lines in the controller, the following hearders:
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="document.pdf"');
header('Content-Transfer-Encoding: binary');

Zend framework 3 - DOMPDF

I'm trying to use DOMPDF module with ZF 3.
I've installed it with composer composer require dino/dompdf-module and looks ok.
Then i've imported the dompdf module to my order controller
use DOMPDFModule\View\Model\PdfModel;
After that, i've created a new action called printOrderPdfAction() and a new view, here's the following code:
Controller:
public function printOrderPdfAction()
{
$this->layout(FALSE);
$pdf = new PdfModel();
$pdf->setOption('filename', 'order-pdf');
$pdf->setOption('paperSize', 'a4');
$pdf->setOption('paperOrientation', 'portrait');
$pdf->setVariables([
'message' => 'This is a test message'
]);
return $pdf;
}
View:
<html>
<body>
<h2><?= $this->message?></h2>
</body>
</html>
This should download automatically the pdf, however it's returning the view and it's not downloading the pdf file.
Like this:
Anyone can help me to solve this?
You may be experiencing an issue where some browsers need quotes around the file name in the Content-Disposition header, otherwise the browser ignores the header and the file is not downloaded.
Example:
Content-Disposition: attachment; filename=report.pdf
Should really be:
Content-Disposition: attachment; filename="report.pdf"
In DompdfModule the quotes were in fact missing. This has since been fixed in https://github.com/raykolbe/DOMPDFModule/pull/67 and is slated to be released in v0.5.0.
You can try dev-master or the specific commit 7f11506a22ebabb3aac5e800eada1d8e85e22916 to see if this solves the problem you're experiencing.

Downloading AND installing .mobileconfig in Safari - Not installing - OS X (not iOS)

In our app, we direct the user to download a .mobileconfig. Originally the problem was Safari just displayed the XML rather than downloaded that, but we got around this with a PHP script (below).
<?php
$file = "http://example.com/myProfile.mobileconfig";
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=\"$file\"");
readfile ($file);
?>
However we commonly see it where the .mobileconfig is downloaded and automatically it brings up the 'do you wish to install page'. How is that done? Are we missing something in Content-Type?
Thanks,
Sam
Experienced same problem, the solution is below.
Just set the content type, works like a charm ;)
public function controllerMethod() {
// $config contains generated XML file as string.
$config = $this->generateConfig('apple', Input::all());
// Make response -> attach $config to response
$response = Response::make($config);
// Set headers
$response->headers->set('Content-Type', 'application/x-apple-aspen-config');
$response->headers->set('Content-Disposition', "attachment; filename='mail.mobileconfig'");
return $response;
}

Creating a temp .htm file in PHP and send it to the user?

Is there a simple way to create an empty temp .htm file on the server and send it to the user as download? I don't need to really create the file with fopen(), it's enough to just create it temporarily and send it to the user.
I need that for a website authentication. I found there is tmpfile() function within PHP, but it doesn't quite work for me yet. I am working on a Symfony project, maybe there are also a header function I don't know of.
All I need is:
$token = '12345';
$filename = $token . '.htm';
createatmpfile($filename);
header(send .htm file as download to the user);
Not sure how that works, but maybe my pseudocode above explains what I am looking for ..
EDITED:
That's how it works for Symfony2 (thanks Grad):
use Symfony\Component\HttpFoundation\Response;
Controller method:
public function generateAction() {
$response = new Response();
$response->headers->set('Content-Disposition', 'attachment; filename="'.$token.'.htm"');
return $response;
}
In plain PHP you could use to following line to force the user to download the response
header('Content-Disposition: attachment; filename="filename.htm"');
In Symfony you can use:
$this->getResponse()->setHttpHeader('Content-Disposition', 'attachment; filename="filename.htm"');
With this header set you can either just execute your controller (and let the view fill in the response), or use $contents = file_get_contents($path) together with return $this->renderText($contents).
But depending on what you're trying to achieve: you don't have to create a tempfile to force the to download it.

Categories