Laravel 5.4 Response File -> Error in File - php

I am working with Laravel 5.4 and save some JPEG-Files to Storage with
`Storage::disk('local')->put('upload/pictures/full-size/'.$filename ,$picture);`
And now i try to get this pictures again which i tryed like
...
Routes:
Route::get('pictures/full/{filename}', ['as' => 'picture_full', 'uses' => 'ImageController#getFull']);
...
Image Controller:
public function getFull(Image $image)
{
$path = storage_path('app/'.Config::get('pictures.icon_size').$image->filename);
$handler = new \Symfony\Component\HttpFoundation\File\File($path);
$header_content_type = $handler->getMimeType();
$header_content_length = $handler->getSize();
$headers = array(
'Content-Type' => $header_content_type,
'Content-Length' => $header_content_length
);
return response()->file($path, $headers);
}
So now my Problem is, that the file can't be shown.
The Browser says the File contains an Error.
Tryed a lot, but just don't see what I am making wrong.
Anyone has an idea?

Related

Laravel 8 download PDF with Livewire

On my page I am making an invoice that is fully compatible with Livewire. I use this package: https://github.com/LaravelDaily/laravel-invoices to generate my invoice and everything works fine. But their is one problem I ran into. I can't download my PDF with Livewire.
Here is a basic example to generate a PDF and download it:
public function invoice()
{
$customer = new Buyer([
'name' => 'John Doe',
'custom_fields' => [
'email' => 'test#example.com',
],
]);
$item = (new InvoiceItem())->title('Service 1')->pricePerUnit(2);
$invoice = Invoice::make()
->buyer($customer)
->discountByPercent(10)
->taxRate(15)
->shipping(1.99)
->addItem($item);
return $invoice->download();
}
Whenever I click on a button
<a role="button" class="pdf-download cursor-pointer" wire:click="invoice">download</a>
Nothing happens. So the problem is that Livewire doesn't support this download method. And this download method looks like this:
public function download()
{
$this->render();
return new Response($this->output, Response::HTTP_OK, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="' . $this->filename . '"',
'Content-Length' => strlen($this->output),
]);
}
$this->render(); Renders a template in a specific folder
Is their a work around for this? Where I can download my pdf with a template or maybe a different strategy. I allready tried one thing. I stored the invoice into a session, like so:
Session::put('invoice', $invoice);
Session::save();
And in a different controller I have.
if ($invoice = Session::get('invoice')) {
$invoice->download();
}
But that gives me this error:
serialization of 'closure' is not allowed
And I tried some stuff I found here: https://github.com/livewire/livewire/issues/483
But nothing works. Can someone give me a direction on where to look or how to fix this? Thanks!
return response()->streamDownload(function () use($invoice) {
echo $invoice->stream();
}, 'invoice.pdf');
Seems to do the trick.

I want to make a private directory using Laravel 6

I want to make a private directory using Laravel 6.
Only users who have already logged in can access the directory.
So, I implemented below:
routes/web.php
Route::group(['middleware' => ['private_web']], function() { // 'private_web' includes auth
Route::get('/private/{path?}', 'PrivateController#index')->name('private')->where('path', '.*');
});
PrivateController.php
public function index(Request $request, $path = null) {
$storage_path = 'private/' . $path;
$mime_type = Storage::mimeType($storage_path);
$headers = [ 'Content-Type' => $mime_type, ];
return Storage::response($storage_path, null, $headers);
}
It is working.
But, when I got a html from the directory using Chrome, a css linked from the html wasn't applied (the css is in private directory and just downloaded successfully).
The cause is already known and it is Storage::mimeType returns 'text/plain' against css.
I can fix it by making a branch:
if (ends_with($path, '.css')) {
$mime_type = 'text/css';
} else {
$mime_type = Storage::mimeType($storage_path);
}
Question:
Is there more better solution?
I'm afraid of increasing such branch at each file type...
thanks.

Error. Failed to load pdf document in laravel

I want to load pdf file in html but i got an error.
here is my function
public function getDocument($file){
$filePath = 'app/final/attachments/AA-19-4-2019-18123/'.$file;
$type = Storage::mimeType($filePath);
$pdfContent = Storage::get($filePath);
return Response::make($pdfContent, 200, [
'Content-Type' => $type,
'Content-Disposition' => 'inline; filename="'.$file.'"'
]);
}
here is my route
Route::get('/documents/pdf-document/{file}', 'inboxController#getDocument');
and here is my code in blade
<embed src="{{ action('inboxController#getDocument', ['file'=> basename($attach)]) }}" style="width:100%;height:auto;overflow: hidden;" frameborder="0" allowfullscreen>
it seems like, the error is because of the filename of the file. When i changed it to asdf.pdf, it loaded the file, but when i change its filename i wont loaded anymore. Images doesnt have really a problem. only pdf files. Please help me
edit
when i tried to use this static code, then remove {file} from route and also in blade, then pdf will loaded. i cant figure it out why.
public function getDocument(){
$filePath = 'app/final/attachments/AA-19-4-2019-18123/my.pdf';
$type = Storage::mimeType($filePath);
$pdfContent = Storage::get($filePath);
return Response::make($pdfContent, 200, [
'Content-Type' => $type,
'Content-Disposition' => 'inline; filename="'.$file.'"'
]);
}
You can do it this way :
php artisan storage:link
Next Go to the storage folder under 'public', and create a Folder 'FOLDER_NAME'
Your function :
public function getDocument($filename){
return response()->file('storage/FOLDER_NAME/'.$filename);
}
In your routes, web.php :
Route::get('/pdf/{filename}', ['as' => 'filename', 'uses' => 'ControllerName#getDocument' ]);
Then you can call it from your blade :
See PDF File:

