Directing to a white page in browser instead downloading a PDF in laravel-dompdf - dompdf

I have a problem in laravel-dompdf. I think my code is right and I do not know why it directs to a white page instead of downloading a pdf. It is working in other controller but here is not.
My code in my controller:
public function export_pdf()
{
if(Auth::user()->campus_id == 0){
$processes = Process::join('bags','processes.bag_id', '=', 'bags.id')
->join('stations','processes.station_id', '=', 'stations.id')
->select('bags.*','stations.*','processes.*')
->where('stations.campus_id', Session::get('test'))
->orderBy('processes.id', 'desc')
->get();
// Send data to the view using loadView function of PDF facade
$pdf = PDF::loadView('collectionReportspdf', compact('processes'));
// If you want to store the generated pdf to the server then you can use the store function
$pdf->save(storage_path().'_filename.pdf');
// Finally, you can download the file using download function
return $pdf->download('reports.pdf');
}
else{
$processes = Process::join('bags','processes.bag_id', '=', 'bags.id')
->join('stations','processes.station_id', '=', 'stations.id')
->select('bags.*','stations.*','processes.*')
->where('stations.campus_id', Auth::user()->campus_id)
->orderBy('processes.id', 'desc')
->get();
// Send data to the view using loadView function of PDF facade
$pdf = PDF::loadView('collectionReportspdf', compact('processes'));
// If you want to store the generated pdf to the server then you can use the store function
$pdf->save(storage_path().'_filename.pdf');
// Finally, you can download the file using download function
return $pdf->download('reports.pdf');
}
}

In the past, I've had to render the PDF before saving or outputting to the browser.
Try adding the following above $pdf->save():
$pdf->render();
If it still doesn't work, try replacing the return statement with echo.

Related

Spatie Media Library not generating jpeg for videos

OK, so Lets start with code
App\Models\User
public function registerMediaConversions(Media $media = null): void
{
$this
->addMediaConversion('thumb')
->width(368)
->height(232)
->extractVideoFrameAtSecond(1)
->performOnCollections('stories')
->nonQueued();
}
media-library.php
'ffmpeg_path' => env('FFMPEG_PATH', '/usr/local/bin/ffmpeg'),
'ffprobe_path' => env('FFPROBE_PATH', '/usr/local/bin/ffprobe'),
Test Route
Route::get('test', function() {
$video = new \Spatie\MediaLibrary\Conversions\ImageGenerators\Video();
echo $video->convert('demo.mov');
});
StoryController.php (snip)
$model = Auth::user();
//if request is a video
if($request->hasFile('video') && $request->file('video')->isValid()){
$media = $model->addMediaFromRequest('video')
->toMediaCollection('stories');
}
When the video is uploaded, it is added to the library successfully. The issue is no thumbnail is being generated based on the model information. When I use the test route, it does generate the thumbnail successfully. I am not sure what I am missing but after 8 hours I am starting to wonder if this is a bug or if there is more troubleshooting I can do.
Nothing is showing up in the laravel.log, nothing is showing up on the frontend, nothing is showing up out of the ordinary in Telescope so I am at a loss.

Replace Old image with new image in laravel

