Open Monograph Press  1.1
 All Classes Namespaces Functions Variables Groups Pages
FileManager.inc.php
1 <?php
2 
23 define('FILE_MODE_MASK', 0666);
24 define('DIRECTORY_MODE_MASK', 0777);
25 
26 define('DOCUMENT_TYPE_DEFAULT', 'default');
27 define('DOCUMENT_TYPE_EXCEL', 'excel');
28 define('DOCUMENT_TYPE_HTML', 'html');
29 define('DOCUMENT_TYPE_IMAGE', 'image');
30 define('DOCUMENT_TYPE_PDF', 'pdf');
31 define('DOCUMENT_TYPE_WORD', 'word');
32 define('DOCUMENT_TYPE_ZIP', 'zip');
33 
34 class FileManager {
38  function FileManager() {
39  }
40 
46  function uploadedFileExists($fileName) {
47  if (isset($_FILES[$fileName]) && isset($_FILES[$fileName]['tmp_name'])
48  && is_uploaded_file($_FILES[$fileName]['tmp_name'])) {
49  return true;
50  }
51  return false;
52  }
53 
59  function uploadError($fileName) {
60  return (isset($_FILES[$fileName]) && $_FILES[$fileName]['error'] != 0);
61  }
62 
68  function getUploadedFilePath($fileName) {
69  if (isset($_FILES[$fileName]['tmp_name']) && is_uploaded_file($_FILES[$fileName]['tmp_name'])) {
70  return $_FILES[$fileName]['tmp_name'];
71  }
72  return false;
73  }
74 
80  function getUploadedFileName($fileName) {
81  if (isset($_FILES[$fileName]['name'])) {
82  return $_FILES[$fileName]['name'];
83  }
84  return false;
85  }
86 
92  function getUploadedFileType($fileName) {
93  if (isset($_FILES[$fileName])) {
94  $type = String::mime_content_type($_FILES[$fileName]['tmp_name']);
95  if (!empty($type)) return $type;
96  return $_FILES[$fileName]['type'];
97  }
98  return false;
99  }
100 
107  function uploadFile($fileName, $destFileName) {
108  $destDir = dirname($destFileName);
109  if (!$this->fileExists($destDir, 'dir')) {
110  // Try to create the destination directory
111  $this->mkdirtree($destDir);
112  }
113  if (!isset($_FILES[$fileName])) return false;
114  if (move_uploaded_file($_FILES[$fileName]['tmp_name'], $destFileName))
115  return $this->setMode($destFileName, FILE_MODE_MASK);
116  return false;
117  }
118 
125  function writeFile($dest, &$contents) {
126  $success = true;
127  $destDir = dirname($dest);
128  if (!$this->fileExists($destDir, 'dir')) {
129  // Try to create the destination directory
130  $this->mkdirtree($destDir);
131  }
132  if (($f = fopen($dest, 'wb'))===false) $success = false;
133  if ($success && fwrite($f, $contents)===false) $success = false;
134  @fclose($f);
135 
136  if ($success)
137  return $this->setMode($dest, FILE_MODE_MASK);
138  return false;
139  }
140 
147  function copyFile($source, $dest) {
148  $success = true;
149  $destDir = dirname($dest);
150  if (!$this->fileExists($destDir, 'dir')) {
151  // Try to create the destination directory
152  $this->mkdirtree($destDir);
153  }
154  if (copy($source, $dest))
155  return $this->setMode($dest, FILE_MODE_MASK);
156  return false;
157  }
158 
166  function copyDir($source, $dest) {
167  if (is_dir($source)) {
168  $this->mkdir($dest);
169  $destDir = dir($source);
170 
171  while (($entry = $destDir->read()) !== false) {
172  if ($entry == '.' || $entry == '..') {
173  continue;
174  }
175 
176  $Entry = $source . DIRECTORY_SEPARATOR . $entry;
177  if (is_dir($Entry) ) {
178  $this->copyDir($Entry, $dest . DIRECTORY_SEPARATOR . $entry );
179  continue;
180  }
181  $this->copyFile($Entry, $dest . DIRECTORY_SEPARATOR . $entry );
182  }
183 
184  $destDir->close();
185  } else {
186  $this->copyFile($source, $dest);
187  }
188 
189  if ($this->fileExists($dest, 'dir')) {
190  return true;
191  } else return false;
192  }
193 
194 
201  function readFile($filePath, $output = false) {
202  if (is_readable($filePath)) {
203  $f = fopen($filePath, 'rb');
204  $data = '';
205  while (!feof($f)) {
206  $data .= fread($f, 4096);
207  if ($output) {
208  echo $data;
209  $data = '';
210  }
211  }
212  fclose($f);
213 
214  if ($output) {
215  $returner = true;
216  return $returner;
217  } else {
218  return $data;
219  }
220 
221  } else {
222  $returner = false;
223  return $returner;
224  }
225  }
226 
235  function downloadFile($filePath, $mediaType = null, $inline = false, $fileName = null) {
236  $result = null;
237  if (HookRegistry::call('FileManager::downloadFile', array(&$filePath, &$mediaType, &$inline, &$result, &$fileName))) return $result;
238  $postDownloadHookList = array('FileManager::downloadFileFinished', 'UsageEventPlugin::getUsageEvent');
239  if (is_readable($filePath)) {
240  if ($mediaType === null) {
241  // If the media type wasn't specified, try to detect.
242  $mediaType = String::mime_content_type($filePath);
243  if (empty($mediaType)) $mediaType = 'application/octet-stream';
244  }
245  if ($fileName === null) {
246  // If the filename wasn't specified, use the server-side.
247  $fileName = basename($filePath);
248  }
249 
250  // Free some memory
251  $postDownloadHooks = null;
252  $hooks = HookRegistry::getHooks();
253  foreach ($postDownloadHookList as $hookName) {
254  if (isset($hooks[$hookName])) {
255  $postDownloadHooks[$hookName] = $hooks[$hookName];
256  }
257  }
258  unset($hooks);
259  Registry::clear();
260 
261  // Stream the file to the end user.
262  header("Content-Type: $mediaType");
263  header('Content-Length: ' . filesize($filePath));
264  header('Content-Disposition: ' . ($inline ? 'inline' : 'attachment') . "; filename=\"$fileName\"");
265  header('Cache-Control: private'); // Workarounds for IE weirdness
266  header('Pragma: public');
267 
268  // Beware of converting to instance call
269  // https://github.com/pkp/pkp-lib/commit/82f4a36db406ecac3eb88875541a74123e455713#commitcomment-1459396
270  FileManager::readFile($filePath, true);
271 
272  if ($postDownloadHooks) {
273  foreach ($postDownloadHooks as $hookName => $hooks) {
274  HookRegistry::setHooks($hookName, $hooks);
275  }
276  }
277  $returner = true;
278  } else {
279  $returner = false;
280  }
281  HookRegistry::call('FileManager::downloadFileFinished', array(&$returner));
282 
283  return $returner;
284  }
285 
291  function deleteFile($filePath) {
292  if ($this->fileExists($filePath)) {
293  return unlink($filePath);
294  } else {
295  return false;
296  }
297  }
298 
305  function mkdir($dirPath, $perms = null) {
306  if ($perms !== null) {
307  return mkdir($dirPath, $perms);
308  } else {
309  if (mkdir($dirPath))
310  return $this->setMode($dirPath, DIRECTORY_MODE_MASK);
311  return false;
312  }
313  }
314 
320  function rmdir($dirPath) {
321  return rmdir($dirPath);
322  }
323 
328  function rmtree($file) {
329  if (file_exists($file)) {
330  if (is_dir($file)) {
331  $handle = opendir($file);
332  while (($filename = readdir($handle)) !== false) {
333  if ($filename != '.' && $filename != '..') {
334  $this->rmtree($file . '/' . $filename);
335  }
336  }
337  closedir($handle);
338  rmdir($file);
339 
340  } else {
341  unlink($file);
342  }
343  }
344  }
345 
352  function mkdirtree($dirPath, $perms = null) {
353  if (!file_exists($dirPath)) {
354  if ($this->mkdirtree(dirname($dirPath), $perms)) {
355  return $this->mkdir($dirPath, $perms);
356  } else {
357  return false;
358  }
359  }
360  return true;
361  }
362 
368  function fileExists($filePath, $type = 'file') {
369  switch ($type) {
370  case 'file':
371  return file_exists($filePath);
372  case 'dir':
373  return file_exists($filePath) && is_dir($filePath);
374  default:
375  return false;
376  }
377  }
378 
384  function getDocumentType($type) {
385  if ($this->getImageExtension($type))
386  return DOCUMENT_TYPE_IMAGE;
387 
388  switch ($type) {
389  case 'application/pdf':
390  case 'application/x-pdf':
391  case 'text/pdf':
392  case 'text/x-pdf':
393  return DOCUMENT_TYPE_PDF;
394  case 'application/msword':
395  case 'application/word':
396  return DOCUMENT_TYPE_WORD;
397  case 'application/excel':
398  return DOCUMENT_TYPE_EXCEL;
399  case 'text/html':
400  return DOCUMENT_TYPE_HTML;
401  case 'application/zip':
402  case 'application/x-zip':
403  case 'application/x-zip-compressed':
404  case 'application/x-compress':
405  case 'application/x-compressed':
406  case 'multipart/x-zip':
407  return DOCUMENT_TYPE_ZIP;
408  default:
409  return DOCUMENT_TYPE_DEFAULT;
410  }
411  }
412 
418  function getDocumentExtension($type) {
419  switch ($type) {
420  case 'application/pdf':
421  return '.pdf';
422  case 'application/word':
423  return '.doc';
424  case 'text/html':
425  return '.html';
426  default:
427  return false;
428  }
429  }
430 
436  function getImageExtension($type) {
437  switch ($type) {
438  case 'image/gif':
439  return '.gif';
440  case 'image/jpeg':
441  case 'image/pjpeg':
442  return '.jpg';
443  case 'image/png':
444  case 'image/x-png':
445  return '.png';
446  case 'image/vnd.microsoft.icon':
447  case 'image/x-icon':
448  case 'image/x-ico':
449  case 'image/ico':
450  return '.ico';
451  case 'application/x-shockwave-flash':
452  return '.swf';
453  case 'video/x-flv':
454  case 'application/x-flash-video':
455  case 'flv-application/octet-stream':
456  return '.flv';
457  case 'audio/mpeg':
458  return '.mp3';
459  case 'audio/x-aiff':
460  return '.aiff';
461  case 'audio/x-wav':
462  return '.wav';
463  case 'video/mpeg':
464  return '.mpg';
465  case 'video/quicktime':
466  return '.mov';
467  case 'video/mp4':
468  return '.mp4';
469  case 'text/javascript':
470  return '.js';
471  default:
472  return false;
473  }
474  }
475 
481  function getExtension($fileName) {
482  $extension = '';
483  $fileParts = explode('.', $fileName);
484  if (is_array($fileParts)) {
485  $extension = $fileParts[count($fileParts) - 1];
486  }
487  return $extension;
488  }
489 
493  function truncateFileName($fileName, $length = 127) {
494  if (String::strlen($fileName) <= $length) return $fileName;
495  $ext = $this->getExtension($fileName);
496  $truncated = String::substr($fileName, 0, $length - 1 - String::strlen($ext)) . '.' . $ext;
497  return String::substr($truncated, 0, $length);
498  }
499 
505  function getNiceFileSize($size) {
506  $niceFileSizeUnits = array('B', 'KB', 'MB', 'GB');
507  for($i = 0; $i < 4 && $size > 1024; $i++) {
508  $size >>= 10;
509  }
510  return $size . $niceFileSizeUnits[$i];
511  }
512 
519  function setMode($path, $mask) {
520  $umask = Config::getVar('files', 'umask');
521  if (!$umask)
522  return true;
523  return chmod($path, $mask & ~$umask);
524  }
525 
531  function parseFileExtension($fileName) {
532  $fileParts = explode('.', $fileName);
533  if (is_array($fileParts)) {
534  $fileExtension = $fileParts[count($fileParts) - 1];
535  }
536 
537  // FIXME Check for evil
538  if (!isset($fileExtension) || stristr($fileExtension, 'php') || strlen($fileExtension) > 6 || !preg_match('/^\w+$/', $fileExtension)) {
539  $fileExtension = 'txt';
540  }
541 
542  return $fileExtension;
543  }
544 }
545 
546 ?>
static strlen($string)
Definition: String.inc.php:137
getNiceFileSize($size)
static substr($string, $start, $length=false)
Definition: String.inc.php:187
getDocumentExtension($type)
copyFile($source, $dest)
uploadError($fileName)
getExtension($fileName)
Class defining basic operations for file management.
mkdir($dirPath, $perms=null)
mkdirtree($dirPath, $perms=null)
static getVar($section, $key, $default=null)
Definition: Config.inc.php:35
rmdir($dirPath)
truncateFileName($fileName, $length=127)
static call($hookName, $args=null)
writeFile($dest, &$contents)
static mime_content_type($filename)
Definition: String.inc.php:412
getUploadedFilePath($fileName)
setMode($path, $mask)
getUploadedFileType($fileName)
deleteFile($filePath)
readFile($filePath, $output=false)
downloadFile($filePath, $mediaType=null, $inline=false, $fileName=null)
static setHooks($hookName, $callbacks)
getUploadedFileName($fileName)
uploadedFileExists($fileName)
static & getHooks()
getImageExtension($type)
parseFileExtension($fileName)
uploadFile($fileName, $destFileName)
getDocumentType($type)
fileExists($filePath, $type= 'file')
copyDir($source, $dest)