Commit 8ba6b67ecf09bc33523c1353d245aaa0d3550ef8

Authored by Megan Watson
1 parent 82c4f1a1

KTS-2390

"Need a way to download or checkout multiple files at the same time"
Refactored the code to zip files into a class. Updated the Bulk Export with the new class. Added the bulk check out action.

Committed by: Megan Watson
Reviewed by: Conrad Vermeulen



git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@7301 c91229c3-7414-0410-bfa2-8a42b809f60b
lib/foldermanagement/compressionArchiveUtil.inc.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Id:
  4 + *
  5 + * The contents of this file are subject to the KnowledgeTree Public
  6 + * License Version 1.1.2 ("License"); You may not use this file except in
  7 + * compliance with the License. You may obtain a copy of the License at
  8 + * http://www.knowledgetree.com/KPL
  9 + *
  10 + * Software distributed under the License is distributed on an "AS IS"
  11 + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
  12 + * See the License for the specific language governing rights and
  13 + * limitations under the License.
  14 + *
  15 + * All copies of the Covered Code must include on each user interface screen:
  16 + * (i) the "Powered by KnowledgeTree" logo and
  17 + * (ii) the KnowledgeTree copyright notice
  18 + * in the same form as they appear in the distribution. See the License for
  19 + * requirements.
  20 + *
  21 + * The Original Code is: KnowledgeTree Open Source
  22 + *
  23 + * The Initial Developer of the Original Code is The Jam Warehouse Software
  24 + * (Pty) Ltd, trading as KnowledgeTree.
  25 + * Portions created by The Jam Warehouse Software (Pty) Ltd are Copyright
  26 + * (C) 2007 The Jam Warehouse Software (Pty) Ltd;
  27 + * All Rights Reserved.
  28 + * Contributor( s): ______________________________________
  29 + *
  30 + */
  31 +
  32 +/**
  33 +* Class to create and download a zip file
  34 +*/
  35 +class ZipFolder {
  36 +
  37 + var $sTmpPath = '';
  38 + var $sZipFileName = '';
  39 + var $sZipFile = '';
  40 + var $aPaths = array();
  41 + var $aReplaceKeys = array();
  42 + var $aReplaceValues = array();
  43 + var $sOutputEncoding = 'UTF-8';
  44 +
  45 + /**
  46 + * Constructor
  47 + */
  48 + function ZipFolder($sZipFileName) {
  49 + $this->oKTConfig =& KTConfig::getSingleton();
  50 + $this->oStorage =& KTStorageManagerUtil::getSingleton();
  51 +
  52 + $sBasedir = $this->oKTConfig->get("urls/tmpDirectory");
  53 + $sTmpPath = tempnam($sBasedir, 'kt_compress_zip');
  54 +
  55 + unlink($sTmpPath);
  56 + mkdir($sTmpPath, 0700);
  57 +
  58 + $this->sTmpPath = $sTmpPath;
  59 + $this->sZipFileName = $sZipFileName;
  60 + $this->aPaths = array();
  61 +
  62 + $aReplace = array(
  63 + "[" => "[[]",
  64 + " " => "[ ]",
  65 + "*" => "[*]",
  66 + "?" => "[?]",
  67 + );
  68 +
  69 + $this->aReplaceKeys = array_keys($aReplace);
  70 + $this->aReplaceValues = array_values($aReplace);
  71 + }
  72 +
  73 + /**
  74 + * Add a document to the zip file
  75 + */
  76 + function addDocumentToZip($oDocument) {
  77 + $sParentFolder = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf('%s/%s', $this->sTmpPath, $oDocument->getFullPath()))));
  78 + $newDir = $this->sTmpPath;
  79 + $sFullPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', $this->_convertEncoding($oDocument->getFullPath(), true))));
  80 + foreach (split('/', $sFullPath) as $dirPart) {
  81 + $newDir = sprintf("%s/%s", $newDir, $dirPart);
  82 + if (!file_exists($newDir)) {
  83 + mkdir($newDir, 0700);
  84 + }
  85 + }
  86 +
  87 + $sOrigFile = str_replace('<', '', str_replace('</', '', str_replace('>', '', $this->oStorage->temporaryFile($oDocument))));
  88 + $sFilename = sprintf("%s/%s", $sParentFolder, str_replace('<', '', str_replace('</', '', str_replace('>', '', $oDocument->getFileName()))));
  89 + $sFilename = $this->_convertEncoding($sFilename, true);
  90 + copy($sOrigFile, $sFilename);
  91 +
  92 + $sPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf("%s/%s", $oDocument->getFullPath(), $oDocument->getFileName()))));
  93 + $sPath = str_replace($this->aReplaceKeys, $this->aReplaceValues, $sPath);
  94 + $sPath = $this->_convertEncoding($sPath, true);
  95 +
  96 + $this->aPaths[] = $sPath;
  97 + return true;
  98 + }
  99 +
  100 + /**
  101 + * Add a folder to the zip file
  102 + */
  103 + function addFolderToZip($oFolder) {
  104 + $sFolderPath = $oFolder->getFullPath().'/'.$oFolder->getName().'/';
  105 + $sParentFolder = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf('%s/%s', $this->sTmpPath, $sFolderPath))));
  106 + $newDir = $this->sTmpPath;
  107 + $sFullPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', $this->_convertEncoding($sFolderPath, true))));
  108 + foreach (split('/', $sFullPath) as $dirPart) {
  109 + $newDir = sprintf("%s/%s", $newDir, $dirPart);
  110 + if (!file_exists($newDir)) {
  111 + mkdir($newDir, 0700);
  112 + }
  113 + }
  114 +
  115 + $sPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf("%s", $sFolderPath))));
  116 + $sPath = str_replace($this->aReplaceKeys, $this->aReplaceValues, $sPath);
  117 + $sPath = $this->_convertEncoding($sPath, true);
  118 +
  119 + $this->aPaths[] = $sPath;
  120 + return true;
  121 + }
  122 +
  123 + /**
  124 + * Zip the temp folder
  125 + */
  126 + function createZipFile($bEchoStatus = FALSE) {
  127 + if(empty($this->aPaths)){
  128 + return PEAR::raiseError(_kt("No folders or documents found to compress"));
  129 + //$this->addErrorMessage(_kt("No folders or documents found to compress"));
  130 + //return false;
  131 + }
  132 +
  133 + $sManifest = sprintf("%s/%s", $this->sTmpPath, "MANIFEST");
  134 + file_put_contents($sManifest, join("\n", $this->aPaths));
  135 + $sZipFile = sprintf("%s/%s.zip", $this->sTmpPath, $this->sZipFileName);
  136 + $sZipFile = str_replace('<', '', str_replace('</', '', str_replace('>', '', $sZipFile)));
  137 + $sZipCommand = KTUtil::findCommand("export/zip", "zip");
  138 + $aCmd = array($sZipCommand, "-r", $sZipFile, ".", "-i@MANIFEST");
  139 + $sOldPath = getcwd();
  140 + chdir($this->sTmpPath);
  141 + // Note that the popen means that pexec will return a file descriptor
  142 + $aOptions = array('popen' => 'r');
  143 + $fh = KTUtil::pexec($aCmd, $aOptions);
  144 +
  145 + if($bEchoStatus){
  146 + $last_beat = time();
  147 + while(!feof($fh)) {
  148 + if ($i % 1000 == 0) {
  149 + $this_beat = time();
  150 + if ($last_beat + 1 < $this_beat) {
  151 + $last_beat = $this_beat;
  152 + print "&nbsp;";
  153 + }
  154 + }
  155 + $contents = fread($fh, 4096);
  156 + if ($contents) {
  157 + print nl2br($this->_convertEncoding($contents, false));
  158 + }
  159 + $i++;
  160 + }
  161 + }
  162 + pclose($fh);
  163 +
  164 + // Save the zip file and path into session
  165 + $_SESSION['zipcompression'] = KTUtil::arrayGet($_SESSION, 'zipcompression', array());
  166 + $sExportCode = KTUtil::randomString();
  167 + $_SESSION['zipcompression'][$sExportCode] = array(
  168 + 'file' => $sZipFile,
  169 + 'dir' => $this->oZip->sTmpPath,
  170 + );
  171 + $_SESSION['zipcompression']['exportcode'] = $sExportCode;
  172 +
  173 + $this->sZipFile = $sZipFile;
  174 + return $sExportCode;
  175 + }
  176 +
  177 + /**
  178 + * Download the zip file
  179 + */
  180 + function downloadZipFile($exportCode = NULL) {
  181 + if(!(isset($exportCode) && !empty($exportCode))) {
  182 + $exportCode = KTUtil::arrayGet($_SESSION['zipcompression'], 'exportcode');
  183 + }
  184 + $aData = KTUtil::arrayGet($_SESSION['zipcompression'], $exportCode);
  185 +
  186 + if(!empty($aData)){
  187 + $sZipFile = $aData['file'];
  188 + $sTmpPath = $aData['dir'];
  189 + }else{
  190 + $sZipFile = $this->sZipFile;
  191 + $sTmpPath = $this->sTmpPath;
  192 + }
  193 +
  194 + if (!file_exists($sZipFile)) {
  195 + return PEAR::raiseError(_kt('The ZIP file can only be downloaded once - if you cancel the download, you will need to reload the page.'));
  196 + }
  197 +
  198 + header("Content-Type: application/zip");
  199 + header("Content-Length: ". filesize($sZipFile));
  200 + header("Content-Disposition: attachment; filename=\"" . $this->sZipFileName . ".zip" . "\"");
  201 + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  202 + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  203 + header("Cache-Control: must-revalidate");
  204 + readfile($sZipFile);
  205 + $sTmpDir = $sTmpPath;
  206 + KTUtil::deleteDirectory($sTmpDir);
  207 + return true;
  208 + }
  209 +
  210 + /**
  211 + * Check that iconv exists and that the selected encoding is supported.
  212 + */
  213 + function checkConvertEncoding() {
  214 + if(!function_exists("iconv")) {
  215 + return PEAR::raiseError(_kt('IConv PHP extension not installed. The zip file compression could not handle output filename encoding conversion !'));
  216 + }
  217 + $oKTConfig = $this->oKTConfig;
  218 + $this->sOutputEncoding = $oKTConfig->get('export/encoding', 'UTF-8');
  219 +
  220 + // Test the specified encoding
  221 + if(iconv("UTF-8", $this->sOutputEncoding, "") === FALSE) {
  222 + return PEAR::raiseError(_kt('Specified output encoding for the zip files compression does not exists !'));
  223 + }
  224 + return true;
  225 + }
  226 +
  227 + function _convertEncoding($sMystring, $bEncode) {
  228 + if (strcasecmp($this->sOutputEncoding, "UTF-8") === 0) {
  229 + return $sMystring;
  230 + }
  231 + if ($bEncode) {
  232 + return iconv("UTF-8", $this->sOutputEncoding, $sMystring);
  233 + } else {
  234 + return iconv($this->sOutputEncoding, "UTF-8", $sMystring);
  235 + }
  236 + }
  237 +}
  238 +?>
