svg
This commit is contained in:
@ -4,3 +4,5 @@ oneup_uploader:
|
|||||||
frontend: dropzone
|
frontend: dropzone
|
||||||
logo:
|
logo:
|
||||||
frontend: dropzone
|
frontend: dropzone
|
||||||
|
file:
|
||||||
|
frontend: dropzone
|
@ -3,7 +3,9 @@
|
|||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
use App\Service\FileService;
|
use App\Service\FileService;
|
||||||
|
use Oneup\UploaderBundle\Uploader\Response\ResponseInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
@ -45,11 +47,44 @@ class FileController extends AbstractController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/user/file/{domain}/{id}/uploadmodal', name: 'app_files_uploadmodal', methods: ['GET'])]
|
#[Route('/user/uploadmodal/{domain}/{id}', name: 'app_files_uploadmodal', methods: ['GET'])]
|
||||||
public function upload(string $domain, int $id, Request $request): Response
|
public function uploadmodal(string $domain, int $id, Request $request): Response
|
||||||
{
|
{
|
||||||
$relativePath = $request->query->get('path', '');
|
$relativePath = $request->query->get('path', '');
|
||||||
|
|
||||||
|
return $this->render('file\upload.html.twig', [
|
||||||
|
'useheader' => false,
|
||||||
|
'usemenu' => false,
|
||||||
|
'usesidebar' => false,
|
||||||
|
'endpoint' => 'file',
|
||||||
|
'domain' => $domain,
|
||||||
|
'id' => $id,
|
||||||
|
'path' => $relativePath,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/user/uploadfile', name: 'app_files_uploadfile', methods: ['POST'])]
|
||||||
|
public function upload(Request $request): Response|ResponseInterface
|
||||||
|
{
|
||||||
|
/** @var UploadedFile $file */
|
||||||
|
$file = $request->files->get('file');
|
||||||
|
$domain = $request->query->get('domain');
|
||||||
|
$id = $request->query->get('id');
|
||||||
|
$relativePath = $request->query->get('path', '');
|
||||||
|
|
||||||
|
if (!$file || !$domain || !$id) {
|
||||||
|
return new Response('Invalid parameters', 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$baseDir = $this->getParameter('kernel.project_dir').'/uploads/'.$domain.'/'.$id.'/'.ltrim($relativePath, '/');
|
||||||
|
|
||||||
|
if (!is_dir($baseDir)) {
|
||||||
|
mkdir($baseDir, 0775, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$originalName = $file->getClientOriginalName();
|
||||||
|
$file->move($baseDir, $originalName);
|
||||||
|
|
||||||
return new JsonResponse(['success' => true]);
|
return new JsonResponse(['success' => true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,11 +11,7 @@
|
|||||||
|
|
||||||
{% if editable %}
|
{% if editable %}
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<form method="post" enctype="multipart/form-data" class="d-flex gap-2 align-items-center" id="upload-form-{{ domain }}-{{ id }}">
|
<a class="btn btn-info" style="max-width:100%; margin-bottom:15px;" data-bs-toggle="modal" data-bs-target="#mymodal" onClick="ModalLoad('mymodal','Upload','{{ path('app_files_uploadmodal',{domain:domain, id:id,path:path}) }}');" title='Upload'>Upload</a>
|
||||||
<input type="file" name="file" required>
|
|
||||||
<input type="hidden" name="path" value="{{ path }}">
|
|
||||||
<button type="submit" class="btn btn-sm btn-primary">Uploader</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@ -50,72 +46,79 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
$(function () {
|
||||||
function initFileBrowser(container) {
|
function refreshContainer(containerId, path) {
|
||||||
if (!container) return;
|
const $oldContainer = $('#' + containerId);
|
||||||
|
const base = $oldContainer.data('base-path');
|
||||||
|
|
||||||
container.addEventListener('click', function (e) {
|
$.get(base, { path: path }, function (html) {
|
||||||
// Navigation
|
console.log(html);
|
||||||
if (e.target.classList.contains('file-nav')) {
|
const $doc = $('<div>').html(html);
|
||||||
e.preventDefault();
|
const $newContainer = $doc.find('#' + containerId);
|
||||||
const path = e.target.dataset.path;
|
console.log(containerId);
|
||||||
refreshContainer(container, path);
|
if ($newContainer.length) {
|
||||||
|
console.log("HHHHHHHHHHHHHHHHHHHH");
|
||||||
|
$oldContainer.replaceWith($newContainer);
|
||||||
|
initFileBrowser($newContainer); // rebind events
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Suppression
|
function initFileBrowser($container) {
|
||||||
if (e.target.classList.contains('btn-delete')) {
|
const containerId = $container.attr('id');
|
||||||
|
|
||||||
|
// Clear any previous bindings (important!)
|
||||||
|
$container.off('click');
|
||||||
|
|
||||||
|
// Navigation dossier
|
||||||
|
$container.on('click', '.file-nav', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const path = $(this).data('path');
|
||||||
|
refreshContainer(containerId, path);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Suppression fichier ou dossier
|
||||||
|
$container.on('click', '.btn-delete', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!confirm('Supprimer ce fichier ?')) return;
|
if (!confirm('Supprimer ce fichier ?')) return;
|
||||||
|
|
||||||
const pathToDelete = e.target.dataset.path;
|
const pathToDelete = $(this).data('path');
|
||||||
const currentPath = container.dataset.currentPath || '';
|
const currentPath = $container.data('current-path');
|
||||||
|
|
||||||
fetch('/user/file/' + container.dataset.domain + '/' + container.dataset.id + '/delete', {
|
$.ajax({
|
||||||
|
url: '/user/file/' + $container.data('domain') + '/' + $container.data('id') + '/delete',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
contentType: 'application/json',
|
||||||
'Content-Type': 'application/json',
|
data: JSON.stringify({ path: pathToDelete }),
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
success: function (res) {
|
||||||
},
|
if (res.success) {
|
||||||
body: JSON.stringify({ path: pathToDelete })
|
refreshContainer(containerId, currentPath);
|
||||||
})
|
|
||||||
.then(res => res.json())
|
|
||||||
.then(data => {
|
|
||||||
if (data.success) {
|
|
||||||
// Rafraîchit après suppression
|
|
||||||
refreshContainer(container, currentPath);
|
|
||||||
} else {
|
} else {
|
||||||
alert('Erreur : ' + data.error);
|
alert('Erreur : ' + res.error);
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
.catch(err => alert('Erreur lors de la suppression : ' + err.message));
|
error: function (xhr) {
|
||||||
|
alert('Erreur lors de la suppression : ' + xhr.responseText);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshContainer(oldContainer, path) {
|
// Init navigateur fichiers
|
||||||
const domain = oldContainer.dataset.domain;
|
const containerId = 'file-browser-{{ domain }}-{{ id|e('html_attr') }}';
|
||||||
const id = oldContainer.dataset.id;
|
const $browser = $('#' + containerId);
|
||||||
const base = oldContainer.dataset.basePath;
|
initFileBrowser($browser);
|
||||||
|
|
||||||
fetch(base + '?path=' + encodeURIComponent(path))
|
// Rafraîchir après fermeture modale
|
||||||
.then(response => response.text())
|
$('#mymodal').on('hidden.bs.modal', function () {
|
||||||
.then(html => {
|
const $browser = $('#' + containerId);
|
||||||
const parser = new DOMParser();
|
const currentPath = $browser.data('current-path') || '';
|
||||||
const doc = parser.parseFromString(html, 'text/html');
|
refreshContainer(containerId, currentPath);
|
||||||
const newContainer = doc.getElementById(oldContainer.id);
|
|
||||||
if (newContainer) {
|
|
||||||
oldContainer.replaceWith(newContainer);
|
|
||||||
newContainer.dataset.currentPath = path;
|
|
||||||
initFileBrowser(newContainer); // re-binde sur le nouveau DOM
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
|
||||||
document.querySelectorAll('.file-browser').forEach(initFileBrowser);
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
45
templates/file/upload.html.twig
Normal file
45
templates/file/upload.html.twig
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block localstyle %}
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<a class="btn btn-secondary" onClick="closeModal();">Annuler</a>
|
||||||
|
<form action="{{ path('app_files_uploadfile', {
|
||||||
|
domain: domain,
|
||||||
|
id: id,
|
||||||
|
path: path
|
||||||
|
}) }}"
|
||||||
|
class="dropzone" id="myDropzone" style="margin-top:10px"></form>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block localscript %}
|
||||||
|
<script>
|
||||||
|
Dropzone.options.myDropzone = {
|
||||||
|
paramName: "{{endpoint}}",
|
||||||
|
maxFilesize: 20, // MB
|
||||||
|
parallelUploads: 5,
|
||||||
|
uploadMultiple: false,
|
||||||
|
dictDefaultMessage: "Déposez vos fichiers ici pour les téléverser",
|
||||||
|
successmultiple: function (files, response) {
|
||||||
|
console.log("multi uploaded", files);
|
||||||
|
},
|
||||||
|
queuecomplete: function () {
|
||||||
|
// Quand tous les fichiers sont uploadés, on ferme la modale et rafraîchit le navigateur
|
||||||
|
window.parent.$("#mymodal").modal('hide');
|
||||||
|
if (typeof window.parent.refreshFileBrowser === 'function') {
|
||||||
|
window.parent.refreshFileBrowser(); // à définir côté parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function closeModal() {
|
||||||
|
window.parent.$("#mymodal").modal('hide');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
Reference in New Issue
Block a user