How to make roles in yii - php

So i am new to the yii framework and i am doing this blog style of a website trying to cover most of the features i can think off and the one I am stuck at is the having differnet user roles for example.
Lets say we have a writer and a normal logged in user and i want to make a writer when he go on the article page he can see some buttons while a normal loged in user can only see the comment button.
How do i come up with something to do this inside of the Yii Framework? and tutorials i can find on the internet?
Thank you for your time.

List all roles in User model
class User extends MyModel {
const ROLE_ADMIN = 1,
ROLE_AUTHOR = 2,
ROLE_USER = 3;
Also add role field to user (in database and in model).
In components/UserIdentity.php add some methods
public function isAuthor() {
return !empty($this->user) && $this->user->role == User::ROLE_AUTHOR;
}
public function isGuest(){
return empty($this->user);
}
Also, I recommend to add this method to User model:
public function getRole($role = null) {
$roles = [
self::ROLE_ADMIN => 'Admin',
self::ROLE_AUTHOR => 'Author',
self::ROLE_USER => 'User',
];
if (!is_null($role)) {
return isset($roles[$role]) ? $roles[$role] : 'Unknown role';
}
return $roles;
}

Hello thank you for the help that other people gave me but I have a found a a simple guide which i understood very easily and its very nice to use. you can find the tutorial in the following Link . Thank you For you help guys!

Related

Display data in gridview base on rbac role in yii2

How to display records in gridview in yii2 using rule created for roles, in RBAC ?
Suppose, there is two roles "admin" and "agent".
Now the requirement is;
In grid for agent, display only client which is assigned to that
agent.
For admin, grid will show all client list.
Here the example I am using this in my code
// User.php -> Model
public function getUserRolesAsArray($userId)
{
$roles = Yii::$app->authManager->getRolesByUser($userId);
if (!empty($roles)) {
foreach ($roles as $role) {
$userRole[] = $role->name;
}
return $userRole;
}
}
// view.php -> view file
[
'label' => 'Role',
'value' => $model->getUserRoles($model->id) ?? null,
],
Kindly try this i think this may be help you
It is done,
I have to create a permissions that will given to role, and based on that permission, DataProvider query is modified

Laravel - get rows not in custom hasMany relationship

I have an admin table and admin has many form. Each form is assigned to an admin that is displayed on their dashboard.
The trouble is there can be form that is that is not assigned to any admin.
I want to get all those forms Any help is appreciated. Thank you!
Edit : Admin is related to form via a custom relation as described Here
To summarize,
Admin.php
public function states(){
return $this->belongsToMany('App\State');
}
public function cities()
{
return $this->belongsToMany('App\City');
}
//gets the forms in this admin's city or state
//Let me know if there is a better way to do this, i feel like im overdoing stuff here
public function forms()
{
//cities
$cities = $this->cities->pluck('name');
//states
$states = $this->states->pluck('name');
$users = User::whereIn('state',$states)>orWhereIn('city',$cities)->get()->pluck('id');
$forms = Form::whereIn('user_id',$users);
return $forms;
}
Id like to get the form that doesnt belong to any admin
You may be looking for doesntHave.
$forms=Form::doesntHave('admin')->get();
Why don't you simply do the reverse of it?
$forms = Form::whereNotIn('user_id', $users);

Yii2 ManyToMany relation - Get Client window's data

I have a small (no, not that small) probleme in my current project. Today I came across with Yii and viaTable but something is not working with it. I think something is wrong with the table linking.
My goal would be to get all the data from the client windows(Ablak)
that is connected to a user via felhasznalo2ablak table.
I have 3 tables. Felhasznalo(Users in English), Ablak(Client Window in English) and Felhasznalo2Ablak which is the via table.
Here are the table structures:
Felhasznalo(Model):
public function getWindows() {
return $this->hasMany(Ablak::className(), ['id' => 'ablak_id'])- >viaTable('felhasznalo2ablak',['felhasznalo_id','id']);
}
Ablak(Model):
public function getUsers() {
return $this->hasMany(Felhasznalo::className(), ['id' => 'felhasznalo_id'])->viaTable('felhasznalo2ablak', ['ablak_id' => 'id']);
}
And the query in the controller:
$u = Felhasznalo::findOne(Yii::$app->user->getId());
$allowedWindows = $u->getWindows();
foreach ($allowedWindows as $aw) {
print_r($aw);
}
I want to get the ralational data from Ablak table that blongs to a specific user. It works but not tha way it should. Any ideas guys?
Thank you for your answers!
Gábor
Check the link in your Felhasznalo::getWindows()
public function getWindows() {
return $this
->hasMany(Ablak::className(), ['id' => 'ablak_id'])
->viaTable('felhasznalo2ablak', ['felhasznalo_id' => 'id']);
}
Query for all "Windows"
$u = Felhasznalo::findOne(Yii::$app->user->getId());
$allowedWindows = $u->getWindows()->all();
print_r($allowedWindows);
I forget to answer my thread. So the problem was solved by adding forign keys to my database structure and after that i generated the model files with gii.

Laravel Creating userInfo database table when user registers

I am doing an extension build on the User model on larval 5.
What I want to accomplish is once the user registers and is validated I want ANOTHER database table created named userInfo which has a belongsto Relationship with the User model and the User model has a hasOne relationship with userInfo.
Two things.
How to I successfully implement this logic. I was reading
http://laravel.com/docs/master/eloquent-relationships#inserting-related-models
and
http://laravel.com/docs/5.1/events#registering-events-and-listeners
But Im not to sure
And second.
Where best do I implement this logic.
Thanks in advance
PS. I do not what to combine the two database because the user model is when they register and data that lives in userInfo is "optional" for the user to fill out After authentication.
If I am understanding the question correctly, you want to create an additional related model to the user when they register. That should be pretty straightforward - something like:
$user->userInfo()->save(UserInfo::create([
//whatever information you need to save to the userInfo table - if any
]));
as for where to put it, you have options there. You could put it the 'store' method on your registration controller. Or extract it out to a service class 'RegisterUser', and create the user and userInfo there.
something like:
//controller method
public function store(Request $request, RegisterUser $registerUser)
{
$user = $registerUser->handle($request);
return view(....)
}
//RegisterUser class
public function __construct(UserInfo $userInfo)
{
$this->userInfo = $userInfo;
}
public function handle($request)
{
// create your user
$user = .....
$user->userInfo()->save($this->userInfo->create([
.....
]));
// whatever else you need to do - send email, etc
return $user;
}
Edit: If you are using Laravel 5 and the default registration scaffolding, then you can add code to the app\Services\Registar class. This class is called by the postRegister method in the trait. Change the create method:
// app\Services\Registar
public function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
$user->userInfo()->save($this->userInfo->create([
.....
]));
// whatever else you need to do - send email, etc
return $user;
}
If you are using Laravel 5.1 then the Registar class doesn't exist anymore, the create method has been moved to the AuthController (the method is the same, just in a different location) so override it there.
Your answer pointed me in the right direction but I made some simple tweek to your edited question.
$user->userInfo()->firstOrCreate([
'aboutMe' => 'Please Fill out so users can know about you',
'bodyType' => '--',
]);
return $user;

