laravel snappy pdf: getting an error the file was not created - laravel

I have about 1500 students in my database and I need to generate an invoice for each one. For this purpose I am using this library https://github.com/barryvdh/laravel-snappy . When I try to generate I get this error:
The file '/var/www/skmpastebimaslt/public_html/storage/checks/24767 Dominykas Butkevičius 1581703819.pdf' was not created (command: /usr/local/bin/wkhtmltopdf --lowquality '/tmp/knp_snappy5e46e28b5d61f2.13362077.html' '/var/www/skmpastebimaslt/public_html/storage/checks/24767 Dominykas Butkeviius 1581703819.pdf').
https://gyazo.com/3a3f60713601a663a1360cd65fee9914
Invoices are generated for four users then the app crashes. The most interesting thing is that even though the error says the file was not created but it was created, I can find it in my storage folder.
My code:
public function saveCheckPdf(Student $student, Check $check = null, $fileName = null)
{
if (empty($fileName)) {
$fileName = 'kvitas_' . time() . '.pdf';
}
$path = storage_path('checks/' . $fileName . '.pdf');
$this->renderCheckPdf($student, $check)->save($path);
return $path;
}
private function renderCheckPdf(Student $student, Check $check = null)
{
$bills = $this->billRepository->getCurrentSeasonBills($student->id);
$payments = $this->paymentRepository->getCurrentSeasonPayments($student->id);
$fileName = $student->fullname . ' kvitas';
$billsSum = $bills->sum('sum');
$paymentsSum = $payments->sum('sum');
if (empty($check)) {
$check = !empty($student->checks[0]) ? $student->checks[0] : false;
}
return newPDF::loadView('student.check_pdf', compact('student', 'payments', 'bills', 'billsSum', 'paymentsSum', 'fileName', 'check'));
}
Then I just loop through each user and call saveCheckPdf method in my controller like this
$this->pdfService->saveCheckPdf($student, null, $student->id . ' ' . $student->fullname . ' ' . time());
Maybe anyone faced the same problem?

Related

How to Save File in storage folder with Original name?

I want to store an uploaded file with its original client name in the storage folder. What do I need to add or change in my code?Any help or recommendation will be greatly appreciated
Here my Controller
public function store(Request $request) {
$path = "dev/table/".$input['id']."";
$originalName = $request->file->getClientOriginalName();
$file = $request->file;
Storage::disk('local')->put($path . '/' . $originalName, $request->file);
}
Edit: I know how to get the originalClientName. the problem is storing the file in the folder using the original name, not the hash name. It doesn't store in the file in the original it makes a new folder instead here is the output "dev/table/101/Capture1.PNG/xtZ9iFoJMoLrLaPDDPvc4DMJEXkRL3R4qWOionMC.png" what I trying to get is "dev/table/101/Capture1.PNG"
I have tried to use StoreAs Or putFileAs but the method is undefined
I managed to figure out how to store it with a custom name, for those who want to know how to do it here is the code
$id = $input['id'];
$originalName = $request->file->getClientOriginalName();
$path = "dev/table/$id/".$originalName;
Storage::disk('local')->put($path, file_get_contents($request->file));
public function store(Request $request) {
$originalName = $request->file->getClientOriginalName();
$extension = $request->file->getClientOriginalExtension();
$path = "dev/table/" . $input['id'] . "/" . $originalName . "." . $extension;
$file = $request->file;
Storage::disk('local')->put($path, $file);
}
To get the original file name you can use this in your ControllerClass:
$file = $request->file->getClientOriginalName();
To get additional the extension you can use this Laravel Request Method:
$ext = $request->file->getClientOriginalExtension();
Then you can save with:
$fileName = $file.'.'.$ext;
$request->file->storeAs($path, $fileName);
// or
Storage::disk('local')->put($path . '/' . $fileName , $request->file);
You can save files using storage with the default name using putFileAs function instead of put which allow take third param as a file name
$path = "dev/table/101/";
$originalName = request()->file->getClientOriginalName();
$image = request()->file;
Storage::disk('local')->putFileAs($path, $image, $originalName);
Update
You can do something like this with put,
Storage::disk('local')->put($path.$originalName, file_get_contents($image));
I tried to manage like this;
$insurance = $request->file('insurance_papers');
$insuranceExtention = $insurance->getClientOriginalExtension();
$path = "public/files/" . $carrier->id . "/insurance_papers." . $insuranceExtention;
Storage::disk('local')->put($path, file_get_contents($insurance));
You can try this, this is work for me
if ($request->hasFile('attachment')) {
$image = $request->file('attachment');
$imageName = time() . '.' . $image->getClientOriginalExtension();
$path = "foldername/".$imageName;
Storage::disk('public')->put($path, file_get_contents($image));
}

