diff --git a/.env b/.env
index 72d334f..6ac6765 100644
--- a/.env
+++ b/.env
@@ -120,10 +120,14 @@ MERCURE_URL=https://127.0.0.1/.well-known/mercure
MERCURE_PUBLIC_URL=https://127.0.0.1/.well-known/mercure
MERCURE_JWT_SECRET="!ChangeMe!"
-# Messenger
-# MESSENGER_TRANSPORT_DSN=doctrine://default
-# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
-# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
+# Minio
+MINIO_URL=http://127.0.0.1:9000
+MINIO_KEY=minio
+MINIO_SECRET=changeme
+MINIO_BUCKET=nine
+MINIO_ROOT=
+MINIO_PATH_STYLE=1
+MINIO_SECURE=0
# Lock
LOCK_DSN="postgresql://symfony:ChangeMe@127.0.0.1:5432/app?serverVersion=13&charset=utf8"
diff --git a/composer.json b/composer.json
index f898b90..a64f2a9 100644
--- a/composer.json
+++ b/composer.json
@@ -7,6 +7,7 @@
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
+ "aws/aws-sdk-php": "^3.234",
"doctrine/annotations": "^1.0",
"doctrine/doctrine-bundle": "^2.6",
"doctrine/doctrine-migrations-bundle": "^3.2",
diff --git a/composer.lock b/composer.lock
index 1513f3f..4bab223 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,150 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "55a8fc0f19cbcfaa9fd74ecf5d8ff8d5",
+ "content-hash": "b10025eb97ca0ec25b18857a1f4c520f",
"packages": [
+ {
+ "name": "aws/aws-crt-php",
+ "version": "v1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/awslabs/aws-crt-php.git",
+ "reference": "3942776a8c99209908ee0b287746263725685732"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/3942776a8c99209908ee0b287746263725685732",
+ "reference": "3942776a8c99209908ee0b287746263725685732",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35|^5.4.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "AWS SDK Common Runtime Team",
+ "email": "aws-sdk-common-runtime@amazon.com"
+ }
+ ],
+ "description": "AWS Common Runtime for PHP",
+ "homepage": "http://aws.amazon.com/sdkforphp",
+ "keywords": [
+ "amazon",
+ "aws",
+ "crt",
+ "sdk"
+ ],
+ "support": {
+ "issues": "https://github.com/awslabs/aws-crt-php/issues",
+ "source": "https://github.com/awslabs/aws-crt-php/tree/v1.0.2"
+ },
+ "time": "2021-09-03T22:57:30+00:00"
+ },
+ {
+ "name": "aws/aws-sdk-php",
+ "version": "3.234.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/aws/aws-sdk-php.git",
+ "reference": "d2113f1e5ec9f7f19de2472f5063333b39a55280"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/d2113f1e5ec9f7f19de2472f5063333b39a55280",
+ "reference": "d2113f1e5ec9f7f19de2472f5063333b39a55280",
+ "shasum": ""
+ },
+ "require": {
+ "aws/aws-crt-php": "^1.0.2",
+ "ext-json": "*",
+ "ext-pcre": "*",
+ "ext-simplexml": "*",
+ "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5",
+ "guzzlehttp/promises": "^1.4.0",
+ "guzzlehttp/psr7": "^1.8.5 || ^2.3",
+ "mtdowling/jmespath.php": "^2.6",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "andrewsville/php-token-reflection": "^1.4",
+ "aws/aws-php-sns-message-validator": "~1.0",
+ "behat/behat": "~3.0",
+ "composer/composer": "^1.10.22",
+ "doctrine/cache": "~1.4",
+ "ext-dom": "*",
+ "ext-openssl": "*",
+ "ext-pcntl": "*",
+ "ext-sockets": "*",
+ "nette/neon": "^2.3",
+ "paragonie/random_compat": ">= 2",
+ "phpunit/phpunit": "^4.8.35 || ^5.6.3",
+ "psr/cache": "^1.0",
+ "psr/simple-cache": "^1.0",
+ "sebastian/comparator": "^1.2.3"
+ },
+ "suggest": {
+ "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications",
+ "doctrine/cache": "To use the DoctrineCacheAdapter",
+ "ext-curl": "To send requests using cURL",
+ "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages",
+ "ext-sockets": "To use client-side monitoring"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions.php"
+ ],
+ "psr-4": {
+ "Aws\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "Amazon Web Services",
+ "homepage": "http://aws.amazon.com"
+ }
+ ],
+ "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project",
+ "homepage": "http://aws.amazon.com/sdkforphp",
+ "keywords": [
+ "amazon",
+ "aws",
+ "cloud",
+ "dynamodb",
+ "ec2",
+ "glacier",
+ "s3",
+ "sdk"
+ ],
+ "support": {
+ "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
+ "issues": "https://github.com/aws/aws-sdk-php/issues",
+ "source": "https://github.com/aws/aws-sdk-php/tree/3.234.0"
+ },
+ "time": "2022-08-22T18:20:42+00:00"
+ },
{
"name": "brick/math",
"version": "0.9.3",
@@ -1962,6 +2104,130 @@
},
"time": "2022-01-11T08:28:06+00:00"
},
+ {
+ "name": "guzzlehttp/guzzle",
+ "version": "7.4.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle.git",
+ "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/1dd98b0564cb3f6bd16ce683cb755f94c10fbd82",
+ "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "guzzlehttp/promises": "^1.5",
+ "guzzlehttp/psr7": "^1.9 || ^2.4",
+ "php": "^7.2.5 || ^8.0",
+ "psr/http-client": "^1.0",
+ "symfony/deprecation-contracts": "^2.2 || ^3.0"
+ },
+ "provide": {
+ "psr/http-client-implementation": "1.0"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.4.1",
+ "ext-curl": "*",
+ "php-http/client-integration-tests": "^3.0",
+ "phpunit/phpunit": "^8.5.5 || ^9.3.5",
+ "psr/log": "^1.1 || ^2.0 || ^3.0"
+ },
+ "suggest": {
+ "ext-curl": "Required for CURL handler support",
+ "ext-intl": "Required for Internationalized Domain Name (IDN) support",
+ "psr/log": "Required for using the Log middleware"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.4-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
+ "psr-4": {
+ "GuzzleHttp\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ },
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Jeremy Lindblom",
+ "email": "jeremeamia@gmail.com",
+ "homepage": "https://github.com/jeremeamia"
+ },
+ {
+ "name": "George Mponos",
+ "email": "gmponos@gmail.com",
+ "homepage": "https://github.com/gmponos"
+ },
+ {
+ "name": "Tobias Nyholm",
+ "email": "tobias.nyholm@gmail.com",
+ "homepage": "https://github.com/Nyholm"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://github.com/sagikazarmark"
+ },
+ {
+ "name": "Tobias Schultze",
+ "email": "webmaster@tubo-world.de",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "Guzzle is a PHP HTTP client library",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "psr-18",
+ "psr-7",
+ "rest",
+ "web service"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/guzzle/issues",
+ "source": "https://github.com/guzzle/guzzle/tree/7.4.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/Nyholm",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-06-20T22:16:13+00:00"
+ },
{
"name": "guzzlehttp/promises",
"version": "1.5.1",
@@ -2701,6 +2967,67 @@
],
"time": "2022-06-09T09:09:00+00:00"
},
+ {
+ "name": "mtdowling/jmespath.php",
+ "version": "2.6.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/jmespath/jmespath.php.git",
+ "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/9b87907a81b87bc76d19a7fb2d61e61486ee9edb",
+ "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.4 || ^7.0 || ^8.0",
+ "symfony/polyfill-mbstring": "^1.17"
+ },
+ "require-dev": {
+ "composer/xdebug-handler": "^1.4 || ^2.0",
+ "phpunit/phpunit": "^4.8.36 || ^7.5.15"
+ },
+ "bin": [
+ "bin/jp.php"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/JmesPath.php"
+ ],
+ "psr-4": {
+ "JmesPath\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Declaratively specify how to extract elements from a JSON document",
+ "keywords": [
+ "json",
+ "jsonpath"
+ ],
+ "support": {
+ "issues": "https://github.com/jmespath/jmespath.php/issues",
+ "source": "https://github.com/jmespath/jmespath.php/tree/2.6.1"
+ },
+ "time": "2021-06-14T00:11:39+00:00"
+ },
{
"name": "nelmio/api-doc-bundle",
"version": "v4.9.0",
@@ -12879,5 +13206,5 @@
"ext-iconv": "*"
},
"platform-dev": [],
- "plugin-api-version": "2.2.0"
+ "plugin-api-version": "2.3.0"
}
diff --git a/config/routes.yaml b/config/routes.yaml
index f86600f..fa16e6a 100644
--- a/config/routes.yaml
+++ b/config/routes.yaml
@@ -18,11 +18,6 @@ app_modo_home:
controller: App\Controller\HomeController::homemodo
defaults: { access: modo }
-app_ckeditor_upload:
- path: /user/upload
- controller: App\Controller\HomeController::upload
- defaults: { access: user }
-
oneup_uploader:
resource: .
type: uploader
@@ -160,6 +155,50 @@ app_user_crop02:
path: /user/crop02/{type}/{reportinput}
controller: App\Controller\CropController::crop02
+#== Minio =======================================================================================================
+
+#-- Access admin
+app_admin_minio_image:
+ path: /admin/minio/image
+ controller: App\Controller\MinioController::image
+
+app_admin_minio_document:
+ path: /admin/minio/document
+ controller: App\Controller\MinioController::document
+
+#-- Access modo
+app_modo_minio_image:
+ path: /modo/minio/image
+ controller: App\Controller\MinioController::image
+
+app_modo_minio_document:
+ path: /modo/minio/document
+ controller: App\Controller\MinioController::document
+
+#-- Access user
+app_user_minio_image:
+ path: /user/minio/image
+ controller: App\Controller\MinioController::image
+
+app_user_minio_document:
+ path: /user/minio/document
+ controller: App\Controller\MinioController::document
+
+#-- Access public
+app_minio_image:
+ path: /minio/image
+ controller: App\Controller\MinioController::image
+
+app_minio_document:
+ path: /minio/document
+ controller: App\Controller\MinioController::document
+
+#== Ckeditor ====================================================================================================
+app_ckeditor_upload:
+ path: /user/upload
+ controller: App\Controller\MinioController::ckupload
+ defaults: { access: user }
+
#== Audit =======================================================================================================
#--Access admin
@@ -168,7 +207,6 @@ app_admin_audit_renderid:
controller: App\Controller\AuditController::auditrender
defaults: { access: admin }
-#--Access admin
app_admin_audit_render:
path: /admin/audit/{entityname}
controller: App\Controller\AuditController::list
diff --git a/config/services.yaml b/config/services.yaml
index 0000b0d..6b64a05 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -92,6 +92,14 @@ parameters:
proxyHost: '%env(resolve:PROXY_HOST)%'
proxyPort: '%env(resolve:PROXY_PORT)%'
+ minioUrl: '%env(resolve:MINIO_URL)%'
+ minioKey: '%env(resolve:MINIO_KEY)%'
+ minioSecret: '%env(resolve:MINIO_SECRET)%'
+ minioBucket: '%env(resolve:MINIO_BUCKET)%'
+ minioRoot: '%env(resolve:MINIO_ROOT)%'
+ minioPathstyle: '%env(resolve:MINIO_PATH_STYLE)%'
+ minioSecure: '%env(resolve:MINIO_SECURE)%'
+
sondeUse: '%env(resolve:SONDE_USE)%'
sondeUrl: '%env(resolve:SONDE_URL)%'
@@ -216,5 +224,9 @@ services:
App\Service\ApiService:
public: true
+ App\Service\MinioService:
+ public: true
+ arguments: ["%kernel.project_dir%","%minioUrl%","%minioKey%","%minioSecret%","%minioBucket%","%minioRoot%","%minioPathstyle%","%minioSecure%","%kernel.environment%"]
+
App\Controller\RestController:
public: true
\ No newline at end of file
diff --git a/containers/minio/nginx.conf b/containers/minio/nginx.conf
new file mode 100644
index 0000000..2519220
--- /dev/null
+++ b/containers/minio/nginx.conf
@@ -0,0 +1,67 @@
+
+user nginx;
+worker_processes auto;
+
+error_log /var/log/nginx/error.log warn;
+pid /var/run/nginx.pid;
+
+
+events {
+ worker_connections 1024;
+}
+
+
+http {
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+
+ log_format main '$remote_addr - $remote_user [$time_local] "$request" '
+ '$status $body_bytes_sent "$http_referer" '
+ '"$http_user_agent" "$http_x_forwarded_for"';
+
+ access_log /var/log/nginx/access.log main;
+
+ sendfile on;
+ #tcp_nopush on;
+
+ keepalive_timeout 65;
+
+ #gzip on;
+
+ # include /etc/nginx/conf.d/*.conf;
+
+ upstream minio {
+ server minio1:9000;
+ server minio2:9000;
+ server minio3:9000;
+ server minio4:9000;
+ }
+
+ server {
+ listen 9000;
+ server_name localhost;
+
+ # To allow special characters in headers
+ ignore_invalid_headers off;
+ # Allow any size file to be uploaded.
+ # Set to a value such as 1000m; to restrict file size to a specific value
+ client_max_body_size 0;
+ # To disable buffering
+ proxy_buffering off;
+
+ location / {
+ proxy_set_header Host $http_host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ proxy_connect_timeout 300;
+ # Default is HTTP/1, keepalive is only enabled in HTTP/1.1
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ chunked_transfer_encoding off;
+
+ proxy_pass http://minio;
+ }
+ }
+}
diff --git a/docker-compose.yml b/docker-compose.yml
index eb8e188..bc981cc 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -55,8 +55,8 @@ services:
LDAP_LOG_LEVEL: "256"
LDAP_ORGANISATION: "nineskeletor"
LDAP_DOMAIN: "nine.fr"
- LDAP_ADMIN_PASSWORD: "admin"
- LDAP_CONFIG_PASSWORD: "config"
+ LDAP_ADMIN_PASSWORD: "changeme"
+ LDAP_CONFIG_PASSWORD: "changeme"
LDAP_READONLY_USER: "true"
LDAP_READONLY_USER_USERNAME: "readonly"
LDAP_READONLY_USER_PASSWORD: "readonly"
@@ -80,7 +80,99 @@ services:
depends_on:
- openldap
+ minio1:
+ image: minio/minio:RELEASE.2021-01-16T02-19-44Z
+ container_name: minio1
+ volumes:
+ - data1-1:/data1
+ - data1-2:/data2
+ expose:
+ - "9000"
+ environment:
+ MINIO_ROOT_USER: minio
+ MINIO_ROOT_PASSWORD: changeme
+ command: server http://minio{1...4}/data{1...2}
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live"]
+ interval: 30s
+ timeout: 20s
+ retries: 3
+
+ minio2:
+ image: minio/minio:RELEASE.2021-01-16T02-19-44Z
+ container_name: minio2
+ volumes:
+ - data2-1:/data1
+ - data2-2:/data2
+ expose:
+ - "9000"
+ environment:
+ MINIO_ROOT_USER: minio
+ MINIO_ROOT_PASSWORD: changeme
+ command: server http://minio{1...4}/data{1...2}
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live"]
+ interval: 30s
+ timeout: 20s
+ retries: 3
+
+ minio3:
+ image: minio/minio:RELEASE.2021-01-16T02-19-44Z
+ container_name: minio3
+ volumes:
+ - data3-1:/data1
+ - data3-2:/data2
+ expose:
+ - "9000"
+ environment:
+ MINIO_ROOT_USER: minio
+ MINIO_ROOT_PASSWORD: changeme
+ command: server http://minio{1...4}/data{1...2}
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live"]
+ interval: 30s
+ timeout: 20s
+ retries: 3
+
+ minio4:
+ image: minio/minio:RELEASE.2021-01-16T02-19-44Z
+ container_name: minio4
+ volumes:
+ - data4-1:/data1
+ - data4-2:/data2
+ expose:
+ - "9000"
+ environment:
+ MINIO_ROOT_USER: minio
+ MINIO_ROOT_PASSWORD: changeme
+ command: server http://minio{1...4}/data{1...2}
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live"]
+ interval: 30s
+ timeout: 20s
+ retries: 3
+
+ nginx:
+ image: nginx:1.19.2-alpine
+ volumes:
+ - ./containers/minio/nginx.conf:/etc/nginx/nginx.conf:ro
+ ports:
+ - "9000:9000"
+ depends_on:
+ - minio1
+ - minio2
+ - minio3
+ - minio4
+
volumes:
db-data:
mercure_data:
mercure_config:
+ data1-1:
+ data1-2:
+ data2-1:
+ data2-2:
+ data3-1:
+ data3-2:
+ data4-1:
+ data4-2:
\ No newline at end of file
diff --git a/src/Controller/CropController.php b/src/Controller/CropController.php
index c6c95f5..6825dbb 100644
--- a/src/Controller/CropController.php
+++ b/src/Controller/CropController.php
@@ -9,14 +9,17 @@ use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpFoundation\Response;
+use App\Service\MinioService;
class CropController extends AbstractController
{
private $appKernel;
+ private $minio;
- public function __construct(KernelInterface $appKernel)
+ public function __construct(KernelInterface $appKernel, MinioService $minio)
{
$this->appKernel = $appKernel;
+ $this->minio = $minio;
}
// Etape 01 - Téléchargement de l'image
@@ -102,6 +105,11 @@ class CropController extends AbstractController
$data = $form->getData();
$thumb_image_location = "uploads/$type/thumb_".$file;
$cropped = $this->resizeThumbnailImage($thumb_image_location, $large_image_location,$data["ws"],$data["hs"],$data["xs"],$data["ys"],$scale);
+
+ // Dépot des fichiers sur minio
+ $this->minio->upload($large_image_location,$large_image_location,true);
+ $this->minio->upload($thumb_image_location,$thumb_image_location,true);
+
$submited=true;
}
@@ -117,32 +125,6 @@ class CropController extends AbstractController
]);
}
- // Upload ckeditor
- public function ckupload(Request $request) {
- // Fichier temporaire uploadé
- $tmpfile = $request->files->get('upload');
- $extention = $tmpfile->getClientOriginalExtension();
-
- // Répertoire de Destination
- $fs = new Filesystem();
- $rootdir = $this->appKernel->getProjectDir()."/public";
- $fs->mkdir($rootdir."/uploads/ckeditor");
-
- // Fichier cible
- $targetName = uniqid().".".$extention;
- $targetFile = $rootdir."/uploads/ckeditor/".$targetName;
- $targetUrl = "/".$this->getParameter('appAlias')."/uploads/ckeditor/".$targetName;
- $message = "";
-
- move_uploaded_file($tmpfile,$targetFile);
-
- $output["uploaded"]=1;
- $output["fileName"]=$targetName;
- $output["url"]=$targetUrl;
-
- return new Response(json_encode($output));
- }
-
// Calcul de la hauteur
protected function getHeight($image) {
$size = getimagesize($image);
diff --git a/src/Controller/GroupController.php b/src/Controller/GroupController.php
index c2fcce8..f893987 100644
--- a/src/Controller/GroupController.php
+++ b/src/Controller/GroupController.php
@@ -160,10 +160,7 @@ class GroupController extends AbstractController
$userinfo="";
if($data->getOwner()) {
- if(stripos($data->getOwner()->getAvatar(),"http")===0)
- $userinfo.="";
- else
- $userinfo.="getOwner()->getAvatar()."' class='avatar'>";
+ $userinfo.=""uploads/avatar/".$data->getOwner()->getAvatar()])."' class='avatar'>";
$userinfo.="
".$data->getOwner()->getUsername();
}
@@ -516,11 +513,7 @@ class GroupController extends AbstractController
$action.="";
// Avatar
- if(stripos($data->getAvatar(),"http")===0)
- $avatar="";
- else
- $avatar="getAvatar()."' class='avatar'>";
-
+ $avatar=""uploads/avatar/".$data->getAvatar()])."' class='avatar'>";
array_push($output["data"],array("DT_RowId"=>"user".$data->getId(),$action,$avatar,$data->getUsername(),$data->getEmail(),"",""));
}
@@ -654,10 +647,7 @@ class GroupController extends AbstractController
$action.="";
// Avatar
- if(stripos($data->getAvatar(),"http")===0)
- $avatar="";
- else
- $avatar="getAvatar()."' class='avatar'>";
+ $avatar=""uploads/avatar/".$data->getAvatar()])."' class='avatar'>";
// Flag manager
$rolegroup="";
diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php
index e648f1a..fedc290 100644
--- a/src/Controller/HomeController.php
+++ b/src/Controller/HomeController.php
@@ -4,7 +4,7 @@ namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\Filesystem\Filesystem;
+
class HomeController extends AbstractController
{
@@ -52,30 +52,6 @@ class HomeController extends AbstractController
}
- public function upload($access,Request $request): Response
- {
- // Fichier temporaire uploadé
- $tmpfile = $request->files->get('upload');
- $extention = $tmpfile->getClientOriginalExtension();
- // Répertoire de Destination
- $fs = new Filesystem();
- $rootdir = $this->getParameter('kernel.project_dir') . '/public';
- $fs->mkdir($rootdir."/uploads/ckeditor");
-
- // Fichier cible
- $targetName = uniqid().".".$extention;
- $targetFile = $rootdir."/uploads/ckeditor/".$targetName;
- $targetUrl = $this->getParameter('appAlias')."uploads/ckeditor/".$targetName;
- $message = "";
-
- move_uploaded_file($tmpfile,$targetFile);
-
- $output["uploaded"]=1;
- $output["fileName"]=$targetName;
- $output["url"]=$targetUrl;
-
- return new Response(json_encode($output));
- }
}
\ No newline at end of file
diff --git a/src/Controller/MinioController.php b/src/Controller/MinioController.php
new file mode 100644
index 0000000..84f402b
--- /dev/null
+++ b/src/Controller/MinioController.php
@@ -0,0 +1,101 @@
+appKernel = $appKernel;
+ $this->minio = $minio;
+ }
+
+ public function ckupload($access,Request $request): Response
+ {
+ // Fichier temporaire uploadé
+ $tmpfile = $request->files->get('upload');
+ $extention = $tmpfile->getClientOriginalExtension();
+
+ // Répertoire de Destination
+ $fs = new Filesystem();
+ $rootdir = $this->getParameter('kernel.project_dir') . '/public';
+ $fs->mkdir($rootdir."/uploads/ckeditor");
+
+ // Fichier cible
+ $targetName = uniqid().".".$extention;
+ $targetFile = "uploads/ckeditor/".$targetName;
+ $targetUrl = $this->getParameter('appAlias')."uploads/ckeditor/".$targetName;
+ $targetUrl = $this->generateUrl('app_minio_document',["file"=>"uploads/ckeditor/".$targetName]);
+ $message = "";
+
+ //move_uploaded_file($tmpfile,$targetFile);
+ $this->minio->upload($tmpfile,$targetFile,true);
+
+ $output["uploaded"]=1;
+ $output["fileName"]=$targetName;
+ $output["url"]=$targetUrl;
+
+ return new Response(json_encode($output));
+ }
+
+ public function image(Request $request): Response
+ {
+ $file=$request->query->get("file");
+ switch($file) {
+ case "uploads/avatar/admin.jpg":
+ case "uploads/avatar/noavatar.png":
+ case "uploads/avatar/system.jpg":
+ case "uploads/header/header.jpg":
+ case "uploads/logo/logo.png":
+ $filePath = $file;
+ $content = file_get_contents($file);
+ break;
+
+ default:
+ // C'est une url = on affiche l'url
+ if(stripos($file,"http")===0) {
+ $filePath = $file;
+ $content = file_get_contents($file);
+ }
+ // C'est du contenu dynamique on download depuis minio
+ elseif(stripos($file,"uploads")===0) {
+ $filePath = $this->minio->download($file, $file, true);
+ $content = file_get_contents($filePath);
+ }
+ // C'est du contenu statique on download depuis minio
+ else {
+ $filePath = $file;
+ $content = file_get_contents($file);
+ }
+ break;
+ }
+
+ return new Response($content, 200, [
+ 'Content-Type' => mime_content_type($filePath),
+ 'Cache-Control' => 'max-age='.(60 * 60 * 24 * 7),
+ 'Expires' => gmdate(DATE_RFC1123, time() + 60 * 60 * 24 * 365),
+ ]);
+ }
+
+ public function document(Request $request)
+ {
+ $file=$request->query->get("file");
+ $filePath = $this->minio->download($file, $file, true);
+ $content = file_get_contents($filePath);
+
+ return new Response($content, 200, [
+ 'Content-Type' => mime_content_type($filePath),
+ 'Cache-Control' => 'max-age='.(60 * 60 * 24 * 7),
+ 'Expires' => gmdate(DATE_RFC1123, time() + 60 * 60 * 24 * 365),
+ ]);
+ }
+}
diff --git a/src/Controller/PublishController.php b/src/Controller/PublishController.php
index 66c2345..ac24cf7 100644
--- a/src/Controller/PublishController.php
+++ b/src/Controller/PublishController.php
@@ -22,12 +22,8 @@ class PublishController extends AbstractController
$ret["from"]["id"]=$this->getUser()->getId();
$ret["from"]["username"]=$this->getUser()->getUsername();
$ret["from"]["displayname"]=$this->getUser()->getDisplayname();
-
+ $ret["from"]["avatar"]=$this->generateUrl('app_minio_image',["file"=>"uploads/avatar/".$this->getUser()->getAvatar()]);
- if(stripos($this->getUser()->getAvatar(),"http")===0)
- $ret["from"]["avatar"]=$this->getUser()->getAvatar();
- else
- $ret["from"]["avatar"]=$this->getParameter('appAlias')."uploads/avatar/".$this->getUser()->getAvatar();
$update = new Update(
$channel."-".$id,
diff --git a/src/Controller/RestController.php b/src/Controller/RestController.php
index 3fc7c93..94eb845 100644
--- a/src/Controller/RestController.php
+++ b/src/Controller/RestController.php
@@ -399,8 +399,7 @@ class RestController extends AbstractFOSRestController
$output["userposition"]=$user->getPosition();
$output["userpostaladress"]=$user->getPostaladress();
$output["usertelephonenumber"]=$user->getTelephonenumber();
- if(stripos($user->getAvatar(),"http")===0) $output["useravatar"]=$user->getAvatar();
- else $output["useravatar"]="https://".$this->getParameter("appWeburl").$this->getParameter("appAlias")."uploads/avatar/".$user->getAvatar();
+ $output["useravatar"]="https://".str_replace("//","/",$this->getParameter("appWeburl").$this->getParameter("appAlias").$this->generateUrl('app_minio_image',["file"=>"uploads/avatar/".$user->getAvatar()],true));
$output["userniveau01"]=$this->niveau01Format($user->getNiveau01());
$output["userniveau02"]=$this->niveau02Format($user->getNiveau02());
$output["usergroups"]=[];
diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php
index f50f60a..32f6bcd 100644
--- a/src/Controller/UserController.php
+++ b/src/Controller/UserController.php
@@ -255,11 +255,8 @@ class UserController extends AbstractController
$tmp=array();
if($access=="admin"||$access=="modo") array_push($tmp,$action);
- if(stripos($data->getAvatar(),"http")===0)
- array_push($tmp,"");
- else
- array_push($tmp,"getAvatar()."' class='avatar'>");
-
+ array_push($tmp,""uploads/avatar/".$data->getAvatar()])."' class='avatar'>");
+
array_push($tmp,$data->getUsername());
array_push($tmp,$data->getLastname());
array_push($tmp,$data->getFirstname());
diff --git a/src/Service/MinioService.php b/src/Service/MinioService.php
new file mode 100644
index 0000000..c2508e6
--- /dev/null
+++ b/src/Service/MinioService.php
@@ -0,0 +1,238 @@
+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 $returnFile = false)
+ {
+ // 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
+ try {
+ $result = $this->client->getObject([
+ 'Bucket' => $this->minioBucket,
+ 'Key' => $this->minioRoot.$file,
+ 'SaveAs' => $tmpdir.'/'.$filename,
+ ]);
+ } catch (S3Exception $e) {
+ dump($e);
+ switch ($e->getResponse()->getStatusCode()) {
+ case 404:
+ throw new NotFoundHttpException($this->translator->trans(self::ERR_FILE_NOT_FOUND, [], 'messages'));
+ break;
+ default:
+ \Sentry\captureException($e);
+ throw new Exception(self::ERR_UNAVAILABLE);
+ break;
+ }
+ } catch (Exception $e) {
+ \Sentry\captureException($e);
+ throw new Exception(self::ERR_UNAVAILABLE);
+ }
+
+ if ($returnFile) {
+ return $tmpdir.'/'.$filename;
+ } else {
+ //Suppression de la copie locale
+ unlink($tmpdir.'/'.$filename);
+ $res = new Response($result['Body'], 200);
+ $res->headers->set('Content-Type', 'application/pdf');
+ $res->headers->set('Content-Description', 'File Transfer');
+ $res->headers->set('Content-Disposition', 'attachment; filename='.$filename);
+ $res->headers->set('Expires', '0');
+ $res->headers->set('Cache-Control', 'must-revalidate');
+ $res->headers->set('Pragma', 'public');
+
+ return $res;
+ }
+ }
+
+ 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) {
+ unlink($file);
+ }
+ }
+
+ /**
+ * 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);
+ dump($this->minioRoot.$to);
+ dump($e->getMessage());
+ 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) {
+ dump($e->getMessage());
+ throw new Exception(self::ERR_UNAVAILABLE);
+ }
+ }
+}
diff --git a/src/Service/UploadListener.php b/src/Service/UploadListener.php
index e86fa91..a3dec5a 100644
--- a/src/Service/UploadListener.php
+++ b/src/Service/UploadListener.php
@@ -3,14 +3,17 @@ namespace App\Service;
use Doctrine\ORM\EntityManagerInterface;
use Oneup\UploaderBundle\Event\PostPersistEvent;
+use App\Service\MinioService;
class UploadListener
{
private $em;
+ private $minio;
- public function __construct(EntityManagerInterface $em)
+ public function __construct(EntityManagerInterface $em, MinioService $minio)
{
$this->em = $em;
+ $this->minio = $minio;
}
protected function getHeight($image) {
@@ -76,6 +79,15 @@ class UploadListener
$type=$event->getType();
switch($type) {
+ case "logo":
+ $file=$event->getFile();
+ $filename=$file->getFilename();
+ $response = $event->getResponse();
+ $response['file'] = $filename;
+
+ $this->minio->upload($file,"uploads/logo/".$filename,true);
+ break;
+
default:
$file=$event->getFile();
$filename=$file->getFilename();
diff --git a/templates/Config/edit.html.twig b/templates/Config/edit.html.twig
index 12b00bc..a18db9e 100755
--- a/templates/Config/edit.html.twig
+++ b/templates/Config/edit.html.twig
@@ -60,17 +60,17 @@
{% set color = app.session.get('colorbgbodylight') %}
{% endif %}
-
+
Modifier
{% elseif config.type=="header" %}