Display a link if an item has a PDF in laravel - php

I am trying to get an item to display a link to PDF if that item has a PDF associated with it. I am not sure how the if statement would be formatted. I am using Laravel for this.
Here is the code that I have in the controller for the item:
//PDF Upload
if($request->hasFile('spec_sheet')) {
//Get file name and extension
$filenameWithExt = $request->file('spec_sheet')->getClientOriginalName();
//Get just file name
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
//Get Ext
$extension = $request->file('spec_sheet')->getClientOriginalExtension();
//Store file name
$fileNameOfPdfToStore = $filename. '.' .$extension;
//Upload
$path = $request->file('spec_sheet')->storeAs('public/mcelroy-specs', $fileNameOfPdfToStore);
}
$rental = new Rental;
$rental->title = $request->title;
$rental->name = $request->name;
$rental->description = $request->description;
$rental->product_image = $fileNameToStore;
$rental->spec_sheet = $fileNameOfPdfToStore;
$rental->save();
In the view I have this:
#foreach($rentals as $rental)
<article class="cards-item">
<figure class="card product">
<div class="card-images">
<img src="/storage/rentals/{{$rental->product_image}}" alt="" >
</div>
<figcaption class="card-content">
<h1 class="card-title">{{ $rental->title }}</h1>
<h2 class="card-title product_title">{{ $rental->name }}</h2>
<p class="card-text" style="text-align:left;">{{ $rental->description }}
#if(!empty($spec_sheet))
Download Spec Sheet
#endif
</p>
<form action="{{ route('cart.store') }} " method="POST">
{{ csrf_field() }}
<input type="hidden" name="id" value="{{ $rental->id }}">
<input type="hidden" name="title" value="{{ $rental->title }}">
{{-- <input type="hidden" name="pickupDate" value="{{ $rental->pickupDate }}">
<input type="hidden" name="returnDate" value="returnDate"> --}}
<div class="buttons">
<div class="back">
<button class="primary button" type="submit">Add to Cart</button>
</div>
</div>
</form>
</figcaption>
</figure>
</article>
#endforeach

Seems like you are looking for the right way to do something in Laravel, but there is no right way.
Given
#if(!empty($spec_sheet))
Download Spec Sheet
#endif
I would make two changes, 1) shouldn't $spec_sheet be $rental->spec_sheet? and 2) swap out the #if(!empty(...)) with #unless(empty()) as I feel that including a ! will make it harder to understand when you come back to this in a few weeks.
So I am suggesting you use this which should be just fine, since there's no right way to do this in Laravel.
#unless(empty($rental->spec_sheet))
Download Spec Sheet
#endunless

Your code above will not work if there is no PDF attached, as the variable $fileNameOfPdfToStore will not exist and a hard error will be thrown. But assuming you fix that issue and store an empty string for the file name or perhaps NULL instead of the file path, then you could create a new attribute in the Rental model that looks like this:
public function getHasSpecSheetAttribute() {
return $this->spec_sheet==null? false:true;
}
Then in your view you would do this:
#if($rental->hasSpecSheet)
Download Spec Sheet
#endif
In order to fix the PDF upload code, just put an else statement and put this inside of it:
$fileNameOfPdfToStore = null;

#if(strlen({$rental->spec_sheet) > 0))
Download Spec Sheet
#endif
use string length to determine if there was file name uploaded or not

Related

How can I upload image in local folder laravel?

