src/Service/S3Service.php line 15

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use Aws\Exception\AwsException;
  4. use Aws\S3\S3Client;
  5. use Psr\Log\LoggerInterface;
  6. class S3Service
  7. {
  8.     private $s3Client;
  9.     private $bucket;
  10.     private $logger;
  11.     public function __construct(LoggerInterface $logger)
  12.     {
  13.         $this->s3Client = new S3Client([
  14.             'region' => $_ENV['AWS_REGION'],
  15.             'version' => 'latest',
  16.             'credentials' => [
  17.                 'key' => $_ENV['AWS_ACCESS_KEY_ID'],
  18.                 'secret' => $_ENV['AWS_SECRET_ACCESS_KEY'],
  19.             ],
  20.         ]);
  21.         $this->bucket $_ENV['AWS_BUCKET_NAME'];
  22.         $this->logger $logger;
  23.     }
  24.     /**
  25.      * Valide qu'une clé S3 n'est pas vide
  26.      */
  27.     private function validateKey($key)
  28.     {
  29.         if (empty($key) || trim($key) === '') {
  30.             throw new \InvalidArgumentException('La clé S3 ne peut pas être vide');
  31.         }
  32.         return trim($key);
  33.     }
  34.     public function listFiles($prefix '')
  35.     {
  36.         try {
  37.             $objects $this->s3Client->listObjectsV2([
  38.                 'Bucket' => $this->bucket,
  39.                 'Prefix' => $prefix,
  40.             ]);
  41.             return $objects['Contents'] ?? [];
  42.         } catch (\Exception $e) {
  43.             $this->logger->error("Erreur lors de la récupération des fichiers S3 : " $e->getMessage());
  44.             return [];
  45.         }
  46.     }
  47.     public function uploadDocument($content$key)
  48.     {
  49.         try {
  50.             // Validation et nettoyage de la clé
  51.             $cleanKey $this->validateKey($key);
  52.             $cleanKey str_replace(" ""_"$cleanKey);
  53.             $result $this->s3Client->putObject([
  54.                 'Bucket' => $this->bucket,
  55.                 'Key' => $cleanKey,
  56.                 'Body' => $content,
  57.                 'ACL' => 'private',
  58.                 'ServerSideEncryption' => 'AES256',
  59.             ]);
  60.             return $result->get('ObjectURL') ?? $result->get('Location');
  61.         } catch (\InvalidArgumentException $e) {
  62.             $this->logger->error("Clé S3 invalide : " $e->getMessage());
  63.             return false;
  64.         } catch (\Exception $e) {
  65.             $this->logger->error("Erreur lors de l'upload vers S3 : " $e->getMessage());
  66.             return false;
  67.         }
  68.     }
  69.     public function downloadDocument($s3Key)
  70.     {
  71.         try {
  72.             // Validation de la clé avant utilisation
  73.             $cleanKey $this->validateKey($s3Key);
  74.             $result $this->s3Client->getObject([
  75.                 'Bucket' => $this->bucket,
  76.                 'Key' => $cleanKey,
  77.             ]);
  78.             return $result['Body'];
  79.         } catch (\InvalidArgumentException $e) {
  80.             $this->logger->error("Clé S3 invalide pour le téléchargement : " $e->getMessage());
  81.             return false;
  82.         } catch (AwsException $e) {
  83.             $this->logger->error("Erreur AWS lors du téléchargement : " $e->getMessage());
  84.             return false;
  85.         }
  86.     }
  87.     public function getSignedUrl($key$expiration '+1 hour')
  88.     {
  89.         try {
  90.             // Validation de la clé
  91.             $cleanKey $this->validateKey($key);
  92.             $command $this->s3Client->getCommand('GetObject', [
  93.                 'Bucket' => $this->bucket,
  94.                 'Key' => $cleanKey,
  95.             ]);
  96.             $signedUrl $this->s3Client->createPresignedRequest($command$expiration)->getUri();
  97.             return (string)$signedUrl;
  98.         } catch (\InvalidArgumentException $e) {
  99.             $this->logger->error("Clé S3 invalide pour l'URL signée : " $e->getMessage());
  100.             return false;
  101.         } catch (\Exception $e) {
  102.             $this->logger->error("Erreur lors de la génération de l'URL signée : " $e->getMessage());
  103.             return false;
  104.         }
  105.     }
  106.     public function getJson($key)
  107.     {
  108.         try {
  109.             // Validation de la clé
  110.             $cleanKey $this->validateKey($key);
  111.             $result $this->s3Client->getObject([
  112.                 'Bucket' => $this->bucket,
  113.                 'Key' => $cleanKey,
  114.             ]);
  115.             return json_decode($result['Body'], true);
  116.         } catch (\InvalidArgumentException $e) {
  117.             $this->logger->error("Clé S3 invalide pour le JSON : " $e->getMessage());
  118.             throw $e;
  119.         } catch (\Exception $e) {
  120.             $this->logger->error("Erreur lors de la récupération du JSON depuis S3 : " $e->getMessage());
  121.             throw $e;
  122.         }
  123.     }
  124.     public function extractKeyFromUrl($url)
  125.     {
  126.         if (empty($url)) {
  127.             return '';
  128.         }
  129.         $parsedUrl parse_url($url);
  130.         if (isset($parsedUrl['path'])) {
  131.             // Supprime le premier slash initial "/" et les slashes multiples
  132.             $key ltrim($parsedUrl['path'], '/');
  133.             // Nettoie les slashes doubles
  134.             $key preg_replace('/\/+/''/'$key);
  135.             return $key;
  136.         }
  137.         return $url;
  138.     }
  139.     public function getFileFromS3($fileName)
  140.     {
  141.         try {
  142.             // Validation de la clé
  143.             $cleanFileName $this->validateKey($fileName);
  144.             $result $this->s3Client->getObject([
  145.                 'Bucket' => $this->bucket,
  146.                 'Key' => $cleanFileName,
  147.             ]);
  148.             return $result['Body'];
  149.         } catch (\InvalidArgumentException $e) {
  150.             $this->logger->error("Nom de fichier S3 invalide : " $e->getMessage());
  151.             return null;
  152.         } catch (AwsException $e) {
  153.             $this->logger->error("Error retrieving file from S3: " $e->getMessage());
  154.             return null;
  155.         }
  156.     }
  157.     /**
  158.      * Vérifie si un objet existe dans S3
  159.      */
  160.     public function objectExists($key)
  161.     {
  162.         try {
  163.             $cleanKey $this->validateKey($key);
  164.             $this->s3Client->headObject([
  165.                 'Bucket' => $this->bucket,
  166.                 'Key' => $cleanKey,
  167.             ]);
  168.             return true;
  169.         } catch (\Exception $e) {
  170.             return false;
  171.         }
  172.     }
  173. }