Kohana - adding values to the query before ORM::Save - php

I am using the ORM to save the user registration data into the database. The code is as follows.
if ($_POST) {
$user = Model::factory('member');
$post = $user->validate_create($_POST);
if ($post->check()) {
$user->values($post);
$user->save();
// redirect to create gallery.
}
}
I have some values such as the UserType which is not part of the $_POST but has to be saved in the members table as part of the user registration. Is it a good idea to alter the values of $post and add UserType to it or is there any other recommended methods for achieving this?

It's ok to alter the $post since it's just an array with the values taken from request now.
You can do it either by editing the $post array:
$post['usertype'] = 'customer';
$user->values($post);
$user->save();
Or you can set the value to your ORM object directly:
$user->values($post);
$user->usertype = 'customer';
$user->save();
Both should be fine

You can use hidden inputs in your form. For example:
Form::hidden('usertype', 'customer');
If you don't want to change $_POST array.
If you want to check is user sending $_POST request, use Kohana's method:
if($this->request->method() === Request::POST) {}
instead of:
if($_POST)
By the way, get a $_POST data in this way:
$post = $this->request->post();

Related

On a Laravel 'update' function, how to parse a JSON object, and store it with a ForEach loop

I am using the Laravel framework to work with my MySQL database, and currently want to update my database from a JSON object, that will be sent from somewhere else.
Currently, I have it the same as my 'Store' function, which is obviously not going to work, because it will update everything, or refuse to work because it is missing information.
This is the for each I have currently, it does not work, but I am not experienced with how it is best to parse a JSON with a for-each, then store it.
public function update(Request $request,$student)
{
$storeData = User::find($student);
foreach ($request as $value) {
$storeData-> username = $value;
}
Here is my store function, with all the info that the front-end team may send in a JSON format.
$storeData->username=$request->input('username');
$storeData->password=$request->input('password');
$storeData->email=$request->input('email');
$storeData->location=$request->input('location');
$storeData->role=DB::table('users')->where('user_id', $student)->value('role');
$storeData->devotional_id=$request->input('devotional_id');
$storeData->gift_id=$request->input('gift_id');
$storeData->save();
return dd("Info Recieved");
You can write the method like the below snippet.
Also, assume you are working with laravel API, so you don't need to parse the incoming JSON input, but you will receive these values as items in the request object.
However, you should use the filled method in order to determine if the field is existing and has a value, the update function will override with empty values otherwise.
I just added this method to the first input, but you have to use it each and every input if you are not sure what the front end will pass.
public function update(Request $request, $student)
{
$storeData = User::find($student); // should be id
if ($request->filled('username')) { // use this for other items also
$storeData->username = $request->input('username');
}
$storeData->password = $request->input('password');
$storeData->email = $request->input('email');
$storeData->location = $request->input('location');
$storeData->role = DB::table('users')->where('user_id', $student)->value('role');
$storeData->devotional_id = $request->input('devotional_id');
$storeData->gift_id = $request->input('gift_id');
$storeData->update();
dd("Info Recieved");
}
Why would they send json data from the front in a post?
Really it would be from a form input. Like Rinto said it would be request object.
$user->username = $request->user_name;
I'm gathering this is a form on the front to create a new user. Why not use the built in auth scaffolding that has this set up for you in the register area?
So I'd personally use...
//look up user that matches the email or create a new user
$user = User::firstOrNew(['email' => request('email')]);
//add other input values here
$user->name = request('name');
//save
$user->save();
Hard to give an exact answer to this when the question is a bit vague in what you're doing. There are many methods in Laravel to accomplish things. From your code it just looks like registration. Also, the big gotcha I see in your code is you are passing a text only password and then adding that password in plain text to your database. That is a big security flaw.
you can convert your JSON object to an array and then do your foreach loop on the new array. To update a table in Laravel it's update ($storeData->update();) not save. Save is to insert.
$Arr = json_decode($request, true);

How to send multiple variable to a view in laravel when one or more variables are null

When a new user is registered and is redirected to profile page. All these $userconatact , $qualification and $profileimage variables are null. Home page is setup with if (condition) to have buttons to fill form or show available data to user. There are three forms and user has to fill these form one by one. All these variables or one of them could be null but I still want to send the null value to view. Is there any way to make this view happen.
class ProfileController extends Controller
{
public function showprofile($type=null, $id='id'){
$contactquery = Usercontact::where('user_id',Auth::user()->id)->select('*')->get();
$usercontact = $contactquery->toArray();
$qualificationquery = userqualification::where('user_id',Auth::user()->id)->select('*')->get();
$qualification = $qualificationquery->toArray();
$profileimagequery = Profileimage::where('user_id',Auth::user()->id)->select('id','user_id','profileimage')->get();
$profileimage = $profileimagequery->toArray();
return view('home')->withUsercontact($usercontact)->withQualification($qualification)->withProfileimage($profileimage);
}
}
I tried using if statements but if didn't work
return view('home')
if(!empty($usercontact)){->withUsercontact($usercontact)}
if(!empty($qualification)){->withQualification($qualification)}
if(!empty($profileimage)){->withProfileimage($profileimage);}
Is there any way to use if statements like this to make it easy.
1) Use compact which will automatically create key value pairs for you.
return view('home')->compact('usercontact','qualification','profileImage')
2) Here are a few other improvements to your code. You can use the Auth facade to access the logged-in user.
$usercontact = Auth::user();
3) Define relationships on your user model and access the qualifications by this. This will return a Collection.
$qualification = $usercontact->qualifications;
You can use compact to send data from your controllers to views.
return view('home')->compact('usercontact', 'qualification', profileimage');
Your code can be refactored as below.
public function showprofile($type=null, $id='id')
{
$usercontact = Usercontact::where('user_id',Auth::user()->id)->first();
$qualification = Userqualification::where('user_id',Auth::user()->id)->first();
$profileimage = Profileimage::where('user_id',Auth::user()->id)->select('id','user_id','profileimage')->first();
return view('home')->compact('usercontact', 'qualification', 'profileimage');
}
Note the Userqualification model name in the code according to the convention. Try to add relationships to your models to make your query easier.
Try this style to send data to view
return view('home',['Usercontact'=>$usercontact,'Qualification'=>$qualification,'Profileimage'=>$profileimage]);
In view you will be able to get data by array key

How to modify certain fields in entity using only associative array?

I'm implementing editing user profile via API. The page where user edits its data contains a lot of fields, but when user submits the form, only edited fields are sent to my API endpoint. Also I'm not using form mapping.
Only way I see is to write something like this:
public function editProfile(FormInterface $form, User $user): User
{
$args = $form->getData();
if ($args['email']) {
$user->setEmail($args['email']);
}
if ($args['phone']) {
$user->setPhone($args['phone']);
}
// ...
$this->em->persist($user);
$this->em->flush();
return $user;
}
But it looks terrible and my form may contain up to several tens of fields.
Does anybody know good solution for this case?
Use form mapping and submit form with disabled clear missing fields option:
In form builder:
$options->setDefaults([
'data_class' => MyEntity:class
]);
In controller:
$data = $request->request->all();
$form->submit($data, false);`
instead of $form->handleRequest($request);

Laravel empty password being hashed when updating user

When I'm updating my model-bound form with
$user->update(Input::all())
My password field is re-hashed, even when it's empty. I have set my User.php class to automatically hash that field, but shouldn't it be skipped since the field is empty?
You could use in this case:
Input::except('password')
so in your controller you could do it this way:
if (trim(Input::get('password')) == '') {
$data = Input::except('password');
}
else {
$data = Input::all();
}
$user->update($data);
However you should consider other possible issues for that. In this case if user send input with id name (and anyone can do it even if you don't have such field in your form) he could change easily other users passwords/accounts and destroy your whole data.
You should use in your User model at least:
protected $guarded = array('id');
to protect user id from being changed during mass assignment but maybe there are also some other fields you would like to protect (you should list them in $guarded array.
For me much better option in this case is using standard user updating:
$user = User::find($id);
if (trim(Input::get('password')) != '') {
$user->password = Hash::make(trim(Input::get('password')));
}
$user->name = Input::get('name');
// and so on - this way you know what you are changing and you won't change something you don't want to change
$user->save();
Just as Tom Bird commented, here's some code for an example.
If you use a mutator like setPasswordAttribute() method in your model then you can do this:
public function setPasswordAttribute($password)
{
if (!empty($password))
{
$this->attributes['password'] = bcrypt($password);
}
}
This will prevent a new password from being hashed. This setPasswordAttribute() method is called a "mutator" and became available in Laravel 4.2 from what I see. http://laravel.com/docs/4.2/eloquent
Because you have sent all of the input to the user model it assumes you want to update all fields including the password even though it is an empty string, it is possible to hash an empty string.
You need to check if the password is empty and if it is use Input::except('password')
The simple method you can use for this is array_filter. Array_filter filter excludes any empty field. so if you password field is empty then it will not be included in the user update model and when the password field is not included it will not be hashed since mutators and accessors only work when the model has the given attribute. When you filter it out the fields, the model does not receive the field and thus will not hash. You use it in following way...
$user->update(array_filter(Input::all()));
or
$user->update(array_filter($request->all()));
The only problem with this is it will not only exclude password but also all the field that were set empty.
public function update($id)
{
$register = Register::findOrFail($id);
if (empty(Request::get('password'))) {
$data = Request::except('password');
} else {
$data = Request::all();
}
$register->update($data);
return redirect('register');
}

Get value of custom user field in Drupal 7 template?

I'm building my first site with drupal. And I made a custom user field: Full name.
Now I want to get the value of this fild in my template to say “Hello, %username%”.
How do I do that?
Clive's answer is correct except that you should use field_get_items to get the values for a field. It will handle the language for you. You should also sanitize the value.
function THEME_preprocess_page() {
global $user;
$user = user_load($user->uid); // Make sure the user object is fully loaded
$full_names = field_get_items('user', $user, 'field_full_name');
if ($full_names) {
$vars['full_name'] = check_plain($full_names[0]['value']);
}
}
If your site uses the Entity API module, you can also use a entity metadata wrapper like this
function THEME_preprocess_page() {
global $user;
$user = user_load($user->uid); // Make sure the user object is fully loaded
$wrapper = entity_metadata_wrapper('user', $user);
$vars['full_name'] = $wrapper->field_full_name->get(0)->value(array('sanitize' => TRUE));
}
See also Writing robust code that uses fields, in Drupal 7
Depending on your setup/field name, something like this in template.php (preprocess function for the template file):
function mytheme_preprocess_page() {
global $user;
$user = user_load($user->uid); // Make sure the user object is fully loaded
$vars['full_name'] = $user->field_full_name[LANGUAGE_NONE][0]['value'];
}
Then something like this in page.tpl.php:
if (isset($full_name) && !empty($full_name)) :
echo 'Hello ' . $full_name;
endif;
Note that LANGUAGE_NONE may need to be changed if you're running a multi-lingual site.
I know this question was asked quite a while ago, but I wanted to post an alternative. It looks like you want to change the field in the $variables array that is $variables['name'] to what you have in your custom field that I've called field_real_name. If you are using a preprocess function, there is no need to pull in the global $user object. You have access to the $variables array, so you can get the user information with this - it will load the information associated with the uid (see template_preprocess_username):
function mythemename_preprocess_username(&$variables) {
$account = user_load($variables['account']->uid);
...more code will go here in a moment
}
If you dpm($account) (or kpr($account) if you aren't using devel) you will see that you have access to all of the user information, without using the global $user object.
Then you can change the output of $variables['name'] to be your field_real_name as follows:
function mythemename_preprocess_username(&$variables) {
// Load user information with user fields
$account = user_load($variables['account']->uid);
// See if user has real_name set, if so use that as the name instead
$real_name = $account->field_real_name[LANGUAGE_NONE][0]['safe_value'];
if (isset($real_name)) {
$variables['name'] = $real_name;
}
}
We can add the below code anywhere in the template file.
<?php
global $user;
$user = user_load($user->uid);
print $user->name;
?>

Categories