dir_path)) {
mkdir($this->dir_path,0755);
} else {
if ( fileperms($this->dir_path) != 0x4755 ) {
chmod($this->dir_path,0755);
}
}
}
protected static function finfo() {
if (!isset(self::$finfo)) {
self::$finfo = new finfo(FILEINFO_MIME, forge_get_config('libmagic_db', 'projectimport'));
}
return self::$finfo;
}
/**
* Constructor
* @param HTML generator $HTML
* @param string $storage_base path to the storage directory (if omitted, uses a temprary dir in /tmp)
*/
public function AbstractFilesDirectory($HTML, $storage_base=False) {
$this->html_generator = $HTML;
if (!isset(self::$finfo)) {
self::$finfo = new finfo(FILEINFO_MIME, forge_get_config('libmagic_db', 'projectimport'));
}
if(! $storage_base) {
$storage_base = tempnam("/tmp", "ff-projectimport");
}
$this->dir_path = $storage_base;
$this->createStorage();
}
/**
* Move a file on the server (typically an uploaded one) into the storage dir
* @param string $filename
* @param string $newfilename (optional) rename file on the fly
* @return boolean|string
*/
public function addFileMovingIt($filename, $newfilename=FALSE) {
if($newfilename) {
$newpath = $this->dir_path . $newfilename;
} else {
$newpath = $this->dir_path . basename($filename);
}
// do the move of the file
$ret = rename($filename, $newpath);
if (!$ret) {
$this->setError(sprintf(_('File %s cannot be moved to the storage location %s'), $filename, $newpath));
return false;
}
return $newpath;
}
/**
* Displays an HTML list of the directory contents
* @return string HTML
*/
public function displayContents() {
$html = '';
if (is_dir($this->dir_path)) {
// maybe use scandir instead ?
if ($dh = opendir($this->dir_path)) {
$html.='
';
while (($file = readdir($dh)) !== false) {
if ($file != '.' && $file != '..') {
$html.='- '.'filename: '. $file .': filetype: ' . filetype($this->dir_path . $file) . '
';
}
}
closedir($dh);
$html.='
';
}
}
return $html;
}
public function getMimeType($filepath) {
$finfo = self::finfo();
if (!$finfo) {
$this->setError(_('Opening fileinfo database failed'));
return false;
}
$mimetype = $finfo->file($filepath);
$mimetype = strstr($mimetype, ';', true);
// try to identify OpenDocument Package Zip container
if ($mimetype == 'application/octet-stream') {
$zip = new ZipArchive;
$res = $zip->open($filepath);
if ($res === TRUE) {
// if it has a mimetype file in the zip, then read its contents
$contents = $zip->getFromName('mimetype');
if($contents) {
$mimetype = $contents;
}
}
}
return $mimetype;
}
/**
* Returns an HTML box/table containing (single) file selection radio buttons
* @param string $preselected filename
* @return boolean|string
*/
public function displayFileSelectionForm($preselected = False) {
$html = '';
if (is_dir($this->dir_path)) {
$contents = scandir($this->dir_path);
if(count($contents) > 2) {
$html .= $this->html_generator->boxTop(_("Uploaded files available"));
$html .= '';
$html .= $this->html_generator->boxBottom();
}
}
return $html;
}
/**
* Returns the path given a SHA1 hash for a filename
* @param unknown_type $filesha1
* @return Ambigous
*/
public function getFilePath($filesha1) {
$filepath = False;
if (is_dir($this->dir_path)) {
$contents = scandir($this->dir_path);
foreach($contents as $file) {
if ($filesha1 == sha1($file)) {
$filepath = $this->dir_path . $file;
break;
}
}
}
return $filepath;
}
}
/**
* Specialized file storage management class for site-level files
*
* Files are stored inside $projectimport/storage_base (for instance '$core/data_path/plugins/projectimport/)
*
* @author Olivier Berger
*
*/
class SiteAdminFilesDirectory extends AbstractFilesDirectory {
public function SiteAdminFilesDirectory($HTML) {
$storage_base = forge_get_config('storage_base', 'projectimport');
parent::AbstractFilesDirectory($HTML, $storage_base);
}
}
/**
* Specialized file storage management class for project-level files
*
* Files are stored inside subdirs of $projectimport/storage_base (for instance '$core/data_path/plugins/projectimport/_projname_/)
*
* @author Olivier Berger
*
*/
class ProjectFilesDirectory extends AbstractFilesDirectory {
/**
* Constructor
* @param HTML generator $HTML
* @param integer $group_id
*/
public function ProjectFilesDirectory($HTML, $group_id) {
// store the project files inside a group unix name's subdir
$group = group_get_object($group_id);
$storage_base = forge_get_config('storage_base', 'projectimport');
$storage_base .= '/'. $group->getUnixName().'/';
parent::AbstractFilesDirectory($HTML, $storage_base);
}
}
/**
* Utility HTML display class for pages containing a file upload and selection form
*
* @author Olivier Berger
*
*/
class FileManagerPage {
/**
* filename of the selected file POSTed
* @var string
*/
protected $posted_selecteddumpfile;
/**
* filename of the uploaded file POSTed
* @var string
*/
protected $posted_uploadedfile;
protected $html_generator;
protected $message;
/**
* File storage
* @var AbstractFilesDirectory
*/
protected $storage;
/**
* Constructor
* @param HTML generator $HTML
* @param AbstractFilesDirectory $storage (optional)
*/
function FileManagerPage($HTML, $storage=False) {
$this->html_generator = $HTML;
$this->message = '';
// If specialized storage provided, then use it
if($storage) {
$this->storage = $storage;
} else {
// otherwise create one with temporary directory
$this->storage = new AbstractFilesDirectory($this->html_generator);
}
$this->posted_selecteddumpfile = False;
$this->posted_uploadedfile = False;
}
/**
* Adds a $feedback message
* @param string $message
*/
function feedback($message) {
global $feedback;
if ($feedback) $feedback .= '
';
$feedback .= $message;
}
/**
* Parses the POSTed data to initialize the $posted_selecteddumpfile and $posted_uploadedfile and returns selected file name (if any)
* @return Ambigous
*/
function initialize_chosenfile_from_submitted() {
$filechosen = FALSE;
$uploaded_file = getUploadedFile('uploaded_file');
//print_r($uploaded_file);
// process chosen file -> $filechosen set after this (or not)
if (getStringFromPost('submit_file')) {
$filesha1s = array();
foreach (array_keys($_POST) as $key) {
if(!strncmp($key, 'file_', 5)) {
$filesha1 = substr($key, 5);
$filesha1s[] = $filesha1;
}
}
if (count($filesha1s) > 1) {
$this->feedback(_('Please select only one file'));
} else {
if (count($filesha1s) == 1) {
$filechosen = $this->storage->getFilePath($filesha1s[0]);
if(!$filechosen) {
$this->feedback(_('File not found on server'));
}
}
}
}
// Process uploaded file : $this->posted_selecteddumpfile set afterwards (or not)
if($uploaded_file) {
// May use codendi's rules to check results of upload ?
//$rule_file = new Rule_File();
//if ($rule_file->isValid($uploaded_file)) {
if($uploaded_file['error'] == UPLOAD_ERR_OK ) {
if ($filechosen) {
$this->feedback(_('Please either select existing file OR upload new file'));
$filechosen = False;
}
else {
$imported_file = $uploaded_file['tmp_name'];
$imported_file = $this->storage->addFileMovingIt($imported_file, $uploaded_file['name']);
if(! $imported_file) {
$this->feedback($this->storage->getErrorMessage());
}
else {
$this->posted_uploadedfile = $uploaded_file['name'];
$this->message .= sprintf(_('File "%s" uploaded and pre-selected'),$this->posted_uploadedfile);
}
}
}
else {
$error_code = $uploaded_file['error'];
if ($error_code != UPLOAD_ERR_NO_FILE ) {
switch ($error_code) {
case UPLOAD_ERR_INI_SIZE:
$this->feedback(_('The uploaded file exceeds the upload_max_filesize directive in php.ini'));
case UPLOAD_ERR_FORM_SIZE:
$this->feedback(_('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form'));
case UPLOAD_ERR_PARTIAL:
$this->feedback(_('The uploaded file was only partially uploaded'));
/* case UPLOAD_ERR_NO_FILE:
return 'No file was uploaded';*/
case UPLOAD_ERR_NO_TMP_DIR:
$this->feedback(_('Missing a temporary folder'));
case UPLOAD_ERR_CANT_WRITE:
$this->feedback(_('Failed to write file to disk'));
case UPLOAD_ERR_EXTENSION:
$this->feedback(_('File upload stopped by extension'));
default:
$this->feedback(_('Unknown upload error %d', $error_code));
}
}
}
}
if($filechosen) {
$this->posted_selecteddumpfile = $filechosen;
}
return $filechosen;
}
}