Reputation: 29121
I have a QR code PNG being dynamically generated. I can access it by going to www.example.com/events/qrgen
, which causes it to be displayed in the browser correctly.
Now, I would like another option that downloads the PNG file. Here is what I've tried:
// this action displays a QR code in the browser
public function qrgen() {
$this->layout = false;
$this->response->type('image/png');
}
// this action SHOULD make the png download
public function download_qrgen() {
$qrUrl = Router::url(['controller'=>'events', 'action'=>'qrgen']);
$this->response->file($qrUrl, ['download'=>true, 'name'=>'qr']);
return $this->response;
}
// in the "qrgen" view
QRcode::png('example value', null, "M", 4, 4);
But when I access www.example.com/events/download_qrgen
, it gives an error "That page could not be found", and shows the CakeResponse->file(string, array)
value as: /var/www/example.com//events/qrgen
.
If I try a file in my webroot, it correctly downloads the file. But I can't seem to get it to download a dynamically generated png like this.
Upvotes: 0
Views: 129
Reputation: 60463
CakeResponse::file()
expects a file system path passed to it, not a URL, it's not going to make any HTTP requests to obtain the data.
You have to obtain the data yourself, and then either buffer it in a temporary file whose path in the filesystem you can pass to CakeResponse::file()
:
public function download_qrgen() {
$this->layout = false;
$qrcodeData = $this->_getViewObject()->render('qrgen');
$temp = tmpfile();
fwrite($temp, $qrcodeData);
$filePath = stream_get_meta_data($temp)['uri'];
$this->response->file($filePath, ['download' => true, 'name' => 'qr.png']);
return $this->response;
}
or you prepare the response with the data and headers yourself:
public function download_qrgen() {
$this->layout = false;
$qrcodeData = $this->_getViewObject()->render('qrgen');
$this->response->type('image/png');
$this->response->download('qr.png');
$this->response->length(strlen($qrcodeData));
$this->response->header('Content-Transfer-Encoding', 'binary');
$this->response->body($qrcodeData);
return $this->response;
}
See also
Upvotes: 1