File uploader gives null when i want to sent it to my database - laravel

I was trying to make a file uploader in laravel. But when i want to send it to database it have a null value when i send it to the controller. I don't know where I have to go to with this problem to fix it.
My view:
<div class="container">
<form method="POST" action="/admin/add-album/add">
#csrf
<label>Album name</label>
<input type="text" name="album_name" class="form-control">
<br>
<input id="file-upload" type="file" name="album_picture" accept="image/*">
<br>
<input type="submit" name="submit" class="form-control">
</form>
</div>
My controller:
public function addAlbumDatabase(Request $request)
{
request()->validate([
'album_name' => ['required'],
]);
$slug = $this->slugify(request('album_name'));
$user = \Auth::user();
dd($request->file('album_picture'));
if ($files = $request->album_picture) {
$destinationPath = 'public/images/';
$profileImage = date('YmdHis') . "." . $files->getClientOriginalExtension();
$files->move($destinationPath, $profileImage);
} else {
dd("mislukt om de image up te loaden");
}
Albums::create([
'user_id' => $user->id,
'album_name' => request('album_name'),
'album_profile_picture' => $profileImage,
'album_slug'=> $slug
]);
return redirect('admin/add-album');
}
my model:
class Albums extends Model {
protected $fillable = [
'user_id', 'album_name', 'album_profile_picture', 'album_slug'
];
}

Add enctype="multipart/form-data" in your form rule. So:
<form method="POST" action="/admin/add-album/add" enctype="multipart/form-data">

Related

Call to a member function getClientOriginalExtension() on null what should do?

public function store(Request $request)
{
$data = new product1();
$file = $request->file;
$filename= time().'.'.$file->getClientOriginalExtension();
$request->file->move('assets', $filename);
$data->file = $filename;
$data->name = $request->name;
$data->description = $request->description;
$data->author = $request->author;
$data->comment = $request->comment;
$data->save();
return redirect()->back();
}
View:
<form action="{{ url('uploadproduct') }}" method="post" enctype="multipart/form-data">
#csrf
<div class="form-group">
<input class="form-control" name="comment" placeholder="Write comment" type="text" style=" width: 50%;">
<input class="btn btn-primary" type="submit" value="Done" style=" width: 20%;">
</div>
</form>
$file is null when trying to get its properties.
You can either condition the process to the existence of $file (in case that the 'file' input is not required), or simply check what is happening that input value is null when requesting it.
Maybe there's no <input type="file" name="file"> in your form...
Or maybe your form has no enctype="multipart/form-data" property that allows you to submit files.
I DO also recommend you to validate your request before processing the data: https://laravel.com/docs/8.x/validation
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'file' => 'required'
]);
if ($validator->fails()) {
return Redirect::back()->withErrors($validator)->withInput();
}
// Here you start processing your inputs
}

Get product id to store attachments accordingly

I currently have the add attachment button for each product on the product list page. After clicking the button, will proceed to add attachment form. How do I get the current product ID from the product table in order to store the attachment data into the attachment table?
Route
Route::post('/store/{product}', 'AttachmentController#store')->name('attachment.store');
Product Model
public function attachment()
{
return $this->hasMany(Attachment::class, 'product_id', 'id');
}
Attachment Model
public function product()
{
return $this->belongsTo(Product::class, 'product_id');
}
Controller
public function create()
{
return view('document.create', ['prod' => Product::select('id', 'name')->get()]);
}
public function store(Request $request, Product $product) {
$data['product_id'] = $product->id;
$data = $request->validate([
'file' => 'required',
'file.*' => 'mimes:csv,xlsx,pdf,docx',
]);
$attachmentData = [];
if($request->hasFile('file'))
{
foreach($request->file('file') as $file) {
$path = public_path('storage/attachments/'.$request->product_id);
$fileName = time().'-'.$file->getClientOriginalName();
$file->move($path, $fileName);
$attachmentData[] = $fileName;
}
$data['file'] = json_encode($attachmentData);
}
$attachment = Attachment::create($data);
return redirect()->route('product.index')->with('success','Attachment added successfully');
}
Blade View
<form method="POST" action="{{route('attachment.store')}}" enctype="multipart/form-data">
#csrf
<h3><b>Add Attachment</b></h3>
<input type="submit" class="btn btn-primary mr-2" value="Save">
<div class="row">
<h4 class="card-title">General</h4>
<input type="text" name="product_id" value="{{ $product->id ?? '' }}" hidden>
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" class="form-control" name="name" required>
</div>
<div class="form-group">
<label>Attachment </label>
<div class="input-group-append">
<label for="attachment" class="btn btn-info">Upload</label>
<input id="attachment" type="file" name="file[]" multiple required>
</div>
</div>
</div>
</form>
You have to use form action like below
<form method="POST" action="{{route('attachment.store',['product'=>$product->id])}}" enctype="multipart/form-data">

