change password when is set - laravel

i want to change password in my update method , when is $request->data['password'] is set and is not null
if is not set old password be replace
this is my code but i'm faced with error !
$user=Model::whereId($id)->update([
"updated_at" => Carbon::now(),
"department_id" => $department,
"username" => $request->data['username'],
'password'=>isset($request->data['password'])?bcrypt($request->data['password']):$user->password,
]);

You can use this solution
$data = [
"updated_at" => Carbon::now(),
"department_id" => $department,
"username" => $request->data['username'],
];
if (! empty($request->data['password'])) {
$data["password"] = bcrypt($request->data['password']);
}
$user = Model::whereId($id)->update($data);

isset checks if the password field exists in the request but if it exists there and is null then it will still pass through. Also your ternary is the other way around.
you can use empty for what you are trying to achieve like:
'password'=>!empty($request->data['password'])?bcrypt($request->data['password']):$user->password,
But if you want to use the ternary there then you must have retrieved your user model before that so your fallback actually has the value of the user password in the database. A similar approach is:
$user=Model::whereId($id)->first();
$user->updated_at = Carbon::now();
$user->department_id => $department;
$user->username = $request->data['username'];
if(!empty($request->data['password']){
$user->password=bcrypt($request->data['password']);
}
$user->save();
That way you don't need a fallback. Returning the user model with the latest changes you can use the fresh() function after you save()
return $user->fresh()

Use "dot" notation to access the arrays (like name="data['password']") :
$password = $request->input('data.password');
$model = Model::find($id);
$model->username = $request->input('data.username');
$model->department_id = $department;
if($password){
$model->password = Hash::make($password);
}
$model->save();
You may use the has method to determine if a value is present on the request. The has method returns true if the value is present on the request:
if ($request->has('data.password')) {
//
}
Or use whenHas. The whenHas method will execute the given closure if a value is present on the request:
$request->whenHas('data.password', function ($input) {
//
});

Related

Hash password after Validator::make

I want to hash the password after validating the data.
My code:
public function create(Request $request){
$data = Validator::make($request->only(['name', 'email', 'password']), [
'name' => 'required|min:3:max:20',
'email' => 'required|email|unique:users',
'password' => 'required|min:6',
]);
if ($data->fails()) {
//Do something
}else{
User::create($data);
}
}
So how to hash the password after validation?
I tried to override the password inside $data, But it's not working
$data->safe()->only('password') = Hash::make($data->safe()->only('password'));
I can't use $request['password'] as I won't be able to validate it and check if it's empty ..etc.
An alternative approach would be to use an Eloquent Mutator to automatically hash the password field when it is set.
// User Model
public function setPasswordAttribute($value): void
{
$this->attributes['password'] = Hash::make($value);
}
I personally like this approach because you won't have to worry about it in the controllers. You can just set it once and forget about it. :)
The quick answer to your question would be to use the Eloquent make function.
$user = User::make($data);
$user->password = Hash::make($password);
$user->save();
Where $password is where ever you have the password stored. In your case:
$password = $data->safe()->only('password')
There may be a more efficient way, based on your exact intent. In general, the above solution will work.
The make function creates an Eloquent model, but does not store it in the database. That's why you can edit the values and then call $user->save()
Use a mutator method to set the password. Override the method by adding:
public function setPasswordAttribute($value)
{
$this->attributes['password'] = 'some random password generator';
}
there is document:
https://laravel.com/docs/8.x/eloquent-mutators#defining-a-mutator

How to change value of a request parameter in laravel

I need to change value of my request parameter like this:
$request->name = "My Value!";
I use this code but does not work:
$request->offsetSet('img', $img);
Try to:
$requestData = $request->all();
$requestData['img'] = $img;
Another way to do it:
$request->merge(['img' => $img]);
Thanks to #JoelHinz for this.
If you want to add or overwrite nested data:
$data['some']['thing'] = 'value';
$request->merge($data);
If you do not inject Request $request object, you can use the global request() helper or \Request:: facade instead of $request
Use merge():
$request->merge([
'user_id' => $modified_user_id_here,
]);
Simple! No need to transfer the entire $request->all() to another variable.
Read more about Laravel's merge() here:
https://laravel.com/docs/collections#method-merge
If you need to customize the request
$data = $request->all();
you can pass the name of the field and the value
$data['product_ref_code'] = 1650;
and finally pass the new request
$last = Product::create($data);
If you need to update a property in the request, I recommend you to use the replace method from Request class used by Laravel
$request->replace(['property to update' => $newValue]);
Use add
$request->request->add(['img' => $img]);
If you use custom requests for validation, for replace data for validation, or to set default data (for checkboxes or other) use override method prepareForValidation().
namespace App\Http\Requests\Admin\Category;
class CategoryRequest extends AbstractRequest
{
protected function prepareForValidation()
{
if ( ! $this->get('url')) {
$this->merge([
'url' => $this->get('name'),
]);
}
$this->merge([
'url' => \Str::slug($this->get('url')),
'active' => (int)$this->get('active'),
]);
}
}
I hope this information will be useful to somebody.
It work for me
$request = new Request();
$request->headers->set('content-type', 'application/json');
$request->initialize(['yourParam' => 2]);
check output
$queryParams = $request->query();
dd($queryParams['yourParam']); // 2
Great answers here but I needed to replace a value in a JSON request. After a little digging into the code, I came up with the following code. Let me know if I'm doing something dumb.
$json = $request->json()->all();
$json['field'] = 'new value';
$request->json()->replace($json);
Try that :
$request["name"] = "My New Value";
$request["img"] = $img;
It's worked in Laravel 8.
Also, make sure to update the model class.
Item
{
fillable=[
'img',
... // other attributes
];
}
in case of updating an item of object you can write the lines bellow
$Obj = $request->data;
$Obj['item'] = value;

Hash::check() return false in laravel 5

I'm just starting with laravel 5, I'm doing a simple login function to check if email and password passed by user matches with the email and password stored in the database. I've been reading the documentation ([https://laravel.com/docs/5.0/hashing1) but Hash::check($content['password'], $user->{'password'}) returns false always. My code looks like this.
When I create a new user I hash the password like that:
$content = json_decode($request->getContent(), true);
$user -> password = Hash::make($content['email']);
And my login function looks like that:
public function login(Request $request)
{
$content = json_decode($request -> getContent(), true);
$user = DB::table('users')->where('email', $content['email'])->first();
if (Hash::check($content['password'], $user->{'password'}))
{
// Redirect to dashboard
}
}
Thanks in advance!!
Actually you are hashing the email instead of password while creating the user. change the code from
$user->password = Hash::make($content['email']);
To
$user->password = Hash::make($content['password']);
i came up with same issue. check database users table, password field. make the size of the field to 60 or more. this fixed mine.
The facade Hash just will encrypt your data:
Hash::make('123456');
is the same that:
$password = bcrypt('123456');
to login a user you need to use AuthController functions:
Auth::attempt(['email' => 'test#test.com' , 'password' => Hash::make('password')]);
it's a example.
If you're receiving a request, you can add this method to login:
if(Auth::attempt(['email' => $request->email, 'password' => $request->password , 'active' => 1])){
flash()->success('Successfully logged in!');
return redirect('/');
}
the attempt function will hash your password field and will compare with database data.

Codeigniter update function doesn't work corectly

I have a problem with the update function. This code is updating all rows in database and i want to update only the row with the login username.The "password" is one that i logged in and i want to replace with password3. The problem is that password replace all rows(passwords) in my database.
function edit_member()
{
$new_member_update_data = array(
'password' => md5($this->input->post('password3'))
);
$this->db->where('password',$this->input->post('password'));
$update = $this->db->update('memberships',$new_member_update_data);
return $update;
}
Suppose you have logged in,then you will get the userId from session right..?So use it here like
function edit_member()
{
$new_member_update_data = array(
'password' => md5($this->input->post('password3'))
);
$this->db->where('iUserId',$this->session->userdata('iUserId'));
$update = $this->db->update('memberships',$new_member_update_data);
return $update;
}
Consider that iUserId will be the field that is unique or even a auto increment field.
Check column password value and $this->input->post('password') value
function edit_member()
{
$password = md5($this->input->post('password3');
$this->db->set('password',$password );
$this->db->where('password',$this->input->post('password'));
$this->db->where('id',$this->input->post('id'));
$update = $this->db->update('memberships');
return $update;
}
Check your Password value which is in DB, if that is encrypted by MD5 then you have to pass the encrypted value of password in WHERE clause.
function edit_member()
{
$password = md5($this->input->post('password3');
$this->db->set('password',$password );
$this->db->where('password',md5($this->input->post('password'));
$update = $this->db->update('memberships');
return $update;
}

Only update field if form value exists

I'm using Form Model Binding as such and updating my DB using the fill() and save() methods.
{{ Form::model($account) }}
{{ Form::text('name', null, array('class'=>'class')) }}
{{ Form::text('email', null, array('class'=>'class')) }}
{{ Form::password('password', array('class'=>'class')) }}
{{ Form::password('password_confirmation', array('class'=>'class')) }}
{{ Form::close() }}
Which fires my editAccount controller method:
$rules = array(
'name' => array('required'),
'email' => array('required'),
'password' => array('confirmed')
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())
{
// Redirect
}
// Save to DB
$account->fill(Input::all());
$account->save();
Which works fine, but if no password was supplied (because the user doesn't want to update/modify it) then the password field is set to null in the db. So, I only want the password field to update if a new password value is supplied via the form.
I know I can do the following:
// Set the fields manually
$account->name = Input::get('name');
$account->email = Input::get('email');
// Only update the password field if a value is supplied
if (Input::get('password')) {
$account->password = Input::get('password');
}
$account->save();
However I'm wondering if there is a more cleaner way to handle this? Like an UpdateOnlyIfValueExists() method within Laravel/Eloquent.
Using Input::only('foo', 'bar') will grab only the values needed to complete the request - instead of using Input::all().
However, if 'foo' or 'bar' doesn't exist within the input, the key will exist with the value of null:
$input = Input::only('foo', 'bar');
var_dump($input);
// Outputs
array (size=2)
'foo' => null
'bar' => null
To filter in a clean way, any values with a null value:
$input = array_filter($input, 'strlen');
In your example, this would replace: $account->fill(Input::all());
Create Base model and override update function like
/**
* #param array $attributes
* #return mixed
*/
public function update(Array $attributes = array()){
foreach($attributes as $key => $value){
if(!is_null($value)) $this->{$key} = $value;
}
return $this->save();
}
After use:
$model = Model::find($id);
$model->update(Input::only('param1', 'param2', 'param3'));
Check this, you can validate if password is present in input, and exclude it from mass assignment. You can use Input::except and Input::only for this purpose
public function update ($id) {
$user = User::findOrFail ($id);
if (Input::get ('password') == '') {
$user->update (Input::except ('password'));
}
else {
$user->update (Input::all ());
}
//return something
}
$data = $request->password ? $request->all():$request->except('password');
$user->update($data);
This will only update the password if it's not null
I would stick with your latter example. Another option would be to use a mutator which checks the value there, and doesn't update if the value is empty. But in my opinion, Eloquent should not be responsible for doing that.
I'd also avoid using ALL input with fill(). Choose only what you want.
This is a pretty shitty and common issue with Laravel (and other frameworks). My solution resembles some of the previous...
I always have the form data Input::all() stored in a variable at the beginning of the update/store methods. Since you usually need it at least twice (validate and create/update) it seems like a good practice. Then with that and before doing anything else I check in update() for the presence of the password, something like this:
$aFormData = Input::all();
if ( !$aFormData['password'] )
unset( $aFormData['password'] );
... the rest of your code here using $aFormData ;) ...
And that's it, hope it helps!
A much cleaner approach would be to use Eloquent Mutators
Under no circumstances would you allow a null or an empty string as password so you can safely define the following mutator in your Account model.
// Only accept a valid password and
// hash a password before saving
public function setPasswordAttribute($password)
{
if ( $password !== null & $password === '' )
{
$this->attributes['password'] = bcrypt($password);
}
}
The above mutator will only set a password attribute if it is not null and an empty string. It also hashes the password before saving so you do not need to do it in your controller action or application elsewhere.
Best approche is to use mutators as Noman Ur Rehman said above, but he had mistake in his code. Right one will be:
public function setPasswordAttribute($password){
if ( $password !== null && $password !== '' )
$this->attributes['password'] = Hash::make($password);
}

Resources