diff --git a/codepot/src/codepot/controllers/file.php b/codepot/src/codepot/controllers/file.php index 229e324e..2cab968d 100644 --- a/codepot/src/codepot/controllers/file.php +++ b/codepot/src/codepot/controllers/file.php @@ -404,7 +404,7 @@ class File extends Controller if (strpos($_FILES[$fid]['name'], ':') !== FALSE || strpos($_FILES[$fid]['name'], '/') !== FALSE) { - /* for wiki */ + // prevents these letters for wiki creole $status = "error - colon or slash not allowed - {$_FILES[$fid]['name']}"; break; } @@ -435,6 +435,172 @@ class File extends Controller print $status; } + function xhr_add_file ($projectid = '', $name = '') + { + $this->load->model ('ProjectModel', 'projects'); + $this->load->model ('FileModel', 'files'); + $this->load->library ('upload'); + + $login = $this->login->getUser (); + $revision_saved = -1; + + if ($login['id'] == '') + { + $status = 'error - anonymous user'; + } + else + { + $name = $this->converter->HexToAscii ($name); + + $project = $this->projects->get ($projectid); + if ($project === FALSE) + { + $status = "error - failed to get the project {$projectid}"; + } + else if ($project === NULL) + { + $status = "error - no such project {$projectid}"; + } + else if (!$login['sysadmin?'] && + $this->projects->projectHasMember($projectid, $login['id']) === FALSE) + { + $status = "error - not a member {$login['id']}"; + } + else + { + $post_add_file_count = $this->input->post('file_add_file_count'); + if ($post_add_file_count === FALSE || $post_add_file_count <= 0) $post_add_file_count = 0; + + $status = ''; + $add_files = array (); + for ($i = 0; $i < $post_add_file_count; $i++) + { + $fid = "file_add_file_{$i}"; + if (array_key_exists($fid, $_FILES) && $_FILES[$fid]['name'] != '') + { + $d = $this->input->post("file_add_file_desc_{$i}"); + if ($d === FALSE || ($d = trim($d)) == '') + { + $status = "error - no short description for {$_FILES[$fid]['name']}"; + break; + } + + if (strpos($_FILES[$fid]['name'], ':') !== FALSE || + strpos($_FILES[$fid]['name'], '/') !== FALSE) + { + // prevents these letters for wiki creole + $status = "error - colon or slash not allowed - {$_FILES[$fid]['name']}"; + break; + } + + array_push ($add_files, array ('fid' => $fid, 'name' => $_FILES[$fid]['name'], 'desc' => $d)); + } + } + + if ($status == '') + { + if (count($add_files) <= 0) + { + $status = 'error - no files uploaded'; + } + else if ($this->files->addFiles ($login['id'], $projectid, $name, $add_files, $this->upload) === FALSE) + { + $status = 'error - ' . $this->files->getErrorMessage(); + } + else + { + $status = 'ok'; + } + } + } + } + + print $status; + } + + function xhr_edit_file ($projectid = '', $name = '') + { + $this->load->model ('ProjectModel', 'projects'); + $this->load->model ('FileModel', 'files'); + + $login = $this->login->getUser (); + $revision_saved = -1; + + if ($login['id'] == '') + { + $status = 'error - anonymous user'; + } + else + { + $name = $this->converter->HexToAscii ($name); + + $project = $this->projects->get ($projectid); + if ($project === FALSE) + { + $status = "error - failed to get the project {$projectid}"; + } + else if ($project === NULL) + { + $status = "error - no such project {$projectid}"; + } + else if (!$login['sysadmin?'] && + $this->projects->projectHasMember($projectid, $login['id']) === FALSE) + { + $status = "error - not a member {$login['id']}"; + } + else + { + $post_edit_file_count = $this->input->post('file_edit_file_count'); + if ($post_edit_file_count === FALSE || $post_edit_file_count <= 0) $post_edit_file_count = 0; + + $status = ''; + $edit_files = array (); + for ($i = 0; $i < $post_edit_file_count; $i++) + { + $n = $this->input->post("file_edit_file_name_{$i}"); + $k = $this->input->post("file_edit_file_kill_{$i}"); + $d = $this->input->post("file_edit_file_desc_{$i}"); + + if ($n != '') + { + if ($k == 'yes') + { + array_push ($edit_files, array ('name' => $n, 'kill' => $k)); + } + else if ($d !== FALSE) + { + if (($d = trim($d)) == '') + { + $status = "error - no short description for {$n}"; + break; + } + + array_push ($edit_files, array ('name' => $n, 'desc' => $d)); + } + } + } + + if ($status == '') + { + if (count($edit_files) <= 0) + { + //$status = 'error - no input avaialble'; + $status = 'ok'; + } + else if ($this->files->editFiles ($login['id'], $projectid, $name, $edit_files) === FALSE) + { + $status = 'error - ' . $this->files->getErrorMessage(); + } + else + { + $status = 'ok'; + } + } + } + } + + print $status; + } function xhr_delete ($projectid = '', $name = '') { diff --git a/codepot/src/codepot/models/filemodel.php b/codepot/src/codepot/models/filemodel.php index 03171ea3..35e65380 100644 --- a/codepot/src/codepot/models/filemodel.php +++ b/codepot/src/codepot/models/filemodel.php @@ -139,7 +139,6 @@ class FileModel extends Model { $this->db->trans_start (); - /* $this->db->where ('projectid', $projectid); $this->db->where ('name', $name); $this->db->set ('name', $file->name); @@ -149,7 +148,9 @@ class FileModel extends Model $this->db->set ('updatedby', $userid); $this->db->update ('file'); // file_list gets updated for the schema itself (reference/trigger) - */ + /* + // this way of updating is bad in that it won't update info + // if there is no file items in file_list for the target file. $this->db->where ('f.projectid', $projectid); $this->db->where ('f.name', $name); $this->db->where ('f.projectid = fl.projectid'); @@ -161,6 +162,7 @@ class FileModel extends Model $this->db->set ('f.updatedby', $userid); $this->db->set ('fl.name', $file->name); $this->db->update ('file as f, file_list as fl'); + */ $this->db->set ('createdon', date('Y-m-d H:i:s')); $this->db->set ('type', 'file'); @@ -366,6 +368,178 @@ class FileModel extends Model restore_error_handler (); return $x; } + + private function _add_files ($userid, $projectid, $name, $import_files, $uploader) + { + $this->db->trans_begin (); // manual transaction. not using trans_start(). + + $config['allowed_types'] = '*'; + $config['upload_path'] = CODEPOT_FILE_DIR; + $config['max_size'] = CODEPOT_MAX_UPLOAD_SIZE; + $config['encrypt_name'] = TRUE; + $config['overwrite'] = FALSE; + $config['remove_spaces'] = FALSE; + $uploader->initialize ($config); + + $ok_files = array(); + $file_count = count($import_files); + for ($i = 0; $i < $file_count; $i++) + { + $f = $import_files[$i]; + if (!$uploader->do_upload($f['fid'])) + { + $this->errmsg = "Failed to upload {$f['name']}"; + $this->db->trans_rollback (); + $this->delete_all_files ($ok_files); + return FALSE; + } + + $ud = $uploader->data(); + array_push ($ok_files, $ud['full_path']); + + $md5sum = @md5_file ($ud['full_path']); + if ($md5sum === FALSE) + { + $this->db->trans_rollback (); + $this->delete_all_files ($ok_files); + return FALSE; + } + + $this->db->set ('projectid', $projectid); + $this->db->set ('name', $name); + $this->db->set ('filename', $f['name']); + $this->db->set ('encname', $ud['file_name']); + + $this->db->set ('md5sum', $md5sum); + $this->db->set ('description', $f['desc']); + $this->db->insert ('file_list'); + if ($this->db->trans_status() === FALSE) + { + $this->errmsg = $this->db->_error_message(); + $this->db->trans_rollback (); + $this->delete_all_files ($ok_files); + return FALSE; + } + } + + $this->db->set ('createdon', date('Y-m-d H:i:s')); + $this->db->set ('type', 'file'); + $this->db->set ('action', 'update'); + $this->db->set ('projectid', $projectid); + $this->db->set ('userid', $userid); + $this->db->set ('message', $name); + $this->db->insert ('log'); + + if ($this->db->trans_status() === FALSE) + { + $this->errmsg = $this->db->_error_message(); + $this->db->trans_rollback (); + $this->delete_all_files ($ok_files); + return FALSE; + } + + $this->db->trans_commit (); + return TRUE; + } + + function addFiles ($userid, $projectid, $name, $import_files, $uploader) + { + set_error_handler (array ($this, 'capture_error')); + $errmsg = ''; + $x = $this->_add_files ($userid, $projectid, $name, $import_files, $uploader); + restore_error_handler (); + return $x; + } + + private function _edit_files ($userid, $projectid, $name, $edit_files) + { + $this->db->trans_begin (); // manual transaction. not using trans_start(). + + $kill_files = array(); + $file_count = count($edit_files); + for ($i = 0; $i < $file_count; $i++) + { + $f = $edit_files[$i]; + + if (array_key_exists('kill', $f)) + { + $this->db->where ('projectid', $projectid); + $this->db->where ('name', $name); + $this->db->where ('filename', $f['name']); + $this->db->select ('encname'); + $query = $this->db->get('file_list'); + if ($this->db->trans_status() === FALSE) + { + $this->errmsg = $this->db->_error_message(); + $this->db->trans_rollback (); + return FALSE; + } + + $result = $query->result (); + if (empty($result)) + { + $this->errmsg = "no such file - {$f['name']}"; + $this->db->trans_rollback (); + return FALSE; + } + + array_push ($kill_files, CODEPOT_FILE_DIR . '/' . $result[0]->encname); + + $this->db->where ('projectid', $projectid); + $this->db->where ('name', $name); + $this->db->where ('filename', $f['name']); + $query = $this->db->delete('file_list'); + if ($this->db->trans_status() === FALSE) + { + $this->errmsg = $this->db->_error_message(); + $this->db->trans_rollback (); + return FALSE; + } + } + else if (array_key_exists('desc', $f)) + { + $this->db->where ('projectid', $projectid); + $this->db->where ('name', $name); + $this->db->where ('filename', $f['name']); + $this->db->set ('description', $f['desc']); + $this->db->update ('file_list'); + if ($this->db->trans_status() === FALSE) + { + $this->errmsg = $this->db->_error_message(); + $this->db->trans_rollback (); + return FALSE; + } + } + } + + $this->db->set ('createdon', date('Y-m-d H:i:s')); + $this->db->set ('type', 'file'); + $this->db->set ('action', 'update'); + $this->db->set ('projectid', $projectid); + $this->db->set ('userid', $userid); + $this->db->set ('message', $name); + $this->db->insert ('log'); + + if ($this->db->trans_status() === FALSE) + { + $this->errmsg = $this->db->_error_message(); + $this->db->trans_rollback (); + return FALSE; + } + + $this->delete_all_files ($kill_files); + $this->db->trans_commit (); + return TRUE; + } + + function editFiles ($userid, $projectid, $name, $edit_files) + { + set_error_handler (array ($this, 'capture_error')); + $errmsg = ''; + $x = $this->_edit_files ($userid, $projectid, $name, $edit_files); + restore_error_handler (); + return $x; + } } ?> diff --git a/codepot/src/codepot/views/file_home.php b/codepot/src/codepot/views/file_home.php index 1c4c5c78..751fa1a5 100644 --- a/codepot/src/codepot/views/file_home.php +++ b/codepot/src/codepot/views/file_home.php @@ -53,7 +53,6 @@ function render_wiki(input_text) prettyPrint (); } -var new_item_no = 0; var import_in_progress = false; var populated_file_obj = []; var populated_file_max = 0; @@ -108,8 +107,6 @@ $(function () { - new_item_no = 0; - $('#file_home_mainarea_new_files').change (function () { populate_selected_files (); }); @@ -344,15 +341,12 @@ else $file_list_count = count($file->file_list); - for ($i = 0; $i < $file_list_count; $i++) + if ($file_list_count <= 0) { print "