0 239 \ No newline at end of file
... ...
plugins/ktcore/KTBulkActions.php
... ... @@ -31,6 +31,7 @@
31 31  
32 32 require_once(KT_LIB_DIR . '/actions/bulkaction.php');
33 33 require_once(KT_LIB_DIR . '/widgets/forms.inc.php');
  34 +require_once(KT_LIB_DIR . '/foldermanagement/compressionArchiveUtil.inc.php');
34 35  
35 36  
36 37 class KTBulkDeleteAction extends KTBulkAction {
... ... @@ -486,33 +487,33 @@ class KTBulkArchiveAction extends KTBulkAction {
486 487 DBUtil::rollback();
487 488 return false;
488 489 }
489   -
  490 +
490 491 $oDocumentTransaction = & new DocumentTransaction($document, sprintf(_kt('Document archived: %s'), $this->sReason), 'ktcore.transactions.update');
491 492 $oDocumentTransaction->create();
492   -
  493 +
493 494 DBUtil::commit();
494 495 return true;
495 496 }else if(is_a($oEntity, 'Folder')) {
496 497 DBUtil::startTransaction();
497   -
  498 +
498 499 $aDocuments = array();
499 500 $aChildFolders = array();
500 501 $oFolder = $oEntity;
501   -
  502 +
502 503 // Get folder id
503 504 $sFolderId = $oFolder->getID();
504   -
  505 +
505 506 // Get documents in folder
506 507 $sDocuments = $oFolder->getDocumentIDs($sFolderId);
507 508 $aDocuments = explode(',', $sDocuments);
508   -
  509 +
509 510 // Get all the folders within the folder
510 511 $sWhereClause = "parent_folder_ids = '{$sFolderId}' OR
511 512 parent_folder_ids LIKE '{$sFolderId},%' OR
512 513 parent_folder_ids LIKE '%,{$sFolderId},%' OR
513 514 parent_folder_ids LIKE '%,{$sFolderId}'";
514 515 $aChildFolders = $this->oFolder->getList($sWhereClause);
515   -
  516 +
516 517 // Loop through folders and get documents
517 518 if(!empty($aChildFolders)){
518 519 foreach($aChildFolders as $oChild){
... ... @@ -522,26 +523,26 @@ class KTBulkArchiveAction extends KTBulkAction {
522 523 DBUtil::rollback();
523 524 return false;
524 525 }
525   -
  526 +
526 527 if(!empty($sChildDocs)){
527 528 $aChildDocs = explode(',', $sChildDocs);
528 529 $aDocuments = array_merge($aDocuments, $aChildDocs);
529 530 }
530 531 }
531 532 }
532   -
  533 +
533 534 // Archive all documents
534 535 if(!empty($aDocuments)){
535 536 foreach($aDocuments as $sDocumentId){
536 537 $oDocument = Document::get($sDocumentId);
537   -
  538 +
538 539 $oDocument->setStatusID(ARCHIVED);
539 540 $res = $oDocument->update();
540 541 if (($res === false) || PEAR::isError($res)) {
541 542 DBUtil::rollback();
542 543 return false;
543 544 }
544   -
  545 +
545 546 $oDocumentTransaction = & new DocumentTransaction($oDocument, sprintf(_kt('Document archived: %s'), $this->sReason), 'ktcore.transactions.update');
546 547 $oDocumentTransaction->create();
547 548 }
... ... @@ -573,47 +574,29 @@ class KTBrowseBulkExportAction extends KTBulkAction {
573 574  
574 575 function do_performaction() {
575 576  
576   - $oKTConfig =& KTConfig::getSingleton();
577   - $sBasedir = $oKTConfig->get("urls/tmpDirectory");
578   - $this->sTmpPath= $sTmpPath = tempnam($sBasedir, 'kt_export');
  577 + $folderName = $this->oFolder->getName();
  578 + $this->oZip = new ZipFolder($folderName);
  579 + $res = $this->oZip->checkConvertEncoding();
579 580  
580   - $this->oStorage =& KTStorageManagerUtil::getSingleton();
  581 + $folderurl = KTBrowseUtil::getUrlForFolder($this->oFolder);
  582 + $sReturn = sprintf('<p>' . _kt('Return to the original <a href="%s">folder</a>') . "</p>\n", $folderurl);
581 583  
582   - unlink($sTmpPath);
583   - mkdir($sTmpPath, 0700);
  584 + if(PEAR::isError($res)){
  585 + $this->addErrorMessage($res->getMessage());
  586 + return $sReturn;
  587 + }
584 588  
585 589 $this->startTransaction();
  590 + $oKTConfig =& KTConfig::getSingleton();
586 591 $this->bNoisy = $oKTConfig->get("tweaks/noisyBulkOperations");
587 592  
588   - $this->sTmpPath = $sTmpPath;
589   - $this->aPaths = array();
590   -
591 593 $result = parent::do_performaction();
  594 + $sExportCode = $this->oZip->createZipFile();
592 595  
593   -
594   - $sManifest = sprintf("%s/%s", $this->sTmpPath, "MANIFEST");
595   - file_put_contents($sManifest, join("\n", $this->aPaths));
596   - $sZipFile = sprintf("%s/%s.zip", $this->sTmpPath, $this->oFolder->getName());
597   - $sZipFile = str_replace('<', '', str_replace('</', '', str_replace('>', '', $sZipFile)));
598   - $_SESSION['bulkexport'] = KTUtil::arrayGet($_SESSION, 'bulkexport', array());
599   - $sExportCode = KTUtil::randomString();
600   - $_SESSION['bulkexport'][$sExportCode] = array(
601   - 'file' => $sZipFile,
602   - 'dir' => $this->sTmpPath,
603   - );
604   - $sZipCommand = KTUtil::findCommand("export/zip", "zip");
605   - $aCmd = array(
606   - $sZipCommand,
607   - "-r",
608   - $sZipFile,
609   - ".",
610   - "-i@MANIFEST",
611   - );
612   - $sOldPath = getcwd();
613   - chdir($this->sTmpPath);
614   - // Note that the popen means that pexec will return a file descriptor
615   -
616   - $fh = KTUtil::pexec($aCmd);
  596 + if(PEAR::isError($sExportCode)){
  597 + $this->addErrorMessage($sExportCode->getMessage());
  598 + return $sReturn;
  599 + }
617 600  
618 601 $oTransaction = KTFolderTransaction::createFromArray(array(
619 602 'folderid' => $this->oFolder->getId(),
... ... @@ -624,32 +607,25 @@ class KTBrowseBulkExportAction extends KTBulkAction {
624 607 ));
625 608  
626 609 $this->commitTransaction();
627   -
628   -
629   - header("Content-Type: application/zip");
630   - header("Content-Length: ". filesize($sZipFile));
631   - header("Content-Disposition: attachment; filename=\"" . $this->oFolder->getName() . ".zip" . "\"");
632   - header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
633   - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
634   - header("Cache-Control: must-revalidate");
635   - readfile($sZipFile);
636   - $sTmpDir = $aData['dir'];
637   - KTUtil::deleteDirectory($sTmpDir);
638   -
639   - return $result;
  610 +
  611 + $url = KTUtil::addQueryStringSelf(sprintf('action=downloadZipFile&fFolderId=%d&exportcode=%s', $this->oFolder->getId(), $sExportCode));
  612 + $str = sprintf('<p>' . _kt('Go <a href="%s">here</a> to download the zip file if you are not automatically redirected there') . "</p>\n", $url);
  613 + $folderurl = KTBrowseUtil::getUrlForFolder($this->oFolder);
  614 + $str .= sprintf('<p>' . _kt('Once downloaded, return to the original <a href="%s">folder</a>') . "</p>\n", $folderurl);
  615 + //$str .= sprintf("</div></div></body></html>\n");
  616 + $str .= sprintf('<script language="JavaScript">
  617 + function kt_bulkexport_redirect() {
  618 + document.location.href = "%s";
  619 + }
  620 + callLater(1, kt_bulkexport_redirect);
  621 +
  622 + </script>', $url);
  623 +
  624 + return $str;
640 625 }
641 626  
642 627 function perform_action($oEntity) {
643   - $aReplace = array(
644   - "[" => "[[]",
645   - " " => "[ ]",
646   - "*" => "[*]",
647   - "?" => "[?]",
648   - );
649   -
650   - $aReplaceKeys = array_keys($aReplace);
651   - $aReplaceValues = array_values($aReplace);
652   -
  628 +
653 629 if(is_a($oEntity, 'Document')) {
654 630  
655 631 $oDocument = $oEntity;
... ... @@ -658,113 +634,316 @@ class KTBrowseBulkExportAction extends KTBulkAction {
658 634 $oDocumentTransaction = new DocumentTransaction($oDocument, "Document part of bulk export", 'ktstandard.transactions.bulk_export', array());
659 635 $oDocumentTransaction->create();
660 636 }
661   -
662   - $sParentFolder = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf('%s/%s', $this->sTmpPath, $oDocument->getFullPath()))));
663   - $newDir = $this->sTmpPath;
664   - $sFullPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', $this->_convertEncoding($oDocument->getFullPath(), true))));
665   - foreach (split('/', $sFullPath) as $dirPart) {
666   - $newDir = sprintf("%s/%s", $newDir, $dirPart);
667   - if (!file_exists($newDir)) {
668   - mkdir($newDir, 0700);
669   - }
670   - }
671   - $sOrigFile = str_replace('<', '', str_replace('</', '', str_replace('>', '', $this->oStorage->temporaryFile($oDocument))));
672   - $sFilename = sprintf("%s/%s", $sParentFolder, str_replace('<', '', str_replace('</', '', str_replace('>', '', $oDocument->getFileName()))));
673   - $sFilename = $this->_convertEncoding($sFilename, true);
674   - copy($sOrigFile, $sFilename);
675   - $sPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf("%s/%s", $oDocument->getFullPath(), $oDocument->getFileName()))));
676   - $sPath = str_replace($aReplaceKeys, $aReplaceValues, $sPath);
677   - $sPath = $this->_convertEncoding($sPath, true);
678   - $this->aPaths[] = $sPath;
679   -
  637 + $this->oZip->addDocumentToZip($oDocument);
680 638  
681 639 }else if(is_a($oEntity, 'Folder')) {
682 640 $aDocuments = array();
683 641 $oFolder = $oEntity;
684 642 $sFolderId = $oFolder->getId();
685 643 $sFolderDocs = $oFolder->getDocumentIDs($sFolderId);
686   -
  644 +
687 645 if(!empty($sFolderDocs)){
688 646 $aDocuments = explode(',', $sFolderDocs);
689 647 }
690   -
  648 +
691 649 // Get all the folders within the current folder
692 650 $sWhereClause = "parent_folder_ids = '{$sFolderId}' OR
693 651 parent_folder_ids LIKE '{$sFolderId},%' OR
694 652 parent_folder_ids LIKE '%,{$sFolderId},%' OR
695 653 parent_folder_ids LIKE '%,{$sFolderId}'";
696 654 $aFolderList = $this->oFolder->getList($sWhereClause);
697   -
  655 +
698 656 // Export the folder structure to ensure the export of empty directories
699   - foreach($aFolderList as $k => $oFolderItem){
700   - // Get documents for each folder
701   - $sFolderItemId = $oFolderItem->getID();
702   - $sFolderItemDocs = $oFolderItem->getDocumentIDs($sFolderItemId);
703   -
704   - if(!empty($sFolderItemDocs)){
705   - $aFolderDocs = explode(',', $sFolderItemDocs);
706   - $aDocuments = array_merge($aDocuments, $aFolderDocs);
707   - }
708   -
709   - $sFolderPath = $oFolderItem->getFullPath().'/'.$oFolderItem->getName().'/';
710   - $sParentFolder = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf('%s/%s', $this->sTmpPath, $sFolderPath))));
711   - $newDir = $this->sTmpPath;
712   - $sFullPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', $this->_convertEncoding($sFolderPath, true))));
713   - foreach (split('/', $sFullPath) as $dirPart) {
714   - $newDir = sprintf("%s/%s", $newDir, $dirPart);
715   - if (!file_exists($newDir)) {
716   - mkdir($newDir, 0700);
  657 + if(!empty($aFolderList)){
  658 + foreach($aFolderList as $k => $oFolderItem){
  659 + // Get documents for each folder
  660 + $sFolderItemId = $oFolderItem->getID();
  661 + $sFolderItemDocs = $oFolderItem->getDocumentIDs($sFolderItemId);
  662 +
  663 + if(!empty($sFolderItemDocs)){
  664 + $aFolderDocs = explode(',', $sFolderItemDocs);
  665 + $aDocuments = array_merge($aDocuments, $aFolderDocs);
717 666 }
  667 + $this->oZip->addFolderToZip($oFolderItem);
718 668 }
719   - $sPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf("%s", $sFolderPath))));
720   - $sPath = str_replace($aReplaceKeys, $aReplaceValues, $sPath);
721   - $sPath = $this->_convertEncoding($sPath, true);
722   - $this->aPaths[] = $sPath;
723 669 }
724   -
  670 +
