| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- <?php
- namespace App\Services;
- use Illuminate\Support\Facades\Storage;
- use Illuminate\Support\Facades\Log;
- use Illuminate\Http\UploadedFile;
- use Exception;
- class LogoUploadServices
- {
- /**
- * The storage disk to use for file operations
- */
- private $disk;
- /**
- * Allowed file extensions for logos
- */
- private const ALLOWED_EXTENSIONS = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
- /**
- * Maximum file size in KB
- */
- private const MAX_FILE_SIZE = 2048;
- /**
- * Constructor
- */
- public function __construct()
- {
- $this->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 [];
- }
- }
- }
|