improved the issue show view to manipulate attached files
This commit is contained in:
		| @ -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_1 ON "cpot_issue"("projectid", "status", "type", "summary"); | ||||||
| CREATE INDEX cpot_issue_index_2 ON "cpot_issue"("projectid", "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, | 	"projectid"   VARCHAR(32)   NOT NULL, | ||||||
| 	"issueid"     NUMBER(20,0)  NOT NULL, | 	"issueid"     NUMBER(20,0)  NOT NULL, | ||||||
| 	"name"       VARCHAR(255)  NOT NULL, | 	"filename"    VARCHAR(255)  NOT NULL, | ||||||
| 	"encname"     VARCHAR(255)  NOT NULL, | 	"encname"     VARCHAR(255)  NOT NULL, | ||||||
|  | 	"md5sum"      CHAR(32)      NOT NULL, | ||||||
|  | 	"description" CLOB          NOT NULL, | ||||||
| 	"createdon"   TIMESTAMP     NOT NULL, | 	"createdon"   TIMESTAMP     NOT NULL, | ||||||
| 	"createdby"   VARCHAR(32)   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_projectid FOREIGN KEY ("projectid") REFERENCES "cpot_project"("id"), | ||||||
| 	CONSTRAINT issue_attachment_issueid FOREIGN KEY ("projectid","issueid") REFERENCES "cpot_issue"("projectid","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 | CREATE OR REPLACE TRIGGER cpot_upon_issue_id_update AFTER UPDATE OF "id" ON "cpot_issue" FOR EACH ROW | ||||||
| BEGIN | 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" 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"; | 	UPDATE "cpot_issue_change_attachment" SET "issueid" = :new."id" WHERE "projectid" = :old."projectid" AND "issueid" = :old."id"; | ||||||
| END; | END; | ||||||
|  | |||||||
| @ -135,6 +135,27 @@ CREATE TABLE issue_attachment ( | |||||||
| 		ON DELETE RESTRICT ON UPDATE CASCADE | 		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 ( | CREATE TABLE issue_change ( | ||||||
| 	projectid VARCHAR(32)  NOT NULL, | 	projectid VARCHAR(32)  NOT NULL, | ||||||
| 	id        BIGINT       NOT NULL, | 	id        BIGINT       NOT NULL, | ||||||
|  | |||||||
| @ -257,6 +257,8 @@ class Issue extends Controller | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | DEPRECATED | ||||||
| 	function _edit_issue ($projectid, $hexid, $mode) | 	function _edit_issue ($projectid, $hexid, $mode) | ||||||
| 	{ | 	{ | ||||||
| 		$this->load->helper ('form'); | 		$this->load->helper ('form'); | ||||||
| @ -414,6 +416,7 @@ class Issue extends Controller | |||||||
| 		return $this->_edit_issue ($projectid, $hexid, 'update'); | 		return $this->_edit_issue ($projectid, $hexid, 'update'); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	function delete ($projectid = '', $hexid = '') | 	function delete ($projectid = '', $hexid = '') | ||||||
| 	{ | 	{ | ||||||
| 		$this->load->helper ('form'); | 		$this->load->helper ('form'); | ||||||
| @ -516,6 +519,7 @@ class Issue extends Controller | |||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | */ | ||||||
|  |  | ||||||
| 	function xhr_create ($projectid = '') | 	function xhr_create ($projectid = '') | ||||||
| 	{ | 	{ | ||||||
| @ -609,7 +613,7 @@ class Issue extends Controller | |||||||
|  |  | ||||||
| 					if ($status == '') | 					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(); | 							$status = 'error - ' . $this->issues->getErrorMessage(); | ||||||
| 						} | 						} | ||||||
| @ -681,7 +685,7 @@ class Issue extends Controller | |||||||
|  |  | ||||||
| 					if ($status == '') | 					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(); | 							$status = 'error - ' . $this->issues->getErrorMessage(); | ||||||
| 						} | 						} | ||||||
| @ -697,6 +701,223 @@ class Issue extends Controller | |||||||
| 		print $status; | 		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) | 	private function _handle_file ($login, $projectid, $issueid, $filename) | ||||||
| 	{ | 	{ | ||||||
| 		$this->load->model ('ProjectModel', 'projects'); | 		$this->load->model ('ProjectModel', 'projects'); | ||||||
|  | |||||||
| @ -241,7 +241,6 @@ class FileModel extends Model | |||||||
| 			{ | 			{ | ||||||
| 				if ($i == 0) | 				if ($i == 0) | ||||||
| 				{ | 				{ | ||||||
| 					$this->errmsg = $this->db->_error_message();  |  | ||||||
| 					$this->db->trans_rollback (); | 					$this->db->trans_rollback (); | ||||||
| 					return FALSE; | 					return FALSE; | ||||||
| 				} | 				} | ||||||
|  | |||||||
| @ -451,6 +451,7 @@ class IssueModel extends Model | |||||||
| 		return $this->db->trans_status(); | 		return $this->db->trans_status(); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	 | ||||||
| 	private function delete_all_files ($files) | 	private function delete_all_files ($files) | ||||||
| 	{ | 	{ | ||||||
| 		foreach ($files as $f) @unlink ($f); | 		foreach ($files as $f) @unlink ($f); | ||||||
| @ -580,7 +581,7 @@ class IssueModel extends Model | |||||||
| 		return $newid; | 		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')); | 		set_error_handler (array ($this, 'capture_error')); | ||||||
| 		$errmsg = ''; | 		$errmsg = ''; | ||||||
| @ -589,7 +590,7 @@ class IssueModel extends Model | |||||||
| 		return $x; | 		return $x; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function update_summary_and_description ($userid, $issue) | 	function updateSummaryAndDescription ($userid, $issue) | ||||||
| 	{ | 	{ | ||||||
| 		// TODO: check if userid can do this.. | 		// TODO: check if userid can do this.. | ||||||
| 		$this->db->trans_start (); | 		$this->db->trans_start (); | ||||||
| @ -614,6 +615,278 @@ class IssueModel extends Model | |||||||
|  |  | ||||||
| 		return $issue->id; | 		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); | 			d.prop ('disabled', true); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	 |  | ||||||
| } | } | ||||||
|  |  | ||||||
| var delete_in_progress = false; | var delete_in_progress = false; | ||||||
| var add_file_in_progress = false; | var add_file_in_progress = false; | ||||||
| var edit_file_in_progress = false; | var edit_file_in_progress = false; | ||||||
|  |  | ||||||
| var original_file_name = [<?php | var original_file_name = [ | ||||||
| for ($i = 0; $i < $file_count; $i++) | 	<?php | ||||||
| { | 	for ($i = 0; $i < $file_count; $i++) | ||||||
|  | 	{ | ||||||
| 		$f = $file->file_list[$i]; | 		$f = $file->file_list[$i]; | ||||||
| 		printf ("%s\t'%s'", (($i == 0)? '': ",\n"), addslashes($f->filename)); | 		printf ("%s\t'%s'", (($i == 0)? '': ",\n"), addslashes($f->filename)); | ||||||
| } | 	} | ||||||
| print "\n"; | 	print "\n"; | ||||||
| ?> | 	?> | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| var original_file_desc = [ | var original_file_desc = [ | ||||||
| <?php | 	<?php | ||||||
| for ($i = 0; $i < $file_count; $i++) | 	for ($i = 0; $i < $file_count; $i++) | ||||||
| { | 	{ | ||||||
| 		$f = $file->file_list[$i]; | 		$f = $file->file_list[$i]; | ||||||
| 		printf ("%s\t'%s'", (($i == 0)? '': ",\n"), addslashes($f->description)); | 		printf ("%s\t'%s'", (($i == 0)? '': ",\n"), addslashes($f->description)); | ||||||
| } | 	} | ||||||
| print "\n"; | 	print "\n"; | ||||||
| ?> | 	?> | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| $(function () { | $(function () { | ||||||
|  | |||||||
| @ -290,7 +290,8 @@ $this->load->view ( | |||||||
| 		), | 		), | ||||||
|  |  | ||||||
| 		'ctxmenuitems' => array ( | 		'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 | <?php | ||||||
| $hex_issue_id = $this->converter->AsciiToHex ($issue->id); | $hex_issue_id = $this->converter->AsciiToHex ($issue->id); | ||||||
|  | $issue_file_count = count ($issue->files); | ||||||
| ?> | ?> | ||||||
|  |  | ||||||
| <script type="text/javascript"> | <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 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 () {  | $(function () {  | ||||||
| <?php if (isset($login['id']) && $login['id'] != ''): ?> | <?php if (isset($login['id']) && $login['id'] != ''): ?> | ||||||
| 	$("#issue_show_mainarea_edit_description_tabs").tabs (); | 	$("#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; ?> | <?php endif; ?> | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| @ -226,12 +580,32 @@ $(function () { | |||||||
| 	);  | 	);  | ||||||
|  |  | ||||||
| <?php if (isset($login['id']) && $login['id'] != ''): ?> | <?php if (isset($login['id']) && $login['id'] != ''): ?> | ||||||
| 	$("#issue_show_mainarea_edit_button").button().click ( | 	$('#issue_show_mainarea_edit_button').button().click ( | ||||||
| 		function () {  | 		function () {  | ||||||
| 			$('#issue_show_mainarea_edit_form').dialog('open');  | 			$('#issue_show_mainarea_edit_form').dialog('open');  | ||||||
| 			return false; // prevent the default behavior | 			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; ?> | <?php endif; ?> | ||||||
|  |  | ||||||
| 	$("#issue_show_mainarea_change_form_open").button().click ( | 	$("#issue_show_mainarea_change_form_open").button().click ( | ||||||
| @ -305,9 +679,10 @@ $this->load->view ( | |||||||
| 		), | 		), | ||||||
|  |  | ||||||
| 		'ctxmenuitems' => array ( | 		'ctxmenuitems' => array ( | ||||||
| 			array ("issue/create/{$project->id}", '<i class="fa fa-plus"></i> ' . $this->lang->line('New')), | 			//DEPRECATED | ||||||
| 			array ("issue/update/{$project->id}/{$hex_issue_id}", '<i class="fa fa-edit"></i> ' . $this->lang->line('Edit')), | 			//array ("issue/create/{$project->id}", '<i class="fa fa-plus"></i> ' . $this->lang->line('New')), | ||||||
| 			array ("issue/delete/{$project->id}/{$hex_issue_id}", '<i class="fa fa-trash"></i> ' . $this->lang->line('Delete')) | 			//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 '<a id="issue_show_mainarea_edit_button" href="#">'; | ||||||
| 			print $this->lang->line('Edit'); | 			print $this->lang->line('Edit'); | ||||||
| 			print '</a>'; | 			print '</a>'; | ||||||
|  | 			print '<a id="issue_show_mainarea_delete_button" href="#">'; | ||||||
|  | 			print $this->lang->line('Delete'); | ||||||
|  | 			print '</a>'; | ||||||
| 		} | 		} | ||||||
| 	?> | 	?> | ||||||
| </div> | </div> | ||||||
| @ -370,13 +748,20 @@ $this->load->view ( | |||||||
| </pre> | </pre> | ||||||
| </div> <!-- issue_show_mainarea_description --> | </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)): ?> | <?php if (!empty($issue->files)): ?> | ||||||
| <ul> | <ul> | ||||||
| <?php | <?php | ||||||
| 	 | 	for ($i = 0; $i < $issue_file_count; $i++) | ||||||
| 	foreach ($issue->files as $f) |  | ||||||
| 	{ | 	{ | ||||||
|  | 		$f = $issue->files[$i]; | ||||||
| 		$hexname = $this->converter->AsciiToHex ($f->filename); | 		$hexname = $this->converter->AsciiToHex ($f->filename); | ||||||
| 		print '<li>'; | 		print '<li>'; | ||||||
| 		print anchor ( | 		print anchor ( | ||||||
| @ -390,6 +775,7 @@ $this->load->view ( | |||||||
| ?> | ?> | ||||||
| </ul> | </ul> | ||||||
| <?php endif; ?> | <?php endif; ?> | ||||||
|  |  | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
| <div id="issue_show_mainarea_changes"> | <div id="issue_show_mainarea_changes"> | ||||||
| @ -552,6 +938,39 @@ $this->load->view ( | |||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</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; ?> | <?php endif; ?> | ||||||
|  |  | ||||||
| <div id="issue_show_mainarea_change_form"> | <div id="issue_show_mainarea_change_form"> | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user