Laravel 5.5 Check User exist with three param in two tables - php

I develop the register module , i want to check users registered in my web app with email , nationalCode or mobile , i have two tables , users and userInfo , i store email in users table and i store nationalCode and mobile in userInfo table , i want to write code to detect if email or nationalCode or mobile of the user exist in my two tables , i show warning text that user have registered in my site, please help me to do this job,
I use step form and i write ajax to call method to do this task,
note that it may be possible teh user have three matches or just one of them is matched
thanks for your helps :)
Here is the ajax code :
$.ajax({
url: url',
type: 'POST',
data: {
_token: CSRF_TOKEN ,
code:code,
email:email,
mobile:mobile,
},
dataType: 'JSON',
success:function(data) {
//return data
}
});
and here is my method is controller
public function checkUser(Request $request)
{
$email = $request->email;
$mobile = $request->mobile;
$code = $request->code;
//here the query to detect user exist with three params
}

Let's say you have your relationships defined as follows:
class User extends Model
{
public function info()
{
return $this->hasOne(UserInfo::class);
}
}
class UserInfo extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
... then you can check the existence of this user with something like this.
$user = User::where('email', $request->email)
->whereHas('info', function($query) use($request) {
$query->where('mobile', $request->mobile)
->where('code', $request->code);
})
->exists();
// user will be false if there's no record matching those parameters
Alternatively, if you don't have your relationships defined, then you probably need to do something like this instead.
$user = User::where('email', $request->email)->exists();
$info = UserInfo::where([
'mobile' => $request->mobile,
'code' => $request->code
])->exists();
if($user && $info) {
// user exists
}
I would still prefer to go with option one :)

If you put unique identifier in you table, database will automatically detect it and return the error, but its not good practice to let database to handle that,
If you want to use Eloquent then the query would look like this
public function checkUser(Request $request)
{
$email = $request->email;
$mobile = $request->mobile;
$code = $request->code;
$user = User::query()->where('email', '=', $email)->orWhere('mobile','=',$mobile)
->orWhere('code', '=',$code)->get();
if($user) {
// User already exits
return;
}
}
But this validation for me is not good, Better is to use Laravel Requests
https://laravel.com/docs/5.7/validation#form-request-validation
To generate custom request use this command (php artisan make:request RequestName)
public function rules()
{
return [
'title' => 'required|unique:users',
'mobile' => 'required|unique:users',
'code' => 'required|unique:users',
];
}
Using the request is simple
public function checkUser(YourCustomRequest $request)
{
// Laravel will take care of all fields and check them if they exist in the database
}

Related

Laravel : Change data after update Request

I am using Select2 for create multiple data in database.
My Languages Field In Database:
English,French,Spanish
My Controller
public function store(UserCreateRequest $request)
{
$data = $request->all();
$data['languages'] = implode(',', $request['languages']);
User::create($data);
return redirect()->back()->with('message', 'Account Successfully Created');
}
But After Update The language field changes as follows
["English","French","Spanish"]
Update in controller
public function update(Request $request, $id)
{
$user = User::findOrFail($id);
$user->update($request->all());
return redirect()->back()->with('message', 'Account Successfully Updated');
}
I'm Using in_array() in edit Form For Showing Selected Data
You can create one methods, or rewrite you'r update methods
public function update(Request $request, $id)
{
$user = User::findOrFail($id);
$data = $request->all();
$data['languages'] = implode(',', $request['languages']);
$user->update($data);
return redirect()->back()->with('message', 'Account Successfully Updated');
}
But I think batter create relation user -> manyToMany -> language, table example
user {user_id, email, password}
user_language {user_language_id, user_id, language_id}
language {language_id, key, title}
For select get all from language.
For attach language to user use attach method. For get all language just call ->languages on user. And etc. Sorry for my English I hope you understand me.

Laravel exclude current user from array

Logic
I have store function and it's returning data of users in the group.
The person who saves this data is also included of group users.
Now I want to exclude s/he from group users when data returns.
code
I've commented the code so you can understand it better.
public function store(Request $request)
{
$user = $request->user(); // current user who should be excluded
$group = Group::where('id', $request->input('group_id'))->first();
$message = new GroupMessage;
$message->group_id = $request->input('group_id');
$message->user_id = $user->id;
$message->note = $request->input('newMessage');
$message->message_id = $request->input('message_id');
$message->save();
// returning data
// 'user' is current user (also available in 'group.users')
// remove current 'user' from ('group.users')
$ms = GroupMessage::where('id', $message->id)->with(['user', 'group', 'group.users'])->first();
return response()->json([
'data' => new NotesResource($ms),
'message' => 'Message sent successfully.'
], 200);
Log::info('message data sent.');
broadcast(new MessageSent($message))->toOthers();
}
Screenshot
here is how code above returns data
Any idea?
You can exclude this User using Eager Loading Constraints:
$ms = GroupMessage::where('id', $message->id)
->with(['user', 'group.users' => function ($query) use ($user) {
$query->where('users.id', '<>', $user->id);
}])->first();
Laravel 7.x Docs - Eloquent - Relationships - Constraining Eager Loads

Call to a member function save() on null

