Skip to content

Commit 4017a96

Browse files
Improve code
1 parent 4f56bd3 commit 4017a96

11 files changed

+81
-70
lines changed

database/migrations/2024_12_19_000003_create_push_notification_recipients_table.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function up(): void
2727
$table->string('error_message')->nullable();
2828
$table->timestamps();
2929

30-
$table->foreign('push_notification_id')->references('id')->on('push_notifications')->onDelete('cascade');
30+
$table->foreign('push_notification_id');
3131
$table->index(['push_notification_id', 'user_type', 'user_id'], 'pnr_notification_user_index');
3232
$table->index(['user_type', 'user_id', 'status'], 'pnr_user_status_index');
3333
$table->index(['user_type', 'user_id', 'read_at'], 'pnr_user_read_index');

src/Commands/ProcessScheduledNotificationsCommand.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public function handle(): int
4646

4747
if ($notifications->isEmpty()) {
4848
$this->info('✅ No scheduled notifications to process');
49+
4950
return self::SUCCESS;
5051
}
5152

@@ -63,33 +64,34 @@ public function handle(): int
6364

6465
foreach ($notifications as $notification) {
6566
$processed++;
66-
67+
6768
$this->line("Processing notification #{$notification->id}: {$notification->title}");
68-
69+
6970
if ($dryRun) {
70-
$this->line(" → Would send to: {$notification->target_type}" .
71+
$this->line(" → Would send to: {$notification->target_type}" .
7172
($notification->target_value ? " ({$notification->target_value})" : ''));
73+
7274
continue;
7375
}
7476

7577
try {
7678
$result = $this->sendNotification($notification);
77-
79+
7880
if ($result['success']) {
7981
$successful++;
8082
$this->line(" ✅ Sent successfully (sent: {$result['sent_count']}, failed: {$result['failed_count']})");
8183
} else {
8284
$failed++;
8385
$this->line(" ❌ Failed: {$result['message']}");
8486
}
85-
87+
8688
} catch (\Exception $e) {
8789
$failed++;
8890
$this->line(" ❌ Error: {$e->getMessage()}");
89-
91+
9092
// Mark notification as failed
9193
$notification->markAsFailed($e->getMessage());
92-
94+
9395
logger()->error('Scheduled notification processing failed', [
9496
'notification_id' => $notification->id,
9597
'error' => $e->getMessage(),
@@ -125,7 +127,7 @@ protected function sendNotification(PushNotification $notification): array
125127
'all' => $this->pushNotificationService->sendToAll($notificationData),
126128
'platform' => $this->pushNotificationService->sendToPlatform($notification->target_value, $notificationData),
127129
'user_type' => $this->pushNotificationService->sendToUserType($notification->target_value, $notificationData),
128-
'user' => $this->pushNotificationService->sendToUser('customer', (int)$notification->target_value, $notificationData),
130+
'user' => $this->pushNotificationService->sendToUser('customer', (int) $notification->target_value, $notificationData),
129131
default => throw new \InvalidArgumentException("Invalid target type: {$notification->target_type}")
130132
};
131133

src/Commands/SendPushNotificationCommand.php

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,14 @@ protected function handleInteractive(): int
5252
$title = $this->ask('Notification title');
5353
if (empty($title)) {
5454
$this->error('Title is required');
55+
5556
return self::FAILURE;
5657
}
5758

5859
$message = $this->ask('Notification message');
5960
if (empty($message)) {
6061
$this->error('Message is required');
62+
6163
return self::FAILURE;
6264
}
6365

@@ -73,16 +75,17 @@ protected function handleInteractive(): int
7375
} elseif ($target === 'user') {
7476
$userType = $this->choice('Select user type', ['customer', 'admin']);
7577
$userId = $this->ask('Enter user ID');
76-
if (!is_numeric($userId)) {
78+
if (! is_numeric($userId)) {
7779
$this->error('User ID must be numeric');
80+
7881
return self::FAILURE;
7982
}
8083
$targetValue = $userId;
8184
}
8285

8386
$actionUrl = $this->ask('Action URL (optional)');
8487
$imageUrl = $this->ask('Image URL (optional)');
85-
88+
8689
$addData = $this->confirm('Add custom data?', false);
8790
$data = null;
8891
if ($addData) {
@@ -91,6 +94,7 @@ protected function handleInteractive(): int
9194
$data = json_decode($dataInput, true);
9295
if (json_last_error() !== JSON_ERROR_NONE) {
9396
$this->error('Invalid JSON data');
97+
9498
return self::FAILURE;
9599
}
96100
}
@@ -99,8 +103,9 @@ protected function handleInteractive(): int
99103
$schedule = null;
100104
if ($this->confirm('Schedule notification?', false)) {
101105
$schedule = $this->ask('Schedule time (Y-m-d H:i:s format)');
102-
if ($schedule && !strtotime($schedule)) {
106+
if ($schedule && ! strtotime($schedule)) {
103107
$this->error('Invalid date format');
108+
104109
return self::FAILURE;
105110
}
106111
}
@@ -131,6 +136,7 @@ protected function handleNonInteractive(): int
131136

132137
if (empty($title) || empty($message)) {
133138
$this->error('Title and message are required. Use --title and --message options or run with --interactive');
139+
134140
return self::FAILURE;
135141
}
136142

@@ -140,6 +146,7 @@ protected function handleNonInteractive(): int
140146
// Validate target and target-value combination
141147
if (in_array($target, ['platform', 'user_type', 'user']) && empty($targetValue)) {
142148
$this->error("Target value is required when target is '{$target}'");
149+
143150
return self::FAILURE;
144151
}
145152

@@ -148,13 +155,15 @@ protected function handleNonInteractive(): int
148155
$data = json_decode($this->option('data'), true);
149156
if (json_last_error() !== JSON_ERROR_NONE) {
150157
$this->error('Invalid JSON data');
158+
151159
return self::FAILURE;
152160
}
153161
}
154162

155163
$schedule = $this->option('schedule');
156-
if ($schedule && !strtotime($schedule)) {
164+
if ($schedule && ! strtotime($schedule)) {
157165
$this->error('Invalid schedule date format');
166+
158167
return self::FAILURE;
159168
}
160169

@@ -189,6 +198,7 @@ protected function sendNotification(array $notificationData): int
189198
if (isset($notificationData['scheduled_at']) && $notificationData['scheduled_at']) {
190199
$this->info("✅ Notification scheduled for: {$notificationData['scheduled_at']}");
191200
$this->info("Notification ID: {$pushNotification->id}");
201+
192202
return self::SUCCESS;
193203
}
194204

@@ -205,6 +215,7 @@ protected function sendNotification(array $notificationData): int
205215
'error' => $e->getMessage(),
206216
'data' => $notificationData,
207217
]);
218+
208219
return self::FAILURE;
209220
}
210221
}
@@ -226,7 +237,8 @@ protected function sendBasedOnTarget(array $notificationData): array
226237

227238
case 'user':
228239
$userType = $notificationData['user_type'] ?? 'customer';
229-
return $this->pushNotificationService->sendToUser($userType, (int)$targetValue, $notificationData);
240+
241+
return $this->pushNotificationService->sendToUser($userType, (int) $targetValue, $notificationData);
230242

231243
default:
232244
throw new \InvalidArgumentException("Invalid target type: {$target}");
@@ -236,7 +248,7 @@ protected function sendBasedOnTarget(array $notificationData): array
236248
protected function displayResult(array $result, PushNotification $pushNotification): void
237249
{
238250
$this->line('');
239-
251+
240252
if ($result['success']) {
241253
$this->info('✅ Notification sent successfully!');
242254
} else {

src/Http/Controllers/ApiController.php

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Botble\Base\Facades\Assets;
1111
use Botble\Base\Http\Responses\BaseHttpResponse;
1212
use Botble\Setting\Http\Controllers\SettingController;
13+
use Exception;
1314
use Illuminate\Http\Request;
1415
use Illuminate\Support\Facades\Storage;
1516

@@ -90,25 +91,12 @@ public function sendNotification(SendNotificationRequest $request, BaseHttpRespo
9091
$target = $request->input('target', 'all');
9192

9293
// Send notification based on target
93-
switch ($target) {
94-
case 'android':
95-
$result = $pushService->sendToPlatform('android', $notification);
96-
97-
break;
98-
case 'ios':
99-
$result = $pushService->sendToPlatform('ios', $notification);
100-
101-
break;
102-
case 'customers':
103-
$result = $pushService->sendToUserType('customer', $notification);
104-
105-
break;
106-
case 'all':
107-
default:
108-
$result = $pushService->sendToAll($notification);
109-
110-
break;
111-
}
94+
$result = match ($target) {
95+
'android' => $pushService->sendToPlatform('android', $notification),
96+
'ios' => $pushService->sendToPlatform('ios', $notification),
97+
'customers' => $pushService->sendToUserType('customer', $notification),
98+
default => $pushService->sendToAll($notification),
99+
};
112100

113101
if ($result['success']) {
114102
return $response
@@ -168,7 +156,7 @@ public function uploadServiceAccount(Request $request, BaseHttpResponse $respons
168156
$missingFields = [];
169157

170158
foreach ($requiredFields as $field) {
171-
if (! isset($json[$field]) || empty($json[$field])) {
159+
if (empty($json[$field])) {
172160
$missingFields[] = $field;
173161
}
174162
}
@@ -211,7 +199,7 @@ public function uploadServiceAccount(Request $request, BaseHttpResponse $respons
211199
])
212200
->setMessage('Service account file uploaded and configured successfully');
213201

214-
} catch (\Exception $e) {
202+
} catch (Exception $e) {
215203
logger()->error('Failed to upload service account file', [
216204
'error' => $e->getMessage(),
217205
'file' => $e->getFile(),
@@ -240,7 +228,7 @@ public function removeServiceAccount(BaseHttpResponse $response)
240228
return $response
241229
->setMessage('Service account file removed successfully');
242230

243-
} catch (\Exception $e) {
231+
} catch (Exception $e) {
244232
logger()->error('Failed to remove service account file', [
245233
'error' => $e->getMessage(),
246234
'path' => setting('fcm_service_account_path'),

src/Http/Controllers/AuthenticationController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public function checkEmail(CheckEmailRequest $request, BaseHttpResponse $respons
161161
$user = ApiHelper::newModel()->where('email', $request->input('email'))->first();
162162

163163
$data = [
164-
'exists' => $user ? true : false,
164+
'exists' => (bool) $user,
165165
];
166166

167167
if ($user) {

src/Http/Controllers/DeviceTokenController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ public function destroyByToken(Request $request, BaseHttpResponse $response)
189189

190190
$userType = $this->getUserType($user);
191191

192-
$deviceToken = DeviceToken::where('token', $request->input('token'))
192+
$deviceToken = DeviceToken::query()->where('token', $request->input('token'))
193193
->forUser($userType, $user->id)
194194
->first();
195195

src/Http/Controllers/NotificationController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ public function destroy(Request $request, int $id, BaseHttpResponse $response)
255255
protected function getUserType($user): string
256256
{
257257
// Determine user type based on the model class
258-
$class = get_class($user);
258+
$class = $user::class;
259259

260260
if (str_contains($class, 'Customer')) {
261261
return 'customer';

src/Http/Middleware/ForceJsonResponseMiddleware.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public function handle(Request $request, Closure $next)
1616
if ($request->bearerToken()) {
1717
$user = Auth::guard('sanctum')->user();
1818

19-
if ($user && $user instanceof Authenticatable) {
19+
if ($user instanceof Authenticatable) {
2020
Auth::setUser($user);
2121
}
2222
}

src/Models/PushNotification.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Botble\Base\Models\BaseModel;
66
use Botble\Base\Models\Concerns\HasUuidsOrIntegerIds;
7+
use Carbon\Carbon;
78
use Illuminate\Database\Eloquent\Relations\BelongsTo;
89
use Illuminate\Database\Eloquent\Relations\HasMany;
910

@@ -42,6 +43,13 @@ class PushNotification extends BaseModel
4243
'read_count' => 'integer',
4344
];
4445

46+
protected static function booted(): void
47+
{
48+
static::deleting(function (PushNotification $pushNotification) {
49+
$pushNotification->recipients()->delete();
50+
});
51+
}
52+
4553
public function recipients(): HasMany
4654
{
4755
return $this->hasMany(PushNotificationRecipient::class);
@@ -73,7 +81,7 @@ public function scopeScheduled($query)
7381
{
7482
return $query->where('status', 'scheduled')
7583
->whereNotNull('scheduled_at')
76-
->where('scheduled_at', '<=', now());
84+
->where('scheduled_at', '<=', Carbon::now());
7785
}
7886

7987
public function markAsSent(int $sentCount = 0, int $failedCount = 0): void
@@ -82,15 +90,15 @@ public function markAsSent(int $sentCount = 0, int $failedCount = 0): void
8290
'status' => 'sent',
8391
'sent_count' => $sentCount,
8492
'failed_count' => $failedCount,
85-
'sent_at' => now(),
93+
'sent_at' => Carbon::now(),
8694
]);
8795
}
8896

8997
public function markAsFailed(?string $reason = null): void
9098
{
9199
$this->update([
92100
'status' => 'failed',
93-
'sent_at' => now(),
101+
'sent_at' => Carbon::now(),
94102
]);
95103
}
96104

@@ -129,13 +137,13 @@ public function isScheduled(): bool
129137

130138
public function canBeSent(): bool
131139
{
132-
return in_array($this->status, ['scheduled']) &&
140+
return $this->status == 'scheduled' &&
133141
(! $this->scheduled_at || $this->scheduled_at->isPast());
134142
}
135143

136144
public static function createFromRequest(array $data, ?int $createdBy = null): self
137145
{
138-
return static::create([
146+
return static::query()->create([
139147
'title' => $data['title'],
140148
'message' => $data['message'],
141149
'type' => $data['type'] ?? 'general',

0 commit comments

Comments
 (0)