Ver Fonte

#3068 Files: Bulk downloading fixes. Refactoring.

Alexander há 5 anos atrás
pai
commit
685bbddf04

+ 18 - 8
modules/boonex/files/classes/BxFilesDb.php

@@ -109,19 +109,29 @@ class BxFilesDb extends BxBaseModFilesDb
         ]);
     }
 
-    public function getFolderFilesEx($iFile, $sType = 'folder') {
+    public function getFolderFilesEx($mFile, $sType = 'folder') {
         $CNF = &$this->_oConfig->CNF;
-        return $this->getAll("
 
+        $sQuery = "
             SELECT `{$CNF['TABLE_ENTRIES']}`.`{$CNF['FIELD_ID']}`, `{$CNF['TABLE_ENTRIES']}`.`{$CNF['FIELD_AUTHOR']}`, `{$CNF['TABLE_ENTRIES']}`.`{$CNF['FIELD_TITLE']}`, `{$CNF['TABLE_ENTRIES']}`.`type`, `{$CNF['TABLE_FILES']}`.`path`, `{$CNF['TABLE_FILES']}`.`ext`, `{$CNF['TABLE_FILES']}`.`size` 
             FROM `{$CNF['TABLE_ENTRIES']}` 
             LEFT JOIN `{$CNF['TABLE_FILES']}` ON `{$CNF['TABLE_ENTRIES']}`.`{$CNF['FIELD_FILE_ID']}` = `{$CNF['TABLE_FILES']}`.`{$CNF['FIELD_ID']}`
-            WHERE `{$CNF['TABLE_ENTRIES']}`.`".($sType == 'folder' ? 'parent_folder_id' : $CNF['FIELD_ID'])."` = :file
-            
-            ", [
-                'file' => $iFile,
-            ]
-        );
+        ";
+
+        if ($sType == 'mixed') {
+            if (!is_array($mFile) || empty($mFile)) return false;
+            $aIDs = [];
+            foreach ($mFile as $iFile) $aIDs[] = intval($iFile);
+
+            return $this->getAll($sQuery. "WHERE `{$CNF['TABLE_ENTRIES']}`.`{$CNF['FIELD_ID']}` IN (".implode(',', $aIDs).")");
+        } else {
+            return $this->getAll($sQuery. "
+                WHERE `{$CNF['TABLE_ENTRIES']}`.`".($sType == 'folder' ? 'parent_folder_id' : $CNF['FIELD_ID'])."` = :file                
+                ", [
+                    'file' => $mFile,
+                ]
+            );
+        }
     }
 
     public function getFolderNestingLevel($iFolder) {

+ 27 - 9
modules/boonex/files/classes/BxFilesModule.php

@@ -61,6 +61,12 @@ class BxFilesModule extends BxBaseModTextModule
         if (!empty($sBulk)) {
             $aFilesToDownload = json_decode($sBulk);
         }
+
+        if (!is_array($aFilesToDownload)) {
+            $this->_oTemplate->displayPageNotFound();
+            return;
+        }
+
         $iContentId = reset($aFilesToDownload);
 
         $aData = $this->_oDb->getContentInfoById((int)$iContentId);
@@ -76,6 +82,11 @@ class BxFilesModule extends BxBaseModTextModule
 
         if ($aData['type'] == 'folder' || $aFilesToDownload) {
             $sZipFilePath = $this->prepareFolderForDownloading($aFilesToDownload);
+            if ($sZipFilePath == -1) {
+                $this->_oTemplate->displayMsg(_t('_bx_files_txt_max_size_reached', _t_format_size(intval(getParam('bx_files_max_bulk_download_size')) * 1024 * 1024)));
+                return;
+            }
+
             if (!$sZipFilePath) {
                 $this->_oTemplate->displayPageNotFound();
                 return;
@@ -522,24 +533,31 @@ class BxFilesModule extends BxBaseModTextModule
     private function prepareFolderForDownloading($aFiles) {
         $CNF = &$this->_oConfig->CNF;
 
-        $aFilesList = [];
-        foreach ($aFiles as $iFile) {
-            $aData = $this->_oDb->getContentInfoById(intval($iFile));
-            $aFilesList = array_merge($aFilesList, $this->getFolderFiles(intval($iFile), $aData['type'] == 'folder' ? $this->sanitizeFileName($aData['title']).'/' : '/', $aData['type']));
-        }
+        $aFilesList = $this->getFolderFiles($aFiles, '/', 'mixed');
         if(!$aFilesList) return false;
 
+        $iMaxSize = intval(getParam('bx_files_max_bulk_download_size')) * 1024 * 1024;
+        if ($iMaxSize) {
+            $iTotalSize = 0;
+            foreach ($aFilesList as $aFile) {
+                $iTotalSize += $aFile['size'];
+            }
+            if ($iTotalSize >= $iMaxSize) return -1;
+        }
+
         $sZipFile = BX_DIRECTORY_PATH_TMP.'files-folder-'.mt_rand().'.zip';
         if (file_exists($sZipFile)) @unlink($sZipFile);
 
         $oZipFile = new ZipArchive();
         if ($oZipFile->open($sZipFile, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)) {
-            $oZipFile->setCompressionIndex(0, ZipArchive::CM_STORE);
 
+            $iIndex = 0;
             foreach ($aFilesList as $aFile) {
                 $sFilePath = BX_DIRECTORY_STORAGE . $CNF['OBJECT_STORAGE'].'/'.$aFile['path'];
-                if (file_exists($sFilePath) && is_readable($sFilePath))
+                if (file_exists($sFilePath) && is_readable($sFilePath)) {
                     $oZipFile->addFile($sFilePath, $aFile['filename']);
+                    $oZipFile->setCompressionIndex($iIndex++, ZipArchive::CM_STORE);
+                }
             }
 
             $oZipFile->close();
@@ -549,8 +567,8 @@ class BxFilesModule extends BxBaseModTextModule
         }
     }
 
-    private function getFolderFiles($iFile, $sRelPath, $sType) {
-        $aFiles = $this->_oDb->getFolderFilesEx($iFile, $sType);
+    private function getFolderFiles($mFile, $sRelPath, $sType) {
+        $aFiles = $this->_oDb->getFolderFilesEx($mFile, $sType);
         if (!$aFiles) return [];
 
         $aResult = [];

+ 53 - 41
modules/boonex/files/classes/BxFilesSearchResult.php

@@ -253,7 +253,7 @@ class BxFilesSearchResult extends BxBaseModTextSearchResult
 
         $this->oModule->_oTemplate->addCss('main.css');
 
-        return $this->showBrowseToolbar([
+        $aParams = [
             'aRequestParams' => [
                 'unit_view_param' => $this->sUnitViewParamName,
                 'bookmarks_param' => $this->sBookmarksParamName,
@@ -269,7 +269,9 @@ class BxFilesSearchResult extends BxBaseModTextSearchResult
             'keyword' => bx_get('keyword') ? bx_get('keyword') : '',
             'current_folder' => $this->aCurrent['restriction']['folder']['value'],
             'current_page' => $this->aCurrent['paginate']['start'],
-        ]);
+        ];
+
+        return $this->getBrowseToolbar($aParams);
     }
 
     function getSearchData ()
@@ -352,7 +354,7 @@ class BxFilesSearchResult extends BxBaseModTextSearchResult
 
     }
 
-    public function showBrowseToolbar($aParams) {
+    protected function getBrowseToolbarControls(&$aParams, $sJsObject) {
         $aSortingOptions = [];
         if (isset($aParams['sorting_options'])) {
             foreach ($aParams['sorting_options'] as $sSorting) {
@@ -360,17 +362,6 @@ class BxFilesSearchResult extends BxBaseModTextSearchResult
             }
         }
 
-        $sUniqueIdent = mt_rand();
-        $aParams['unique_ident'] = $sUniqueIdent;
-        $aParams['context'] = $this->iFileManagerUploadTo;
-
-        $this->oModule->_oTemplate->addJs('toolbar_tools.js');
-
-        $sJsCode = $this->oModule->_oTemplate->getJsCode(['type' => 'toolbar_tools', 'uniq' => $sUniqueIdent], $aParams);
-        $sJsObject = $this->oModule->_oConfig->getJsObject(['type' => 'toolbar_tools', 'uniq' => $sUniqueIdent]);
-
-        $this->setUnitParams(['toolbar_js_object' => $sJsObject]);
-
         $oForm = new BxTemplFormView([], $this->oModule->_oTemplate);
         $aInputSorting = [
             'type' => 'select',
@@ -424,24 +415,6 @@ class BxFilesSearchResult extends BxBaseModTextSearchResult
             ];
         }
 
-        $aFolderPathTmpl = [];
-        $aFolderPath = $this->oModule->_oDb->getFolderPath($this->aCurrent['restriction']['folder']['value']);
-        if ($aFolderPath) {
-            $aFolderPathTmpl[] = [
-                'name' => _t('_bx_files_txt_folder_root'),
-                'folder' => '0',
-                'js_object' => $sJsObject,
-            ];
-
-            foreach ($aFolderPath as $aEntry) {
-                $aFolderPathTmpl[] = [
-                    'name' => strmaxtextlen($aEntry['name'], 20),
-                    'folder' => $aEntry['folder'],
-                    'js_object' => $sJsObject,
-                ];
-            }
-        }
-
         $aBulkActions = [];
         $aBulkActions[] = ['js_object' => $sJsObject, 'handler' => 'downloadFiles', 'title' => _t('_bx_files_bulk_action_title_download'), 'icon' => 'download'];
         if (isLogged()) {
@@ -452,14 +425,9 @@ class BxFilesSearchResult extends BxBaseModTextSearchResult
             }
         }
 
-
-        return $this->oModule->_oTemplate->parseHtmlByName('files_browser_toolbar.html', [
-            'js_object' => $sJsObject,
-            'js_code' => $sJsCode,
-            'unique_ident' => $sUniqueIdent,
+        return [
             'sorting_dropdown' => $oForm->genRowStandard($aInputSorting),
             'filter_box' => $oForm->genRowStandard($aInputFilter),
-            'bx_repeat:folder_path' => $aFolderPathTmpl,
             'bx_if:upload_visible' => [
                 'condition' => $bUploadAllowed,
                 'content' => $aUploadButtonParams,
@@ -485,6 +453,52 @@ class BxFilesSearchResult extends BxBaseModTextSearchResult
                     'unit_view_param' => $aParams['aRequestParams']['unit_view_param'],
                 ],
             ],
+            'bx_repeat:sorting_options' => $aSortingOptions,
+            'bx_repeat:bulk_actions' => $aBulkActions,
+        ];
+    }
+
+    protected function getBrowseToolbarBreadcrumbs($sJsObject) {
+        $aFolderPathTmpl = [];
+        $aFolderPath = $this->oModule->_oDb->getFolderPath($this->aCurrent['restriction']['folder']['value']);
+        if ($aFolderPath) {
+            $aFolderPathTmpl[] = [
+                'name' => _t('_bx_files_txt_folder_root'),
+                'folder' => '0',
+                'js_object' => $sJsObject,
+            ];
+
+            foreach ($aFolderPath as $aEntry) {
+                $aFolderPathTmpl[] = [
+                    'name' => strmaxtextlen($aEntry['name'], 20),
+                    'folder' => $aEntry['folder'],
+                    'js_object' => $sJsObject,
+                ];
+            }
+        }
+
+        return $aFolderPathTmpl;
+    }
+
+    protected function getBrowseToolbar(&$aParams) {
+        $this->oModule->_oTemplate->addJs('toolbar_tools.js');
+
+        $sUniqueIdent = mt_rand();
+        $aParams['unique_ident'] = $sUniqueIdent;
+        $aParams['context'] = $this->iFileManagerUploadTo;
+
+        $sJsCode = $this->oModule->_oTemplate->getJsCode(['type' => 'toolbar_tools', 'uniq' => $sUniqueIdent], $aParams);
+        $sJsObject = $this->oModule->_oConfig->getJsObject(['type' => 'toolbar_tools', 'uniq' => $sUniqueIdent]);
+
+        $this->setUnitParams(['toolbar_js_object' => $sJsObject]);
+
+        $aToolbarControls = $this->getBrowseToolbarControls($aParams, $sJsObject);
+
+        return $this->oModule->_oTemplate->parseHtmlByName('files_browser_toolbar.html', array_merge($aToolbarControls, [
+            'js_object' => $sJsObject,
+            'js_code' => $sJsCode,
+            'unique_ident' => $sUniqueIdent,
+            'bx_repeat:folder_path' => $this->getBrowseToolbarBreadcrumbs($sJsObject),
             'bx_if:select_all_checkbox' => [
                 'condition' => $aParams['layout'] == 'table',
                 'content' => [
@@ -492,9 +506,7 @@ class BxFilesSearchResult extends BxBaseModTextSearchResult
                     'unique_ident' => $sUniqueIdent,
                 ],
             ],
-            'bx_repeat:sorting_options' => $aSortingOptions,
-            'bx_repeat:bulk_actions' => $aBulkActions,
-        ]);
+        ]));
     }
 }
 

+ 2 - 0
modules/boonex/files/install/langs/en.xml

@@ -258,6 +258,7 @@
 
     <string name="_bx_files_option_link_to_preview"><![CDATA[Link file title to a preview popup instead of a file view page in context blocks]]></string>
     <string name="_bx_files_option_max_nesting_level"><![CDATA[Folders max nesting level]]></string>
+    <string name="_bx_files_option_max_bulk_download_size"><![CDATA[Max size of files in a bulk/folder download archive (Mb)]]></string>
 
     <string name="_bx_files_entry_info_size"><![CDATA[Size]]></string>
     <string name="_bx_files_entry_info_date"><![CDATA[Date]]></string>
@@ -281,6 +282,7 @@
     <string name="_bx_files_txt_move_to"><![CDATA[Move To]]></string>
     <string name="_bx_files_txt_move_to_nowhere"><![CDATA[There are no folders created yet]]></string>
     <string name="_bx_files_txt_move_here"><![CDATA[Move here?]]></string>
+    <string name="_bx_files_txt_max_size_reached"><![CDATA[Too large archive for downloading. Max overall size of files for bulk downloading is {0}.]]></string>
 
     <string name="_bx_files_bulk_action_title_download"><![CDATA[Download]]></string>
     <string name="_bx_files_bulk_action_title_bookmark"><![CDATA[Bookmark]]></string>

+ 1 - 0
modules/boonex/files/install/sql/enable.sql

@@ -14,6 +14,7 @@ INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `c
 ('bx_files_summary_chars', '700', @iCategId, '_bx_files_option_summary_chars', 'digit', '', '', '', 1),
 ('bx_files_show_link_to_preview', '', @iCategId, '_bx_files_option_link_to_preview', 'checkbox', '', '', '', 5),
 ('bx_files_max_nesting_level', '3', @iCategId, '_bx_files_option_max_nesting_level', 'digit', '', '', '', 6),
+('bx_files_max_bulk_download_size', '100', @iCategId, '_bx_files_option_max_bulk_download_size', 'digit', '', '', '', 7),
 ('bx_files_per_page_browse', '12', @iCategId, '_bx_files_option_per_page_browse', 'digit', '', '', '', 10),
 ('bx_files_per_page_profile', '6', @iCategId, '_bx_files_option_per_page_profile', 'digit', '', '', '', 12),
 ('bx_files_per_page_browse_showcase', '32', @iCategId, '_sys_option_per_page_browse_showcase', 'digit', '', '', '', 15),

+ 2 - 0
modules/boonex/russian/data/langs/bx_files/ru.xml

@@ -257,6 +257,7 @@
 
     <string name="_bx_files_option_link_to_preview"><![CDATA[Открывать предпросмотри при нажатии на файл в контекстных блоках]]></string>
     <string name="_bx_files_option_max_nesting_level"><![CDATA[Максимальная вложенность папок]]></string>
+    <string name="_bx_files_option_max_bulk_download_size"><![CDATA[Максимальный размер файлов при загрузке группой/папкой (Мб)]]></string>
 
     <string name="_bx_files_entry_info_size"><![CDATA[Размер]]></string>
     <string name="_bx_files_entry_info_date"><![CDATA[Дата]]></string>
@@ -280,6 +281,7 @@
     <string name="_bx_files_txt_move_to"><![CDATA[Переместить в]]></string>
     <string name="_bx_files_txt_move_to_nowhere"><![CDATA[Еще не создано ни одной папки]]></string>
     <string name="_bx_files_txt_move_here"><![CDATA[Переместить сюда?]]></string>
+    <string name="_bx_files_txt_max_size_reached"><![CDATA[Слишком большой архив для загрузки. Максимальый суммарный размер файлов для загрузки {0}.]]></string>
 
     <string name="_bx_files_bulk_action_title_download"><![CDATA[Скачать]]></string>
     <string name="_bx_files_bulk_action_title_bookmark"><![CDATA[Сделать закладки]]></string>