diff --git a/src/Controllers/Attributes/AttributeController.php b/src/Controllers/Attributes/AttributeController.php
index 2cd71934..5bc91ae8 100644
--- a/src/Controllers/Attributes/AttributeController.php
+++ b/src/Controllers/Attributes/AttributeController.php
@@ -21,19 +21,15 @@
 
 class AttributeController extends AbstractAdminWithBulkController
 {
-    private AttributeImporter $attributeImporter;
-
     public function __construct(
-        AttributeImporter $attributeImporter,
+        private readonly AttributeImporter $attributeImporter,
         FormFactoryInterface $formFactory,
         SerializerInterface $serializer,
         UrlGeneratorInterface $urlGenerator
     ) {
         parent::__construct($formFactory, $serializer, $urlGenerator);
-        $this->attributeImporter = $attributeImporter;
     }
 
-
     /**
      * @inheritDoc
      */
diff --git a/src/Controllers/CacheController.php b/src/Controllers/CacheController.php
index ead8047e..e71f35a2 100644
--- a/src/Controllers/CacheController.php
+++ b/src/Controllers/CacheController.php
@@ -14,15 +14,10 @@
 
 final class CacheController extends RozierApp
 {
-    private LoggerInterface $logger;
-    private CacheClearerInterface $cacheClearer;
-
     public function __construct(
-        CacheClearerInterface $cacheClearer,
-        LoggerInterface $logger
+        private readonly CacheClearerInterface $cacheClearer,
+        private readonly LoggerInterface $logger
     ) {
-        $this->logger = $logger;
-        $this->cacheClearer = $cacheClearer;
     }
 
     public function deleteDoctrineCache(Request $request): Response
diff --git a/src/Controllers/CustomForms/CustomFormsUtilsController.php b/src/Controllers/CustomForms/CustomFormsUtilsController.php
index 11516b8a..5c293ccb 100644
--- a/src/Controllers/CustomForms/CustomFormsUtilsController.php
+++ b/src/Controllers/CustomForms/CustomFormsUtilsController.php
@@ -16,14 +16,8 @@
 
 class CustomFormsUtilsController extends RozierApp
 {
-    private CustomFormAnswerSerializer $customFormAnswerSerializer;
-
-    /**
-     * @param CustomFormAnswerSerializer $customFormAnswerSerializer
-     */
-    public function __construct(CustomFormAnswerSerializer $customFormAnswerSerializer)
+    public function __construct(private readonly CustomFormAnswerSerializer $customFormAnswerSerializer)
     {
-        $this->customFormAnswerSerializer = $customFormAnswerSerializer;
     }
 
     /**
diff --git a/src/Controllers/Documents/DocumentTranslationsController.php b/src/Controllers/Documents/DocumentTranslationsController.php
index 0fcb8cdc..624f1da9 100644
--- a/src/Controllers/Documents/DocumentTranslationsController.php
+++ b/src/Controllers/Documents/DocumentTranslationsController.php
@@ -12,6 +12,7 @@
 use RZ\Roadiz\CoreBundle\Entity\Translation;
 use RZ\Roadiz\CoreBundle\Event\Document\DocumentTranslationUpdatedEvent;
 use Symfony\Component\Form\Extension\Core\Type\HiddenType;
+use Symfony\Component\Form\FormInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
@@ -34,7 +35,7 @@ class DocumentTranslationsController extends RozierApp
      * @return Response
      * @throws RuntimeError
      */
-    public function editAction(Request $request, int $documentId, ?int $translationId = null)
+    public function editAction(Request $request, int $documentId, ?int $translationId = null): Response
     {
         $this->denyAccessUnlessGranted('ROLE_ACCESS_DOCUMENTS');
 
@@ -117,14 +118,10 @@ public function editAction(Request $request, int $documentId, ?int $translationI
         throw new ResourceNotFoundException();
     }
 
-    /**
-     * @param Document $document
-     * @param TranslationInterface $translation
-     *
-     * @return DocumentTranslation
-     */
-    protected function createDocumentTranslation(Document $document, TranslationInterface $translation)
-    {
+    protected function createDocumentTranslation(
+        Document $document,
+        TranslationInterface $translation
+    ): DocumentTranslation {
         $dt = new DocumentTranslation();
         $dt->setDocument($document);
         $dt->setTranslation($translation);
@@ -144,7 +141,7 @@ protected function createDocumentTranslation(Document $document, TranslationInte
      * @return Response
      * @throws RuntimeError
      */
-    public function deleteAction(Request $request, int $documentId, int $translationId)
+    public function deleteAction(Request $request, int $documentId, int $translationId): Response
     {
         $this->denyAccessUnlessGranted('ROLE_ACCESS_DOCUMENTS_DELETE');
 
@@ -201,12 +198,7 @@ public function deleteAction(Request $request, int $documentId, int $translation
         throw new ResourceNotFoundException();
     }
 
-    /**
-     * @param DocumentTranslation $doc
-     *
-     * @return \Symfony\Component\Form\FormInterface
-     */
-    private function buildDeleteForm(DocumentTranslation $doc)
+    private function buildDeleteForm(DocumentTranslation $doc): FormInterface
     {
         $defaults = [
             'documentTranslationId' => $doc->getId(),
@@ -240,11 +232,6 @@ protected function onPostUpdate(PersistableInterface $entity, Request $request):
         }
     }
 
-    /**
-     * @param PersistableInterface $entity
-     *
-     * @return Response
-     */
     protected function getPostUpdateRedirection(PersistableInterface $entity): ?Response
     {
         if (
diff --git a/src/Controllers/Documents/DocumentsController.php b/src/Controllers/Documents/DocumentsController.php
index b049b5d3..1a707200 100644
--- a/src/Controllers/Documents/DocumentsController.php
+++ b/src/Controllers/Documents/DocumentsController.php
@@ -60,18 +60,6 @@
 
 class DocumentsController extends RozierApp
 {
-    private array $documentPlatforms;
-    private DocumentFactory $documentFactory;
-    private HandlerFactoryInterface $handlerFactory;
-    private LoggerInterface $logger;
-    private RandomImageFinder $randomImageFinder;
-    private RendererInterface $renderer;
-    private DocumentUrlGeneratorInterface $documentUrlGenerator;
-    private UrlGeneratorInterface $urlGenerator;
-    private FilesystemOperator $documentsStorage;
-    private ?string $googleServerId;
-    private ?string $soundcloudClientId;
-
     protected array $thumbnailFormat = [
         'quality' => 50,
         'fit' => '128x128',
@@ -81,34 +69,21 @@ class DocumentsController extends RozierApp
         'controls' => false,
         'loading' => 'lazy',
     ];
-    private EmbedFinderFactory $embedFinderFactory;
 
     public function __construct(
-        array $documentPlatforms,
-        FilesystemOperator $documentsStorage,
-        HandlerFactoryInterface $handlerFactory,
-        LoggerInterface $logger,
-        RandomImageFinder $randomImageFinder,
-        DocumentFactory $documentFactory,
-        RendererInterface $renderer,
-        DocumentUrlGeneratorInterface $documentUrlGenerator,
-        UrlGeneratorInterface $urlGenerator,
-        EmbedFinderFactory $embedFinderFactory,
-        ?string $googleServerId = null,
-        ?string $soundcloudClientId = null
+        private readonly array $documentPlatforms,
+        private readonly FilesystemOperator $documentsStorage,
+        private readonly HandlerFactoryInterface $handlerFactory,
+        private readonly LoggerInterface $logger,
+        private readonly RandomImageFinder $randomImageFinder,
+        private readonly DocumentFactory $documentFactory,
+        private readonly RendererInterface $renderer,
+        private readonly DocumentUrlGeneratorInterface $documentUrlGenerator,
+        private readonly UrlGeneratorInterface $urlGenerator,
+        private readonly EmbedFinderFactory $embedFinderFactory,
+        private readonly ?string $googleServerId = null,
+        private readonly ?string $soundcloudClientId = null
     ) {
-        $this->documentPlatforms = $documentPlatforms;
-        $this->handlerFactory = $handlerFactory;
-        $this->logger = $logger;
-        $this->randomImageFinder = $randomImageFinder;
-        $this->documentFactory = $documentFactory;
-        $this->renderer = $renderer;
-        $this->documentUrlGenerator = $documentUrlGenerator;
-        $this->urlGenerator = $urlGenerator;
-        $this->googleServerId = $googleServerId;
-        $this->soundcloudClientId = $soundcloudClientId;
-        $this->documentsStorage = $documentsStorage;
-        $this->embedFinderFactory = $embedFinderFactory;
     }
 
     /**
diff --git a/src/Controllers/FoldersController.php b/src/Controllers/FoldersController.php
index 92b122db..c3e866b5 100644
--- a/src/Controllers/FoldersController.php
+++ b/src/Controllers/FoldersController.php
@@ -25,11 +25,8 @@
 
 class FoldersController extends RozierApp
 {
-    private DocumentArchiver $documentArchiver;
-
-    public function __construct(DocumentArchiver $documentArchiver)
+    public function __construct(private readonly DocumentArchiver $documentArchiver)
     {
-        $this->documentArchiver = $documentArchiver;
     }
 
     public function indexAction(Request $request): Response
diff --git a/src/Controllers/GroupsUtilsController.php b/src/Controllers/GroupsUtilsController.php
index e090be63..25e6be3e 100644
--- a/src/Controllers/GroupsUtilsController.php
+++ b/src/Controllers/GroupsUtilsController.php
@@ -20,17 +20,10 @@
 
 class GroupsUtilsController extends RozierApp
 {
-    private SerializerInterface $serializer;
-    private GroupsImporter $groupsImporter;
-
-    /**
-     * @param SerializerInterface $serializer
-     * @param GroupsImporter $groupsImporter
-     */
-    public function __construct(SerializerInterface $serializer, GroupsImporter $groupsImporter)
-    {
-        $this->serializer = $serializer;
-        $this->groupsImporter = $groupsImporter;
+    public function __construct(
+        private readonly SerializerInterface $serializer,
+        private readonly GroupsImporter $groupsImporter
+    ) {
     }
 
     /**
diff --git a/src/Controllers/LoginController.php b/src/Controllers/LoginController.php
index 5714ba77..7dea01cb 100644
--- a/src/Controllers/LoginController.php
+++ b/src/Controllers/LoginController.php
@@ -41,10 +41,9 @@ public function imageAction(Request $request): Response
                     'quality' => 80,
                     'sharpen' => 5,
                 ]);
-                $response->setData([
+                return $response->setData([
                     'url' => $this->documentUrlGenerator->getUrl()
                 ]);
-                return $response;
             }
         }
 
@@ -54,9 +53,8 @@ public function imageAction(Request $request): Response
         if (null !== $feed) {
             $url = $feed['url'] ?? $feed['urls']['regular'] ?? $feed['urls']['full'] ?? $feed['urls']['raw'] ?? null;
         }
-        $response->setData([
-            'url' => '/themes/Rozier/static/assets/img/default_login.jpg'
+        return $response->setData([
+            'url' => $url ?? '/themes/Rozier/static/assets/img/default_login.jpg'
         ]);
-        return $response;
     }
 }
diff --git a/src/Controllers/NodeTypeFieldsController.php b/src/Controllers/NodeTypeFieldsController.php
index fad5a557..4bdcd44b 100644
--- a/src/Controllers/NodeTypeFieldsController.php
+++ b/src/Controllers/NodeTypeFieldsController.php
@@ -12,7 +12,6 @@
 use Symfony\Component\Form\FormError;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\KernelInterface;
 use Symfony\Component\Messenger\Envelope;
 use Symfony\Component\Messenger\MessageBusInterface;
 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
@@ -22,13 +21,10 @@
 
 class NodeTypeFieldsController extends RozierApp
 {
-    private MessageBusInterface $messageBus;
-    private KernelInterface $kernel;
-
-    public function __construct(KernelInterface $kernel, MessageBusInterface $messageBus)
-    {
-        $this->messageBus = $messageBus;
-        $this->kernel = $kernel;
+    public function __construct(
+        private readonly bool $allowNodeTypeEdition,
+        private readonly MessageBusInterface $messageBus
+    ) {
     }
 
     /**
@@ -82,7 +78,7 @@ public function editAction(Request $request, int $nodeTypeFieldId): Response
         $form->handleRequest($request);
 
         if ($form->isSubmitted() && $form->isValid()) {
-            if (!$this->kernel->isDebug()) {
+            if (!$this->allowNodeTypeEdition) {
                 $form->addError(new FormError('You cannot edit node-type fields in production.'));
             } else {
                 $this->em()->flush();
@@ -138,12 +134,12 @@ public function addAction(Request $request, int $nodeTypeId): Response
         $this->assignation['field'] = $field;
 
         $form = $this->createForm(NodeTypeFieldType::class, $field, [
-            'disabled' => !$this->kernel->isDebug()
+            'disabled' => !$this->allowNodeTypeEdition
         ]);
         $form->handleRequest($request);
 
         if ($form->isSubmitted() && $form->isValid()) {
-            if (!$this->kernel->isDebug()) {
+            if (!$this->allowNodeTypeEdition) {
                 $form->addError(new FormError('You cannot add node-type fields in production.'));
             } else {
                 try {
@@ -198,7 +194,7 @@ public function deleteAction(Request $request, int $nodeTypeFieldId): Response
         $form->handleRequest($request);
 
         if ($form->isSubmitted() && $form->isValid()) {
-            if (!$this->kernel->isDebug()) {
+            if (!$this->allowNodeTypeEdition) {
                 $form->addError(new FormError('You cannot delete node-type fields in production.'));
             } else {
                 /** @var NodeType $nodeType */
diff --git a/src/Controllers/NodeTypes/NodeTypesController.php b/src/Controllers/NodeTypes/NodeTypesController.php
index 3926d683..1d148c6e 100644
--- a/src/Controllers/NodeTypes/NodeTypesController.php
+++ b/src/Controllers/NodeTypes/NodeTypesController.php
@@ -12,7 +12,6 @@
 use Symfony\Component\Form\FormError;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\KernelInterface;
 use Symfony\Component\Messenger\Envelope;
 use Symfony\Component\Messenger\MessageBusInterface;
 use Themes\Rozier\Forms\NodeTypeType;
@@ -22,13 +21,10 @@
 
 class NodeTypesController extends RozierApp
 {
-    private MessageBusInterface $messageBus;
-    private KernelInterface $kernel;
-
-    public function __construct(KernelInterface $kernel, MessageBusInterface $messageBus)
-    {
-        $this->messageBus = $messageBus;
-        $this->kernel = $kernel;
+    public function __construct(
+        private readonly bool $allowNodeTypeEdition,
+        private readonly MessageBusInterface $messageBus
+    ) {
     }
 
     public function indexAction(Request $request): Response
@@ -112,12 +108,12 @@ public function addAction(Request $request): Response
         $nodeType = new NodeType();
 
         $form = $this->createForm(NodeTypeType::class, $nodeType, [
-            'disabled' => !$this->kernel->isDebug()
+            'disabled' => !$this->allowNodeTypeEdition
         ]);
         $form->handleRequest($request);
 
         if ($form->isSubmitted() && $form->isValid()) {
-            if (!$this->kernel->isDebug()) {
+            if (!$this->allowNodeTypeEdition) {
                 $form->addError(new FormError('You cannot create a node-type in production mode.'));
             } else {
                 try {
@@ -166,7 +162,7 @@ public function deleteAction(Request $request, int $nodeTypeId): Response
         $form->handleRequest($request);
 
         if ($form->isSubmitted() && $form->isValid()) {
-            if (!$this->kernel->isDebug()) {
+            if (!$this->allowNodeTypeEdition) {
                 $form->addError(new FormError('You cannot delete a node-type in production mode.'));
             } else {
                 $this->messageBus->dispatch(new Envelope(new DeleteNodeTypeMessage($nodeType->getId())));
diff --git a/src/Controllers/NodeTypes/NodeTypesUtilsController.php b/src/Controllers/NodeTypes/NodeTypesUtilsController.php
index b7c07e63..059a6b13 100644
--- a/src/Controllers/NodeTypes/NodeTypesUtilsController.php
+++ b/src/Controllers/NodeTypes/NodeTypesUtilsController.php
@@ -29,21 +29,12 @@
 
 class NodeTypesUtilsController extends RozierApp
 {
-    private SerializerInterface $serializer;
-    private NodeTypes $nodeTypesBag;
-    private NodeTypesImporter $nodeTypesImporter;
-    private MessageBusInterface $messageBus;
-
     public function __construct(
-        SerializerInterface $serializer,
-        NodeTypes $nodeTypesBag,
-        NodeTypesImporter $nodeTypesImporter,
-        MessageBusInterface $messageBus
+        private readonly SerializerInterface $serializer,
+        private readonly NodeTypes $nodeTypesBag,
+        private readonly NodeTypesImporter $nodeTypesImporter,
+        private readonly MessageBusInterface $messageBus
     ) {
-        $this->serializer = $serializer;
-        $this->nodeTypesBag = $nodeTypesBag;
-        $this->nodeTypesImporter = $nodeTypesImporter;
-        $this->messageBus = $messageBus;
     }
 
     /**
@@ -81,7 +72,6 @@ public function exportJsonFileAction(Request $request, int $nodeTypeId): JsonRes
 
     /**
      * @param Request $request
-     *
      * @return BinaryFileResponse
      * @throws RuntimeError
      */
@@ -152,10 +142,6 @@ public function exportTypeScriptDeclarationAction(Request $request): Response
         return $response;
     }
 
-    /**
-     * @param Request $request
-     * @return BinaryFileResponse
-     */
     public function exportAllAction(Request $request): BinaryFileResponse
     {
         $this->denyAccessUnlessGranted('ROLE_ACCESS_NODETYPES');
diff --git a/src/Controllers/Nodes/ExportController.php b/src/Controllers/Nodes/ExportController.php
index 15549a66..4ba71fd0 100644
--- a/src/Controllers/Nodes/ExportController.php
+++ b/src/Controllers/Nodes/ExportController.php
@@ -17,14 +17,8 @@
 
 class ExportController extends RozierApp
 {
-    private NodeSourceXlsxSerializer $xlsxSerializer;
-
-    /**
-     * @param NodeSourceXlsxSerializer $xlsxSerializer
-     */
-    public function __construct(NodeSourceXlsxSerializer $xlsxSerializer)
+    public function __construct(private readonly NodeSourceXlsxSerializer $xlsxSerializer)
     {
-        $this->xlsxSerializer = $xlsxSerializer;
     }
 
     /**
diff --git a/src/Controllers/Nodes/NodesAttributesController.php b/src/Controllers/Nodes/NodesAttributesController.php
index 5f11f8bd..d11e3ecd 100644
--- a/src/Controllers/Nodes/NodesAttributesController.php
+++ b/src/Controllers/Nodes/NodesAttributesController.php
@@ -26,14 +26,8 @@
 
 class NodesAttributesController extends RozierApp
 {
-    private FormFactoryInterface $formFactory;
-
-    /**
-     * @param FormFactoryInterface $formFactory
-     */
-    public function __construct(FormFactoryInterface $formFactory)
+    public function __construct(private readonly FormFactoryInterface $formFactory)
     {
-        $this->formFactory = $formFactory;
     }
 
     /**
diff --git a/src/Controllers/Nodes/NodesController.php b/src/Controllers/Nodes/NodesController.php
index d2763db6..c4ce1284 100644
--- a/src/Controllers/Nodes/NodesController.php
+++ b/src/Controllers/Nodes/NodesController.php
@@ -42,21 +42,6 @@ class NodesController extends RozierApp
 {
     use NodesTrait;
 
-    private NodeChrootResolver $nodeChrootResolver;
-    private NodeMover $nodeMover;
-    private Registry $workflowRegistry;
-    private HandlerFactoryInterface $handlerFactory;
-    private UniqueNodeGenerator $uniqueNodeGenerator;
-    private NodeFactory $nodeFactory;
-    /**
-     * @var class-string<AbstractType>
-     */
-    private string $nodeFormTypeClass;
-    /**
-     * @var class-string<AbstractType>
-     */
-    private string $addNodeFormTypeClass;
-
     /**
      * @param NodeChrootResolver $nodeChrootResolver
      * @param NodeMover $nodeMover
@@ -68,23 +53,15 @@ class NodesController extends RozierApp
      * @param class-string<AbstractType> $addNodeFormTypeClass
      */
     public function __construct(
-        NodeChrootResolver $nodeChrootResolver,
-        NodeMover $nodeMover,
-        Registry $workflowRegistry,
-        HandlerFactoryInterface $handlerFactory,
-        UniqueNodeGenerator $uniqueNodeGenerator,
-        NodeFactory $nodeFactory,
-        string $nodeFormTypeClass,
-        string $addNodeFormTypeClass
+        private readonly NodeChrootResolver $nodeChrootResolver,
+        private readonly NodeMover $nodeMover,
+        private readonly Registry $workflowRegistry,
+        private readonly HandlerFactoryInterface $handlerFactory,
+        private readonly UniqueNodeGenerator $uniqueNodeGenerator,
+        private readonly NodeFactory $nodeFactory,
+        private readonly string $nodeFormTypeClass,
+        private readonly string $addNodeFormTypeClass
     ) {
-        $this->nodeChrootResolver = $nodeChrootResolver;
-        $this->nodeMover = $nodeMover;
-        $this->workflowRegistry = $workflowRegistry;
-        $this->handlerFactory = $handlerFactory;
-        $this->nodeFormTypeClass = $nodeFormTypeClass;
-        $this->addNodeFormTypeClass = $addNodeFormTypeClass;
-        $this->uniqueNodeGenerator = $uniqueNodeGenerator;
-        $this->nodeFactory = $nodeFactory;
     }
 
     protected function getNodeFactory(): NodeFactory
diff --git a/src/Controllers/Nodes/NodesSourcesController.php b/src/Controllers/Nodes/NodesSourcesController.php
index ce28da25..980ed5f3 100644
--- a/src/Controllers/Nodes/NodesSourcesController.php
+++ b/src/Controllers/Nodes/NodesSourcesController.php
@@ -34,13 +34,10 @@ class NodesSourcesController extends RozierApp
 {
     use VersionedControllerTrait;
 
-    private JwtExtension $jwtExtension;
-    private FormErrorSerializer $formErrorSerializer;
-
-    public function __construct(JwtExtension $jwtExtension, FormErrorSerializer $formErrorSerializer)
-    {
-        $this->jwtExtension = $jwtExtension;
-        $this->formErrorSerializer = $formErrorSerializer;
+    public function __construct(
+        private readonly JwtExtension $jwtExtension,
+        private readonly FormErrorSerializer $formErrorSerializer
+    ) {
     }
 
     /**
@@ -241,7 +238,6 @@ public function removeAction(Request $request, int $nodeSourceId): Response
         $form->handleRequest($request);
 
         if ($form->isSubmitted() && $form->isValid()) {
-            /** @var Node $node */
             $node = $ns->getNode();
             /*
              * Dispatch event
diff --git a/src/Controllers/Nodes/NodesTreesController.php b/src/Controllers/Nodes/NodesTreesController.php
index 085d4410..7604d5b6 100644
--- a/src/Controllers/Nodes/NodesTreesController.php
+++ b/src/Controllers/Nodes/NodesTreesController.php
@@ -32,31 +32,13 @@
 
 class NodesTreesController extends RozierApp
 {
-    private NodeChrootResolver $nodeChrootResolver;
-    private TreeWidgetFactory $treeWidgetFactory;
-    private FormFactoryInterface $formFactory;
-    private HandlerFactoryInterface $handlerFactory;
-    private Registry $workflowRegistry;
-
-    /**
-     * @param NodeChrootResolver $nodeChrootResolver
-     * @param TreeWidgetFactory $treeWidgetFactory
-     * @param FormFactoryInterface $formFactory
-     * @param HandlerFactoryInterface $handlerFactory
-     * @param Registry $workflowRegistry
-     */
     public function __construct(
-        NodeChrootResolver $nodeChrootResolver,
-        TreeWidgetFactory $treeWidgetFactory,
-        FormFactoryInterface $formFactory,
-        HandlerFactoryInterface $handlerFactory,
-        Registry $workflowRegistry
+        private readonly NodeChrootResolver $nodeChrootResolver,
+        private readonly TreeWidgetFactory $treeWidgetFactory,
+        private readonly FormFactoryInterface $formFactory,
+        private readonly HandlerFactoryInterface $handlerFactory,
+        private readonly Registry $workflowRegistry
     ) {
-        $this->nodeChrootResolver = $nodeChrootResolver;
-        $this->treeWidgetFactory = $treeWidgetFactory;
-        $this->formFactory = $formFactory;
-        $this->handlerFactory = $handlerFactory;
-        $this->workflowRegistry = $workflowRegistry;
     }
 
     /**
@@ -359,12 +341,7 @@ private function bulkDeleteNodes(array $data)
         return $this->getTranslator()->trans('wrong.request');
     }
 
-    /**
-     * @param array $data
-     *
-     * @return string
-     */
-    private function bulkStatusNodes(array $data)
+    private function bulkStatusNodes(array $data): string
     {
         if (!empty($data['nodesIds'])) {
             $nodesIds = trim($data['nodesIds']);
@@ -393,10 +370,7 @@ private function bulkStatusNodes(array $data)
         return $this->getTranslator()->trans('wrong.request');
     }
 
-    /**
-     * @return FormInterface
-     */
-    private function buildBulkTagForm()
+    private function buildBulkTagForm(): FormInterface
     {
         /** @var FormBuilder $builder */
         $builder = $this->formFactory
diff --git a/src/Controllers/Nodes/NodesUtilsController.php b/src/Controllers/Nodes/NodesUtilsController.php
index e2e293a9..cf73e9fc 100644
--- a/src/Controllers/Nodes/NodesUtilsController.php
+++ b/src/Controllers/Nodes/NodesUtilsController.php
@@ -16,14 +16,8 @@
 
 class NodesUtilsController extends RozierApp
 {
-    private NodeNamePolicyInterface $nodeNamePolicy;
-
-    /**
-     * @param NodeNamePolicyInterface $nodeNamePolicy
-     */
-    public function __construct(NodeNamePolicyInterface $nodeNamePolicy)
+    public function __construct(private readonly NodeNamePolicyInterface $nodeNamePolicy)
     {
-        $this->nodeNamePolicy = $nodeNamePolicy;
     }
 
     /**
diff --git a/src/Controllers/Nodes/TranstypeController.php b/src/Controllers/Nodes/TranstypeController.php
index c8b51d90..7e3326ae 100644
--- a/src/Controllers/Nodes/TranstypeController.php
+++ b/src/Controllers/Nodes/TranstypeController.php
@@ -10,7 +10,6 @@
 use RZ\Roadiz\CoreBundle\Event\NodesSources\NodesSourcesUpdatedEvent;
 use RZ\Roadiz\CoreBundle\Node\NodeTranstyper;
 use RZ\Roadiz\CoreBundle\Security\Authorization\Voter\NodeVoter;
-use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
@@ -20,14 +19,8 @@
 
 class TranstypeController extends RozierApp
 {
-    private NodeTranstyper $nodeTranstyper;
-
-    /**
-     * @param NodeTranstyper $nodeTranstyper
-     */
-    public function __construct(NodeTranstyper $nodeTranstyper)
+    public function __construct(private readonly NodeTranstyper $nodeTranstyper)
     {
-        $this->nodeTranstyper = $nodeTranstyper;
     }
 
     /**
diff --git a/src/Controllers/RolesUtilsController.php b/src/Controllers/RolesUtilsController.php
index f0a5907e..4cc08dc7 100644
--- a/src/Controllers/RolesUtilsController.php
+++ b/src/Controllers/RolesUtilsController.php
@@ -20,17 +20,10 @@
 
 class RolesUtilsController extends RozierApp
 {
-    private SerializerInterface $serializer;
-    private RolesImporter $rolesImporter;
-
-    /**
-     * @param SerializerInterface $serializer
-     * @param RolesImporter $rolesImporter
-     */
-    public function __construct(SerializerInterface $serializer, RolesImporter $rolesImporter)
-    {
-        $this->serializer = $serializer;
-        $this->rolesImporter = $rolesImporter;
+    public function __construct(
+        private readonly SerializerInterface $serializer,
+        private readonly RolesImporter $rolesImporter
+    ) {
     }
 
     /**
diff --git a/src/Controllers/SearchController.php b/src/Controllers/SearchController.php
index d6d4aecf..6d0b4e8c 100644
--- a/src/Controllers/SearchController.php
+++ b/src/Controllers/SearchController.php
@@ -68,7 +68,7 @@ public function notBlank(mixed $var): bool
      *
      * @return array
      */
-    protected function appendDateTimeCriteria(array &$data, string $fieldName)
+    protected function appendDateTimeCriteria(array &$data, string $fieldName): array
     {
         $date = $data[$fieldName]['compareDatetime'];
         if ($date instanceof DateTime) {
@@ -86,7 +86,7 @@ protected function appendDateTimeCriteria(array &$data, string $fieldName)
      * @param string $prefix
      * @return mixed
      */
-    protected function processCriteria($data, string $prefix = "")
+    protected function processCriteria($data, string $prefix = ""): mixed
     {
         if (!empty($data[$prefix . "nodeName"])) {
             if (isset($data[$prefix . "nodeName_exact"]) && $data[$prefix . "nodeName_exact"] === true) {
@@ -139,11 +139,11 @@ protected function processCriteria($data, string $prefix = "")
     }
 
     /**
-     * @param array|\Traversable $data
+     * @param array $data
      * @param NodeType $nodetype
-     * @return mixed
+     * @return array
      */
-    protected function processCriteriaNodetype($data, NodeType $nodetype)
+    protected function processCriteriaNodetype(array $data, NodeType $nodetype): array
     {
         $fields = $nodetype->getFields();
         foreach ($data as $key => $value) {
@@ -197,7 +197,7 @@ protected function processCriteriaNodetype($data, NodeType $nodetype)
      * @return Response
      * @throws RuntimeError
      */
-    public function searchNodeAction(Request $request)
+    public function searchNodeAction(Request $request): Response
     {
         $builder = $this->buildSimpleForm('');
         $form = $this->addButtons($builder)->getForm();
@@ -253,12 +253,12 @@ public function searchNodeAction(Request $request)
      * @param Request $request
      * @param int $nodetypeId
      *
-     * @return null|RedirectResponse|Response
+     * @return Response
      * @throws Exception
      * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
      * @throws RuntimeError
      */
-    public function searchNodeSourceAction(Request $request, int $nodetypeId)
+    public function searchNodeSourceAction(Request $request, int $nodetypeId): Response
     {
         /** @var NodeType|null $nodetype */
         $nodetype = $this->em()->find(NodeType::class, $nodetypeId);
@@ -346,7 +346,7 @@ protected function addButtons(FormBuilderInterface $builder, bool $exportXlsx =
      *
      * @return null|RedirectResponse
      */
-    protected function handleNodeTypeForm(FormInterface $nodeTypeForm)
+    protected function handleNodeTypeForm(FormInterface $nodeTypeForm): ?RedirectResponse
     {
         if ($nodeTypeForm->isSubmitted() && $nodeTypeForm->isValid()) {
             if (empty($nodeTypeForm->getData()['nodetype'])) {
@@ -451,7 +451,7 @@ protected function handleNodeForm(FormInterface $form, NodeType $nodetype): ?Res
      * @throws Exception
      * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
      */
-    protected function getXlsxResults(NodeType $nodetype, $entities): string
+    protected function getXlsxResults(NodeType $nodetype, iterable $entities): string
     {
         $fields = $nodetype->getFields();
         $keys = [];
diff --git a/src/Controllers/SettingsController.php b/src/Controllers/SettingsController.php
index 8a57e58d..9fbd1ecc 100644
--- a/src/Controllers/SettingsController.php
+++ b/src/Controllers/SettingsController.php
@@ -28,13 +28,10 @@
 
 class SettingsController extends RozierApp
 {
-    private FormFactoryInterface $formFactory;
-    private FormErrorSerializer $formErrorSerializer;
-
-    public function __construct(FormFactoryInterface $formFactory, FormErrorSerializer $formErrorSerializer)
-    {
-        $this->formFactory = $formFactory;
-        $this->formErrorSerializer = $formErrorSerializer;
+    public function __construct(
+        private readonly FormFactoryInterface $formFactory,
+        private readonly FormErrorSerializer $formErrorSerializer
+    ) {
     }
 
     /**
diff --git a/src/Controllers/SettingsUtilsController.php b/src/Controllers/SettingsUtilsController.php
index dff29f0e..8d963eb4 100644
--- a/src/Controllers/SettingsUtilsController.php
+++ b/src/Controllers/SettingsUtilsController.php
@@ -6,9 +6,9 @@
 
 use JMS\Serializer\SerializationContext;
 use JMS\Serializer\SerializerInterface;
-use RZ\Roadiz\CoreBundle\Importer\SettingsImporter;
 use RZ\Roadiz\CoreBundle\Entity\Setting;
 use RZ\Roadiz\CoreBundle\Entity\SettingGroup;
+use RZ\Roadiz\CoreBundle\Importer\SettingsImporter;
 use RZ\Roadiz\Utils\StringHandler;
 use Symfony\Component\Form\Extension\Core\Type\FileType;
 use Symfony\Component\Form\FormError;
@@ -21,17 +21,10 @@
 
 class SettingsUtilsController extends RozierApp
 {
-    private SerializerInterface $serializer;
-    private SettingsImporter $settingsImporter;
-
-    /**
-     * @param SerializerInterface $serializer
-     * @param SettingsImporter $settingsImporter
-     */
-    public function __construct(SerializerInterface $serializer, SettingsImporter $settingsImporter)
-    {
-        $this->serializer = $serializer;
-        $this->settingsImporter = $settingsImporter;
+    public function __construct(
+        private readonly SerializerInterface $serializer,
+        private readonly SettingsImporter $settingsImporter
+    ) {
     }
 
     /**
diff --git a/src/Controllers/Tags/TagMultiCreationController.php b/src/Controllers/Tags/TagMultiCreationController.php
index f71ddb4a..fa8632b9 100644
--- a/src/Controllers/Tags/TagMultiCreationController.php
+++ b/src/Controllers/Tags/TagMultiCreationController.php
@@ -9,7 +9,6 @@
 use RZ\Roadiz\CoreBundle\Event\Tag\TagCreatedEvent;
 use RZ\Roadiz\CoreBundle\Tag\TagFactory;
 use Symfony\Component\Form\FormError;
-use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
@@ -18,79 +17,73 @@
 
 class TagMultiCreationController extends RozierApp
 {
-    private TagFactory $tagFactory;
-
-    /**
-     * @param TagFactory $tagFactory
-     */
-    public function __construct(TagFactory $tagFactory)
+    public function __construct(private readonly TagFactory $tagFactory)
     {
-        $this->tagFactory = $tagFactory;
     }
 
     /**
      * @param Request $request
      * @param int $parentTagId
-     * @return RedirectResponse|Response|null
+     * @return Response
      * @throws \Twig\Error\RuntimeError
      */
-    public function addChildAction(Request $request, int $parentTagId)
+    public function addChildAction(Request $request, int $parentTagId): Response
     {
         $this->denyAccessUnlessGranted('ROLE_ACCESS_TAGS');
 
         $translation = $this->em()->getRepository(Translation::class)->findDefault();
         $parentTag = $this->em()->find(Tag::class, $parentTagId);
 
-        if (null !== $parentTag) {
-            $form = $this->createForm(MultiTagType::class);
-            $form->handleRequest($request);
-
-            if ($form->isSubmitted() && $form->isValid()) {
-                try {
-                    $data = $form->getData();
-                    $names = explode(',', $data['names']);
-                    $names = array_map('trim', $names);
-                    $names = array_filter($names);
-                    $names = array_unique($names);
-
-                    /*
-                     * Get latest position to add tags after.
-                     */
-                    $latestPosition = $this->em()
-                        ->getRepository(Tag::class)
-                        ->findLatestPositionInParent($parentTag);
+        if (null === $parentTag) {
+            throw new ResourceNotFoundException();
+        }
 
-                    $tagsArray = [];
-                    foreach ($names as $name) {
-                        $tagsArray[] = $this->tagFactory->create($name, $translation, $parentTag, $latestPosition);
-                        $this->em()->flush();
-                    }
+        $form = $this->createForm(MultiTagType::class);
+        $form->handleRequest($request);
+
+        if ($form->isSubmitted() && $form->isValid()) {
+            try {
+                $data = $form->getData();
+                $names = explode(',', $data['names']);
+                $names = array_map('trim', $names);
+                $names = array_filter($names);
+                $names = array_unique($names);
+
+                /*
+                 * Get latest position to add tags after.
+                 */
+                $latestPosition = $this->em()
+                    ->getRepository(Tag::class)
+                    ->findLatestPositionInParent($parentTag);
+
+                $tagsArray = [];
+                foreach ($names as $name) {
+                    $tagsArray[] = $this->tagFactory->create($name, $translation, $parentTag, $latestPosition);
+                    $this->em()->flush();
+                }
 
+                /*
+                 * Dispatch event and msg
+                 */
+                foreach ($tagsArray as $tag) {
                     /*
-                     * Dispatch event and msg
+                     * Dispatch event
                      */
-                    foreach ($tagsArray as $tag) {
-                        /*
-                         * Dispatch event
-                         */
-                        $this->dispatchEvent(new TagCreatedEvent($tag));
-                        $msg = $this->getTranslator()->trans('child.tag.%name%.created', ['%name%' => $tag->getTagName()]);
-                        $this->publishConfirmMessage($request, $msg, $tag);
-                    }
-
-                    return $this->redirectToRoute('tagsTreePage', ['tagId' => $parentTagId]);
-                } catch (\InvalidArgumentException $e) {
-                    $form->addError(new FormError($e->getMessage()));
+                    $this->dispatchEvent(new TagCreatedEvent($tag));
+                    $msg = $this->getTranslator()->trans('child.tag.%name%.created', ['%name%' => $tag->getTagName()]);
+                    $this->publishConfirmMessage($request, $msg, $tag);
                 }
-            }
 
-            $this->assignation['translation'] = $translation;
-            $this->assignation['form'] = $form->createView();
-            $this->assignation['tag'] = $parentTag;
-
-            return $this->render('@RoadizRozier/tags/add-multiple.html.twig', $this->assignation);
+                return $this->redirectToRoute('tagsTreePage', ['tagId' => $parentTagId]);
+            } catch (\InvalidArgumentException $e) {
+                $form->addError(new FormError($e->getMessage()));
+            }
         }
 
-        throw new ResourceNotFoundException();
+        $this->assignation['translation'] = $translation;
+        $this->assignation['form'] = $form->createView();
+        $this->assignation['tag'] = $parentTag;
+
+        return $this->render('@RoadizRozier/tags/add-multiple.html.twig', $this->assignation);
     }
 }
diff --git a/src/Controllers/Tags/TagsController.php b/src/Controllers/Tags/TagsController.php
index ca50fb93..f5fd8a81 100644
--- a/src/Controllers/Tags/TagsController.php
+++ b/src/Controllers/Tags/TagsController.php
@@ -39,23 +39,11 @@ class TagsController extends RozierApp
 {
     use VersionedControllerTrait;
 
-    private HandlerFactoryInterface $handlerFactory;
-    private FormFactoryInterface $formFactory;
-    private TreeWidgetFactory $treeWidgetFactory;
-
-    /**
-     * @param FormFactoryInterface $formFactory
-     * @param HandlerFactoryInterface $handlerFactory
-     * @param TreeWidgetFactory $treeWidgetFactory
-     */
     public function __construct(
-        FormFactoryInterface $formFactory,
-        HandlerFactoryInterface $handlerFactory,
-        TreeWidgetFactory $treeWidgetFactory
+        private readonly FormFactoryInterface $formFactory,
+        private readonly HandlerFactoryInterface $handlerFactory,
+        private readonly TreeWidgetFactory $treeWidgetFactory
     ) {
-        $this->handlerFactory = $handlerFactory;
-        $this->formFactory = $formFactory;
-        $this->treeWidgetFactory = $treeWidgetFactory;
     }
 
     /**
@@ -304,8 +292,8 @@ public function bulkDeleteAction(Request $request): Response
 
     /**
      * @param Request $request
-     *
      * @return Response
+     * @throws RuntimeError
      */
     public function addAction(Request $request): Response
     {
@@ -361,6 +349,7 @@ public function addAction(Request $request): Response
      * @param int $tagId
      *
      * @return Response
+     * @throws RuntimeError
      */
     public function editSettingsAction(Request $request, int $tagId): Response
     {
@@ -430,6 +419,7 @@ public function editSettingsAction(Request $request, int $tagId): Response
      * @param int|null $translationId
      *
      * @return Response
+     * @throws RuntimeError
      */
     public function treeAction(Request $request, int $tagId, ?int $translationId = null): Response
     {
@@ -461,9 +451,10 @@ public function treeAction(Request $request, int $tagId, ?int $translationId = n
      * Return a deletion form for requested tag.
      *
      * @param Request $request
-     * @param int     $tagId
+     * @param int $tagId
      *
      * @return Response
+     * @throws RuntimeError
      */
     public function deleteAction(Request $request, int $tagId): Response
     {
@@ -523,6 +514,7 @@ public function deleteAction(Request $request, int $tagId): Response
      * @param int|null $translationId
      *
      * @return Response
+     * @throws RuntimeError
      */
     public function addChildAction(Request $request, int $tagId, ?int $translationId = null): Response
     {
@@ -649,13 +641,13 @@ private function buildDeleteForm(Tag $tag): FormInterface
     }
 
     /**
-     * @param false|string $referer
+     * @param null|string $referer
      * @param array $tagsIds
      *
      * @return FormInterface
      */
     private function buildBulkDeleteForm(
-        $referer = false,
+        ?string $referer = null,
         array $tagsIds = []
     ): FormInterface {
         $builder = $this->formFactory
@@ -669,7 +661,7 @@ private function buildBulkDeleteForm(
                 ],
             ]);
 
-        if (false !== $referer && (new UnicodeString($referer))->startsWith('/')) {
+        if (null !== $referer && (new UnicodeString($referer))->startsWith('/')) {
             $builder->add('referer', HiddenType::class, [
                 'data' => $referer,
             ]);
diff --git a/src/Controllers/Tags/TagsUtilsController.php b/src/Controllers/Tags/TagsUtilsController.php
index 1108a87d..71f96693 100644
--- a/src/Controllers/Tags/TagsUtilsController.php
+++ b/src/Controllers/Tags/TagsUtilsController.php
@@ -14,14 +14,8 @@
 
 class TagsUtilsController extends RozierApp
 {
-    private SerializerInterface $serializer;
-
-    /**
-     * @param SerializerInterface $serializer
-     */
-    public function __construct(SerializerInterface $serializer)
+    public function __construct(private readonly SerializerInterface $serializer)
     {
-        $this->serializer = $serializer;
     }
 
     /**
diff --git a/src/Controllers/TranslationsController.php b/src/Controllers/TranslationsController.php
index 968a268e..601c24b1 100644
--- a/src/Controllers/TranslationsController.php
+++ b/src/Controllers/TranslationsController.php
@@ -4,12 +4,12 @@
 
 namespace Themes\Rozier\Controllers;
 
+use RZ\Roadiz\Core\Handlers\HandlerFactoryInterface;
 use RZ\Roadiz\CoreBundle\Entity\Translation;
+use RZ\Roadiz\CoreBundle\EntityHandler\TranslationHandler;
 use RZ\Roadiz\CoreBundle\Event\Translation\TranslationCreatedEvent;
 use RZ\Roadiz\CoreBundle\Event\Translation\TranslationDeletedEvent;
 use RZ\Roadiz\CoreBundle\Event\Translation\TranslationUpdatedEvent;
-use RZ\Roadiz\Core\Handlers\HandlerFactoryInterface;
-use RZ\Roadiz\CoreBundle\EntityHandler\TranslationHandler;
 use Symfony\Component\Form\Extension\Core\Type\FormType;
 use Symfony\Component\Form\FormError;
 use Symfony\Component\HttpFoundation\Request;
@@ -23,11 +23,8 @@ class TranslationsController extends RozierApp
 {
     public const ITEM_PER_PAGE = 5;
 
-    private HandlerFactoryInterface $handlerFactory;
-
-    public function __construct(HandlerFactoryInterface $handlerFactory)
+    public function __construct(private readonly HandlerFactoryInterface $handlerFactory)
     {
-        $this->handlerFactory = $handlerFactory;
     }
 
     /**
diff --git a/src/Controllers/WebhookController.php b/src/Controllers/WebhookController.php
index ff1186ec..f86bfe1c 100644
--- a/src/Controllers/WebhookController.php
+++ b/src/Controllers/WebhookController.php
@@ -19,16 +19,13 @@
 
 final class WebhookController extends AbstractAdminWithBulkController
 {
-    private WebhookDispatcher $webhookDispatcher;
-
     public function __construct(
-        WebhookDispatcher $webhookDispatcher,
+        private readonly WebhookDispatcher $webhookDispatcher,
         FormFactoryInterface $formFactory,
         SerializerInterface $serializer,
         UrlGeneratorInterface $urlGenerator
     ) {
         parent::__construct($formFactory, $serializer, $urlGenerator);
-        $this->webhookDispatcher = $webhookDispatcher;
     }
 
     public function triggerAction(Request $request, string $id): Response