diff --git a/assets/controllers.json b/assets/controllers.json index 29ea244..677eeb6 100755 --- a/assets/controllers.json +++ b/assets/controllers.json @@ -1,5 +1,14 @@ { "controllers": { + "@symfony/ux-dropzone": { + "dropzone": { + "enabled": true, + "fetch": "eager", + "autoimport": { + "@symfony/ux-dropzone/dist/style.min.css": true + } + } + }, "@symfony/ux-turbo": { "turbo-core": { "enabled": true, diff --git a/composer.json b/composer.json index cce3927..3054838 100755 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "oneup/flysystem-bundle": "^4.12.3", "phpdocumentor/reflection-docblock": "^5.6.1", "phpstan/phpdoc-parser": "^2.0", - "symfony/apache-pack": "^1.0", + "symfony/apache-pack": "^1.0.1", "symfony/asset": "7.2.*", "symfony/asset-mapper": "7.2.*", "symfony/console": "7.2.*", @@ -43,6 +43,7 @@ "symfony/translation": "7.2.*", "symfony/twig-bundle": "7.2.*", "symfony/uid": "7.2.*", + "symfony/ux-dropzone": "^2.22.1", "symfony/ux-icons": "^2.22.1", "symfony/ux-turbo": "^2.22.1", "symfony/ux-twig-component": "^2.22.1", diff --git a/composer.lock b/composer.lock index 510cd22..7e0fe8f 100755 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3032276cf7af61e3028a0f94b2488b8d", + "content-hash": "34cf52bb9dcb8783d8297d6634221de2", "packages": [ { "name": "composer/semver", @@ -7420,6 +7420,85 @@ ], "time": "2024-09-25T14:21:43+00:00" }, + { + "name": "symfony/ux-dropzone", + "version": "v2.22.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/ux-dropzone.git", + "reference": "4debd59383bd98141c90bef5a98107710117af80" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ux-dropzone/zipball/4debd59383bd98141c90bef5a98107710117af80", + "reference": "4debd59383bd98141c90bef5a98107710117af80", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/form": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/options-resolver": "^5.4|^6.0|^7.0" + }, + "require-dev": { + "symfony/framework-bundle": "^5.4|^6.0|^7.0", + "symfony/phpunit-bridge": "^5.4|^6.0|^7.0", + "symfony/twig-bundle": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0", + "twig/twig": "^2.14.7|^3.0.4" + }, + "type": "symfony-bundle", + "extra": { + "thanks": { + "url": "https://github.com/symfony/ux", + "name": "symfony/ux" + } + }, + "autoload": { + "psr-4": { + "Symfony\\UX\\Dropzone\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Titouan Galopin", + "email": "galopintitouan@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "File input dropzones for Symfony Forms", + "homepage": "https://symfony.com", + "keywords": [ + "symfony-ux" + ], + "support": { + "source": "https://github.com/symfony/ux-dropzone/tree/v2.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-05T16:05:57+00:00" + }, { "name": "symfony/ux-icons", "version": "v2.22.1", diff --git a/config/bundles.php b/config/bundles.php index 3177489..bd9028d 100755 --- a/config/bundles.php +++ b/config/bundles.php @@ -19,4 +19,5 @@ return [ Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true], TalesFromADev\Twig\Extra\Tailwind\Bridge\Symfony\Bundle\TalesFromADevTwigExtraTailwindBundle::class => ['all' => true], TalesFromADev\FlowbiteBundle\TalesFromADevFlowbiteBundle::class => ['all' => true], + Symfony\UX\Dropzone\DropzoneBundle::class => ['all' => true], ]; diff --git a/src/Controller/FilesController.php b/src/Controller/FilesController.php index 5e1d645..b947dd1 100755 --- a/src/Controller/FilesController.php +++ b/src/Controller/FilesController.php @@ -4,9 +4,11 @@ namespace App\Controller; use App\Form\CreateDirectoryType; use App\Form\RenameType; +use App\Form\UploadType; use League\Flysystem\Filesystem; use League\Flysystem\FilesystemException; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\HeaderUtils; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; @@ -108,7 +110,9 @@ class FilesController extends AbstractController $this->addFlash('error', 'Le fichier n\'existe pas.'); } - return $this->redirectToRoute('app_files_index'); + return $this->redirectToRoute('app_files_index', [ + 'path' => dirname($file), + ]); } /** @@ -128,7 +132,9 @@ class FilesController extends AbstractController $this->addFlash('error', 'Le dossier n\'existe pas.'); } - return $this->redirectToRoute('app_files_index'); + return $this->redirectToRoute('app_files_index', [ + 'path' => dirname($path), + ]); } /** @@ -248,6 +254,46 @@ class FilesController extends AbstractController ]); } + /** + * @throws FilesystemException + */ + #[Route('/upload', name: 'upload')] + public function upload(#[MapQueryParameter('path')] string $path, Request $request, Filesystem $defaultAdapter): Response + { + $path = $this->normalizePath($path); + + $form = $this->createForm(UploadType::class); + + if ($path !== '' && !$defaultAdapter->directoryExists($path)) { + throw $this->createNotFoundException("Ce dossier n'existe pas !"); + } + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $data = $form->getData(); + $files = $data['files']; + + /** + * @var UploadedFile $file + */ + foreach ($files as $file) { + $filename = $file->getClientOriginalName(); + $defaultAdapter->write($path . '/' . $filename, $file->getContent()); + } + + $this->addFlash('success', 'Les ' . count($files) . ' fichiers ont bien été envoyés.'); + + return $this->redirectToRoute('app_files_index', [ + 'path' => $path, + ]); + } + + return $this->render('files/upload.html.twig', [ + 'form' => $form->createView(), + 'path' => $path, + ]); + } private function normalizePath(string $path): string { diff --git a/src/Form/UploadType.php b/src/Form/UploadType.php new file mode 100644 index 0000000..d0dc378 --- /dev/null +++ b/src/Form/UploadType.php @@ -0,0 +1,35 @@ +add('files', DropzoneType::class, [ + 'label' => 'Fichiers à envoyer', + 'attr' => [ + 'placeholder' => 'Déposez vos fichiers ici', + ], + 'multiple' => true, + ]) + ->add('submit', SubmitType::class, [ + 'label' => 'Uploader', + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + ]); + } +} diff --git a/symfony.lock b/symfony.lock index 19500ec..dc74938 100755 --- a/symfony.lock +++ b/symfony.lock @@ -295,6 +295,9 @@ "ref": "0df5844274d871b37fc3816c57a768ffc60a43a5" } }, + "symfony/ux-dropzone": { + "version": "v2.22.1" + }, "symfony/ux-icons": { "version": "2.22", "recipe": { diff --git a/templates/files/index.html.twig b/templates/files/index.html.twig index 6900701..71159c2 100755 --- a/templates/files/index.html.twig +++ b/templates/files/index.html.twig @@ -12,6 +12,9 @@ Créer un dossier + Ajouter des fichiers
{% include 'partials/breadbrumb.html.twig' %} diff --git a/templates/files/upload.html.twig b/templates/files/upload.html.twig new file mode 100644 index 0000000..2c4dddb --- /dev/null +++ b/templates/files/upload.html.twig @@ -0,0 +1,15 @@ +{% extends 'base.html.twig' %} + +{% block body %} +
+
+

Ajouter des fichiers dans /{{ path }}

+ {{ form(form) }} +
+
+{% endblock %} + +{% block title %} + Ajouter des fichiers +{% endblock %} +