From 09f4e2be2b405a8a5d4f85d4b2b3ce79f46e47fa Mon Sep 17 00:00:00 2001 From: Lorenz Ulrich Date: Sun, 10 Dec 2023 21:44:41 +0100 Subject: [PATCH] FEATURE: Make taxonomies sortable Since all Taxonomy items are nodes, the sortingIndex of the nodes is already respected. Instead of just having an alphabetical sorting by title, we allow sorting taxonomies in the backend module. This is helpful if taxonomies are used e.g. as a filter in the frontend and you explicitly want to sort the items. --- Classes/Controller/ModuleController.php | 59 ++++++++++++++++--- Configuration/Policy.yaml | 2 +- .../Fusion/Backend/Views/Taxonomy.List.fusion | 26 +++++++- 3 files changed, 77 insertions(+), 10 deletions(-) diff --git a/Classes/Controller/ModuleController.php b/Classes/Controller/ModuleController.php index cbaa8bb..72b8fe0 100644 --- a/Classes/Controller/ModuleController.php +++ b/Classes/Controller/ModuleController.php @@ -274,12 +274,6 @@ public function vocabularyAction(NodeInterface $vocabulary) $this->view->assign('vocabulary', $vocabulary); $this->view->assign('defaultVocabulary', $this->getNodeInDefaultDimensions($vocabulary)); $taxonomies = $this->fetchChildTaxonomies($vocabulary); - usort($taxonomies, function (array $taxonomyA, array $taxonomyB) { - return strcmp( - $taxonomyA['node']->getProperty('title') ?: '', - $taxonomyB['node']->getProperty('title') ?: '' - ); - }); $this->view->assign('taxonomies', $taxonomies); } @@ -501,7 +495,7 @@ public function updateTaxonomyAction(NodeInterface $taxonomy, array $properties) public function deleteTaxonomyAction(NodeInterface $taxonomy) { if ($taxonomy->isAutoCreated()) { - throw new \Exception('cannot delete autocrated taxonomies'); + throw new \Exception('cannot delete autocreated taxonomies'); } $flowQuery = new FlowQuery([$taxonomy]); @@ -518,5 +512,56 @@ public function deleteTaxonomyAction(NodeInterface $taxonomy) $this->redirect('vocabulary', null, null, ['vocabulary' => $vocabulary]); } + /** + * Move taxonomy up + * + * @param NodeInterface $taxonomy + * @return void + */ + public function moveUpTaxonomyAction(NodeInterface $taxonomy) + { + $this->persistenceManager->allowObject($taxonomy); + + $flowQuery = new FlowQuery([$taxonomy]); + $nextSiblingNode = $flowQuery->prev()->get(0); + $taxonomy->moveBefore($nextSiblingNode); + $this->persistenceManager->persistAll(); + + $this->addFlashMessage( + sprintf('Moved up taxonomy %s', $taxonomy->getPath()) + ); + + $vocabulary = $flowQuery + ->closest('[instanceof ' . $this->taxonomyService->getVocabularyNodeType() . ']') + ->get(0); + + $this->redirect('vocabulary', null, null, ['vocabulary' => $vocabulary]); + } + + /** + * Move taxonomy down + * + * @param NodeInterface $taxonomy + * @return void + */ + public function moveDownTaxonomyAction(NodeInterface $taxonomy) + { + $this->persistenceManager->allowObject($taxonomy); + + $flowQuery = new FlowQuery([$taxonomy]); + $nextSiblingNode = $flowQuery->next()->get(0); + $taxonomy->moveAfter($nextSiblingNode); + $this->persistenceManager->persistAll(); + + $this->addFlashMessage( + sprintf('Moved down taxonomy %s', $taxonomy->getPath()) + ); + + $vocabulary = $flowQuery + ->closest('[instanceof ' . $this->taxonomyService->getVocabularyNodeType() . ']') + ->get(0); + + $this->redirect('vocabulary', null, null, ['vocabulary' => $vocabulary]); + } } diff --git a/Configuration/Policy.yaml b/Configuration/Policy.yaml index ccda8dd..7501093 100644 --- a/Configuration/Policy.yaml +++ b/Configuration/Policy.yaml @@ -5,7 +5,7 @@ privilegeTargets: 'Sitegeist.Taxonomy:Module.ManageVocabularyActions': matcher: 'method(Sitegeist\Taxonomy\Controller\ModuleController->(newVocabulary|createVocabulary|editVocabulary|updateVocabulary|deleteVocabulary)Action())' 'Sitegeist.Taxonomy:Module.ManageTaxonomyActions': - matcher: 'method(Sitegeist\Taxonomy\Controller\ModuleController->(newTaxonomy|createTaxonomy|editTaxonomy|updateTaxonomy|deleteTaxonomy)Action())' + matcher: 'method(Sitegeist\Taxonomy\Controller\ModuleController->(newTaxonomy|createTaxonomy|editTaxonomy|updateTaxonomy|deleteTaxonomy|moveUpTaxonomy|moveDownTaxonomy)Action())' 'Sitegeist.Taxonomy:SecondaryInspector.Tree': matcher: 'method(Sitegeist\Taxonomy\Controller\SecondaryInspectorController->treeAction())' diff --git a/Resources/Private/Fusion/Backend/Views/Taxonomy.List.fusion b/Resources/Private/Fusion/Backend/Views/Taxonomy.List.fusion index 30de808..1eff827 100644 --- a/Resources/Private/Fusion/Backend/Views/Taxonomy.List.fusion +++ b/Resources/Private/Fusion/Backend/Views/Taxonomy.List.fusion @@ -42,7 +42,7 @@ prototype(Sitegeist.Taxonomy:Views.Module.Taxonomy.List) < prototype(Neos.Fusion - + @@ -72,6 +72,8 @@ prototype(Sitegeist.Taxonomy:Views.Module.Taxonomy.List) < prototype(Neos.Fusion prototype(Sitegeist.Taxonomy:Views.Module.Taxonomy.List.Item) < prototype(Neos.Fusion:Component) { taxon = null + isFirst = false + isLast = false renderer = afx` @@ -94,6 +96,26 @@ prototype(Sitegeist.Taxonomy:Views.Module.Taxonomy.List.Item) < prototype(Neos.F + + + + + + + + - + `