725 671 // Add all documents to the export
726 672 if(!empty($aDocuments)){
727 673 foreach($aDocuments as $sDocumentId){
728 674 $oDocument = Document::get($sDocumentId);
729   -
  675 +
730 676 if ($this->bNoisy) {
731 677 $oDocumentTransaction = new DocumentTransaction($oDocument, "Document part of bulk export", 'ktstandard.transactions.bulk_export', array());
732 678 $oDocumentTransaction->create();
733 679 }
  680 + $this->oZip->addDocumentToZip($oDocument);
  681 + }
  682 + }
  683 + }
  684 + return true;
  685 + }
  686 +
  687 + function do_downloadZipFile() {
  688 + $sCode = $this->oValidator->validateString($_REQUEST['exportcode']);
  689 +
  690 + $folderName = $this->oFolder->getName();
  691 + $this->oZip = new ZipFolder($folderName);
734 692  
735   - $sParentFolder = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf('%s/%s', $this->sTmpPath, $oDocument->getFullPath()))));
736   - $newDir = $this->sTmpPath;
737   - $sFullPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', $this->_convertEncoding($oDocument->getFullPath(), true))));
738   - foreach (split('/', $sFullPath) as $dirPart) {
739   - $newDir = sprintf("%s/%s", $newDir, $dirPart);
740   - if (!file_exists($newDir)) {
741   - mkdir($newDir, 0700);
  693 + $res = $this->oZip->downloadZipFile($sCode);
  694 +
  695 + if(PEAR::isError($res)){
  696 + $this->addErrorMessage($res->getMessage());
  697 + redirect(generateControllerUrl("browse", "fBrowseType=folder&fFolderId=" . $this->oFolder->getId()));
  698 + }
  699 + exit(0);
  700 + }
  701 +}
  702 +
  703 +class KTBrowseBulkCheckoutAction extends KTBulkAction {
  704 + var $sName = 'ktcore.actions.bulk.checkout';
  705 + var $_sPermission = 'ktcore.permissions.write';
  706 + var $_bMutator = true;
  707 +
  708 + function getDisplayName() {
  709 + return _kt('Checkout');
  710 + }
  711 +
  712 + function check_entity($oEntity) {
  713 + if(is_a($oEntity, 'Document')) {
  714 + if ($oEntity->getIsCheckedOut()) {
  715 + return PEAR::raiseError(_kt('Document is already checked out'));
  716 + }
  717 + }else if(!is_a($oEntity, 'Folder')) {
  718 + return PEAR::raiseError(_kt('Document cannot be checked out'));
  719 + }
  720 + return parent::check_entity($oEntity);
  721 + }
  722 +
  723 + function form_collectinfo() {
  724 + $oForm = new KTForm;
  725 + $oForm->setOptions(array(
  726 + 'identifier' => 'ktcore.actions.bulk.checkout.form',
  727 + 'label' => _kt('Checkout Items'),
  728 + 'submit_label' => _kt('Checkout'),
  729 + 'action' => 'performaction',
  730 + 'fail_action' => 'collectinfo',
  731 + 'cancel_action' => 'main',
  732 + 'context' => $this,
  733 + ));
  734 +
  735 + $oForm-> setWidgets(array(
  736 + array('ktcore.widgets.reason',array(
  737 + 'name' => 'reason',
  738 + 'label' => _kt('Reason'),
  739 + 'description' => _kt('Please specify why you are checking out these documents. It will assist other users in understanding why you have locked these files.'),
  740 + 'value' => null,
  741 + 'required' => true,
  742 + )),
  743 + array('ktcore.widgets.boolean', array(
  744 + 'label' => _kt('Download Files'),
  745 + 'description' => _kt('Indicate whether you would like to download these file as part of the checkout.'),
  746 + 'name' => 'download_file',
  747 + 'value' => true,
  748 + )),
  749 + ));
  750 +
  751 + $oForm->setValidators(array(
  752 + array('ktcore.validators.string', array(
  753 + 'test' => 'reason',
  754 + 'max_length' => 250,
  755 + 'output' => 'reason',
  756 + )),
  757 + array('ktcore.validators.boolean', array(
  758 + 'test' => 'download_file',
  759 + 'output' => 'download_file',
  760 + )),
  761 + ));
  762 +
  763 + return $oForm;
  764 + }
  765 +
  766 + // info collection step
  767 + function do_collectinfo() {
  768 + $this->store_lists();
  769 + $this->get_lists();
  770 + $oTemplating =& KTTemplating::getSingleton();
  771 + $oTemplate = $oTemplating->loadTemplate('ktcore/bulk_action_info');
  772 + return $oTemplate->render(array('context' => $this,
  773 + 'form' => $this->form_collectinfo()));
  774 + }
  775 +
  776 + function do_performaction() {
  777 + // Get reason for checkout & check if docs must be downloaded
  778 + $this->store_lists();
  779 + $this->get_lists();
  780 +
  781 + $oForm = $this->form_collectinfo();
  782 + $res = $oForm->validate();
  783 + if (!empty($res['errors'])) {
  784 + $oForm->handleError();
  785 + }
  786 +
  787 + $this->sReason = $_REQUEST['data']['reason'];
  788 + $this->bDownload = $_REQUEST['data']['download_file'];
  789 +
  790 + $oKTConfig =& KTConfig::getSingleton();
  791 + $this->bNoisy = $oKTConfig->get("tweaks/noisyBulkOperations");
  792 +
  793 + $folderurl = KTBrowseUtil::getUrlForFolder($this->oFolder);
  794 + $sReturn = sprintf('<p>' . _kt('Return to the original <a href="%s">folder</a>') . "</p>\n", $folderurl);
  795 +
  796 + $this->startTransaction();
  797 +
  798 + // if files are to be downloaded - create the temp directory for the bulk export
  799 + if($this->bDownload){
  800 + $folderName = $this->oFolder->getName();
  801 + $this->oZip = new ZipFolder($folderName);
  802 + $res = $this->oZip->checkConvertEncoding();
  803 +
  804 + if(PEAR::isError($res)){
  805 + $this->addErrorMessage($res->getMessage());
  806 + return $sReturn;
  807 + }
  808 + }
  809 +
  810 +
  811 + $result = parent::do_performaction();
  812 +
  813 + if(PEAR::isError($result)){
  814 + $this->addErrorMessage($result->getMessage());
  815 + return $sReturn;
  816 + }
  817 +
  818 + if($this->bDownload){
  819 + $sExportCode = $this->oZip->createZipFile();
  820 +
  821 + if(PEAR::isError($sExportCode)){
  822 + $this->addErrorMessage($sExportCode->getMessage());
  823 + return $sReturn;
  824 + }
  825 + }
  826 +
  827 + $this->commitTransaction();
  828 +
  829 + if($this->bDownload){
  830 +
  831 + $url = KTUtil::addQueryStringSelf(sprintf('action=downloadZipFile&fFolderId=%d&exportcode=%s', $this->oFolder->getId(), $sExportCode));
  832 + $str = sprintf('<p>' . _kt('Go <a href="%s">here</a> to download the zip file if you are not automatically redirected there') . "</p>\n", $url);
  833 + $folderurl = KTBrowseUtil::getUrlForFolder($this->oFolder);
  834 + $str .= sprintf('<p>' . _kt('Once downloaded, return to the original <a href="%s">folder</a>') . "</p>\n", $folderurl);
  835 + $str .= sprintf("</div></div></body></html>\n");
  836 + $str .= sprintf('<script language="JavaScript">
  837 + function kt_bulkexport_redirect() {
  838 + document.location.href = "%s";
  839 + }
  840 + callLater(1, kt_bulkexport_redirect);
  841 +
  842 + </script>', $url);
  843 +
  844 + return $str;
  845 + }
  846 + return $result;
  847 + }
  848 +
  849 + function perform_action($oEntity) {
  850 + // checkout document
  851 + $sReason = $this->sReason;
  852 +
  853 + if(is_a($oEntity, 'Document')) {
  854 + $res = KTDocumentUtil::checkout($oEntity, $sReason, $this->oUser);
  855 +
  856 + if(PEAR::isError($res)) {
  857 + return PEAR::raiseError($oEntity->getName().': '.$res->getMessage());
  858 + }
  859 + if($this->bDownload){
  860 + if ($this->bNoisy) {
  861 + $oDocumentTransaction = new DocumentTransaction($oEntity, "Document part of bulk checkout", 'ktstandard.transactions.check_out', array());
  862 + $oDocumentTransaction->create();
  863 + }
  864 + $this->oZip->addDocumentToZip($oEntity);
  865 + }
  866 +
  867 + }else if(is_a($oEntity, 'Folder')) {
  868 + // get documents and subfolders
  869 + $aDocuments = array();
  870 + $oFolder = $oEntity;
  871 +
  872 + $sFolderId = $oFolder->getId();
  873 + $sFolderDocs = $oFolder->getDocumentIDs($sFolderId);
  874 +
  875 + // get documents directly in the folder
  876 + if(!empty($sFolderDocs)){
  877 + $aDocuments = explode(',', $sFolderDocs);
  878 + }
  879 +
  880 + // Get all the folders within the current folder
  881 + $sWhereClause = "parent_folder_ids = '{$sFolderId}' OR
  882 + parent_folder_ids LIKE '{$sFolderId},%' OR
  883 + parent_folder_ids LIKE '%,{$sFolderId},%' OR
  884 + parent_folder_ids LIKE '%,{$sFolderId}'";
  885 + $aFolderList = $this->oFolder->getList($sWhereClause);
  886 +
  887 + // Get the documents within the folder
  888 + if(!empty($aFolderList)){
  889 + foreach($aFolderList as $k => $oFolderItem){
  890 + // Get documents for each folder
  891 + $sFolderItemId = $oFolderItem->getID();
  892 + $sFolderItemDocs = $oFolderItem->getDocumentIDs($sFolderItemId);
  893 +
  894 + if(!empty($sFolderItemDocs)){
  895 + $aFolderDocs = explode(',', $sFolderItemDocs);
  896 + $aDocuments = array_merge($aDocuments, $aFolderDocs);
  897 + }
  898 +
  899 + // Add the folder to the zip file
  900 + if($this->bDownload){
  901 + $this->oZip->addFolderToZip($oFolderItem);
  902 + }
  903 + }
  904 + }
  905 +
  906 + // Checkout each document within the folder structure
  907 + if(!empty($aDocuments)){
  908 + foreach($aDocuments as $sDocId){
  909 + $oDocument = Document::get($sDocId);
  910 + if(PEAR::isError($oDocument)) {
  911 + return PEAR::raiseError(_kt('Folder documents cannot be checked out'));
  912 + }
  913 +
  914 + $res = KTDocumentUtil::checkout($oDocument, $sReason, $this->oUser);
  915 + if(PEAR::isError($res)) {
  916 + return PEAR::raiseError($oDocument->getName().': '.$res->getMessage());
  917 + }
  918 +
  919 + // Add document to the zip file
  920 + if($this->bDownload){
  921 + if ($this->bNoisy) {
  922 + $oDocumentTransaction = new DocumentTransaction($oDocument, "Document part of bulk checkout", 'ktstandard.transactions.check_out', array());
  923 + $oDocumentTransaction->create();
742 924 }
  925 + $this->oZip->addDocumentToZip($oDocument);
743 926 }
744   - $sOrigFile = str_replace('<', '', str_replace('</', '', str_replace('>', '', $this->oStorage->temporaryFile($oDocument))));
745   - $sFilename = sprintf("%s/%s", $sParentFolder, str_replace('<', '', str_replace('</', '', str_replace('>', '', $oDocument->getFileName()))));
746   - $sFilename = $this->_convertEncoding($sFilename, true);
747   - copy($sOrigFile, $sFilename);
748   - $sPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf("%s/%s", $oDocument->getFullPath(), $oDocument->getFileName()))));
749   - $sPath = str_replace($aReplaceKeys, $aReplaceValues, $sPath);
750   - $sPath = $this->_convertEncoding($sPath, true);
751   - $this->aPaths[] = $sPath;
752 927 }
753   - }
  928 + }
