CakePHP: How to build a User's Profile page - php

How do we build a profile page that outputs the user's data? and this page can only be viewed by the user who logged in. It's something like when we go to our profile page and view our own username, password, email, address..etc. Then we may edit it by ourselves. It, of course can't be edited by other users.
I'm confused with the need of a profile table, now I think we would not need it? we can just populate the data using some PHP logic on a page we create as profile.ctp ?
This is confusing, I followed this http://book.cakephp.org/#!/view/1041/hasOne and created a profile table with some fields my users table has, and then with a foreign key called user_id. I checked on User and Profile model both are correctly defined in the relationship. I have this in Profile model:
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
and this in User model:
var $hasOne = 'Profile';
As I browse to my profile/index there are field names without any records. It's empty set. I thought it was supposed to retrieve data from the users' table ??
What's the best way to create a profile page for the existing users.. and the upcoming registrations ?

You do not need a profile table (if you already have a users table with their info).
One way of having this done is, after user validation, compare his id with id of the user which profile he wants to visualize. If those match, then it's a user who is viewing his own profile, and you can let him view his info.
Ofcourse there's a great deal of security issues you would have to take into account if you are thinking to make this a public accessible web site.

Related

User Management / Get iduser

I'm creating a user management where you can change a user's role, USER or ADMIN.
I'm a beginner in Laravel 9, and I would like to know how can I get the iduser when I click on the user's button ? For example this is a user profile.
The button can change his role form user to admin but I can't get his id...
I tried this but it's written 0 instead of 2 (his iduser)
$userID = User::find('iduser');
dd($userID);
Thank you very much!
Edit : When I click on a user profile, I want to get HIS/HER id, not mine or logged user :)
FOR EXAMPLE :
This user, I click on "Changer en administrateur" (change to admin), I just want his id ;)
If you want to get logged in user id you can do
$userID = Auth::user()->id;
Either from User model ,try
$userID = User::all()->pluck('id');
$request->validate([
'type' => 'required',
]);
DB::table('users')
->where('iduser', $request->iduser)
->update(
['type' => $request->type]
);
This one works to select a user's id :)

cakephp find query conditions on associated model

I have a model User and a model Role in a CakePHP application. The association between the two models is the following:
User $belongsTo Role
Role $hasMany User
I want to make a query on the User model to find all users with a specific role (let's say the role Supervisor). I did my query like this:
$supervisors = $this->User->find('all', array(
'contain' => array(
'Role' => array(
'conditions' => array(
'Role.name' => 'Supervisor'
)
)
)
));
But the above query returns me all the users in my users table. It does not return only the users with role Supervisor. I know that if I do two queries, one on the Role model to find the id of the role type 'Supervisor' and then do another query on the User model and pass the id of the supervisor role record in the conditions on my User model like this:
$supervisor_role_id = $this->Role->field('id', array('Role.name' => 'Supervisor'));
$supervisors = $this->User->find('all', array(
'conditions' => array(
'User.role_id' => $supervisor_role_id
)
));
The above queries will give me the desired result. But I don't wanna do 2 queries to do this. Why doesn't the first approach work. Any idea please?
Thank you
The reason your attempt didn't work
CakePHP's Containble Behavior creates separate queries for each model. So - what you did was basically described like this: "Find all Users. Also find any Roles with the name of 'Supervisor". As you can see, there is no condition that crosses between the two.
So, you can do one of the following:
1) [easy way] Query the other way around
Query from the Role model and contain it's user(s). This pulls the role you want (based on your provided conditions) then contains any/all of it's users.
Note - if you've already loaded the 'User' model (or it's been loaded by default because you're in the UsersController), you can run your find like this: $this->User->Role->find(..... - so you don't have to load the Role model separately.
2) Use JOINs (see CakePHP Book on Joining Tables)
This allows you to limit the result of a parent model based on it's associated data.

Save a HABTM record to database CakePHP

