OwlCyberSecurity - MANAGER
Edit File: PushNotificationResource.php
<?php namespace App\Filament\Resources; use App\Filament\Resources\PushNotificationResource\Pages; use App\Filament\Resources\PushNotificationResource\RelationManagers; use App\Models\PushNotification; use Filament\Forms; use Filament\Forms\Components\Card; use Filament\Forms\Components\TextInput; use Filament\Forms\Form; use Filament\Notifications\Notification ; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Actions\BulkAction; use Filament\Tables\Filters\Filter; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Support\Facades\Http; use Filament\Tables\Columns\TextColumn; class PushNotificationResource extends Resource { protected static ?string $model = PushNotification::class; protected static ?string $navigationIcon = 'heroicon-o-bell'; protected static ?string $modelLabel = 'پوش نوتیفیکیشن'; protected static ?string $pluralModelLabel = 'پوش نوتیفیکیشن'; protected static ?string $slug = 'push_notification'; protected static ?string $navigationGroup = 'مدیریت کاربران'; protected static ?int $navigationSort = 8; public static function table(Table $table): Table { return $table ->columns([ TextColumn::make('user.name')->label('یوزر'), TextColumn::make('app_version')->label('نسخه ی برنامه'), TextColumn::make('endpoint')->label('توکن'), TextColumn::make('count')->label('تعداد ارسال'), TextColumn::make('created_at')->label('تاریخ'), ]) ->filters([ Filter::make('count') ->form([ TextInput::make('count') ->numeric() ->label('تعداد ارسال'), ]) ->query(function (Builder $query, array $data): Builder { return isset($data['count']) ? $query->where('count', $data['count']) : $query; }), Filter::make('less_than_count') ->form([ TextInput::make('less_than_count') ->numeric() ->label('کمتر از'), ]) ->query(function (Builder $query, array $data): Builder { return isset($data['less_than_count']) ? $query->where('count', '<=', $data['less_than_count']) : $query; }), Filter::make('more_than_count') ->form([ TextInput::make('more_than_count') ->numeric() ->label('بیشتر از'), ]) ->query(function (Builder $query, array $data): Builder { return isset($data['more_than_count']) ? $query->where('count', '>=', $data['more_than_count']) : $query; }), Filter::make('endpoint') ->form([ TextInput::make('endpoint') ->label('subscribe'), ]) ->query(function (Builder $query, array $data): Builder { return isset($data['endpoint']) ? $query->where('endpoint','like', $data['endpoint'].'%') : $query; }), ]) ->actions([ Tables\Actions\Action::make('softDelete') ->label('حذف') // Label for Soft Delete ->icon('heroicon-o-trash') // Add icon for better UX ->color('danger') // Color styling for delete action ->requiresConfirmation() ->action(function (PushNotification $record) { $record->delete(); // Soft delete the specific record Notification::make() ->title('Record Soft Deleted') ->body('رکورد با موفقیت حذف شد.') ->success() ->send(); }), ]) ->bulkActions([ BulkAction::make('sendNotification') ->label('ارسال نوتیفیکیشن') ->form([ Card::make() ->schema([ TextInput::make('title')->label('عنوان')->required(), TextInput::make('body')->label('بدنه')->required(), TextInput::make('url')->label('URL')->required(), ]), ]) ->action(function (Collection $recordIds, array $data) { $title = $data['title']; $body = $data['body']; $url = $data['url']; $subscribers = []; foreach ($recordIds as $recordId) { $record = PushNotification::where('id', $recordId->id)->first(); if ($record) { $subscribers[] = $record->endpoint; } } $sendNotification = function (array $subscribersList) use ($title, $body, $url) { $payload = [ "title" => $title, "body" => $body, "onclick_action" => 0, "url" => $url, "subscribers" => array_values($subscribersList), "utm" => [], "light_up_screen" => true, "buttons" => [], "icon" => "https://charsooq.com/assets/images/icons/logo2.png", ]; return Http::withHeaders([ 'Authorization' => 'Token 5533ba9efc68f03b2acc737a7c624928f926deab', 'X-api-key' => '9fa69ab5-c10d-4de1-a33f-16d6140ec7d8', ])->post('https://app.najva.com/api/v2/notification/management/send-direct/', $payload); }; $response = $sendNotification($subscribers); if ($response->successful()) { foreach ($recordIds as $recordId) { $record = PushNotification::where('id', $recordId->id)->first(); $record?->increment('count'); } Notification::make() ->body('نوتیفیکیشن ارسال شد') ->success() ->send(); } else { $errorMessage = $response->json() ?? $response->body(); $invalidSubscribers = $errorMessage['subscribers'] ?? []; $subscriberString = str_replace('Invalid subscriber: ', '', $invalidSubscribers[0]); $cleanedSubscribers = array_map('trim', explode(',', $subscriberString)); foreach ($cleanedSubscribers as $invalidSubscriber) { $key = array_search($invalidSubscriber, $subscribers); if ($key != false) { unset($subscribers[$key]); } PushNotification::where('endpoint', $invalidSubscriber)->delete(); } $retryResponse = $sendNotification($subscribers); if ($retryResponse->successful()) { foreach ($recordIds as $recordId) { $record = PushNotification::where('id', $recordId->id)->first(); if ($record && in_array($record->endpoint, $subscribers)) { $record->increment('count'); } } Notification::make() ->body('نوتیفیکیشن ارسال شد') ->success() ->send(); } else { Notification::make() ->body('نوتیفیکیشن ارسال نشد به خاطر: ' . $retryResponse->body()) ->danger() ->send(); } } }) ])->defaultSort('updated_at', 'desc'); } public static function getRelations(): array { return [ // ]; } public static function getPages(): array { return [ 'index' => Pages\ListPushNotifications::route('/'), // 'create' => Pages\CreatePushNotification::route('/create'), // 'edit' => Pages\EditPushNotification::route('/{record}/edit'), ]; } public static function canViewAny(): bool { return auth()->user()->can('push_notification::view'); } }