I want to get the role id of the logged user to make visible specific links of website. currently I have student and tutor tables and separate login for both users. student table has role as 1 and tutor table as role as 2, how can I check the logged user's role .
I tried
<?php echo Yii::app()->user->role;?>
but it returns following error
Property "CWebUser.role" is not defined.
pls advice
There are two solutions:
Using setState() in extended CUserIdentity class. It calls once during user auth and woudn't be updated on next page refresh. Don't store there important information like roles or passwords, cause it could be stored in cookie. It easy to store there information like name, last visit time, etc.
Here is an example: http://www.yiiframework.com/wiki/6/how-to-add-more-information-to-yii-app-user
Extends CWebUser and add some public methods, for example getRole():
main.php
'user' => array('class' => 'application.components.WebUser')
WebUser.php
class WebUser extends CWebUser {
public $role;
public function getRole(){
if ($this->role === null) {
// Here you need to get User role
$this->role = Yii::app()->db->createCommand("SELECT role FROM {{user}} WHERE id=:id")->queryScalar(array(':id' => Yii::app()->user->id));
}
return $this->role;
}
}
Then call if where you need Yii::app()->user->role or Yii::app()->user->getRole()
Related
In my Product Policy file I have the following:
public function change_customer_pricing(User $user) {
return $user->id == 2;
}
How do I return more than one user ID to the Controller?
My controller:
public function change_customer_pricing($ProdID) {
$user = Auth::user();
//dd($user->can('change_customer_pricing', Product::class));
if (!$user->can('change_customer_pricing', Product::class))
return redirect()->route('home')->with('status', 'You are not Authorized to access')->with('code', 'red');
...
public function change_customer_pricing(User $user){
return in_array($user->UserID,[2,12,14]);
}
If you're looking to determine if a User has authorisation to perform an action on a Product, you need a relationship between the User and Product and then check the relationship.
Say you have a user_id field on your Product which holds the id of the User that created that Product for example and only that User is allowed to update or delete the Product. You would want to check the id of the authenticated User matches the user_id of the Product.
public function change_customer_pricin(User $user, Product $product)
{
return $user->id === $product->user_id;
}
Then you can use any of the baked in authorisation functions with Laravel. As you're wanthing to check if a User is authorised from a controller, you can do:
public function change_customer_pricing($ProdID)
{
$product = Product::find($ProdId);
$this->authorize('change_product_pricing', $product);
}
As a side note, you might want to consider using route model binding in your controller.
Update
As your Product doesn't have a relationship to a User and you're looking to authorise multiple Users, you could check id of the currently authenticated User against an array:
public function change_customer_pricin(User $user)
{
return in_array($user->id, [1, 2, 3, 4];
}
This is the quickest and simplest solution. However, it is not very maintainable as you'd have to add/remove as requirements changed.
A better solution would be to use roles and permissions to determine authorisation. You define permissions which are used scope access then you can associate (assign) permissions directly to a User or to a Role (and the a Role to a User). When an action is performed, you check if a User has the required Role or Permission.
There are a few packages available which provide such functionalty, a very popular option is Spatie Permission and another popular choice is Laratrust.
I work on a website for my last school project, it's a website where (as a normal user) you can match with a coach and once you two have matched together, you can share a page where the coach can update your daily workout routine.
I'm stucked at the matching method, my entity User has a propriety idCoach which is an array that can contains other Users. The idea is when you are on the coach's profile page, and you press on the match button, it adds the coach on your idCoach propriety.
This is my propriery from my User entity:
/**
* #ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="idSportif")
*/
private $idCoach;
this is what i tried on the controller :
/**
* #Route("/user/match/{id}", name="match")
*/
public function matchCoach(ObjectManager $om, User $user) {
$currentUser = $this->getUser();
$currentUser->addIdCoach($user);
$om->persist($currentUser);
$om->flush();
return $this->render('profile/index.html.twig', [
'user' => $currentUser,
]);
}
but it gives me an error message :
Call to a member function addIdCoach() on null.
so getUser() returns null, that's why you get the error.
Does your Controller extend AbstractController and getUser() should therefore return the currently logged in user? In this case, it seems like you are not logged in. I would check the security configuration to make sure only logged in users can access this url.
Further comments:
Your naming is a little confusing, what is an "idCoach"? If this property holds the associated coaches, I would name it "coaches".
Your method changes data, so it should only be called via POST, not GET.
I have used dektrium/yii2-user in my application.
And there is a method named getID() in User.php of vendor/dektrium and this method can be accessed by Yii::$app->user->getID() and returns id of the logged in user.
However, there is another method named getProfile() whose function is to return complete profile details of currently logged in user. But, this method is giving 500-internal server error.
exception 'yii\base\UnknownMethodException' with message 'Calling unknown method: yii\web\User::getProfile()' in ... ...
I Googled the issue but found nothing... Help me folks..
I believe that you can get the profile of the currently logged in user like this:
Yii::$app->user->identity->profile;
because Yii::$app->user->identity returns the current user - the User object.
You are confusing Yii's web user object with the user model :)
EDIT:
Yii::$app->user is referring to yii\web\User - the application component that manages the user authentication status.
You ask that User component to get the 'identity' which is :
IdentityInterface is the interface that should be implemented by a class providing identity information
In this case, Dektrium User model implements the IdentityInterface and you are able to call getId on it and get the id for the User model.
class User extends ActiveRecord implements IdentityInterface
This code:
Yii::$app->user->identity->profile;
Will return the Profile model data associated with the User
And you can access it's fields directly:
Yii::$app->user->identity->profile->location;
See dektrium\user\models\Profile for details.
People always gets confused about yii\web\User, the IdentityInterface and the User model..
Myself included :p
If you have an instance of an user ($user), you can use the getProfile() function:
$profile = $user->getProfile()->one();
And it returns profile record from that user.
If you don't have an instance of user, but the id ($user_id), you could get an instance of Profile model directly:
$profile = Profile::find()->where(['user_id' => $user_id)->one();
And Yii::$app->user is an interface to the user model defined in your app (dektrium user model in this case): http://www.yiiframework.com/doc-2.0/yii-web-user.html
to sum up:
$user_id = Yii::$app->user->getID();
$profile = Profile::find()->where(['user_id' => $user_id)->one();
Try this one
\app\models\User::findOne(Yii::$app->user->identity->id)->profile;
I have two models 'a' and 'b' and a->hasMany('b') and b->belongsTo('a')
So when I create one 'b' this should belongs to exactly one 'a'.
The problem is with the usual Route::resource('b', 'bController') I can just create this 'b' and don't know to which 'a' this belongs.
I tried editing the create() method in bController to create($id) but
Redirect::action('bController#create', $a->id)
Still redirects to /b/create?2 an gives an error
Missing argument 1 for bController::create()
Maybe a bit easier to unserstand when I use phoneand user.
Every phone belongs to one user.
How can I create a phone? How do I give the create() the parameter of the user and still use the Route::resource?
I think you are on a wrong direction because User and Phone are two models and hence a User has many phones so here Phone model is a child model (related) of User class and a Phone can't exist without a User so you only need to create a User through the controller and Phone will be created when the User gets created, for example:
Route::resource('users', 'UserController');
Now assume that you have tow models as User and Phone and the User model has phones method which builds the relationship (phones = User->hasMany('Phone')) and the Phone model has a user method which builds the relationship (user = Phone->belomgsTo('User')).
// User model
class User extends Eloquent {
//...
public function phones()
{
return $this->hasMany('Phone');
}
}
// Phone model
class Phone extends Eloquent {
//...
public function user()
{
return $this->belongsTo('user');
}
}
Now to create a User the store method will be used like this:
// UserController.php
class UserController extends BaseController {
// Other methods
// Creates a User
// URI: /users Method: POST
public function store()
{
// Create a User using User model
$user = User::create(...);
if($user) {
// Initialize/Create a Phone
$phone = new Phone(array(...));
if($phone) {
// Save the Phone and relate with User
$user->phones()->save($phone);
}
}
}
}
This is the basic idea and the final thing is that, a Phone doesn't require a Controller to be created, because it's the part of a User so when you create a new User then create a (or more) Phone from the UserController after you create a User or update a Phone when you update a User.
So if you want to load a User with it's related Phone models then you may do it like this:
$user = User::with('phones')->find(1);
So, when you load a user, you can load all the phones related with that user so during editing of an user; you only need to load a User with related Phone models and pass that model to the view.
To add a new Phone to an existing User you need to edit the User model so you can load a User model with phones and pass that User model to the view for editing. When new Phone being added to the user, you only need to attach that Phone with existing User, that's it. Hope it makes sense.
I have a cakephp2 application where users login based on their credentials on a db. Authentication & Authorizations work fine.
I have a notes table, in which users's notes are stored. Each user can have many notes.
On one page I need to extract all the notes of the logged in user.
I have created a note model :
class Note extends AppModel {
public $name = 'Note';
public $belongsTo = 'User';
}
and in my user model I have:
class User extends AppModel {
public $name = 'User';
public $displayField = 'name';
public $hasMany = 'Note';....
In the usercontroller i have created:
public function getnotes($id = null) {
$this->User->id = $id;
}
but no matter what find statement I run, I can't get only the notes for the specific user. I run debug($id) and I get false on screen, so obviously the current user id is not being recognized.
I have to list all the notes of a user then link to each individual notes page.
Integrate an AUTH component in cakePHP ...so you will get logged in users ID/Info by auth functions and array like($this->Auth->user('id'))
for auth integration use below link as refence
http://book.cakephp.org/2.0/en/tutorials-and-examples/blog-auth-example/auth.html
now use this user ID like this in finding records
$this->Note->find('all',array('conditions'=>array('Note.user_id'=>$this->Auth->user('id')))