Laravel - search submit is not redirecting to the next blade

In my Laravel-5.8, I am using the index as the search page:
public function index()
{
$search = '';
if (request('search'))
{
$search = request('search');
return redirect()->route('client', [$search]);
}
return view('index', ['search' => $search]);
}
public function client($clientid)
{
$myparam = $clientid;
$client = new Client();
$res = $client->request('GET','https://example/{$myparam}', [
'query' => ['key' => 'jkkffd091']
])->getBody();
$geoLocation = json_decode($res->getContents(), true);
return view('client', [
'geoLocation' => $geoLocation
]);
}
Here is my index blade:
<form method="GET" action="{{ route('index', ['search' => $search]) }}">
<div class="field">
<label class="label blog-sidebar-label" for="search">
<input class="search-field" type="search" name="search" id="search" placeholder="client id..." value="{{ $search }}">
</label>
</div>
</form>
I have this route:
Route::get('/', [HomeController::class, 'index'])->name('index');
Route::get('client/{search}', [HomeController::class, 'client'])->name('client');
What I want to achieve is that when the search button for index is submitted with the clientid in the text input field, it should take the clientid as parameter and pass it to client controller. Also redirect to client blade.Then when nothing is in the text input field, it should indicate.
But it is not redirecting. How do I achieve this?
Thanks
Probably you want to submit without a submit button. Then you can submit with JS :
<form id="submitForm" method="GET" action="{{ route('index', ['search' => $search]) }}">
<div class="field">
<label class="label blog-sidebar-label" for="search">
<input class="search-field" type="search" name="search" id="search" placeholder="client id..." value="{{ $search }}">
</label>
</div>
</form>
<!-- JS code below -->
<script>
document.getElementById("search").onchange = function() {myFunction()};
function myFunction() {
document.getElementById("submitForm").submit();
}
</script>

Call to a member function getClientOriginalName() on array

I have a multiple image. When I upload multiple image. I get this error.
Call to a member function getClientOriginalName() on array
my blade
<form action="{{ route('design-studios.store') }}" method="post" enctype="multipart/form-data">
#csrf
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title" value="{{ old('title') }}">
</div>
//......
<div class="form-group">
<fieldset class="border p-3">
<legend>Slideshow</legend>
<div class="form-group">
<label for="sliders">Image</label>
<input id="sliders" name="sliders[]" type="file" multiple class="form-control">
</div>
</fieldset>
</div>
</form>
My Controller.
public function store(Request $request)
{
$design_studio = new DesignStudio;
$design_studio->user_id = 1;
$design_studio->title = $request->title;
$design_studio->lang = $request->lang;
$design_studio->body = $request->body;
if($request->has('image')) {
$image = $request->file('image');
$filename = $image->getClientOriginalName();
$image->move(public_path('images/design-studio'), $filename);
$design_studio->image = $request->file('image')->getClientOriginalName();
}
if ($sliders = $request->file('sliders')) {
foreach ($sliders as $slider) {
$filename = $slider->getClientOriginalName();
$slider->move(public_path('images/design-studio'), $filename);
$design_studio->sliders = $request->file('sliders')->getClientOriginalName();
}
}
$design_studio->save();
$design_studio->categories()->attach($request->category);
return redirect()->route('design-studios.index');
}
My Model
protected $casts = [
'sliders' => array()
];
I get this error.
Call to a member function getClientOriginalName() on array
Here you need to call that method on the file you are looping through instead of trying to call it on the array of files.
$design_studio->sliders = $slider->getClientOriginalName();

Laravel Image Upload not saving to public folder