I am new in larval development, I am unable to upload image in local folder and I am getting error getClientOriginalExtension() on null. Even I have added code enctype="multipart/form-data" in my form, but still am getting the error. Can anyone give suggestion how to resolve this issue. I have given below my code.
MyBlade file
****MyBlade file****
<form action="{{ route('register.post') }}" method="POST" enctype="multipart/form-data" accept-charset="utf-8" >
#csrf
<div class="form-group row">
<label for="uname" class="col-md-4 col-form-label text-md-right">User Name</label>
<div class="col-md-6">
<input type="text" id="username" class="form-control" name="username" required />
#if ($errors->has('username'))
<span class="text-danger">{{ $errors->first('username') }}</span>
#endif
</div>
</div>
<div class="form-group row{{ $errors->has('image') ? ' has-error' : '' }}">
<label for="name" class="col-md-4 col-form-label text-md-right">Profile Picture</label>
<div class="col-md-6">
<input id="image" type="file" class="form-control" name="image">
</div>
</div>
My Controller File
if ($request->input('image')!=null){
$files = $request->input('image');
$extension = $files->getClientOriginalExtension();
$filaname = time().','.$extension;
$files->move('public/image/',$filaname);
// $post->image= $filaname;
}
else{
return $request;
}
I am getting err:Call to a member function getClientOriginalExtension() on bool
If you use $request->file('image') instead of $request->input('image') you have fixed the problem. The image will then be moved to the public/image folder.
However, if you want to upload the file to the storage/public folder, you can use the storeAs() method on the $file to store it in the storage folder.
// Your controller
public function update(Request $request, $postId)
{
if (! $request->hasFile('image')) {
return $request;
}
// Use file() instead of input()
$file = $request->file('image');
$extension = $file->getClientOriginalExtension();
// Note you have a typo in your example, you're using a `,` instead of a `.`
$filename = time().'.'.$extension;
// To store (move) the file to the 'public/image' folder, use this:
$file->move('image', $filename);
// To store the file to the 'storage/app/public/image' folder, use this:
$file->storeAs('public/image', $filename);
// Find your post based on some id
$post = Post::find($postId);
// Save the filename to the database on the Post model:
$post->image = $filename;
$post->save();
}
Hope I helped you with this.

Array management and preview with Laravel Livewire

When using an input file to load images with Livewire I found that if the user clicks to load multiple images it works correctly, but if he clicks on the same input a second time, the previews with Livewire are replaced by the selected images. second time. To solve this add an array that loads the images as follows:
My input file
<input wire:change="cargaImagenes" wire:model="imagen" type="file" name="imagen" accept="image/*" class="form-control-file" multiple>
Event Charge
public function cargaImagenes()
{
foreach ($this->imagen as $ima) {
array_push($this->imagenes, $ima);
}
}
The problem is that I do the previews of the images with Livewire in the following way:
#if ($imagenes)
<small>previsualización:</small>
<div class="form-inline">
#foreach($imagenes as $img)
<div wire:key="{{$loop->index}}">
<div class="m-2 img-thumbnail">
<img class="my-2 rounded img-fluid contenedor-img" src="{{ $img->temporaryUrl() }}">
<button class="btn btn-outline-danger" wire:click="eliminarImagen({{ $loop->index }})">
</button>
</div>
</div>
#endforeach
<br>
</div>
#endif
And the problem is that they don't show the first time I select images, it shows when I add more.
For the preview I use the $images property of the array
array_push($this->imagenes, $ima);
Can you give me a suggestion of what I could do to display all the images in the array.
This should work.
Remove wire:change completely.
<input wire:model="imagen" type="file" name="imagen" accept="image/*" class="form-control-file" multiple>
Hook on the updatedImagen() event method:
public function updatedImagen()
{
foreach ($this->imagen as $ima) {
$this->imagenes[] = $ima;
}
}

How to download file from storage?

I'm using Laravel's file storage system and I'm trying to trigger a download response to download my files through the browser, but it cant find the correct file instead it downloads my file page view script. I have a storage link set up as well.
Any suggestions would be appreciated.
File.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<form action="{{route('upload')}}" method="POST"
enctype="multipart/form-data" name="formName">
{{csrf_field() }}
<input type="file" name="file">
<input type="submit" class="btn" name="submit">
</form>
<div class="row">
#foreach($files as $file)
<a href="{{route('download',$file)}}" download="{{$file->name}}">
{{$file->name}}</a>
</div>
</div>
#endsection
Download function
public function download($file){
return response()->download(storage_path('/storage/app/files/'.$file));
}
file routes
Route::get('files', 'FileController#index')->name('upload');
Route::post('files', 'FileController#store');
Route::get('files/{file}', 'FileController#download')->name('download');
Remove this download="{{$file->name}}" from the link.
You can add download as html attribute:
<a href="{!! route('download', $file->name) !!}" download>{{ $file->name }}</a>
But you don't need it in this case, use just:
{{$file->name}}
The response()->download() method in your controller will generate a response that forces the browser to download the file at the given path. So make sure your path i correct.
If your file is in your-project-root-path/storage/app/files/, you can use:
return response()->download(storage_path('/app/files/'. $file));
If your file is in your-project-root-path/storage/storage/app/files/, use:
return response()->download(storage_path('/storage/app/files/'. $file));
I think you are passing the file object instead of the filename to your download route.
Try
#extends('layouts.app')
#section('content')
<div class="container">
<form action="{{route('upload')}}" method="POST"
enctype="multipart/form-data" name="formName">
{{csrf_field() }}
<input type="file" name="file">
<input type="submit" class="btn" name="submit">
</form>
<div class="row">
#foreach($files as $file)
<a href="{{route('download',$file->name)}}" download>
{{$file->name}}</a>
</div>
</div>
#endsection
Try replacing {{route('download',$file)}} with {{route('download',$file->name)}}.
Also try replacing the download controller with this code
public function download($file){
return response()->download(storage_path('app/files/'.$file));
}
public function jpg_download($id)
{
if (auth()->user()->download_count < 5) {
auth()->user()->increment('download_count');
$data = DB::table('products')->where('id', $id)->first();
$path = public_path('/storage/item/jpg/' . $data->jpg);
return response()->download($path);
}
dd('Next Day Download');
}

