get target user permission name according to role - laravel

im managing my registerd users... now i want see which user have which permission according the her/his role .. i want to show permissions in check box and make them check if user have that role. problem is target user permission according her role
my controller to view target user permission:
public function view(Request $request, User $user){
$roles = Role::with('permissions')->get();
$permissions = Permission::get();
return view('adminarea.roles.view', compact('roles','user', 'permissions'));
}
Blade file:
#foreach ( $permissions as $per )
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" name="permissions_ids[]" id="permissions"
value="{{ $per->id }}" style="margin-right:5px" #if (?)
checked="true"
#endif>
<label class="custom-control-label" for="permissions">{{ $per->name }}</label>
</div>
#endforeach
Model Relations :
Role table:
public function users()
{
return $this
->belongsToMany('App\User')
->withTimestamps();
}
public function permissions()
{
return $this->belongsToMany(Permission::class, 'roles_permissions');
}
Permission table:
public function roles()
{
return $this->belongsToMany(Role::class, 'roles_permissions');
}
User table:
public function roles()
{
return $this->belongsToMany(Role::class, 'users_roles');
}
Table Structure :
this is my roles_permission schema:
Schema::create('roles_permissions', function (Blueprint $table) {
$table->unsignedBigInteger('role_id');
$table->unsignedBigInteger('permission_id');
//FOREIGN KEY CONSTRAINTS
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
//SETTING THE PRIMARY KEYS
$table->primary(['role_id', 'permission_id']);
});
and users_role schema :
Schema::create('users_roles', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('role_id');
//FOREIGN KEY CONSTRAINTS
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
//SETTING THE PRIMARY KEYS
$table->primary(['user_id', 'role_id']);
});
permission table :
Schema::create('permissions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('description');
$table->timestamps();
});
and role table schema:
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('description');
$table->timestamps();
});

You can make use of laravel policies here.
Create a policy for your Users.
Then create functions like canViewPosts, canAddPosts, canSeeViews, etc. and in each check if the the user has permission to do so.
Example UserPolicy
public function canView(User $user){
return $user->permissions->canView; //given you have permissions relation on user
}
Then in your PostController you go like
$this->authorize('canView', User::class);
Check more in here:
https://laravel.com/docs/5.8/authorization#introduction

Related

i am trying to get the name using a relationship

here what I am trying to get the name of the category by using a relationship
here so far what I have done is I have defined a relationship in my product model as such
Public function category()
{
return $this->belongsto(Category::class);
}
I have also stored the field category id
in my products table
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->integer('Category_id');
$table->string('name');
$table->string('code');
$table->string('color');
$table->string('description');
$table->double('price');
$table->integer('quantity');
$table->string('image');
$table->timestamps();
});
also I have defined a relationship in my Category model such as
public function product()
{
return $this->hasmany(Product::class);
}
ALSO I HAVE DEFINED Relationship IN
PRODUCT AS
Public function category()
{
return $this->belongsto(Category::class);
}
in my view I am trying to get the name of the category
#foreach($products as $pro)
<tr>
<td><img src="{{asset('uploads/maj/'.$pro->image)}}" class="img-circle" alt="User Image" width="50" height="50"> </td>
<td>{{$pro->category->name}}</td>
<td>{{$pro->name}}</td>
<td>{{$pro->code}}</td>
<td>{{$pro->color}}</td>
<td>{{$pro->description}}</td>
<td>{{$pro->price}}</td>
<td>{{$pro->quantity}}</td>
I am receiving the error
Trying to get property 'name' of non-object
how can I get the name of the category ??
I am trying to get it like this but this is giving error
{{$pro->category->name}}
the category table row
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->String('Parent_id');
$table->string('name');
$table->string('status');
$table->timestamps();
});
my laravel version is 7 thanks
Maybe one or more product doesn't have category or category_id is wrong.
you can use condition to check if category is not exist:
{{$pro->category ? $pro->category->name : "no category"}}
or can simply using null coalescing operator:
{{$pro->category->name ?? "no category"}}
if category is required you should prevent it by add table relation/foreign.
try this
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->foreignId('category_id')->nullable()->constrained()->onDelete('cascade');
$table->string('name');
$table->string('code');
$table->string('color');
$table->string('description');
$table->double('price');
$table->integer('quantity');
$table->string('image');
$table->timestamps();
});
in model Product
public function category(){
return $this->belongsTo(Category::class,'category_id','id');
}
thin call products
$products = product::orderBy('created_at','asc')->with('category')->get();
you can chick if has relationship or not
#if(! empty($pro->category)) {{ $pro->category->name }} #else <span>no category</span> #endif
You should try like this way :
(!empty($pro->category)) ? $pro->category->name : 'No category found'
I think You should define foreign key properly because your category_id not follow the coding standard. if you Category Model are in App directory you can use pass namespace like this
Public function category()
{
return $this->belongsto('App\Category','Category_id','id');
}
other wise :
Public function category()
{
return $this->belongsto('App\Models\Category','Category_id','id');
}

