From b9e2f7ad83c36e81b70e2cb31cecaea596ad21f3 Mon Sep 17 00:00:00 2001 From: Ambroise Maupate Date: Tue, 5 Sep 2023 15:52:04 +0200 Subject: [PATCH] feat(Chroot): Display node chroot on mainNodeTree instead of its children --- .../src/Repository/NodeRepository.php | 2 +- .../Authorization/Voter/NodeVoter.php | 17 ++++---- .../AjaxNodeTreeController.php | 2 +- .../AjaxSearchNodesSourcesController.php | 17 ++++---- .../views/nodes/breadcrumb.html.twig | 42 ++++++++++--------- .../views/panels/tree_panel.html.twig | 21 ++++++++-- .../widgets/nodeTree/singleNode.html.twig | 5 +-- lib/Rozier/src/Widgets/AbstractWidget.php | 4 +- lib/Rozier/src/Widgets/FolderTreeWidget.php | 8 +--- lib/Rozier/src/Widgets/NodeTreeWidget.php | 41 +++++++++--------- lib/Rozier/src/Widgets/TagTreeWidget.php | 10 ++--- lib/Rozier/src/Widgets/TreeWidgetFactory.php | 11 +++++ 12 files changed, 104 insertions(+), 76 deletions(-) diff --git a/lib/RoadizCoreBundle/src/Repository/NodeRepository.php b/lib/RoadizCoreBundle/src/Repository/NodeRepository.php index bbb620cb..8509e779 100644 --- a/lib/RoadizCoreBundle/src/Repository/NodeRepository.php +++ b/lib/RoadizCoreBundle/src/Repository/NodeRepository.php @@ -911,7 +911,7 @@ public function findByReverseNodeAndFieldAndTranslation( public function findAllOffspringIdByNode(Node $node): array { $theOffsprings = []; - $in = [$node->getId()]; + $in = \array_filter([(int) $node->getId()]); do { $theOffsprings = array_merge($theOffsprings, $in); diff --git a/lib/RoadizCoreBundle/src/Security/Authorization/Voter/NodeVoter.php b/lib/RoadizCoreBundle/src/Security/Authorization/Voter/NodeVoter.php index be0f1765..065060bd 100644 --- a/lib/RoadizCoreBundle/src/Security/Authorization/Voter/NodeVoter.php +++ b/lib/RoadizCoreBundle/src/Security/Authorization/Voter/NodeVoter.php @@ -37,21 +37,23 @@ public function __construct( private Security $security, private HandlerFactoryInterface $handlerFactory, private CacheItemPoolInterface $cache - ) - { + ) { } protected function supports(string $attribute, $subject): bool { - if (\in_array($attribute, [ + if ( + \in_array($attribute, [ self::CREATE_AT_ROOT, self::READ_AT_ROOT, self::EMPTY_TRASH, - ])) { + ]) + ) { return true; } - if (!\in_array($attribute, [ + if ( + !\in_array($attribute, [ self::CREATE, self::DUPLICATE, self::READ, @@ -63,7 +65,8 @@ protected function supports(string $attribute, $subject): bool self::EDIT_STATUS, self::EDIT_ATTRIBUTE, self::DELETE - ])) { + ]) + ) { return false; } @@ -87,7 +90,7 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $ $subject = $subject->getNode(); } - return match($attribute) { + return match ($attribute) { self::CREATE => $this->canCreate($subject, $user), self::DUPLICATE => $this->canDuplicate($subject, $user), self::CREATE_AT_ROOT => $this->canCreateAtRoot($user), diff --git a/lib/Rozier/src/AjaxControllers/AjaxNodeTreeController.php b/lib/Rozier/src/AjaxControllers/AjaxNodeTreeController.php index abcae510..ece280b4 100644 --- a/lib/Rozier/src/AjaxControllers/AjaxNodeTreeController.php +++ b/lib/Rozier/src/AjaxControllers/AjaxNodeTreeController.php @@ -121,7 +121,7 @@ public function getTreeAction(Request $request): JsonResponse $parent = $this->nodeChrootResolver->getChroot($this->getUser()); } - $nodeTree = $this->treeWidgetFactory->createNodeTree($parent, $translation); + $nodeTree = $this->treeWidgetFactory->createRootNodeTree($parent, $translation); $this->assignation['mainNodeTree'] = true; break; } diff --git a/lib/Rozier/src/AjaxControllers/AjaxSearchNodesSourcesController.php b/lib/Rozier/src/AjaxControllers/AjaxSearchNodesSourcesController.php index 205d683e..f8ac73ef 100644 --- a/lib/Rozier/src/AjaxControllers/AjaxSearchNodesSourcesController.php +++ b/lib/Rozier/src/AjaxControllers/AjaxSearchNodesSourcesController.php @@ -8,25 +8,27 @@ use RZ\Roadiz\CoreBundle\Entity\NodesSourcesDocuments; use RZ\Roadiz\CoreBundle\Entity\Translation; use RZ\Roadiz\CoreBundle\SearchEngine\GlobalNodeSourceSearchHandler; +use RZ\Roadiz\CoreBundle\Security\Authorization\Voter\NodeVoter; use RZ\Roadiz\Documents\UrlGenerators\DocumentUrlGeneratorInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Symfony\Component\Security\Core\Security; class AjaxSearchNodesSourcesController extends AbstractAjaxController { - public const RESULT_COUNT = 8; - private DocumentUrlGeneratorInterface $documentUrlGenerator; + public const RESULT_COUNT = 10; - public function __construct(DocumentUrlGeneratorInterface $documentUrlGenerator) - { - $this->documentUrlGenerator = $documentUrlGenerator; + public function __construct( + private DocumentUrlGeneratorInterface $documentUrlGenerator, + private Security $security + ) { } /** * Handle AJAX edition requests for Node - * such as coming from nodetree widgets. + * such as coming from node-tree widgets. * * @param Request $request * @@ -43,7 +45,7 @@ public function searchAction(Request $request): Response $searchHandler = new GlobalNodeSourceSearchHandler($this->em()); $searchHandler->setDisplayNonPublishedNodes(true); - /** @var array $nodesSources */ + /** @var array $nodesSources */ $nodesSources = $searchHandler->getNodeSourcesBySearchTerm( $request->get('searchTerms'), static::RESULT_COUNT @@ -60,6 +62,7 @@ public function searchAction(Request $request): Response foreach ($nodesSources as $source) { if ( $source instanceof NodesSources && + $this->security->isGranted(NodeVoter::READ, $source) && !key_exists($source->getNode()->getId(), $responseArray['data']) ) { $responseArray['data'][$source->getNode()->getId()] = $this->getNodeSourceData($source); diff --git a/lib/Rozier/src/Resources/views/nodes/breadcrumb.html.twig b/lib/Rozier/src/Resources/views/nodes/breadcrumb.html.twig index 2857aa4c..3ca6d84a 100644 --- a/lib/Rozier/src/Resources/views/nodes/breadcrumb.html.twig +++ b/lib/Rozier/src/Resources/views/nodes/breadcrumb.html.twig @@ -7,30 +7,32 @@ {% apply spaceless %} diff --git a/lib/Rozier/src/Resources/views/panels/tree_panel.html.twig b/lib/Rozier/src/Resources/views/panels/tree_panel.html.twig index cc2a0e8f..ed1fb4b6 100644 --- a/lib/Rozier/src/Resources/views/panels/tree_panel.html.twig +++ b/lib/Rozier/src/Resources/views/panels/tree_panel.html.twig @@ -21,13 +21,28 @@ {% if tabCount > 1 %} {% endif %} diff --git a/lib/Rozier/src/Resources/views/widgets/nodeTree/singleNode.html.twig b/lib/Rozier/src/Resources/views/widgets/nodeTree/singleNode.html.twig index 7974a296..e5c80888 100644 --- a/lib/Rozier/src/Resources/views/widgets/nodeTree/singleNode.html.twig +++ b/lib/Rozier/src/Resources/views/widgets/nodeTree/singleNode.html.twig @@ -7,8 +7,8 @@ {% set type = node.nodeType.name %} {% set classes = [ -type|lower, -'nodetree-element' + type|lower, + 'nodetree-element' ] %} {% set classes = classes|merge(['uk-nestable-item']) %} @@ -52,7 +52,6 @@ type|lower, {% endif %} {% endif %} -
  • {% if not mainNodeTree and not nodeTree.isStackTree %} diff --git a/lib/Rozier/src/Widgets/AbstractWidget.php b/lib/Rozier/src/Widgets/AbstractWidget.php index 1e3561da..c7d973cc 100644 --- a/lib/Rozier/src/Widgets/AbstractWidget.php +++ b/lib/Rozier/src/Widgets/AbstractWidget.php @@ -17,8 +17,8 @@ */ abstract class AbstractWidget { - private RequestStack $requestStack; - private ManagerRegistry $managerRegistry; + protected RequestStack $requestStack; + protected ManagerRegistry $managerRegistry; protected ?TranslationInterface $defaultTranslation = null; /** diff --git a/lib/Rozier/src/Widgets/FolderTreeWidget.php b/lib/Rozier/src/Widgets/FolderTreeWidget.php index 73bd84f4..60aca21e 100644 --- a/lib/Rozier/src/Widgets/FolderTreeWidget.php +++ b/lib/Rozier/src/Widgets/FolderTreeWidget.php @@ -4,7 +4,6 @@ namespace Themes\Rozier\Widgets; -use Doctrine\ORM\Tools\Pagination\Paginator; use Doctrine\Persistence\ManagerRegistry; use RZ\Roadiz\CoreBundle\Entity\Folder; use Symfony\Component\HttpFoundation\RequestStack; @@ -15,10 +14,7 @@ final class FolderTreeWidget extends AbstractWidget { protected ?Folder $parentFolder = null; - /** - * @var array|Paginator|null - */ - protected $folders = null; + protected ?iterable $folders = null; /** * @param RequestStack $requestStack @@ -53,7 +49,7 @@ public function getRootFolder(): ?Folder } /** - * @return array|Paginator + * @return iterable */ public function getFolders(): iterable { diff --git a/lib/Rozier/src/Widgets/NodeTreeWidget.php b/lib/Rozier/src/Widgets/NodeTreeWidget.php index 7aa22bf7..76a3b749 100644 --- a/lib/Rozier/src/Widgets/NodeTreeWidget.php +++ b/lib/Rozier/src/Widgets/NodeTreeWidget.php @@ -4,7 +4,6 @@ namespace Themes\Rozier\Widgets; -use Doctrine\ORM\Tools\Pagination\Paginator; use Doctrine\Persistence\ManagerRegistry; use RZ\Roadiz\Core\AbstractEntities\TranslationInterface; use RZ\Roadiz\CoreBundle\Entity\Node; @@ -19,34 +18,35 @@ final class NodeTreeWidget extends AbstractWidget { public const SESSION_ITEM_PER_PAGE = 'nodetree_item_per_page'; - protected ?Node $parentNode = null; - /** - * @var array|Paginator|null - */ - protected $nodes = null; - protected ?Tag $tag = null; - protected ?TranslationInterface $translation = null; - protected bool $stackTree = false; - protected ?array $filters = null; - protected bool $canReorder = true; - protected array $additionalCriteria = []; + private ?Node $parentNode = null; + private ?iterable $nodes = null; + private ?Tag $tag = null; + private ?TranslationInterface $translation = null; + private bool $stackTree = false; + private ?array $filters = null; + private bool $canReorder = true; + private array $additionalCriteria = []; + private bool $includeRootNode; /** * @param RequestStack $requestStack * @param ManagerRegistry $managerRegistry * @param Node|null $parent Entry point of NodeTreeWidget, set null if it's root * @param TranslationInterface|null $translation NodeTree translation + * @param bool $includeRootNode */ public function __construct( RequestStack $requestStack, ManagerRegistry $managerRegistry, ?Node $parent = null, - ?TranslationInterface $translation = null + ?TranslationInterface $translation = null, + bool $includeRootNode = false ) { parent::__construct($requestStack, $managerRegistry); $this->parentNode = $parent; $this->translation = $translation; + $this->includeRootNode = $includeRootNode; } /** @@ -78,13 +78,13 @@ public function isStackTree(): bool } /** - * @param bool $newstackTree + * @param bool $stackTree * * @return $this */ - public function setStackTree(bool $newstackTree): NodeTreeWidget + public function setStackTree(bool $stackTree): NodeTreeWidget { - $this->stackTree = (bool) $newstackTree; + $this->stackTree = $stackTree; return $this; } @@ -209,7 +209,7 @@ protected function getListManager( /** * @param Node|null $parent * @param bool $subRequest Default: false - * @return array|Paginator + * @return iterable */ public function getChildrenNodes(Node $parent = null, bool $subRequest = false): iterable { @@ -219,7 +219,7 @@ public function getChildrenNodes(Node $parent = null, bool $subRequest = false): /** * @param Node|null $parent * @param bool $subRequest Default: false - * @return array|Paginator + * @return iterable */ public function getReachableChildrenNodes(Node $parent = null, bool $subRequest = false): iterable { @@ -270,10 +270,13 @@ public function getAvailableTranslations(): array } /** - * @return array|Paginator + * @return iterable */ public function getNodes(): iterable { + if ($this->includeRootNode && null !== $this->getRootNode()) { + return [$this->getRootNode()]; + } if (null === $this->nodes) { $manager = $this->getRootListManager(); $this->nodes = $manager->getEntities(); diff --git a/lib/Rozier/src/Widgets/TagTreeWidget.php b/lib/Rozier/src/Widgets/TagTreeWidget.php index 8996c0b1..c4c858f2 100644 --- a/lib/Rozier/src/Widgets/TagTreeWidget.php +++ b/lib/Rozier/src/Widgets/TagTreeWidget.php @@ -4,7 +4,6 @@ namespace Themes\Rozier\Widgets; -use Doctrine\ORM\Tools\Pagination\Paginator; use Doctrine\Persistence\ManagerRegistry; use RZ\Roadiz\CoreBundle\Entity\Tag; use RZ\Roadiz\CoreBundle\Repository\TagRepository; @@ -16,10 +15,7 @@ final class TagTreeWidget extends AbstractWidget { protected ?Tag $parentTag = null; - /** - * @var array|Paginator|null - */ - protected $tags = null; + protected ?iterable $tags = null; protected bool $canReorder = true; protected bool $forceTranslation = false; @@ -111,9 +107,9 @@ public function getRootTag(): ?Tag } /** - * @return array|Paginator|null + * @return iterable */ - public function getTags(): ?iterable + public function getTags(): iterable { if ($this->tags === null) { $this->getTagTreeAssignationForParent(); diff --git a/lib/Rozier/src/Widgets/TreeWidgetFactory.php b/lib/Rozier/src/Widgets/TreeWidgetFactory.php index 575ed8b4..f5a417bc 100644 --- a/lib/Rozier/src/Widgets/TreeWidgetFactory.php +++ b/lib/Rozier/src/Widgets/TreeWidgetFactory.php @@ -36,6 +36,17 @@ public function createNodeTree(?Node $root = null, ?TranslationInterface $transl ); } + public function createRootNodeTree(?Node $root = null, ?TranslationInterface $translation = null): NodeTreeWidget + { + return new NodeTreeWidget( + $this->requestStack, + $this->managerRegistry, + $root, + $translation, + true + ); + } + public function createTagTree(?Tag $root = null): TagTreeWidget { return new TagTreeWidget(