improved the issue show view to manipulate attached files
This commit is contained in:
parent
e88ccc1a9b
commit
e409324188
@ -103,14 +103,17 @@ CREATE TABLE "cpot_issue" (
|
||||
CREATE INDEX cpot_issue_index_1 ON "cpot_issue"("projectid", "status", "type", "summary");
|
||||
CREATE INDEX cpot_issue_index_2 ON "cpot_issue"("projectid", "summary");
|
||||
|
||||
CREATE TABLE "cpot_issue_attachment" (
|
||||
CREATE TABLE "cpot_issue_file_list" (
|
||||
"projectid" VARCHAR(32) NOT NULL,
|
||||
"issueid" NUMBER(20,0) NOT NULL,
|
||||
"name" VARCHAR(255) NOT NULL,
|
||||
"filename" VARCHAR(255) NOT NULL,
|
||||
"encname" VARCHAR(255) NOT NULL,
|
||||
"md5sum" CHAR(32) NOT NULL,
|
||||
"description" CLOB NOT NULL,
|
||||
"createdon" TIMESTAMP NOT NULL,
|
||||
"createdby" VARCHAR(32) NOT NULL,
|
||||
UNIQUE ("projectid", "issueid", "name"),
|
||||
UNIQUE ("projectid", "issueid", "filename"),
|
||||
UNIQUE ("encname"),
|
||||
CONSTRAINT issue_attachment_projectid FOREIGN KEY ("projectid") REFERENCES "cpot_project"("id"),
|
||||
CONSTRAINT issue_attachment_issueid FOREIGN KEY ("projectid","issueid") REFERENCES "cpot_issue"("projectid","id")
|
||||
);
|
||||
@ -242,7 +245,7 @@ END;
|
||||
|
||||
CREATE OR REPLACE TRIGGER cpot_upon_issue_id_update AFTER UPDATE OF "id" ON "cpot_issue" FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE "cpot_issue_attachment" SET "issueid" = :new."id" WHERE "projectid" = :old."projectid" AND "issueid" = :old."id";
|
||||
UPDATE "cpot_issue_file_list" SET "issueid" = :new."id" WHERE "projectid" = :old."projectid" AND "issueid" = :old."id";
|
||||
UPDATE "cpot_issue_change" SET "id" = :new."id" WHERE "projectid" = :old."projectid" AND "id" = :old."id";
|
||||
UPDATE "cpot_issue_change_attachment" SET "issueid" = :new."id" WHERE "projectid" = :old."projectid" AND "issueid" = :old."id";
|
||||
END;
|
||||
|
@ -135,6 +135,27 @@ CREATE TABLE issue_attachment (
|
||||
ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE issue_file_list (
|
||||
projectid VARCHAR(32) NOT NULL,
|
||||
issueid BIGINT NOT NULL,
|
||||
filename VARCHAR(255) NOT NULL,
|
||||
encname VARCHAR(255) NOT NULL,
|
||||
md5sum CHAR(32) NOT NULL,
|
||||
description VARCHAR(255) NOT NULL,
|
||||
|
||||
createdon DATETIME NOT NULL,
|
||||
createdby VARCHAR(32) NOT NULL,
|
||||
|
||||
UNIQUE (projectid, issueid, filename),
|
||||
UNIQUE (encname),
|
||||
|
||||
CONSTRAINT issue_file_list_projectid FOREIGN KEY (projectid) REFERENCES project(id)
|
||||
ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
|
||||
CONSTRAINT issue_file_list_issueid FOREIGN KEY (projectid,issueid) REFERENCES issue(projectid,id)
|
||||
ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE issue_change (
|
||||
projectid VARCHAR(32) NOT NULL,
|
||||
id BIGINT NOT NULL,
|
||||
|
@ -257,6 +257,8 @@ class Issue extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
DEPRECATED
|
||||
function _edit_issue ($projectid, $hexid, $mode)
|
||||
{
|
||||
$this->load->helper ('form');
|
||||
@ -414,6 +416,7 @@ class Issue extends Controller
|
||||
return $this->_edit_issue ($projectid, $hexid, 'update');
|
||||
}
|
||||
|
||||
|
||||
function delete ($projectid = '', $hexid = '')
|
||||
{
|
||||
$this->load->helper ('form');
|
||||
@ -516,6 +519,7 @@ class Issue extends Controller
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
function xhr_create ($projectid = '')
|
||||
{
|
||||
@ -609,7 +613,7 @@ class Issue extends Controller
|
||||
|
||||
if ($status == '')
|
||||
{
|
||||
if ($this->issues->create_with_files ($login['id'], $issue, $attached_files, $this->upload) === FALSE)
|
||||
if ($this->issues->createWithFiles ($login['id'], $issue, $attached_files, $this->upload) === FALSE)
|
||||
{
|
||||
$status = 'error - ' . $this->issues->getErrorMessage();
|
||||
}
|
||||
@ -681,7 +685,7 @@ class Issue extends Controller
|
||||
|
||||
if ($status == '')
|
||||
{
|
||||
if ($this->issues->update_summary_and_description ($login['id'], $issue) === FALSE)
|
||||
if ($this->issues->updateSummaryAndDescription ($login['id'], $issue) === FALSE)
|
||||
{
|
||||
$status = 'error - ' . $this->issues->getErrorMessage();
|
||||
}
|
||||
@ -697,6 +701,223 @@ class Issue extends Controller
|
||||
print $status;
|
||||
}
|
||||
|
||||
function xhr_delete ($projectid = '', $issueid = '')
|
||||
{
|
||||
$this->load->model ('ProjectModel', 'projects');
|
||||
$this->load->model ('IssueModel', 'issues');
|
||||
|
||||
$login = $this->login->getUser ();
|
||||
|
||||
if ($login['id'] == '')
|
||||
{
|
||||
$status = 'error - anonymous user';
|
||||
}
|
||||
else
|
||||
{
|
||||
$issueid = $this->converter->HexToAscii ($issueid);
|
||||
|
||||
$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_delete_confirm = $this->input->post('issue_delete_confirm');
|
||||
|
||||
if ($post_delete_confirm !== FALSE && $post_delete_confirm == 'Y')
|
||||
{
|
||||
if ($this->issues->deleteWithFiles ($login['id'], $projectid, $issueid) === FALSE)
|
||||
{
|
||||
$status = 'error - ' . $this->issues->getErrorMessage();
|
||||
}
|
||||
else
|
||||
{
|
||||
$status = 'ok';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$status = 'error - not confirmed';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print $status;
|
||||
}
|
||||
|
||||
function xhr_add_file ($projectid = '', $issueid = '')
|
||||
{
|
||||
$this->load->model ('ProjectModel', 'projects');
|
||||
$this->load->model ('IssueModel', 'issues');
|
||||
$this->load->library ('upload');
|
||||
|
||||
$login = $this->login->getUser ();
|
||||
$revision_saved = -1;
|
||||
|
||||
if ($login['id'] == '')
|
||||
{
|
||||
$status = 'error - anonymous user';
|
||||
}
|
||||
else
|
||||
{
|
||||
$issueid = $this->converter->HexToAscii ($issueid);
|
||||
|
||||
$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('issue_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 = "issue_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)) == '') $d = '';
|
||||
|
||||
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->issues->addFiles ($login['id'], $projectid, $issueid, $add_files, $this->upload) === FALSE)
|
||||
{
|
||||
$status = 'error - ' . $this->issues->getErrorMessage();
|
||||
}
|
||||
else
|
||||
{
|
||||
$status = 'ok';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print $status;
|
||||
}
|
||||
|
||||
function xhr_edit_file ($projectid = '', $issueid = '')
|
||||
{
|
||||
$this->load->model ('ProjectModel', 'projects');
|
||||
$this->load->model ('IssueModel', 'issues');
|
||||
|
||||
$login = $this->login->getUser ();
|
||||
$revision_saved = -1;
|
||||
|
||||
if ($login['id'] == '')
|
||||
{
|
||||
$status = 'error - anonymous user';
|
||||
}
|
||||
else
|
||||
{
|
||||
$issueid = $this->converter->HexToAscii ($issueid);
|
||||
|
||||
$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('issue_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("issue_edit_file_name_{$i}");
|
||||
$k = $this->input->post("issue_edit_file_kill_{$i}");
|
||||
$d = $this->input->post("issue_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->issues->editFiles ($login['id'], $projectid, $issueid, $edit_files) === FALSE)
|
||||
{
|
||||
$status = 'error - ' . $this->issues->getErrorMessage();
|
||||
}
|
||||
else
|
||||
{
|
||||
$status = 'ok';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print $status;
|
||||
}
|
||||
|
||||
private function _handle_file ($login, $projectid, $issueid, $filename)
|
||||
{
|
||||
$this->load->model ('ProjectModel', 'projects');
|
||||
|
@ -241,7 +241,6 @@ class FileModel extends Model
|
||||
{
|
||||
if ($i == 0)
|
||||
{
|
||||
$this->errmsg = $this->db->_error_message();
|
||||
$this->db->trans_rollback ();
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -451,6 +451,7 @@ class IssueModel extends Model
|
||||
return $this->db->trans_status();
|
||||
}
|
||||
|
||||
|
||||
private function delete_all_files ($files)
|
||||
{
|
||||
foreach ($files as $f) @unlink ($f);
|
||||
@ -580,7 +581,7 @@ class IssueModel extends Model
|
||||
return $newid;
|
||||
}
|
||||
|
||||
function create_with_files ($userid, $issue, $attached_files, $uploader)
|
||||
function createWithFiles ($userid, $issue, $attached_files, $uploader)
|
||||
{
|
||||
set_error_handler (array ($this, 'capture_error'));
|
||||
$errmsg = '';
|
||||
@ -589,7 +590,7 @@ class IssueModel extends Model
|
||||
return $x;
|
||||
}
|
||||
|
||||
function update_summary_and_description ($userid, $issue)
|
||||
function updateSummaryAndDescription ($userid, $issue)
|
||||
{
|
||||
// TODO: check if userid can do this..
|
||||
$this->db->trans_start ();
|
||||
@ -614,6 +615,278 @@ class IssueModel extends Model
|
||||
|
||||
return $issue->id;
|
||||
}
|
||||
|
||||
private function _delete_issue ($userid, $projectid, $issueid)
|
||||
{
|
||||
$this->db->trans_begin (); // manual transaction. not using trans_start().
|
||||
|
||||
$this->db->where ('projectid', $projectid);
|
||||
$this->db->where ('issueid', $issueid);
|
||||
$query = $this->db->get ('issue_file_list');
|
||||
if ($this->db->trans_status() === FALSE)
|
||||
{
|
||||
$this->errmsg = $this->db->_error_message();
|
||||
$this->db->trans_rollback ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$result = $query->result ();
|
||||
$file_names = array ();
|
||||
foreach ($result as $f)
|
||||
{
|
||||
array_push ($file_names, $f->encname);
|
||||
}
|
||||
|
||||
$this->db->where ('projectid', $projectid);
|
||||
$this->db->where ('issueid', $issueid);
|
||||
$this->db->delete ('issue_file_list');
|
||||
if ($this->db->trans_status() === FALSE)
|
||||
{
|
||||
$this->errmsg = $this->db->_error_message();
|
||||
$this->db->trans_rollback ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$this->db->where ('projectid', $projectid);
|
||||
$this->db->where ('id', $issueid);
|
||||
$this->db->delete ('issue_change');
|
||||
if ($this->db->trans_status() === FALSE)
|
||||
{
|
||||
$this->errmsg = $this->db->_error_message();
|
||||
$this->db->trans_rollback ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$this->db->where ('projectid', $projectid);
|
||||
$this->db->where ('id', $issueid);
|
||||
$this->db->delete ('issue');
|
||||
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', 'issue');
|
||||
$this->db->set ('action', 'delete');
|
||||
$this->db->set ('projectid', $projectid);
|
||||
$this->db->set ('userid', $userid);
|
||||
$this->db->set ('message', $issueid);
|
||||
$this->db->insert ('log');
|
||||
|
||||
if ($this->db->trans_status() === FALSE)
|
||||
{
|
||||
$this->errmsg = $this->db->_error_message();
|
||||
$this->db->trans_rollback ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$file_name_count = count($file_names);
|
||||
for ($i = 0; $i < $file_name_count; $i++)
|
||||
{
|
||||
$encname = $file_names[$i];
|
||||
$path = CODEPOT_ISSUE_FILE_DIR . '/' . $encname;
|
||||
if (@unlink ($path) === FALSE)
|
||||
{
|
||||
if ($i == 0)
|
||||
{
|
||||
$this->db->trans_rollback ();
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is no good way to recover from the error.
|
||||
// carry on. some files will get orphaned.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->db->trans_commit ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function deleteWithFiles ($userid, $projectid, $issueid)
|
||||
{
|
||||
set_error_handler (array ($this, 'capture_error'));
|
||||
$errmsg = '';
|
||||
$x = $this->_delete_issue ($userid, $projectid, $issueid);
|
||||
restore_error_handler ();
|
||||
return $x;
|
||||
}
|
||||
|
||||
|
||||
private function _add_files ($userid, $projectid, $issueid, $add_files, $uploader)
|
||||
{
|
||||
$this->db->trans_begin (); // manual transaction. not using trans_start().
|
||||
|
||||
$config['allowed_types'] = '*';
|
||||
$config['upload_path'] = CODEPOT_ISSUE_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($add_files);
|
||||
for ($i = 0; $i < $file_count; $i++)
|
||||
{
|
||||
$f = $add_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 ('issueid', $issueid);
|
||||
$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 ('issue_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', 'issue');
|
||||
$this->db->set ('action', 'update');
|
||||
$this->db->set ('projectid', $projectid);
|
||||
$this->db->set ('userid', $userid);
|
||||
$this->db->set ('message', $issueid);
|
||||
$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, $issueid, $add_files, $uploader)
|
||||
{
|
||||
set_error_handler (array ($this, 'capture_error'));
|
||||
$errmsg = '';
|
||||
$x = $this->_add_files ($userid, $projectid, $issueid, $add_files, $uploader);
|
||||
restore_error_handler ();
|
||||
return $x;
|
||||
}
|
||||
|
||||
private function _edit_files ($userid, $projectid, $issueid, $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 ('issueid', $issueid);
|
||||
$this->db->where ('filename', $f['name']);
|
||||
$this->db->select ('encname');
|
||||
$query = $this->db->get('issue_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_ISSUE_FILE_DIR . '/' . $result[0]->encname);
|
||||
|
||||
$this->db->where ('projectid', $projectid);
|
||||
$this->db->where ('issueid', $issueid);
|
||||
$this->db->where ('filename', $f['name']);
|
||||
$query = $this->db->delete('issue_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 ('issueid', $issueid);
|
||||
$this->db->where ('filename', $f['name']);
|
||||
$this->db->set ('description', $f['desc']);
|
||||
$this->db->update ('issue_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', 'issue');
|
||||
$this->db->set ('action', 'update');
|
||||
$this->db->set ('projectid', $projectid);
|
||||
$this->db->set ('userid', $userid);
|
||||
$this->db->set ('message', $issueid);
|
||||
$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, $issueid, $edit_files)
|
||||
{
|
||||
set_error_handler (array ($this, 'capture_error'));
|
||||
$errmsg = '';
|
||||
$x = $this->_edit_files ($userid, $projectid, $issueid, $edit_files);
|
||||
restore_error_handler ();
|
||||
return $x;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -124,32 +124,32 @@ function kill_edit_file (no)
|
||||
d.prop ('disabled', true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var delete_in_progress = false;
|
||||
var add_file_in_progress = false;
|
||||
var edit_file_in_progress = false;
|
||||
|
||||
var original_file_name = [<?php
|
||||
for ($i = 0; $i < $file_count; $i++)
|
||||
{
|
||||
var original_file_name = [
|
||||
<?php
|
||||
for ($i = 0; $i < $file_count; $i++)
|
||||
{
|
||||
$f = $file->file_list[$i];
|
||||
printf ("%s\t'%s'", (($i == 0)? '': ",\n"), addslashes($f->filename));
|
||||
}
|
||||
print "\n";
|
||||
?>
|
||||
}
|
||||
print "\n";
|
||||
?>
|
||||
];
|
||||
|
||||
var original_file_desc = [
|
||||
<?php
|
||||
for ($i = 0; $i < $file_count; $i++)
|
||||
{
|
||||
<?php
|
||||
for ($i = 0; $i < $file_count; $i++)
|
||||
{
|
||||
$f = $file->file_list[$i];
|
||||
printf ("%s\t'%s'", (($i == 0)? '': ",\n"), addslashes($f->description));
|
||||
}
|
||||
print "\n";
|
||||
?>
|
||||
}
|
||||
print "\n";
|
||||
?>
|
||||
];
|
||||
|
||||
$(function () {
|
||||
|
@ -290,7 +290,8 @@ $this->load->view (
|
||||
),
|
||||
|
||||
'ctxmenuitems' => array (
|
||||
array ("issue/create/{$project->id}", '<i class="fa fa-plus"></i> ' . $this->lang->line('New'), 'issue_home_new')
|
||||
// DEPRECATED
|
||||
//array ("issue/create/{$project->id}", '<i class="fa fa-plus"></i> ' . $this->lang->line('New'), 'issue_home_new')
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
<?php
|
||||
$hex_issue_id = $this->converter->AsciiToHex ($issue->id);
|
||||
$issue_file_count = count ($issue->files);
|
||||
?>
|
||||
|
||||
<script type="text/javascript">
|
||||
@ -98,8 +99,99 @@ $.widget("ui.combobox", {
|
||||
});
|
||||
|
||||
|
||||
var populated_file_obj_for_adding = [];
|
||||
var populated_file_max_for_adding = 0;
|
||||
|
||||
function populate_selected_files_for_adding ()
|
||||
{
|
||||
var file_desc = {};
|
||||
for (var n = 0; n < populated_file_max_for_adding; n++)
|
||||
{
|
||||
var f = populated_file_obj_for_adding[n];
|
||||
if (f != null)
|
||||
{
|
||||
var d = $('#issue_show_mainarea_add_file_desc_' + n);
|
||||
if (d != null) file_desc[f.name] = d.val();
|
||||
}
|
||||
}
|
||||
|
||||
$('#issue_show_mainarea_add_file_table').empty();
|
||||
populated_file_obj_for_adding = [];
|
||||
|
||||
var f = $('#issue_show_mainarea_add_files').get(0);
|
||||
var f_no = 0;
|
||||
for (var n = 0; n < f.files.length; n++)
|
||||
{
|
||||
if (f.files[n] != null)
|
||||
{
|
||||
var desc = file_desc[f.files[n].name];
|
||||
if (desc == null) desc = '';
|
||||
|
||||
$('#issue_show_mainarea_add_file_table').append (
|
||||
codepot_sprintf (
|
||||
'<tr id="issue_show_mainarea_add_file_row_%d"><td><a href="#" id="issue_show_mainarea_add_file_cancel_%d" onClick="cancel_out_add_file(%d); return false;"><i class="fa fa-trash"></i></a></td><td>%s</td><td><input type="text" id="issue_show_mainarea_add_file_desc_%d" size="40" value="%s" /></td></tr>',
|
||||
f_no, f_no, f_no, codepot_htmlspecialchars(f.files[n].name), f_no, codepot_addslashes(desc)
|
||||
)
|
||||
);
|
||||
|
||||
populated_file_obj_for_adding[f_no] = f.files[n];
|
||||
f_no++;
|
||||
}
|
||||
}
|
||||
|
||||
populated_file_max_for_adding = f_no;
|
||||
}
|
||||
|
||||
function cancel_out_add_file (no)
|
||||
{
|
||||
$('#issue_show_mainarea_add_file_row_' + no).remove ();
|
||||
populated_file_obj_for_adding[no] = null;
|
||||
}
|
||||
|
||||
function kill_edit_file (no)
|
||||
{
|
||||
var n = $('#issue_show_mainarea_edit_file_name_' + no);
|
||||
var d = $('#issue_show_mainarea_edit_file_desc_' + no);
|
||||
if (n && d)
|
||||
{
|
||||
if (d.prop('disabled'))
|
||||
{
|
||||
n.css ('text-decoration', '');
|
||||
d.prop ('disabled', false);
|
||||
}
|
||||
else
|
||||
{
|
||||
n.css ('text-decoration', 'line-through');
|
||||
d.prop ('disabled', true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var work_in_progress = false;
|
||||
|
||||
var original_file_name = [
|
||||
<?php
|
||||
for ($i = 0; $i < $issue_file_count; $i++)
|
||||
{
|
||||
$f = $issue->files[$i];
|
||||
printf ("%s\t'%s'", (($i == 0)? '': ",\n"), addslashes($f->filename));
|
||||
}
|
||||
print "\n";
|
||||
?>
|
||||
];
|
||||
|
||||
var original_file_desc = [
|
||||
<?php
|
||||
for ($i = 0; $i < $issue_file_count; $i++)
|
||||
{
|
||||
$f = $issue->files[$i];
|
||||
printf ("%s\t'%s'", (($i == 0)? '': ",\n"), addslashes($f->description));
|
||||
}
|
||||
print "\n";
|
||||
?>
|
||||
];
|
||||
|
||||
$(function () {
|
||||
<?php if (isset($login['id']) && $login['id'] != ''): ?>
|
||||
$("#issue_show_mainarea_edit_description_tabs").tabs ();
|
||||
@ -185,6 +277,268 @@ $(function () {
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$('#issue_show_mainarea_delete_form').dialog (
|
||||
{
|
||||
title: '<?php print $this->lang->line('Delete');?>',
|
||||
resizable: true,
|
||||
autoOpen: false,
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
modal: true,
|
||||
buttons: {
|
||||
'<?php print $this->lang->line('OK')?>': function () {
|
||||
if (work_in_progress) return;
|
||||
|
||||
if (!!window.FormData)
|
||||
{
|
||||
// FormData is supported
|
||||
work_in_progress = true;
|
||||
|
||||
var form_data = new FormData();
|
||||
|
||||
var f = $('#issue_show_mainarea_delete_confirm');
|
||||
if (f != null && f.is(':checked')) form_data.append ('issue_delete_confirm', 'Y');
|
||||
|
||||
$('#issue_show_mainarea_delete_form').dialog('disable');
|
||||
$.ajax({
|
||||
url: codepot_merge_path('<?php print site_url() ?>', '<?php print "/issue/xhr_delete/{$project->id}/{$hex_issue_id}"; ?>'),
|
||||
type: 'POST',
|
||||
data: form_data,
|
||||
mimeType: 'multipart/form-data',
|
||||
contentType: false,
|
||||
processData: false,
|
||||
cache: false,
|
||||
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
work_in_progress = false;
|
||||
$('#issue_show_mainarea_delete_form').dialog('enable');
|
||||
$('#issue_show_mainarea_delete_form').dialog('close');
|
||||
if (data == 'ok')
|
||||
{
|
||||
// refresh the page to the head revision
|
||||
$(location).attr ('href', codepot_merge_path('<?php print site_url(); ?>', '<?php print "/issue/home/{$project->id}"; ?>'));
|
||||
}
|
||||
else
|
||||
{
|
||||
show_alert ('<pre>' + codepot_htmlspecialchars(data) + '</pre>', "<?php print $this->lang->line('Error')?>");
|
||||
}
|
||||
},
|
||||
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
work_in_progress = false;
|
||||
$('#issue_show_mainarea_delete_form').dialog('enable');
|
||||
$('#issue_show_mainarea_delete_form').dialog('close');
|
||||
show_alert ('Failed - ' + errorThrown, "<?php print $this->lang->line('Error')?>");
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
show_alert ('<pre>NOT SUPPORTED</pre>', "<?php print $this->lang->line('Error')?>");
|
||||
}
|
||||
},
|
||||
'<?php print $this->lang->line('Cancel')?>': function () {
|
||||
if (work_in_progress) return;
|
||||
$('#issue_show_mainarea_delete_form').dialog('close');
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
beforeClose: function() {
|
||||
// if importing is in progress, prevent dialog closing
|
||||
return !work_in_progress;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
$('#issue_show_mainarea_add_files').change (function () {
|
||||
populate_selected_files_for_adding ();
|
||||
});
|
||||
|
||||
$('#issue_show_mainarea_add_file_form').dialog (
|
||||
{
|
||||
title: '<?php print $this->lang->line('Add');?>',
|
||||
resizable: true,
|
||||
autoOpen: false,
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
modal: true,
|
||||
buttons: {
|
||||
'<?php print $this->lang->line('OK')?>': function () {
|
||||
if (work_in_progress) return;
|
||||
|
||||
if (!!window.FormData)
|
||||
{
|
||||
// FormData is supported
|
||||
work_in_progress = true;
|
||||
|
||||
var form_data = new FormData();
|
||||
|
||||
var f_no = 0;
|
||||
for (var i = 0; i <= populated_file_max_for_adding; i++)
|
||||
{
|
||||
var f = populated_file_obj_for_adding[i];
|
||||
if (f != null)
|
||||
{
|
||||
form_data.append ('issue_add_file_' + f_no, f);
|
||||
|
||||
var d = $('#issue_show_mainarea_add_file_desc_' + i);
|
||||
if (d != null) form_data.append('issue_add_file_desc_' + f_no, d.val());
|
||||
f_no++;
|
||||
}
|
||||
}
|
||||
form_data.append ('issue_add_file_count', f_no);
|
||||
|
||||
$('#issue_show_mainarea_add_file_form').dialog('disable');
|
||||
$.ajax({
|
||||
url: codepot_merge_path('<?php print site_url() ?>', '<?php print "/issue/xhr_add_file/{$project->id}/{$hex_issue_id}"; ?>'),
|
||||
type: 'POST',
|
||||
data: form_data,
|
||||
mimeType: 'multipart/form-data',
|
||||
contentType: false,
|
||||
processData: false,
|
||||
cache: false,
|
||||
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
work_in_progress = false;
|
||||
$('#issue_show_mainarea_add_file_form').dialog('enable');
|
||||
$('#issue_show_mainarea_add_file_form').dialog('close');
|
||||
if (data == 'ok')
|
||||
{
|
||||
// refresh the page to the head revision
|
||||
$(location).attr ('href', codepot_merge_path('<?php print site_url(); ?>', '<?php print "/issue/show/{$project->id}/{$hex_issue_id}"; ?>'));
|
||||
}
|
||||
else
|
||||
{
|
||||
show_alert ('<pre>' + codepot_htmlspecialchars(data) + '</pre>', "<?php print $this->lang->line('Error')?>");
|
||||
}
|
||||
},
|
||||
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
work_in_progress = false;
|
||||
$('#issue_show_mainarea_add_file_form').dialog('enable');
|
||||
$('#issue_show_mainarea_add_file_form').dialog('close');
|
||||
show_alert ('Failed - ' + errorThrown, "<?php print $this->lang->line('Error')?>");
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
show_alert ('<pre>NOT SUPPORTED</pre>', "<?php print $this->lang->line('Error')?>");
|
||||
}
|
||||
},
|
||||
'<?php print $this->lang->line('Cancel')?>': function () {
|
||||
if (work_in_progress) return;
|
||||
$('#issue_show_mainarea_add_file_form').dialog('close');
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
beforeClose: function() {
|
||||
// if importing is in progress, prevent dialog closing
|
||||
return !work_in_progress;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$('#issue_show_mainarea_edit_file_form').dialog (
|
||||
{
|
||||
title: '<?php print $this->lang->line('Edit');?>',
|
||||
resizable: true,
|
||||
autoOpen: false,
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
modal: true,
|
||||
buttons: {
|
||||
'<?php print $this->lang->line('OK')?>': function () {
|
||||
if (work_in_progress) return;
|
||||
|
||||
if (!!window.FormData)
|
||||
{
|
||||
// FormData is supported
|
||||
work_in_progress = true;
|
||||
|
||||
var form_data = new FormData();
|
||||
|
||||
var f_no = 0;
|
||||
for (var i = 0; i <= <?php print $issue_file_count; ?>; i++)
|
||||
{
|
||||
var n = $('#issue_show_mainarea_edit_file_name_' + i);
|
||||
var d = $('#issue_show_mainarea_edit_file_desc_' + i);
|
||||
|
||||
if (n && d)
|
||||
{
|
||||
if (d.prop('disabled'))
|
||||
{
|
||||
form_data.append ('issue_edit_file_name_' + f_no, original_file_name[i]);
|
||||
form_data.append('issue_edit_file_kill_' + f_no, 'yes');
|
||||
f_no++;
|
||||
}
|
||||
else if (d.val() != original_file_desc[i])
|
||||
{
|
||||
form_data.append ('issue_edit_file_name_' + f_no, original_file_name[i]);
|
||||
form_data.append('issue_edit_file_desc_' + f_no, d.val());
|
||||
f_no++;
|
||||
}
|
||||
}
|
||||
}
|
||||
form_data.append ('issue_edit_file_count', f_no);
|
||||
|
||||
$('#issue_show_mainarea_edit_file_form').dialog('disable');
|
||||
$.ajax({
|
||||
url: codepot_merge_path('<?php print site_url() ?>', '<?php print "/issue/xhr_edit_file/{$project->id}/{$hex_issue_id}"; ?>'),
|
||||
type: 'POST',
|
||||
data: form_data,
|
||||
mimeType: 'multipart/form-data',
|
||||
contentType: false,
|
||||
processData: false,
|
||||
cache: false,
|
||||
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
work_in_progress = false;
|
||||
$('#issue_show_mainarea_edit_file_form').dialog('enable');
|
||||
$('#issue_show_mainarea_edit_file_form').dialog('close');
|
||||
if (data == 'ok')
|
||||
{
|
||||
// refresh the page to the head revision
|
||||
$(location).attr ('href', codepot_merge_path('<?php print site_url(); ?>', '<?php print "/issue/show/{$project->id}/{$hex_issue_id}"; ?>'));
|
||||
}
|
||||
else
|
||||
{
|
||||
show_alert ('<pre>' + codepot_htmlspecialchars(data) + '</pre>', "<?php print $this->lang->line('Error')?>");
|
||||
}
|
||||
},
|
||||
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
work_in_progress = false;
|
||||
$('#issue_show_mainarea_edit_file_form').dialog('enable');
|
||||
$('#issue_show_mainarea_edit_file_form').dialog('close');
|
||||
show_alert ('Failed - ' + errorThrown, "<?php print $this->lang->line('Error')?>");
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
show_alert ('<pre>NOT SUPPORTED</pre>', "<?php print $this->lang->line('Error')?>");
|
||||
}
|
||||
},
|
||||
'<?php print $this->lang->line('Cancel')?>': function () {
|
||||
if (work_in_progress) return;
|
||||
$('#issue_show_mainarea_edit_file_form').dialog('close');
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
beforeClose: function() {
|
||||
// if importing is in progress, prevent dialog closing
|
||||
return !work_in_progress;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
/*
|
||||
@ -226,12 +580,32 @@ $(function () {
|
||||
);
|
||||
|
||||
<?php if (isset($login['id']) && $login['id'] != ''): ?>
|
||||
$("#issue_show_mainarea_edit_button").button().click (
|
||||
$('#issue_show_mainarea_edit_button').button().click (
|
||||
function () {
|
||||
$('#issue_show_mainarea_edit_form').dialog('open');
|
||||
return false; // prevent the default behavior
|
||||
}
|
||||
);
|
||||
$('#issue_show_mainarea_delete_button').button().click (
|
||||
function () {
|
||||
$('#issue_show_mainarea_delete_form').dialog('open');
|
||||
return false; // prevent the default behavior
|
||||
}
|
||||
);
|
||||
|
||||
$('#issue_show_mainarea_add_file_button').button().click (
|
||||
function() {
|
||||
$('#issue_show_mainarea_add_file_form').dialog('open');
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
$('#issue_show_mainarea_edit_file_button').button().click (
|
||||
function() {
|
||||
$('#issue_show_mainarea_edit_file_form').dialog('open');
|
||||
return false;
|
||||
}
|
||||
);
|
||||
<?php endif; ?>
|
||||
|
||||
$("#issue_show_mainarea_change_form_open").button().click (
|
||||
@ -305,9 +679,10 @@ $this->load->view (
|
||||
),
|
||||
|
||||
'ctxmenuitems' => array (
|
||||
array ("issue/create/{$project->id}", '<i class="fa fa-plus"></i> ' . $this->lang->line('New')),
|
||||
array ("issue/update/{$project->id}/{$hex_issue_id}", '<i class="fa fa-edit"></i> ' . $this->lang->line('Edit')),
|
||||
array ("issue/delete/{$project->id}/{$hex_issue_id}", '<i class="fa fa-trash"></i> ' . $this->lang->line('Delete'))
|
||||
//DEPRECATED
|
||||
//array ("issue/create/{$project->id}", '<i class="fa fa-plus"></i> ' . $this->lang->line('New')),
|
||||
//array ("issue/update/{$project->id}/{$hex_issue_id}", '<i class="fa fa-edit"></i> ' . $this->lang->line('Edit')),
|
||||
//array ("issue/delete/{$project->id}/{$hex_issue_id}", '<i class="fa fa-trash"></i> ' . $this->lang->line('Delete'))
|
||||
)
|
||||
)
|
||||
);
|
||||
@ -360,6 +735,9 @@ $this->load->view (
|
||||
print '<a id="issue_show_mainarea_edit_button" href="#">';
|
||||
print $this->lang->line('Edit');
|
||||
print '</a>';
|
||||
print '<a id="issue_show_mainarea_delete_button" href="#">';
|
||||
print $this->lang->line('Delete');
|
||||
print '</a>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
@ -370,13 +748,20 @@ $this->load->view (
|
||||
</pre>
|
||||
</div> <!-- issue_show_mainarea_description -->
|
||||
|
||||
<div id="issue_show_mainarea_file_list">
|
||||
<div id="issue_show_mainarea_files">
|
||||
<?php print $this->lang->line('Attachments'); ?>
|
||||
|
||||
<?php if (isset($login['id']) && $login['id'] != ''): ?>
|
||||
<a id="issue_show_mainarea_add_file_button" href='#'><?php print $this->lang->line('Add')?></a>
|
||||
<a id="issue_show_mainarea_edit_file_button" href='#'><?php print $this->lang->line('Edit')?></a>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($issue->files)): ?>
|
||||
<ul>
|
||||
<?php
|
||||
|
||||
foreach ($issue->files as $f)
|
||||
for ($i = 0; $i < $issue_file_count; $i++)
|
||||
{
|
||||
$f = $issue->files[$i];
|
||||
$hexname = $this->converter->AsciiToHex ($f->filename);
|
||||
print '<li>';
|
||||
print anchor (
|
||||
@ -390,6 +775,7 @@ $this->load->view (
|
||||
?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="issue_show_mainarea_changes">
|
||||
@ -552,6 +938,39 @@ $this->load->view (
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id='issue_show_mainarea_delete_form'>
|
||||
<input type='checkbox' id='issue_show_mainarea_delete_confirm' />
|
||||
<?php print $this->lang->line('MSG_SURE_TO_DELETE_THIS') . ' - ' . $issue->id . ': ' . htmlspecialchars($issue->summary); ?>
|
||||
</div>
|
||||
|
||||
<div id='issue_show_mainarea_add_file_form'>
|
||||
<div id='issue_show_mainarea_add_file_input'>
|
||||
<input type='file' id='issue_show_mainarea_add_files' name='issue_show_add_files' multiple='' autocomplete='off' style='color: transparent;' />
|
||||
<table id='issue_show_mainarea_add_file_table'></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id='issue_show_mainarea_edit_file_form'>
|
||||
|
||||
<table>
|
||||
<?php
|
||||
|
||||
for ($i = 0; $i < $issue_file_count; $i++)
|
||||
{
|
||||
$f = $issue->files[$i];
|
||||
print '<tr><td>';
|
||||
printf ('<a href="#" onClick="kill_edit_file(%d); return false;"><i class="fa fa-trash"></i></a>', $i);
|
||||
print '</td><td>';
|
||||
printf ('<span id="issue_show_mainarea_edit_file_name_%d">%s</span>', $i, htmlspecialchars($f->filename));
|
||||
print '</td><td>';
|
||||
printf ('<input type="text" id="issue_show_mainarea_edit_file_desc_%d" value="%s" size="40" autocomplete="off" />', $i, addslashes($f->description));
|
||||
print '</td></tr>';
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<div id="issue_show_mainarea_change_form">
|
||||
|
Loading…
Reference in New Issue
Block a user