Trying to get property of non-object when i try to $blog->user->name

in my model user
public function blogs(){
return $this->hasMany('App\Blog');
}
in my model blog
public function user(){
return $this->belongsTo('App\User','user_id');
}
in my BlogController
public function show($id)
{
$blog = Blog::find($id);
dd($blog->user->name);
return view('admin.pages.blogs.show',compact('blog'));
}
database table user ( id,role_id,name)
if role_id = 1(admin) then result $blog->user->name is null
if role_id = 2(author) then result $blog->user->name is name of user
how can i fix when role_id = 1
You need to remove user_id from Blog model.
public function user()
{
return $this->belongsTo(User::class);
}
UPD. In any case role_id does not matter. So you need to make sure DB contains related records. For example:
blogs:
id user_id text
1 123 '...'
users:
id name
123 'Linh'
First of all you change blogs users and roles migration.
blogs migration
Schema::create('blogs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->string('title');
$table->string('slug')->unique();
$table->string('image');
$table->string('body');
$table->tinyInteger('status')->default(0);
$table->tinyInteger('is_approved')->default(0);
$table->integer('view_count')->default(0);
$table->timestamps();
});
users migration
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('role_id')->default(2);
$table->foreign('role_id')->references('id')->on('roles');
$table->string('name');
$table->string('username')->unique();
$table->string('email')->unique();
$table->string('password');
$table->string('image')->default('default.png');
$table->text('about')->nullable();
$table->rememberToken();
$table->timestamps();
});
roles migration
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('slug')->unique();
$table->timestamps();
});
User model
public function blogs(){
return $this->hasMany('App\Blog');
}
Blog model
public function user(){
return $this->belongsTo('App\User');
}
BlogController
public function show($id)
{
$blog = Blog::find($id);
dd($blog->user->name);//check
return view('admin.pages.blogs.show',compact('blog'));
}

How to return name of table of grade when save like json?