I am working on a followers / following system with CakePHP 2.
I have setup my database with a users table, and a user_users table. The users table is the main table containing every user on the system, whilst the user_users table contains the records of followers.
I then have a UsersController, User model and Follower model.
I can successful output a button to either say Follow or Following dependent on whether the currently logged in user is following the user of which the profile they are viewing belongs to, however what I am unable to understand how to do, is create new following relationships in the table. In other words, I do not know how to create records in the user_users table.
I am not sure where the logic for this should go, and thus what my "Follow" button should point to.
This is probably a very simple question, but I am totally stumped. I have tried adding a "follow" action to the UsersController but I cannot get that to work.
Any help much appreciated,
Duncan
HATBM isn't a good fit in this situation. From the cookbook:
HABTM data is treated like a complete set, each time a new data
association is added the complete set of associated rows in database
is dropped and created again so you will always need to pass the whole
data set for saving. For an alternative to using HABTM see hasMany
through (The Join Model)
For this reason, HABTM is mainly good for pretty 'dumb' relationships. I've used it in cases such as where a User has to select many Interests - and they just get a list of checkboxes, where they can click multiple Interests, and save them all in one hit.
In your case, it'll be easier to have a separate table with it's own model. I'd call it Relationships or something similar. It would have an id, followed_by_id, following_id, and any other fields you may need.
I've dug up some code from an old cake 1.3 app, but it should help you out. Your Relationships model would look something like this:
<?php
class Relationship extends AppModel {
var $name = 'Relationship';
var $belongsTo = array(
'FollowedBy' => array(
'className' => 'User',
'foreignKey' => 'followed_by_id'
),
'Following' => array(
'className' => 'User',
'foreignKey' => 'following_id'
)
);
}
?>
Your User's model would have to have relationships like this:
var $hasMany = array(
'Followers' => array(
'className' => 'Relationship',
'foreignKey' => 'following_id',
'dependent'=> true
),
'FollowingUsers' => array(
'className' => 'Relationship',
'foreignKey' => 'followed_by_id',
'dependent'=> true
),
);
Then in your relationships controller, you'd have methods something like this:
function add($following_id = null) {
$this->Relationship->create();
$this->Relationship->set('followed_by_id',$this->Auth->User('id'));
$this->Relationship->set('following_id',$following_id);
$this->Relationship->save();
$this->redirect($this->referer());
}
function delete($id = null) {
$this->Relationship->delete($id);
$this->redirect($this->referer());
}
Note that in that code, I'm modifying the database with a GET request - which I really shouldn't be doing (it's old code, from years ago). You'll want to enforce a POST request for both the add and delete methods, since they're modifying the database.
But still, that code should set you on the right track.

Lithium Auth::check user with relationships, relational database

I am using Auth::check('user', $this->request), where 'user' is the name of my Auth::config configuration, to successfully authenticate and login users against a Users table. Upon successful user login, the user information is stored in the session and can be accessed via Auth::check('user').
I have a relational design in place where the Users table has a many-to-one relationship with a table named Sites. When Auth::check queries the Users table to authenticate a user logging in, it only returns information from the Users table. I need Auth:check to return the User with its related data from the Sites table. Both the User and Site models have the appropriate hasOne and hasMany relationships defined. How can I ensure that the user is queried and returned with its corresponding related data via Auth::check()?
While it's generally inadvisable to store more session information than is absolutely necessary, it's possible to do this through the 'query' configuration key of the Form auth adapter. Just create a wrapper method in your Users model that can take a query configuration array, and return a user object with associated relationships. Probably something like this:
public static function authenticate (array $query) {
return static::all($query + array('with' => 'Sites'));
}
Then, add 'query' => 'authenticate' to your 'user' auth configuration.

How can this association be set up?

I'm using the cakephp framework to develop an application and I'm running into some trouble understanding the associations between these models fully. Below you can see the four models along with their relative database fields.
User
id
Profile
id
user_id
Post (A blog post on the users profile)
id
profile_id
topic_id
Topic (A topic for a blog post)
id
name
Here are the associations as they currently stand:
User
hasOne: Profile
Profile
hasMany: Posts
Post
belongsTo: Topic, Profile
Now my problem. I am unsure if you have to define associations like User hasMany Posts or if it's already assumed because User hasOne Profile and Profile hasMany Posts. My other problem is defining the relationship between a post and its topic.
A profile can have unlimited posts
A post must be associated with a profile
A post can only have one topic
The topic table contains a list of all topics
A post does not NEED a topic
Given these criteria how should my associations look? All the research I've done on associations only shows simple examples.
I'm using CakePHP version 2.1.3
Thanks for any and all help and/or advice in advance
You can recursively find associations of associations, or even better, use Containable.
In the model (I recommend putting it in AppModel, since I find myself using Containable for everything):
class AppModel extends Model {
public $actsAs = array('Containable');
...
}
Then when you call read (or find, or paginate) for User, most likely in your controller, do this:
$this->User->contain(array(
'Profile' => array(
'Post'
)
));
$data = $this->User->read();
$set('user',$data);
If you set that data to your view, you can then access the id of one of the posts from $user['Profile']['Post'][0]['id'].
Now for your next question, you can have conditional associations.
public $hasMany = array(
'Topic' => array(
'className' => 'Topic',
'conditions' => 'Post.topic_id IS NOT NULL'
)
)
I think everything looks fine
Your assumption is correct you dont have to define the User / Post relationship. Users dont have many Posts, Profiles do. You could store the user_id on the Post rather than profile_id to make thing a bit more intuitive but thats up to you.
Topic hasMany Post and you are done. The topic/post conditions you describe can be controlled via the forms and before saves on the model. For example 'A post must be associated with a profile', well at the point you save the post you add in the profile_id based on session info of the logged in user.

Categories