I am using the following code
public function show()
{
$id = Auth::user()->id;
$usuario = User::find($id);
$mascotin = Mascota::all();
$mascota = Mascota::find($id);
$mascota->save();
$cant_mascota = Mascota::count();
$cant_pregunta = Pregunta::count();
return view('usuario.show',[
'usuario' => $usuario,
'mascotin' => $mascotin,
'mascota' => $mascota,
'cant_mascota' => $cant_mascota,
'cant_pregunta' => $cant_pregunta,
]);
}
It gives me this error
Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_ERROR).Call to a member function save() on null
User Model
public function mascotas(){
return $this->hasMany('App\Mascota','user_id', 'id');
}
Mascota Model
public function usuario()
{
return $this->belongsTo('App\User', 'id','user_id');
}
Route
Route::get('/home', 'UserController#show')->name('home');
Hope you guys can help me, I'm new in laravel and I have like 1 day tring to solve this problem
$usuario = Auth::user();
$id = $usuario->id; // you already have user from Auth or Request, does not need to request database again
$mascotin = Mascota::all();
$mascota = $mascotin->find($id); // you can search in collection
//if you want to create Mascotin if it doesn't exists use Mascota::firstOrCreate(['id' => $id]);
if(!$mascota){
throw new \Exception('Mascota not found', 404); //if $mascota is mandatory
}
$mascota->save(); // this does not have place here unless you are changing $mascota before that
$cant_mascota = $mascotin->count();
$cant_pregunta = Pregunta::count();
Also you should add auth middleware to this route. Only logged users should see it.
I am not sure what "Mascota" means (it will be good to use english when you share your code) but it is not good to have the same id as user. Better use relationships.

Hash password before saving with Laravel Backpacker

A simple question: how do I modify (hash) the request value before saving it with Laravel Backpacker CRUD admin?
As far as i understand, it should be done somewhere before these methods are executed in the crud controller:
public function store(StoreRequest $request)
{
return parent::storeCrud();
}
public function update(UpdateRequest $request)
{
return parent::updateCrud();
}
but I have no idea how to do it correctly.
Edit: the request is not a Request object, but rather StoreRequest or UpdateRequest that looks something like this:
Fix:
public function update(UpdateRequest $request)
{
// Hash password before save
if (!empty($request->password)) {
$request->offsetSet('password', Hash::make($request->password));
}
return parent::updateCrud($request); // <-- Pass the modified request, otherwise the CRUD reads it again from post data
}
You can update $request values using the offsetSet method
$request->offsetSet('name', $newName);
Edit: To update user password you can do something like this:
public function update_password(Request $request)
{
$user = User::find(Auth::user()->id);
if (Hash::check($request->old_password, $user->password)) {
$user->fill([
'password' => Hash::make($request->password)
])->update();
return redirect()->back()->with('message' => 'Your password has been updated.');
}
else {
return redirect()->back()->with('message' => 'The password entered do not match our records.');
}
}
I did not check the code but it should work. Now update it to your needs.
If you're asking about how to modify data in $request variable, you can just do this:
$request->property = 'New value';
Also, you can add data to reuqest itself (not into variable):
request()->request->add(['key' => 'value']);

Passing Data to view in a Redirect request to prevent double submission

I am trying to prevent double submission through the back button in a simple voting application
I was doing this before. After voting it returns this view
return View::make('votes.votesresults')->with('candidates',$candidates)->with('count',$count);
This passes two variables to votesresult view but unfortunately if someone clicks the back button they can resubmit their votes. I looked around and came across the PRG pattern. Am supposed to use a redirect to prevent this. So i tried this
return Redirect::route('votes.votesresults')->with('candidates',$candidates)->with('count',$count);
Here are my controllers
public function votesuccess()
{
$rules = array(
'name' => 'required'
);
$validator = Validator::make(Input::all(),$rules);
if ($validator->fails()) {
return Redirect::to('votes/index')
->withErrors($validator)
->withInput(Input::except('password'));
} else {
// store
$vote = new Vote;
$candidates = Candidate::all();
$candidate_id =Input::get('name');
$candidate = Candidate::find($candidate_id);
$vote = $candidate->votes()->save($vote);
//$count = DB::table('votes')->where('candidate_id','=','$candidate_id')->count();
$count = DB::table('votes')->count();
// redirect
Session::flash('message', 'Successfully Cast your vote!');
//return View::make('votes.voteresults')->with('candidates', $candidates)->with('count',$count);
return Redirect::route('voteresults')->with('candidates', $candidates)->with('count',$count);
}
}
public function voteresult()
{
$candidates = Candidate::all();
return View::make('votes.voteresults');
}
My routes are like this
Route::post('votesuccess', array('as' => 'votesuccess', 'uses'=>'VoteController#votesuccess'));
Route::get('voteresults', array('as' => 'voteresults', 'uses'=>'VoteController#voteresult'));
This does not work because it returns undefined variable: candidates. My results view requires these variables. So how do I implement the PRG pattern correctly such that I prevent double submission while being able to pass data to my view
You are redirecting to the route named voteresults, which is handled by the voteresult function and not the votesuccess function.
In your votesuccess function, you should load the view and include the candidates variable in that view. You can access the candidates variable stored in the session by using Session::get('candidates').
It would help to see you voter results view to see what's going on there, and where/how you've put in logic to avoid duplicate submission. Are you concerned about accidental re-submissions, or just multiple submissions from the same user? If the latter, then you would need to build in some logic that limits a user to only 1 vote. You could do this by check if the user has a related vote.
if ( ! $candidate->votes() ) {
// no votes exist, proceed with storing vote
}
Below is you controller refactored a bit:
public function votesuccess()
{
$rules = array(
'name' => 'required'
);
$validator = Validator::make(Input::all(),$rules);
if ($validator->fails()) {
return Redirect::back('votes/index')
->withErrors($validator)
->withInput(Input::except('password'));
} else {
// store
$candidate = Candidate::find(Input::get('name'));
$vote = $candidate->votes()->save(new Vote);
// redirect
Session::flash('message', 'Successfully Cast your vote!');
return Redirect::route('voteresults');
}
}
public function voteresult()
{
$candidates = Candidate::all();
$count = DB::table('votes')->count();
return View::make('votes.voteresults', compact('candidates', 'count'));
}

Categories