I have two tables, users and grades.
users table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('first_name')->nullable();
$table->string('last_name')->nullable();
$table->string('grade_id')->nullable();
}
}
grades table
public function up()
{
Schema::create('grades', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}
I save id of grade with json_encode,
I save in field like this
$user->grade_id = json_encode($request->input('grade_id'));
I want to return the grade name but I did not solve my problem
Controller
public function index()
{
$grades = Grade::all();
return view('index', compact('grades');
}
User.php
public function grade()
{
return $this->belongsTo(Grade::class);
}
index.blade.php
#if(isset(auth()->user()->grade_id) && !empty(auth()->user()->grade_id))
<?php
$grade = json_decode(auth()->user()->grade->name, true);
#foreach($grade as $key=>$item)
<li>
<div class="grade">{{ $grade[$key] }}</div>
</li>
#endforeach
?>
#endif
I get this errpr
Trying to get property of non-object
Bad answer
You save an array of ids in the users table. Then when you do $grade = json_decode(auth()->user()->grade->name) you get something you don't want to have. Indeed, the value of auth()->user()->grade is ["8", "8"], this is not a grade model. Now you should understand why this $grade = json_decode(auth()->user()->grade->name) fail: you're trying to get name property of a non object (as user()->grade is just an array).
To solve it badly (read the next part of my answer) you can just do this in your controller (you shouldn't do any <?php ?> in your view files):
public function index()
{
$grades_ids = json_decode(auth()->user()->grade); // ["8", "8"]
$grades = Grade::whereIn('id', $grades_ids)->get(); // Eloquent collection
return view('index', compact('grades');
}
And use it in your view:
#if($grades->count())
<ul>
#foreach($grades as $grade)
<li>
<div class="grade">{{ $grade->id }}</div>
</li>
#endforeach
</ul>
#endif
Good answer
Here you have a typical many to many relationships. A grade can have multiple users, and a user can have multiple grades. Then you should think of using a pivot table rather than a encoding several grade_id in json.
Create a users table:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('first_name')->nullable();
$table->string('last_name')->nullable();
}
}
Then you create your grades table:
public function up()
{
Schema::create('grades', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->timestamps();
});
}
Then you create the new user_grade_table:
public function up()
{
Schema::create('user_grade', function (Blueprint $table) {
$table->primary(['user_id', 'grade_id']);
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('grade_id');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('grade_id')->references('id')->on('users')->onDelete('cascade');
});
}
public function down()
{
Schema::table('user_grade', function (Blueprint $table) {
$table->dropPrimary('user_grade_user_id_grade_id_primary');
$table->dropForeign('user_grade_user_id_foreign');
$table->dropForeign('user_grade_grade_id_foreign');
});
Schema::dropIfExists('user_grade');
}
Don't forget to run the migrations. When this is done, you have to update your models, adding the belongs to many on both models.
User model
public function grades()
{
return $this->belongsToMany(Grade::class, 'user_grade', 'user_id', 'grade_id');
}
Same for grade model:
public function users()
{
return $this->belongsToMany(User::class, 'user_grade', 'grade_id', 'user_id');
}
Finally you can use it in your blade file:
#if($grades = auth()->user()->grades)
<ul>
#foreach($grades as $grade)
<li>
<div class="grade">{{ $grade->name }}</div>
</li>
#endforeach
</ul>
#endif

Limit number of files that can be uploaded by user (Laravel 5.3)

I have this scenario in my app, a user can only upload one journal in each edition (an edition contains many journals from many users) but a user can also tag another users to entitle them as one of the journal authors if needed (tagged user will still be able to upload a journal to the same edition with a journal where the user is tagged in as the author if the user haven't upload any journal yet). So far I managed to make this happen except for limiting the number of files that can be uploaded in each edition. Below are my migrations :
Edition table :
class CreateTableEdition extends Migration {
public function up() {
Schema::create('edition', function (Blueprint $table) {
$table->increments('id');
$table->integer('volume');
$table->text('cover')->nullable();
$table->integer('number');
$table->timestamps();
});
Schema::table('journal', function(Blueprint $table) {
$table->foreign('id_edition')->references('id')->on('edition')->onDelete('cascade')->onUpdate('cascade');
});
}
public function down() {
Schema::table('journal', function(Blueprint $table) {
$table->dropForeign('journal_id_edition_foreign');
});
Schema::drop('edition');
}
}
Journal table :
class CreateTableJournal extends Migration {
public function up() {
Schema::create('journal', function (Blueprint $table) {
$table->increments('id');
$table->string('title', 255);
$table->text('abstract');
$table->text('file');
$table->integer('id_edition')->unsigned();
$table->integer('user_id')->unsigned();
$table->string('journalslug');
$table->timestamps();
});
Schema::table('journal', function(Blueprint $table) {
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
});
}
public function down() {
Schema::table('journal', function(Blueprint $table) {
$table->dropForeign('journal_user_id_foreign');
});
Schema::drop('journal');
}
}
Users table :
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('username')->unique();
$table->string('userslug');
$table->string('nameslug');
$table->string('email')->unique();
$table->string('phone')->nullable();
$table->string('address')->nullable();
$table->string('password');
$table->rememberToken();
$table->enum('level', ['admin', 'author']);
$table->timestamps();
});
}
public function down()
{
Schema::drop('users');
}
}
Penulis table (pivot table to connect users table and journal table)
public function up()
{
Schema::create('penulis', function (Blueprint $table) {
// Create tabel penulis
$table->integer('id_user')->unsigned()->index();
$table->integer('id_journal')->unsigned()->index();
$table->timestamps();
$table->primary(['id_user', 'id_journal']);
$table->foreign('id_user')
->references('id')
->on('users')
->onDelete('cascade')
->onUpdate('cascade');
$table->foreign('id_journal')
->references('id')
->on('journal')
->onDelete('cascade')
->onUpdate('cascade');
});
}
public function down()
{
Schema::drop('penulis');
}
}
-Edition table and Journal table has one-to-many relationship (one edition can have many journals)
-Users table and Journal table has multiple relationship, the first one is many-to-many relationship to enable a user tagging another user as one of the authors of the journal that he/she is going to upload. This relationship connected using a pivot table (penulis table). The second one is one-to-many relationship (one user has many journals) to make it possible that the user who uploaded the journal are the only one who can modify or deleting the journal (tagged users cannot).
Now back to the question, how to make this possible ? limiting the number of files that can be uploaded by users so that a user can only upload one journal in each edition. Below is my current controller to store the journal.
public function storejournal(JournalRequest $request) {
$input = $request->all();
$input['user_id'] = Auth::id();
//Input PDF
if ($request->hasFile('file')) {
$input['file'] = $this->uploadPDF($request);
}
$id = $request->id;
$journal = Edition::findOrFail($id)->journal()->create($input);
$journal->user()->attach($request->input('penulis'));
return redirect()->route('edition', ['id' => $id]);
}
If anyone can help that'd be great, thank you and sorry for my terrible English.
You could use Laravel Form Request Validator with Exists (not tested)
First, create the Form Request as such:
php artisan make:request JournalUserFormRequest
Then edit to check if the combination of id_journal and id_user already exists:
//JournalUserFormRequest
public function rules()
{
$user = Auth::user();
$edition = Edition::findOrFail($request->id)
return [
'id_journal' => [
'required',
Rule::exists('journal')->where(function ($query) {
$query->where('id_user', $user->id)
->where('id_edition', $edition->id);
}),
],
]
}
You can then take the validated request and store it.
public function storejournal(JournalUserFormRequest $request) {
$id = $request->id;
$journal = Edition::findOrFail($id)->journal()->create($input);
$journal->user()->attach($request->input('penulis'));
return redirect()->route('edition', ['id' => $id]);
}

