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;
Related
I'm trying to learn Spatie Laravel Permission Package. When trying to insert data to models has permissions table it gives the below error in postman. I don't know clearly how to insert data. I used the guide of spatie documentation.
error,
Call to a member function givePermissionTo() on null
here is my controller function
public function models()
{
Role::create(['name'=>'writer']);
Permission::create(['name'=>'edit post']);
Auth::id()->givePermissionTo('edit articles');
return 'hello';
}
I don't know if the question is clear enough. Please tell me if it's not clear.
Auth::id() return the id of the authenticated user, but you need to call givePermissionTo on a user object, not a user id.
try
Auth::user()->givePermissionTo('edit articles');
#brombeer was right. the issue was in the Auth::id() It says the authenticated user is not accessed in.
I changed my function line Auth::id()->givePermissionTo('edit articles'); to auth()->user()->givePermissionTo('edit articles');. Also the called __construct() function like this,
public function __construct()
{
$this->middleware('auth');
}
Then I accessed as an authorized user and inserted log in the token as a bearer token in postman. Then the issue was fixed.
Auth::id returns the id of the user. The method givePermissionTo should be called on an object of the user and not the id.
Here are two ways you can do it:
Method 1
Auth::user()->givePermissionTo('edit articles');
Method 2
$user = Auth::user();
$user->givePermissionTo('edit articles);
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 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()
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.
Laravel Cashier is not saving stripe data to my DB after a user is created.
When I create a new user and then try to assign a subscription() to that user (or any other user for that matter) the data is being sent to Stripe approriately, as I can see the customer id, plan chosen, etc... But my database user stripe columns do not get updated in my database.
When I remove the code to create() a user and just subscribe a user, the data persists to the database like it should. It only doesn't work after I've created a new user THEN try to subscribe any user.
I'm using Jeffrey Way's Model Validation Package.
$user = $this->userModel->create($input);
if ($user->hasErrors()) {
throw new \Exception($user->getErrors());
}
$this->createStripeSubscription($user->id, $input['creditCardToken']);
private function createStripeSubscription($user_id, $token) {
//$this->userModel->find(1)->subscription('monthly')->create($token); // Doesn't work either
$this->userModel->find($user_id)->subscription('monthly')->create($token);
}
I had similar problem with Ardent validation in Confide.
Overriding saving method of BillableTrait in user model solved the issue.
class User extends ConfideUser implements BillableInterface {
use BillableTrait;
public function saveBillableInstance()
{
$this->forceSave();
}
}
The problem was a conflict with Jeffrey Way's Validation Model package. Or at least the way I was trying to implement it while using Cashier. I decided to abstract out my Validation in it's own class and remove the Validation Model package. All is good.