Laravel save multi part form - php

I have a 3 part form that I want to be able to update the database after each submit. There is one table that holds all the fields below.
form1 asks for first and last name
form2 asks for email and phone
form3 asks for city and state
In my controller I have 3 separate functions to save each step of the form:
public function name(Request $request){
$lead = Lead::firstOrNew(123);
$lead->firstName = $request->get('firstName ');
$lead->lastName = $request->get('lastName');
$lead->save();
return redirect('/form2');
}
public function info(Request $request){
$lead = Lead::find(123);
$lead->email = $request->get('email');
$lead->phone = $request->get('phone');
$lead->save();
return redirect('/form3');
}
public function address(Request $request){
$lead = Lead::find(123);
$lead->city = $request->get('city');
$lead->state = $request->get('state');
$lead->save();
return redirect('/done');
}
Is there any way to combine that to one update function?

Just do conditional check, update the model and define redirect url:
public function info(Request $request) {
$lead = Lead::firstOrNew(123);
if ($request->has('firstName') && $request->has('lastName')) {
$lead->firstName = $request->get('firstName ');
$lead->lastName = $request->get('lastName');
$redirect = '/form2';
} else if ($request->has('email') && $request->has('phone')) {
$lead->email = $request->get('email');
$lead->phone = $request->get('lastName');
$redirect = '/form3';
} else if ($request->has('city') && $request->has('state')) {
$lead->city = $request->get('city');
$lead->state = $request->get('state');
$redirect = '/done';
}
$lead->save();
return redirect($redirect);
}
Also, you can probably do group update via update just make sure you whitelist the attributes in your model
public function info(Request $request) {
$lead = Lead::firstOrNew(123);
$lead->update($request->all());
if ($request->has('firstName') && $request->has('lastName')) {
$redirect = '/form2';
} else if ($request->has('email') && $request->has('phone')) {
$redirect = '/form3';
} else if ($request->has('city') && $request->has('state')) {
$redirect = '/done';
}
return redirect($redirect);
}
Or I'd better just add a redirect variable to your form like:
<input type="hidden" name="redirect" value="form1">
and simplify your controller method like:
public function info(Request $request) {
$lead = Lead::firstOrNew(123);
$lead->update($request->all());
return redirect($request->input('redirect'));
}

You could refactor the methods to call a common "update" function. See example code below.
public function name(Request $request){
$this->update(123, $request);
return redirect('/form2');
}
public function info(Request $request){
$this->update(123, $request);
return redirect('/form3');
}
public function address(Request $request){
$this->update(123, $request);
return redirect('/done');
}
private function update($id, $request) {
$lead = Lead::find($id);
foreach ($field as ['firstName', 'lastName', ...]) {
if ($request->has($field)) {
$lead->{$field} = $request->get($field);
}
}
$lead->save();
}

You can add a hidden field to all three forms (but with the name name, e.g form_name), and set their values to identify the form (form1, form2, form3) when it is submitted. Then in your controller, you check the value of the form_name field on the request to determine where you want to redirect to, like this:
public function info(Request $request) {
$lead = Lead::firstOrNew(123);
$lead->update($request->all());
//this will be from the hidden field (form_name)
$form_type = $request->get('form_name');
if ($form_type == 'form1') {
$redirect = '/form2';
} else if ($form_type == 'form2') {
$redirect = '/form3';
} else if ($form_type == 'form3') {
$redirect = '/done';
}
return redirect($redirect);
}

If you have the option for using javaScript then save the first and second form data on cookies or local storage and when the user reaches last part of the form then take data out of cookies or local storage then added with the last form, but keep these in the hidden input.

Given that HTTP requests are stateless (which means each request know nothing about the one before and after it), I would rather prefer you use sessions, so that you can be able to store information as you redirect from one form to the other. In that case, your code should look like so:
<?php
public function name(Request $request){
Session::put('nameData', $request->all()); //Store the info from form1 in session and redirect to form2
return redirect('/form2');
}
public function info(Request $request){
$validSessionData = Session::has('nameData');
if (!$validSessionData) { //Check if the user filled form1, if not, go back to form1
return redirect('/form1');
}
$nameAndInfo = Session::pull('nameData', []) + $request->all(); //Merge the info from form1 with info from form2. You could decide to keep them separate and merge later.
Session::put('nameAndInfo', $nameAndInfo);
return redirect('/form3');
}
public function address(Request $request){
$validSessionData = Session::has('nameAndInfo');
if (!$validSessionData) { Another check. You could also extend this by checking for form2 session data
return redirect('/form1');
}
$allData = Session::pull('nameAndInfo', []) + $request->all(); //Merge all session data
$lead = Lead::firstOrNew(123);
$lead->firstName = $allData['firstName'];
$lead->lastName = $allData['lastName'];
$lead->email = $allData['email'];
$lead->phone = $allData['phone'];
$lead->city = $allData['city'];
$lead->state = $allData['state'];
$lead->save();
return redirect('/done');
}