One to Many not working on Laravel Eloquent

I have three models that are related. First I have User that belongs to a Role. On the other hand, Role has many roles. Role belongs to many permissions and Permissions belongs to many Role. I am using the AuthServiceProvider as suggested by jeffrey way of laracast. But the problem now, when I want to fetch all the permissions of a User I am having error which is, "Call to a member function getKey() on boolean". Can someone please help me on this. Please refer to the codes below.
User.php
public function role()
{
return $this->belongsTo('App\Role');
}
public function assignRole($role)
{
return $this->roles()->save(
Role::whereName($role)->firstOrFail()
);
}
public function hasRole($role)
{
if(is_string($role)){
return $this->role->contains('name', $role);
}
return !! $role->intersect($this->role)->count();
}
Role.php
class Role extends Model
{
public function users()
{
return $this->hasMany('App\User');
}
public function permissions()
{
return $this->belongsToMany('App\Permission');
}
public function givePermissions(Permission $permission)
{
return $this->permissions()->save($permission);
}
}
Permission.php
class Permission extends Model
{
public function roles()
{
return $this->belongsToMany('App\Role');
}
}
AuthServiceProvider
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
//get all permissions
foreach ($this->getPermissionTo() as $permission ) {
$gate->define($permission->name, function($user) use ($permission){
return $user->hasRole($permission->roles);
});
}
}
public function getPermissionTo()
{
return Permission::with('roles')->get();
}
and lastly, heres the user table that has a foreign key of role_id
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->integer('role_id')->unsigned();
$table->string('id_no')->unique()->index();
$table->string('u_first_name');
$table->string('u_middle_name');
$table->string('u_last_name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
roles table
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('label')->nullable();
$table->timestamps();
});
permissions table
Schema::create('permissions', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('label')->nullable();
$table->timestamps();
});
permission_role table
Schema::create('permission_role', function (Blueprint $table) {
$table->integer('permission_id')->unsigned();
$table->integer('role_id')->unsigned();
$table->foreign('permission_id')
->references('id')
->on('permissions')
->onDelete('cascade');
$table->foreign('role_id')
->references('id')
->on('roles')
->onDelete('cascade');
$table->primary(['permission_id', 'role_id']);
});
In the line: return !! $role->intersect($this->role)->count();, the part that says $this->role is probably not returning a collection, which is why you're getting this error. In Collection.php there's a method that iterates through all the items in a collection you send through the intersection method that gets the primary key of it. Because you're not sending a collection to the intersect() method, it tries to use the method getKey() in a boolean. Try:
return !! $role->intersect($this->role->get())->count();

Resources