From d9c0cc4170fe4ae2f8d059a563f62e40a98cb3f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Chauveau?= <jerome.chauveau@unicaen.fr>
Date: Mon, 22 Jan 2024 15:50:22 +0100
Subject: [PATCH] manage single zipped file. #14

---
 XML2HTMLPlugin.php | 86 +++++++++++++++++++++++++++++-----------------
 1 file changed, 55 insertions(+), 31 deletions(-)

diff --git a/XML2HTMLPlugin.php b/XML2HTMLPlugin.php
index cc0c93c..e13633e 100644
--- a/XML2HTMLPlugin.php
+++ b/XML2HTMLPlugin.php
@@ -38,7 +38,7 @@ class XML2HTMLPlugin extends GenericPlugin
         //handle only on zip galleys - supposed to be an xml archive (source + images)
         $zipMode = $galley && $galley->getFileType() === 'application/zip';
         if ($zipMode) {
-            $this->archiveView($galley->getFile()->getData('path'), $submission->getId(), $galley->getId(),'article');
+            $this->archiveView($galley->getFile()->getData('path'), $submission->getId(), $galley->getId(), 'article');
             return true;
         } else return false;
     }
@@ -51,7 +51,7 @@ class XML2HTMLPlugin extends GenericPlugin
         $submissionFile =& $params[3];
         $zipMode = $submissionFile->getData('mimetype') === "application/zip";
         if ($zipMode) {
-            $this->archiveView($submissionFile->getData('path'), $submission->getId(), $galley->getId(),'catalog');
+            $this->archiveView($submissionFile->getData('path'), $submission->getId(), $galley->getId(), 'catalog');
             return true;
         } else
             return false;
@@ -63,7 +63,7 @@ class XML2HTMLPlugin extends GenericPlugin
         $htmlFile = XML2HTMLPlugin::getHTMLPathFromZipPath($filePath);
         $html = file_get_contents($htmlFile);
         //make transfo only if html does not exist
-        if(!$html) {
+        if (!$html) {
             //get sources format from settings
             $context = Application::get()
                 ->getRequest()
@@ -74,7 +74,7 @@ class XML2HTMLPlugin extends GenericPlugin
                 'format'
             );
 
-            if($format == NULL || $format == '')
+            if ($format == NULL || $format == '')
                 $format = 'JATS';//default value is JATS
 
             $xmlFilePath = XML2HTMLPlugin::unzipXMLArchive($filePath);
@@ -88,7 +88,7 @@ class XML2HTMLPlugin extends GenericPlugin
             file_put_contents($htmlFile, $html, LOCK_EX);
         }
         $templateMgr = TemplateManager::getManager($this->getRequest());
-        $templateMgr->assign('assetsPath',$this->getPluginAssetsPath($this->getRequest()));
+        $templateMgr->assign('assetsPath', $this->getPluginAssetsPath($this->getRequest()));
         $templateMgr->assign('text', $html);
         $templateMgr->display($this->getTemplateResource('HTMLGalleyView.tpl'));
     }
@@ -99,14 +99,15 @@ class XML2HTMLPlugin extends GenericPlugin
      * @param $zipPath
      * @return string
      */