Trouble printing out image from public folder laravel

I want to show the image that I had just uploaded and only show it to those who have uploaded it. For example, user table contain jack, Emily and John, so if jack were to upload a file the image will show directly under him, but I don't know how to do it?
This is how it look like now:
Controller: (how I store the image)
public function store1(Request $request){
$this->validate($request, [
'file' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
if ($request->hasFile('file')) {
$image = $request->file('file');
$name = $image->getClientOriginalName();
$size = $image->getClientSize();
$destinationPath = public_path('/images');
$image->move($destinationPath, $name);
$userImage = new UserImage;
$userImage->name = $name;
$userImage->size = $size;
//dd($userImage);
$userImage->save();
}
view.blade.php
#foreach ($data as $object)
<b>Name: </b>{{ $object->name }}<br><br>
#endforeach
I saw people using this inside their blade.php, but I don't know what the $model is:
<img src="{{ asset('public/images/' . $model->image) }}">
Upload.blade.php (this is my upload page where user will upload their image)
{{ csrf_field() }}
<div class="form-group">
<label for="imageInput" class="control-label col-sm-3">Upload Image</label>
<div class="col-sm-9">
<input type="file" name="file">
</div>
</div>
<div class="form-group">
<div class="col-md-6-offset-2">
<input type="submit" class="btn btn-primary" value="Save">
</div>
</div>
</form>
There are many ways to do it.
You could either use Eloquent or using query builder of Laravel.
In your controller you should get all the images that the user uploaded.
Query builder approach :
//don't forget the namespace
`use DB;`
//in your function write this.
$images = DB::table('user_images')
->join('users', 'users.id', '=', 'user_images.user_id')
->where('users.id', '=', $id)
->get();
//use dd($images) to verify that the variable $images has data
//send $images in your view
in your view write a foreach loop like so:
#foreach($images as $image)
<img src="{{ asset('public/images/' . $image->name ) }}">
#endforeach

homestead laravel 5 : link Download file from storage

i am need hint link to download upload file, currently i am following this answer
here is my code
Routes file :
Route::get('getDownload/{remind_letter}',
['as'=>'downloadData',
'uses'=>'DockController#getDownload']);
Controller File :
public function getDownload($remind_letter)
{
$download = Dock::where('remind_letter','=',$remind_letter)->firstOrFail();
$file =Storage::disk('local')->get($download->remind_letter);
return (new response($file))->header('Content-Type', $entry->m1);
}
result file
<div class="row">
<div class="form-group">
<div class="col-xs-5">
<label class="col-sm-7">Remind Letter :</label>
<input type="text" name="remind_letter" value="{{$getData->remind_letter}}">
</div>
<div><a href="{{ route('downloadData',$getData->remind_letter) }}">
<button class="btn btn-success btn-sm">Download</button></a></div>
</div>
</div>
and the result link dock.start/star/getDownload/home/vagrant/Code/dock/storage/app/25/JTK/2015/Renewal License Kaspersky/Moonarch Security/tmp/phpQaGzoD.pdf
but the link is always show up error 404 and i can't download file
FYI when upload file i am using storage_path() function
it fix, i am wrong logic, when upload file it should using getFilename() function, $entry->filename = $filename->getFilename().$extension;

Categories