From 917db15e786af4b03bb4acd50b97bb490ce6c84b Mon Sep 17 00:00:00 2001 From: devoalda Date: Sun, 13 Aug 2023 08:35:26 +0800 Subject: [PATCH] fix(Frontend Fix): Fixed: - Model Relationships - Model Policies - Frontend UI --- .../Controllers/ProjectTodoController.php | 34 +++-- app/Http/Livewire/Pomo/Pomos.php | 2 +- app/Models/Project.php | 15 ++- app/Models/Todo.php | 9 +- app/Policies/ProjectPolicy.php | 10 +- app/Policies/TodoPolicy.php | 25 ++-- .../views/livewire/pomo/load-pomo.blade.php | 7 +- .../views/livewire/todo/todays-todo.blade.php | 61 ++++----- resources/views/todo/todo_list.blade.php | 127 +++++++++--------- tests/Feature/Project/TodoCRUDTest.php | 2 - 10 files changed, 151 insertions(+), 141 deletions(-) diff --git a/app/Http/Controllers/ProjectTodoController.php b/app/Http/Controllers/ProjectTodoController.php index ebe4dd1..36057fb 100644 --- a/app/Http/Controllers/ProjectTodoController.php +++ b/app/Http/Controllers/ProjectTodoController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers; use App\Http\Requests\Project\StoreTodoRequest; use App\Http\Requests\Project\UpdateTodoRequest; use App\Http\Resources\TodoResource; +use App\Models\Project; use App\Models\Todo; use App\Models\User; use Illuminate\Contracts\View\Factory; @@ -15,6 +16,7 @@ use Illuminate\Http\RedirectResponse; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Auth; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Gate; class ProjectTodoController extends Controller { @@ -23,26 +25,31 @@ class ProjectTodoController extends Controller /** * Display a listing of all Todos for a Project. */ - public function index(Request $request, $project_id): - Factory|Application|View|\Illuminate\Contracts\Foundation\Application|RedirectResponse|TodoResource + public function index(Request $request, $project_id): Factory|Application|View|RedirectResponse|TodoResource|JsonResponse { $user = Auth::user(); - $projects = $user->projects(); - $project = $projects->find($project_id); + $project = $user->projects()->find($project_id); + + if (!$project) { + if ($request->expectsJson()) { + return response()->json([ + 'message' => 'Project not found', + ], 404); + } + return redirect()->route('project.index') + ->with('error', 'Project not found'); + } + + $this->authorize('view', $project); if ($request->expectsJson()) { - $this->authorize('viewAny', [Todo::class, $project]); + $this->authorize('viewAny', $project); $todos = $project->todos()->paginate(4); return new TodoResource($todos); } - - if (!$project || $project->user->id !== $user->id) - return back() - ->with('error', 'Project not found'); - $todos = $project->todos; return view('todo.index', [ @@ -134,8 +141,11 @@ class ProjectTodoController extends Controller */ public function update($project_id, UpdateTodoRequest $request, Todo $todo) { - $project = auth()->user()->projects->find($project_id); - $this->authorize('update', [Todo::class, $project, $todo]); +// $project = auth()->user()->projects->find($project_id); + + if (Gate::denies('update', $todo)) { + return back()->with('error', 'You are not authorized to update this todo'); + } // Update other fields $todo->fill($request->validated()); diff --git a/app/Http/Livewire/Pomo/Pomos.php b/app/Http/Livewire/Pomo/Pomos.php index 0381077..2475059 100644 --- a/app/Http/Livewire/Pomo/Pomos.php +++ b/app/Http/Livewire/Pomo/Pomos.php @@ -30,7 +30,7 @@ class Pomos extends Component $user = User::find(auth()->id()); $pomos = Pomo::whereHas('todo', function ($query) use ($user) { - $query->whereHas('project', function ($query) use ($user) { + $query->whereHas('projects', function ($query) use ($user) { $query->whereHas('user', function ($query) use ($user) { $query->where('user_id', $user->id); }); diff --git a/app/Models/Project.php b/app/Models/Project.php index 5c37b6d..0fd62dc 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -30,17 +30,20 @@ class Project extends Model */ public function todos(): BelongsToMany { - return $this->belongsToMany(Todo::class, 'project_todo', 'project_id', 'todo_id'); + return $this->belongsToMany( + Todo::class, + 'project_todo', + 'project_id', + 'todo_id' + ); } - public function user(): HasOneThrough + public function user(): BelongsToMany { - return $this->hasOneThrough( + return $this->belongsToMany( User::class, - projectUser::class, + 'project_user', 'project_id', - 'id', - 'id', 'user_id' ); } diff --git a/app/Models/Todo.php b/app/Models/Todo.php index e01a134..e40dce4 100644 --- a/app/Models/Todo.php +++ b/app/Models/Todo.php @@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use App\Traits\UuidTrait; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Illuminate\Database\Eloquent\Relations\HasOneThrough; @@ -50,9 +51,13 @@ class Todo extends Model ->get(); } - public function project(): HasOneThrough + public function projects(): BelongsToMany { - return $this->hasOneThrough(Project::class, projectTodo::class, 'todo_id', 'id', 'id', 'project_id'); + return $this->belongsToMany( + Project::class, + 'project_todo', + 'todo_id', + 'project_id'); } diff --git a/app/Policies/ProjectPolicy.php b/app/Policies/ProjectPolicy.php index 499c77d..6b2f883 100644 --- a/app/Policies/ProjectPolicy.php +++ b/app/Policies/ProjectPolicy.php @@ -21,7 +21,7 @@ class ProjectPolicy */ public function view(User $user, Project $project): bool { - return $user->id === $project->user->id; + return $project->user->contains('id', $user->id); } /** @@ -37,7 +37,7 @@ class ProjectPolicy */ public function update(User $user, Project $project): bool { - return $user->id === $project->user->id; + return $project->user->contains('id', $user->id); } /** @@ -45,7 +45,7 @@ class ProjectPolicy */ public function delete(User $user, Project $project): bool { - return $user->id === $project->user->id; + return $project->user->contains('id', $user->id); } /** @@ -53,7 +53,7 @@ class ProjectPolicy */ public function restore(User $user, Project $project): bool { - return $user->id === $project->user->id; + return $project->user->contains('id', $user->id); } /** @@ -61,6 +61,6 @@ class ProjectPolicy */ public function forceDelete(User $user, Project $project): bool { - return $user->id === $project->user->id; + return $project->user->contains('id', $user->id); } } diff --git a/app/Policies/TodoPolicy.php b/app/Policies/TodoPolicy.php index ac18f54..1cffcaa 100644 --- a/app/Policies/TodoPolicy.php +++ b/app/Policies/TodoPolicy.php @@ -5,10 +5,13 @@ namespace App\Policies; use App\Models\Project; use App\Models\Todo; use App\Models\User; +use Illuminate\Auth\Access\HandlesAuthorization; use Illuminate\Auth\Access\Response; class TodoPolicy { + use HandlesAuthorization; + /** * Determine whether the user can view any models. */ @@ -22,7 +25,8 @@ class TodoPolicy */ public function view(User $user, Project $project, Todo $todo): bool { - return $user->id === $todo->project->user->id; + // Check if user is owner of project and todo + return $project->user->contains('id', $user->id) && $todo->projects->contains('id', $project->id); } /** @@ -36,12 +40,11 @@ class TodoPolicy /** * Determine whether the user can update the model. */ - public function update(User $user, Project $project, Todo $todo): bool + public function update(User $user, Todo $todo): bool { - if (!$project || $project->user->id !== $user->id || $todo->user()[0]->id !== $user->id) - return false; + $project = $todo->projects->first(); - return $user->id === $todo->project->user->id; + return $project->user->contains('id', $user->id) && $todo->projects->contains('id', $project->id); } /** @@ -49,7 +52,9 @@ class TodoPolicy */ public function delete(User $user, Todo $todo): bool { - return $user->id === $todo->project->user->id; + $project = $todo->projects->first(); + + return $project->user->contains('id', $user->id); } /** @@ -57,7 +62,9 @@ class TodoPolicy */ public function restore(User $user, Todo $todo): bool { - return $user->id === $todo->project->user->id; + $project = $todo->projects->first(); + + return $project->user->contains('id', $user->id); } /** @@ -65,6 +72,8 @@ class TodoPolicy */ public function forceDelete(User $user, Todo $todo): bool { - return $user->id === $todo->project->user->id; + $project = $todo->projects->first(); + + return $project->user->contains('id', $user->id); } } diff --git a/resources/views/livewire/pomo/load-pomo.blade.php b/resources/views/livewire/pomo/load-pomo.blade.php index 296d84c..f9bbb19 100644 --- a/resources/views/livewire/pomo/load-pomo.blade.php +++ b/resources/views/livewire/pomo/load-pomo.blade.php @@ -2,10 +2,11 @@ @foreach ($pomos as $pomo)
Start: {{ \Carbon\Carbon::createFromTimestamp($pomo->pomo_start)->format('d/m/Y H:i') }} diff --git a/resources/views/livewire/todo/todays-todo.blade.php b/resources/views/livewire/todo/todays-todo.blade.php index db706f7..284d628 100644 --- a/resources/views/livewire/todo/todays-todo.blade.php +++ b/resources/views/livewire/todo/todays-todo.blade.php @@ -5,56 +5,41 @@
@foreach ($todos as $todo) + @if ($todo->projects->isNotEmpty()) + @php + $project = $todo->projects->first(); + $due = null; - - + @if($todos->hasMorePages())