754 929 }
755 930 return true;
756 931 }
757   -
758   - function _convertEncoding($sMystring, $bEncode) {
759   - if (strcasecmp($this->sOutputEncoding, "UTF-8") === 0) {
760   - return $sMystring;
761   - }
762   - if ($bEncode) {
763   - return iconv("UTF-8", $this->sOutputEncoding, $sMystring);
764   - } else {
765   - return iconv($this->sOutputEncoding, "UTF-8", $sMystring);
766   - }
  932 +
  933 + function do_downloadZipFile() {
  934 + $sCode = $this->oValidator->validateString($_REQUEST['exportcode']);
  935 +
  936 + $folderName = $this->oFolder->getName();
  937 + $this->oZip = new ZipFolder($folderName);
  938 +
  939 + $res = $this->oZip->downloadZipFile($sCode);
  940 +
  941 + if(PEAR::isError($res)){
  942 + $this->addErrorMessage($res->getMessage());
  943 + redirect(generateControllerUrl("browse", "fBrowseType=folder&fFolderId=" . $this->oFolder->getId()));
  944 + }
  945 + exit(0);
767 946 }
768   -
769 947 }
  948 +
770 949 ?>
771 950 \ No newline at end of file
... ...
plugins/ktcore/KTCorePlugin.php
... ... @@ -91,6 +91,7 @@ class KTCorePlugin extends KTPlugin {
91 91 $this->registerAction('bulkaction', 'KTBulkCopyAction', 'ktcore.actions.bulk.copy', 'KTBulkActions.php');
92 92 $this->registerAction('bulkaction', 'KTBulkArchiveAction', 'ktcore.actions.bulk.archive', 'KTBulkActions.php');
93 93 $this->registerAction('bulkaction', 'KTBrowseBulkExportAction', 'ktcore.actions.bulk.export', 'KTBulkActions.php');
  94 + $this->registerAction('bulkaction', 'KTBrowseBulkCheckoutAction', 'ktcore.actions.bulk.checkout', 'KTBulkActions.php');
94 95  
95 96 // Dashlets
96 97 $this->registerDashlet('KTInfoDashlet', 'ktcore.dashlet.info', 'KTDashlets.php');
... ...
plugins/ktstandard/KTBulkExportPlugin.php
... ... @@ -34,6 +34,7 @@ require_once(KT_LIB_DIR . &#39;/plugins/pluginregistry.inc.php&#39;);
34 34 require_once(KT_LIB_DIR . '/browse/browseutil.inc.php');
35 35  
36 36 require_once(KT_LIB_DIR . '/config/config.inc.php');
  37 +require_once(KT_LIB_DIR . '/foldermanagement/compressionArchiveUtil.inc.php');
37 38  
38 39 class KTBulkExportPlugin extends KTPlugin {
39 40 var $sNamespace = "ktstandard.bulkexport.plugin";
... ... @@ -55,48 +56,16 @@ class KTBulkExportAction extends KTFolderAction {
55 56 var $sName = 'ktstandard.bulkexport.action';
56 57 var $sPermissionName = "ktcore.permissions.read";
57 58 var $_sShowPermission = "ktcore.permissions.read";
58   - var $sOutputEncoding = 'UTF-8';
59   -
60   - function _checkConvertEncoding() {
61   - if(!function_exists("iconv")) {
62   - $this->addErrorMessage(_kt('IConv PHP extension not installed. Bulk export could not handle output filename encoding conversion !'));
63   - return false;
64   - }
65   - $oKTConfig = KTConfig::getSingleton();
66   - $this->sOutputEncoding = $oKTConfig->get('export/encoding', 'UTF-8');
67   -
68   - // Test the specified encoding
69   - if(iconv("UTF-8", $this->sOutputEncoding, "") === FALSE) {
70   - $this->addErrorMessage(_kt('Specified output encoding for bulk export does not exists !'));
71   - return false;
72   - }
73   - return true;
74   - }
75   -
76   - /**
77   - * Convert encoding to defined character encoding
78   - *
79   - * @param string the string to convert
80   - * @param boolean encode(true) or decode(false) string
81   - * @return string the encoded string
82   - */
83   - function _convertEncoding($sMystring, $bEncode) {
84   - if (strcasecmp($this->sOutputEncoding, "UTF-8") === 0) {
85   - return $sMystring;
86   - }
87   - if ($bEncode) {
88   - return iconv("UTF-8", $this->sOutputEncoding, $sMystring);
89   - } else {
90   - return iconv($this->sOutputEncoding, "UTF-8", $sMystring);
91   - }
92   - }
93 59  
94 60 function getDisplayName() {
95 61 return _kt('Bulk Export');
96 62 }
97 63  
98 64 function do_main() {
99   - if(!$this->_checkConvertEncoding()) {
  65 + $folderName = $this->oFolder->getName();
  66 + $this->oZip = new ZipFolder($folderName);
  67 +
  68 + if(!$this->oZip->checkConvertEncoding()) {
100 69 redirect(KTBrowseUtil::getUrlForFolder($oFolder));
101 70 exit(0);
102 71 }
... ... @@ -105,7 +74,7 @@ class KTBulkExportAction extends KTFolderAction {
105 74 $aQuery = $this->buildQuery();
106 75 $this->oValidator->notError($aQuery);
107 76 $aDocumentIds = DBUtil::getResultArrayKey($aQuery, 'id');
108   -
  77 +
109 78 /* Modified 07/09/2007 by megan_w */
110 79 // Get all the folders within the current folder
111 80 $sCurrentFolderId = $this->oFolder->getId();
... ... @@ -116,11 +85,10 @@ class KTBulkExportAction extends KTFolderAction {
116 85  
117 86 $aFolderList = $this->oFolder->getList($sWhereClause);
118 87 /* End modified */
119   -
  88 +
120 89 $this->startTransaction();
121 90  
122 91 $oKTConfig =& KTConfig::getSingleton();
123   - $sBasedir = $oKTConfig->get("urls/tmpDirectory");
124 92 $bNoisy = $oKTConfig->get("tweaks/noisyBulkOperations");
125 93  
126 94 // Redirect if there are no documents and no folders to export
... ... @@ -129,114 +97,31 @@ class KTBulkExportAction extends KTFolderAction {
129 97 redirect(KTBrowseUtil::getUrlForFolder($oFolder));
130 98 exit(0);
131 99 }
132   -
  100 +
133 101 $this->oPage->requireJSResource('thirdpartyjs/MochiKit/Base.js');
134 102 $this->oPage->requireJSResource('thirdpartyjs/MochiKit/Async.js');
135 103 $this->oPage->template = "kt3/minimal_page";
136 104 $this->handleOutput("");
137 105  
138   - $sTmpPath = tempnam($sBasedir, 'kt_export');
139   - unlink($sTmpPath);
140   - mkdir($sTmpPath, 0700);
141   - $this->sTmpPath = $sTmpPath;
142   - $aPaths = array();
143   - $aReplace = array(
144   - "[" => "[[]",
145   - " " => "[ ]",
146   - "*" => "[*]",
147   - "?" => "[?]",
148   - );
149   - $aReplaceKeys = array_keys($aReplace);
150   - $aReplaceValues = array_values($aReplace);
151 106 if(!empty($aDocumentIds)){
152 107 foreach ($aDocumentIds as $iId) {
153 108 $oDocument = Document::get($iId);
154   -
  109 +
155 110 if ($bNoisy) {
156 111 $oDocumentTransaction = & new DocumentTransaction($oDocument, "Document part of bulk export", 'ktstandard.transactions.bulk_export', array());
157 112 $oDocumentTransaction->create();
158 113 }
159   -
160   - $sParentFolder = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf('%s/%s', $sTmpPath, $oDocument->getFullPath()))));
161   - $newDir = $this->sTmpPath;
162   - $sFullPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', $this->_convertEncoding($oDocument->getFullPath(), true))));
163   - foreach (split('/', $sFullPath) as $dirPart) {
164   - $newDir = sprintf("%s/%s", $newDir, $dirPart);
165   - if (!file_exists($newDir)) {
166   - mkdir($newDir, 0700);
167   - }
168   - }
169   - $sOrigFile = str_replace('<', '', str_replace('</', '', str_replace('>', '', $oStorage->temporaryFile($oDocument))));
170   - $sFilename = sprintf("%s/%s", $sParentFolder, str_replace('<', '', str_replace('</', '', str_replace('>', '', $oDocument->getFileName()))));
171   - $sFilename = $this->_convertEncoding($sFilename, true);
172   - copy($sOrigFile, $sFilename);
173   - $sPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf("%s/%s", $oDocument->getFullPath(), $oDocument->getFileName()))));
174   - $sPath = str_replace($aReplaceKeys, $aReplaceValues, $sPath);
175   - $sPath = $this->_convertEncoding($sPath, true);
176   - $aPaths[] = $sPath;
  114 +
  115 + $this->oZip->addDocumentToZip($oDocument);
177 116 }
178 117 }
179   -
180   - /* Modified 07/09/2007 by megan_w */
  118 +
181 119 // Export the folder structure to ensure the export of empty directories
182 120 foreach($aFolderList as $k => $oFolderItem){
183   - $sFolderPath = $oFolderItem->getFullPath().'/'.$oFolderItem->getName().'/';
184   - $sParentFolder = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf('%s/%s', $sTmpPath, $sFolderPath))));
185   - $newDir = $this->sTmpPath;
186   - $sFullPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', $this->_convertEncoding($sFolderPath, true))));
187   - foreach (split('/', $sFullPath) as $dirPart) {
188   - $newDir = sprintf("%s/%s", $newDir, $dirPart);
189   - if (!file_exists($newDir)) {
190   - mkdir($newDir, 0700);
191   - }
192   - }
193   - $sPath = str_replace('<', '', str_replace('</', '', str_replace('>', '', sprintf("%s", $sFolderPath))));
194   - $sPath = str_replace($aReplaceKeys, $aReplaceValues, $sPath);
195   - $sPath = $this->_convertEncoding($sPath, true);
196   - $aPaths[] = $sPath;
  121 + $this->oZip->addFolderToZip($oFolderItem);
