I have been using Laravel for a couple years and I'm stumped on this one. Using Laravel 5.4 with voyager. I have my own controller outside of the BREAD controller
Form:
<form method="POST" action="/admin/invites" accept-charset="UTF-8" class="form-edit-add">
<input name="_token" type="hidden" value="QgLgj5tG4RfD2CxCsqE2Qn5jcWfwQhsk5THT30vO">
<div class="panel-body">
<div class="form-group">
<label for="name">Business</label>
<input class="form-control" placeholder="Business Name" name="business_id" type="text">
</div>
<div class="form-group">
<label for="body">Referral Name</label>
<input class="form-control" placeholder="Referral Name" name="referral_name" type="text">
</div>
</div>
<input class="btn btn-primary width-100 mb-xs" type="submit" value="Save">
</form>
web routes:
Route::resource('/admin/invites', 'InviteController');
Controller:
public function store(Requests\InviteRequest $request)
{
DB::table('invites')->insert(
[
'user_id' => Auth::user()->id,
'business_id' => $request->business_id,
'referral_name' => $request->referral_name,
'url_token' => str_random(16)
]
);
return redirect('/admin/invites')->with([
'message' => "Successfully Added New",
'alert-type' => 'success',
]);
}
When I submit it creates 2 rows in the database. I don't have duplicate routes or controllers. My Request file is empty. I have an ID in the table that is auto increment with primary index.
Any thoughts or troubleshooting tips?
I think the main point you are missing here is that Voyager calls its store() twice. First, through AJAX to validate the fields and then again by normal form submit to store the BREAD to the database.
Take a look at the default store() implementation in Voyager:
public function store(Request $request)
{
$slug = $this->getSlug($request);
$dataType = Voyager::model('DataType')->where('slug', '=', $slug)->first();
// Check permission
Voyager::canOrFail('add_'.$dataType->name);
//Validate fields with ajax
$val = $this->validateBread($request->all(), $dataType->addRows);
if ($val->fails()) {
return response()->json(['errors' => $val->messages()]);
}
if (!$request->ajax()) {
$data = $this->insertUpdateData($request, $slug, $dataType->addRows, new $dataType->model_name());
return redirect()
->route("voyager.{$dataType->slug}.edit", ['id' => $data->id])
->with([
'message' => "Successfully Added New {$dataType->display_name_singular}",
'alert-type' => 'success',
]);
}
}
Notice the if (!$request->ajax()) condition, the first AJAX call would bypass that but the second call would get into it and store to the database.
So in short, you have to follow the same structure in your store() method. Perform your validations first. Then when it's time to save, put that code into the if (!$request->ajax()) condition.
your form has some issues:
<label for="name">Business</label>
<input class="form-control" placeholder="Business Name" name="business_id" type="text">
change label for to for="business_id
<label for="body">Referral Name</label>
<input class="form-control" placeholder="Referral Name" name="referral_name"
</div>
change label for to for="referral_name
change your store method to this:
public function store(Requests\InviteRequest $request) {
$this->validate($request, array(
'user_id' => 'required',
'business_id' => 'required',
'referral_name' => 'required',
));
DB::table('invites')->insert([
'user_id' => $request->user_id,
'business_id' => $request->business_id,
'referral_name' => $request->referral_name,
'url_token' => str_random(16),
// If you don't use timestamp delete these lines below
'created_at' => Carbon::now()->format('Y-m-d H:i:s'),
'updated_at' => Carbon::now()->format('Y-m-d H:i:s'),
]);
return redirect('/admin/invites')->with([
'message' => "Successfully Added New",
'alert-type' => 'success',
]);
}
see if it works.
Related
basically every time I submit the form, the page refresh, and no items are stored in the DB. Here's the code.
PodcastController
public function store(Request $request) {
$request->validate([
'title' => 'required',
'description' => 'required',
'image' => 'image|mimes:jpeg,png,jpg,webp|max:2048',
'audio' => 'audio|mimes:audio/mpeg',
'category' => 'required',
]);
if ($request->image) {
$imageName = uniqid() . '.' . $request->image->extension();
$request->image->move(public_path('podcast/images'), $imageName);
}
if ($request->audio) {
$audioName = uniqid() . '.' . $request->audio->extension();
$request->audio->move(public_path('podcast/audios'), $audioName);
}
Podcast::create([
'title' => $request->title,
'description' => $request->description,
'image' => $imageName,
'audio' => $audioName,
'category' => $request->category,
]);
return redirect()->route('podcast.list')->with('Success', 'Podcast Created!');
}
Route
Route::resource(
'podcasts',
App\Http\Controllers\PodcastController::class
);
create.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<div class="col-md-6">
<form action="{{ route('podcasts.store') }}" method="POST" enctype=multipart/form-data>
#csrf
<input class="form-control" type="text" name="title" placeholder="title">
<input class="form-control mt-4" type="textarea" name="description" placeholder="description">
<select name="category" class="form-control mt-4">
<option value="select" disabled>Are you a Creator or a User?</option>
<option value="news">News</option>
<option value="music">Music</option>
</select>
<label for="image" class="mt-3">Image</label>
<input type="file" class="form-control" id="image" name="image">
<label for="audio" class="mt-3">Audio</label>
<input type="file" class="form-control" id="video" name="audio">
<button type="submit" class="btn btn-primary mt-3">Submit</button>
</form>
</div>
</div>
#endsection
The page keep refreshing everytime I run submit. I don't know where is the problem.
You catching a failure while validating. After catching these validate errors, you should develop your code what to do.
https://laravel.com/api/9.x/Illuminate/Validation/ValidationException.html
try {
$request->validate([
'title' => 'required',
'description' => 'required',
'image' => 'image|mimes:jpeg,png,jpg,webp|max:2048',
'audio' => 'audio|mimes:audio/mpeg',
'category' => 'required',
]);
} catch (\Illuminate\Validation\ValidationException $e) {
// do something...
dd($e->errors());
}
I am trying to save an image into the database using Laravel. At the moment I am getting an error message:"Method App\Http\Controllers\ProductController::save does not exist." The desired output is to be able to store the image into the database in laravel along with my other product variables. I have included code of some parts I think is relevant to this question. I also don't have a save() method, it says it can't find a save() method.
ProductController#store
public function store(Request $request)
{
$this->validate($request, [
'productImage' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
if ($request->hasFile('productImage')) {
$image = $request->file('productImage');
$name = time().'.'.$image->getClientOriginalExtension();
$destinationPath = public_path('/images');
$image->move($destinationPath, $name);
$this->save();
}
$data = request()->validate([
'productName' => 'required',
'productLink' => 'required',
'productPrice' => 'required',
'productDescription' => 'required'
]);
$product = new Product([
'productName' => $request->get('productName'),
'productLink' => $request->get('productLink'),
'productPrice' => $request->get('productPrice'),
'productDescription' => $request->get('productDescription')
]);
$product->save();
return redirect('/pr');
}
createProduct.blade.php
<form action="/storeProduct" method="post" enctype='multipart/form-data'>
#csrf
<label for="productName">Product Name:</label><br>
<input type="text" id="productName" name="productName" autocomplete="off" value="{{
old('productName') }}"><br>
#error('productName') <p style="color: red">{{ $message }}</p> #enderror
<label for="productImage">Product Image:</label><br>
<input type="file" id="productImage" name="productImage" autocomplete="off" value="{{
old('productImage') }}"><br>
#error('productImage') <p style="color: red">{{ $message }}</p> #enderror
<label for="productLink">Product Link:</label><br>
<input type="text" id="productLink" name="productLink" autocomplete="off" value="{{
old('productLink') }}"><br>
#error('productLink') <p style="color: red">{{ $message }}</p> #enderror
<label for="productPrice">Product Price:</label><br>
<input type="decimal" id="productPrice" name="productPrice" autocomplete="off" value="{{
old('productPrice') }}"><br>
#error('productPrice') <p style="color: red">{{ $message }}</p> #enderror
<label for="productDescription">Product Description:</label><br>
<input type="text" id="productDescription" name="productDescription" autocomplete="off" value="
{{ old('productDescription') }}"><br>
#error('productDescription') <p style="color: red">{{ $message }}</p> #enderror
<input type="submit" value="Submit">
</form>
web.php
Route::post('/storeProduct', 'ProductController#store');
I still don't understand what is wrong with my code, and why it isn't storing the image, I was following what someone else has done on another stackoverflow question. I have my GitHub repository below if you want to see my full code.
https://github.com/xiaoheixi/blog
First of all, $this->save() calls a method named save of the ProductController. You don't have such a method in the controller and even if you have one, it's not a good practice and likely to be cause of error if you call controller's another method from the method of the same controller.
Consider below code;
// Get image file from response
$image_file = $request->file('productImage');
// Save uploaded image to `local` disk and get path
$image_path = $image_file->storeAs('images', time().'.'.$image_file->getClientOriginalExtension(), 'local');
// Create product record
Product::create([
'productName' => $request->get('productName'),
'productLink' => $request->get('productLink'),
'productPrice' => $request->get('productPrice'),
'productDescription' => $request->get('productDescription'),
'productImage' => $image_path,
]);
// No need to call `save()` function
Hope this helps you a little bit.
the error is due to this line :
$this->save();
It's trying to call a function save() who don't exist on your controller
I have managed to come to a fix for this question. Its my own question, and I am now uploading my own solution that fixes this problem. Big shoutout to ElektaKode for providing me the essential knowledge to perform this operation.
public function store(Request $request)
{
$data = request()->validate([
'productName' => 'required',
'productImage' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
'productLink' => 'required',
'productPrice' => 'required',
'productDescription' => 'required'
]);
$image_file = $request->file('productImage');
$image_path = $image_file->storeAs('images', time().'.'.$image_file->getClientOriginalExtension(), 'local');
$destinationPath = public_path('/images');
$name = time().'.'.$image_file->getClientOriginalExtension();
$image_file->move($destinationPath, $name);
$product = new Product([
'productName' => $request->get('productName'),
'productImage' => $image_path,
'productLink' => $request->get('productLink'),
'productPrice' => $request->get('productPrice'),
'productDescription' => $request->get('productDescription')
]);
$product->save();
return redirect('/pr');
}
Thanks for everyone's help and I hope I can help future Professional Experience students from Western Sydney University if they come across a client who requires an ecommerce website as well.
this error is accourding this code line $this->save() just delete it .
you also have another problem reacording a new product, you can just modify your method :
Product::create([
'productName' => $request->get('productName'),
'productLink' => $request->get('productLink'),
'productPrice' => $request->get('productPrice'),
'productDescription' => $request->get('productDescription'),
'image' => $name
]);
//there's no need to call save method
return redirect('/pr');
while using eloquent you don't have to call save method
be sure that you add all this column in your model fillable
I'm editing a Laravel script.
I want add a form option in admin panel
I put this codes:
for route:
Route::post('order-check/edit-order', [
'as' => 'admin.orders.details.change',
'uses' => 'OrderStatusController#change',
'middleware' => 'can:admin.orders.index',
]);
OrderStatusController:
public function change(Request $request){
$validatedData = $request->validate([
'id' => 'required',
'address' => 'required',
'city' => 'required',
'state' => 'required',
]);
$order = Order::findOrFail($request->id);
$order->billing_address_1 = $request->address;
$order->billing_city = $request->city;
$order->billing_state = $request->state;
$order->save();
return back()
->withInput()->withSuccess('OK');
}
And resources file:
<form method="POST" action="{{ route('admin.orders.details.change') }}">
<input name="id" value="{{ $order->id }}" hidden>
<input name="address" value="{{$order->address}}">
<input name="city" value="{{$order->city}}">
<input name="state" value="{{ $order->state }}">
<button type="submit">
In that resources file, I already compacted the $order variable.
Now when I click on the button,
The DELETE method is not supported for this route. Supported methods: POST.
error appears
But I have not used from delete method at all
you need add #csrf between form tag #csrf
Please help me, I'm trying to validate each row of the row that was highlighted with red in the form using the validate([]). If a user filled one of the columns in a row, and try to submit it with the other fields left unfilled, then it will prompt the user that the remaining fields are required to be filled. I have come up with various conditions but sadly none on them worked out,
this is my store function
public function store(Request $request){
$currentStatus = 0;
$data = $request->validate([
'to' => 'required',
'date' => 'date',
'address' => 'required',
'reference' => 'required',
'attention' => 'required',
'area' => 'required',
'project' => 'required',
'salesman' => 'required',
'location' => 'required'
]);
\App\Contract::create($data + ['status' => $currentStatus]);
return redirect('contracts/pendings');
first u need to create a FormRequest php artisan make:request MyControllerNameRequest
Then in MyControllerNameRequest define your rules
public function rules(): array
{
return [
'firstField' => ['required', 'int'],
'secondField' => ['required', 'int'],
'thirdFied' => ['required', 'int'],
'fourthField' => ['required', 'int'],
];
}
after go in to your controller and add MyControllerNameRequest like attribute in action
public function store(MyControllerNameRequest $request)
{
$model = Model::create($request->validated());
return redirect()->route('route.name');
}
or in some_name.blade.php add required
<input type="text" name="name" value="{{ old('value') }}" required>
I'm assuming that the names in HTML look like this:
<form method="post" action="{{ route('test') }}">
#csrf
<input type="text" name="data[0][quantity]">
<input type="text" name="data[0][unit]">
<input type="text" name="data[1][quantity]">
<input type="text" name="data[1][unit]">
<input type="submit">
</form>
You could try something like this in your controller.
$this->validate($request, [
'data.*.quantity' => 'sometimes|required_with:data.*.unit',
'data.*.unit' => 'sometimes|required_with:data.*.quantity',
]);
The required_with params accept multiples fields separated per comma, so you may have to pass all your fields in the validation. The sometimes validates only when it's passed values, so this may do the trick.
I have a simple registration where validation passes, but create doesn't fill up fullname and phone(I checked they are passed - by echoing).
I also tried by using request()->input('fullname'); but I got same result.
For login after storing values this auth()->login($user) and auth()->attempt() both fails.
I don't know since uniqid for password is same as stored....
public function register(Request $request) {
$this->validate($request, [
'fullname' => 'required|min:2|max:255',
'email' => 'required|email|unique:users',
'phone' => 'required'
]);
$passcode = uniqid();
$user = User::create([
'fullname' => $request->fullname,
'email' => $request->email,
'password' => bcrypt($passcode),
'phone' => $request->phone
]);
if(User::sendEmail($passcode, $request->email, $request->fullname)) {
if (auth()->login($user)) {
session()->flash('user', 'You have been logged in..');
session()->flash('data', request());
return redirect()->route('dashboard');
}
session()->flash('login', 'Not logged in.');
}
return redirect()->back();
}
<form action="{{ route('register') }}" method="POST">
{{ csrf_field() }}
<input type="text" name="fullname" placeholder="Full name">
<input type="text" name="email" placeholder="E-mail">
<input type="text" name="phone" placeholder="Phone">
<button type="submit">Continue</button>
</form>