Check for a many to many relation when listing a resource

I'm implementing relationships in Eloquent, and I'm facing the following problem:
An article can have many followers (users), and a user can follow many articles (by follow I mean, the users get notifications when a followed article is updated).
Defining such a relationship is easy:
class User extends Eloquent {
public function followedArticles()
{
return $this->belongsToMany('Article', 'article_followers');
}
}
also
class Article extends Eloquent {
public function followers()
{
return $this->belongsToMany('User', 'article_followers');
}
}
Now, when listing articles I want to show an extra information about each article: if the current user is or is not following it.
So for each article I would have:
article_id
title
content
etc.
is_following (extra field)
What I am doing now is this:
$articles = Article::with(array(
'followers' => function($query) use ($userId) {
$query->where('article_followers.user_id', '=', $userId);
}
)
);
This way I have an extra field for each article: 'followers` containing an array with a single user, if the user is following the article, or an empty array if he is not following it.
In my controller I can process this data to have the form I want, but I feel this kind of a hack.
I would love to have a simple is_following field with a boolean (whether the user following the article).
Is there a simple way of doing this?
One way of doing this would be to create an accessor for the custom field:
class Article extends Eloquent {
protected $appends = array('is_following');
public function followers()
{
return $this->belongsToMany('User', 'article_followers');
}
public function getIsFollowingAttribute() {
// Insert code here to determine if the
// current instance is related to the current user
}
}
What this will do is create a new field named 'is_following' which will automatically be added to the returned json object or model.
The code to determine whether or not the currently logged in user is following the article would depend upon your application.
Something like this should work:
return $this->followers()->contains($user->id);

Categories