197 122 }
198   - /* End modified */
199   -
200   - $sManifest = sprintf("%s/%s", $this->sTmpPath, "MANIFEST");
201   - file_put_contents($sManifest, join("\n", $aPaths));
202   - $sZipFile = sprintf("%s/%s.zip", $this->sTmpPath, $this->oFolder->getName());
203   - $sZipFile = str_replace('<', '', str_replace('</', '', str_replace('>', '', $sZipFile)));
204   - $_SESSION['bulkexport'] = KTUtil::arrayGet($_SESSION, 'bulkexport', array());
205   - $sExportCode = KTUtil::randomString();
206   - $_SESSION['bulkexport'][$sExportCode] = array(
207   - 'file' => $sZipFile,
208   - 'dir' => $this->sTmpPath,
209   - );
210   - $sZipCommand = KTUtil::findCommand("export/zip", "zip");
211   - $aCmd = array(
212   - $sZipCommand,
213   - "-r",
214   - $sZipFile,
215   - ".",
216   - "-i@MANIFEST",
217   - );
218   - $sOldPath = getcwd();
219   - chdir($this->sTmpPath);
220   - // Note that the popen means that pexec will return a file descriptor
221   - $aOptions = array('popen' => 'r');
222   - $fh = KTUtil::pexec($aCmd, $aOptions);
223   -
224   - $last_beat = time();
225   - while(!feof($fh)) {
226   - if ($i % 1000 == 0) {
227   - $this_beat = time();
228   - if ($last_beat + 1 < $this_beat) {
229   - $last_beat = $this_beat;
230   - print "&nbsp;";
231   - }
232   - }
233   - $contents = fread($fh, 4096);
234   - if ($contents) {
235   - print nl2br($this->_convertEncoding($contents, false));
236   - }
237   - $i++;
238   - }
239   - pclose($fh);
  123 +
  124 + $sExportCode = $this->oZip->createZipFile(TRUE);
