PageRenderTime 27ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/ojs/ojs-2.3.0/lib/pkp/classes/file/FileManager.inc.php

https://github.com/mcrider/pkpUpgradeTestSuite
PHP | 451 lines | 261 code | 42 blank | 148 comment | 61 complexity | 6fcc9797523d0c17a42f6164ea600af7 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * @defgroup file
  4. */
  5. /**
  6. * @file classes/file/FileManager.inc.php
  7. *
  8. * Copyright (c) 2000-2009 John Willinsky
  9. * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
  10. *
  11. * @class FileManager
  12. * @ingroup file
  13. *
  14. * @brief Class defining basic operations for file management.
  15. */
  16. // $Id: FileManager.inc.php,v 1.10 2009/09/29 23:39:13 asmecher Exp $
  17. define('FILE_MODE_MASK', 0666);
  18. define('DIRECTORY_MODE_MASK', 0777);
  19. class FileManager {
  20. /**
  21. * Constructor
  22. */
  23. function FileManager() {
  24. }
  25. /**
  26. * Return true if an uploaded file exists.
  27. * @param $fileName string the name of the file used in the POST form
  28. * @return boolean
  29. */
  30. function uploadedFileExists($fileName) {
  31. if (isset($_FILES[$fileName]['tmp_name']) && is_uploaded_file($_FILES[$fileName]['tmp_name'])) {
  32. return true;
  33. }
  34. return false;
  35. }
  36. /**
  37. * Return true iff an error occurred when trying to upload a file.
  38. * @param $fileName string the name of the file used in the POST form
  39. * @return boolean
  40. */
  41. function uploadError($fileName) {
  42. return (isset($_FILES[$fileName]) && $_FILES[$fileName]['error'] != 0);
  43. }
  44. /**
  45. * Return the (temporary) path to an uploaded file.
  46. * @param $fileName string the name of the file used in the POST form
  47. * @return string (boolean false if no such file)
  48. */
  49. function getUploadedFilePath($fileName) {
  50. if (isset($_FILES[$fileName]['tmp_name']) && is_uploaded_file($_FILES[$fileName]['tmp_name'])) {
  51. return $_FILES[$fileName]['tmp_name'];
  52. }
  53. return false;
  54. }
  55. /**
  56. * Return the user-specific (not temporary) filename of an uploaded file.
  57. * @param $fileName string the name of the file used in the POST form
  58. * @return string (boolean false if no such file)
  59. */
  60. function getUploadedFileName($fileName) {
  61. if (isset($_FILES[$fileName]['name'])) {
  62. return $_FILES[$fileName]['name'];
  63. }
  64. return false;
  65. }
  66. /**
  67. * Return the type of an uploaded file.
  68. * @param $fileName string the name of the file used in the POST form
  69. * @return string
  70. */
  71. function getUploadedFileType($fileName) {
  72. if (isset($_FILES[$fileName])) {
  73. $type = String::mime_content_type($_FILES[$fileName]['tmp_name']);
  74. if (!empty($type)) return $type;
  75. return $_FILES[$fileName]['type'];
  76. }
  77. return false;
  78. }
  79. /**
  80. * Upload a file.
  81. * @param $fileName string the name of the file used in the POST form
  82. * @param $dest string the path where the file is to be saved
  83. * @return boolean returns true if successful
  84. */
  85. function uploadFile($fileName, $destFileName) {
  86. $destDir = dirname($destFileName);
  87. if (!FileManager::fileExists($destDir, 'dir')) {
  88. // Try to create the destination directory
  89. FileManager::mkdirtree($destDir);
  90. }
  91. if (!isset($_FILES[$fileName])) return false;
  92. if (move_uploaded_file($_FILES[$fileName]['tmp_name'], $destFileName))
  93. return FileManager::setMode($destFileName, FILE_MODE_MASK);
  94. return false;
  95. }
  96. /**
  97. * Write a file.
  98. * @param $dest string the path where the file is to be saved
  99. * @param $contents string the contents to write to the file
  100. * @return boolean returns true if successful
  101. */
  102. function writeFile($dest, &$contents) {
  103. $success = true;
  104. $destDir = dirname($dest);
  105. if (!FileManager::fileExists($destDir, 'dir')) {
  106. // Try to create the destination directory
  107. FileManager::mkdirtree($destDir);
  108. }
  109. if (($f = fopen($dest, 'wb'))===false) $success = false;
  110. if ($success && fwrite($f, $contents)===false) $success = false;
  111. @fclose($f);
  112. if ($success)
  113. return FileManager::setMode($dest, FILE_MODE_MASK);
  114. return false;
  115. }
  116. /**
  117. * Copy a file.
  118. * @param $source string the source URL for the file
  119. * @param $dest string the path where the file is to be saved
  120. * @return boolean returns true if successful
  121. */
  122. function copyFile($source, $dest) {
  123. $success = true;
  124. $destDir = dirname($dest);
  125. if (!FileManager::fileExists($destDir, 'dir')) {
  126. // Try to create the destination directory
  127. FileManager::mkdirtree($destDir);
  128. }
  129. if (copy($source, $dest))
  130. return FileManager::setMode($dest, FILE_MODE_MASK);
  131. return false;
  132. }
  133. /**
  134. * Read a file's contents.
  135. * @param $filePath string the location of the file to be read
  136. * @param $output boolean output the file's contents instead of returning a string
  137. * @return boolean
  138. */
  139. function &readFile($filePath, $output = false) {
  140. if (is_readable($filePath)) {
  141. $f = fopen($filePath, 'rb');
  142. $data = '';
  143. while (!feof($f)) {
  144. $data .= fread($f, 4096);
  145. if ($output) {
  146. echo $data;
  147. $data = '';
  148. }
  149. }
  150. fclose($f);
  151. if ($output) {
  152. $returner = true;
  153. return $returner;
  154. } else {
  155. return $data;
  156. }
  157. } else {
  158. $returner = false;
  159. return $returner;
  160. }
  161. }
  162. /**
  163. * Download a file.
  164. * Outputs HTTP headers and file content for download
  165. * @param $filePath string the location of the file to be sent
  166. * @param $type string the MIME type of the file, optional
  167. * @param $inline print file as inline instead of attachment, optional
  168. * @return boolean
  169. */
  170. function downloadFile($filePath, $type = null, $inline = false) {
  171. $result = null;
  172. if (HookRegistry::call('FileManager::downloadFile', array(&$filePath, &$type, &$inline, &$result))) return $result;
  173. if (is_readable($filePath)) {
  174. if ($type == null) {
  175. $type = String::mime_content_type($filePath);
  176. if (empty($type)) $type = 'application/octet-stream';
  177. }
  178. Registry::clear(); // Free some memory
  179. header("Content-Type: $type");
  180. header("Content-Length: ".filesize($filePath));
  181. header("Content-Disposition: " . ($inline ? 'inline' : 'attachment') . "; filename=\"" .basename($filePath)."\"");
  182. header("Cache-Control: private"); // Workarounds for IE weirdness
  183. header("Pragma: public");
  184. import('file.FileManager');
  185. FileManager::readFile($filePath, true);
  186. return true;
  187. } else {
  188. return false;
  189. }
  190. }
  191. /**
  192. * View a file inline (variant of downloadFile).
  193. * @see FileManager::downloadFile
  194. */
  195. function viewFile($filePath, $type = null) {
  196. FileManager::downloadFile($filePath, $type, true);
  197. }
  198. /**
  199. * Delete a file.
  200. * @param $filePath string the location of the file to be deleted
  201. * @return boolean returns true if successful
  202. */
  203. function deleteFile($filePath) {
  204. if (FileManager::fileExists($filePath)) {
  205. return unlink($filePath);
  206. } else {
  207. return false;
  208. }
  209. }
  210. /**
  211. * Create a new directory.
  212. * @param $dirPath string the full path of the directory to be created
  213. * @param $perms string the permissions level of the directory (optional)
  214. * @return boolean returns true if successful
  215. */
  216. function mkdir($dirPath, $perms = null) {
  217. if ($perms !== null) {
  218. return mkdir($dirPath, $perms);
  219. } else {
  220. if (mkdir($dirPath))
  221. return FileManager::setMode($dirPath, DIRECTORY_MODE_MASK);
  222. return false;
  223. }
  224. }
  225. /**
  226. * Remove a directory.
  227. * @param $dirPath string the full path of the directory to be delete
  228. * @return boolean returns true if successful
  229. */
  230. function rmdir($dirPath) {
  231. return rmdir($dirPath);
  232. }
  233. /**
  234. * Delete all contents including directory (equivalent to "rm -r")
  235. * @param $file string the full path of the directory to be removed
  236. */
  237. function rmtree($file) {
  238. if (file_exists($file)) {
  239. if (is_dir($file)) {
  240. $handle = opendir($file);
  241. import('file.FileManager');
  242. while (($filename = readdir($handle)) !== false) {
  243. if ($filename != '.' && $filename != '..') {
  244. FileManager::rmtree($file . '/' . $filename);
  245. }
  246. }
  247. closedir($handle);
  248. rmdir($file);
  249. } else {
  250. unlink($file);
  251. }
  252. }
  253. }
  254. /**
  255. * Create a new directory, including all intermediate directories if required (equivalent to "mkdir -p")
  256. * @param $dirPath string the full path of the directory to be created
  257. * @param $perms string the permissions level of the directory (optional)
  258. * @return boolean returns true if successful
  259. */
  260. function mkdirtree($dirPath, $perms = null) {
  261. if (!file_exists($dirPath)) {
  262. if (FileManager::mkdirtree(dirname($dirPath), $perms)) {
  263. return FileManager::mkdir($dirPath, $perms);
  264. } else {
  265. return false;
  266. }
  267. }
  268. return true;
  269. }
  270. /**
  271. * Check if a file path is valid;
  272. * @param $filePath string the file/directory to check
  273. * @param $type string (file|dir) the type of path
  274. */
  275. function fileExists($filePath, $type = 'file') {
  276. switch ($type) {
  277. case 'file':
  278. return file_exists($filePath);
  279. case 'dir':
  280. return file_exists($filePath) && is_dir($filePath);
  281. default:
  282. return false;
  283. }
  284. }
  285. /**
  286. * Returns file extension associated with the given document type,
  287. * or false if the type does not belong to a recognized document type.
  288. * @param $type string
  289. */
  290. function getDocumentExtension($type) {
  291. switch ($type) {
  292. case 'application/pdf':
  293. return '.pdf';
  294. case 'application/word':
  295. return '.doc';
  296. case 'text/html':
  297. return '.html';
  298. default:
  299. return false;
  300. }
  301. }
  302. /**
  303. * Returns file extension associated with the given image type,
  304. * or false if the type does not belong to a recognized image type.
  305. * @param $type string
  306. */
  307. function getImageExtension($type) {
  308. switch ($type) {
  309. case 'image/gif':
  310. return '.gif';
  311. case 'image/jpeg':
  312. case 'image/pjpeg':
  313. return'.jpg';
  314. case 'image/png':
  315. case 'image/x-png':
  316. return '.png';
  317. case 'image/vnd.microsoft.icon':
  318. case 'image/x-icon':
  319. case 'image/ico':
  320. return '.ico';
  321. case 'application/x-shockwave-flash':
  322. return '.swf';
  323. case 'video/x-flv':
  324. case 'application/x-flash-video':
  325. case 'flv-application/octet-stream':
  326. case 'application/octet-stream':
  327. return '.flv';
  328. case 'audio/mpeg':
  329. return '.mp3';
  330. case 'audio/x-aiff':
  331. return '.aiff';
  332. case 'audio/x-wav':
  333. return '.wav';
  334. case 'video/mpeg':
  335. return '.mpg';
  336. case 'video/quicktime':
  337. return '.mov';
  338. case 'video/mp4':
  339. return '.mp4';
  340. case 'text/javascript':
  341. return '.js';
  342. default:
  343. return false;
  344. }
  345. }
  346. /**
  347. * Parse file extension from file name.
  348. * @param string a valid file name
  349. * @return string extension
  350. */
  351. function getExtension($fileName) {
  352. $extension = '';
  353. $fileParts = explode('.', $fileName);
  354. if (is_array($fileParts)) {
  355. $extension = $fileParts[count($fileParts) - 1];
  356. }
  357. return $extension;
  358. }
  359. /**
  360. * Truncate a filename to fit in the specified length.
  361. */
  362. function truncateFileName($fileName, $length = 127) {
  363. if (String::strlen($fileName) <= $length) return $fileName;
  364. $ext = FileManager::getExtension($fileName);
  365. $truncated = String::substr($fileName, 0, $length - 1 - String::strlen($ext)) . '.' . $ext;
  366. return String::substr($truncated, 0, $length);
  367. }
  368. /**
  369. * Return pretty file size string (in B, KB, MB, or GB units).
  370. * @param $size int file size in bytes
  371. * @return string
  372. */
  373. function getNiceFileSize($size) {
  374. $niceFileSizeUnits = array('B', 'KB', 'MB', 'GB');
  375. for($i = 0; $i < 4 && $size > 1024; $i++) {
  376. $size >>= 10;
  377. }
  378. return $size . $niceFileSizeUnits[$i];
  379. }
  380. /**
  381. * Set file/directory mode based on the 'umask' config setting.
  382. * @param $path string
  383. * @param $mask int
  384. * @return boolean
  385. */
  386. function setMode($path, $mask) {
  387. $umask = Config::getVar('files', 'umask');
  388. if (!$umask)
  389. return true;
  390. return chmod($path, $mask & ~$umask);
  391. }
  392. /**
  393. * Parse the file extension from a filename/path.
  394. * @param $fileName string
  395. * @return string
  396. */
  397. function parseFileExtension($fileName) {
  398. $fileParts = explode('.', $fileName);
  399. if (is_array($fileParts)) {
  400. $fileExtension = $fileParts[count($fileParts) - 1];
  401. }
  402. // FIXME Check for evil
  403. if (!isset($fileExtension) || strstr($fileExtension, 'php') || strlen($fileExtension) > 6 || !preg_match('/^\w+$/', $fileExtension)) {
  404. $fileExtension = 'txt';
  405. }
  406. return $fileExtension;
  407. }
  408. }
  409. ?>