I am struggling with this image upload system.
It is supposed to upload an image that will be attached to a post (each post has 1 image).
Everything seems to be working fine, the problem is that when I check the database for the image path, I see a path to a random temporary file and the image doesn't even get uploaded to the right folder inside the app public folder.
Check the logic below:
PostController.php
public function store(Request $request)
{
$post = new Post;
$request->validate([
'title' => 'required',
'description' => 'required',
'slug' => 'required',
'message' => 'required',
'user' => 'required',
'post_image' => 'image|mimes:jpeg,png,jpg,gif|max:2048'
]);
if ($request->has('post_image')) {
$image = $request->file('post_image');
$name = Str::slug($request->input('title')).'_'.time();
$folder = '/uploads/images/';
$filePath = $folder . $name. '.' . $image->getClientOriginalExtension();
$this->uploadOne($image, $folder, 'public', $name);
$post->post_image = Storage::url($filePath);;
}
Post::create($request->all());
return \Redirect::to('admin')->with('success','Great! Post created successfully.');
}
UploadTrait.php
trait UploadTrait
{
public function uploadOne(UploadedFile $uploadedFile, $folder = null, $disk = 'public', $filename = null)
{
$name = !is_null($filename) ? $filename : Str::random(25);
$file = $uploadedFile->storeAs($folder, $name.'.'.$uploadedFile->getClientOriginalExtension(), $disk);
return $file;
}
}
Post.php (model)
class Post extends Model
{
protected $fillable = [
'title',
'description',
'slug',
'message',
'user',
'post_image'
];
public function getImageAttribute(){
return $this->post_image;
}
}
Create.blade.php
<form action="{{ route('blog.store') }}" method="POST" name="add_post" role="form" enctype="multipart/form-data">
{{ csrf_field() }}
<h1>New Post</h1>
<div role="separator" class="dropdown-divider"></div>
<div class="form-row">
<div class="form-group col-12 col-md-6">
<label for="title">Post Title</label>
<input type="text" autocomplete="off" class="form-control" id="title" name="title" placeholder="Your post title" required>
<span class="text-danger">{{ $errors->first('title') }}</span>
</div>
<div class="form-group col-12 col-md-6">
<label for="slug">Slug</label>
<input type="text" autocomplete="off" class="form-control" id="slug" name="slug" placeholder="Write post slug" required>
<span class="text-danger">{{ $errors->first('slug') }}</span>
</div>
</div>
<div class="form-row">
<div class="form-group col-12 col-md-12">
<label for="description">Post Description</label>
<textarea class="form-control" id="description" name="description" placeholder="Enter a small description for your post" required></textarea>
<span class="text-danger">{{ $errors->first('description') }}</span>
</div>
</div>
<div class="badge badge-warning badge-pill">Message</div>
<div role="separator" class="dropdown-divider"></div>
<div class="form-row">
<div class="form-group col-md-12">
<textarea class="form-control" col="4" id="message" name="message"></textarea>
<span class="text-danger">{{ $errors->first('message') }}</span>
</div>
</div>
<input type="hidden" value="{{ Auth::user()->name }}" name="user">
<input id="post_image" type="file" class="form-control" name="post_image">
<button type="submit" class="btn btn-warning btn-block">Create Post</button>
</form>
Thank you for your help!
Regards,
Tiago
You can use directly the functions provided by Laravel itself
$image_path = Storage::disk('public')->putFile('folders/inside/public', $request->file('post_image'));
Notice Storage::disk('public') that specifies the public folder.
Then you can update your request array with $request['image_path'] = $image_path and save it like you're currently doing or you cant still use your $post = new Post; and set every input data like $post->title = $request->title; then save like $post->save();
You did not save the image path in the database on the created post
$post = new Post; //here you have created an empty Post object
...
$post->post_image = Storage::url($filePath); //here you assigned the post_image to the empty object.
Post::create($request->all());// here you create a new POST object with the request data, which does not contain the post_image
Thank you David! I managed to correct the path that gets saved to the database, but the files are not getting uploaded (even though the path in database says /uploads/images/something.png, when i check the folder, the image is not there.. there is not even an uploads folder. This is the method I have now with your suggestions:
public function store(Request $request)
{
$request->validate([
'title' => 'required',
'description' => 'required',
'slug' => 'required',
'message' => 'required',
'user' => 'required',
'post_image' => 'image|mimes:jpeg,png,jpg,gif|max:2048'
]);
if ($request->has('post_image')) {
$image = $request->file('post_image');
$name = Str::slug($request->input('title')).'_'.time();
$folder = '/uploads/images';
$filePath = $folder . $name. '.' . $image->getClientOriginalExtension();
$this->uploadOne($image, $folder, 'public', $name);
$image_path = Storage::disk('public')->putFile('uploads/images', $request->file('post_image'));
$request['image_path'] = $image_path;
}
$post = new Post;
$post->title = $request->title;
$post->description = $request->description;
$post->slug = $request->slug;
$post->message = $request->message;
$post->user = $request->user;
$post->post_image = $request->image_path;
$post->save();
return \Redirect::to('admin')->with('success','Great! Post created successfully.');
}
Input in form
<form method="POST" enctype="multipart/form-data" action="/url">
<input id="category_logo" type="file" class="form-control" name="category_logo">...
Code in controller
$category = Category::find($id);
if($request->has('category_logo')) {
$image = $request->file('category_logo');
$category->category_logo = $image->getClientOriginalName();
$image->move(public_path('img/logo'), $image->getClientOriginalName());
}
$category->save();
Works for me!

Resources