All checks were successful
Cadoles/nineskeletor/pipeline/pr-master This commit looks good
226 lines
6.5 KiB
PHP
226 lines
6.5 KiB
PHP
<?php
|
|
|
|
namespace App\Service;
|
|
|
|
use Aws\S3\Exception\S3Exception;
|
|
use Exception;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
use Symfony\Component\Filesystem\Filesystem;
|
|
|
|
|
|
class MinioService
|
|
{
|
|
const ERR_UNAVAILABLE = 'Service de gestion de fichiers momentanément indisponible.';
|
|
const ERR_FILE_NOT_FOUND = 'messages.minio.404';
|
|
|
|
private $rootPath;
|
|
private $client;
|
|
private $listClient;
|
|
private $minioBucket;
|
|
private $minioRoot;
|
|
private $minioPathStyle;
|
|
private $minioSecure;
|
|
|
|
public function __construct($rootPath, $minioUrl, $minioKey, $minioSecret, $minioBucket, $minioRoot, $minioPathstyle, $minioSecure)
|
|
{
|
|
$this->rootPath = $rootPath;
|
|
$this->minioBucket = $minioBucket;
|
|
$this->minioPathStyle = ($minioPathstyle==1?true:false);
|
|
$this->minioRoot = $minioRoot;
|
|
$this->client = $this->getClient($minioUrl, $minioKey, $minioSecret, $minioPathstyle, $minioSecure);
|
|
$this->initBucket();
|
|
}
|
|
|
|
public function download(string $file, string $filename, bool $usecache = true)
|
|
{
|
|
// On s'assure que le repertoire temporaire de destination existe bien
|
|
$fs = new Filesystem();
|
|
$tmpdir=$this->rootPath."/var/tmp";
|
|
$fs->mkdir($tmpdir."/".dirname($filename));
|
|
|
|
// Approche repassant par le serveur d'appel
|
|
if(!$usecache||!$fs->exists($tmpdir.'/'.$filename)) {
|
|
try {
|
|
$result = $this->client->getObject([
|
|
'Bucket' => $this->minioBucket,
|
|
'Key' => $this->minioRoot.$file,
|
|
'SaveAs' => $tmpdir.'/'.$filename,
|
|
]);
|
|
} catch (S3Exception $e) {
|
|
switch ($e->getResponse()->getStatusCode()) {
|
|
case 404:
|
|
throw new NotFoundHttpException(self::ERR_FILE_NOT_FOUND);
|
|
break;
|
|
default:
|
|
\Sentry\captureException($e);
|
|
throw new Exception(self::ERR_UNAVAILABLE);
|
|
break;
|
|
}
|
|
} catch (Exception $e) {
|
|
\Sentry\captureException($e);
|
|
throw new Exception(self::ERR_UNAVAILABLE);
|
|
}
|
|
}
|
|
|
|
return $tmpdir.'/'.$filename;
|
|
}
|
|
|
|
public function upload($file, $filename, $deleteSource = false)
|
|
{
|
|
try {
|
|
$this->client->putObject([
|
|
'Bucket' => $this->minioBucket,
|
|
'Key' => $this->minioRoot.$filename,
|
|
'SourceFile' => $file,
|
|
]);
|
|
} catch (Exception $e) {
|
|
\Sentry\captureException($e);
|
|
throw new Exception(self::ERR_UNAVAILABLE);
|
|
}
|
|
|
|
if ($deleteSource) {
|
|
$tmpdir=$this->rootPath."/var/tmp";
|
|
@unlink($tmpdir."/".$filename);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* move.
|
|
*
|
|
* @param bool $deleteSource
|
|
*
|
|
* @return void
|
|
*/
|
|
public function move(string $from, string $to, $deleteSource = false)
|
|
{
|
|
try {
|
|
$this->client->copyObject([
|
|
'Bucket' => $this->minioBucket,
|
|
'Key' => $this->minioRoot.$to,
|
|
'CopySource' => $this->minioBucket.'/'.$this->minioRoot.$from,
|
|
]);
|
|
} catch (Exception $e) {
|
|
\Sentry\captureException($e);
|
|
throw new Exception(self::ERR_UNAVAILABLE);
|
|
}
|
|
|
|
if ($deleteSource) {
|
|
$this->delete($from);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* delete.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function delete(string $file)
|
|
{
|
|
try {
|
|
$this->client->deleteObject([
|
|
'Bucket' => $this->minioBucket,
|
|
'Key' => $this->minioRoot.$file,
|
|
]);
|
|
} catch (Exception $e) {
|
|
\Sentry\captureException($e);
|
|
throw new Exception(self::ERR_UNAVAILABLE);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* countKeys.
|
|
*
|
|
* @return int
|
|
*/
|
|
public function countKeys(string $prefix)
|
|
{
|
|
//On utilise un path spécifique car listObjectsV2 utilise une autre config de client
|
|
try {
|
|
$response = $this->client->listObjectsV2([
|
|
'Bucket' => $this->minioBucket,
|
|
'Prefix' => $prefix,
|
|
]);
|
|
|
|
return $response->get('KeyCount');
|
|
} catch (Exception $e) {
|
|
\Sentry\captureException($e);
|
|
throw new Exception(self::ERR_UNAVAILABLE);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* listKeys.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function listKeys(string $prefix)
|
|
{
|
|
//On utilise un path spécifique car listObjectsV2 utilise une autre config de client
|
|
try {
|
|
$response = $this->client->listObjectsV2([
|
|
'Bucket' => $this->minioBucket,
|
|
'Prefix' => $prefix,
|
|
]);
|
|
|
|
return $response->get('Contents');
|
|
} catch (Exception $e) {
|
|
\Sentry\captureException($e);
|
|
throw new Exception(self::ERR_UNAVAILABLE);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* download.
|
|
*
|
|
* @param string $file Nom du fichier dans minio
|
|
* @param string $filename Nom du fichier dans la réponse
|
|
* @param bool $returnFile Retourner un fichier ou une réponse
|
|
*/
|
|
|
|
|
|
protected function getClient($minioUrl, $minioKey, $minioSecret, bool $minioPathstyle, bool $minioSecure)
|
|
{
|
|
$client = new \Aws\S3\S3Client([
|
|
'version' => 'latest',
|
|
'region' => 'eu-west-1',
|
|
'endpoint' => $minioUrl,
|
|
//On force le mode DNS
|
|
'use_path_style_endpoint' => $minioPathstyle,
|
|
'credentials' => [
|
|
'key' => $minioKey,
|
|
'secret' => $minioSecret,
|
|
],
|
|
//On désactive les checks SSL pour le moment
|
|
'http' => [
|
|
'verify' => $minioSecure,
|
|
],
|
|
]);
|
|
|
|
return $client;
|
|
}
|
|
|
|
protected function initBucket()
|
|
{
|
|
try {
|
|
$bucketExists = false;
|
|
|
|
$buckets = $this->client->listBuckets()->toArray()['Buckets'];
|
|
|
|
foreach ($buckets as $bucket) {
|
|
if ($this->minioBucket == $bucket['Name']) {
|
|
$bucketExists = true;
|
|
}
|
|
}
|
|
|
|
if (!$bucketExists) {
|
|
$this->client->createBucket([
|
|
'Bucket' => $this->minioBucket,
|
|
]);
|
|
}
|
|
} catch (Exception $e) {
|
|
throw new Exception(self::ERR_UNAVAILABLE);
|
|
}
|
|
}
|
|
}
|