Laravel download image

I have a function to add an image, and upon successful addition in the database, we have a path like public/images/asd.png. The question is how to make sure that when added to the name of the picture, an ID is added, and we have something like public/images/asd1.png, public/images/asd2.png, etc.
function in Model
public function getOriginImageUrl()
{
return $this->attributes['image'];
}
public function getImageAttribute($value)
{
return Storage::exists($value) ? Storage::url($value) : null;
}
function in Controller
if ($request->hasFile('image')) {
$file = $request->file('image');
$blog->image = $file->storeAs('public/images', $file->getClientOriginalName());
}
Instead of id you can combine time() with image name.
if ($request->hasFile('image')) {
$file = $request->file('image');
$namewithextension = $file->getClientOriginalName(); //Name with extension 'filename.jpg'
$name = explode('.', $namewithextension)[0]; // Filename 'filename'
$extension = $file->getClientOriginalExtension(); //Extension 'jpg'
$uploadname = $name. '-' .time() . '.' . $extension;
$blog->image = $file->storeAs('public/images', $uploadname);
}

Laravel 5.4 Error: NotReadableException: Image source not readable

I'm trying to create multiple copies of profile pic in different sizes when a profile is created. But I am constantly getting this error:
" NotReadableException: Image source not readable"
Can somebody point me what I'm missing in my below code:
public function updateprofile(UserProfileRequest $request){
$user_id = Auth::User()->id;
$profile = UserProfile::where('user_id','=',$user_id)->first();
$profile->fullname = $request->fullname;
if ($request->hasFile('img')) {
if($request->file('img')->isValid()) {
$types = array('_original.', '_32.', '_64.', '_128.');
$sizes = array( '32', '64', '128');
$targetPath = 'public/uploads/'.$user_id;
try {
$file = $request->file('img');
$ext = $file->getClientOriginalExtension();
$fName = time();
$original = $fName . array_shift($types) . $ext;
Storage::putFileAs($targetPath, $file, $original);
foreach ($types as $key => $type) {
$newName = $fName . $type . $ext;
Storage::copy($targetPath . $original, $targetPath . $newName);
$newImg = Image::make($targetPath . $newName);
$newImg->resize($sizes[$key], null, function($constraint){
$constraint->aspectRatio();
});
$newImg->save($targetPath . $newName);
}
$profile->img = 'public/uploads/'.$user_id;
} catch (Illuminate\Filesystem\FileNotFoundException $e) {
}
}
}
$profile->save();}
I had the same issue i ran this command and it worked
php artisan storage:link
This command creates a storage directory under the public folder.
Also use public path function to get the public path
$targetPath = public_path('storage/uploads/'. $user_id);
The 'storage' used inside the laravel public_path() function is used to get the storage main folder.
If I'm not mistaken, the path which is provided should be the absolute filepath on your server. For example instead of:
$targetPath = 'public/uploads/'.$user_id;
Use (your actual path will vary depending on your configuration)
$targetPath = '/var/www/sitename/public/uploads/'.$user_id;
Laravel also contains a helper function called public_path() which can be used to obtain the "fully qualified path to the public directory". This would allow you to use something such as:
$targetPath = public_path('uploads/'. $user_id);
Also, on this line, do not forget to place a slash before the new filename:
$newImg = Image::make($targetPath . '/' . $newName);
I would also confirm that the user executing the script (if apache or nginx usually www-data unless altered) has write permissions to your public/uploads/ directory
Finally, I got it working. I made following changes to my code:
Use the full OS path as suggested by commanderZiltoid for the destination path.
Don't use Storage::putFileAs method to save the file. So, remove this line: Storage::putFileAs($targetPath, $file, $original);
Don't use Storage::copy() to copy the file, so, remove this line:
Storage::copy($targetPath . $original, $targetPath . $newName);
For points 2 and 3, use Image::make($file->getRealPath()); This will create the file and remember the path where the file was created. Image->resize method will use this path later.
In the end, save the relative path in the database, as here: $profile->img = 'storage/uploads/'.$user_id.'/img/profile/'.$fName. Since we'll use {{ asset($profile->img) }}, it's necessary to save only the relative path and not the absolute OS path.
if($request->hasFile('img')) {
if($request->file('img')->isValid()) {
$types = array('_original.', '_32.', '_64.', '_128.');
$sizes = array( array('32','32'), array('64','64'), array('128','128'));
$targetPath = '/Users/apple/Documents/_chayyo/chayyo/storage/app/public/uploads/'.$user_id.'/img/profile/';
try {
$file = $request->file('img');
$ext = $file->getClientOriginalExtension();
$fName = time();
$o_name = $fName . array_shift($types) . $ext;
$original = Image::make($file->getRealPath());
$original->save($targetPath . $o_name);
foreach ($types as $key => $type) {
$newName = $fName . $type . $ext;
$newImg = Image::make($file->getRealPath());
$newImg->resize($sizes[$key][0], $sizes[$key][1]);
$newImg->save($targetPath . $newName);
}
$profile->img = 'storage/uploads/'.$user_id.'/img/profile/'.$fName;
}
catch (Illuminate\Filesystem\FileNotFoundException $e) {
}
}
}

