Skip to content

Commit fcd2ef2

Browse files
committed
refactor: improve event management architecture and code structure
- Separate business logic from controllers into EventService - Change value object to EventDetails for better data encapsulation - Update InstructorEventController to use EventService - Refactor request classes to include getEventDetails method - Improve code organization, readability and reduce controller complexity
1 parent 76f5a1a commit fcd2ef2

File tree

7 files changed

+136
-71
lines changed

7 files changed

+136
-71
lines changed

app/Http/Controllers/InstructorEventController.php

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,22 @@
66
use App\Http\Requests\UpdateInstructorEventRequest;
77
use App\Http\Resources\InstructorEventResource;
88
use App\Models\Event;
9-
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
9+
use App\Services\EventService;
10+
use Exception;
1011
use Illuminate\Http\Request;
12+
use Symfony\Component\HttpFoundation\Response;
1113

1214
class InstructorEventController extends Controller
1315
{
14-
use AuthorizesRequests;
16+
public function __construct(protected EventService $eventService) {}
1517

1618
/**
1719
* Display a listing of the resource.
1820
*/
1921
public function index(Request $request)
2022
{
2123
$instructor = $request->user();
22-
23-
$driverIds = $instructor->drivers->pluck('id');
24-
25-
$events = Event::whereIntegerInRaw('user_id', $driverIds)->with('driver')->get();
26-
24+
$events = $this->eventService->getInstructorEvents($instructor);
2725
return InstructorEventResource::collection($events);
2826
}
2927

@@ -32,52 +30,29 @@ public function index(Request $request)
3230
*/
3331
public function store(StoreInstructorEventRequest $request)
3432
{
35-
$validated = $request->validated();
36-
$dateRange = $request->getEventDateRange();
3733
$instructor = $request->user();
38-
$driver = $instructor->drivers()->findOrFail($validated['driver_id']);
34+
$eventDetails = $request->getEventDetails();
35+
$driverId = $request->validated('driver_id');
3936

40-
$event = $driver->events()->create([
41-
'title' => $validated['title'],
42-
'start' => $dateRange->start,
43-
'end' => $dateRange->end,
44-
]);
45-
$event->load('driver');
46-
47-
return response()->json(new InstructorEventResource($event), 201);
37+
return response()->json(new InstructorEventResource($this->eventService->createEvent($instructor, $eventDetails, $driverId)), Response::HTTP_CREATED);
4838
}
4939

5040
/**
5141
* Update the specified resource in storage.
5242
*/
5343
public function update(UpdateInstructorEventRequest $request, Event $event)
5444
{
55-
$validated = $request->validated();
56-
57-
$event->update([
58-
'title' => $validated['title'],
59-
'start' => $validated['start'],
60-
'end' => $validated['end'],
61-
]);
62-
$event->load('driver');
63-
64-
return response()->json(new InstructorEventResource($event));
45+
$eventDetails = $request->getEventDetails();
46+
return new InstructorEventResource($this->eventService->updateEvent($event, $eventDetails));
6547
}
6648

6749
/**
6850
* Remove the specified resource from storage.
51+
* @throws Exception
6952
*/
7053
public function destroy(Request $request, Event $event)
7154
{
72-
$instructor = $request->user();
73-
if (! $instructor->drivers()->where('id', $event->user_id)->exists()) {
74-
return response()->json(['message' => 'Unauthorized event'], 403);
75-
}
76-
77-
$this->authorize('delete', $event);
78-
79-
$event->delete();
80-
55+
$this->eventService->deleteEvent($request->user(), $event);
8156
return response()->noContent();
8257
}
8358
}

app/Http/Requests/StoreInstructorEventRequest.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace App\Http\Requests;
44

5-
use App\ValueObjects\EventDateRange;
5+
use App\ValueObjects\EventDetails;
66
use Illuminate\Foundation\Http\FormRequest;
77

88
class StoreInstructorEventRequest extends FormRequest
@@ -28,8 +28,11 @@ public function rules(): array
2828
];
2929
}
3030

31-
public function getEventDateRange(): EventDateRange
31+
/**
32+
* @throws \DateMalformedStringException
33+
*/
34+
public function getEventDetails(): EventDetails
3235
{
33-
return EventDateRange::fromArray($this->only(['start', 'end']));
36+
return EventDetails::fromArray($this->validated());
3437
}
3538
}