Related

i wanna check if client name doesn't repeat but doesn't work

public function insertclients(Request $request)
{
$client = new Clients();
$client->client_name = $request->input('client_name');
$client->client_society = $request->input('client_society');
$client->client_email = $request->input('client_email');
$client->client_address = $request->input('client_address');
$client->client_phone = $request->input('client_phone');
$client->client_fix = $request->input('client_fix');
if ($this->nameclient($request->input('client_name')) < 1) {
$client->save();
return response()->json($client);
} else {
return response()->json('error', 'Client name already exists'); }
// return redirect('clients')->with('flash_message', 'Client Addedd!');
}
public function nameclient(Request $request)
{
//check count of client name
$count = Clients::where('client_name', $request->input('client_name'))->get();
$clicount = $count->count();
return $clicount;
}
I have this method for add new client but i wanna check if the name don't repeat so i create other function who check the name of client and i call it in the ferst but doesn't work.
You are already sending the input with $this->nameclient($request->input('client_name')
so change your method to accept a string variable
public function nameclient($clientName)
{
return Clients::where('client_name', $clientName)->count();
}
Bonus:
Maybe this way it would be more readable
public function insertclients(Request $request)
{
if ($this->nameclient($request->input('client_name')) {
return response()->json('error', 'Client name already exists');
}
$client = new Clients();
$client->client_name = $request->input('client_name');
$client->client_society = $request->input('client_society');
$client->client_email = $request->input('client_email');
$client->client_address = $request->input('client_address');
$client->client_phone = $request->input('client_phone');
$client->client_fix = $request->input('client_fix');
$client->save();
return response()->json($client);
// return redirect('clients')->with('flash_message', 'Client Addedd!');
}
You can also use laravel Validation instead of using the method nameclient and add the other validation rules in it like required fields and such.
public function insertclients(Request $request)
{
$request->validate([
'client_name' => 'required|unique:clients|max:255',
]);
$client = new Clients();
$client->client_name = $request->input('client_name');
$client->client_society = $request->input('client_society');
$client->client_email = $request->input('client_email');
$client->client_address = $request->input('client_address');
$client->client_phone = $request->input('client_phone');
$client->client_fix = $request->input('client_fix');
$client->save();
return response()->json($client);
// return redirect('clients')->with('flash_message', 'Client Addedd!');
}

Pass argument to method

I have functions that I use in my Article model, they add likes to cookies for a specific article and record the time
public static function hasLikedToday($articleId, string $type)
{
$articleLikesJson = \Cookie::get('article_likes', '{}');
$articleLikes = json_decode($articleLikesJson, true);
// Check if there are any likes for this article
if (! array_key_exists($articleId, $articleLikes)) {
return false;
}
// Check if there are any likes with the given type
if (! array_key_exists($type, $articleLikes[$articleId])) {
return false;
}
$likeDatetime = Carbon::createFromFormat('Y-m-d H:i:s', $articleLikes[$articleId][$type]);
return ! $likeDatetime->addDay()->lt(now());
}
public static function setLikeCookie($articleId, string $type)
{
// Initialize the cookie default
$articleLikesJson = \Cookie::get('article_likes', '[]');
$articleLikes = json_decode($articleLikesJson, true);
// Update the selected articles type
$articleLikes[$articleId][$type] = today()->format('Y-m-d H:i:s');
$articleLikesJson = json_encode($articleLikes);
return cookie()->forever('article_likes', $articleLikesJson);
}
The php.blade page itself has buttons
Like Heart
Like Finger
Here are the routes web.php
Route::get('/article', function () {
$articleLikesJson = \Cookie::get('article_likes', '{}');
return view('article')->with([
'articleLikesJson' => $articleLikesJson,
]);
});
Route::get('article/{id}/like', 'App\Http\Controllers\ArticleController#postLike');
And the postLike() function itself in the controller
public function postLike($id) {
$article = Article::find($id);
$like = request('like');
if ($article->hasLikedToday($article->id, $like)) {
return response()
->json([
'message' => 'You have already liked the Article #'.$article->id.' with '.$like.'.',
]);
}
$cookie = $article->setLikeCookie($article->id, $like);
$article->increment('like_{$like}');
return response()
->json([
'message' => 'Liked the Article #'.$article->id.' with '.$like.'.',
'cookie_json' => $cookie->getValue(),
])
->withCookie($cookie);
}
In general, what is the problem, I have 2 types of likes that can be seen in php.blade, and the problem is to pass the choice of the type of like to the postLike() function, if in my function instead of $like I write 'heart', then everything will be work, but I need to determine which type we choose (heart or finger), tell me how this can be done?
You can use Laravel's Request object.
https://laravel.com/docs/8.x/requests#input
Like this:
use Illuminate\Http\Request;
public function postLike($id, Request $request)
{
$type = $request->input('type');
}

Laravel CustomRequest authorize, pass request data to validate the auth user customer id and the model id match

I'm trying to fix an if-else statement in the request for my controller. What I'm trying to do is: if the auth::user-companyID == $request-companyID then true else false; The companyID for the request is in a hidden field on the blade file.
CustomRequest
public function authorize()
{
$user = Auth::user();
if ($user->companyID == $request->companyID) {
return true;
} else {
return false;
}
}
Controller
public function edit(EquipmentRequest $request, $id)
{
$validated = $request->validated();
$user = Auth::user();
$equipment = EquipmentModel::where('id', '=', $id)->first();
$equipment->Year = $request->Year;
$equipment->Make = $request->Make;
$equipment->Model = $request->Model;
$equipment->Type = $request->Type;
$equipment->unitNumber = $request->unitNumber;
$equipment->AnnualInspectionDate = $request->AnnualInspectionDate;
$equipment->userID = $request->userID;
$equipment->companyID = $user->companyID;
$e = $equipment->save();
if ($e) {
$request->session()->flash('success', 'The equipment was successfully updated.');
} else {
$request->session()->flash('error',
'An error occurred while saving. Please refresh your browser and try again.');
}
return redirect()->route('equipmentlist');
}
This form worked before I started messing with it so I know the form is working correctly on the blade file. I'm not sure if you can pass the request data the way I'm doing it or if I have to do a construct to do it this way. I would really appreciate any advice.
use Illuminate\Http\Request;
public function authorize()
{
$user = auth()->user();
return $user->companyID === request()->companyID;
}

Transfer variable from one to another function in controller

I am using Laravel at this time to secure a page when a user enters their password on a modal form before it opens. I initialized a variable named $crypt, which is hidden in the form, to make every page unique (to prevent other people from opening the page with a URL).
I want to pass the $crypt data to the PDFView. How can I do that? I've tried a lot of things but none worked.
Error
Undefined variable: crypts
Route:
Route::get('/pdfview/{id}/', 'HomeController#pdfview')->name('pdfview');
Generated key code
<div style="display: none">{{ $crypt = str_random(10)}}
Controller
public function encryptslip(Request $request, $crypt)
{
$crypts = $crypt;
$id = $request->nip;
$pass = $request->password;
$nip = Auth::user()->nip;
if (Hash::check($pass, Auth::user()->password)) {
return redirect('/pdfview/' . $nip . '/', ['crypts' => $crypts])->with('crypt', $crypt);
} else {
return redirect('/home')->with('alert', 'Incorrect password');
}
}
public function pdfview(Request $request, $id)
{
$route = url()->current();
$month = Carbon::now()->month;
$periodeinput = DB::table('payrollinput')->where('nip', '=', $id)->orderBy('periode', 'desc')->pluck('periode')->implode('periode');
$periodehistory = DB::table('payrollhistory')->where('nip', '=', $id)->orderBy('periode', 'desc')->pluck('periode')->implode('periode');
// if ($periodeinput !== $month && $periodehistory !== $month) {
// return redirect('home')->with('alert', 'Slip gaji anda siap.');
// } else {
if (Auth::user()->nip == $id) {
$employees = MasterEmployee::where('nip', '=', $id)->first();
$payrollhistory = MasterPayrollHistory::where('nip', '=', $id)->where('periode', '=', $month)->first();
$payrollinput = MasterPayrollInput::where('nip', '=', $id)->where('periode', '=', $month)->first();
view()->share('employees', $employees);
view()->share('payrollhistory', $payrollhistory);
view()->share('payrollinput', $payrollinput);
view()->share('id', $id);
// calculation code
return view('pdfview', ['id' => $id])->with('id', $id)
->with('earningtotal', $earningtotal)
->with('deductiontotal', $deductiontotal)
->with('takehomepay', $takehomepay)
->with('total', $total);
} else {
return redirect('home')->with('alert', 'Sorry it is personally confidential, you are not able to see it.');
}
}
View
<div><{{$crypts}}</div>
when you use return redirect() method that variable is passed to the view as a session variable and in the blade it must be called form
<div>{{session('crypts')}}</div>
to convert this session variable on $request
{{Form:hidden('crypts', json_encode(session('crypts'))}}

POST 500 (Internal Server Error) - Laravel and Ajax

I want to send post request with ajax to controller in laravel. The ajax request send two input arguments and I want controller to find the column in the database with the first argument and then to set the name attribute with the second input argument. But I have this error message Creating default object from empty value
Ajax function:
$('#saveUserProfile').on('click', function () {
var $finduser = $('input[name=findUser]').val();
var $name = $('input[name=userprofilename]').val();
$.ajax({
type:"POST",
url:'/code/task1/public/updateUser',
data: {
'name' : $name,
'finduser' : $finduser,
// 'email' : $email,
},
success:function(data){
$("#input1").val(data[0].name);
}
});
});
and the function in my controller
public function updateUser(Request $request){
$return_array = array();
$findUserInput = $request->get('finduser');
$user = User::where('name',$findUserInput) -> first();
$user->name = $request->get('name');
$user->save();
$data = DB::select("SELECT * FROM users where name='$findUserInput'");
if(count($data) > 0){
foreach($data as $da){
$return_array[] = $da;
}
}
return $return_array;
}
Update: I also make ajax function and controller for finding user which is working good.
ajax function:
$('#buttonFindUser').on('click', function () {
var $name = $('input[name=findUser]').val();
$.ajax({
type:"GET",
url:'/code/task1/public/findUser',
data: {
'name' : $name,
},
success:function(data){
$("#input1").val(data[0].name);
$("#input2").val(data[0].email);
$("#input3").val(data[0].created_at);
}
});
});
Function in my controller:
public function findUser(Request $request){
$return_array = array();
$findUserInput = $request->get('name');
$data = DB::select("SELECT * FROM users where name='$findUserInput'");
if(count($data) > 0){
foreach($data as $da){
$return_array[] = $da;
}
}
return $return_array;
}
Any ideas?
But I have this error message Creating default object from empty value
What's happening is that you are trying to save a user that doesn't exist. You need to check if the $user is null or not in your controller. Right now, the user couldn't be found with the provided name so $user becomes null.
So, you can modify your code to do a null check on $user like so:
public function updateUser(Request $request){
$return_array = array();
$findUserInput = $request->get('finduser');
$user = User::where('name',$findUserInput) -> first();
if(!$user)
return response()->json(['status'=>false,'Description' => 'User could not be found.']);
$user->name = $request->get('name');
$user->save();
$data = DB::select("SELECT * FROM users where name='$findUserInput'");
if(count($data) > 0){
foreach($data as $da){
$return_array[] = $da;
}
}
return $return_array;
}
Here's the null check:
if(!$user)
return response()->json(['status'=>false,'Description' => 'User could not be found.']);
When we don't have a valid user, we just reply back with a json response stating that it couldn't be found.
Update:
Seeing as your input is not being retrieved in the controller, you need to make some changes in JS:
First, you are doing a post request and I cannot see a CSRF token. To add it, follow this answer: https://stackoverflow.com/a/37582060/6270112
So, your data will now become:
data: '_token=' + $('#token').val() + '&name=' + $name + '&finduser=' + $finduser
Also, as aleksejjj mentioned, you need to fix your jquery selectors as well. So, your existing selectors:
var $finduser = $('input[name=findUser]').val();
var $name = $('input[name=userprofilename]').val();
will become:
var $finduser = $('input[name^="findUser"]').val();
var $name = $('input[name^="userprofilename"]').val();
Next, in your controller you need to replace $request->get(...) with $request->input(...).
$findUserInput = $request->get('finduser');
will become
$findUserInput = $request->input('finduser');
and repeat the same with the name field as well.
You need to check your user exist
$user = User::where('name', $findUserInput)->first();
if($user)
{
$user->name = $request->get('name');
$user->save();
}
change this code
$user = User::where('name',$findUserInput) -> first();
to
$user = User::where('name','=',$findUserInput) -> first();
I hope this will work. :)

Categories