Handle export for filebase files and file verions from version 6.1+
authorCyperghost <olaf_schmitz_1@t-online.de>
Tue, 22 Oct 2024 11:19:38 +0000 (13:19 +0200)
committerCyperghost <olaf_schmitz_1@t-online.de>
Tue, 22 Oct 2024 11:19:38 +0000 (13:19 +0200)
files/lib/system/exporter/WBB4xExporter.class.php

index d4284c4c5b71c59d148c233a5d33d8ad6be94408..34edb411e1a922a60953be231e4d5b4795dbcab9 100644 (file)
@@ -3125,7 +3125,11 @@ final class WBB4xExporter extends AbstractExporter
      */
     public function exportFilebaseFiles($offset, $limit)
     {
-        if (\version_compare($this->getPackageVersion('com.woltlab.filebase'), '5.3.0 Alpha 1', '>=')) {
+        if (\version_compare($this->getPackageVersion('com.woltlab.filebase'), '6.1.0 Alpha 1', '>=')) {
+            $this->exportFilebaseFiles61($offset, $limit);
+
+            return;
+        } elseif (\version_compare($this->getPackageVersion('com.woltlab.filebase'), '5.3.0 Alpha 1', '>=')) {
             $this->exportFilebaseFiles53($offset, $limit);
 
             return;
@@ -3198,7 +3202,7 @@ final class WBB4xExporter extends AbstractExporter
     }
 
     /**
-     * Exports filebase files from 5.3+.
+     * Exports filebase files from 5.3 to 6.0.
      *
      * @param   integer     $offset
      * @param   integer     $limit
@@ -3262,8 +3266,81 @@ final class WBB4xExporter extends AbstractExporter
         }
     }
 
-    protected function exportFilebaseFilesHelper(array $row, array $contents = [], array $categories = [])
+    /**
+     * Exports filebase files from 6.1+.
+     */
+    public function exportFilebaseFiles61(int $offset, int $limit): void
     {
+        // get file ids
+        $fileIDs = [];
+        $sql = "SELECT      fileID
+                FROM        filebase" . $this->dbNo . "_file
+                WHERE       fileID BETWEEN ? AND ?
+                ORDER BY    fileID";
+        $statement = $this->database->prepareStatement($sql);
+        $statement->execute([$offset + 1, $offset + $limit]);
+        while ($row = $statement->fetchArray()) {
+            $fileIDs[] = $row['fileID'];
+        }
+        if (empty($fileIDs)) {
+            return;
+        }
+        $conditionBuilder = new PreparedStatementConditionBuilder();
+        $conditionBuilder->add('fileID IN (?)', [$fileIDs]);
+
+        $sql = "SELECT fileIconID
+                FROM   filebase" . $this->dbNo . "_file
+                " . $conditionBuilder;
+        $statement = $this->database->prepareStatement($sql);
+        $statement->execute($conditionBuilder->getParameters());
+        $coreFiles = $this->getFileLocations($statement->fetchAll(\PDO::FETCH_COLUMN));
+
+        // get file contents
+        $fileContents = $fileContentIDs = [];
+        $sql = "SELECT      file_content.*, language.languageCode
+                FROM        filebase" . $this->dbNo . "_file_content file_content
+                LEFT JOIN   wcf" . $this->dbNo . "_language language
+                ON          language.languageID = file_content.languageID
+                " . $conditionBuilder;
+        $statement = $this->database->prepareStatement($sql);
+        $statement->execute($conditionBuilder->getParameters());
+        while ($row = $statement->fetchArray()) {
+            $fileContents[$row['fileID']][$row['languageCode'] ?: ''] = $row;
+            $fileContentIDs[] = $row['fileContentID'];
+        }
+
+        // get tags
+        $tags = $this->getTags('com.woltlab.filebase.file', $fileContentIDs);
+
+        // get files
+        $sql = "SELECT  *
+                FROM    filebase" . $this->dbNo . "_file
+                " . $conditionBuilder;
+        $statement = $this->database->prepareStatement($sql);
+        $statement->execute($conditionBuilder->getParameters());
+        while ($row = $statement->fetchArray()) {
+            $contents = [];
+            if (isset($fileContents[$row['fileID']])) {
+                foreach ($fileContents[$row['fileID']] as $languageCode => $fileContent) {
+                    $contents[$languageCode ?: ''] = [
+                        'subject' => $fileContent['subject'],
+                        'teaser' => $fileContent['teaser'],
+                        'message' => $fileContent['message'],
+                        'tags' => $tags[$fileContent['fileContentID']] ?? [],
+                    ];
+                }
+            }
+
+            $this->exportFilebaseFilesHelper($row, $contents, [$row['categoryID']], $coreFiles);
+        }
+    }
+
+    protected function exportFilebaseFilesHelper(
+        array $row,
+        array $contents = [],
+        array $categories = [],
+        array $coreFiles = []
+    ) {
         $additionalData = [
             'contents' => $contents,
         ];
@@ -3290,7 +3367,13 @@ final class WBB4xExporter extends AbstractExporter
         ];
 
         // file icon
-        if (!empty($row['iconHash'])) {
+        if (!empty($row['fileIconID']) && isset($coreFiles[$row['fileIconID']])) {
+            // since 6.1.0
+            ['location' => $location, 'filename' => $filename] = $coreFiles[$row['fileIconID']];
+            $additionalData['iconLocation'] = $location;
+            $additionalData['iconFilename'] = $filename;
+        } elseif (!empty($row['iconHash'])) {
+            // before 6.1.0
             $data['iconHash'] = $row['iconHash'];
             $data['iconExtension'] = $row['iconExtension'];
             $additionalData['iconLocation'] = $this->getFilebaseDir() . 'images/file/' . \substr($row['iconHash'], 0, 2) . '/' . $row['fileID'] . '.' . $row['iconExtension'];
@@ -3332,7 +3415,11 @@ final class WBB4xExporter extends AbstractExporter
      */
     public function exportFilebaseFileVersions($offset, $limit)
     {
-        if (\version_compare($this->getPackageVersion('com.woltlab.filebase'), '5.3.0 Alpha 1', '>=')) {
+        if (\version_compare($this->getPackageVersion('com.woltlab.filebase'), '6.1.0 Alpha 1', '>=')) {
+            $this->exportFilebaseFileVersions61($offset, $limit);
+
+            return;
+        } elseif (\version_compare($this->getPackageVersion('com.woltlab.filebase'), '5.3.0 Alpha 1', '>=')) {
             $this->exportFilebaseFileVersions53($offset, $limit);
 
             return;
@@ -3358,7 +3445,7 @@ final class WBB4xExporter extends AbstractExporter
     }
 
     /**
-     * Exports filebase file versions from 5.3+.
+     * Exports filebase file versions from 5.3 up to 6.0.
      *
      * @param   integer     $offset
      * @param   integer     $limit
@@ -3415,7 +3502,72 @@ final class WBB4xExporter extends AbstractExporter
         }
     }
 
-    protected function exportFilebaseFileVersionsHelper(array $row, array $contents = [])
+    /**
+     * Exports filebase file versions from 6.1+.
+     *
+     * @param int $offset
+     * @param int $limit
+     */
+    public function exportFilebaseFileVersions61($offset, $limit)
+    {
+        // get version ids
+        $versionIDs = [];
+        $sql = "SELECT      versionID
+                FROM        filebase" . $this->dbNo . "_file_version
+                WHERE       versionID BETWEEN ? AND ?
+                ORDER BY    versionID";
+        $statement = $this->database->prepareStatement($sql);
+        $statement->execute([$offset + 1, $offset + $limit]);
+        while ($row = $statement->fetchArray()) {
+            $versionIDs[] = $row['versionID'];
+        }
+        if (empty($versionIDs)) {
+            return;
+        }
+        $conditionBuilder = new PreparedStatementConditionBuilder();
+        $conditionBuilder->add('versionID IN (?)', [$versionIDs]);
+
+        $sql = "SELECT coreFileID
+                FROM   filebase" . $this->dbNo . "_file_version
+                " . $conditionBuilder;
+        $statement = $this->database->prepareStatement($sql);
+        $statement->execute($conditionBuilder->getParameters());
+        $coreFiles = $this->getFileLocations($statement->fetchAll(\PDO::FETCH_COLUMN));
+
+        // get version contents
+        $versionContents = [];
+        $sql = "SELECT      version_content.*, language.languageCode
+                FROM        filebase" . $this->dbNo . "_file_version_content version_content
+                LEFT JOIN   wcf" . $this->dbNo . "_language language
+                ON          language.languageID = version_content.languageID
+                " . $conditionBuilder;
+        $statement = $this->database->prepareStatement($sql);
+        $statement->execute($conditionBuilder->getParameters());
+        while ($row = $statement->fetchArray()) {
+            $versionContents[$row['versionID']][$row['languageCode'] ?: ''] = $row;
+        }
+
+        // get versions
+        $sql = "SELECT  *
+                FROM    filebase" . $this->dbNo . "_file_version
+                " . $conditionBuilder;
+        $statement = $this->database->prepareStatement($sql);
+        $statement->execute($conditionBuilder->getParameters());
+        while ($row = $statement->fetchArray()) {
+            $contents = [];
+            if (isset($versionContents[$row['versionID']])) {
+                foreach ($versionContents[$row['versionID']] as $languageCode => $versionContent) {
+                    $contents[$languageCode ?: ''] = [
+                        'description' => $versionContent['description'],
+                    ];
+                }
+            }
+
+            $this->exportFilebaseFileVersionsHelper($row, $contents, $coreFiles);
+        }
+    }
+
+    protected function exportFilebaseFileVersionsHelper(array $row, array $contents = [], array $coreFiles = [])
     {
         $data = [
             'fileID' => $row['fileID'],
@@ -3438,7 +3590,13 @@ final class WBB4xExporter extends AbstractExporter
             'contents' => $contents,
             'fileLocation' => '',
         ];
-        if (empty($row['downloadURL'])) {
+        if (!empty($row['coreFileID']) && isset($coreFiles[$row['coreFileID']])) {
+            // since 6.1.0
+            ['location' => $location, 'filename' => $filename] = $coreFiles[$row['coreFileID']];
+            $additionalData['fileLocation'] = $location;
+            $data['filename'] = $filename;
+        } elseif (empty($row['downloadURL'])) {
+            // before 6.1.0
             $additionalData['fileLocation'] = $this->getFilebaseDir() . 'files/' . \substr($row['fileHash'], 0, 2) . '/' . $row['versionID'] . '-' . $row['fileHash'];
         }
 
@@ -4531,7 +4689,7 @@ final class WBB4xExporter extends AbstractExporter
      *
      * @param int[] $fileIDs
      *
-     * @return array{int, string}[]
+     * @return array{int, array{location: string, filename: string}}[]
      */
     private function getFileLocations(array $fileIDs): array
     {
@@ -4543,7 +4701,7 @@ final class WBB4xExporter extends AbstractExporter
         $conditionBuilder->add('fileID IN (?)', [$fileIDs]);
 
         $sql = "SELECT  fileID, fileHash, filename, fileExtension, mimeType
-                FROM    wcf1_file
+                FROM    wcf" . $this->dbNo . "_file
                 " . $conditionBuilder;
 
         $statement = $this->database->prepareStatement($sql);
@@ -4559,16 +4717,19 @@ final class WBB4xExporter extends AbstractExporter
             $folderA = \substr($row['fileHash'], 0, 2);
             $folderB = \substr($row['fileHash'], 2, 2);
 
-            $files[$row['fileID']] = \sprintf(
-                '%s_data/%s/files/%s/%s/%d-%s.%s',
-                $this->fileSystemPath,
-                $isStaticFile ? 'public' : 'private',
-                $folderA,
-                $folderB,
-                $row["fileID"],
-                $row["fileHash"],
-                $row["fileExtension"],
-            );
+            $files[$row['fileID']] = [
+                'location' => \sprintf(
+                    '%s_data/%s/files/%s/%s/%d-%s.%s',
+                    $this->fileSystemPath,
+                    $isStaticFile ? 'public' : 'private',
+                    $folderA,
+                    $folderB,
+                    $row["fileID"],
+                    $row["fileHash"],
+                    $row["fileExtension"],
+                ),
+                'filename' => $row['filename'],
+            ];
         }
 
         return $files;