Dingo/API when Unit Testing: The version given was unknown or has no registered routes

I built an API using dingo/api 0.10.0, Laravel 5.1 and lucadegasperi/oauth2-server-laravel": "^5.1".
All my routes work fine in Postman/Paw!
The problem appears when I try to test the API using PHPUnit.
This is part of my route-api.php file
<?php
$api = app('Dingo\Api\Routing\Router');
$api->version(['v1'], function ($api) {
$api->post('oauth/access_token', function () {
return response(
\LucaDegasperi\OAuth2Server\Facades\Authorizer::issueAccessToken()
)->header('Content-Type', 'application/json');
});
$api->group(['middleware' => ['oauth', 'api.auth']], function ($api) {
$api->post('/register', 'YPS\Http\Controllers\Api\UserController#register');
});
And this is my test file UserRegistrationTest.php
class UserRegistrationTest extends ApiTestCase
{
public function setUp()
{
parent::setUp();
parent::afterApplicationCreated();
}
public function testRegisterSuccess()
{
$data = factory(YPS\User::class)->make()->toArray();
$data['password'] = 'password123';
$this->post('api/register', $data, $this->headers)
->seeStatusCode(201)
->seeJson([
'email' => $data['email'],
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
]);
}
public function testRegisterMissingParams()
{
$this->post('api/register', [], $this->headers, $this->headers, $this->headers)->seeStatusCode(422);
}
}
The ApiTestCase simply retrieves a token and sets the headers.
private function setHeaders()
{
$this->headers = [
'Accept' => 'application/vnd.yps.v1+json',
'Authorization' => 'Bearer ' . $this->OAuthAccessToken,
];
}
Now, the weird part is that the first test testRegisterSuccess runs perfectly and returns the response I expect. But the second one testRegisterMissingParams, even though it's the same route, returns this,
array:2 [
"message" => "The version given was unknown or has no registered routes."
"status_code" => 400
]
I tracked the error and it is in the Laravel adapter here:
public function dispatch(Request $request, $version)
{
// it seems that the second time around can't find any routes with the key 'v1'
if (! isset($this->routes[$version])) {
throw new UnknownVersionException;
}
$routes = $this->mergeExistingRoutes($this->routes[$version]);
$this->router->setRoutes($routes);
return $this->router->dispatch($request);
}
And further more, if i run one test at a time (eg comment one out, run test and then comment the other and run test) i see the result expected in both tests. The problem is when i run multiple tests.
Any thoughts on that?
Thank you!
Run php artisan api:routes to see full path you may have missed something for the URL, also if this working if you request your URL manually?
I had same problem with testing using Dingo & Lumen. This worked for me - remove bootstrap="bootstrap/app.php" from phpunit.xml file and change line processIsolation="false" to processIsolation="true".

Download CSV from serverside to browser in Laravel 4

I'm using Laravel 4 framework, I have a function that creates a csv file called data_78888.csv the number 78888 changes everytime the function is run to generate a csv file. That function returns a string like that : "Download/78888"
The folder where my csv files are created is called "outputs" and is located in my project folder where the app folder is located to, (it is not in the public folder).
What I would like to do is to create a route that points to my Process controller like that :
Route::get('Download/{token}', array('uses' => 'ProcessController#downloadCSV'));
In my controller I would like to send that csv file to the browser to download it , I'm doing like that :
<?php
class ProcessController extends BaseController {
public function downloadCSV($token){
$fileToDownload = "data_".$token.".csv";
$filePath = "outputs/";
return Response::download($filePath, $fileToDownload, array(
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment;filename="'.$fileToDownload
));
}
}
The issue is that this is not working and I get an html file called 78888.htm and an error on the server.
How can I make this working please?
The path to the file has to include the name and file extension of the file.
So try this;
$fileToDownload = "data_".$token.".csv";
$filePath = base_path() . "outputs/" . $fileToDownload;
return Response::download($filePath, $fileToDownload, array(
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment;filename="'.$fileToDownload
));
Also make sure the file exists, before downloading.

Categories