diff --git a/codepot/etc/codepot.ini.in b/codepot/etc/codepot.ini.in index 11681a30..633b4ee0 100644 --- a/codepot/etc/codepot.ini.in +++ b/codepot/etc/codepot.ini.in @@ -91,6 +91,11 @@ max_upload_size = "10000" ;------------------------------------------------------------------------------ max_latest_projects = "10" +;------------------------------------------------------------------------------ +; Maximum number of issues to show +;------------------------------------------------------------------------------ +max_issues_per_page = "50" + ;------------------------------------------------------------------------------ ; Maximum number of log entries to show per details page ;------------------------------------------------------------------------------ diff --git a/codepot/src/codepot/controllers/issue.php b/codepot/src/codepot/controllers/issue.php index 8347ff5e..d481dd99 100644 --- a/codepot/src/codepot/controllers/issue.php +++ b/codepot/src/codepot/controllers/issue.php @@ -8,6 +8,24 @@ class Issue extends Controller var $VIEW_EDIT = 'issue_edit'; var $VIEW_DELETE = 'issue_delete'; + var $TYPE_DEFECT = 'defect'; + var $TYPE_REQUEST = 'request'; + var $TYPE_OTHER = 'other'; + + var $STATUS_NEW = 'new'; + var $STATUS_ACCEPTED = 'accepted'; + var $STATUS_REJECTED = 'rejected'; + var $STATUS_FIXED = 'fixed'; + var $STATUS_WONTFIX = 'wontfix'; + var $STATUS_DUPLICATE = 'duplicate'; + var $STATUS_OTHER = 'other'; + + var $PRIORITY_CRITICAL = 'critical'; + var $PRIORITY_HIGH = 'high'; + var $PRIORITY_MEDIUM = 'medium'; + var $PRIORITY_LOW = 'low'; + var $PRIORITY_OTHER = 'other'; + function Issue () { parent::Controller (); @@ -19,10 +37,10 @@ class Issue extends Controller $this->load->library ('Language', 'lang'); $this->lang->load ('common', CODEPOT_LANG); - + $this->lang->load ('issue', CODEPOT_LANG); } - function home ($projectid = '') + function home ($projectid = '', $offset = 0) { $this->load->model ('ProjectModel', 'projects'); $this->load->model ('IssueModel', 'issues'); @@ -49,25 +67,51 @@ class Issue extends Controller { if ($this->input->post('filter')) { - $filter->status = $this->input->post('filter_status'); + $filter->summary = $this->input->post('filter_summary'); $filter->owner = $this->input->post('filter_owner'); $data['filter'] = $filter; } else { - $filter->status = ''; + $filter->summary = ''; $filter->owner = ''; $data['filter'] = $filter; } - $issues = $this->issues->getAll ($login['id'], $project); + + $this->load->library ('pagination'); + + $num_entries = $this->issues->getNumEntries ($login['id'], $project); + if ($num_entries === FALSE) + { + $data['project'] = $project; + $data['message'] = 'DATABASE ERROR'; + $this->load->view ($this->VIEW_ERROR, $data); + return; + } + + $pagecfg['base_url'] = site_url() . "/issue/home/{$projectid}/"; + $pagecfg['total_rows'] = $num_entries; + $pagecfg['per_page'] = CODEPOT_MAX_ISSUES_PER_PAGE; + $pagecfg['uri_segment'] = 4; + $pagecfg['first_link'] = $this->lang->line('First'); + $pagecfg['last_link'] = $this->lang->line('Last'); + + //$issues = $this->issues->getAll ($login['id'], $project); + $issues = $this->issues->getEntries ($login['id'], $offset, $pagecfg['per_page'], $project); if ($issues === FALSE) { + $data['project'] = $project; $data['message'] = 'DATABASE ERROR'; $this->load->view ($this->VIEW_ERROR, $data); } else { + $this->pagination->initialize ($pagecfg); + $data['page_links'] = $this->pagination->create_links (); + $data['issue_type_array'] = $this->_get_type_array(); + $data['issue_status_array'] = $this->_get_status_array(); + $data['issue_priority_array'] = $this->_get_priority_array(); $data['project'] = $project; $data['issues'] = $issues; $this->load->view ($this->VIEW_HOME, $data); @@ -109,7 +153,8 @@ class Issue extends Controller } else { - if ($this->input->post('issue_change')) + $change_post = $this->input->post('issue_change'); + if ($change_post == 'change') { $change->type = $this->input->post('issue_change_type'); $change->status = $this->input->post('issue_change_status'); @@ -117,7 +162,35 @@ class Issue extends Controller $change->priority = $this->input->post('issue_change_priority'); $change->comment = $this->input->post('issue_change_comment'); - if ($this->issues->change ($login['id'], $project, $id, $change) === FALSE) + if (!$login['sysadmin?'] && + $this->projects->projectHasMember($project->id, $login['id']) === FALSE) + { + $data['project'] = $project; + $data['message'] = "NO PERMISSION - $projectid"; + $this->load->view ($this->VIEW_ERROR, $data); + } + else if ($this->issues->change ($login['id'], $project, $id, $change) === FALSE) + { + $data['project'] = $project; + $data['message'] = 'DATABASE ERROR'; + $this->load->view ($this->VIEW_ERROR, $data); + } + else + { + redirect ("/issue/show/{$projectid}/{$hexid}"); + } + return; + } + else if ($change_post == 'undo') + { + if (!$login['sysadmin?'] && + $this->projects->projectHasMember($project->id, $login['id']) === FALSE) + { + $data['project'] = $project; + $data['message'] = "NO PERMISSION - $projectid"; + $this->load->view ($this->VIEW_ERROR, $data); + } + else if ($this->issues->undo_last_change ($login['id'], $project, $id) === FALSE) { $data['project'] = $project; $data['message'] = 'DATABASE ERROR'; @@ -141,12 +214,15 @@ class Issue extends Controller { $data['project'] = $project; $data['message'] = - $this->lang->line('MSG_NO_SUCH_ISSUE') . + $this->lang->line('MSG_NO_SUCH_ISSUE'). " - {$id}"; $this->load->view ($this->VIEW_ERROR, $data); } else { + $data['issue_type_array'] = $this->_get_type_array(); + $data['issue_status_array'] = $this->_get_status_array(); + $data['issue_priority_array'] = $this->_get_priority_array(); $data['project'] = $project; $data['issue'] = $issue; $this->load->view ($this->VIEW_SHOW, $data); @@ -194,21 +270,22 @@ class Issue extends Controller $this->form_validation->set_rules ( 'issue_summary', 'summary', 'required|max_length[255]'); $this->form_validation->set_rules ( - 'issue_status', 'status', 'required'); + 'issue_description', 'description', 'required'); $this->form_validation->set_rules ( 'issue_type', 'type', 'required'); $this->form_validation->set_rules ( - 'issue_priority', 'priority', 'required'); + 'issue_type', 'status', 'required'); $this->form_validation->set_rules ( - 'issue_owner', 'owner', 'required'); - $this->form_validation->set_rules ( - 'issue_description', 'description', 'required'); + 'issue_type', 'priority', 'required'); $this->form_validation->set_error_delimiters ( '',''); $data['mode'] = $mode; $data['message'] = ''; $data['project'] = $project; + $data['issue_type_array'] = $this->_get_type_array(); + $data['issue_status_array'] = $this->_get_status_array(); + $data['issue_priority_array'] = $this->_get_priority_array(); if ($this->input->post('issue')) { @@ -224,7 +301,7 @@ class Issue extends Controller if ($this->form_validation->run()) { $id = ($mode == 'update')? - $this->issues->update ($login['id'], $issue): + $this->issues->update_partial ($login['id'], $issue): $this->issues->create ($login['id'], $issue); if ($id === FALSE) { @@ -234,7 +311,8 @@ class Issue extends Controller } else { - redirect ("issue/show/{$project->id}/{$hexid}"); + redirect ("issue/show/{$project->id}/" . + $this->converter->AsciiToHex((string)$id)); } } else @@ -272,11 +350,11 @@ class Issue extends Controller $issue->projectid = $projectid; $issue->id = $id; $issue->summary = ''; - $issue->type = ''; - $issue->status = ''; - $issue->owner = ''; - $issue->priority = ''; $issue->description = ''; + $issue->type = $this->TYPE_DEFECT; + $issue->status = $this->STATUS_NEW; + $issue->priority = $this->PRIORITY_OTHER; + $issue->owner = ''; $data['issue'] = $issue; $this->load->view ($this->VIEW_EDIT, $data); @@ -286,9 +364,9 @@ class Issue extends Controller } } - function create ($projectid = '', $hexid = '') + function create ($projectid = '') { - return $this->_edit_issue ($projectid, $hexid, 'create'); + return $this->_edit_issue ($projectid, '', 'create'); } function update ($projectid = '', $hexid = '') @@ -396,4 +474,53 @@ class Issue extends Controller } } + + function _get_type_array () + { + return array ( + $this->TYPE_DEFECT => + $this->lang->line('ISSUE_TYPE_DEFECT'), + $this->TYPE_REQUEST => + $this->lang->line('ISSUE_TYPE_REQUEST'), + $this->TYPE_OTHER => + $this->lang->line('ISSUE_TYPE_OTHER') + ); + } + + function _get_status_array () + { + return array ( + $this->STATUS_NEW => + $this->lang->line('ISSUE_STATUS_NEW'), + $this->STATUS_ACCEPTED => + $this->lang->line('ISSUE_STATUS_ACCEPTED'), + $this->STATUS_REJECTED => + $this->lang->line('ISSUE_STATUS_REJECTED'), + $this->STATUS_FIXED => + $this->lang->line('ISSUE_STATUS_FIXED'), + $this->STATUS_WONTFIX => + $this->lang->line('ISSUE_STATUS_WONTFIX'), + $this->STATUS_DUPLICATE => + $this->lang->line('ISSUE_STATUS_DUPLICATE'), + $this->STATUS_OTHER => + $this->lang->line('ISSUE_STATUS_OTHER') + ); + } + + function _get_priority_array () + { + return array ( + $this->PRIORITY_CRITICAL => + $this->lang->line('ISSUE_PRIORITY_CRITICAL'), + $this->PRIORITY_HIGH => + $this->lang->line('ISSUE_PRIORITY_HIGH'), + $this->PRIORITY_MEDIUM => + $this->lang->line('ISSUE_PRIORITY_MEDIUM'), + $this->PRIORITY_LOW => + $this->lang->line('ISSUE_PRIORITY_LOW'), + $this->PRIORITY_OTHER => + $this->lang->line('ISSUE_PRIORITY_OTHER') + ); + + } } diff --git a/codepot/src/codepot/language/english/Makefile.am b/codepot/src/codepot/language/english/Makefile.am index f0ccbfe1..29e89e1f 100644 --- a/codepot/src/codepot/language/english/Makefile.am +++ b/codepot/src/codepot/language/english/Makefile.am @@ -1,6 +1,7 @@ wwwdir=$(WWWDIR)/codepot/language/english www_DATA = \ common_lang.php \ + issue_lang.php \ index.html EXTRA_DIST = $(www_DATA) diff --git a/codepot/src/codepot/language/english/Makefile.in b/codepot/src/codepot/language/english/Makefile.in index c13d97f3..2104536e 100644 --- a/codepot/src/codepot/language/english/Makefile.in +++ b/codepot/src/codepot/language/english/Makefile.in @@ -164,6 +164,7 @@ top_srcdir = @top_srcdir@ wwwdir = $(WWWDIR)/codepot/language/english www_DATA = \ common_lang.php \ + issue_lang.php \ index.html EXTRA_DIST = $(www_DATA) diff --git a/codepot/src/codepot/language/english/common_lang.php b/codepot/src/codepot/language/english/common_lang.php index 44753702..ff609d3a 100644 --- a/codepot/src/codepot/language/english/common_lang.php +++ b/codepot/src/codepot/language/english/common_lang.php @@ -1,9 +1,12 @@ %s from %s to %s"; +$lang['ISSUE_MSG_CONFIRM_UNDO'] = 'Are you sure to undo the last change?'; +?> diff --git a/codepot/src/codepot/language/indonesian/common_lang.php b/codepot/src/codepot/language/indonesian/common_lang.php index 65401686..0bd34c95 100644 --- a/codepot/src/codepot/language/indonesian/common_lang.php +++ b/codepot/src/codepot/language/indonesian/common_lang.php @@ -1,9 +1,12 @@ %s을/를 %s에서 %s(으)로 변경"; +$lang['ISSUE_MSG_CONFIRM_UNDO'] = '마지막 변경내용을 취소할까요?'; + +?> diff --git a/codepot/src/codepot/models/issuemodel.php b/codepot/src/codepot/models/issuemodel.php index ee8b21b6..4a0a004f 100644 --- a/codepot/src/codepot/models/issuemodel.php +++ b/codepot/src/codepot/models/issuemodel.php @@ -29,7 +29,7 @@ class IssueModel extends Model $this->db->where ('projectid', $project->id); $this->db->where ('id', $id); - $this->db->order_by ('sno', 'desc'); + $this->db->order_by ('sno', 'asc'); $query = $this->db->get ('issue_change'); $this->db->trans_complete (); @@ -41,10 +41,41 @@ class IssueModel extends Model return $result[0]; } + function getNumEntries ($userid, $project) + { + $this->db->trans_start (); + + $this->db->where ('projectid', $project->id); + $this->db->select ('count(id) as count'); + $query = $this->db->get ('issue'); + $result = $query->result(); + + $num = empty($result)? 0: $result[0]->count; + + $this->db->trans_complete (); + if ($this->db->trans_status() === FALSE) return FALSE; + + return $num; + } + + function getEntries ($userid, $offset, $limit, $project) + { + $this->db->trans_start (); + + $this->db->where ('projectid', $project->id); + $this->db->order_by ('id', 'desc'); + $query = $this->db->get ('issue', $limit, $offset); + $this->db->trans_complete (); + + if ($this->db->trans_status() === FALSE) return FALSE; + return $query->result (); + } + function getAll ($userid, $project) { $this->db->trans_start (); $this->db->where ('projectid', $project->id); + $this->db->order_by ('id', 'desc'); $query = $this->db->get ('issue'); $this->db->trans_complete (); @@ -111,6 +142,31 @@ class IssueModel extends Model return $newid; } + function update_partial ($userid, $issue) + { + $this->db->trans_start (); + $this->db->where ('projectid', $issue->projectid); + $this->db->where ('id', $issue->id); + $this->db->set ('summary', $issue->summary); + $this->db->set ('description', $issue->description); + $this->db->set ('updatedon', date('Y-m-d H:i:s')); + $this->db->set ('updatedby', $userid); + $this->db->update ('issue'); + + $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', $issue->projectid); + $this->db->set ('userid', $userid); + $this->db->set ('message', $issue->id); + $this->db->insert ('log'); + + $this->db->trans_complete (); + if ($this->db->trans_status() === FALSE) return FALSE; + + return $issue->id; + } + function update ($userid, $issue) { // TODO: check if userid can do this.. @@ -127,9 +183,9 @@ class IssueModel extends Model $this->db->set ('updatedby', $userid); $this->db->update ('issue'); - $this->db->set ('projectid', $issue->projectid); - $this->db->set ('id', $issue->id); - $this->db->set ('sno', 1); + $this->db->where ('projectid', $issue->projectid); + $this->db->where ('id', $issue->id); + $this->db->where ('sno', 1); $this->db->set ('type', $issue->type); $this->db->set ('status', $issue->status); $this->db->set ('owner', $issue->owner); @@ -206,26 +262,95 @@ class IssueModel extends Model return $id; } + function undo_last_change ($userid, $project, $id) + { + $this->db->trans_start (); + + $this->db->where ('projectid', $project->id); + $this->db->where ('id', $id); + $this->db->select ('MAX(sno) as maxsno'); + $query = $this->db->get ('issue_change'); + if ($this->db->trans_status() === FALSE) + { + $this->db->trans_complete (); + return FALSE; + } + $result = $query->result(); + if (!empty($result)) + { + $maxsno = $result[0]->maxsno; + if ($maxsno > 1) + { + $this->db->where ('projectid', $project->id); + $this->db->where ('id', $id); + $this->db->where ('sno', $maxsno); + $this->db->delete ('issue_change'); + + $this->db->where ('projectid', $project->id); + $this->db->where ('id', $id); + $this->db->select ('MAX(sno) as maxsno'); + $query = $this->db->get ('issue_change'); + if ($this->db->trans_status() === FALSE) + { + $this->db->trans_complete (); + return FALSE; + } + $result = $query->result(); + if (!empty($result)) + { + $maxsno = $result[0]->maxsno; + $this->db->where ('projectid', $project->id); + $this->db->where ('id', $id); + $this->db->where ('sno', $maxsno); + $query = $this->db->get ('issue_change'); + if ($this->db->trans_status() === FALSE) + { + $this->db->trans_complete (); + return FALSE; + } + $result = $query->result(); + if (!empty($result)) + { + $change = $result[0]; + $this->db->where ('projectid', $project->id); + $this->db->where ('id', $id); + $this->db->set ('type', $change->type); + $this->db->set ('status', $change->status); + $this->db->set ('owner', $change->owner); + $this->db->set ('priority', $change->priority); + $this->db->set ('updatedon', $change->updatedon); + $this->db->set ('updatedby', $change->updatedby); + $this->db->update ('issue'); + } + } + } + } + + $this->db->trans_complete (); + return $this->db->trans_status(); + } + function delete ($userid, $issue) { // TODO: check if userid can do this.. $this->db->trans_start (); - $this->db->where ('projectid', $issue->projectid); - $this->db->where ('id', $issue->id); - $this->db->delete ('issue'); $this->db->where ('projectid', $issue->projectid); $this->db->where ('id', $issue->id); $this->db->delete ('issue_change'); + $this->db->where ('projectid', $issue->projectid); + $this->db->where ('id', $issue->id); + $this->db->delete ('issue'); + $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', $issue->projectid); $this->db->set ('userid', $userid); $this->db->set ('message', $issue->id); - $this->db->insert ('log'); + $this->db->trans_complete (); return $this->db->trans_status(); } diff --git a/codepot/src/codepot/models/logmodel.php b/codepot/src/codepot/models/logmodel.php index 19be0972..26934273 100644 --- a/codepot/src/codepot/models/logmodel.php +++ b/codepot/src/codepot/models/logmodel.php @@ -40,10 +40,11 @@ class LogModel extends Model $this->db->order_by ('createdon', 'desc'); $query = $this->db->get ('log', $limit, $offset); - $result = $query->result (); $this->db->trans_complete (); if ($this->db->trans_status() === FALSE) return FALSE; + $result = $query->result (); + $count = 0; $commits = array (); foreach ($result as $row) diff --git a/codepot/src/codepot/views/file_show.php b/codepot/src/codepot/views/file_show.php index de8a48a5..1c97013c 100644 --- a/codepot/src/codepot/views/file_show.php +++ b/codepot/src/codepot/views/file_show.php @@ -12,7 +12,7 @@ function render_wiki() creole_render_wiki ( "project_file_show_textpre", "project_file_show_textarea", - "=dirname(dirname(dirname(dirname(current_url()))))?>/wiki/show/=$project->id?>/" + "=site_url()?>/wiki/show/=$project->id?>/" ); } diff --git a/codepot/src/codepot/views/issue_edit.php b/codepot/src/codepot/views/issue_edit.php index 818ebba0..bef28609 100644 --- a/codepot/src/codepot/views/issue_edit.php +++ b/codepot/src/codepot/views/issue_edit.php @@ -3,7 +3,7 @@
- +' . $this->lang->line('ID') . ' | '; + print '' . $this->lang->line('Type') . ' | '; + print '' . $this->lang->line('Status') . ' | '; + print '' . $this->lang->line('Priority') . ' | '; + print '' . $this->lang->line('Owner') . ' | '; + print '' . $this->lang->line('Summary') . ' | '; + print '
---|---|---|---|---|---|
'; print anchor ("issue/show/{$project->id}/{$hexid}", htmlspecialchars($issue->id)); - print ': '; - print htmlspecialchars($issue->summary); + print ' | '; + print ''; + print (htmlspecialchars( + array_key_exists($issue->type, $issue_type_array)? + $issue_type_array[$issue->type]: $issue->type)); + print ' | '; + + print ''; + print (htmlspecialchars( + array_key_exists($issue->status, $issue_status_array)? + $issue_status_array[$issue->status]: $issue->status)); + print ' | '; + + print ''; + print (htmlspecialchars( + array_key_exists($issue->priority, $issue_priority_array)? + $issue_priority_array[$issue->priority]: $issue->priority)); + print ' | '; + + print ''; print htmlspecialchars($issue->owner); - print htmlspecialchars($issue->createdby); + print ' | '; - print ''; + print ''; + print htmlspecialchars($issue->summary); + print ' | '; + + print '
{$page_links} | "; + print '
'; + print ''; + print date ('Y-m-d', strtotime($new->updatedon)); + print ''; + print ' | '; + + print ''; + print htmlspecialchars($new->updatedby); + print ' | '; + + print '';
+ if ($new->comment != "")
+ {
+ print " ";
+ print " ';
+ $commentno++;
+ }
+
+ print ' ';
+ print '';
+ print ' ';
+
+ print '
| ';
+ print '