*
* Uploads multiple files at once by packing them in a zip
* archive & extracting them on the server.
*
* Developed and tested using the PmWiki 2.2.0-beta series.
* Requires PHP 5 ZipArchive support:
* http://php.net/manual/en/ref.zip.php
*
* To install, add the following line to your configuration file :
include_once("$FarmD/cookbook/multiupload.php");
*
* For more information, please see the online documentation at
* http://www.pmwiki.org/wiki/Cookbook/MultiUpload
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License,
* Version 2, as published by the Free Software Foundation.
* http://www.gnu.org/copyleft/gpl.html
*/
$RecipeInfo['MultiUpload']['Version'] = '2007-11-27';
if ( !class_exists('ZipArchive') ) Abort('PHP 5 ZipArchive support required for multiupload.php cookbook recipe');
SDV($PageUploadFmt,array("
$[Attachments for] {\$FullName}
\$UploadResult
",
'wiki:$[{$SiteGroup}/UploadQuickReference]'));
SDVA( $HandleActions, array( 'postmultiupload' => 'HandlePostMultiUpload' ) );
SDV( $HandleAuth['postmultiupload'], $HandleAuth['postupload'] );
XLSDV( 'en', array( 'ULfailextract' => 'error extracting file' ) );
function HandlePostMultiUpload($pagename, $auth = 'upload') {
global $UploadFileFmt, $LastModFile, $EnableUploadVersions, $Now;
if ( !$_REQUEST['extract'] ) {
HandlePostUpload( $pagename, $auth );
return;
}
$page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT);
if (!$page) Abort("?cannot upload to $pagename");
$zipfile = $_FILES['uploadfile'];
$zname = $zipfile['name'];
$upreport = '{$PageUrl}?action=upload&uprname';
$result = UploadVerifyArchive( $zipfile );
if ( $result != '' ) {
Redirect( $pagename, "$upreport=$zname&$result" );
return;
}
$za = new ZipArchive;
$res = $za->open($zipfile['tmp_name']);
if ($res !== TRUE) Abort("?error opening archive $zname: ".ZipArchiveErrorStr($res) );
$filedir = FmtPageName( "$UploadFileFmt", $pagename );
mkdirp($filedir);
for ( $i = 0; $i < $za->numFiles; ++$i ) {
$stat = $za->statIndex($i);
$name = MakeUploadName( $pagename, preg_replace( '#^.*/([^/]*)$#', '$1', $stat['name'] ) );
if ( $name == '' ) continue;
$filepath = "$filedir/$name";
$result = UploadVerifyArchiveEntry( $stat, $filepath );
if ( $result != '' ) {
Redirect( $pagename, "$upreport=$zname/$name&$result" );
return;
}
if ( IsEnabled( $EnableUploadVersions, 0 ) ) @rename( $filepath, "$filepath,$Now" );
if ( !( $za->renameIndex( $i, $name ) && $za->extractTo( $filedir, $name ) ) ) {
Redirect( $pagename, "$upreport=$zname/$name&upresult=failextract" );
return;
}
fixperms( $filepath, 0444 );
}
if ($LastModFile) { touch($LastModFile); fixperms($LastModFile); }
Redirect( $pagename, "$upreport=$zname&upresult=success" );
}
function UploadVerifyArchive( $uploadfile ) {
global $UploadExtSize;
preg_match( '/\\.([^.\\/]+)$/', $uploadfile['name'], $match ); $ext = @$match[1];
$maxsize = $UploadExtSize[$ext];
if ( $maxsize <= 0 ) return "upresult=badtype&upext=$ext";
if ($uploadfile['size']>$maxsize)
return "upresult=toobigext&upext=$ext&upmax=$maxsize";
switch (@$uploadfile['error']) {
case 1: return 'upresult=toobig';
case 2: return 'upresult=toobig';
case 3: return 'upresult=partial';
case 4: return 'upresult=nofile';
}
if (!is_uploaded_file($uploadfile['tmp_name'])) return 'upresult=nofile';
return '';
}
function UploadVerifyArchiveEntry( $stat, $filepath ) {
global $EnableUploadOverwrite, $UploadExtSize, $UploadPrefixQuota, $UploadDirQuota, $UploadDir;
if ( !$EnableUploadOverwrite && file_exists($filepath) ) return 'upresult=exists';
preg_match( '/\\.([^.\\/]+)$/', $filepath, $match ); $ext = @$match[1];
$maxsize = $UploadExtSize[$ext];
if ( $maxsize <= 0 ) return "upresult=badtype&upext=$ext";
if ( $stat['size'] > $maxsize ) return "upresult=toobigext&upext=$ext&upmax=$maxsize";
$filedir = preg_replace('#/[^/]*$#','',$filepath);
if ( $UploadPrefixQuota && ( dirsize($filedir) - @filesize($filepath) + $stat['size'] ) > $UploadPrefixQuota )
return 'upresult=pquota';
if ( $UploadDirQuota && ( dirsize($UploadDir) - @filesize($filepath) + $stat['size'] ) > $UploadDirQuota )
return 'upresult=tquota';
return '';
}
function ZipArchiveErrorStr($i) {
switch($i) {
case constant('ZIPARCHIVE::ER_OK'): return "No error.";
case constant('ZIPARCHIVE::ER_MULTIDISK'): return "Multi-disk zip archives not supported.";
case constant('ZIPARCHIVE::ER_RENAME'): return "Renaming temporary file failed.";
case constant('ZIPARCHIVE::ER_CLOSE'): return "Closing zip archive failed";
case constant('ZIPARCHIVE::ER_SEEK'): return "Seek error";
case constant('ZIPARCHIVE::ER_READ'): return "Read error";
case constant('ZIPARCHIVE::ER_WRITE'): return "Write error";
case constant('ZIPARCHIVE::ER_CRC'): return "CRC error";
case constant('ZIPARCHIVE::ER_ZIPCLOSED'): return "Containing zip archive was closed";
case constant('ZIPARCHIVE::ER_NOENT'): return "No such file.";
case constant('ZIPARCHIVE::ER_EXISTS'): return "File already exists";
case constant('ZIPARCHIVE::ER_OPEN'): return "Can't open file";
case constant('ZIPARCHIVE::ER_TMPOPEN'): return "Failure to create temporary file.";
case constant('ZIPARCHIVE::ER_ZLIB'): return "Zlib error";
case constant('ZIPARCHIVE::ER_MEMORY'): return "Memory allocation failure";
case constant('ZIPARCHIVE::ER_CHANGED'): return "Entry $i has been changed";
case constant('ZIPARCHIVE::ER_COMPNOTSUPP'): return "Compression method not supported.";
case constant('ZIPARCHIVE::ER_EOF'): return "Premature EOF";
case constant('ZIPARCHIVE::ER_INVAL'): return "Invalid argument";
case constant('ZIPARCHIVE::ER_NOZIP'): return "Not a zip archive";
case constant('ZIPARCHIVE::ER_INTERNAL'): return "Internal error";
case constant('ZIPARCHIVE::ER_INCONS'): return "Zip archive inconsistent";
case constant('ZIPARCHIVE::ER_REMOVE'): return "Can't remove file";
case constant('ZIPARCHIVE::ER_DELETED'): return "Entry has been deleted";
}
return FALSE;
}