-    private static function getHTMLPathFromZipPath($zipPath){
+    private static function getHTMLPathFromZipPath($zipPath)
+    {
         $fileMgr = new PrivateFileManager();
         $filesDir = $fileMgr->getBasePath() . DIRECTORY_SEPARATOR;
         $fullZipPath = $filesDir . $zipPath;
         $fullPrefixPath = str_replace('.zip', '', $fullZipPath);
         $pathInfo = pathinfo($fullZipPath);
         $zipName = $pathInfo['filename'];
-        return str_replace($pathInfo['filename'], $zipName. DIRECTORY_SEPARATOR .  $zipName . '.html', $fullPrefixPath);
+        return str_replace($pathInfo['filename'], $zipName . DIRECTORY_SEPARATOR . $zipName . '.html', $fullPrefixPath);
     }
 
 
@@ -137,11 +138,12 @@ class XML2HTMLPlugin extends GenericPlugin
      * @param $verb
      * @return mixed
      */
-    public function getActions($request, $verb) {
+    public function getActions($request, $verb)
+    {
         $router = $request->getRouter();
         import('lib.pkp.classes.linkAction.request.AjaxModal');
         return array_merge(
-            $this->getEnabled()?array(
+            $this->getEnabled() ? array(
                 new LinkAction(
                     'settings',
                     new AjaxModal(
@@ -151,7 +153,7 @@ class XML2HTMLPlugin extends GenericPlugin
                     __('manager.plugins.settings'),
                     null
                 ),
-            ):array(),
+            ) : array(),
             parent::getActions($request, $verb)
         );
     }
@@ -191,7 +193,8 @@ class XML2HTMLPlugin extends GenericPlugin
     }
 
 
-    function getPluginAssetsPath($request) {
+    function getPluginAssetsPath($request)
+    {
         return $request->getBaseUrl() . '/' . $this->getPluginPath() . '/resources/';
     }
 
@@ -222,6 +225,11 @@ class XML2HTMLPlugin extends GenericPlugin
     }
 
 
+    /**
+     * @param string $path
+     * @return string|void|null
+     * @throws Exception
+     */
     static function unzipXMLArchive(string $path)
     {
         $fileManager = new FileManager();
@@ -238,29 +246,45 @@ class XML2HTMLPlugin extends GenericPlugin
             }
             if ($zip->open($zipPath) === TRUE) {
 
-                $archiveFolderName = NULL;
-                if ($zip->numFiles > 0) {//gets zip top folder name
-                    $archiveFolderName = $zip->getNameIndex(0);
-                } else {
-                    throw new \Exception("Bad zip Submission file.");
-                }
-                $zip->extractTo($zipPathParts['dirname']);
-                rename(
-                    $zipPathParts['dirname'] . DIRECTORY_SEPARATOR . $archiveFolderName,
-                    $zipPathParts['dirname'] . DIRECTORY_SEPARATOR . $zipPathParts['filename']);
-                $zip->close();
-
-                $files = scandir($zipPathParts['dirname'] . DIRECTORY_SEPARATOR . $zipPathParts['filename']);
-                foreach ($files as $file) {
-                    $extension = $fileManager->parseFileExtension($file);
-                    if ($extension == 'xml') {
+                $nbFiles = $zip->numFiles;
+                if ($nbFiles > 0) {
+                    //a zipped file
+                    if ($nbFiles == 1 && str_ends_with($zip->getNameIndex(0), '.xml')) {
                         $basePath = $zipPathParts['dirname'] . DIRECTORY_SEPARATOR . $zipPathParts['filename'] . '/';
+                        $zip->extractTo($basePath);
                         rename(
-                            $basePath . $file,
+                            $basePath . $zip->getNameIndex(0),
                             $basePath . $zipPathParts['filename'] . '.xml'
                         );
-                        return $filesDir . $fileInfo['dirname'] . DIRECTORY_SEPARATOR . $fileInfo['filename'] . DIRECTORY_SEPARATOR . $fileInfo['filename'] . '.xml';
+                        return $basePath . $zipPathParts['filename'] . '.xml';
+                    } //a zipped folder
+                    else if (str_ends_with($zip->getNameIndex(0), '/')) {
+                        $archiveFolderName = $zip->getNameIndex(0); //gets root folder name
+                        $zip->extractTo($zipPathParts['dirname']);
+                        rename(
+                            $zipPathParts['dirname'] . DIRECTORY_SEPARATOR . $archiveFolderName,
+                            $zipPathParts['dirname'] . DIRECTORY_SEPARATOR . $zipPathParts['filename']);
+                        $zip->close();
+
+                        $files = scandir($zipPathParts['dirname'] . DIRECTORY_SEPARATOR . $zipPathParts['filename']);
+                        foreach ($files as $file) {
+                            $extension = $fileManager->parseFileExtension($file);
+                            if ($extension == 'xml') {
+                                $basePath = $zipPathParts['dirname'] . DIRECTORY_SEPARATOR . $zipPathParts['filename'] . '/';
+                                rename(
+                                    $basePath . $file,
+                                    $basePath . $zipPathParts['filename'] . '.xml'
+                                );
+                                return $filesDir . $fileInfo['dirname'] . DIRECTORY_SEPARATOR . $fileInfo['filename'] . DIRECTORY_SEPARATOR . $fileInfo['filename'] . '.xml';
+                            }
+                        }
+
+
+                    } else {
+                        throw new \Exception("Bad zip Submission file.");
                     }
+                } else {
+                    throw new \Exception("Bad zip Submission file.");
                 }
 
             } else {
@@ -280,10 +304,10 @@ class XML2HTMLPlugin extends GenericPlugin
         $page = $args[0];
         $op = $args[1];
 
-        if ($page == 'article' && (/*$op == 'image' || */$op == 'zimage')) {
+        if ($page == 'article' && (/*$op == 'image' || */ $op == 'zimage')) {
             define('HANDLER_CLASS', 'ArticleImageDataHandler');
             import('plugins.generic.xml2html.ArticleImageDataHandler');
-        } else if (($page == 'catalog') && (/*$op == 'image' || */$op == 'zimage')) {
+        } else if (($page == 'catalog') && (/*$op == 'image' || */ $op == 'zimage')) {
             define('HANDLER_CLASS', 'BookImageDataHandler');
             import('plugins.generic.xml2html.BookImageDataHandler');
         }
-- 
GitLab