diff --git a/Classes/Configuration/UseGroupsConfiguration.php b/Classes/Configuration/UseGroupsConfiguration.php index 756a92ab9..c083dd166 100644 --- a/Classes/Configuration/UseGroupsConfiguration.php +++ b/Classes/Configuration/UseGroupsConfiguration.php @@ -56,7 +56,8 @@ private function __construct() 'useGroupsDownload', 'useGroupsFulltext', 'useGroupsAudio', - 'useGroupsScore' + 'useGroupsScore', + 'useGroupsModel' ]; foreach ($configKeys as $key) { @@ -130,6 +131,18 @@ public function getImage(): array return $this->getByType('Image'); } + /** + * Get the configuration for 'Model' use groups type. + * + * @access public + * + * @return array + */ + public function getModel(): array + { + return $this->getByType('Model'); + } + /** * Get the configuration for 'Score' use groups type. * diff --git a/Classes/Controller/ToolboxController.php b/Classes/Controller/ToolboxController.php index e36681358..8ac8fa52d 100644 --- a/Classes/Controller/ToolboxController.php +++ b/Classes/Controller/ToolboxController.php @@ -13,9 +13,14 @@ use Kitodo\Dlf\Common\AbstractDocument; use Kitodo\Dlf\Common\Helper; +use Kitodo\Dlf\Middleware\Embedded3dViewer; use Psr\Http\Message\ResponseInterface; +use TYPO3\CMS\Core\Configuration\Loader\YamlFileLoader; +use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException; +use TYPO3\CMS\Core\Resource\StorageRepository; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\MathUtility; +use TYPO3\CMS\Core\Utility\PathUtility; /** * Controller class for plugin 'Toolbox'. @@ -113,6 +118,10 @@ private function renderTools(): void case 'scoretool': $this->renderToolByName('renderScoreTool'); break; + case 'tx_dlf_viewerselectiontool': + case 'viewerselectiontool': + $this->renderToolByName('renderViewerSelectionTool'); + break; default: $this->logger->warning('Incorrect tool configuration: "' . $this->settings['tools'] . '". Tool "' . $tool . '" does not exist.'); } @@ -135,6 +144,30 @@ private function renderToolByName(string $tool): void $this->view->assign($tool, true); } + /** + * Get the URL of the model. + * + * Gets the URL of the model by parameter or from the configured file group of the document. + * + * @access private + * + * @return string + */ + private function getModelUrl(): string + { + $modelUrl = ''; + if (!empty($this->requestData['model'])) { + $modelUrl = $this->requestData['model']; + } elseif (!($this->isDocMissingOrEmpty() || empty($this->useGroupsConfiguration->getModel()))) { + $this->setPage(); + if (isset($this->requestData['page'])) { + $file = $this->getFile($this->requestData['page'], $this->useGroupsConfiguration->getModel()); + $modelUrl = $file['url'] ?? ''; + } + } + return $modelUrl; + } + /** * Get the score file. * @@ -370,19 +403,55 @@ private function renderImageManipulationTool(): void */ private function renderModelDownloadTool(): void { - // TODO: missing fileGrpsModelDownload, should be added to ext config as useGroupsModelDownload - if ( - $this->isDocMissingOrEmpty() - || empty($this->settings['fileGrpsModelDownload']) - ) { - // Quit without doing anything if required variables are not set. + $modelUrl = $this->getModelUrl(); + if ($modelUrl === '') { + $this->logger->debug("Model URL could not be determined"); return; } + $this->view->assign('modelUrl', $modelUrl); + } - $this->setPage(); - if (isset($this->requestData['page'])) { - $this->view->assign('modelDownload', $this->getFile($this->requestData['page'], GeneralUtility::trimExplode(',', $this->settings['fileGrpsModelDownload']))); + /** + * Renders the viewer selection tool + * Renders the viewer selection tool (used in template) + * @SuppressWarnings(PHPMD.UnusedPrivateMethod) + * + * @access private + * + * @return void + * @throws InsufficientFolderAccessPermissionsException + */ + private function renderViewerSelectionTool(): void + { + $model = $this->getModelUrl(); + if (!$model) { + $this->logger->debug("Model URL could not be determined"); + return; + } + + $pathInfo = PathUtility::pathinfo($model); + $modelFormat = strtolower($pathInfo["extension"]); + $viewers = []; + /** @var StorageRepository $storageRepository */ + $storageRepository = GeneralUtility::makeInstance(StorageRepository::class); + $defaultStorage = $storageRepository->getDefaultStorage(); + if ($defaultStorage->hasFolder(Embedded3dViewer::VIEWER_FOLDER)) { + $viewerFolders = $defaultStorage->getFoldersInFolder($defaultStorage->getFolder(Embedded3dViewer::VIEWER_FOLDER)); + if (count($viewerFolders) > 0) { + /** @var YamlFileLoader $yamlFileLoader */ + $yamlFileLoader = GeneralUtility::makeInstance(YamlFileLoader::class); + foreach ($viewerFolders as $viewerFolder) { + if ($viewerFolder->hasFile(Embedded3dViewer::VIEWER_CONFIG_YML)) { + $fileIdentifier = $viewerFolder->getFile(Embedded3dViewer::VIEWER_CONFIG_YML)->getIdentifier(); + $viewerConfig = $yamlFileLoader->load($defaultStorage->getName() . $fileIdentifier)["viewer"]; + if (!empty($viewerConfig["supportedModelFormats"]) && in_array($modelFormat, array_map('strtolower', $viewerConfig["supportedModelFormats"]))) { + $viewers[] = (object) ['id' => $viewerFolder->getName(), 'name' => $viewerConfig["name"] ?? $viewerFolder->getName()]; + } + } + } + $this->view->assign('viewers', $viewers); + } } } diff --git a/Documentation/Developers/Embedded3DViewer.rst b/Documentation/Developers/Embedded3DViewer.rst index fbcfe643b..9cc93f797 100644 --- a/Documentation/Developers/Embedded3DViewer.rst +++ b/Documentation/Developers/Embedded3DViewer.rst @@ -10,6 +10,8 @@ On this page, you will find all the information needed to configure and embed an :local: :depth: 2 +.. _Embedded 3D Viewer Setup: + Setup ======= @@ -27,11 +29,13 @@ Configuration By default, the viewers from the folder ``dlf_3d_viewers`` are all active and can be accessed and tested via URL. -For this, only the parameter ``tx_dlf[viewer]`` with the name of the viewer and the encoded URL to the model via the parameter ``tx_dlf[model]`` need to be passed to the URL under which the plugin ``plugin.tx_dlf_embedded3dViewer`` is rendered. +For this, only the parameter ``tx_dlf[viewer]`` with the encoded subfolder name of the viewer needs to be passed to the URL where the plugin ``plugin.tx_dlf_embedded3dViewer`` is rendered. .. note:: For example in the DFG Viewer, this is the page whose ID is set via the constant ``config.kitodoPageView``. +To render the model, the encoded URL to the METS document should be set using the parameter ``tx_dlf[id]``. Alternatively, it is possible to define the model directly with an encoded URL via the parameter ``tx_dlf[model]``. + Automatic selection of the viewer ------- diff --git a/Documentation/Plugins/Index.rst b/Documentation/Plugins/Index.rst index 1d24f4495..c9385583e 100644 --- a/Documentation/Plugins/Index.rst +++ b/Documentation/Plugins/Index.rst @@ -1018,6 +1018,21 @@ The fulltext is fetched and rendered by JavaScript into the `