From 70567e6602438e3baf9fef5c8b29813e61222757 Mon Sep 17 00:00:00 2001 From: Michael Kubina Date: Sat, 1 Feb 2025 01:24:01 +0100 Subject: [PATCH] [FEATURE] Seamless document browsing (#1381) Co-authored-by: Michael Kubina Co-authored-by: Sebastian Meyer --- Classes/Controller/NavigationController.php | 8 + .../Domain/Repository/DocumentRepository.php | 168 ++++++++++++++++++ Configuration/FlexForms/Navigation.xml | 14 +- Resources/Private/Language/de.locallang.xlf | 8 + .../Private/Language/de.locallang_be.xlf | 8 + Resources/Private/Language/locallang.xlf | 6 + Resources/Private/Language/locallang_be.xlf | 6 + .../Private/Templates/Navigation/Main.html | 34 ++++ 8 files changed, 249 insertions(+), 3 deletions(-) diff --git a/Classes/Controller/NavigationController.php b/Classes/Controller/NavigationController.php index 9d288eadec..558121dea5 100644 --- a/Classes/Controller/NavigationController.php +++ b/Classes/Controller/NavigationController.php @@ -81,6 +81,14 @@ public function mainAction(): ResponseInterface $this->viewData['requestData'] = $this->requestData; } + // get the closest previous sibling or leaf node + $prevDocumentUid = $this->documentRepository->getPreviousDocumentUid($this->document->getUid()); + $this->view->assign('documentBack', $prevDocumentUid); + + // get the closest next sibling or leaf node + $nextDocumentUid = $this->documentRepository->getNextDocumentUid($this->document->getUid()); + $this->view->assign('documentForward', $nextDocumentUid); + // Steps for X pages backward / forward. Double page view uses double steps. $pageSteps = $this->settings['pageStep'] * ($this->requestData['double'] + 1); diff --git a/Classes/Domain/Repository/DocumentRepository.php b/Classes/Domain/Repository/DocumentRepository.php index 6e10b01fa3..3d6cf173d3 100644 --- a/Classes/Domain/Repository/DocumentRepository.php +++ b/Classes/Domain/Repository/DocumentRepository.php @@ -645,4 +645,172 @@ private function findSolr($collections, $settings, $searchParams, $listedMetadat $search->prepare(); return $search; } + + /** + * Find the uid of the previous document relative to the current document uid. + * Otherwise backtrack the closest previous leaf node. + * + * @access public + * + * @param int $uid + * + * @return int|null + */ + public function getPreviousDocumentUid($uid) + { + $currentDocument = $this->findOneByUid($uid); + if ($currentDocument) { + $currentVolume = ''; + $parentId = $currentDocument->getPartof(); + + if ($parentId) { + + $currentVolume = (string) $currentDocument->getVolumeSorting(); + + $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class); + $queryBuilder = $connectionPool->getQueryBuilderForTable('tx_dlf_documents'); + + // Grab previous volume + $prevDocument = $queryBuilder + ->select( + 'tx_dlf_documents.uid AS uid' + ) + ->from('tx_dlf_documents') + ->where( + $queryBuilder->expr()->eq('tx_dlf_documents.partof', (int) $parentId), + 'tx_dlf_documents.volume_sorting < \'' . $currentVolume . '\'' + ) + ->add('orderBy', 'volume_sorting desc') + ->addOrderBy('tx_dlf_documents.volume_sorting') + ->execute() + ->fetch(); + + if (!empty($prevDocument)) { + return $prevDocument['uid']; + } + + return $this->getLastChild($this->getPreviousDocumentUid($parentId)); + } + } + + return null; + } + + /** + * Find the uid of the next document relative to the current document uid. + * Otherwise backtrack the closest next leaf node. + * + * @access public + * + * @param int $uid + * + * @return int|null + */ + public function getNextDocumentUid($uid) + { + $currentDocument = $this->findOneByUid($uid); + if ($currentDocument) { + $currentVolume = ''; + $parentId = $currentDocument->getPartof(); + + if ($parentId) { + + $currentVolume = (string) $currentDocument->getVolumeSorting(); + + $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class); + $queryBuilder = $connectionPool->getQueryBuilderForTable('tx_dlf_documents'); + + // Grab next volume + $nextDocument = $queryBuilder + ->select( + 'tx_dlf_documents.uid AS uid' + ) + ->from('tx_dlf_documents') + ->where( + $queryBuilder->expr()->eq('tx_dlf_documents.partof', (int) $parentId), + 'tx_dlf_documents.volume_sorting > \'' . $currentVolume . '\'' + ) + ->add('orderBy', 'volume_sorting asc') + ->addOrderBy('tx_dlf_documents.volume_sorting') + ->execute() + ->fetch(); + + if (!empty($nextDocument)) { + return $nextDocument['uid']; + } + + return $this->getFirstChild($this->getNextDocumentUid($parentId)); + } + } + + return null; + } + + /** + * Find the uid of the first leaf node + * + * @access public + * + * @param int $uid + * + * @return int + */ + public function getFirstChild($uid) + { + $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class); + $queryBuilder = $connectionPool->getQueryBuilderForTable('tx_dlf_documents'); + + $child = $queryBuilder + ->select( + 'tx_dlf_documents.uid AS uid' + ) + ->from('tx_dlf_documents') + ->where( + $queryBuilder->expr()->eq('tx_dlf_documents.partof', (int) $uid) + ) + ->add('orderBy', 'volume_sorting asc') + ->addOrderBy('tx_dlf_documents.volume_sorting') + ->execute() + ->fetch(); + + if (empty($child['uid'])) { + return $uid; + } + + return $this->getFirstChild($child['uid']); + } + + /** + * Find the uid of the last leaf node + * + * @access public + * + * @param int $uid + * + * @return int + */ + public function getLastChild($uid) + { + $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class); + $queryBuilder = $connectionPool->getQueryBuilderForTable('tx_dlf_documents'); + + $child = $queryBuilder + ->select( + 'tx_dlf_documents.uid AS uid' + ) + ->from('tx_dlf_documents') + ->where( + $queryBuilder->expr()->eq('tx_dlf_documents.partof', (int) $uid) + ) + ->add('orderBy', 'volume_sorting desc') + ->addOrderBy('tx_dlf_documents.volume_sorting') + ->execute() + ->fetch(); + + if (empty($child['uid'])) { + return $uid; + } + + return $this->getFirstChild($child['uid']); + } } diff --git a/Configuration/FlexForms/Navigation.xml b/Configuration/FlexForms/Navigation.xml index 3f98c73c02..72142da70b 100644 --- a/Configuration/FlexForms/Navigation.xml +++ b/Configuration/FlexForms/Navigation.xml @@ -72,16 +72,24 @@ LLL:EXT:dlf/Resources/Private/Language/locallang_be.xlf:plugins.navigation.flexform.features.rotation rotation - + LLL:EXT:dlf/Resources/Private/Language/locallang_be.xlf:plugins.navigation.flexform.features.measureForward measureForward - + LLL:EXT:dlf/Resources/Private/Language/locallang_be.xlf:plugins.navigation.flexform.features.measureBack measureBack + + LLL:EXT:dlf/Resources/Private/Language/locallang_be.xlf:plugins.navigation.flexform.features.documentBack + documentBack + + + LLL:EXT:dlf/Resources/Private/Language/locallang_be.xlf:plugins.navigation.flexform.features.documentForward + documentForward + - doublePage,pageFirst,pageBack,pageStepBack,pageSelect,pageForward,pageStepForward,pageLast,listView,zoom,rotation,measureForward,measureBack + doublePage,pageFirst,pageBack,pageStepBack,pageSelect,pageForward,pageStepForward,pageLast,listView,zoom,rotation,measureForward,measureBack,documentBack,documentForward 1 diff --git a/Resources/Private/Language/de.locallang.xlf b/Resources/Private/Language/de.locallang.xlf index d1b7392a92..5dba64ef99 100644 --- a/Resources/Private/Language/de.locallang.xlf +++ b/Resources/Private/Language/de.locallang.xlf @@ -293,6 +293,14 @@ + + + + + + + + diff --git a/Resources/Private/Language/de.locallang_be.xlf b/Resources/Private/Language/de.locallang_be.xlf index ba91b5a6d7..3d375d9fe9 100644 --- a/Resources/Private/Language/de.locallang_be.xlf +++ b/Resources/Private/Language/de.locallang_be.xlf @@ -309,6 +309,14 @@ + + + + + + + + diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf index d1901621e1..c355c9681e 100644 --- a/Resources/Private/Language/locallang.xlf +++ b/Resources/Private/Language/locallang.xlf @@ -185,6 +185,12 @@ + + + + + + diff --git a/Resources/Private/Language/locallang_be.xlf b/Resources/Private/Language/locallang_be.xlf index 8c90a17cf3..572ecfd891 100644 --- a/Resources/Private/Language/locallang_be.xlf +++ b/Resources/Private/Language/locallang_be.xlf @@ -212,6 +212,12 @@ + + + + + + diff --git a/Resources/Private/Templates/Navigation/Main.html b/Resources/Private/Templates/Navigation/Main.html index 109c95812c..f6a28f6301 100644 --- a/Resources/Private/Templates/Navigation/Main.html +++ b/Resources/Private/Templates/Navigation/Main.html @@ -302,4 +302,38 @@ + +
+ + + + + + + + + + + + +
+
+ + +
+ + + + + + + + + + + + +
+
+