✨ Ajout de la suppression des fichiers/dossiers
This commit is contained in:
parent
5f14e5f079
commit
7c574fc9a5
2
.env
2
.env
@ -39,3 +39,5 @@ MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
|
|||||||
###> symfony/mailer ###
|
###> symfony/mailer ###
|
||||||
MAILER_DSN=null://null
|
MAILER_DSN=null://null
|
||||||
###< symfony/mailer ###
|
###< symfony/mailer ###
|
||||||
|
|
||||||
|
BASE_PREFIX=kumora
|
@ -4,7 +4,7 @@ framework:
|
|||||||
paths:
|
paths:
|
||||||
- assets/
|
- assets/
|
||||||
missing_import_mode: strict
|
missing_import_mode: strict
|
||||||
public_prefix: /kumora/assets
|
public_prefix: "%env(BASE_PREFIX)%/assets"
|
||||||
|
|
||||||
when@prod:
|
when@prod:
|
||||||
framework:
|
framework:
|
||||||
|
@ -3,4 +3,4 @@ controllers:
|
|||||||
path: ../src/Controller/
|
path: ../src/Controller/
|
||||||
namespace: App\Controller
|
namespace: App\Controller
|
||||||
type: attribute
|
type: attribute
|
||||||
prefix: /kumora
|
prefix: '%base.prefix%'
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
# Put parameters here that don't need to change on each machine where the app is deployed
|
# Put parameters here that don't need to change on each machine where the app is deployed
|
||||||
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
||||||
parameters:
|
parameters:
|
||||||
|
base.prefix: '%env(BASE_PREFIX)%'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# default configuration for services in *this* file
|
# default configuration for services in *this* file
|
||||||
|
@ -6,9 +6,12 @@ use League\Flysystem\Filesystem;
|
|||||||
use League\Flysystem\FilesystemException;
|
use League\Flysystem\FilesystemException;
|
||||||
use League\Flysystem\FilesystemReader;
|
use League\Flysystem\FilesystemReader;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||||
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;
|
use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;
|
||||||
|
use Symfony\Component\HttpKernel\Attribute\MapUploadedFile;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
use Symfony\Component\HttpFoundation\HeaderUtils;
|
use Symfony\Component\HttpFoundation\HeaderUtils;
|
||||||
@ -24,17 +27,12 @@ class FilesController extends AbstractController
|
|||||||
#[Route('/', name: 'index')]
|
#[Route('/', name: 'index')]
|
||||||
public function index(Filesystem $defaultAdapter, UrlGeneratorInterface $urlGenerator, #[MapQueryParameter('path')] string $path = ''): Response
|
public function index(Filesystem $defaultAdapter, UrlGeneratorInterface $urlGenerator, #[MapQueryParameter('path')] string $path = ''): Response
|
||||||
{
|
{
|
||||||
// On retire les slashs en début et fin de chaîne
|
$path = $this->normalizePath($path);
|
||||||
$path = trim($path, '/');
|
|
||||||
// On retire les chemins relatifs
|
|
||||||
$path = str_replace('..', '', $path);
|
|
||||||
$path = str_replace('//', '/', $path);
|
|
||||||
|
|
||||||
if ($path !== '' && !$defaultAdapter->directoryExists($path)) {
|
if ($path !== '' && !$defaultAdapter->directoryExists($path)) {
|
||||||
throw $this->createNotFoundException("Ce dossier n'existe pas !");
|
throw $this->createNotFoundException("Ce dossier n'existe pas !");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$files = $defaultAdapter->listContents('/' . $path);
|
$files = $defaultAdapter->listContents('/' . $path);
|
||||||
|
|
||||||
$realFiles = [];
|
$realFiles = [];
|
||||||
@ -71,25 +69,75 @@ class FilesController extends AbstractController
|
|||||||
#[Route('/file-proxy', name: 'app_file_proxy')]
|
#[Route('/file-proxy', name: 'app_file_proxy')]
|
||||||
public function fileProxy(Filesystem $defaultAdapter, #[MapQueryParameter('filename')]string $filename)
|
public function fileProxy(Filesystem $defaultAdapter, #[MapQueryParameter('filename')]string $filename)
|
||||||
{
|
{
|
||||||
$mimetype = $defaultAdapter->mimeType($filename);
|
$file = $this->normalizePath($filename);
|
||||||
|
$mimetype = $defaultAdapter->mimeType($file);
|
||||||
if ($mimetype === '') {
|
if ($mimetype === '') {
|
||||||
$mimetype = 'application/octet-stream';
|
$mimetype = 'application/octet-stream';
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = new StreamedResponse(static function () use ($filename, $defaultAdapter): void {
|
$response = new StreamedResponse(static function () use ($file, $defaultAdapter): void {
|
||||||
$outputStream = fopen('php://output', 'w');
|
$outputStream = fopen('php://output', 'w');
|
||||||
$fileStream = $defaultAdapter->readStream($filename);
|
$fileStream = $defaultAdapter->readStream($file);
|
||||||
stream_copy_to_stream($fileStream, $outputStream);
|
stream_copy_to_stream($fileStream, $outputStream);
|
||||||
});
|
});
|
||||||
|
|
||||||
$response->headers->set('Content-Type', $mimetype);
|
$response->headers->set('Content-Type', $mimetype);
|
||||||
$disposition = HeaderUtils::makeDisposition(
|
$disposition = HeaderUtils::makeDisposition(
|
||||||
HeaderUtils::DISPOSITION_ATTACHMENT,
|
HeaderUtils::DISPOSITION_ATTACHMENT,
|
||||||
basename($filename)
|
basename($file)
|
||||||
);
|
);
|
||||||
$response->headers->set('Content-Disposition', $disposition);
|
$response->headers->set('Content-Disposition', $disposition);
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FilesystemException
|
||||||
|
*/
|
||||||
|
#[Route('/file-delete', name: 'delete')]
|
||||||
|
public function fileDelete(Filesystem $defaultAdapter, #[MapQueryParameter('filename')] string $filename): RedirectResponse
|
||||||
|
{
|
||||||
|
$file = $this->normalizePath($filename);
|
||||||
|
|
||||||
|
if ($file !== '' && $defaultAdapter->fileExists($file)) {
|
||||||
|
$defaultAdapter->delete($file);
|
||||||
|
|
||||||
|
$this->addFlash('success', 'Le fichier a bien été supprimé.');
|
||||||
|
} else {
|
||||||
|
$this->addFlash('error', 'Le fichier n\'existe pas.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->redirectToRoute('app_files_index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FilesystemException
|
||||||
|
*/
|
||||||
|
#[Route('/directory-delete', name: 'delete_directory')]
|
||||||
|
public function directoryDelete(Filesystem $defaultAdapter, #[MapQueryParameter('path')] string $path): RedirectResponse
|
||||||
|
{
|
||||||
|
$path = $this->normalizePath($path);
|
||||||
|
|
||||||
|
|
||||||
|
if ($path !== '' && $defaultAdapter->directoryExists($path)) {
|
||||||
|
$defaultAdapter->deleteDirectory($path);
|
||||||
|
|
||||||
|
$this->addFlash('success', 'Le dossier a bien été supprimé.');
|
||||||
|
} else {
|
||||||
|
$this->addFlash('error', 'Le dossier n\'existe pas.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->redirectToRoute('app_files_index');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function normalizePath(string $path): string
|
||||||
|
{
|
||||||
|
// On retire les slashs en début et fin de chaîne
|
||||||
|
$path = trim($path, '/');
|
||||||
|
// On retire les chemins relatifs
|
||||||
|
$path = str_replace('..', '', $path);
|
||||||
|
$path = str_replace('//', '/', $path);
|
||||||
|
|
||||||
|
return $path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,11 +53,17 @@
|
|||||||
{% if file.type == 'file' %}
|
{% if file.type == 'file' %}
|
||||||
<a href="{{ file.url }}" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:download" /></a>
|
<a href="{{ file.url }}" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:download" /></a>
|
||||||
<a href="#" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:pencil" /></a>
|
<a href="#" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:pencil" /></a>
|
||||||
<a href="#" class="hover:text-red-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:trash-can" /></a>
|
<a href="{{
|
||||||
|
path('app_files_delete', {
|
||||||
|
filename: file.path
|
||||||
|
})
|
||||||
|
}}" class="hover:text-red-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:trash-can" /></a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ file.url }}" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:link" /></a>
|
<a href="{{ file.url }}" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:link" /></a>
|
||||||
<a href="#" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:pencil" /></a>
|
<a href="#" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:pencil" /></a>
|
||||||
<a href="#" class="hover:text-red-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:trash-can" /></a>
|
<a href="{{ path('app_files_delete_directory', {
|
||||||
|
path: file.path
|
||||||
|
}) }}" class="hover:text-red-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:trash-can" /></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user