PageRenderTime 59ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/wiki/scripts/upload.php

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