app/Http/Requests/UpdateInstructorEventRequest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace App\Http\Requests;
44

5+
use App\ValueObjects\EventDetails;
56
use Illuminate\Foundation\Http\FormRequest;
67

78
class UpdateInstructorEventRequest extends FormRequest
@@ -22,4 +23,12 @@ public function rules(): array
2223
'end' => 'required|date|after:start',
2324
];
2425
}
26+
27+
/**
28+
* @throws \DateMalformedStringException
29+
*/
30+
public function getEventDetails(): EventDetails
31+
{
32+
return EventDetails::fromArray($this->validated());
33+
}
2534
}

app/Models/Event.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
use Illuminate\Database\Eloquent\Model;
66
use Illuminate\Database\Eloquent\Relations\BelongsTo;
77

8+
/**
9+
* @method static whereIntegerInRaw(string $string, $driverIds)
10+
*/
811
class Event extends Model
912
{
1013
protected $fillable = ['title', 'start', 'end', 'user_id'];

app/Services/EventService.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace App\Services;
4+
5+
use App\Models\Event;
6+
use App\Models\User;
7+
use App\ValueObjects\EventDetails;
8+
use Exception;
9+
use Illuminate\Support\Collection;
10+
11+
class EventService
12+
{
13+
public function getInstructorEvents(User $instructor): Collection
14+
{
15+
$driverIds = $instructor->drivers()->pluck('id');
16+
return Event::whereIntegerInRaw('user_id', $driverIds)->with('driver')->get();
17+
}
18+
public function createEvent(User $instructor, EventDetails $eventDetails, int $driverId): Event
19+
{
20+
// Retrieve the driver and handle not-found logic
21+
$driver = $instructor->drivers()->findOrFail($driverId);
22+
23+
$event = $driver->events()->create($eventDetails->toArray());
24+
$event->load('driver');
25+
return $event;
26+
}
27+
28+
public function updateEvent(Event $event, EventDetails $eventDetails): Event
29+
{
30+
$event->update($eventDetails->toArray());
31+
$event->load('driver');
32+
return $event;
33+
}
34+
35+
/**
36+
* @throws Exception
37+
*/
38+
public function deleteEvent(User $instructor, Event $event): void
39+
{
40+
if (!$instructor->drivers()->where('id', $event->user_id)->exists()) {
41+
throw new Exception("Unauthorized action");
42+
}
43+
$event->delete();
44+
45+
}
46+
}

app/ValueObjects/EventDateRange.php

Lines changed: 0 additions & 31 deletions
This file was deleted.

app/ValueObjects/EventDetails.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
namespace App\ValueObjects;
4+
5+
use DateTimeImmutable;
6+
use InvalidArgumentException;
7+
8+
readonly class EventDetails
9+
{
10+
public DateTimeImmutable $start;
11+
public DateTimeImmutable $end;
12+
public string $title;
13+
14+
public function __construct(string $title, DateTimeImmutable $startDate, DateTimeImmutable $endDate)
15+
{
16+
if ($endDate <= $startDate) {
17+
throw new InvalidArgumentException('The end date must be after the start date.');
18+
}
19+
20+
$this->title = $title;
21+
$this->start = $startDate;
22+
$this->end = $endDate;
23+
}
24+
25+
public function getTitle(): string
26+
{
27+
return $this->title;
28+
}
29+
30+
public function getStart(): DateTimeImmutable
31+
{
32+
return $this->start;
33+
}
34+
35+
public function getEnd(): DateTimeImmutable
36+
{
37+
return $this->end;
38+
}
39+
40+
public function toArray(): array
41+
{
42+
return [
43+
'title' => $this->getTitle(),
44+
'start' => $this->getStart(),
45+
'end' => $this->getEnd(),
46+
];
47+
}
48+
49+
/**
50+
* @throws \DateMalformedStringException
51+
*/
52+
public static function fromArray(array $data): self
53+
{
54+
return new self(
55+
$data['title'],
56+
new DateTimeImmutable($data['start']),
57+
new DateTimeImmutable($data['end'])
58+
);
59+
}
60+
}

0 commit comments

Comments
 (0)