240 125  
241 126 $oTransaction = KTFolderTransaction::createFromArray(array(
242 127 'folderid' => $this->oFolder->getId(),
... ... @@ -311,29 +196,17 @@ class KTBulkExportAction extends KTFolderAction {
311 196  
312 197 function do_downloadZipFile() {
313 198 $sCode = $this->oValidator->validateString($_REQUEST['exportcode']);
314   - $aData = KTUtil::arrayGet($_SESSION['bulkexport'], $sCode);
315   - $this->oValidator->notEmpty($aData);
316   - $sZipFile = $aData['file'];
317 199  
318   - if (!file_exists($sZipFile)) {
319   - $this->addErrorMessage(_kt('The ZIP can only be downloaded once - if you cancel the download, you will need to reload the Bulk Export page.'));
  200 + $folderName = $this->oFolder->getName();
  201 + $this->oZip = new ZipFolder($folderName);
  202 +
  203 + if(!$this->oZip->downloadZipFile($sCode)){
320 204 redirect(generateControllerUrl("browse", "fBrowseType=folder&fFolderId=" . $this->oFolder->getId()));
321   - exit(0);
322 205 }
323   -
324   - header("Content-Type: application/zip");
325   - header("Content-Length: ". filesize($sZipFile));
326   - header("Content-Disposition: attachment; filename=\"" . $this->oFolder->getName() . ".zip" . "\"");
327   - header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
328   - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
329   - header("Cache-Control: must-revalidate");
330   - readfile($sZipFile);
331   - $sTmpDir = $aData['dir'];
332   - KTUtil::deleteDirectory($sTmpDir);
333 206 exit(0);
334 207 }
335 208 }
336 209 $oPluginRegistry =& KTPluginRegistry::getSingleton();
337 210 $oPluginRegistry->registerPlugin('KTBulkExportPlugin', 'ktstandard.bulkexport.plugin', __FILE__);
338 211  
339 212 -?>
  213 +?>
340 214 \ No newline at end of file
... ...