CONTROLLER
public function updateproduct(Request $request, $id)
{
// dd($request->all());
$request->validate([
'name'=>'required',
'description'=>'required',
'price'=>'required|numeric',
'quantity'=>'required|numeric',
]);
$product = Product::where('id', $id)->first();
if(is_null($product)) {
$product = new Product();
}
$product->name=$request->name;
$product->description=$request->description;
$product->price=$request->price;
$product->quantity=$request->quantity;
if($request->hasfile('images')){
$existingimages = Image::where(['product_id'=> $product->id, 'source'=> 1])->get();
if($existingimages->count() > 0)
foreach($existingimages as $existingimage) {
$filename = public_path().'files/'.$existingimage->name;
if(file_exists($filename)){
unlink($filename);
$existingimage->delete();
}
}
foreach($request->file('images') as $file){
$name = rand(1,9999).'.'.$file->getClientOriginalName().$file->getClientOriginalExtension();
if($file->move(public_path().'/files/', $name)){
$updateImage = Image::firstWhere('product_id', $product->id);
$updateImage->images = $name;
$updateImage->source = 1;
$updateImage->save();
}
}
}
Please check updated question. Request you to correct me if I wrong. Right now it only updates 1 image and other images remains same. please help me with this.
Your code is somewhat confusing, I'm afraid.
Your request appears to allow for multiple images to be uploaded. Here :
if(file_exists($imagePath)){
unlink($imagePath);
}
you look like you're trying to delete any images that already exist, but when you store upload images you're assigning them a random name (which Laravel can already handle for you, by the way, so there's no need to do it yourself) so you're unlikely to be actually deleting them because there'll likely be no file at that location anyway.
Nowhere does your code actually delete any existing images from the database. Essentially what you want to do is :
If the upload has images, retrieve all the existing images for that product.
Delete the physical files for those existing images.
Delete the database entries for those existing images.
Upload your new images and save their details to the database.
Translating that into code means :
if($request->hasfile('images')){
// Delete any existing image files and database entries.
$existingimages = Image::where('product_id', $product->id)->get();
if($existingimages->count() > 0)
foreach($existingimages as $existingimage) {
$filename = public_path().'files/'.$existingimage->name;
unlink($filename);
$existingimage->delete();
}
}
// Carry on with your upload
}
It adds new images because you are using the Image::create method. If I understood correctly, you want to modify the images of your products in the image table.
Try to modify your code like :
$updateImage = Image::firstWhere('product_id', $product->id);
$updateImage->images = $name;
$updateImage->source = 1;
$updateImage->save();

barryvdh/laravel-dompdf renders blank web page

I'm upgrading from Laravel 7 to 8 and would like to switch to barryvdh/laravel-dompdf for PDF generation. I was using niklasravnsborg/laravel-pdf up until now, but since that package doesn't support Laravel 8, I need to switch. So I am in the processing of altering my existing code to use barryvdh/laravel-dompdf, but I'm running into an issue.
This is my (simplified) controller:
public function update(Request $request) {
$invoice = Invoice::find($request->invoice_id);
if(isset($request->export) AND $request->export == 1) {
$this->exportInvoice($invoice, $request);
}
}
This exportInvoice function is in the same controller file.
I'm using this to generate a test PDF:
$pdf = App::make('dompdf.wrapper');
$pdf->loadHTML('<h1>Test</h1>');
return $pdf->stream();
Now I've managed to narrow down the issue to the place in my code where the PDF generation fails.
If I put the PDF generation code in the if statement in the update function above, then I get the expected result: a simple PDF file.
However, as soon as I move this piece of code to the exportInvoice function, I get a simple blank web page.
I've been googling around, but I was unable to find similar issues.
I've tried putting all my code together in the update function and guess what ... This works as expected. It's as if I'm doing something wrong with the subfunctions, but I can't figure out what.
Does anybody see what I'm doing wrong?
From your update() method, this will stream a PDF back to the browser:
return $pdf->stream();
But from a exportInvoice(), called by the update() method, that will just return the stream back to the update() method. If you don't do anything with it there, it won't reach the browser. You need to return the response returned from exportInvoice().
public function update(Request $request) {
$invoice = Invoice::find($request->invoice_id);
if(isset($request->export) AND $request->export == 1) {
// Note we need to *return* the response to the browser
return $this->exportInvoice($invoice, $request);
}
}
public function exportInvoice($invoice, $request) {
$pdf = App::make('dompdf.wrapper');
$pdf->loadHTML('<h1>Test</h1>');
return $pdf->stream();
}

is there any possibility to display image from public folder in Laravel controller?

this function returns only one image. but I want to show all images which are stored in this folder. can anyone help me?
My controller
public function index()
{
$get=Resturant::all(['id','name','image']);
foreach ($get as $image) {
$path =public_path().'/Images/Resturants/'.$image->image;
$file= File::get($path);
$type= File::mimeType($path);
$response= Response::make($file, 200);
$response->header("Content-Type",$type);
return $response;
}
}
You don't need to be trying to return a file response, since your web server itself can handle serving files in the public folder. Also you wouldn't be trying to return multiple files (somehow) in the response. You can just return an array of the URLs to the files and let what ever is consuming this make the requests to get these files by URL. This would simplify your controller method quite a bit:
return Resturant::pluck('image')
->map(fn ($i) => asset('Images/Resturants/'. $i));
PHP 8 here, but its pretty simple, just have to make URLs from each image.
If you want to have the names to go along with this you can adjust pluck to use a column for the index:
...pluck('image', 'name')...

Generate multiple PDF documents with loop with dompdf in laravel

I am trying to download multiple pdf using dompdf in laravel, but below solution just concatenate into one pdf file
$weeks = ['test','test2'];
$html = '';
foreach($weeks as $hours)
{
$view = view('contract');
$html .= $view->render();
}
$pdf = PDF::loadHTML($html);
$sheet = $pdf->setPaper('a4', 'landscape');
return $sheet->download('download.pdf');
the server can only return a response, if you want several pdf files you should modify your method so that it accepts some parameter and for each parameter generate a pdf
It is not possible to download more than one file in a single HTTP request.
What you could do is pack the files into o zip and download that. You can try https://github.com/zanysoft/laravel-zip or any other available solution.
Another option would be to save the files and return only paths for the saved files back to the client. Then make a new request and download the file for each of the returned filepaths.
Also if you want to save to separate PDF files you need to move PDF creation into your foreach loop (create a PDF for each parameter).
$weeks = ['test','test2'];
$files = [];
foreach($weeks as $hours)
{
$view = view('contract');
$html = $view->render();
$pdf = PDF::loadHTML($html);
$pdf->setPaper('a4', 'landscape');
$pdf->save('documents/'.$hours.'.pdf');
$files[] = 'documents/'.$hours.'.pdf';
}
return response()->json(['files' => $files]);
In this case the foreach doesn't really do anything other than produce two identical PDF files. If you want to actually apply some kind of changes to your view based on values in $weeks you need to pass that to your view.
$view = view('contract', ['data' => $hours]);
That makes $data available in your view and you can change the resulting PDF in that way (show your contract.blade.php if you need more help regarding that).

Resources