disk = Storage::disk('s3'); } /** * Upload logo and manage client sub-folder * * @param UploadedFile $logoFile * @param mixed $azienda * @return string * @throws Exception */ public function uploadLogo(UploadedFile $logoFile, $azienda): string { try { $currentClient = session('currentClient', 'default'); if (!$currentClient) { throw new Exception('No current client found in session'); } $this->validateLogoFile($logoFile); $this->ensureClientFolderExists($currentClient); $this->deleteExistingLogo($currentClient); $logoPath = $this->uploadNewLogo($logoFile, $currentClient); $azienda->logo = $logoPath; $azienda->save(); Log::info("Logo uploaded successfully", [ 'client' => $currentClient, 'path' => $logoPath, 'azienda_id' => $azienda->id ?? null ]); return $logoPath; } catch (Exception $e) { Log::error('Error uploading logo', [ 'message' => $e->getMessage(), 'client' => session('currentClient'), 'azienda_id' => $azienda->id ?? null ]); throw $e; } } /** * Validate the uploaded logo file * * @param UploadedFile $logoFile * @throws Exception */ private function validateLogoFile(UploadedFile $logoFile): void { // Check if file is valid if (!$logoFile->isValid()) { throw new Exception('Invalid file upload'); } // Check file size if ($logoFile->getSize() > (self::MAX_FILE_SIZE * 1024)) { throw new Exception('File size exceeds maximum allowed size of ' . self::MAX_FILE_SIZE . 'KB'); } // Check file extension $extension = strtolower($logoFile->getClientOriginalExtension()); if (!in_array($extension, self::ALLOWED_EXTENSIONS)) { throw new Exception('File type not allowed. Allowed types: ' . implode(', ', self::ALLOWED_EXTENSIONS)); } // Check mime type $mimeType = $logoFile->getMimeType(); $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; if (!in_array($mimeType, $allowedMimeTypes)) { throw new Exception('Invalid file type'); } } /** * Ensure client folder exists in the bucket * * @param string $clientName * @throws Exception */ private function ensureClientFolderExists(string $clientName): void { try { $files = $this->disk->files($clientName); if (empty($files)) { $placeholderPath = $clientName . '/.gitkeep'; $this->disk->put($placeholderPath, ''); Log::info("Created client folder", ['client' => $clientName]); } } catch (Exception $e) { Log::error("Error creating client folder", [ 'client' => $clientName, 'error' => $e->getMessage() ]); throw new Exception("Failed to create client folder: " . $e->getMessage()); } } /** * Delete all existing logo files for the client * * @param string $clientName */ private function deleteExistingLogo(string $clientName): void { try { foreach (self::ALLOWED_EXTENSIONS as $extension) { $logoPath = $clientName . '/logo.' . $extension; if ($this->disk->exists($logoPath)) { $this->disk->delete($logoPath); Log::info("Deleted existing logo", [ 'client' => $clientName, 'file' => "logo.{$extension}" ]); } } } catch (Exception $e) { Log::warning("Error deleting existing logo", [ 'client' => $clientName, 'error' => $e->getMessage() ]); } } /** * Upload the new logo file * * @param UploadedFile $logoFile * @param string $clientName * @return string * @throws Exception */ private function uploadNewLogo(UploadedFile $logoFile, string $clientName): string { try { $extension = strtolower($logoFile->getClientOriginalExtension()); $fileName = 'logo.' . $extension; $logoPath = $this->disk->putFileAs( $clientName, $logoFile, $fileName, 'private' ); if (!$logoPath) { throw new Exception('Failed to upload file to storage'); } Log::info("Logo file uploaded", [ 'client' => $clientName, 'path' => $logoPath, 'size' => $logoFile->getSize() ]); return $logoPath; } catch (Exception $e) { Log::error("Error uploading logo file", [ 'client' => $clientName, 'error' => $e->getMessage() ]); throw new Exception("Failed to upload logo: " . $e->getMessage()); } } /** * Get a temporary URL for the logo * * @param mixed $azienda * @param string $expiresIn * @return string|null */ public function getLogoUrl($azienda, string $expiresIn = '+1 hour'): ?string { if (!$azienda->logo) { return null; } try { if (!$this->disk->exists($azienda->logo)) { Log::warning("Logo file not found", ['path' => $azienda->logo]); return null; } return $this->disk->temporaryUrl($azienda->logo, now()->add($expiresIn)); } catch (Exception $e) { Log::error("Error generating logo URL", [ 'path' => $azienda->logo, 'error' => $e->getMessage() ]); return null; } } /** * Check if logo file exists * * @param mixed $azienda * @return bool */ public function logoExists($azienda): bool { if (!$azienda->logo) { return false; } return $this->disk->exists($azienda->logo); } /** * Delete logo file and update database * * @param mixed $azienda * @return bool */ public function deleteLogo($azienda): bool { try { if ($azienda->logo && $this->disk->exists($azienda->logo)) { $this->disk->delete($azienda->logo); Log::info("Logo deleted", [ 'path' => $azienda->logo, 'azienda_id' => $azienda->id ?? null ]); $azienda->logo = null; $azienda->save(); return true; } return false; } catch (Exception $e) { Log::error("Error deleting logo", [ 'path' => $azienda->logo ?? 'unknown', 'error' => $e->getMessage() ]); return false; } } /** * Get logo file information * * @param mixed $azienda * @return array|null */ public function getLogoInfo($azienda): ?array { if (!$azienda->logo || !$this->disk->exists($azienda->logo)) { return null; } try { return [ 'path' => $azienda->logo, 'size' => $this->disk->size($azienda->logo), 'last_modified' => $this->disk->lastModified($azienda->logo), 'url' => $this->getLogoUrl($azienda), 'exists' => true ]; } catch (Exception $e) { Log::error("Error getting logo info", [ 'path' => $azienda->logo, 'error' => $e->getMessage() ]); return null; } } /** * List all logos for a client * * @param string|null $clientName * @return array */ public function listClientLogos(?string $clientName = null): array { $clientName = $clientName ?? session('currentClient'); if (!$clientName) { return []; } try { $files = $this->disk->files($clientName); return array_filter($files, function($file) { $filename = basename($file); return strpos($filename, 'logo.') === 0; }); } catch (Exception $e) { Log::error("Error listing client logos", [ 'client' => $clientName, 'error' => $e->getMessage() ]); return []; } } }