');
- $('body').append(container);
+ body.append(container);
}
- container.html('');
+ const loader = $('
')
+ loader.html('
Loading...
')
+ body.append(loader)
+
+ container.html();
const url = $(e.target).attr('data-modal');
+ $(container).modal('show');
container.load(url, function() {
- $(container).modal('show');
+ loader.remove()
});
});
diff --git a/core/Cache/SymfonyCacheManager.php b/core/Cache/SymfonyCacheManager.php
index f296142..6ddba95 100644
--- a/core/Cache/SymfonyCacheManager.php
+++ b/core/Cache/SymfonyCacheManager.php
@@ -10,6 +10,7 @@ use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\HttpClient\Exception\ClientException;
+use Symfony\Component\Console\Output\OutputInterface;
/**
* class SymfonyCacheManager.
@@ -51,11 +52,14 @@ class SymfonyCacheManager
}
}
- public function cleanAll()
+ public function cleanAll(OutputInterface $output = null)
{
$application = new Application($this->kernel);
$application->setAutoExit(false);
- $output = new BufferedOutput();
+
+ if (null === $output) {
+ $output = new BufferedOutput();
+ }
$input = new ArrayInput([
'command' => 'cache:clear',
diff --git a/core/Controller/Task/TaskAdminController.php b/core/Controller/Task/TaskAdminController.php
new file mode 100644
index 0000000..51a3098
--- /dev/null
+++ b/core/Controller/Task/TaskAdminController.php
@@ -0,0 +1,59 @@
+dispatch($event, TaskInitEvent::INIT_EVENT);
+
+ return $this->render('@Core/task/task_admin/index.html.twig', [
+ 'pager' => $event->getTasks(),
+ ]);
+ }
+
+ /**
+ * @Route("/run/{task}", name="admin_task_run", methods={"GET"})
+ */
+ public function run(
+ string $task,
+ Request $request,
+ EventDispatcherInterface $eventDispatcher
+ ): Response {
+ if (!$this->isCsrfTokenValid('task_run', $request->query->get('_token'))) {
+ throw $this->createAccessDeniedException();
+ }
+
+ $output = new BufferedOutput();
+ $event = new TaskRunRequestedEvent($task, $request->query, $output);
+ $eventDispatcher->dispatch($event, TaskRunRequestedEvent::RUN_REQUEST_EVENT);
+
+ $content = $output->fetch();
+
+ return $this->render('@Core/task/task_admin/run.html.twig', [
+ 'output' => $content,
+ ]);
+ }
+
+ public function getSection(): string
+ {
+ return 'task';
+ }
+}
diff --git a/core/Event/Task/TaskInitEvent.php b/core/Event/Task/TaskInitEvent.php
new file mode 100644
index 0000000..ce9a45f
--- /dev/null
+++ b/core/Event/Task/TaskInitEvent.php
@@ -0,0 +1,37 @@
+
+ */
+class TaskInitEvent extends Event
+{
+ const INIT_EVENT = 'task_event.init';
+
+ protected array $tasks = [];
+
+ public function getTasks(): array
+ {
+ usort($this->tasks, function ($t1, $t2) {
+ return $t1['section'] != $t2['section'];
+ });
+
+ return $this->tasks;
+ }
+
+ public function addTask(string $task, string $label, string $section): self
+ {
+ $this->tasks[$task] = [
+ 'label' => $label,
+ 'section' => $section,
+ 'task' => $task,
+ ];
+
+ return $this;
+ }
+}
diff --git a/core/Event/Task/TaskRunRequestedEvent.php b/core/Event/Task/TaskRunRequestedEvent.php
new file mode 100644
index 0000000..d25ed89
--- /dev/null
+++ b/core/Event/Task/TaskRunRequestedEvent.php
@@ -0,0 +1,44 @@
+
+ */
+class TaskRunRequestedEvent extends Event
+{
+ const RUN_REQUEST_EVENT = 'task_event.run_request';
+
+ protected string $task;
+ protected InputBag $parameters;
+ protected BufferedOutput $output;
+
+ public function __construct(string $task, InputBag $parameters, BufferedOutput $output)
+ {
+ $this->task = $task;
+ $this->parameters = $parameters;
+ $this->output = $output;
+ }
+
+ public function getTask(): string
+ {
+ return $this->task;
+ }
+
+ public function getParameters(): ParameterBagInterface
+ {
+ return $this->parameters;
+ }
+
+ public function getOutput(): BufferedOutput
+ {
+ return $this->output;
+ }
+}
diff --git a/core/EventSuscriber/SettingEventSubscriber.php b/core/EventSuscriber/SettingEventSubscriber.php
index d65e783..d8db765 100644
--- a/core/EventSuscriber/SettingEventSubscriber.php
+++ b/core/EventSuscriber/SettingEventSubscriber.php
@@ -10,7 +10,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
*
* @author Simon Vieille
*/
-class SettingEventSubscriber implements EventSubscriberInterface
+abstract class SettingEventSubscriber implements EventSubscriberInterface
{
protected static int $priority = 0;
diff --git a/core/EventSuscriber/Task/CacheCleanTaskEventSubscriber.php b/core/EventSuscriber/Task/CacheCleanTaskEventSubscriber.php
new file mode 100644
index 0000000..d682d48
--- /dev/null
+++ b/core/EventSuscriber/Task/CacheCleanTaskEventSubscriber.php
@@ -0,0 +1,36 @@
+
+ */
+class CacheCleanTaskEventSubscriber extends TaskEventSubscriber
+{
+ protected SymfonyCacheManager $cacheManager;
+
+ public function __construct(SymfonyCacheManager $cacheManager)
+ {
+ $this->cacheManager = $cacheManager;
+ }
+
+ public function onInit(TaskInitEvent $event)
+ {
+ $event->addTask('cache:clear', 'Clean all cache', '♻️ Cache');
+ }
+
+ public function onRunRequest(TaskRunRequestedEvent $event)
+ {
+ if ('cache:clear' !== $event->getTask()) {
+ return;
+ }
+
+ $this->cacheManager->cleanAll($event->getOutput());
+ }
+}
diff --git a/core/EventSuscriber/Task/TaskEventSubscriber.php b/core/EventSuscriber/Task/TaskEventSubscriber.php
new file mode 100644
index 0000000..a6ab5d8
--- /dev/null
+++ b/core/EventSuscriber/Task/TaskEventSubscriber.php
@@ -0,0 +1,33 @@
+
+ */
+abstract class TaskEventSubscriber implements EventSubscriberInterface
+{
+ protected static int $priority = 0;
+
+ public static function getSubscribedEvents()
+ {
+ return [
+ TaskInitEvent::INIT_EVENT => ['onInit', self::$priority],
+ TaskRunRequestedEvent::RUN_REQUEST_EVENT => ['onRunRequest', self::$priority],
+ ];
+ }
+
+ public function onInit(TaskInitEvent $event)
+ {
+ }
+
+ public function onRunRequest(TaskRunRequestedEvent $event)
+ {
+ }
+}
diff --git a/core/Resources/translations/messages.fr.yaml b/core/Resources/translations/messages.fr.yaml
index 0e160d0..b6fe635 100644
--- a/core/Resources/translations/messages.fr.yaml
+++ b/core/Resources/translations/messages.fr.yaml
@@ -153,3 +153,7 @@
"Regular expression: do not add the delimiter": "Expréssion régulière : ne pas ajouter de délimiteur"
"Content type": "Type de contenu"
'Leave blank equals "text/html"': 'Laissez vide équivaut à "text/html"'
+"Close": "Fermer"
+"Tasks": "Tâches"
+"Results": "Résultats"
+"Clean all cache": "Nettoyer tout le cache"
diff --git a/core/Resources/views/admin/module/menu.html.twig b/core/Resources/views/admin/module/menu.html.twig
index e684a6b..d09222d 100644
--- a/core/Resources/views/admin/module/menu.html.twig
+++ b/core/Resources/views/admin/module/menu.html.twig
@@ -68,6 +68,16 @@
+
+
+
+