I'm currently working on a Laravel project that requires a home owner to log in to the website. Then, he/she is required to fill a form on guest details. When he/she submits the form, it will be displayed in a list. Now, when a home owner submits a form, every other home owner can see it too. How can I make it so that only the logged in home owner able to see his/her list of guests? Is this possible to do?
My GuestController is as follows:
class GuestController extends Controller
{
public function index()
{
//returns admin's view
$guest = Guest::all();
return view('pages.guest.index', compact('guest'));
}
public function show()
{
//returns a home owner's view
$guest = Guest::all();
return view('pages.guest.show', compact('guest'));
}
public function create()
{
return view('pages.guest.create');
}
public function store(Request $request)
{
$guest = new Guest;
$guest->code = random_int(100000, 999999);
$guest->hash = hash('sha256', $guest['code']);
$guest->owner = Auth::user()->name;
$guest->unit = Auth::user()->unit;
$guest->guestname = $request->input('guestname');
$guest->guestphone = $request->input('guestphone');
$guest->guestic = $request->input('guestic');
$guest->guestcar = $request->input('guestcar');
$guest->datevisit = $request->input('datevisit');
$guest->timevisit = $request->input('timevisit');
$guest->save();
return redirect('show-pass')->with('status', 'Guest Added Successfully');
}
At the database level, make the owner a foreign key on the guests table. I am guessing that the owners belong to users table, so you will have something like this in your migration file
//...
Schema::create('guests', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained();
$table->bigUnsignedInteger('code');
//...
});
So your store method will be as
public function store(Request $request)
{
$guest = new Guest;
$guest->code = random_int(100000, 999999);
$guest->user_id = Auth::id();
//...
return redirect('show-pass')->with('status', 'Guest Added Successfully');
}
And then your index() method will be
public function index()
{
//returns admin's view
$guest = Guest::where('user_id', Auth::id())->get();
return view('pages.guest.index', compact('guest'));
}
PS: you should define relationships in the respective User and Guest models to make things even smoother.
You can try something like this. I am expecting this function will call when a user other than admin login and want to see list of his guests. Please check documentation as well.
public function show()
{
//returns a home owner's view
$guest = Guest::where('owner',Auth::user()->name)->get();
return view('pages.guest.show', compact('guest'));
}
Whenever you store a form, make sure you store the logged user's ID too and not just the name. You may encounter problems in the future if there are multiple users with the same name.
For your guests database, you should create a column with users id as foreign key. Once you're able to do that and you name the column as owner_id for example, add this to your store function
$guest->owner_id = Auth::user()->id;
You can now do this with your show function
public function show()
{
//returns a home owner's view
$guest = Guest::where('owner_id', '=', Auth::user()->id)->get();
return view('pages.guest.show', compact('guest'));
}
Related
I have two tables in Database, user table and meeting table.
when a user login successfully I want that the information in the meeting table shown to them.
but not all of them just the one which he created them or invited to.
this ids my route:
Route::get('/dashboard/per_user{id}',[meetingController::class, 'meet_for_user'])-
>name('meet_for_user');
this is my controller:
public function meet_for_user()
{
$meetings=meeting::with('users')->get();
return view('dashboard', compact('meetings'));
}
this is user model:
public function meeting()
{
return $this->hasMany(meeting::class,'idCreateMeeting','id');
}
this is meeting model:
public function users()
{
return $this->belongsTo(User::class,'idCreateMeeting','id');
}
If you change how your route is defined to expect a User id, you can use route model binding to inject the User into your controller method and get their meetings from there.
Route::get('/dashboard/per_user/{user}',[meetingController::class, 'meet_for_user'])
->name('meet_for_user');
public function meet_for_user(User $user)
{
$meetings = $user->meetings;
return view('dashboard', compact('meetings'));
}
So if a user wants to edit their own ticket they can do it from a form. But if they change the ID in the form, they can also edit another user's ticket. How do I prevent this?
public function edit(Ticket $ticket)
{
$user = request()->user()->ticket()->get();
if ($ticket === $user){
return view('users.tickets.edit',['ticket' => $ticket,]);
}
else{
abort(403);
}
}
It automatically pick abort 403
This is the user Model
public function ticket(){
return $this->belongsToMany(Ticket::class, 'ticket_user');
}
This is the ticket model
public function users() {
return $this->belongsToMany(User::class, 'ticket_user');
}
The logic itself could look like this:
$ticket->users->contains($request->user())
In your controller it could look like this:
use Illuminate\Http\Request;
public function edit(Request $request, Ticket $ticket)
{
if (! $ticket->users->contains($request->user())) {
return abort(403);
}
return view('users.tickets.edit', [
'ticket' => $ticket
]);
}
Docs for Collection::contains.
I suggest looking into how you could exclude your authorisation logic into gates and policies.
The right implementation for me looks like this.
The models:
*User
id
...
*Ticket
id
...
UserTicket
*id
*ticket_id
*user_id
When you create a ticket you have to create a new UserTicket for any user is able to edit the ticket.
Then you check if there is a record in UserTicket that has the user_id.
For example:
The Ticket model
public function users()
{
return $this->hasManyThrough(UserTicket::class, User::class);
}
And the edit controller
public function edit(Ticket $ticket)
{
$currentUser = request()->user();
$ticketUsers = $ticket->users;
// loop each ticketUser and check their id == $currentUser->id
}
I am trying to return view where Task Created will have each user assigned to them.
Example
In my view blade, I click on Task Name -> it should return a view of task assign under task id 1 to add users to work on the task
Task Controller
public function show($id)
{
$task = Task::find($id);
$task->task_assignments = TaskAssignment::where('task_id', $task->id)->get();
return view('tAssignments.index')->with('task', $task);
}
Task Assignment Controller
public function show($id)
{
$task = Task::find($id);
$task_assignments = TaskAssignment::find($id);
return view('tAssignments.index', compact('task', 'task_assignments'));
}
Just fetch the data for that user about whom you want to know
Use
->findOrFail(id)
Return that data in the view file and render it according to use.
If you want it more perfectly you may use a ajax call .
This is how i manage to answer and pass the variable. Please let me know if there is any better view
public function show($id)
{
$task = Task::findOrFail($id);
$task_assignment = TaskAssignment::find($id);
$task->task_assignments = TaskAssignment::where('task_id', $task->id)->get();
return view('tAssignments.index', compact('task', 'task_assignment'))->with('task_id', $task->id);
}
For example:
when a user logged or registered in for the first time and didnt make a profile yet is there anyway u can check where ever he made a profile so u can send him an alert to make one incase he didnt make a profile yet.
Does laravel have Helper functions for that or u need to do someting like this?
if(\Auth::check())
{
$user_id = \Auth::user()->id;
$profile = Profile::where('id', $profile->id)->where('user_id', $user_id)->first();
if($profile->count() > 0 ) {
return false;
} else {
return true;
}
}
Assuming you want a Profiletable to hold information from the User without merging them together, you will want to:
Run on the project root folder:
php artisan make:migration:schema create_profiles_table --schema="user_id:integer:foreign, title:string"
Create the relationship:
User Model
public function profiles()
{
return $this->hasOne('App\Profile', 'id', 'user_id');
}
Profile Model
public function users()
{
return $this->belongsTo('App\User', 'user_id', 'id');
}
Check if a User have a profile:
In your controller
if (is_null(Auth::user()->profiles)) {
//your logic here
}
My Shema database is
User Table
id
login
parent
Sign Table
id
name
user_id (Sign owner)
Pivot table user_sign
id
user_id
sign_id
My User model contain
public function signs() {
return $this->belongsToMany('App\Sign', 'user_sign');
}
public function parent(){
return $this->belongsTo('User', 'parent');
}
public function children(){
return $this->hasMany('User', 'parent', 'user_id');
}
And my Sign model contain
public function users() {
return $this->belongsToMany('App\User', 'user_sign')->select(['users.id','name']);
}
A parent user can attach / sync Sign to a child user via this route (he send sign_id and child_id)
Route::put('sign/share', 'SignController#share')
To do this action, in my controller i must check :
- if Owner of sign_id is $user_id
- If child_id is child of $user_id
And after that, i do my attach / sync.
Now, in my controller i have :
public function share(Request $request)
{
$userId = $request->input('user_id');
$sign = Sign::where('user_id', $userId)->find($id);
if(!$sign){
return response()->json(['message'=>'FAIL'], 404);
}
}
But I completely blocked after this... It's possible to check and attach in one line ?
Thanks for your help
As far as syncing/attaching you can use this sytanx
$user->roles()->sync([1, 2, 3]);
As given in Laravel Docs
You can do the both checks in the condition of IF and assign in case of true, thats how your controller will look like finally.
public function share(Request $request)
{
$userId = $request->input('user_id');
$signId = $request->input('sign_id');
$childId = $request->input('child_id');
if (Sign::find($singId)->user_id == $userId && User::find($userId)->child_id == $childId)
{
//Attach the sign to child user
User::find($childId)->signs()->attach($signId);
}
else
{
return response()->json(['message'=>'FAIL'], 404);
}
}