Simple Groupware PHP Cross Reference Groupware Applications

Source: /src/lib/pmwiki/scripts/upload.php - 352 lines - 14682 bytes - Summary - Text - Print

   1  <?php if (!defined('PmWiki')) exit();
   2  /*  Copyright 2004-2009 Patrick R. Michaud (pmichaud@pobox.com)
   3      This file is part of PmWiki; you can redistribute it and/or modify
   4      it under the terms of the GNU General Public License as published
   5      by the Free Software Foundation; either version 2 of the License, or
   6      (at your option) any later version.  See pmwiki.php for full details.
   7  
   8      This script adds upload capabilities to PmWiki.  Uploads can be
   9      enabled by setting
  10          $EnableUpload = 1;
  11      in config.php.  In addition, an upload password must be set, as
  12      the default is to lock uploads.  In some configurations it may also
  13      be necessary to set values for $UploadDir and $UploadUrlFmt,
  14      especially if any form of URL rewriting is being performed.
  15      See the PmWiki.UploadsAdmin page for more information.
  16  */
  17  
  18  ## $EnableUploadOverwrite determines if we allow previously uploaded
  19  ## files to be overwritten.
  20  SDV($EnableUploadOverwrite,1);
  21  
  22  ## $UploadExts contains the list of file extensions we're willing to
  23  ## accept, along with the Content-Type: value appropriate for each.
  24  SDVA($UploadExts,array(
  25    'gif' => 'image/gif', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg',
  26    'png' => 'image/png', 'bmp' => 'image/bmp', 'ico' => 'image/x-icon',
  27    'wbmp'=> 'image/vnd.wap.wbmp', 'svg' => 'image/svg+xml', 'xcf' => 'image/x-xcf',
  28    'mp3' => 'audio/mpeg', 'au' => 'audio/basic', 'wav' => 'audio/x-wav',
  29    'ogg' => 'audio/ogg', 'flac' => 'audio/x-flac',
  30    'ogv' => 'video/ogg', 'mp4' => 'video/mp4', 'webm' => 'video/webm',
  31    'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg',
  32    'mov' => 'video/quicktime', 'qt' => 'video/quicktime',
  33    'wmf' => 'text/plain', 'avi' => 'video/x-msvideo',
  34    'zip' => 'application/zip', '7z' => 'application/x-7z-compressed',
  35    'gz' => 'application/x-gzip', 'tgz' => 'application/x-gzip',
  36    'rpm' => 'application/x-rpm', 
  37    'hqx' => 'application/mac-binhex40', 'sit' => 'application/x-stuffit',
  38    'doc' => 'application/msword', 'ppt' => 'application/vnd.ms-powerpoint',
  39    'xls' => 'application/vnd.ms-excel', 'mdb' => 'text/plain',
  40    'exe' => 'application/octet-stream',
  41    'pdf' => 'application/pdf', 'psd' => 'text/plain', 
  42    'ps' => 'application/postscript', 'ai' => 'application/postscript',
  43    'eps' => 'application/postscript',
  44    'htm' => 'text/html', 'html' => 'text/html', 'css' => 'text/css', 
  45    'fla' => 'application/x-shockwave-flash', 
  46    'swf' => 'application/x-shockwave-flash',
  47    'txt' => 'text/plain', 'rtf' => 'application/rtf', 
  48    'tex' => 'application/x-tex', 'dvi' => 'application/x-dvi',
  49    'odt' => 'application/vnd.oasis.opendocument.text',
  50    'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
  51    'odp' => 'application/vnd.oasis.opendocument.presentation',
  52    'odg' => 'application/vnd.oasis.opendocument.graphics',
  53    'epub'=> 'application/epub+zip',
  54    'kml' => 'application/vnd.google-earth.kml+xml',
  55    'kmz' => 'application/vnd.google-earth.kmz',
  56    '' => 'text/plain'));
  57  
  58  SDV($UploadMaxSize,50000);
  59  SDV($UploadPrefixQuota,0);
  60  SDV($UploadDirQuota,0);
  61  foreach($UploadExts as $k=>$v) 
  62    if (!isset($UploadExtSize[$k])) $UploadExtSize[$k]=$UploadMaxSize;
  63  
  64  SDV($UploadDir,'ext/cms/uploads');
  65  SDV($UploadPrefixFmt,'/$Group');
  66  SDV($UploadFileFmt,"$UploadDir$UploadPrefixFmt");
  67  $v = preg_replace('#^/(.*/)#', '', $UploadDir);
  68  SDV($UploadUrlFmt,preg_replace('#/[^/]*$#', "/$v", $PubDirUrl, 1));
  69  SDV($LinkUploadCreateFmt, "<a rel='nofollow' class='createlinktext' href='\$LinkUpload'>\$LinkText</a><a rel='nofollow' class='createlink' href='\$LinkUpload'>&nbsp;&Delta;</a>");
  70  SDVA($ActionTitleFmt, array('upload' => '| $[Attach]'));
  71  
  72  SDV($PageUploadFmt,array("
  73    <div id='wikiupload'>
  74    <h2 class='wikiaction'>$[Attachments for] {\$FullName}</h2>
  75    <h3>\$UploadResult</h3>
  76    <form enctype='multipart/form-data' action='{\$PageUrl}' method='post'>
  77    <input type='hidden' name='n' value='{\$FullName}' />
  78    <input type='hidden' name='action' value='postupload' />
  79    <table border='0'>
  80      <tr><td align='right'>$[File to upload:]</td><td><input
  81        name='uploadfile' type='file' /></td></tr>
  82      <tr><td align='right'>$[Name attachment as:]</td>
  83        <td><input type='text' name='upname' value='\$UploadName' /><input 
  84          type='submit' value=' $[Upload] ' /><br />
  85          </td></tr></table></form></div>",
  86    'wiki:$[{$SiteGroup}/UploadQuickReference]'));
  87  XLSDV('en',array(
  88    'ULsuccess' => 'successfully uploaded',
  89    'ULbadname' => 'invalid attachment name',
  90    'ULbadtype' => '\'$upext\' is not an allowed file extension',
  91    'ULtoobig' => 'file is larger than maximum allowed by webserver',
  92    'ULtoobigext' => 'file is larger than allowed maximum of $upmax
  93       bytes for \'$upext\' files',
  94    'ULpartial' => 'incomplete file received',
  95    'ULnofile' => 'no file uploaded',
  96    'ULexists' => 'file with that name already exists',
  97    'ULpquota' => 'group quota exceeded',
  98    'ULtquota' => 'upload quota exceeded'));
  99  SDV($PageAttributes['passwdupload'],'$[Set new upload password:]');
 100  SDV($DefaultPasswords['upload'],'*');
 101  SDV($AuthCascade['upload'], 'read');
 102  SDV($FmtPV['$PasswdUpload'], 'PasswdVar($pn, "upload")');
 103  
 104  Markup('attachlist', 'directives', 
 105    '/\\(:attachlist\\s*(.*?):\\)/ei',
 106    "Keep('<ul>'.FmtUploadList('$pagename',PSS('$1')).'</ul>')");
 107  SDV($GUIButtons['attach'], array(220, 'Attach:', '', '$[file.ext]',
 108    '$GUIButtonDirUrlFmt/attach.gif"$[Attach file]"'));
 109  SDV($LinkFunctions['Attach:'], 'LinkUpload');
 110  SDV($IMap['Attach:'], '$1');
 111  SDVA($HandleActions, array('upload' => 'HandleUpload',
 112    'postupload' => 'HandlePostUpload',
 113    'download' => 'HandleDownload'));
 114  SDVA($HandleAuth, array('upload' => 'upload',
 115    'download' => 'read'));
 116  SDV($HandleAuth['postupload'], $HandleAuth['upload']);
 117  SDV($UploadVerifyFunction, 'UploadVerifyBasic');
 118  
 119  function MakeUploadName($pagename,$x) {
 120    global $UploadNameChars, $MakeUploadNamePatterns;
 121    SDV($UploadNameChars, "-\\w. ");
 122    SDV($MakeUploadNamePatterns, array(
 123      "/[^$UploadNameChars]/" => '',
 124      '/\\.[^.]*$/e' => 'strtolower("$0")',
 125      '/^[^[:alnum:]_]+/' => '',
 126      '/[^[:alnum:]_]+$/' => ''));
 127     return preg_replace(array_keys($MakeUploadNamePatterns),
 128              array_values($MakeUploadNamePatterns), $x);
 129  }
 130  
 131  function LinkUpload($pagename, $imap, $path, $alt, $txt, $fmt=NULL) {
 132    global $FmtV, $UploadFileFmt, $LinkUploadCreateFmt, $UploadUrlFmt,
 133      $UploadPrefixFmt, $EnableDirectDownload;
 134    if (preg_match('!^(.*)/([^/]+)$!', $path, $match)) {
 135      $pagename = MakePageName($pagename, $match[1]);
 136      $path = $match[2];
 137    }
 138    $upname = MakeUploadName($pagename, $path);
 139    // tb
 140    $filepath = FmtPageName("$UploadUrlFmt/\$Group/$upname", $pagename);
 141    $FmtV['$LinkUpload'] = 
 142      FmtPageName("\$PageUrl?action=upload&amp;upname=$upname", $pagename);
 143    $FmtV['$LinkText'] = $txt;
 144  
 145  //  if (!file_exists($filepath)) 
 146  //    return FmtPageName($LinkUploadCreateFmt, $pagename);
 147  
 148    $path = PUE(pmwiki_url(FmtPageName(file_exists(sys_custom($filepath)) 
 149            ? "$UploadUrlFmt$UploadPrefixFmt/$upname"
 150            : "?page=$pagename&file=$upname",
 151            $pagename)));
 152  
 153    return LinkIMap($pagename, $imap, $path, $alt, $txt, $fmt);
 154  }
 155  
 156  # Authenticate group downloads with the group password
 157  function UploadAuth($pagename, $auth, $cache=0){
 158    global $GroupAttributesFmt, $EnableUploadGroupAuth;
 159    if (IsEnabled($EnableUploadGroupAuth,0)){
 160      SDV($GroupAttributesFmt,'$Group/GroupAttributes');
 161      $pn_upload = FmtPageName($GroupAttributesFmt, $pagename);
 162    } else $pn_upload = $pagename;
 163    $page = RetrieveAuthPage($pn_upload, $auth, true, READPAGE_CURRENT);
 164    if(!$page) Abort("?No '$auth' permissions for $pagename");
 165    if($cache) PCache($pn_upload,$page);
 166    return true;
 167  }
 168  
 169  function HandleUpload($pagename, $auth = 'upload') {
 170    global $FmtV,$UploadExtMax,
 171      $HandleUploadFmt,$PageStartFmt,$PageEndFmt,$PageUploadFmt;
 172    UploadAuth($pagename, $auth, 1);
 173    $FmtV['$UploadName'] = MakeUploadName($pagename,@$_REQUEST['upname']);
 174    $upresult = htmlspecialchars(@$_REQUEST['upresult']);
 175    $uprname = htmlspecialchars(@$_REQUEST['uprname']);
 176    $FmtV['$upext'] = htmlspecialchars(@$_REQUEST['upext']);
 177    $FmtV['$upmax'] = htmlspecialchars(@$_REQUEST['upmax']);
 178    $FmtV['$UploadResult'] = ($upresult) ?
 179      FmtPageName("<i>$uprname</i>: $[UL$upresult]",$pagename) : '';
 180    SDV($HandleUploadFmt,array(&$PageStartFmt,&$PageUploadFmt,&$PageEndFmt));
 181    PrintFmt($pagename,$HandleUploadFmt);
 182  }
 183  
 184  function HandleDownload($pagename, $auth = 'read') {
 185    global $UploadFileFmt, $UploadExts, $DownloadDisposition, $EnableIMSCaching;
 186    SDV($DownloadDisposition, "inline");
 187    UploadAuth($pagename, $auth);
 188    $upname = MakeUploadName($pagename, @$_REQUEST['upname']);
 189    $filepath = FmtPageName("$UploadFileFmt/$upname", $pagename);
 190    if (!$upname || !file_exists($filepath)) {
 191      header("HTTP/1.0 404 Not Found");
 192      Abort("?requested file not found");
 193      exit();
 194    }
 195    if (IsEnabled($EnableIMSCaching, 0)) {
 196      header('Cache-Control: private');
 197      header('Expires: ');
 198      $filelastmod = gmdate('D, d M Y H:i:s \G\M\T', filemtime($filepath));
 199      if (@$_SERVER['HTTP_IF_MODIFIED_SINCE'] == $filelastmod)
 200        { header("HTTP/1.0 304 Not Modified"); exit(); }
 201      header("Last-Modified: $filelastmod");
 202    }
 203    preg_match('/\\.([^.]+)$/',$filepath,$match); 
 204    if ($UploadExts[@$match[1]]) 
 205      header("Content-Type: {$UploadExts[@$match[1]]}");
 206    header("Content-Length: ".filesize($filepath));
 207    header("Content-disposition: $DownloadDisposition; filename=\"$upname\"");
 208    $fp = fopen($filepath, "rb");
 209    if ($fp) {
 210      while (!feof($fp)) echo fread($fp, 4096);
 211      flush();
 212      fclose($fp);
 213    }
 214    exit();
 215  }  
 216   
 217  function HandlePostUpload($pagename, $auth = 'upload') {
 218    global $UploadVerifyFunction, $UploadFileFmt, $LastModFile, 
 219      $EnableUploadVersions, $Now, $RecentUploadsFmt, $FmtV,
 220      $NotifyItemUploadFmt, $NotifyItemFmt, $IsUploadPosted,
 221      $UploadRedirectFunction;
 222    UploadAuth($pagename, $auth);
 223    $uploadfile = $_FILES['uploadfile'];
 224    $upname = $_REQUEST['upname'];
 225    if ($upname=='') $upname=$uploadfile['name'];
 226    $upname = MakeUploadName($pagename,$upname);
 227    if (!function_exists($UploadVerifyFunction))
 228      Abort('?no UploadVerifyFunction available');
 229    $filepath = FmtPageName("$UploadFileFmt/$upname",$pagename);
 230    $result = $UploadVerifyFunction($pagename,$uploadfile,$filepath);
 231    if ($result=='') {
 232      $filedir = preg_replace('#/[^/]*$#','',$filepath);
 233      mkdirp($filedir);
 234      if (IsEnabled($EnableUploadVersions, 0))
 235        @rename($filepath, "$filepath,$Now");
 236      if (!move_uploaded_file($uploadfile['tmp_name'],$filepath))
 237        { Abort("?cannot move uploaded file to $filepath"); return; }
 238      fixperms($filepath,0444);
 239      if ($LastModFile) { touch($LastModFile); fixperms($LastModFile); }
 240      $result = "upresult=success";
 241        $FmtV['$upname'] = $upname;
 242        $FmtV['$upsize'] = $uploadfile['size'];
 243      if (IsEnabled($RecentUploadsFmt, 0)) {
 244        PostRecentChanges($pagename, '', '', $RecentUploadsFmt);
 245      }
 246      if (IsEnabled($NotifyItemUploadFmt, 0) && function_exists('NotifyUpdate')) {
 247        $NotifyItemFmt = $NotifyItemUploadFmt;
 248        $IsUploadPosted = 1;
 249        register_shutdown_function('NotifyUpdate', $pagename, getcwd());
 250      }
 251    }
 252    SDV($UploadRedirectFunction, 'Redirect');
 253    $UploadRedirectFunction($pagename,"{\$PageUrl}?action=upload&uprname=$upname&$result");
 254  }
 255  
 256  function UploadVerifyBasic($pagename,$uploadfile,$filepath) {
 257    global $EnableUploadOverwrite,$UploadExtSize,$UploadPrefixQuota,
 258      $UploadDirQuota,$UploadDir;
 259    if (!$EnableUploadOverwrite && file_exists($filepath)) 
 260      return 'upresult=exists';
 261    preg_match('/\\.([^.\\/]+)$/',$filepath,$match); $ext=@$match[1];
 262    $maxsize = $UploadExtSize[$ext];
 263    if ($maxsize<=0) return "upresult=badtype&upext=$ext";
 264    if ($uploadfile['size']>$maxsize) 
 265      return "upresult=toobigext&upext=$ext&upmax=$maxsize";
 266    switch (@$uploadfile['error']) {
 267      case 1: return 'upresult=toobig';
 268      case 2: return 'upresult=toobig';
 269      case 3: return 'upresult=partial';
 270      case 4: return 'upresult=nofile';
 271    }
 272    if (!is_uploaded_file($uploadfile['tmp_name'])) return 'upresult=nofile';
 273    $filedir = preg_replace('#/[^/]*$#','',$filepath);
 274    if ($UploadPrefixQuota && 
 275        (dirsize($filedir)-@filesize($filepath)+$uploadfile['size']) >
 276          $UploadPrefixQuota) return 'upresult=pquota';
 277    if ($UploadDirQuota && 
 278        (dirsize($UploadDir)-@filesize($filepath)+$uploadfile['size']) >
 279          $UploadDirQuota) return 'upresult=tquota';
 280    return '';
 281  }
 282  
 283  function dirsize($dir) {
 284    $size = 0;
 285    $dirp = @opendir($dir);
 286    if (!$dirp) return 0;
 287    while (($file=readdir($dirp)) !== false) {
 288      if ($file[0]=='.') continue;
 289      if (is_dir("$dir/$file")) $size+=dirsize("$dir/$file");
 290      else $size+=filesize("$dir/$file");
 291    }
 292    closedir($dirp);
 293    return $size;
 294  }
 295  
 296  function FmtUploadList($pagename, $args) {
 297    global $UploadDir, $UploadPrefixFmt, $UploadUrlFmt, $EnableUploadOverwrite,
 298      $TimeFmt, $EnableDirectDownload;
 299  
 300    $opt = ParseArgs($args);
 301    if (@$opt[''][0]) $pagename = MakePageName($pagename, $opt[''][0]);
 302    if (@$opt['ext']) 
 303      $matchext = '/\\.(' 
 304        . implode('|', preg_split('/\\W+/', $opt['ext'], -1, PREG_SPLIT_NO_EMPTY))
 305        . ')$/i';
 306  
 307    $uploaddir = FmtPageName("$UploadDir$UploadPrefixFmt", $pagename);
 308    $uploadurl = FmtPageName(IsEnabled($EnableDirectDownload, 1) 
 309                            ? "$UploadUrlFmt$UploadPrefixFmt/"
 310                            : "\$PageUrl?action=download&amp;upname=",
 311                        $pagename);
 312  
 313    $dirp = @opendir($uploaddir);
 314    if (!$dirp) return '';
 315    $filelist = array();
 316    while (($file=readdir($dirp)) !== false) {
 317      if ($file{0} == '.') continue;
 318      if (@$matchext && !preg_match(@$matchext, $file)) continue;
 319      $filelist[$file] = $file;
 320    }
 321    closedir($dirp);
 322    $out = array();
 323    natcasesort($filelist);
 324    $overwrite = '';
 325    foreach($filelist as $file=>$x) {
 326      $name = PUE("$uploadurl$file");
 327      $stat = stat("$uploaddir/$file");
 328      if ($EnableUploadOverwrite) 
 329        $overwrite = FmtPageName("<a rel='nofollow' class='createlink'
 330          href='\$PageUrl?action=upload&amp;upname=$file'>&nbsp;&Delta;</a>", 
 331          $pagename);
 332      $out[] = "<li> <a href='$name'>$file</a>$overwrite ... ".
 333        number_format($stat['size']) . " bytes ... " . 
 334        strftime($TimeFmt, $stat['mtime']) . "</li>";
 335    }
 336    return implode("\n",$out);
 337  }
 338  
 339  # this adds (:if [!]attachments:) to the markup
 340  $Conditions['attachments'] = "AttachExist(\$pagename)";
 341  function AttachExist($pagename) {
 342    global $UploadDir, $UploadPrefixFmt;
 343    $uploaddir = FmtPageName("$UploadDir$UploadPrefixFmt", $pagename);
 344    $count = 0;
 345    $dirp = @opendir($uploaddir);
 346    if ($dirp) {
 347      while (($file = readdir($dirp)) !== false) 
 348        if ($file{0} != '.') $count++;
 349      closedir($dirp);
 350    }
 351    return $count;
 352  }

title

Description

title

Description

title

Description

title

title

Body