getFileService()->getFileUrl($filePath, $expiresIn); } /** * Check if file exists in S3 */ public function fileExists(?string $filePath): bool { if (!$filePath) { return false; } try { return \Illuminate\Support\Facades\Storage::disk('s3')->exists($filePath); } catch (\Exception $e) { Log::warning("Error checking file existence", [ 'path' => $filePath, 'error' => $e->getMessage() ]); return false; } } /** * Get file info */ public function getFileInfo(?string $filePath): ?array { if (!$filePath) { return null; } return $this->getFileService()->getFileInfo($filePath); } /** * Delete file from S3 */ public function deleteFile(string $filePath): bool { return $this->getFileService()->deleteFile($filePath); } /** * Get file name from path */ public function getFileName(?string $filePath): ?string { if (!$filePath) { return null; } return basename($filePath); } /** * Check if path is S3 path */ public function isS3Path(?string $path): bool { if (!$path) { return false; } return strpos($path, '/members/') !== false || strpos($path, session('currentClient', 'default')) === 0; } /** * Convert file paths array to string for database storage */ public function filePathsToString(array $paths): string { return implode('|', array_filter($paths)); } /** * Convert file paths string from database to array */ public function stringToFilePaths(?string $pathsString): array { if (!$pathsString) { return []; } return array_filter(explode('|', $pathsString)); } /** * Get multiple file URLs */ public function getMultipleFileUrls(array $filePaths): array { $urls = []; foreach ($filePaths as $path) { $url = $this->getFileUrl($path); if ($url) { $urls[$path] = $url; } } return $urls; } /** * Clean up files for deleted member */ public function cleanupMemberFiles(int $memberId): void { try { $currentClient = session('currentClient', 'default'); $memberPath = $currentClient . '/members/' . $memberId . '/'; $disk = \Illuminate\Support\Facades\Storage::disk('s3'); // Delete all files in member's folder $files = $disk->allFiles($memberPath); foreach ($files as $file) { $disk->delete($file); } // Delete empty directories $directories = $disk->allDirectories($memberPath); foreach (array_reverse($directories) as $directory) { $disk->deleteDirectory($directory); } Log::info("Cleaned up files for deleted member", ['member_id' => $memberId]); } catch (\Exception $e) { Log::error("Error cleaning up member files", [ 'member_id' => $memberId, 'error' => $e->getMessage() ]); } } /** * Validate file upload */ public function validateFileUpload($file, string $type = 'document'): array { $errors = []; if (!$file) { $errors[] = 'No file provided'; return $errors; } if (!$file->isValid()) { $errors[] = 'Invalid file upload'; return $errors; } $extension = strtolower($file->getClientOriginalExtension()); $size = $file->getSize(); if ($type === 'image') { $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif']; $maxSize = 2048 * 1024; // 2MB if (!in_array($extension, $allowedExtensions)) { $errors[] = 'Invalid image format. Allowed: ' . implode(', ', $allowedExtensions); } if ($size > $maxSize) { $errors[] = 'Image too large. Maximum size: 2MB'; } } elseif ($type === 'document') { $allowedExtensions = ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx']; $maxSize = 10240 * 1024; // 10MB if (!in_array($extension, $allowedExtensions)) { $errors[] = 'Invalid document format. Allowed: ' . implode(', ', $allowedExtensions); } if ($size > $maxSize) { $errors[] = 'Document too large. Maximum size: 10MB'; } } return $errors; } }