I want to delete the stored image while update new image

I want to delete the stored image while update new image
public function update($id)
{
$users = AdminLogin::find($id);
if(Input::hasFile('image_file'))
{
$file = Input::file('image_file');
$name = time() . '-' . $file->getClientOriginalName();
$file = $file->move(('uploads/images'), $name);
$users->image_file= $name;
}
$users->save();
return response()->json($users);
}
You can write this. This will solve your problem
public function update($id)
{
$users = AdminLogin::find($id);
if(Input::hasFile('image_file'))
{
$usersImage = public_path("uploads/images/{$users->image_file}"); // get previous image from folder
if (File::exists($usersImage)) { // unlink or remove previous image from folder
unlink($usersImage);
}
$file = Input::file('image_file');
$name = time() . '-' . $file->getClientOriginalName();
$file = $file->move(('uploads/images'), $name);
$users->image_file= $name;
}
$users->save();
return response()->json($users);
}
This will delete the previous image and update the new image
Well, the answer is technically incorrect. What if the save operation fails, since you have deleted that image the current record will not have an image anymore.
So to overcome this problem you can adjust your code like:
if(Input::hasFile('image_file'))
{
$file = Input::file('image_file');
$name = time() . '-' . $file->getClientOriginalName();
$file = $file->move(('uploads/images'), $name);
$users->image_file= $name;
}
$users->save();
if(Input::hasFile('image_file'))
{
$usersImage = public_path("uploads/images/{$users->image_file}"); // get previous image from folder
if (File::exists($usersImage)) { // unlink or remove previous image from folder
unlink($usersImage);
}
}

Download a file to the desktop where field name equals file name in codeigniter

I have code written to allow someone to enter a date. if the submit date equals the file name then codeigniter should download the file to the desktop. The code shown makes sense to me but when I run it I get 'file was not found'. I can pull the file up on the server though and the name matches what is returned in the mysql database. My end goal is to be able to download the file with the same filename as my submission_date field
if($this->input->post('submit')) {
$trlr_num = $this->input->post('trlr_num');
} elseif($this->uri->segment(4)) {
$trlr_num = $this->uri->segment(4);
}
if( !empty($trlr_num)) {
$query = $this->trailer_model->select_trailer_draw($trlr_num);
$result =& $query->row_array();
if( !empty($result)) {
// Get filepath to bill
$directory = 'http://intranet.gmwdc.com/inc/img/inspection/upload';
$file = $directory.'/'.$result['submission_date'];
$this->load->helper('download');
if(file_exists($file)) {
$data = file_get_contents($file);
force_download($result['submission_date'],$data);
} else {
$this->session->set_status_data('error','File was not found.');
}
return;
} else {
$this->session->set_userdata('error','No Inspection Draw Found');
}
}
You might be referring wrong directory or file name. Also, it seems that $file is having no extension.
$file = $directory . '/' . $result['submission_date'] . $extension;
Edited
Instead of $directory try Codeigniter FCPATH which points to your Codeigniter installation directory.
$file = FCPATH . 'dir1/dir2/' . $result['submission_date'];

Resources